Exec::RetType Exec_CrdAction::DoCrdAction(CpptrajState& State, ArgList& actionargs, DataSet_Coords* CRD, Action* act, TrajFrameCounter const& frameCount) const { Timer total_time; total_time.Start(); # ifdef MPI ActionInit state(State.DSL(), State.DFL(), trajComm_); # else ActionInit state(State.DSL(), State.DFL()); # endif if ( act->Init( actionargs, state, State.Debug() ) != Action::OK ) return CpptrajState::ERR; actionargs.CheckForMoreArgs(); // Set up frame and parm for COORDS. ActionSetup originalSetup( CRD->TopPtr(), CRD->CoordsInfo(), CRD->Size() ); Frame originalFrame = CRD->AllocateFrame(); ActionFrame frm( &originalFrame, 0 ); // Set up for this topology Action::RetType setup_ret = act->Setup( originalSetup ); if ( setup_ret == Action::ERR || setup_ret == Action::SKIP ) return CpptrajState::ERR; // Loop over all frames in COORDS. ProgressBar progress( frameCount.TotalReadFrames() ); int set = 0; for (int frame = frameCount.Start(); frame < frameCount.Stop(); frame += frameCount.Offset(), ++set) { progress.Update( set ); CRD->GetFrame( frame, originalFrame ); frm.SetTrajoutNum( set ); Action::RetType ret = act->DoAction( set, frm ); if (ret == Action::ERR) { mprinterr("Error: crdaction: Frame %i, set %i\n", frame + 1, set + 1); break; } // Check if frame was modified. If so, update COORDS. if ( ret == Action::MODIFY_COORDS ) CRD->SetCRD( frame, frm.Frm() ); } # ifdef MPI act->SyncAction(); # endif // Check if parm was modified. If so, update COORDS. if ( setup_ret == Action::MODIFY_TOPOLOGY ) { mprintf("Info: crdaction: Parm for %s was modified by action %s\n", CRD->legend(), actionargs.Command()); CRD->CoordsSetup( originalSetup.Top(), originalSetup.CoordInfo() ); } act->Print(); State.MasterDataFileWrite(); total_time.Stop(); mprintf("TIME: Total action execution time: %.4f seconds.\n", total_time.Total()); return CpptrajState::OK; }
// Exec_SortEnsembleData::Execute() Exec::RetType Exec_SortEnsembleData::Execute(CpptrajState& State, ArgList& argIn) { debug_ = State.Debug(); DataSetList setsToSort; std::string dsarg = argIn.GetStringNext(); while (!dsarg.empty()) { setsToSort += State.DSL().GetMultipleSets( dsarg ); dsarg = argIn.GetStringNext(); } int err = 0; # ifdef MPI // For now, require ensemble mode in parallel. if (!Parallel::EnsembleIsSetup()) { rprinterr("Error: Data set ensemble sort requires ensemble mode in parallel.\n"); return CpptrajState::ERR; } // Only TrajComm masters have complete data. if (Parallel::TrajComm().Master()) { comm_ = Parallel::MasterComm(); # endif DataSetList OutputSets; err = SortData( setsToSort, OutputSets ); if (err == 0) { // Remove unsorted sets. for (DataSetList::const_iterator ds = setsToSort.begin(); ds != setsToSort.end(); ++ds) State.DSL().RemoveSet( *ds ); // Add sorted sets. for (DataSetList::const_iterator ds = OutputSets.begin(); ds != OutputSets.end(); ++ds) State.DSL().AddSet( *ds ); // Since sorted sets have been transferred to master DSL, OutputSets now // just has copies. OutputSets.SetHasCopies( true ); mprintf("\tSorted sets:\n"); OutputSets.List(); } # ifdef MPI } if (Parallel::World().CheckError( err )) # else if (err != 0) # endif return CpptrajState::ERR; return CpptrajState::OK; }
Exec::RetType Exec_DataFilter::Execute(CpptrajState& State, ArgList& argIn) { Action_FilterByData filterAction; ActionInit state(State.DSL(), State.DFL()); if (filterAction.Init(argIn, state, State.Debug()) != Action::OK) return CpptrajState::ERR; size_t nframes = filterAction.DetermineFrames(); if (nframes < 1) { mprinterr("Error: No data to filter. All sets must contain some data.\n"); return CpptrajState::ERR; } ProgressBar progress( nframes ); ActionFrame frm; for (size_t frame = 0; frame != nframes; frame++) { progress.Update( frame ); filterAction.DoAction(frame, frm); // Filter does not need frame. } // Trigger master datafile write just in case State.MasterDataFileWrite(); return CpptrajState::OK; }
int SequenceAlign(CpptrajState& State, ArgList& argIn) { std::string blastfile = argIn.GetStringKey("blastfile"); if (blastfile.empty()) { mprinterr("Error: 'blastfile' must be specified.\n"); return 1; } ReferenceFrame qref = State.DSL()->GetReferenceFrame(argIn); if (qref.error() || qref.empty()) { mprinterr("Error: Must specify reference structure for query.\n"); return 1; } std::string outfilename = argIn.GetStringKey("out"); if (outfilename.empty()) { mprinterr("Error: Must specify output file.\n"); return 1; } TrajectoryFile::TrajFormatType fmt = TrajectoryFile::GetFormatFromArg(argIn); if (fmt != TrajectoryFile::PDBFILE && fmt != TrajectoryFile::MOL2FILE) fmt = TrajectoryFile::PDBFILE; // Default to PDB int smaskoffset = argIn.getKeyInt("smaskoffset", 0) + 1; int qmaskoffset = argIn.getKeyInt("qmaskoffset", 0) + 1; // Load blast file mprintf("\tReading BLAST alignment from '%s'\n", blastfile.c_str()); BufferedLine infile; if (infile.OpenFileRead( blastfile )) return 1; // Seek down to first Query line. const char* ptr = infile.Line(); bool atFirstQuery = false; while (ptr != 0) { if (*ptr == 'Q') { if ( strncmp(ptr, "Query", 5) == 0 ) { atFirstQuery = true; break; } } ptr = infile.Line(); } if (!atFirstQuery) { mprinterr("Error: 'Query' not found.\n"); return 1; } // Read alignment. Replacing query with subject. typedef std::vector<char> Carray; typedef std::vector<int> Iarray; Carray Query; // Query residues Carray Sbjct; // Sbjct residues Iarray Smap; // Smap[Sbjct index] = Query index while (ptr != 0) { const char* qline = ptr; // query line const char* aline = infile.Line(); // alignment line const char* sline = infile.Line(); // subject line if (aline == 0 || sline == 0) { mprinterr("Error: Missing alignment line or subject line after Query:\n"); mprinterr("Error: %s", qline); return 1; } for (int idx = 12; qline[idx] != ' '; idx++) { if (qline[idx] == '-') { // Sbjct does not have corresponding res in Query Smap.push_back(-1); Sbjct.push_back( sline[idx] ); } else if (sline[idx] == '-') { // Query does not have a corresponding res in Sbjct Query.push_back( qline[idx] ); } else { // Direct Query to Sbjct map Smap.push_back( Query.size() ); Sbjct.push_back( sline[idx] ); Query.push_back( qline[idx] ); } } // Scan to next Query ptr = infile.Line(); while (ptr != 0) { if (*ptr == 'Q') { if ( strncmp(ptr, "Query", 5) == 0 ) break; } ptr = infile.Line(); } } // DEBUG std::string SmaskExp, QmaskExp; if (State.Debug() > 0) mprintf(" Map of Sbjct to Query:\n"); for (int sres = 0; sres != (int)Sbjct.size(); sres++) { if (State.Debug() > 0) mprintf("%-i %3s %i", sres+smaskoffset, Residue::ConvertResName(Sbjct[sres]), Smap[sres]+qmaskoffset); const char* qres = ""; if (Smap[sres] != -1) { qres = Residue::ConvertResName(Query[Smap[sres]]); if (SmaskExp.empty()) SmaskExp.assign( integerToString(sres+smaskoffset) ); else SmaskExp.append( "," + integerToString(sres+smaskoffset) ); if (QmaskExp.empty()) QmaskExp.assign( integerToString(Smap[sres]+qmaskoffset) ); else QmaskExp.append( "," + integerToString(Smap[sres]+qmaskoffset) ); } if (State.Debug() > 0) mprintf(" %3s\n", qres); } mprintf("Smask: %s\n", SmaskExp.c_str()); mprintf("Qmask: %s\n", QmaskExp.c_str()); // Check that query residues match reference. for (unsigned int sres = 0; sres != Sbjct.size(); sres++) { int qres = Smap[sres]; if (qres != -1) { if (Query[qres] != qref.Parm().Res(qres).SingleCharName()) { mprintf("Warning: Potential residue mismatch: Query %s reference %s\n", Residue::ConvertResName(Query[qres]), qref.Parm().Res(qres).c_str()); } } } // Build subject using coordinate from reference. //AtomMask sMask; // Contain atoms that should be in sTop Topology sTop; Frame sFrame; Iarray placeHolder; // Atom indices of placeholder residues. for (unsigned int sres = 0; sres != Sbjct.size(); sres++) { int qres = Smap[sres]; NameType SresName( Residue::ConvertResName(Sbjct[sres]) ); if (qres != -1) { Residue const& QR = qref.Parm().Res(qres); Residue SR(SresName, sres+1, ' ', QR.ChainID()); if (Query[qres] == Sbjct[sres]) { // Exact match. All non-H atoms. for (int qat = QR.FirstAtom(); qat != QR.LastAtom(); qat++) { if (qref.Parm()[qat].Element() != Atom::HYDROGEN) sTop.AddTopAtom( qref.Parm()[qat], SR ); sFrame.AddXYZ( qref.Coord().XYZ(qat) ); //sMask.AddAtom(qat); } } else { // Partial match. Copy only backbone and CB. for (int qat = QR.FirstAtom(); qat != QR.LastAtom(); qat++) { if ( qref.Parm()[qat].Name().Match("N" ) || qref.Parm()[qat].Name().Match("CA") || qref.Parm()[qat].Name().Match("CB") || qref.Parm()[qat].Name().Match("C" ) || qref.Parm()[qat].Name().Match("O" ) ) { sTop.AddTopAtom( qref.Parm()[qat], SR ); sFrame.AddXYZ( qref.Coord().XYZ(qat) ); } } } } else { // Residue in query does not exist for subject. Just put placeholder CA for now. Vec3 Zero(0.0); placeHolder.push_back( sTop.Natom() ); sTop.AddTopAtom( Atom("CA", "C "), Residue(SresName, sres+1, ' ', ' ') ); sFrame.AddXYZ( Zero.Dptr() ); } } //sTop.PrintAtomInfo("*"); mprintf("\tPlaceholder residue indices:"); for (Iarray::const_iterator p = placeHolder.begin(); p != placeHolder.end(); ++p) mprintf(" %i", *p + 1); mprintf("\n"); // Try to give placeholders more reasonable coordinates. if (!placeHolder.empty()) { Iarray current_indices; unsigned int pidx = 0; while (pidx < placeHolder.size()) { if (current_indices.empty()) { current_indices.push_back( placeHolder[pidx++] ); // Search for the end of this segment for (; pidx != placeHolder.size(); pidx++) { if (placeHolder[pidx] - current_indices.back() > 1) break; current_indices.push_back( placeHolder[pidx] ); } // DEBUG mprintf("\tSegment:"); for (Iarray::const_iterator it = current_indices.begin(); it != current_indices.end(); ++it) mprintf(" %i", *it + 1); // Get coordinates of residues bordering segment. int prev_res = sTop[current_indices.front()].ResNum() - 1; int next_res = sTop[current_indices.back() ].ResNum() + 1; mprintf(" (prev_res=%i, next_res=%i)\n", prev_res+1, next_res+1); Vec3 prev_crd(sFrame.XYZ(current_indices.front() - 1)); Vec3 next_crd(sFrame.XYZ(current_indices.back() + 1)); prev_crd.Print("prev_crd"); next_crd.Print("next_crd"); Vec3 crd_step = (next_crd - prev_crd) / (double)(current_indices.size()+1); crd_step.Print("crd_step"); double* xyz = sFrame.xAddress() + (current_indices.front() * 3); for (unsigned int i = 0; i != current_indices.size(); i++, xyz += 3) { prev_crd += crd_step; xyz[0] = prev_crd[0]; xyz[1] = prev_crd[1]; xyz[2] = prev_crd[2]; } current_indices.clear(); } } } //Topology* sTop = qref.Parm().partialModifyStateByMask( sMask ); //if (sTop == 0) return 1; //Frame sFrame(qref.Coord(), sMask); // Write output traj Trajout_Single trajout; if (trajout.PrepareTrajWrite(outfilename, argIn, &sTop, CoordinateInfo(), 1, fmt)) return 1; if (trajout.WriteSingle(0, sFrame)) return 1; trajout.EndTraj(); return 0; }
Exec::RetType Exec_CrdAction::DoCrdAction(CpptrajState& State, ArgList& actionargs, DataSet_Coords* CRD, Action* act, TrajFrameCounter const& frameCount) const { Timer total_time; total_time.Start(); # ifdef MPI ActionInit state(State.DSL(), State.DFL(), trajComm_); # else ActionInit state(State.DSL(), State.DFL()); # endif if ( act->Init( actionargs, state, State.Debug() ) != Action::OK ) return CpptrajState::ERR; actionargs.CheckForMoreArgs(); // Set up frame and parm for COORDS. ActionSetup originalSetup( CRD->TopPtr(), CRD->CoordsInfo(), CRD->Size() ); Frame originalFrame = CRD->AllocateFrame(); // Set up for this topology Action::RetType setup_ret = act->Setup( originalSetup ); if ( setup_ret == Action::ERR || setup_ret == Action::SKIP ) return CpptrajState::ERR; // If the topology was modified, we will need a new COORDS set. DataSet_Coords* crdOut = 0; if ( setup_ret == Action::MODIFY_TOPOLOGY ) { // This will not work for a TRJ set. switch ( CRD->Type() ) { case DataSet::TRAJ : mprinterr("Error: Cannot modify TRAJ data sets.\n"); break; case DataSet::COORDS : crdOut = (DataSet_Coords*)new DataSet_Coords_CRD(); break; case DataSet::REF_FRAME : crdOut = (DataSet_Coords*)new DataSet_Coords_REF(); break; default: crdOut = 0; // SANITY } if (crdOut == 0) return CpptrajState::ERR; mprintf("Info: crdaction: COORDS set '%s' will be modified by action '%s'\n", CRD->legend(), actionargs.Command()); if (frameCount.TotalReadFrames() != (int)CRD->Size()) mprintf("Info: crdaction: Previous size= %zu, new size is %i\n", CRD->Size(), frameCount.TotalReadFrames()); // Set up set, copy original metadata crdOut->SetMeta( CRD->Meta() ); if (crdOut->CoordsSetup( originalSetup.Top(), originalSetup.CoordInfo() )) return CpptrajState::ERR; DataSet::SizeArray mfArray(1, frameCount.TotalReadFrames()); if (crdOut->Allocate( mfArray )) return CpptrajState::ERR; } // Loop over all frames in COORDS. ProgressBar* progress = 0; if (State.ShowProgress()) progress = new ProgressBar( frameCount.TotalReadFrames() ); int set = 0; for (int frame = frameCount.Start(); frame < frameCount.Stop(); frame += frameCount.Offset(), ++set) { // Since Frame can be modified by actions, save original and use currentFrame ActionFrame frm( &originalFrame, set ); if (progress != 0) progress->Update( set ); CRD->GetFrame( frame, originalFrame ); Action::RetType ret = act->DoAction( set, frm ); if (ret == Action::ERR) { mprinterr("Error: crdaction: Frame %i, set %i\n", frame + 1, set + 1); break; } // Check if frame was modified. If so, update COORDS. if ( ret == Action::MODIFY_COORDS ) { if (crdOut != 0) crdOut->AddFrame( frm.Frm() ); else CRD->SetCRD( frame, frm.Frm() ); } } if (progress != 0) delete progress; # ifdef MPI act->SyncAction(); # endif // If topology was modified, replace old set with new. if ( setup_ret == Action::MODIFY_TOPOLOGY ) { mprintf("Info: crdaction: Topology for '%s' was modified by action '%s'\n", CRD->legend(), actionargs.Command()); State.DSL().RemoveSet( CRD ); State.DSL().AddSet( crdOut ); } act->Print(); State.MasterDataFileWrite(); total_time.Stop(); mprintf("TIME: Total action execution time: %.4f seconds.\n", total_time.Total()); return CpptrajState::OK; }
// Exec_PermuteDihedrals::Execute() Exec::RetType Exec_PermuteDihedrals::Execute(CpptrajState& State, ArgList& argIn) { debug_ = State.Debug(); mode_ = INTERVAL; // Get Keywords - first determine mode if (argIn.hasKey("random")) mode_ = RANDOM; else if (argIn.hasKey("interval")) mode_ = INTERVAL; // Get input COORDS set std::string setname = argIn.GetStringKey("crdset"); if (setname.empty()) { mprinterr("Error: Specify COORDS dataset name with 'crdset'.\n"); return CpptrajState::ERR; } DataSet_Coords* CRD = (DataSet_Coords*)State.DSL().FindCoordsSet( setname ); if (CRD == 0) { mprinterr("Error: Could not find COORDS set '%s'\n", setname.c_str()); return CpptrajState::ERR; } mprintf(" PERMUTEDIHEDRALS: Using COORDS '%s'\n", CRD->legend()); // Get residue range Range resRange; resRange.SetRange(argIn.GetStringKey("resrange")); if (!resRange.Empty()) resRange.ShiftBy(-1); // User res args start from 1 mprintf("\tPermutating dihedrals in"); if (resRange.Empty()) mprintf(" all solute residues.\n"); else mprintf(" residue range [%s]\n", resRange.RangeArg()); // Determine which angles to search for DihedralSearch dihSearch; dihSearch.SearchForArgs(argIn); // If nothing is enabled, enable all dihSearch.SearchForAll(); mprintf("\tSearching for types:"); dihSearch.PrintTypes(); mprintf("\n"); // Setup output trajectory outframe_ = 0; std::string outfilename = argIn.GetStringKey("outtraj"); if (!outfilename.empty()) { mprintf("\tCoordinates output to '%s'\n", outfilename.c_str()); Topology* outtop = State.DSL().GetTopology( argIn ); if (outtop == 0) { mprinterr("Error: No topology for output traj.\n"); return CpptrajState::ERR; } // Setup output trajectory FIXME: Correct frames for # of rotations if (outtraj_.PrepareTrajWrite(outfilename, argIn, CRD->TopPtr(), CRD->CoordsInfo(), CRD->Size(), TrajectoryFile::UNKNOWN_TRAJ)) return CpptrajState::ERR; } // Setup output coords outfilename = argIn.GetStringKey("crdout"); if (!outfilename.empty()) { mprintf("\tCoordinates saved to set '%s'\n", outfilename.c_str()); crdout_ = (DataSet_Coords_CRD*)State.DSL().AddSet(DataSet::COORDS, outfilename); if (crdout_ == 0) return CpptrajState::ERR; crdout_->CoordsSetup( CRD->Top(), CRD->CoordsInfo() ); } // Get specific mode options. double interval_in_deg = 60.0; if ( mode_ == INTERVAL ) { interval_in_deg = argIn.getNextDouble(60.0); mprintf("\tDihedrals will be rotated at intervals of %.2f degrees.\n", interval_in_deg); } else if (mode_ == RANDOM) { check_for_clashes_ = argIn.hasKey("check"); checkAllResidues_ = argIn.hasKey("checkallresidues"); cutoff_ = argIn.getKeyDouble("cutoff",0.8); rescutoff_ = argIn.getKeyDouble("rescutoff",10.0); backtrack_ = argIn.getKeyInt("backtrack",4); increment_ = argIn.getKeyInt("increment",1); max_factor_ = argIn.getKeyInt("maxfactor",2); int iseed = argIn.getKeyInt("rseed",-1); // Output file for # of problems DataFile* problemFile = State.DFL().AddDataFile(argIn.GetStringKey("out"), argIn); // Dataset to store number of problems number_of_problems_ = State.DSL().AddSet(DataSet::INTEGER, argIn.GetStringNext(),"Nprob"); if (number_of_problems_==0) return CpptrajState::ERR; // Add dataset to data file list if (problemFile != 0) problemFile->AddDataSet(number_of_problems_); // Check validity of args if (cutoff_ < Constants::SMALL) { mprinterr("Error: cutoff too small.\n"); return CpptrajState::ERR; } if (rescutoff_ < Constants::SMALL) { mprinterr("Error: rescutoff too small.\n"); return CpptrajState::ERR; } if (backtrack_ < 0) { mprinterr("Error: backtrack value must be >= 0\n"); return CpptrajState::ERR; } if ( increment_<1 || (360 % increment_)!=0 ) { mprinterr("Error: increment must be a factor of 360.\n"); return CpptrajState::ERR; } // Calculate max increment max_increment_ = 360 / increment_; // Seed random number gen RN_.rn_set( iseed ); // Print info mprintf("\tDihedrals will be rotated to random values.\n"); if (iseed==-1) mprintf("\tRandom number generator will be seeded using time.\n"); else mprintf("\tRandom number generator will be seeded using %i\n",iseed); if (check_for_clashes_) { mprintf("\tWill attempt to recover from bad steric clashes.\n"); if (checkAllResidues_) mprintf("\tAll residues will be checked.\n"); else mprintf("\tResidues up to the currenly rotating dihedral will be checked.\n"); mprintf("\tAtom cutoff %.2f, residue cutoff %.2f, backtrack = %i\n", cutoff_, rescutoff_, backtrack_); mprintf("\tWhen clashes occur dihedral will be incremented by %i\n",increment_); mprintf("\tMax # attempted rotations = %i times number dihedrals.\n", max_factor_); } // Square cutoffs to compare to dist^2 instead of dist cutoff_ *= cutoff_; rescutoff_ *= rescutoff_; // Increment backtrack by 1 since we need to skip over current res ++backtrack_; // Initialize CheckStructure if (checkStructure_.SetOptions( false, false, false, State.Debug(), "*", "", 0.8, 1.15, 4.0 )) { mprinterr("Error: Could not set up structure check.\n"); return CpptrajState::ERR; } // Set up CheckStructure for this parm (false = nobondcheck) if (checkStructure_.Setup(CRD->Top(), CRD->CoordsInfo().TrajBox())) return CpptrajState::ERR; } // Determine from selected mask atoms which dihedrals will be rotated. PermuteDihedralsType dst; // If range is empty (i.e. no resrange arg given) look through all // solute residues. Range actualRange; if (resRange.Empty()) actualRange = CRD->Top().SoluteResidues(); else actualRange = resRange; // Search for dihedrals if (dihSearch.FindDihedrals(CRD->Top(), actualRange)) return CpptrajState::ERR; // For each found dihedral, set up mask of atoms that will move upon // rotation. Also set up mask of atoms in this residue that will not // move, including atom2. if (debug_>0) mprintf("DEBUG: Dihedrals:\n"); for (DihedralSearch::mask_it dih = dihSearch.begin(); dih != dihSearch.end(); ++dih) { dst.checkAtoms.clear(); // Set mask of atoms that will move during dihedral rotation. dst.Rmask = DihedralSearch::MovingAtoms(CRD->Top(), dih->A1(), dih->A2()); // If randomly rotating angles, check for atoms that are in the same // residue as A1 but will not move. They need to be checked for clashes // since further rotations will not help them. if (mode_ == RANDOM && check_for_clashes_) { CharMask cMask( dst.Rmask.ConvertToCharMask(), dst.Rmask.Nselected() ); int a1res = CRD->Top()[dih->A1()].ResNum(); for (int maskatom = CRD->Top().Res(a1res).FirstAtom(); maskatom < CRD->Top().Res(a1res).LastAtom(); ++maskatom) if (!cMask.AtomInCharMask(maskatom)) dst.checkAtoms.push_back( maskatom ); dst.checkAtoms.push_back(dih->A1()); // TODO: Does this need to be added first? // Since only the second atom and atoms it is bonded to move during // rotation, base the check on the residue of the second atom. dst.resnum = a1res; } dst.atom0 = dih->A0(); // FIXME: This duplicates info dst.atom1 = dih->A1(); dst.atom2 = dih->A2(); dst.atom3 = dih->A3(); BB_dihedrals_.push_back(dst); // DEBUG: List dihedral info. if (debug_ > 0) { mprintf("\t%s-%s-%s-%s\n", CRD->Top().TruncResAtomName(dih->A0()).c_str(), CRD->Top().TruncResAtomName(dih->A1()).c_str(), CRD->Top().TruncResAtomName(dih->A2()).c_str(), CRD->Top().TruncResAtomName(dih->A3()).c_str() ); if (debug_ > 1 && mode_ == RANDOM && check_for_clashes_) { mprintf("\t\tCheckAtoms="); for (std::vector<int>::const_iterator ca = dst.checkAtoms.begin(); ca != dst.checkAtoms.end(); ++ca) mprintf(" %i", *ca + 1); mprintf("\n"); } if (debug_ > 2) { mprintf("\t\t"); dst.Rmask.PrintMaskAtoms("Rmask:"); } } } // Set up simple structure check. First step is coarse; check distances // between a certain atom in each residue (first, COM, CA, some other atom?) // to see if residues are in each others neighborhood. Second step is to // check the atoms in each close residue. if (check_for_clashes_) { ResidueCheckType rct; int res = 0; for (Topology::res_iterator residue = CRD->Top().ResStart(); residue != CRD->Top().ResEnd(); ++residue) { rct.resnum = res++; rct.start = residue->FirstAtom(); rct.stop = residue->LastAtom(); rct.checkatom = rct.start; ResCheck_.push_back(rct); } } // Perform dihedral permute Frame currentFrame = CRD->AllocateFrame(); for (unsigned int set = 0; set != CRD->Size(); set++) { CRD->GetFrame(set, currentFrame); int n_problems = 0; switch (mode_) { case RANDOM: RandomizeAngles(currentFrame, CRD->Top()); // Check the resulting structure n_problems = checkStructure_.CheckOverlaps( currentFrame ); //mprintf("%i\tResulting structure has %i problems.\n",frameNum,n_problems); number_of_problems_->Add(set, &n_problems); if (outtraj_.IsInitialized()) outtraj_.WriteSingle(outframe_++, currentFrame); if (crdout_ != 0) crdout_->AddFrame( currentFrame ); break; case INTERVAL: IntervalAngles(currentFrame, CRD->Top(), interval_in_deg); break; } } if (outtraj_.IsInitialized()) outtraj_.EndTraj(); return CpptrajState::OK; }
// Exec_ParallelAnalysis::Execute() Exec::RetType Exec_ParallelAnalysis::Execute(CpptrajState& State, ArgList& argIn) { Timer t_total; t_total.Start(); Timer t_sync; bool syncToMaster = argIn.hasKey("sync"); std::vector<unsigned int> setSizesBefore; if (syncToMaster) { t_sync.Start(); setSizesBefore.reserve( State.DSL().size() ); for (DataSetList::const_iterator it = State.DSL().begin(); it != State.DSL().end(); ++it) setSizesBefore.push_back( (*it)->Size() ); t_sync.Stop(); } // DEBUG - Have each thread report what analyses it knows about and what // data sets it has. /* for (int rank = 0; rank < Parallel::World().Size(); rank++) { if (rank == Parallel::World().Rank()) { printf("Rank %i, %u analyses, %zu data sets:\n", rank, State.Analyses().size(), State.DSL().size()); for (DataSetList::const_iterator it = State.DSL().begin(); it != State.DSL().end(); ++it) printf("\t'%s' (%zu)\n", (*it)->Meta().PrintName().c_str(), (*it)->Size()); } Parallel::World().Barrier(); } Parallel::World().Barrier(); */ mprintf(" PARALLELANALYSIS: Will attempt to run current Analyses in parallel.\n\n" "*** THIS COMMAND IS STILL EXPERIMENTAL! ***\n\n"); if (syncToMaster) mprintf("\tResulting data sets will be synced back to master.\n"); // Naively divide up all analyses among threads. int my_start, my_stop; int nelts = Parallel::World().DivideAmongProcesses( my_start, my_stop, State.Analyses().size() ); rprintf("Dividing %zu analyses among %i threads: %i to %i (%i)\n", State.Analyses().size(), Parallel::World().Size(), my_start, my_stop, nelts); // Each thread runs the analyses they are responsible for. int nerr = 0; for (int na = my_start; na != my_stop; na++) { // TODO check setup status if (State.Analyses().Ana(na).Analyze() != Analysis::OK) { rprinterr("Error: Analysis failed: '%s'\n", State.Analyses().Args(na).ArgLine()); nerr++; } } // This error check serves as a barrier if (Parallel::World().CheckError( nerr )) return CpptrajState::ERR; State.DFL().AllThreads_WriteAllDF(); State.Analyses().Clear(); if (syncToMaster) { t_sync.Start(); // Check which sizes have changed. if (setSizesBefore.size() != State.DSL().size()) { mprintf("Warning: Number of sets have changed. Not attempting to sync sets to master.\n"); } else { for (unsigned int idx = 0; idx != State.DSL().size(); idx++) { int setHasChanged = 0; if (!Parallel::World().Master()) { if (setSizesBefore[idx] != State.DSL()[idx]->Size()) { if (State.Debug() > 0) rprintf("Set '%s' size has changed from %u to %zu\n", State.DSL()[idx]->legend(), setSizesBefore[idx], State.DSL()[idx]->Size()); setHasChanged = 1; } } int totalChanged; Parallel::World().AllReduce(&totalChanged, &setHasChanged, 1, MPI_INT, MPI_SUM); if (totalChanged > 0) { if (totalChanged == 1) { int sourceRank = 0; if (setHasChanged == 1) setHasChanged = Parallel::World().Rank(); Parallel::World().ReduceMaster(&sourceRank, &setHasChanged, 1, MPI_INT, MPI_SUM); if (State.Debug() > 0) mprintf("DEBUG: Need to sync '%s' from %i\n", State.DSL()[idx]->legend(), sourceRank); if (Parallel::World().Master()) State.DSL()[idx]->RecvSet( sourceRank, Parallel::World() ); else if (setHasChanged == Parallel::World().Rank()) State.DSL()[idx]->SendSet( 0, Parallel::World() ); } else mprintf("Warning: '%s' exists on multiple threads. Not syncing.\n", State.DSL()[idx]->legend()); } } } t_sync.Stop(); } t_total.Stop(); if (syncToMaster) t_sync.WriteTiming(2, "Sync:", t_total.Total()); t_total.WriteTiming(1, "Total:"); return CpptrajState::OK; }
// Exec_DataSetCmd::ModifyPoints() Exec::RetType Exec_DataSetCmd::ModifyPoints(CpptrajState& State, ArgList& argIn, bool drop) { const char* mode; if (drop) mode = "Drop"; else mode = "Kee"; // Keywords std::string name = argIn.GetStringKey("name"); int start = argIn.getKeyInt("start", 0) - 1; int stop = argIn.getKeyInt("stop", -1); int offset = argIn.getKeyInt("offset", -1); Range points; if (start < 0 && stop < 0 && offset < 0) { std::string rangearg = argIn.GetStringKey("range"); if (rangearg.empty()) { mprinterr("Error: Must specify range or start/stop/offset.\n"); return CpptrajState::ERR; } points.SetRange( rangearg ); if (points.Empty()) { mprinterr("Error: Range '%s' is empty.\n", rangearg.c_str()); return CpptrajState::ERR; } mprintf("\t%sping points in range %s\n", mode, rangearg.c_str()); // User args start from 1 points.ShiftBy(-1); } // Get data set to drop/keep points from // Loop over all DataSet arguments std::string ds_arg = argIn.GetStringNext(); while (!ds_arg.empty()) { DataSetList dsl = State.DSL().GetMultipleSets( ds_arg ); for (DataSetList::const_iterator it = dsl.begin(); it != dsl.end(); ++it) { DataSet* DS = *it; if (DS->Size() < 1) { mprinterr("Error: Set '%s' is empty.\n", DS->legend()); return CpptrajState::ERR; } // Restrict to 1D sets for now TODO more types if (DS->Group() != DataSet::SCALAR_1D) { mprinterr("Error: Currently only works for 1D scalar data sets.\n"); return CpptrajState::ERR; } DataSet_1D* ds1 = (DataSet_1D*)DS; // Output data set DataSet* out = 0; if (name.empty()) { // Modifying this set. Create new temporary set. out = State.DSL().Allocate( ds1->Type() ); if (out == 0) return CpptrajState::ERR; *out = *ds1; mprintf("\tOverwriting set '%s'\n", ds1->legend()); } else { // Write to new set MetaData md = ds1->Meta(); md.SetName( name ); out = State.DSL().AddSet(ds1->Type(), md); if (out == 0) return CpptrajState::ERR; mprintf("\tNew set is '%s'\n", out->Meta().PrintName().c_str()); } out->Allocate(DataSet::SizeArray(1, ds1->Size())); if (points.Empty()) { // Drop by start/stop/offset. Set defaults if needed if (start < 0) start = 0; if (stop < 0) stop = ds1->Size(); if (offset < 0) offset = 1; mprintf("\t%sping points from %i to %i, step %i\n", mode, start+1, stop, offset); for (int idx = start; idx < stop; idx += offset) points.AddToRange( idx ); } // TODO check that range values are valid? if (State.Debug() > 0) mprintf("DEBUG: Keeping points:"); Range::const_iterator pt = points.begin(); int idx = 0; int odx = 0; if (drop) { // Drop points for (; idx < (int)ds1->Size(); idx++) { if (pt == points.end()) break; if (*pt != idx) { if (State.Debug() > 0) mprintf(" %i", idx + 1); KeepPoint(ds1, out, idx, odx); } else ++pt; } // Keep all remaining points for (; idx < (int)ds1->Size(); idx++) { if (State.Debug() > 0) mprintf(" %i", idx + 1); KeepPoint(ds1, out, idx, odx); } } else { // Keep points for (; pt != points.end(); pt++) { if (*pt >= (int)ds1->Size()) break; if (State.Debug() > 0) mprintf(" %i", *pt + 1); KeepPoint(ds1, out, *pt, odx); } } if (State.Debug() > 0) mprintf("\n"); if (name.empty()) { // Replace old set with new set State.DSL().RemoveSet( ds1 ); State.DSL().AddSet( out ); } } // END loop over sets ds_arg = argIn.GetStringNext(); } // END loop over set args return CpptrajState::OK; }