ForceFields::ForceField *constructForceField( const BoundsMatrix &mmat, RDGeom::PointPtrVect &positions, const VECT_CHIRALSET &csets, double weightChiral, double weightFourthDim, std::map<std::pair<int, int>, double> *extraWeights, double basinSizeTol) { unsigned int N = mmat.numRows(); CHECK_INVARIANT(N == positions.size(), ""); ForceFields::ForceField *field = new ForceFields::ForceField(positions[0]->dimension()); for (unsigned int i = 0; i < N; i++) { field->positions().push_back(positions[i]); } for (unsigned int i = 1; i < N; i++) { for (unsigned int j = 0; j < i; j++) { double w = 1.0; double l = mmat.getLowerBound(i, j); double u = mmat.getUpperBound(i, j); bool includeIt = false; if (extraWeights) { std::map<std::pair<int, int>, double>::const_iterator mapIt; mapIt = extraWeights->find(std::make_pair(i, j)); if (mapIt != extraWeights->end()) { w = mapIt->second; includeIt = true; } } if (u - l <= basinSizeTol) { includeIt = true; } if (includeIt) { DistViolationContrib *contrib = new DistViolationContrib(field, i, j, u, l, w); field->contribs().push_back(ForceFields::ContribPtr(contrib)); } } } // now add chiral constraints if (weightChiral > 1.e-8) { for (VECT_CHIRALSET::const_iterator csi = csets.begin(); csi != csets.end(); csi++) { ChiralViolationContrib *contrib = new ChiralViolationContrib(field, csi->get(), weightChiral); field->contribs().push_back(ForceFields::ContribPtr(contrib)); } } // finally the contribution from the fourth dimension if we need to if ((field->dimension() == 4) && (weightFourthDim > 1.e-8)) { for (unsigned int i = 1; i < N; i++) { FourthDimContrib *contrib = new FourthDimContrib(field, i, weightFourthDim); field->contribs().push_back(ForceFields::ContribPtr(contrib)); } } return field; } // constructForceField