int TrajinList::AddTrajin(std::string const& fname, Topology* topIn, ArgList const& argIn) { if (topIn == 0) { mprinterr("Error: No topology for input trajectory '%s'\n", fname.c_str()); return 1; } // CRDIDXARG finalCrdIndicesArg_.clear(); ArgList trajin_args = argIn; bool isRemdtraj = trajin_args.hasKey("remdtraj"); int err = 0; File::NameArray fnames = File::ExpandToFilenames( fname ); if (fnames.empty()) return 1; Trajin* traj = 0; for (File::NameArray::const_iterator fn = fnames.begin(); fn != fnames.end(); ++fn) { ArgList args = trajin_args; if (isRemdtraj) traj = new Trajin_Multi(); else traj = new Trajin_Single(); if (traj == 0) { mprinterr("Error: Memory allocation for input trajectory failed.\n"); return 1; } traj->SetDebug(debug_); if ( traj->SetupTrajRead(*fn, args, topIn) ) { mprinterr("Error: Could not set up input trajectory '%s'.\n", fn->full()); delete traj; err++; continue; } // Add to trajin list and update # of frames. trajin_.push_back( traj ); UpdateMaxFrames( traj->Traj() ); } if (err > 0) return 1; // FIXME: For backwards compat. overwrite Topology box info with traj box info. topIn->SetBoxFromTraj( trajin_.back()->TrajCoordInfo().TrajBox() ); return 0; }
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; }
// TrajinList::AddEnsembleIn() int TrajinList::AddEnsembleIn(std::string const& fname, Topology* topIn, ArgList const& argIn) { if (topIn == 0) { mprinterr("Error: No topology for input ensemble '%s'\n", fname.c_str()); return 1; } int err = 0; File::NameArray fnames = File::ExpandToFilenames( fname ); if (fnames.empty()) return 1; TrajectoryFile::TrajFormatType trajinFmt; TrajectoryIO* tio = 0; for (File::NameArray::const_iterator fn = fnames.begin(); fn != fnames.end(); ++fn) { ArgList args = argIn; // Determine whether this file is multiple file or single file ensemble. tio = TrajectoryFile::DetectFormat( *fn, trajinFmt ); if (tio == 0) { mprinterr("Error: Could not determine trajectory %s format\n", fn->full()); err++; continue; } EnsembleIn* ensemble = 0; # ifdef ENABLE_SINGLE_ENSEMBLE if (tio->CanProcessEnsemble()) ensemble = new EnsembleIn_Single(); else # endif ensemble = new EnsembleIn_Multi(); if (ensemble == 0) { mprinterr("Error: Memory allocation for input ensemble failed.\n"); delete tio; return 1; } ensemble->SetDebug( debug_ ); // CRDIDXARG: Append coordinate indices arg if there is one args.AddArg( finalCrdIndicesArg_ ); if ( ensemble->SetupEnsembleRead(*fn, args, topIn) ) { mprinterr("Error: Could not set up input ensemble '%s'.\n", fname.c_str()); delete ensemble; delete tio; err++; continue; } // Currently all input ensembles must be same size. if (ensembleSize_ == -1) ensembleSize_ = ensemble->EnsembleCoordInfo().EnsembleSize(); else if (ensembleSize_ != ensemble->EnsembleCoordInfo().EnsembleSize()) { mprinterr("Error: Ensemble size (%i) does not match first ensemble size (%i).\n", ensemble->EnsembleCoordInfo().EnsembleSize(), ensembleSize_); return 1; } // CRDIDXARG: If trajectory is REMD ensemble and sorting by CRDIDX, need to // save final CRDIDX for next ensemble command. // TODO: This is very clunky - remlog dataset should contain all exchanges // so trajin doesnt have to worry about it. # ifdef ENABLE_SINGLE_ENSEMBLE if ( !tio->CanProcessEnsemble() ) { # endif EnsembleIn_Multi const& mTraj = static_cast<EnsembleIn_Multi const&>( *ensemble ); if ( mTraj.TargetMode() == ReplicaInfo::CRDIDX ) { finalCrdIndicesArg_ = mTraj.FinalCrdIndices(); if (finalCrdIndicesArg_.empty()) { mprinterr("Error: Could not obtain final remlog indices.\n"); delete ensemble; delete tio; err++; continue; } //mprintf("DEBUG: Final crd indices arg: %s\n", finalCrdIndicesArg_.c_str()); } # ifdef ENABLE_SINGLE_ENSEMBLE } else mprintf("Warning: Single ensemble cannot process crdidx.\n"); # endif // Add to ensemble list and update # of frames. ensemble_.push_back( ensemble ); UpdateMaxFrames( ensemble->Traj() ); delete tio; } if (err > 0) return 1; // FIXME: For backwards compat. overwrite Topology box info with traj box info. topIn->SetBoxFromTraj( ensemble_.back()->EnsembleCoordInfo().TrajBox() ); return 0; }
/** 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; }