void Intertwine::doPointshapePoint(int x, int y, ToolLoop* loop) { Symmetry* symmetry = loop->getSymmetry(); if (symmetry) { Point origin(loop->getCelOrigin()); // Convert the point to the sprite position so we can apply the // symmetry transformation. Stroke main_stroke; main_stroke.addPoint(Point(x, y) + origin); Strokes strokes; symmetry->generateStrokes(main_stroke, strokes, loop); for (const auto& stroke : strokes) { // We call transformPoint() moving back each point to the cel // origin. loop->getPointShape()->transformPoint( loop, stroke[0].x - origin.x, stroke[0].y - origin.y); } } else { loop->getPointShape()->transformPoint(loop, x, y); } }
SymmetryPropagator::SymmetryPropagator(PCSolver* solver, const Symmetry& sym) : Propagator(DEFAULTCONSTRID, solver, "symmetry propagator"), symmetrical(sym.getSymmetrical()), inverse(sym.getInverse()), nextToPropagate(0) { getPCSolver().accept(this); getPCSolver().accept(this, EV_BACKTRACK); getPCSolver().accept(this, EV_PROPAGATE); for (auto litpair : symmetrical) { getPCSolver().accept(this, litpair.first, FAST); // NOTE: negation of litpair.first is always in the symmetrical-map, so no need to add it twice. } }
void test_symmetry(const Symmetry& s) { std::map<int, Symmetry::const_iterator> m; for (Symmetry::const_iterator i = s.begin(); i != s.end(); ++i) { for (unsigned int j = 0; j < 81; ++j) { if ((*i)[j]) { std::pair<std::map<int, Symmetry::const_iterator>::iterator, bool> result = m.insert(std::make_pair(j, i)); assert(result.second); } } } for (unsigned int j = 0; j < 81; ++j) { std::map<int, Symmetry::const_iterator>::iterator it = m.find(j); assert(it != m.end()); } }
void Intertwine::doPointshapePoint(int x, int y, ToolLoop* loop) { Symmetry* symmetry = loop->getSymmetry(); if (symmetry) { Stroke main_stroke; main_stroke.addPoint(gfx::Point(x, y)); Strokes strokes; symmetry->generateStrokes(main_stroke, strokes); for (const auto& stroke : strokes) loop->getPointShape()->transformPoint( loop, stroke[0].x, stroke[0].y); } else { loop->getPointShape()->transformPoint(loop, x, y); } }
int main(int argc, char *argv[]){ // Option Parser Options opt = setupOptions(argc,argv); Transforms tr; // Super-helical Radius Loop for (double sr = opt.superHelicalRadius[0]; sr <= opt.superHelicalRadius[1]; sr += opt.superHelicalRadius[2]){ // Alpha-helical Phase Angle Loop for (double aph = opt.alphaHelicalPhaseAngle[0]; aph < opt.alphaHelicalPhaseAngle[1];aph+=opt.alphaHelicalPhaseAngle[2]){ // Super-helical Pitch Angle loop added by David Slochower for(double shpa = opt.superHelicalPitchAngle[0]; shpa < opt.superHelicalPitchAngle[1]; shpa+=opt.superHelicalPitchAngle[2]) { double shPitch = (2*M_PI*sr)/tan(M_PI*shpa/180); // Generate a coiled helix CoiledCoils cc; // Values used for previous work: cc.northCoiledCoils(sr, 1.5232, shPitch, 2.25, opt.numberOfResidues, 103.195, aph); // March 31, 2010: Jason Donald // Hard code values of h (rise/residue) = 1.51, r1 (alpha-helical radius), and theta (alpha helical frequency) // based on median values observed by Gevorg Grigoryan //cc.northCoiledCoils(sr, 1.51, shPitch, 2.26, opt.numberOfResidues, 102.8, aph); AtomPointerVector coil = cc.getCoiledCoil(sr, 1.51, shPitch, 2.26, 102.8, aph, 0.0,opt.numberOfResidues); // Apply symmetry operations to create a bundle int C_axis = atoi(opt.symmetry.substr(1,(opt.symmetry.length()-1)).c_str()); if (opt.symmetry.substr(0,1) == "C"){ Symmetry sym; sym.applyCN(coil,C_axis); // Write out bundle char filename[80]; sprintf(filename, "%s_%s_%03d_%05.2f_%05.2f_shp%05.2f.pdb", opt.name.c_str(),opt.symmetry.c_str(),opt.numberOfResidues, sr, aph, shpa); cout << "Writing "<<filename<<endl; PDBWriter pout; pout.open(filename); pout.write(sym.getAtomPointers()); pout.close(); } else if (opt.symmetry.substr(0,1) == "D"){ // Z Rotate for (double spa = opt.superHelicalPhaseAngle[0]; spa < opt.superHelicalPhaseAngle[1]; spa += opt.superHelicalPhaseAngle[2]){ coil.clearSavedCoor(); coil.saveCoor("preSPA"); Matrix zRot = CartesianGeometry::getZRotationMatrix(spa); //coil.rotate(zRot); tr.rotate(coil, zRot); // Z Trans for (double ztrans = opt.d2zTranslation[0];ztrans < opt.d2zTranslation[1]; ztrans += opt.d2zTranslation[2]){ coil.saveCoor("preZtrans"); CartesianPoint z(0,0,ztrans); //coil.translate(z); tr.translate(coil, z); Symmetry sym; sym.applyDN(coil,C_axis); // Write out bundle char filename[80]; sprintf(filename, "%s_%s_%03d_%05.2f_%05.2f_shp%05.2f_%05.2f_%05.2f.pdb", opt.name.c_str(),opt.symmetry.c_str(),opt.numberOfResidues,sr, aph, shpa, spa, ztrans); cout << "Writing "<<filename<<endl; PDBWriter pout; pout.open(filename); pout.write(sym.getAtomPointers()); pout.close(); coil.applySavedCoor("preZtrans"); } // Ztrans coil.applySavedCoor("preSPA"); } // SHA } } } } }
void Interstitial::voronoi(const ISO& iso, const Symmetry& symmetry, double tol) { // Clear space clear(); // Output Output::newline(); Output::print("Searching for interstitial sites using Voronoi method"); Output::increase(); // Set up image iterator ImageIterator images; images.setCell(iso.basis(), 12); // Loop over unique atoms in the structure int i, j, k; List<double> weights; OList<Vector3D> points; OList<Vector3D> vertices; Linked<Vector3D> intPoints; for (i = 0; i < symmetry.orbits().length(); ++i) { // Reset variables weights.length(0); points.length(0); vertices.length(0); // Loop over atoms in the structure for (j = 0; j < iso.atoms().length(); ++j) { for (k = 0; k < iso.atoms()[j].length(); ++k) { // Loop over images images.reset(symmetry.orbits()[i].atoms()[0]->fractional(), iso.atoms()[j][k].fractional()); while (!images.finished()) { // Skip if atoms are the same if (++images < 1e-8) continue; // Save current point points += symmetry.orbits()[i].atoms()[0]->cartesian() + images.cartVector(); weights += 0.5; } } } // Calculate Voronoi volume symmetry.orbits()[i].atoms()[0]->cartesian().voronoi(points, weights, tol, &vertices); // Save points for (j = 0; j < vertices.length(); ++j) { intPoints += iso.basis().getFractional(vertices[j]); ISO::moveIntoCell(*intPoints.last()); } } // Reduce points to unique ones bool found; double curDistance; Vector3D rotPoint; Vector3D equivPoint; Vector3D origin(0.0); Linked<double> distances; Linked<double>::iterator itDist; Linked<Vector3D>::iterator it; Linked<Vector3D> uniquePoints; Linked<Vector3D>::iterator itUnique; for (it = intPoints.begin(); it != intPoints.end(); ++it) { // Get current distance to origin curDistance = iso.basis().distance(*it, FRACTIONAL, origin, FRACTIONAL); // Loop over points that were already saved found = false; itDist = distances.begin(); itUnique = uniquePoints.begin(); for (; itDist != distances.end(); ++itDist, ++itUnique) { // Current points are not the same if (Num<double>::abs(curDistance - *itDist) <= tol) { if (iso.basis().distance(*it, FRACTIONAL, *itUnique, FRACTIONAL) <= tol) { found = true; break; } } // Loop over symmetry operations for (i = 0; i < symmetry.operations().length(); ++i) { // Loop over translations rotPoint = symmetry.operations()[i].rotation() * *it; for (j = 0; j < symmetry.operations()[i].translations().length(); ++j) { // Check if points are the same equivPoint = rotPoint; equivPoint += symmetry.operations()[i].translations()[j]; if (iso.basis().distance(equivPoint, FRACTIONAL, *itUnique, FRACTIONAL) <= tol) { found = true; break; } } if (found) break; } if (found) break; } // Found a new point if (!found) { distances += curDistance; uniquePoints += *it; } } // Save unique points _sites.length(uniquePoints.length()); for (i = 0, it = uniquePoints.begin(); it != uniquePoints.end(); ++i, ++it) _sites[i] = *it; // Output Output::newline(); Output::print("Found "); Output::print(_sites.length()); Output::print(" possible interstitial site"); if (_sites.length() != 1) Output::print("s"); Output::increase(); for (i = 0; i < _sites.length(); ++i) { Output::newline(); Output::print("Site "); Output::print(i+1); Output::print(":"); for (j = 0; j < 3; ++j) { Output::print(" "); Output::print(_sites[i][j], 8); } } Output::decrease(); // Output Output::decrease(); }
void Interstitial::evaluate(const ISO& iso, const Symmetry& symmetry, int numPointsPerAtom, double tol, double scale) { // Clear space clear(); // Output Output::newline(); Output::print("Searching for interstitial sites using "); Output::print(numPointsPerAtom); Output::print(" starting point"); if (numPointsPerAtom != 1) Output::print("s"); Output::print(" per atom and a scale of "); Output::print(scale); Output::increase(); // Constants used in generating points on sphere around each atom double phiScale = Constants::pi * (3 - sqrt(5)); double yScale = 2.0 / numPointsPerAtom; // Loop over unique atoms in the structure int i, j, k; int count = 0; double y; double r; double phi; double curDistance; double nearDistance; double startDistance; Vector3D curPoint; Linked<Vector3D > points; for (i = 0; i < symmetry.orbits().length(); ++i) { // Get the distance to nearest atom in the structure nearDistance = -1; for (j = 0; j < iso.atoms().length(); ++j) { for (k = 0; k < iso.atoms()[j].length(); ++k) { curDistance = iso.basis().distance(symmetry.orbits()[i].atoms()[0]->fractional(), FRACTIONAL, \ iso.atoms()[j][k].fractional(), FRACTIONAL); if (curDistance > 0) { if ((nearDistance == -1) || (curDistance < nearDistance)) nearDistance = curDistance; } } } // Set the starting distance away from atom startDistance = nearDistance / 2; // Loop over starting points for (j = 0; j < numPointsPerAtom; ++j) { // Check if running current point on current processor if ((++count + Multi::rank()) % Multi::worldSize() == 0) { // Get current starting point y = j * yScale - 1 + (yScale / 2); r = sqrt(1 - y*y); phi = j * phiScale; curPoint.set(symmetry.orbits()[i].atoms()[0]->cartesian()[0] + startDistance*r*cos(phi), \ symmetry.orbits()[i].atoms()[0]->cartesian()[1] + startDistance*y, \ symmetry.orbits()[i].atoms()[0]->cartesian()[2] + startDistance*r*sin(phi)); // Minimize the current point if (!minimizePoint(curPoint, iso, scale)) continue; // Save current point in fractional coordinates points += iso.basis().getFractional(curPoint); ISO::moveIntoCell(*points.last()); } } } // Reduce list of points to unique ones int m; bool found; int numLoops; Vector3D rotPoint; Vector3D equivPoint; Vector3D origin(0.0); Linked<double> distances; Linked<double>::iterator itDist; Linked<Vector3D> uniquePoints; Linked<Vector3D>::iterator it; Linked<Vector3D>::iterator itUnique; for (i = 0; i < Multi::worldSize(); ++i) { // Send number of points in list on current processor numLoops = points.length(); Multi::broadcast(numLoops, i); // Loop over points if (i == Multi::rank()) it = points.begin(); for (j = 0; j < numLoops; ++j) { // Send out current point if (i == Multi::rank()) { curPoint = *it; ++it; } Multi::broadcast(curPoint, i); // Get current distance to origin curDistance = iso.basis().distance(curPoint, FRACTIONAL, origin, FRACTIONAL); // Loop over points that were already saved found = false; itDist = distances.begin(); itUnique = uniquePoints.begin(); for (; itDist != distances.end(); ++itDist, ++itUnique) { // Current points are not the same if (Num<double>::abs(curDistance - *itDist) <= tol) { if (iso.basis().distance(curPoint, FRACTIONAL, *itUnique, FRACTIONAL) <= tol) { found = true; break; } } // Loop over symmetry operations for (k = 0; k < symmetry.operations().length(); ++k) { // Loop over translations rotPoint = symmetry.operations()[k].rotation() * curPoint; for (m = 0; m < symmetry.operations()[k].translations().length(); ++m) { // Check if points are the same equivPoint = rotPoint; equivPoint += symmetry.operations()[k].translations()[m]; if (iso.basis().distance(equivPoint, FRACTIONAL, *itUnique, FRACTIONAL) <= tol) { found = true; break; } } if (found) break; } if (found) break; } // Found a new point if (!found) { distances += curDistance; uniquePoints += curPoint; } } } // Save unique points _sites.length(uniquePoints.length()); for (i = 0, it = uniquePoints.begin(); it != uniquePoints.end(); ++i, ++it) _sites[i] = *it; // Output Output::newline(); Output::print("Found "); Output::print(_sites.length()); Output::print(" possible interstitial site"); if (_sites.length() != 1) Output::print("s"); Output::increase(); for (i = 0; i < _sites.length(); ++i) { Output::newline(); Output::print("Site "); Output::print(i+1); Output::print(":"); for (j = 0; j < 3; ++j) { Output::print(" "); Output::print(_sites[i][j], 8); } } Output::decrease(); // Output Output::decrease(); }
/****************************************** * * ======= MAIN ======= * ******************************************/ int main(int argc, char *argv[]) { // Define Objects for the test CoiledCoils cc; CoiledCoilFitter ccf; PDBWriter pout; /****************************************************************************** * * === GEVORG/CRICKS CC GENERATION === * ******************************************************************************/ //sys.writePdb(opt.fileName); cc.getCoiledCoilCricks(4.910, -4.027, -13.530, 2.267, 102.806, 149.984, 0.0, 26); AtomPointerVector cricks = cc.getAtomPointers(); pout.open("/tmp/cricks.pdb"); pout.write(cricks); pout.close(); double shr = 4.910; double risePerRes = 1.51; double shp = 128.206; double ahr = 2.26; double ahp = 102.8; double ahphase = 149.984; double dZ = 0.0; //meaningless parameter at the moment. cc.getCoiledCoil(shr, risePerRes, shp, ahr, ahp, ahphase, dZ, 26); AtomPointerVector norths = cc.getAtomPointers(); pout.open("/tmp/norths.pdb"); pout.write(norths); pout.close(); Symmetry sym; sym.applyCN(norths,2); pout.open("/tmp/northC2.pdb"); pout.write(sym.getAtomPointers()); pout.close(); System sys; sys.readPdb("/tmp/northC2.pdb"); // Fitting procedure.. // Add helix chain A ccf.addNextHelix(&sys.getChain("A").getAtomPointers()); // Add helix chain B ccf.addNextHelix(&sys.getChain("B").getAtomPointers()); // Set symmetry ccf.setSymmetry("C"); // Do fittin procedure ccf.fit(); // Do something else.. vector<double> params = ccf.getMinimizedParameters(); if ( abs(params[0] - shr) > 0.1){ cerr << "ERROR Super-helical radius is off. Target = "<<shr<<" MinValue = "<<params[0]<<endl; } else if (abs(params[1] - risePerRes) > 0.1){ cerr << "ERROR RisePerRes is off. Target = "<<risePerRes<<" MinValue = "<<params[1]<<endl; } else if (abs(params[2] - shp) > 0.1){ cerr << "ERROR Super-helical pitch is off. Target = "<<shp<<" MinValue = "<<params[2]<<endl; } else if (abs(params[3] - ahr) > 0.1){ cerr << "ERROR Alpha-helical radius is off. Target = "<<ahr<<" MinValue = "<<params[3]<<endl; } else if (abs(params[4] - ahp) > 0.1){ cerr << "ERROR Alpha-helical pitch is off. Target = "<<ahp<<" MinValue = "<<params[4]<<endl; } else if (abs(params[5] - ahphase) > 0.1){ cerr << "ERROR Alpha-helical phase is off. Target = "<<ahphase<<" MinValue = "<<params[5]<<endl; } else if (abs(params[6] - dZ) > 0.1){ cerr << "ERROR deltaZ offset is off. Target = "<<dZ<<" MinValue = "<<params[6]<<endl; } else { cout << "LEAD"; } }
int main(int argc, char *argv[]) { // the program requires the location of the "exampleFiles" as an argument if (argc < 1) { cerr << "USAGE:\nexample_coiled_coil_and_symmetric_bundles" << endl; exit(0); } cout << " ***************************************************************************************" << endl; cout << "" << endl; cout << " How to generate coiled-coils in MSL (" << MslTools::getMSLversion() << ") " << endl; cout << "" << endl; cout << " ***************************************************************************************" << endl; cout << endl; cout << endl; // CoiledCoils object used to create a coiled helix (by a number of algorithms) CoiledCoils cc; // A super-helical radius double sr = 6.5; // An alpha-helical phase angle double aph = 0.0; // A super-helical pitch angle, and pitch distance double shpa = 190; double shPitch = (2*M_PI*sr)/tan(M_PI*shpa/180); // Hard code values of h (rise/residue) = 1.51, r1 (alpha-helical radius), and theta (alpha helical frequency) double risePerResidue = 1.51; // Use observed medians by Gevorg Grigoryan (Probing Deisgnability via a Generalized Model of Helical Bundle Geometry, JMB 2010) double alphaHelicalRadius = 2.26; double alphaHelicalFrequency = 102.8; // Number of residues in coil ( lets do 4 heptads = 28 residues ) double numberOfResidues = 28; // Generate a coiled coil, using specified parameters //cc.northCoiledCoils(sr, risePerResidue, shPitch, alphaHelicalRadius, numberOfResidues, alphaHelicalFrequency, aph); // dZ double dZ = 0.0; // Get the atoms from the CoiledCoils object back (this is a single coiled-coil helix) AtomPointerVector coil = cc.getCoiledCoil(sr, risePerResidue, shPitch, alphaHelicalRadius, alphaHelicalFrequency,dZ, aph,numberOfResidues); cout << "Writing /tmp/singleHelixCoil.pdb"<<endl; PDBWriter pout; pout.open("/tmp/singleHelixCoil.pdb"); pout.write(coil); pout.close(); // Create a symmtery object to generate a coiled bundle ( C4 symmetric ) Symmetry sym; // Apply C4 to "coil" sym.applyCN(coil,4); cout << "Writing /tmp/C4HelixCoil.pdb"<<endl; pout.open("/tmp/C4HelixCoil.pdb"); pout.write(sym.getAtomPointers()); pout.close(); }
void ToolLoopManager::doLoopStep(bool last_step) { // Original set of points to interwine (original user stroke, // relative to sprite origin). Stroke main_stroke; if (!last_step) m_toolLoop->getController()->getStrokeToInterwine(m_stroke, main_stroke); else main_stroke = m_stroke; // Calculate the area to be updated in all document observers. Symmetry* symmetry = m_toolLoop->getSymmetry(); Strokes strokes; if (symmetry) symmetry->generateStrokes(main_stroke, strokes, m_toolLoop); else strokes.push_back(main_stroke); calculateDirtyArea(strokes); // Validate source image area. if (m_toolLoop->getInk()->needsSpecialSourceArea()) { gfx::Region srcArea; m_toolLoop->getInk()->createSpecialSourceArea(m_dirtyArea, srcArea); m_toolLoop->validateSrcImage(srcArea); } else { m_toolLoop->validateSrcImage(m_dirtyArea); } m_toolLoop->getInk()->prepareForStrokes(m_toolLoop, strokes); // Invalidate destionation image areas. if (m_toolLoop->getTracePolicy() == TracePolicy::Last) { // Copy source to destination (reset the previous trace). Useful // for tools like Line and Ellipse (we kept the last trace only). m_toolLoop->invalidateDstImage(); } else if (m_toolLoop->getTracePolicy() == TracePolicy::AccumulateUpdateLast) { // Revalidate only this last dirty area (e.g. pixel-perfect // freehand algorithm needs this trace policy to redraw only the // last dirty area, which can vary in one pixel from the previous // tool loop cycle). m_toolLoop->invalidateDstImage(m_dirtyArea); } m_toolLoop->validateDstImage(m_dirtyArea); // Join or fill user points if (!m_toolLoop->getFilled() || (!last_step && !m_toolLoop->getPreviewFilled())) m_toolLoop->getIntertwine()->joinStroke(m_toolLoop, main_stroke); else m_toolLoop->getIntertwine()->fillStroke(m_toolLoop, main_stroke); if (m_toolLoop->getTracePolicy() == TracePolicy::Overlap) { // Copy destination to source (yes, destination to source). In // this way each new trace overlaps the previous one. m_toolLoop->copyValidDstToSrcImage(m_dirtyArea); } if (!m_dirtyArea.isEmpty()) m_toolLoop->updateDirtyArea(); }