예제 #1
0
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 );
}
예제 #2
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;
}