void SingleDomainRMSD::setReferenceAtoms( const std::vector<Vector>& conf, const std::vector<double>& align_in, const std::vector<double>& displace_in ){ reference_atoms.resize( conf.size() ); align.resize( conf.size() ); displace.resize( conf.size() ); der_index.resize( conf.size() ); double wa=0, wd=0; for(unsigned i=0;i<conf.size();++i){ wa+=align_in[i]; wd+=displace_in[i]; } Vector center; for(unsigned i=0;i<conf.size();++i){ align[i]=align_in[i] / wa; displace[i]=displace_in[i] / wd; center+=conf[i]*align[i]; der_index[i]=i; } for(unsigned i=0;i<conf.size();++i) reference_atoms[i]=conf[i]-center; setNumberOfAtoms( conf.size() ); setNumberOfArguments( 0 ); }
/* The next function is meant to be called from Python. It creates the energy term object at the C level and stores all the parameters in there in a form that is convient to access for the C routine above. This is the routine that is imported into and called by the Python module, OBC.py. */ static PyObject * OBCTerm(PyObject *dummy, PyObject *args) { PyFFEnergyTermObject *self; int numParticles; PyArrayObject *charges; PyArrayObject *atomicRadii; PyArrayObject *scaleFactors; double strength; /* Create a new energy term object and return if the creation fails. */ self = PyFFEnergyTerm_New(); if (self == NULL) return NULL; /* Convert the parameters to C data types. */ if (!PyArg_ParseTuple(args, "O!idO!O!O!", &PyUniverseSpec_Type, &self->universe_spec, &numParticles, &strength, &PyArray_Type, &charges, &PyArray_Type, &atomicRadii, &PyArray_Type, &scaleFactors)) return NULL; /* We keep a reference to the universe_spec in the newly created energy term object, so we have to increase the reference count. */ Py_INCREF(self->universe_spec); /* A pointer to the evaluation routine. */ self->eval_func = ef_evaluator; /* The name of the energy term object. */ self->evaluator_name = "OBC"; /* The names of the individual energy terms - just one here. */ self->term_names[0] = allocstring("OBC"); if (self->term_names[0] == NULL) return PyErr_NoMemory(); self->nterms = 1; struct ObcParameters* obcParameters = newObcParameters( numParticles, strength, (double *)charges->data, (double *)atomicRadii->data, (double *)scaleFactors->data); struct ReferenceObc* obc = newReferenceObc(obcParameters); /* self->param is a storage area for parameters. Note that there are only 40 slots (double) there. */ self->param[0] = (double) numParticles; self->param[1] = strength; /* self->data is the other storage area for parameters. There are 40 Python object slots there */ self->data[0] = (PyObject *)charges; Py_INCREF(charges); self->data[1] = (PyObject *)atomicRadii; Py_INCREF(atomicRadii); self->data[2] = (PyObject *)scaleFactors; Py_INCREF(scaleFactors); self->data[3] = (PyObject *)obcParameters; Py_INCREF(obcParameters); // Seems to increment the number of particles setNumberOfAtoms(obcParameters, numParticles); self->data[4] = (PyObject *)obc; Py_INCREF(obc); /* Return the energy term object. */ return (PyObject *)self; }