Exec::RetType Exec_Precision::Execute(CpptrajState& State, ArgList& argIn) { // Next string is DataSet(s)/DataFile that command pertains to. std::string name1 = argIn.GetStringNext(); if (name1.empty()) { mprinterr("Error: No filename/setname given.\n"); return CpptrajState::ERR; } // This will break if dataset name starts with a digit... int width = argIn.getNextInteger(12); if (width < 1) { mprintf("Error: Cannot set width < 1 (%i).\n", width); return CpptrajState::ERR; } int precision = argIn.getNextInteger(4); if (precision < 0) precision = 0; DataFile* df = State.DFL().GetDataFile(name1); if (df != 0) { mprintf("\tSetting precision for all sets in %s to %i.%i\n", df->DataFilename().base(), width, precision); df->SetDataFilePrecision(width, precision); } else { State.DSL().SetPrecisionOfDataSets( name1, width, precision ); } return CpptrajState::OK; }
// Exec_DataSetCmd::Make2D() Exec::RetType Exec_DataSetCmd::Make2D(CpptrajState& State, ArgList& argIn) { std::string name = argIn.GetStringKey("name"); int ncols = argIn.getKeyInt("ncols", 0); int nrows = argIn.getKeyInt("nrows", 0); if (ncols <= 0 || nrows <= 0) { mprinterr("Error: Must specify both ncols and nrows\n"); return CpptrajState::ERR; } DataSet* ds1 = State.DSL().GetDataSet( argIn.GetStringNext() ); if (ds1 == 0) return CpptrajState::ERR; if (ds1->Ndim() != 1) { mprinterr("Error: make2d only works for 1D data sets.\n"); return CpptrajState::ERR; } if (nrows * ncols != (int)ds1->Size()) { mprinterr("Error: Size of '%s' (%zu) != nrows X ncols.\n", ds1->legend(), ds1->Size()); return CpptrajState::ERR; } if (name.empty()) name = State.DSL().GenerateDefaultName("make2d"); MetaData md(name, MetaData::M_MATRIX); DataSet* ds3 = State.DSL().AddSet( DataSet::MATRIX_DBL, md ); if (ds3 == 0) return CpptrajState::ERR; mprintf("\tConverting values from 1D set '%s' to 2D matrix '%s' with %i cols, %i rows.\n", ds1->legend(), ds3->legend(), ncols, nrows); DataSet_1D const& data = static_cast<DataSet_1D const&>( *ds1 ); DataSet_MatrixDbl& matrix = static_cast<DataSet_MatrixDbl&>( *ds3 ); if (matrix.Allocate2D( ncols, nrows )) return CpptrajState::ERR; for (unsigned int idx = 0; idx != data.Size(); idx++) matrix.AddElement( data.Dval(idx) ); return CpptrajState::OK; }
// Exec_DataSetCmd::MakeXY() Exec::RetType Exec_DataSetCmd::MakeXY(CpptrajState& State, ArgList& argIn) { std::string name = argIn.GetStringKey("name"); DataSet* ds1 = State.DSL().GetDataSet( argIn.GetStringNext() ); DataSet* ds2 = State.DSL().GetDataSet( argIn.GetStringNext() ); if (ds1 == 0 || ds2 == 0) return CpptrajState::ERR; if (ds1->Ndim() != 1 || ds2->Ndim() != 1) { mprinterr("Error: makexy only works for 1D data sets.\n"); return CpptrajState::ERR; } DataSet* ds3 = State.DSL().AddSet( DataSet::XYMESH, name, "XY" ); if (ds3 == 0) return CpptrajState::ERR; mprintf("\tUsing values from '%s' as X, values from '%s' as Y, output set '%s'\n", ds1->legend(), ds2->legend(), ds3->legend()); DataSet_1D const& ds_x = static_cast<DataSet_1D const&>( *ds1 ); DataSet_1D const& ds_y = static_cast<DataSet_1D const&>( *ds2 ); DataSet_1D& out = static_cast<DataSet_1D&>( *ds3 ); size_t nframes = std::min( ds_x.Size(), ds_y.Size() ); if (ds_x.Size() != ds_y.Size()) mprintf("Warning: Data sets do not have equal sizes, only using %zu frames.\n", nframes); double XY[2]; for (size_t i = 0; i != nframes; i++) { XY[0] = ds_x.Dval(i); XY[1] = ds_y.Dval(i); out.Add( i, XY ); } return CpptrajState::OK; }
// Exec_CrdAction::ProcessArgs() Exec::RetType Exec_CrdAction::ProcessArgs(CpptrajState& State, ArgList& argIn) { std::string setname = argIn.GetStringNext(); if (setname.empty()) { mprinterr("Error: %s: Specify COORDS dataset name.\n", argIn.Command()); return CpptrajState::ERR; } DataSet_Coords* CRD = (DataSet_Coords*)State.DSL().FindCoordsSet( setname ); if (CRD == 0) { mprinterr("Error: %s: No COORDS set with name %s found.\n", argIn.Command(), setname.c_str()); return CpptrajState::ERR; } mprintf("\tUsing set '%s'\n", CRD->legend()); // Start, stop, offset TrajFrameCounter frameCount; ArgList crdarg( argIn.GetStringKey("crdframes"), "," ); if (frameCount.CheckFrameArgs( CRD->Size(), crdarg )) return CpptrajState::ERR; frameCount.PrintInfoLine(CRD->legend()); ArgList actionargs = argIn.RemainingArgs(); actionargs.MarkArg(0); Cmd const& cmd = Command::SearchTokenType( DispatchObject::ACTION, actionargs.Command() ); if ( cmd.Empty() ) return CpptrajState::ERR; Action* act = (Action*)cmd.Alloc(); if (act == 0) return CpptrajState::ERR; CpptrajState::RetType err = DoCrdAction(State, actionargs, CRD, act, frameCount); delete act; return err; }
// Exec_DataSetCmd::ChangeOutputFormat() Exec::RetType Exec_DataSetCmd::ChangeOutputFormat(CpptrajState const& State, ArgList& argIn) { TextFormat::FmtType fmt; if (argIn.hasKey("double")) fmt = TextFormat::DOUBLE; else if (argIn.hasKey("scientific")) fmt = TextFormat::SCIENTIFIC; else if (argIn.hasKey("general")) fmt = TextFormat::GDOUBLE; else { mprinterr("Error: Expected either 'double', 'scientific', or 'general'\n"); return CpptrajState::ERR; } // 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 ds = dsl.begin(); ds != dsl.end(); ++ds) if ((*ds)->SetupFormat().SetFormatType(fmt)) mprintf("\tSet '%s' output format changed to '%s'\n", (*ds)->legend(), TextFormat::typeDescription(fmt)); ds_arg = argIn.GetStringNext(); } return CpptrajState::OK; }
Exec::RetType Exec_ParmBox::Execute(CpptrajState& State, ArgList& argIn) { Box pbox; bool nobox = false; if ( argIn.hasKey("nobox") ) nobox = true; else { pbox.SetX( argIn.getKeyDouble("x",0) ); pbox.SetY( argIn.getKeyDouble("y",0) ); pbox.SetZ( argIn.getKeyDouble("z",0) ); pbox.SetAlpha( argIn.getKeyDouble("alpha",0) ); pbox.SetBeta( argIn.getKeyDouble("beta",0) ); pbox.SetGamma( argIn.getKeyDouble("gamma",0) ); } Topology* parm = State.DSL().GetTopByIndex( argIn ); if (parm == 0) return CpptrajState::ERR; if (nobox) mprintf("\tRemoving box information from parm %i:%s\n", parm->Pindex(), parm->c_str()); else // Fill in missing parm box information from specified parm pbox.SetMissingInfo( parm->ParmBox() ); if (argIn.hasKey("truncoct")) pbox.SetTruncOct(); parm->SetParmBox( pbox ); parm->ParmBox().PrintInfo(); return CpptrajState::OK; }
Exec::RetType Exec_ParmStrip::Execute(CpptrajState& State, ArgList& argIn) { Topology* parm = State.DSL().GetTopByIndex( argIn ); if (parm == 0) return CpptrajState::ERR; // Check if this topology has already been used to set up an input // trajectory, as this will break the traj read. bool topology_in_use = false; const char* fname = 0; for (TrajinList::trajin_it tIn = State.InputTrajList().trajin_begin(); tIn != State.InputTrajList().trajin_end(); ++tIn) if ( (*tIn)->Traj().Parm() == parm ) { topology_in_use = true; fname = (*tIn)->Traj().Filename().full(); break; } if (!topology_in_use) { for (TrajinList::ensemble_it eIn = State.InputTrajList().ensemble_begin(); eIn != State.InputTrajList().ensemble_end(); ++eIn) if ( (*eIn)->Traj().Parm() == parm ) { topology_in_use = true; fname = (*eIn)->Traj().Filename().full(); break; } } if (topology_in_use) { mprinterr("Error: Topology '%s' has already been used to set up trajectory '%s'.\n" "Error: To strip this topology use the 'strip' action.\n", parm->c_str(), fname); return CpptrajState::ERR; } AtomMask tempMask( argIn.GetMaskNext() ); // Since want to keep atoms outside mask, invert selection tempMask.InvertMaskExpression(); if (parm->SetupIntegerMask( tempMask )) return CpptrajState::ERR; mprintf("\tStripping atoms in mask [%s] (%i) from %s\n",tempMask.MaskString(), parm->Natom() - tempMask.Nselected(), parm->c_str()); Topology* tempParm = parm->modifyStateByMask(tempMask); if (tempParm==0) { mprinterr("Error: %s: Could not strip parm.\n", argIn.Command()); return CpptrajState::ERR; } else { // Replace parm with stripped version *parm = *tempParm; parm->Brief("Stripped parm:"); delete tempParm; } 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; }
// Exec_DataSetCmd::VectorCoord() Exec::RetType Exec_DataSetCmd::VectorCoord(CpptrajState& State, ArgList& argIn) { // Keywords std::string name = argIn.GetStringKey("name"); int idx; if (argIn.hasKey("X")) idx = 0; else if (argIn.hasKey("Y")) idx = 1; else if (argIn.hasKey("Z")) idx = 2; else { mprinterr("Error: 'vectorcoord' requires specifying X, Y, or Z.\n"); return CpptrajState::ERR; } // Data set DataSet* ds1 = State.DSL().GetDataSet( argIn.GetStringNext() ); if (ds1 == 0) return CpptrajState::ERR; if (ds1->Type() != DataSet::VECTOR) { mprinterr("Error: 'vectorcoord' only works with vector data sets.\n"); return CpptrajState::ERR; } if (ds1->Size() < 1) { mprinterr("Error: '%s' is empty.\n", ds1->legend()); return CpptrajState::ERR; } // Create output set. static const char* XYZ[3] = { "X", "Y", "Z" }; DataSet* out = State.DSL().AddSet( DataSet::DOUBLE, name, "COORD"); if (out == 0) return CpptrajState::ERR; // Extract data mprintf("\tExtracting %s coordinate from vector %s to %s\n", XYZ[idx], ds1->legend(), out->Meta().PrintName().c_str()); DataSet_Vector const& vec = static_cast<DataSet_Vector const&>( *ds1 ); for (unsigned int n = 0; n != vec.Size(); n++) { double d = vec.VXYZ(n)[idx]; out->Add( n, &d ); } return CpptrajState::OK; }
Exec::RetType Exec_ReadData::Execute(CpptrajState& State, ArgList& argIn) { DataFile dataIn; dataIn.SetDebug( State.DFL().Debug() ); std::string filenameIn = argIn.GetStringNext(); File::NameArray fnames = File::ExpandToFilenames( filenameIn ); if (fnames.empty()) { mprinterr("Error: '%s' matches no files.\n", filenameIn.c_str()); return CpptrajState::ERR; } int err = 0; int idx = -1; bool useIndex = argIn.hasKey("separate"); for (File::NameArray::const_iterator fn = fnames.begin(); fn != fnames.end(); ++fn) { if (useIndex) idx++; if (dataIn.ReadDataIn( *fn, argIn, State.DSL(), idx, fnames.size() )!=0) { mprinterr("Error: Could not read data file '%s'.\n", fn->full()); err++; } } if (err > 0) return CpptrajState::ERR; return CpptrajState::OK; }
// Exec_DataSetCmd::Concatenate() Exec::RetType Exec_DataSetCmd::Concatenate(CpptrajState& State, ArgList& argIn) { std::string name = argIn.GetStringKey("name"); bool use_offset = !argIn.hasKey("nooffset"); DataSet* ds3 = State.DSL().AddSet( DataSet::XYMESH, name, "CAT" ); if (ds3 == 0) return CpptrajState::ERR; DataSet_1D& out = static_cast<DataSet_1D&>( *ds3 ); mprintf("\tConcatenating sets into '%s'\n", out.legend()); if (use_offset) mprintf("\tX values will be offset.\n"); else mprintf("\tX values will not be offset.\n"); std::string dsarg = argIn.GetStringNext(); double offset = 0.0; while (!dsarg.empty()) { DataSetList dsl = State.DSL().GetMultipleSets( dsarg ); double XY[2]; for (DataSetList::const_iterator ds = dsl.begin(); ds != dsl.end(); ++ds) { if ( (*ds)->Group() != DataSet::SCALAR_1D ) { mprintf("Warning: '%s': Concatenation only supported for 1D scalar data sets.\n", (*ds)->legend()); } else { DataSet_1D const& set = static_cast<DataSet_1D const&>( *(*ds) ); mprintf("\t\t'%s'\n", set.legend()); for (size_t i = 0; i != set.Size(); i++) { XY[0] = set.Xcrd( i ) + offset; XY[1] = set.Dval( i ); out.Add( i, XY ); // NOTE: value of i does not matter for mesh } if (use_offset) offset = XY[0]; } } dsarg = argIn.GetStringNext(); } return CpptrajState::OK; }
Exec::RetType Exec_ParmSolvent::Execute(CpptrajState& State, ArgList& argIn) { std::string maskexpr; if (!argIn.hasKey("none")) { maskexpr = argIn.GetMaskNext(); if ( maskexpr.empty() ) { mprinterr("Error: solvent: No mask specified.\n"); return CpptrajState::ERR; } } // Get parm index Topology* parm = State.DSL().GetTopByIndex( argIn ); if (parm == 0) return CpptrajState::ERR; parm->SetSolvent( maskexpr ); return CpptrajState::OK; }
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_DataSetCmd::Execute() Exec::RetType Exec_DataSetCmd::Execute(CpptrajState& State, ArgList& argIn) { RetType err = CpptrajState::OK; if (argIn.Contains("legend")) { // Set legend for one data set std::string legend = argIn.GetStringKey("legend"); DataSet* ds = State.DSL().GetDataSet( argIn.GetStringNext() ); if (ds == 0) return CpptrajState::ERR; mprintf("\tChanging legend '%s' to '%s'\n", ds->legend(), legend.c_str()); ds->SetLegend( legend ); // --------------------------------------------- } else if (argIn.hasKey("outformat")) { // Change double precision set output format err = ChangeOutputFormat(State, argIn); // --------------------------------------------- } else if (argIn.hasKey("remove")) { // Remove data sets by various criteria err = Remove(State, argIn); // --------------------------------------------- } else if (argIn.hasKey("makexy")) { // Combine values from two sets into 1 err = MakeXY(State, argIn); // --------------------------------------------- } else if (argIn.hasKey("make2d")) { // Create 2D matrix from 1D set err = Make2D(State, argIn); // --------------------------------------------- } else if (argIn.hasKey("vectorcoord")) { // Extract vector X/Y/Z coord as new set err = VectorCoord(State, argIn); // --------------------------------------------- } else if (argIn.hasKey("filter")) { // Filter points in data set to make new data set err = Filter(State, argIn); // --------------------------------------------- } else if (argIn.hasKey("cat")) { // Concatenate two or more data sets err = Concatenate(State, argIn); // --------------------------------------------- } else if (argIn.hasKey("droppoints")) { // Drop points from set err = ModifyPoints(State, argIn, true); // --------------------------------------------- } else if (argIn.hasKey("keeppoints")) { // Keep points in set err = ModifyPoints(State, argIn, false); // --------------------------------------------- } else if (argIn.hasKey("dim")) { // Modify dimension of set(s) err = ChangeDim(State, argIn); // --------------------------------------------- } else if (argIn.hasKey("invert")) { // Invert set(s) X/Y, create new sets err = InvertSets(State, argIn); // --------------------------------------------- } else { // Default: change mode/type for one or more sets. err = ChangeModeType(State, argIn); } return err; }
// Exec_Analyze::Execute() Exec::RetType Exec_Analyze::Execute(CpptrajState& State, ArgList& argIn) { // Remove 'analyze' ArgList arg = argIn; arg.RemoveFirstArg(); if (arg.empty()) { mprinterr("Error: No analysis command specified.\n"); return CpptrajState::ERR; } mprintf("Warning: The 'analyze' prefix is no longer necessary and may be soon deprecated.\n"); if (arg.CommandIs("matrix")) mprintf("Warning: NOTE: 'analyze matrix' is now 'diagmatrix'.\n"); else mprintf("Warning: To add an analysis command the the queue, only the command name needs\n" "Warning: to be specified, e.g. '%s <args>'.\n", arg.Command()); Cmd const& cmd = Command::SearchTokenType(DispatchObject::ANALYSIS, arg.Command()); if (cmd.Empty()) { mprinterr("Error: Analysis command '%s' not found.\n", arg.Command()); return CpptrajState::ERR; } return State.AddToAnalysisQueue( (Analysis*)cmd.Alloc(), arg ); }
Exec::RetType Exec_LoadTraj::Execute(CpptrajState& State, ArgList& argIn) { // Get Keywords std::string setname = argIn.GetStringKey("name"); if (setname.empty()) { mprinterr("Error: Must provide data set name ('name <setname>')\n"); return CpptrajState::ERR; } DataSet_Coords_TRJ* trj = (DataSet_Coords_TRJ*) State.DSL().FindSetOfType(setname, DataSet::TRAJ); if (trj == 0) trj = (DataSet_Coords_TRJ*) State.DSL().AddSet(DataSet::TRAJ, setname, "__DTRJ__"); if (trj == 0) { mprinterr("Error: Could not set up TRAJ data set.\n"); return CpptrajState::ERR; } std::string trajname = argIn.GetStringNext(); if (trajname.empty()) { // Add all existing input trajectories if (State.InputTrajList().empty()) { mprinterr("Error: No input trajectories loaded.\n"); return CpptrajState::ERR; } if (State.InputTrajList().Mode() != TrajinList::NORMAL) { mprinterr("Error: Cannot convert ensemble input trajectories to data.\n"); return CpptrajState::ERR; } mprintf("\tSaving currently loaded input trajectories as data set with name '%s'\n", setname.c_str()); for (TrajinList::trajin_it Trajin = State.InputTrajList().trajin_begin(); Trajin != State.InputTrajList().trajin_end(); ++Trajin) if (trj->AddInputTraj( *Trajin )) return CpptrajState::ERR; // TODO: Clear input trajectories from trajinList? } else { // Add the named trajectory if (trj->AddSingleTrajin( trajname, argIn, State.DSL().GetTopology(argIn) )) return CpptrajState::ERR; } return CpptrajState::OK; }
/** Set up variable with value. In this case allow any amount of whitespace, * so re-tokenize the original argument line (minus the command). */ CpptrajState::RetType Control_Set::SetupControl(CpptrajState& State, ArgList& argIn, Varray& CurrentVars) { ArgList remaining = argIn.RemainingArgs(); size_t pos0 = remaining.ArgLineStr().find_first_of("="); if (pos0 == std::string::npos) { mprinterr("Error: Expected <var>=<value>\n"); return CpptrajState::ERR; } size_t pos1 = pos0; bool append = false; if (pos0 > 0 && remaining.ArgLineStr()[pos0-1] == '+') { pos0--; append = true; } std::string variable = NoWhitespace( remaining.ArgLineStr().substr(0, pos0) ); if (variable.empty()) { mprinterr("Error: No variable name.\n"); return CpptrajState::ERR; } ArgList equals( NoLeadingWhitespace(remaining.ArgLineStr().substr(pos1+1)) ); std::string value; if (equals.Contains("inmask")) { AtomMask mask( equals.GetStringKey("inmask") ); Topology* top = State.DSL().GetTopByIndex( equals ); if (top == 0) return CpptrajState::ERR; if (top->SetupIntegerMask( mask )) return CpptrajState::ERR; if (equals.hasKey("atoms")) value = integerToString( mask.Nselected() ); else if (equals.hasKey("residues")) { int curRes = -1; int nres = 0; for (AtomMask::const_iterator at = mask.begin(); at != mask.end(); ++at) { int res = (*top)[*at].ResNum(); if (res != curRes) { nres++; curRes = res; } } value = integerToString( nres ); } else if (equals.hasKey("molecules")) { int curMol = -1; int nmol = 0; for (AtomMask::const_iterator at = mask.begin(); at != mask.end(); ++at) { int mol = (*top)[*at].MolNum(); if (mol != curMol) { nmol++; curMol = mol; } } value = integerToString( nmol ); } else { mprinterr("Error: Expected 'atoms', 'residues', or 'molecules'.\n"); return CpptrajState::ERR; } } else if (equals.hasKey("trajinframes")) { value = integerToString(State.InputTrajList().MaxFrames()); } else value = equals.ArgLineStr(); if (append) CurrentVars.AppendVariable( "$" + variable, value ); else CurrentVars.UpdateVariable( "$" + variable, value ); mprintf("\tVariable '%s' set to '%s'\n", variable.c_str(), value.c_str()); for (int iarg = 0; iarg < argIn.Nargs(); iarg++) argIn.MarkArg( iarg ); 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_DataSetCmd::Remove() Exec::RetType Exec_DataSetCmd::Remove(CpptrajState& State, ArgList& argIn) { std::string status; // Get criterion type CriterionType criterion = UNKNOWN_C; for (int i = 1; i < (int)N_C; i++) if (argIn.hasKey( CriterionKeys[i] )) { criterion = (CriterionType)i; status.assign( CriterionKeys[i] ); break; } if (criterion == UNKNOWN_C) { mprinterr("Error: No criterion specified for 'remove'.\n"); return CpptrajState::ERR; } // Get select type SelectType select = UNKNOWN_S; std::string val1, val2; for (const SelectPairType* ptr = SelectKeys; ptr->key_ != 0; ptr++) if (argIn.Contains( ptr->key_ )) { select = ptr->type_; val1 = argIn.GetStringKey( ptr->key_ ); status.append( " " + std::string(ptr->key_) + " " + val1 ); // Get 'and' value for between/outside. TODO put nargs in SelectPairType? if (select == BETWEEN || select == OUTSIDE) { val2 = argIn.GetStringKey("and"); if (val2.empty()) { mprinterr("Error: Missing 'and' value for selection '%s'\n", ptr->key_); return CpptrajState::ERR; } status.append(" and " + val2); } break; } if (select == UNKNOWN_S || val1.empty()) { mprinterr("Error: No selection specified for 'remove'.\n"); return CpptrajState::ERR; } if ( (criterion == SMODE || criterion == STYPE) && (select != EQUAL && select != NOT_EQUAL) ) { mprinterr("Error: Specified select not valid for criterion '%s'\n", CriterionKeys[criterion]); return CpptrajState::ERR; } mprintf("\tRemoving data sets"); std::string setSelectArg = argIn.GetStringNext(); if (setSelectArg.empty()) setSelectArg.assign("*"); else mprintf(" within selection '%s'", setSelectArg.c_str()); mprintf(" %s\n", status.c_str()); DataSetList tempDSL = State.DSL().GetMultipleSets( setSelectArg ); if (tempDSL.empty()) { mprinterr("Error: No data sets selected.\n"); return CpptrajState::ERR; } // Remove sets unsigned int Nremoved = 0; if ( criterion == AVERAGE ) { if (!validDouble( val1 )) { mprinterr("Error: '%s' is not a valid number\n", val1.c_str()); return CpptrajState::ERR; } double d_val1 = convertToDouble( val1 ); double d_val2 = d_val1; if (!val2.empty()) { if (!validDouble( val2 )) { mprinterr("Error: '%s' is not a valid number\n", val2.c_str()); return CpptrajState::ERR; } d_val2 = convertToDouble( val2 ); } for (DataSetList::const_iterator ds = tempDSL.begin(); ds != tempDSL.end(); ++ds) { if ( (*ds)->Group() != DataSet::SCALAR_1D ) mprintf("Warning: '%s' is not a valid data set for 'average' criterion.\n", (*ds)->legend()); else { DataSet_1D const& ds1 = static_cast<DataSet_1D const&>( *(*ds) ); double avg = ds1.Avg(); bool remove = false; switch (select) { case EQUAL : remove = (avg == d_val1); break; case NOT_EQUAL : remove = (avg != d_val1); break; case LESS_THAN : remove = (avg < d_val1); break; case GREATER_THAN : remove = (avg > d_val1); break; case BETWEEN : remove = (avg > d_val1 && avg < d_val2); break; case OUTSIDE : remove = (avg < d_val1 || avg > d_val2); break; case UNKNOWN_S: case N_S : return CpptrajState::ERR; // Sanity check } if (remove) { mprintf("\t Removing set '%s' (avg is %g)\n", (*ds)->legend(), avg); State.RemoveDataSet( *ds ); ++Nremoved; } } } } else if ( criterion == SIZE ) { if (!validInteger( val1 )) { mprinterr("Error: '%s' is not a valid number\n", val1.c_str()); return CpptrajState::ERR; } unsigned int i_val1 = (unsigned int)convertToInteger( val1 ); unsigned int i_val2 = i_val1; if (!val2.empty()) { if (!validInteger( val2 )) { mprinterr("Error: '%s' is not a valid number\n", val2.c_str()); return CpptrajState::ERR; } i_val2 = convertToInteger( val2 ); } for (DataSetList::const_iterator ds = tempDSL.begin(); ds != tempDSL.end(); ++ds) { unsigned int size = (*ds)->Size(); bool remove = false; switch ( select ) { case EQUAL : remove = (size == i_val1); break; case NOT_EQUAL : remove = (size != i_val1); break; case LESS_THAN : remove = (size < i_val1); break; case GREATER_THAN : remove = (size > i_val1); break; case BETWEEN : remove = (size > i_val1 && size < i_val2); break; case OUTSIDE : remove = (size < i_val1 || size > i_val2); break; case UNKNOWN_S: case N_S : return CpptrajState::ERR; // Sanity check } if (remove) { mprintf("\t Removing set '%s' (size is %u)\n", (*ds)->legend(), size); State.RemoveDataSet( *ds ); ++Nremoved; } } } else if ( criterion == SMODE ) { MetaData::scalarMode mode_val = MetaData::ModeFromKeyword( val1 ); if (mode_val == MetaData::UNKNOWN_MODE) { mprinterr("Error: '%s' is not a valid mode.\n", val1.c_str()); return CpptrajState::ERR; } for (DataSetList::const_iterator ds = tempDSL.begin(); ds != tempDSL.end(); ++ds) { bool remove = false; MetaData::scalarMode mode = (*ds)->Meta().ScalarMode(); if (select == EQUAL ) remove = ( mode == mode_val ); else if (select == NOT_EQUAL) remove = ( mode != mode_val ); else return CpptrajState::ERR; // Sanity check if (remove) { mprintf("\t Removing set '%s' (mode is '%s')\n", (*ds)->legend(), MetaData::ModeString(mode)); State.RemoveDataSet( *ds ); ++Nremoved; } } } else if ( criterion == STYPE ) { MetaData::scalarType type_val = MetaData::TypeFromKeyword( val1, MetaData::UNKNOWN_MODE ); if (type_val == MetaData::UNDEFINED) { mprinterr("Error: '%s' is not a valid type.\n", val1.c_str()); return CpptrajState::ERR; } for (DataSetList::const_iterator ds = tempDSL.begin(); ds != tempDSL.end(); ++ds) { bool remove = false; MetaData::scalarType type = (*ds)->Meta().ScalarType(); if (select == EQUAL ) remove = ( type == type_val ); else if (select == NOT_EQUAL) remove = ( type != type_val ); else return CpptrajState::ERR; // Sanity check if (remove) { mprintf("\t Removing set '%s' (typeis '%s')\n", (*ds)->legend(), MetaData::TypeString(type)); State.RemoveDataSet( *ds ); ++Nremoved; } } } else { mprinterr("Internal Error: Criterion not yet implemented.\n"); return CpptrajState::ERR; } mprintf("\tRemoved %u of %zu sets.\n", Nremoved, tempDSL.size()); return CpptrajState::OK; }
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_RotateDihedral::Execute() Exec::RetType Exec_RotateDihedral::Execute(CpptrajState& State, ArgList& argIn) { // 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; } if (CRD->Size() < 1) { mprinterr("Error: COORDS set is empty.\n"); return CpptrajState::ERR; } int frame = argIn.getKeyInt("frame", 0); if (frame < 0 || frame >= (int)CRD->Size()) { mprinterr("Error: Specified frame %i is out of range.\n", frame+1); return CpptrajState::ERR; } mprintf(" ROTATEDIHEDRAL: Using COORDS '%s', frame %i\n", CRD->legend(), frame+1); // Get target frame Frame FRM = CRD->AllocateFrame(); CRD->GetFrame(frame, FRM); // Save as reference Frame refFrame = FRM; // Create output COORDS set if necessary DataSet_Coords* OUT = 0; int outframe = 0; std::string outname = argIn.GetStringKey("name"); if (outname.empty()) { // This will not work for TRAJ data sets if (CRD->Type() == DataSet::TRAJ) { mprinterr("Error: Using TRAJ as input set requires use of 'name' keyword for output.\n"); return CpptrajState::ERR; } OUT = CRD; outframe = frame; } else { // Create new output set with 1 empty frame. OUT = (DataSet_Coords*)State.DSL().AddSet( DataSet::COORDS, outname ); if (OUT == 0) return CpptrajState::ERR; OUT->Allocate( DataSet::SizeArray(1, 1) ); OUT->CoordsSetup( CRD->Top(), CRD->CoordsInfo() ); OUT->AddFrame( CRD->AllocateFrame() ); mprintf("\tOutput to set '%s'\n", OUT->legend()); } // Determine whether we are setting or incrementing. enum ModeType { SET = 0, INCREMENT }; ModeType mode = SET; if (argIn.Contains("value")) mode = SET; else if (argIn.Contains("increment")) mode = INCREMENT; else { mprinterr("Error: Specify 'value <value>' or 'increment <increment>'\n"); return CpptrajState::ERR; } double value = argIn.getKeyDouble(ModeStr[mode], 0.0); switch (mode) { case SET: mprintf("\tDihedral will be set to %g degrees.\n", value); break; case INCREMENT: mprintf("\tDihedral will be incremented by %g degrees.\n", value); break; } // Convert to radians value *= Constants::DEGRAD; // Select dihedral atoms int A1, A2, A3, A4; if (argIn.Contains("type")) { // By type ArgList typeArg = argIn.GetStringKey("type"); if (typeArg.empty()) { mprinterr("Error: No dihedral type specified after 'type'\n"); return CpptrajState::ERR; } DihedralSearch dihSearch; dihSearch.SearchForArgs( typeArg ); if (dihSearch.NoDihedralTokens()) { mprinterr("Error: Specified dihedral type not recognized.\n"); return CpptrajState::ERR; } // Get residue int res = argIn.getKeyInt("res", -1); if (res <= 0) { mprinterr("Error: If 'type' specified 'res' must be specified and > 0.\n"); return CpptrajState::ERR; } // Search for dihedrals. User residue #s start from 1. if (dihSearch.FindDihedrals(CRD->Top(), Range(res-1))) return CpptrajState::ERR; DihedralSearch::mask_it dih = dihSearch.begin(); A1 = dih->A0(); A2 = dih->A1(); A3 = dih->A2(); A4 = dih->A3(); } else { // By masks AtomMask m1( argIn.GetMaskNext() ); AtomMask m2( argIn.GetMaskNext() ); AtomMask m3( argIn.GetMaskNext() ); AtomMask m4( argIn.GetMaskNext() ); if (CRD->Top().SetupIntegerMask( m1 )) return CpptrajState::ERR; if (CRD->Top().SetupIntegerMask( m2 )) return CpptrajState::ERR; if (CRD->Top().SetupIntegerMask( m3 )) return CpptrajState::ERR; if (CRD->Top().SetupIntegerMask( m4 )) return CpptrajState::ERR; if (m1.Nselected() != 1) return MaskError( m1 ); if (m2.Nselected() != 1) return MaskError( m2 ); if (m3.Nselected() != 1) return MaskError( m3 ); if (m4.Nselected() != 1) return MaskError( m4 ); A1 = m1[0]; A2 = m2[0]; A3 = m3[0]; A4 = m4[0]; } mprintf("\tRotating dihedral defined by atoms '%s'-'%s'-'%s'-'%s'\n", CRD->Top().AtomMaskName(A1).c_str(), CRD->Top().AtomMaskName(A2).c_str(), CRD->Top().AtomMaskName(A3).c_str(), CRD->Top().AtomMaskName(A4).c_str()); // Set mask of atoms that will move during dihedral rotation AtomMask Rmask = DihedralSearch::MovingAtoms(CRD->Top(), A2, A3); // Calculate current value of dihedral double torsion = Torsion( FRM.XYZ(A1), FRM.XYZ(A2), FRM.XYZ(A3), FRM.XYZ(A4) ); // Calculate delta needed to get to target value. double delta; switch (mode) { case SET: delta = value - torsion; break; case INCREMENT: delta = value; break; } mprintf("\tOriginal torsion is %g, rotating by %g degrees.\n", torsion*Constants::RADDEG, delta*Constants::RADDEG); // Set axis of rotation Vec3 axisOfRotation = FRM.SetAxisOfRotation( A2, A3 ); // Calculate rotation matrix for delta. Matrix_3x3 rotationMatrix; rotationMatrix.CalcRotationMatrix(axisOfRotation, delta); // Rotate around axis FRM.Rotate(rotationMatrix, Rmask); // RMS-fit the non-moving part of the coords back on original AtomMask refMask = Rmask; refMask.InvertMask(); FRM.Align( refFrame, refMask ); // Update coords OUT->SetCRD( outframe, FRM ); return CpptrajState::OK; }
// Exec_UpdateParameters::Execute() Exec::RetType Exec_UpdateParameters::Execute(CpptrajState& State, ArgList& argIn) { std::string dsname = argIn.GetStringKey("setname"); if (dsname.empty()) { mprinterr("Error: Specify parameter set.\n"); return CpptrajState::ERR; } DataSet* ds = State.DSL().GetDataSet( dsname ); if (ds == 0) { mprinterr("Error: Parameter data set '%s' not found.\n", dsname.c_str()); return CpptrajState::ERR; } if (ds->Type() != DataSet::PARAMETERS) { mprinterr("Error: Set '%s' is not a parameter data set.\n", ds->legend()); return CpptrajState::ERR; } DataSet_Parameters const& prm = static_cast<DataSet_Parameters const&>( *ds ); Topology* dstop = State.DSL().GetTopology( argIn ); if (dstop == 0) { mprinterr("Error: No topology specified.\n"); return CpptrajState::ERR; } Topology& top = static_cast<Topology&>( *dstop ); mprintf("\tUpdating parameters in topology '%s' using those in set '%s'\n", top.c_str(), prm.legend()); // Get list of existing parameters. // We assume a parameter in topology is never repeated, so as soon // as it is found we can move to the next one. ParmHolder<int> ParmIndices; // Bond parameters BondTypes(ParmIndices, top, top.Bonds()); BondTypes(ParmIndices, top, top.BondsH()); for (ParmHolder<BondParmType>::const_iterator it1 = prm.BP().begin(); it1 != prm.BP().end(); ++it1) { for (ParmHolder<int>::const_iterator it0 = ParmIndices.begin(); it0 != ParmIndices.end(); ++it0) { if (it1->first == it0->first) { BondParmType& bp = top.SetBondParm(it0->second); mprintf("\tUpdating bond parameter %s - %s from %f %f to %f %f\n", *(it0->first[0]), *(it0->first[1]), bp.Rk(), bp.Req(), it1->second.Rk(), it1->second.Req()); bp = it1->second; break; } } } ParmIndices.clear(); // Angle parameters AngleTypes(ParmIndices, top, top.Angles()); AngleTypes(ParmIndices, top, top.AnglesH()); for (ParmHolder<AngleParmType>::const_iterator it1 = prm.AP().begin(); it1 != prm.AP().end(); ++it1) { for (ParmHolder<int>::const_iterator it0 = ParmIndices.begin(); it0 != ParmIndices.end(); ++it0) { if (it1->first == it0->first) { AngleParmType& bp = top.SetAngleParm(it0->second); mprintf("\tUpdating angle parameter %s - %s - %s from %f %f to %f %f\n", *(it0->first[0]), *(it0->first[1]), *(it0->first[2]), bp.Tk(), bp.Teq(), it1->second.Tk(), it1->second.Teq()); bp = it1->second; break; } } } ParmIndices.clear(); // Dihedral parameters DihedralTypes(ParmIndices, top, top.Dihedrals()); DihedralTypes(ParmIndices, top, top.DihedralsH()); for (ParmHolder<DihedralParmType>::const_iterator it1 = prm.DP().begin(); it1 != prm.DP().end(); ++it1) { for (ParmHolder<int>::const_iterator it0 = ParmIndices.begin(); it0 != ParmIndices.end(); ++it0) { if (it1->first == it0->first) { DihedralParmType& bp = top.SetDihedralParm(it0->second); mprintf("\tUpdating dihedral parameter %s - %s - %s %s from %f %f %f to %f %f %f\n", *(it0->first[0]), *(it0->first[1]), *(it0->first[2]), *(it0->first[3]), bp.Pk(), bp.Pn(), bp.Phase(), it1->second.Pk(), it1->second.Pn(), it1->second.Phase()); bp = it1->second; break; } } } ParmIndices.clear(); if (top.Chamber().HasChamber()) { ChamberParmType& chm = top.SetChamber(); // UB parameters BondTypes(ParmIndices, top, chm.UB()); for (ParmHolder<BondParmType>::const_iterator it1 = prm.UB().begin(); it1 != prm.UB().end(); ++it1) { for (ParmHolder<int>::const_iterator it0 = ParmIndices.begin(); it0 != ParmIndices.end(); ++it0) { if (it1->first == it0->first) { BondParmType& bp = chm.SetUBparm(it0->second); mprintf("\tUpdating UB parameter %s - %s from %f %f to %f %f\n", *(it0->first[0]), *(it0->first[1]), bp.Rk(), bp.Req(), it1->second.Rk(), it1->second.Req()); bp = it1->second; break; } } } ParmIndices.clear(); // Improper parameters DihedralTypes(ParmIndices, top, chm.Impropers()); for (ParmHolder<DihedralParmType>::const_iterator it1 = prm.IP().begin(); it1 != prm.IP().end(); ++it1) { for (ParmHolder<int>::const_iterator it0 = ParmIndices.begin(); it0 != ParmIndices.end(); ++it0) { if (it1->first == it0->first) { DihedralParmType& bp = chm.SetImproperParm(it0->second); mprintf("\tUpdating improper parameter %s - %s - %s %s from %f %f %f to %f %f %f\n", *(it0->first[0]), *(it0->first[1]), *(it0->first[2]), *(it0->first[3]), bp.Pk(), bp.Pn(), bp.Phase(), it1->second.Pk(), it1->second.Pn(), it1->second.Phase()); bp = it1->second; break; } } } ParmIndices.clear(); } //for (ParmHolder<int>::const_iterator it = ParmIndices.begin(); it != ParmIndices.end(); ++it) // mprintf("\t%s %s %i\n", *(it->first[0]), *(it->first[1]), it->second); 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::Filter() Exec::RetType Exec_DataSetCmd::Filter(CpptrajState& State, ArgList& argIn) { std::string name = argIn.GetStringKey("name"); int rowmin = argIn.getKeyInt("rowmin", -1); int rowmax = argIn.getKeyInt("rowmax", -1); int colmin = argIn.getKeyInt("colmin", -1); int colmax = argIn.getKeyInt("colmax", -1); DataSet* ds1 = State.DSL().GetDataSet( argIn.GetStringNext() ); if (ds1 == 0) return CpptrajState::ERR; if ( ds1->Group() == DataSet::SCALAR_1D ) { mprinterr("Error: Not yet set up for 1D sets.\n"); return CpptrajState::ERR; } else if (ds1->Group() == DataSet::MATRIX_2D) { DataSet_2D const& matrixIn = static_cast<DataSet_2D const&>( *ds1 ); if (rowmin < 0) rowmin = 0; if (rowmax < 0) rowmax = matrixIn.Nrows(); int nrows = rowmax - rowmin; if (nrows < 1) { mprinterr("Error: Keeping less than 1 row.\n"); return CpptrajState::ERR; } else if (nrows > (int)matrixIn.Nrows()) nrows = matrixIn.Nrows(); if (colmin < 0) colmin = 0; if (colmax < 0) colmax = matrixIn.Ncols(); int ncols = colmax - colmin; if (ncols < 1) { mprinterr("Error: Keeping less than 1 column.\n"); return CpptrajState::ERR; } else if (ncols > (int)matrixIn.Ncols()) ncols = matrixIn.Ncols(); mprintf("\tMatrix to filter: %s\n", ds1->legend()); mprintf("\tKeeping rows >= %i and < %i\n", rowmin, rowmax); mprintf("\tKeeping cols >= %i and < %i\n", colmin, colmax); mprintf("\tCreating new matrix with %i rows and %i columns.\n", nrows, ncols); DataSet* ds3 = State.DSL().AddSet( DataSet::MATRIX_DBL, name, "make2d" ); if (ds3 == 0) return CpptrajState::ERR; DataSet_MatrixDbl& matrixOut = static_cast<DataSet_MatrixDbl&>( *ds3 ); matrixOut.Allocate2D(ncols, nrows); matrixOut.SetDim( Dimension::X, Dimension(matrixIn.Dim(0).Coord(colmin), matrixIn.Dim(0).Step(), matrixIn.Dim(0).Label()) ); matrixOut.SetDim( Dimension::Y, Dimension(matrixIn.Dim(1).Coord(rowmin), matrixIn.Dim(1).Step(), matrixIn.Dim(1).Label()) ); for (int row = 0; row < (int)matrixIn.Nrows(); row++) { if (row >= rowmin && row < rowmax) { for (int col = 0; col < (int)matrixIn.Ncols(); col++) { if (col >= colmin && col < colmax) { double val = matrixIn.GetElement(col, row); matrixOut.SetElement( col-colmin, row-rowmin, val ); //mprintf("DEBUG:\tmatrixIn(%i, %i) = %f to matrixOut(%i, %i)\n", // col, row, val, col-colmin, row-rowmin); } } } } } return CpptrajState::OK; }
// Exec_DataSetCmd::ChangeDim() Exec::RetType Exec_DataSetCmd::ChangeDim(CpptrajState const& State, ArgList& argIn) { int ndim = -1; if (argIn.hasKey("xdim")) ndim = 0; else if (argIn.hasKey("ydim")) ndim = 1; else if (argIn.hasKey("zdim")) ndim = 2; else ndim = argIn.getKeyInt("ndim", -1); if (ndim < 0) { mprinterr("Error: Specify xdim/ydim/zdim or dimension number with ndim.\n"); return CpptrajState::ERR; } if (ndim < 3) { static const char DIMSTR[3] = { 'X', 'Y', 'Z' }; mprintf("\tChanging the following in the %c dimension:\n", DIMSTR[ndim]); } else mprintf("\tChanging the following in dimension %i\n", ndim); bool changeLabel, changeMin, changeStep; std::string label; double min = 0.0; double step = 0.0; if (argIn.Contains("label")) { label = argIn.GetStringKey("label"); changeLabel = true; mprintf("\tNew Label: %s\n", label.c_str()); } else changeLabel = false; if (argIn.Contains("step")) { step = argIn.getKeyDouble("step", 0.0); changeStep = true; mprintf("\tNew step: %g\n", step); } else changeStep = false; if (argIn.Contains("min")) { min = argIn.getKeyDouble("min", 0.0); changeMin = true; mprintf("\tNew min: %g\n", min); } else changeMin = false; // 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 ds = dsl.begin(); ds != dsl.end(); ++ds) { if (ndim < (int)(*ds)->Ndim()) { mprintf("\t%s\n", (*ds)->legend()); Dimension dim = (*ds)->Dim(ndim); if (changeLabel) dim.SetLabel( label ); if (changeMin) dim.ChangeMin( min ); if (changeStep) dim.ChangeStep( step ); (*ds)->SetDim(ndim, dim); } else mprintf("Warning: Set '%s' has fewer then %i dimensions - skipping.\n", (*ds)->legend(), ndim); } ds_arg = argIn.GetStringNext(); } return CpptrajState::OK; }
// Exec_DataSetCmd::ChangeModeType() Exec::RetType Exec_DataSetCmd::ChangeModeType(CpptrajState const& State, ArgList& argIn) { std::string modeKey = argIn.GetStringKey("mode"); std::string typeKey = argIn.GetStringKey("type"); if (modeKey.empty() && typeKey.empty()) { mprinterr("Error: No valid keywords specified.\n"); return CpptrajState::ERR; } // First determine mode if specified. MetaData::scalarMode dmode = MetaData::UNKNOWN_MODE; if (!modeKey.empty()) { dmode = MetaData::ModeFromKeyword( modeKey ); if (dmode == MetaData::UNKNOWN_MODE) { mprinterr("Error: Invalid mode keyword '%s'\n", modeKey.c_str()); return CpptrajState::ERR; } } // Next determine type if specified. MetaData::scalarType dtype = MetaData::UNDEFINED; if (!typeKey.empty()) { dtype = MetaData::TypeFromKeyword( typeKey, dmode ); if (dtype == MetaData::UNDEFINED) { mprinterr("Error: Invalid type keyword '%s'\n", typeKey.c_str()); return CpptrajState::ERR; } } // Additional options for type 'noe' AssociatedData_NOE noeData; if (dtype == MetaData::NOE) { if (noeData.NOE_Args(argIn)) return CpptrajState::ERR; } if (dmode != MetaData::UNKNOWN_MODE) mprintf("\tDataSet mode = %s\n", MetaData::ModeString(dmode)); if (dtype != MetaData::UNDEFINED) mprintf("\tDataSet type = %s\n", MetaData::TypeString(dtype)); // 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 ds = dsl.begin(); ds != dsl.end(); ++ds) { if (dmode != MetaData::UNKNOWN_MODE) { // Warn if mode does not seem appropriate for the data set type. if ( dmode >= MetaData::M_DISTANCE && dmode <= MetaData::M_RMS && (*ds)->Group() != DataSet::SCALAR_1D ) mprintf("Warning: '%s': Expected scalar 1D data set type for mode '%s'\n", (*ds)->legend(), MetaData::ModeString(dmode)); else if ( dmode == MetaData::M_VECTOR && (*ds)->Type() != DataSet::VECTOR ) mprintf("Warning: '%s': Expected vector data set type for mode '%s'\n", (*ds)->legend(), MetaData::ModeString(dmode)); else if ( dmode == MetaData::M_MATRIX && (*ds)->Group() != DataSet::MATRIX_2D ) mprintf("Warning: '%s': Expected 2D matrix data set type for mode '%s'\n", (*ds)->legend(), MetaData::ModeString(dmode)); } if ( dtype == MetaData::NOE ) (*ds)->AssociateData( &noeData ); mprintf("\t\t'%s'\n", (*ds)->legend()); MetaData md = (*ds)->Meta(); md.SetScalarMode( dmode ); md.SetScalarType( dtype ); (*ds)->SetMeta( md ); } ds_arg = argIn.GetStringNext(); } return CpptrajState::OK; }
/** Syntax: dataset invert <set arg0> ... name <new name> */ Exec::RetType Exec_DataSetCmd::InvertSets(CpptrajState& State, ArgList& argIn) { DataSetList& DSL = State.DSL(); // Get keywords DataSet* inputNames = 0; std::string dsname = argIn.GetStringKey("legendset"); if (!dsname.empty()) { inputNames = DSL.GetDataSet( dsname ); if (inputNames == 0) { mprinterr("Error: Name set '%s' not found.\n", dsname.c_str()); return CpptrajState::ERR; } if (inputNames->Type() != DataSet::STRING) { mprinterr("Error: Set '%s' does not contain strings.\n", inputNames->legend()); return CpptrajState::ERR; } mprintf("\tUsing names from set '%s' as legends for inverted sets.\n", inputNames->legend()); } dsname = argIn.GetStringKey("name"); if (dsname.empty()) { mprinterr("Error: 'invert' requires that 'name <new set name>' be specified.\n"); return CpptrajState::ERR; } mprintf("\tNew sets will be named '%s'\n", dsname.c_str()); DataFile* outfile = State.DFL().AddDataFile( argIn.GetStringKey("out"), argIn ); if (outfile != 0) mprintf("\tNew sets will be output to '%s'\n", outfile->DataFilename().full()); // TODO determine type some other way DataSet::DataType outtype = DataSet::DOUBLE; // Get input DataSets std::vector<DataSet_1D*> input_sets; std::string dsarg = argIn.GetStringNext(); while (!dsarg.empty()) { DataSetList sets = DSL.GetMultipleSets( dsarg ); for (DataSetList::const_iterator ds = sets.begin(); ds != sets.end(); ++ds) { if ( (*ds)->Group() != DataSet::SCALAR_1D ) { mprintf("Warning: '%s': Inversion only supported for 1D scalar data sets.\n", (*ds)->legend()); } else { if (!input_sets.empty()) { if ( (*ds)->Size() != input_sets.back()->Size() ) { mprinterr("Error: Set '%s' has different size (%zu) than previous set (%zu)\n", (*ds)->legend(), (*ds)->Size(), input_sets.back()->Size()); return CpptrajState::ERR; } } input_sets.push_back( (DataSet_1D*)*ds ); } } dsarg = argIn.GetStringNext(); } if (input_sets.empty()) { mprinterr("Error: No sets selected.\n"); return CpptrajState::ERR; } if (inputNames != 0 && inputNames->Size() != input_sets.front()->Size()) { mprinterr("Error: Name set '%s' size (%zu) differs from # data points (%zu).\n", inputNames->legend(), inputNames->Size(), input_sets.front()->Size()); return CpptrajState::ERR; } mprintf("\t%zu input sets; creating %zu output sets.\n", input_sets.size(), input_sets.front()->Size()); // Need an output data set for each point in input sets std::vector<DataSet*> output_sets; int column = 1; for (int idx = 0; idx != (int)input_sets[0]->Size(); idx++, column++) { DataSet* ds = 0; ds = DSL.AddSet(outtype, MetaData(dsname, column)); if (ds == 0) return CpptrajState::ERR; if (inputNames != 0) ds->SetLegend( (*((DataSet_string*)inputNames))[idx] ); output_sets.push_back( ds ); if (outfile != 0) outfile->AddDataSet( ds ); } // Create a data set containing names of each input data set DataSet* nameset = DSL.AddSet(DataSet::STRING, MetaData(dsname, column)); if (nameset == 0) return CpptrajState::ERR; if (inputNames != 0) nameset->SetLegend("Names"); if (outfile != 0) outfile->AddDataSet( nameset ); // Populate output data sets for (int jdx = 0; jdx != (int)input_sets.size(); jdx++) { DataSet_1D const& INP = static_cast<DataSet_1D const&>( *(input_sets[jdx]) ); nameset->Add( jdx, INP.legend() ); for (unsigned int idx = 0; idx != INP.Size(); idx++) { double dval = INP.Dval( idx ); output_sets[idx]->Add( jdx, &dval ); } } return CpptrajState::OK; }
/** Set up each mask/integer loop. */ int ControlBlock_For::SetupBlock(CpptrajState& State, ArgList& argIn) { mprintf(" Setting up 'for' loop.\n"); Vars_.clear(); Topology* currentTop = 0; static const char* TypeStr[] = { "ATOMS ", "RESIDUES ", "MOLECULES ", "MOL_FIRST_RES ", "MOL_LAST_RES " }; static const char* OpStr[] = {"+=", "-=", "<", ">"}; description_.assign("for ("); int MaxIterations = -1; int iarg = 0; while (iarg < argIn.Nargs()) { // Advance to next unmarked argument. while (iarg < argIn.Nargs() && argIn.Marked(iarg)) iarg++; if (iarg == argIn.Nargs()) break; // Determine 'for' type ForType ftype = UNKNOWN; bool isMaskFor = true; int argToMark = iarg; if ( argIn[iarg] == "atoms" ) ftype = ATOMS; else if ( argIn[iarg] == "residues" ) ftype = RESIDUES; else if ( argIn[iarg] == "molecules" ) ftype = MOLECULES; else if ( argIn[iarg] == "molfirstres" ) ftype = MOLFIRSTRES; else if ( argIn[iarg] == "mollastres" ) ftype = MOLLASTRES; else if ( argIn[iarg].find(";") != std::string::npos ) { isMaskFor = false; ftype = INTEGER; } // If type is still unknown, check for list. if (ftype == UNKNOWN) { if (iarg+1 < argIn.Nargs() && argIn[iarg+1] == "in") { ftype = LIST; isMaskFor = false; argToMark = iarg+1; } } // Exit if type could not be determined. if (ftype == UNKNOWN) { mprinterr("Error: for loop type not specfied.\n"); return 1; } argIn.MarkArg(argToMark); Vars_.push_back( LoopVar() ); LoopVar& MH = Vars_.back(); int Niterations = -1; // Set up for specific type if (description_ != "for (") description_.append(", "); // ------------------------------------------- if (isMaskFor) { // {atoms|residues|molecules} <var> inmask <mask> [TOP KEYWORDS] if (argIn[iarg+2] != "inmask") { mprinterr("Error: Expected 'inmask', got %s\n", argIn[iarg+2].c_str()); return 1; } AtomMask currentMask; if (currentMask.SetMaskString( argIn.GetStringKey("inmask") )) return 1; MH.varType_ = ftype; Topology* top = State.DSL().GetTopByIndex( argIn ); if (top != 0) currentTop = top; if (currentTop == 0) return 1; MH.varname_ = argIn.GetStringNext(); if (MH.varname_.empty()) { mprinterr("Error: 'for inmask': missing variable name.\n"); return 1; } MH.varname_ = "$" + MH.varname_; // Set up mask if (currentTop->SetupIntegerMask( currentMask )) return 1; currentMask.MaskInfo(); if (currentMask.None()) return 1; // Set up indices if (MH.varType_ == ATOMS) MH.Idxs_ = currentMask.Selected(); else if (MH.varType_ == RESIDUES) { int curRes = -1; for (AtomMask::const_iterator at = currentMask.begin(); at != currentMask.end(); ++at) { int res = (*currentTop)[*at].ResNum(); if (res != curRes) { MH.Idxs_.push_back( res ); curRes = res; } } } else if (MH.varType_ == MOLECULES || MH.varType_ == MOLFIRSTRES || MH.varType_ == MOLLASTRES) { int curMol = -1; for (AtomMask::const_iterator at = currentMask.begin(); at != currentMask.end(); ++at) { int mol = (*currentTop)[*at].MolNum(); if (mol != curMol) { if (MH.varType_ == MOLECULES) MH.Idxs_.push_back( mol ); else { int res; if (MH.varType_ == MOLFIRSTRES) res = (*currentTop)[ currentTop->Mol( mol ).BeginAtom() ].ResNum(); else // MOLLASTRES res = (*currentTop)[ currentTop->Mol( mol ).EndAtom()-1 ].ResNum(); MH.Idxs_.push_back( res ); } curMol = mol; } } } Niterations = (int)MH.Idxs_.size(); description_.append(std::string(TypeStr[MH.varType_]) + MH.varname_ + " inmask " + currentMask.MaskExpression()); // ------------------------------------------- } else if (ftype == INTEGER) { // [<var>=<start>;[<var><OP><end>;]<var><OP>[<value>]] MH.varType_ = ftype; ArgList varArg( argIn[iarg], ";" ); if (varArg.Nargs() < 2 || varArg.Nargs() > 3) { mprinterr("Error: Malformed 'for' loop variable.\n" "Error: Expected '[<var>=<start>;[<var><OP><end>;]<var><OP>[<value>]]'\n" "Error: Got '%s'\n", argIn[iarg].c_str()); return 1; } // First argument: <var>=<start> ArgList startArg( varArg[0], "=" ); if (startArg.Nargs() != 2) { mprinterr("Error: Malformed 'start' argument.\n" "Error: Expected <var>=<start>, got '%s'\n", varArg[0].c_str()); return 1; } MH.varname_ = startArg[0]; if (!validInteger(startArg[1])) { // TODO allow variables mprinterr("Error: Start argument must be an integer.\n"); return 1; } else MH.start_ = convertToInteger(startArg[1]); // Second argument: <var><OP><end> size_t pos0 = MH.varname_.size(); size_t pos1 = pos0 + 1; MH.endOp_ = NO_OP; int iargIdx = 1; if (varArg.Nargs() == 3) { iargIdx = 2; if ( varArg[1][pos0] == '<' ) MH.endOp_ = LESS_THAN; else if (varArg[1][pos0] == '>') MH.endOp_ = GREATER_THAN; if (MH.endOp_ == NO_OP) { mprinterr("Error: Unrecognized end op: '%s'\n", varArg[1].substr(pos0, pos1-pos0).c_str()); return 1; } std::string endStr = varArg[1].substr(pos1); if (!validInteger(endStr)) { // TODO allow variables mprinterr("Error: End argument must be an integer.\n"); return 1; } else MH.end_ = convertToInteger(endStr); } // Third argument: <var><OP>[<value>] pos1 = pos0 + 2; MH.incOp_ = NO_OP; bool needValue = false; if ( varArg[iargIdx][pos0] == '+' ) { if (varArg[iargIdx][pos0+1] == '+') { MH.incOp_ = INCREMENT; MH.inc_ = 1; } else if (varArg[iargIdx][pos0+1] == '=') { MH.incOp_ = INCREMENT; needValue = true; } } else if ( varArg[iargIdx][pos0] == '-' ) { if (varArg[iargIdx][pos0+1] == '-' ) { MH.incOp_ = DECREMENT; MH.inc_ = 1; } else if (varArg[iargIdx][pos0+1] == '=') { MH.incOp_ = DECREMENT; needValue = true; } } if (MH.incOp_ == NO_OP) { mprinterr("Error: Unrecognized increment op: '%s'\n", varArg[iargIdx].substr(pos0, pos1-pos0).c_str()); return 1; } if (needValue) { std::string incStr = varArg[iargIdx].substr(pos1); if (!validInteger(incStr)) { mprinterr("Error: increment value is not a valid integer.\n"); return 1; } MH.inc_ = convertToInteger(incStr); if (MH.inc_ < 1) { mprinterr("Error: Extra '-' detected in increment.\n"); return 1; } } // Description MH.varname_ = "$" + MH.varname_; std::string sval = integerToString(MH.start_); description_.append("(" + MH.varname_ + "=" + sval + "; "); std::string eval; if (iargIdx == 2) { // End argument present eval = integerToString(MH.end_); description_.append(MH.varname_ + std::string(OpStr[MH.endOp_]) + eval + "; "); // Check end > start for increment, start > end for decrement int maxval, minval; if (MH.incOp_ == INCREMENT) { if (MH.start_ >= MH.end_) { mprinterr("Error: start must be less than end for increment.\n"); return 1; } minval = MH.start_; maxval = MH.end_; } else { if (MH.end_ >= MH.start_) { mprinterr("Error: end must be less than start for decrement.\n"); return 1; } minval = MH.end_; maxval = MH.start_; } // Figure out number of iterations Niterations = (maxval - minval) / MH.inc_; if (((maxval-minval) % MH.inc_) > 0) Niterations++; } description_.append( MH.varname_ + std::string(OpStr[MH.incOp_]) + integerToString(MH.inc_) + ")" ); // If decrementing just negate value if (MH.incOp_ == DECREMENT) MH.inc_ = -MH.inc_; // DEBUG //mprintf("DEBUG: start=%i endOp=%i end=%i incOp=%i val=%i startArg=%s endArg=%s\n", // MH.start_, (int)MH.endOp_, MH.end_, (int)MH.incOp_, MH.inc_, // MH.startArg_.c_str(), MH.endArg_.c_str()); // ------------------------------------------- } else if (ftype == LIST) { // <var> in <string0>[,<string1>...] MH.varType_ = ftype; // Variable name MH.varname_ = argIn.GetStringNext(); if (MH.varname_.empty()) { mprinterr("Error: 'for in': missing variable name.\n"); return 1; } MH.varname_ = "$" + MH.varname_; // Comma-separated list of strings std::string listArg = argIn.GetStringNext(); if (listArg.empty()) { mprinterr("Error: 'for in': missing comma-separated list of strings.\n"); return 1; } ArgList list(listArg, ","); if (list.Nargs() < 1) { mprinterr("Error: Could not parse '%s' for 'for in'\n", listArg.c_str()); return 1; } for (int il = 0; il != list.Nargs(); il++) { // Check if file name expansion should occur if (list[il].find_first_of("*?") != std::string::npos) { File::NameArray files = File::ExpandToFilenames( list[il] ); for (File::NameArray::const_iterator fn = files.begin(); fn != files.end(); ++fn) MH.List_.push_back( fn->Full() ); } else MH.List_.push_back( list[il] ); } Niterations = (int)MH.List_.size(); // Description description_.append( MH.varname_ + " in " + listArg ); } // Check number of values if (MaxIterations == -1) MaxIterations = Niterations; else if (Niterations != -1 && Niterations != MaxIterations) { mprintf("Warning: # iterations %i != previous # iterations %i\n", Niterations, MaxIterations); MaxIterations = std::min(Niterations, MaxIterations); } } mprintf("\tLoop will execute for %i iterations.\n", MaxIterations); if (MaxIterations < 1) { mprinterr("Error: Loop has less than 1 iteration.\n"); return 1; } description_.append(") do"); return 0; }