// ============================================================================= // ----- RepName Class --------------------------------------------------------- // RepName CONSTRUCTOR File::RepName::RepName(FileName const& fname, int debugIn) : extChar_('.') { if (debugIn > 1) mprintf("\tREMDTRAJ: FileName=[%s]\n", fname.full()); if ( fname.Ext().empty() ) { mprinterr("Error: Traj %s has no numerical extension, required for automatic\n" "Error: detection of replica trajectories. Expected filename format is\n" "Error: <Prefix>.<#> (with optional compression extension), examples:\n" "Error: Rep.traj.nc.000, remd.x.01.gz etc.\n", fname.base()); return; } // Split off everything before replica extension size_t found = fname.Full().rfind( fname.Ext() ); Prefix_.assign( fname.Full().substr(0, found) ); ReplicaExt_.assign( fname.Ext() ); // This should be the numeric extension // Remove leading '.' if (ReplicaExt_[0] == '.') ReplicaExt_.erase(0,1); CompressExt_.assign( fname.Compress() ); if (debugIn > 1) { mprintf("\tREMDTRAJ: Prefix=[%s], #Ext=[%s], CompressExt=[%s]\n", Prefix_.c_str(), ReplicaExt_.c_str(), CompressExt_.c_str()); } // CHARMM replica numbers are format <name>_<num> if ( !validInteger(ReplicaExt_) ) { size_t uscore = fname.Full().rfind('_'); if (uscore != std::string::npos) { Prefix_.assign( fname.Full().substr(0, uscore) ); ReplicaExt_.assign( fname.Full().substr(uscore+1) ); extChar_ = '_'; if (debugIn > 0) mprintf("\tREMDTRAJ: CHARMM style replica names detected, prefix='%s' ext='%s'\n", Prefix_.c_str(), ReplicaExt_.c_str()); } } // Check that the numerical extension is valid. if ( !validInteger(ReplicaExt_) ) { mprinterr("Error: Replica extension [%s] is not an integer.\n", ReplicaExt_.c_str()); Prefix_.clear(); // Empty Prefix_ indicates error. return; } ExtWidth_ = (int)ReplicaExt_.size(); if (debugIn > 1) mprintf("\tREMDTRAJ: Numerical Extension width=%i\n", ExtWidth_); // Store lowest replica number lowestRepnum_ = convertToInteger( ReplicaExt_ ); // TODO: Do not allow negative replica numbers? if (debugIn > 1) mprintf("\tREMDTRAJ: index of first replica = %i\n", lowestRepnum_); }
bool parametersChecking(TYPE &n, TYPE &k) { TYPE *nPtr = &n; TYPE *kPtr = &k; int typeCheckInt = 0; if(typeid(*nPtr).name() == typeid(typeCheckInt).name() && typeid(*kPtr).name() == typeid(typeCheckInt).name()){ // If given parameters integer, then these integers are checked for validity // if they qualify to calculate binomial coefficient if (validInteger(n,k)){ return true; } else{ return false; } } else { return false; } return false; }
bool Traj_Gro::ID_TrajFormat(CpptrajFile& infile) { // Title line, atoms line, then resnum, resname, atomname, atomnum, X, Y, Z if (infile.OpenFile()) return false; int nread = 0; if (infile.NextLine() != 0) { // Title const char* ptr = infile.NextLine(); // Natom if (ptr != 0) { // Ensure only a single value on # atoms line std::string natom_str( ptr ); RemoveTrailingWhitespace( natom_str ); if (validInteger(natom_str)) { ptr = infile.NextLine(); // First atom if (ptr != 0) { char resnum[6], resname[6], atname[6], atnum[6]; float XYZ[3]; nread = sscanf(ptr, "%5c%5c%5c%5c%f %f %f", resnum, resname, atname, atnum, XYZ, XYZ+1, XYZ+2); } } } } infile.CloseFile(); return (nread == 7); }
/** 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; }
// 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; }
// DataIO_Std::Read_1D() int DataIO_Std::Read_1D(std::string const& fname, DataSetList& datasetlist, std::string const& dsname) { ArgList labels; bool hasLabels = false; // Buffer file BufferedLine buffer; if (buffer.OpenFileRead( fname )) return 1; // Read the first line. Attempt to determine the number of columns const char* linebuffer = buffer.Line(); if (linebuffer == 0) return 1; int ntoken = buffer.TokenizeLine( SEPARATORS ); if ( ntoken == 0 ) { mprinterr("Error: No columns detected in %s\n", buffer.Filename().full()); return 1; } // Try to skip past any comments. If line begins with a '#', assume it // contains labels. bool isCommentLine = true; const char* ptr = linebuffer; while (isCommentLine) { // Skip past any whitespace while ( *ptr != '\0' && isspace(*ptr) ) ++ptr; // Assume these are column labels until proven otherwise. if (*ptr == '#') { labels.SetList(ptr+1, SEPARATORS ); if (!labels.empty()) { hasLabels = true; // If first label is Frame assume it is the index column if (labels[0] == "Frame" && indexcol_ == -1) indexcol_ = 0; } linebuffer = buffer.Line(); ptr = linebuffer; if (ptr == 0) { mprinterr("Error: No data found in file.\n"); return 1; } } else // Not a recognized comment character, assume data. isCommentLine = false; } // Special case: check if labels are '#F1 F2 <name> [nframes <#>]'. If so, assume // this is a cluster matrix file. if ((labels.Nargs() == 3 || labels.Nargs() == 5) && labels[0] == "F1" && labels[1] == "F2") { mprintf("Warning: Header format '#F1 F2 <name>' detected, assuming cluster pairwise matrix.\n"); return IS_ASCII_CMATRIX; } // Column user args start from 1 if (indexcol_ > -1) mprintf("\tUsing column %i as index column.\n", indexcol_ + 1); // Should be at first data line. Tokenize the line. ntoken = buffer.TokenizeLine( SEPARATORS ); // If # of data columns does not match # labels, clear labels. if ( !labels.empty() && ntoken != labels.Nargs() ) { labels.ClearList(); hasLabels = false; } // Index column checks if (indexcol_ != -1 ) { if (indexcol_ >= ntoken) { mprinterr("Error: Specified index column %i is out of range (%i columns).\n", indexcol_+1, ntoken); return 1; } if (!onlycols_.Empty() && !onlycols_.InRange(indexcol_)) { mprinterr("Error: Index column %i specified, but not in given column range '%s'\n", indexcol_+1, onlycols_.RangeArg()); return 1; } } // Determine the type of data stored in each column. Assume numbers should // be read with double precision. MetaData md( dsname ); DataSetList::DataListType inputSets; unsigned int nsets = 0; for (int col = 0; col != ntoken; ++col) { std::string token( buffer.NextToken() ); if (!onlycols_.Empty() && !onlycols_.InRange( col )) { mprintf("\tSkipping column %i\n", col+1); inputSets.push_back( 0 ); } else { md.SetIdx( col+1 ); if (hasLabels) md.SetLegend( labels[col] ); if ( col == indexcol_ ) { // Always save the index column as floating point inputSets.push_back( new DataSet_double() ); } else if (validInteger(token)) { // Integer number inputSets.push_back( datasetlist.Allocate(DataSet::INTEGER) ); } else if (validDouble(token)) { // Floating point number inputSets.push_back( new DataSet_double() ); } else { // Assume string. Not allowed for index column. if (col == indexcol_) { mprintf("Warning: '%s' index column %i has string values. No indices will be read.\n", buffer.Filename().full(), indexcol_+1); indexcol_ = -1; } inputSets.push_back( new DataSet_string() ); } inputSets.back()->SetMeta( md ); nsets++; } } if (inputSets.empty() || nsets == 0) { mprinterr("Error: No data detected.\n"); return 1; } // Read in data while (linebuffer != 0) { if ( buffer.TokenizeLine( SEPARATORS ) != ntoken ) { PrintColumnError(buffer.LineNumber()); break; } // Convert data in columns for (int i = 0; i < ntoken; ++i) { const char* token = buffer.NextToken(); if (inputSets[i] != 0) { if (inputSets[i]->Type() == DataSet::DOUBLE) ((DataSet_double*)inputSets[i])->AddElement( atof(token) ); else if (inputSets[i]->Type() == DataSet::INTEGER) ((DataSet_integer*)inputSets[i])->AddElement( atoi(token) ); else ((DataSet_string*)inputSets[i])->AddElement( std::string(token) ); } } //Ndata++; linebuffer = buffer.Line(); } buffer.CloseFile(); mprintf("\tDataFile %s has %i columns, %i lines.\n", buffer.Filename().full(), ntoken, buffer.LineNumber()); // Create list containing only data sets. DataSetList::DataListType mySets; DataSet_double* Xptr = 0; for (int idx = 0; idx != (int)inputSets.size(); idx++) { if (inputSets[idx] != 0) { if ( idx != indexcol_ ) mySets.push_back( inputSets[idx] ); else Xptr = (DataSet_double*)inputSets[idx]; } } mprintf("\tRead %zu data sets.\n", mySets.size()); std::string Xlabel; if (indexcol_ != -1 && indexcol_ < labels.Nargs()) Xlabel = labels[indexcol_]; if (Xptr == 0) datasetlist.AddOrAppendSets(Xlabel, DataSetList::Darray(), mySets); else { datasetlist.AddOrAppendSets(Xlabel, Xptr->Data(), mySets); delete Xptr; } return 0; }
// Action_MakeStructure::Init() Action::RetType Action_MakeStructure::Init(ArgList& actionArgs, TopologyList* PFL, DataSetList* DSL, DataFileList* DFL, int debugIn) { debug_ = debugIn; secstruct_.clear(); // Get all arguments std::string ss_expr = actionArgs.GetStringNext(); while ( !ss_expr.empty() ) { ArgList ss_arg(ss_expr, ":"); if (ss_arg.Nargs() < 2) { mprinterr("Error: Malformed SS arg.\n"); Help(); return Action::ERR; } // Type is 1st arg, range is 2nd arg. SecStructHolder ss_holder(ss_arg[1], FindSStype(ss_arg[0])); if (ss_arg.Nargs() == 2) { // Find SS type: <ss type>:<range> if (ss_holder.sstype_idx == SS_EMPTY) { mprinterr("Error: SS type %s not found.\n", ss_arg[0].c_str()); return Action::ERR; } ss_holder.dihSearch_.SearchFor(MetaData::PHI); ss_holder.dihSearch_.SearchFor(MetaData::PSI); secstruct_.push_back( ss_holder ); } else if (ss_arg[0] == "ref") { // Use dihedrals from reference structure if (ss_arg.Nargs() < 3) { mprinterr("Error: Invalid 'ref' arg. Requires 'ref:<range>:<refname>[:<ref range>]'\n"); return Action::ERR; } ss_arg.MarkArg(0); ss_arg.MarkArg(1); // Sanity check: Currently only unique args of this type are allowed if (ss_holder.sstype_idx != SS_EMPTY) { mprinterr("Error: Ref backbone types must be unique [%s]\n", ss_arg[0].c_str()); return Action::ERR; } // Use backbone phi/psi from reference structure ss_holder.dihSearch_.SearchFor(MetaData::PHI); ss_holder.dihSearch_.SearchFor(MetaData::PSI); // Get reference structure DataSet_Coords_REF* REF = (DataSet_Coords_REF*) DSL->FindSetOfType(ss_arg.GetStringNext(), DataSet::REF_FRAME); // ss_arg[2] if (REF == 0) { mprinterr("Error: Could not get reference structure [%s]\n", ss_arg[2].c_str()); return Action::ERR; } // Get reference residue range, or use resRange Range refRange(ss_arg.GetStringNext(), -1); // ss_arg[3] if (!refRange.Empty()) { if (ss_holder.resRange.Size() != refRange.Size()) { mprinterr("Error: Reference range [%s] must match residue range [%s]\n", refRange.RangeArg(), ss_holder.resRange.RangeArg()); return Action::ERR; } } else refRange = ss_holder.resRange; // Look for phi/psi only in reference DihedralSearch refSearch; refSearch.SearchFor(MetaData::PHI); refSearch.SearchFor(MetaData::PSI); if (refSearch.FindDihedrals( REF->Top(), refRange )) return Action::ERR; // For each found dihedral, set theta for (DihedralSearch::mask_it dih = refSearch.begin(); dih != refSearch.end(); ++dih) { double torsion = Torsion( REF->RefFrame().XYZ(dih->A0()), REF->RefFrame().XYZ(dih->A1()), REF->RefFrame().XYZ(dih->A2()), REF->RefFrame().XYZ(dih->A3()) ); ss_holder.thetas_.push_back( (float)torsion ); } secstruct_.push_back( ss_holder ); } else if (ss_arg.Nargs() == 4 && isalpha(ss_arg[2][0])) { // Single dihedral type: <name>:<range>:<dih type>:<angle> DihedralSearch::DihedralType dtype = DihedralSearch::GetType(ss_arg[2]); if (ss_holder.sstype_idx == SS_EMPTY) { // Type not yet defined. Create new type. if (dtype == MetaData::UNDEFINED) { mprinterr("Error: Dihedral type %s not found.\n", ss_arg[2].c_str()); return Action::ERR; } if (!validDouble(ss_arg[3])) { mprinterr("Error: 4th arg (angle) is not a valid number.\n"); return Action::ERR; } SS.push_back( SS_TYPE(convertToDouble(ss_arg[3]), 0.0, 0.0, 0.0, 2, ss_arg[0]) ); ss_holder.sstype_idx = (int)(SS.size() - 1); } ss_holder.dihSearch_.SearchFor( dtype ); secstruct_.push_back( ss_holder ); } else if (ss_arg.Nargs() == 7 || ss_arg.Nargs() == 8) { // Single custom dihedral type: <name>:<range>:<at0>:<at1>:<at2>:<at3>:<angle>[:<offset>] if (ss_holder.sstype_idx == SS_EMPTY) { // Type not yet defined. Create new type. if (!validDouble(ss_arg[6])) { mprinterr("Error: 7th arg (angle) is not a valid number.\n"); return Action::ERR; } SS.push_back( SS_TYPE(convertToDouble(ss_arg[6]), 0.0, 0.0, 0.0, 2, ss_arg[0]) ); ss_holder.sstype_idx = (int)(SS.size() - 1); } int offset = 0; if (ss_arg.Nargs() == 8) { if (!validInteger(ss_arg[7])) { mprinterr("Error: 8th arg (offset) is not a valid number.\n"); return Action::ERR; } offset = convertToInteger(ss_arg[7]); } ss_holder.dihSearch_.SearchForNewType(offset,ss_arg[2],ss_arg[3],ss_arg[4],ss_arg[5], ss_arg[0]); secstruct_.push_back( ss_holder ); } else if (ss_arg.Nargs() == 4 || ss_arg.Nargs() == 6) { // Custom SS/turn type: <name>:<range>:<phi1>:<psi1>[:<phi2>:<psi2>] if (ss_holder.sstype_idx == SS_EMPTY) { // Type not yet defined. Create new type. if (!validDouble(ss_arg[2]) || !validDouble(ss_arg[3])) { mprinterr("Error: 3rd or 4th arg (phi1/psi1) is not a valid number.\n"); return Action::ERR; } double phi1 = convertToDouble(ss_arg[2]); double psi1 = convertToDouble(ss_arg[3]); int isTurn = 0; double phi2 = 0.0; double psi2 = 0.0; if (ss_arg.Nargs() == 6) { isTurn = 1; if (!validDouble(ss_arg[4]) || !validDouble(ss_arg[5])) { mprinterr("Error: 5th or 6th arg (phi2/psi2) is not a valid number.\n"); return Action::ERR; } phi2 = convertToDouble(ss_arg[4]); psi2 = convertToDouble(ss_arg[5]); } SS.push_back(SS_TYPE(phi1, psi1, phi2, psi2, isTurn, ss_arg[0] )); ss_holder.sstype_idx = (int)(SS.size() - 1); } ss_holder.dihSearch_.SearchFor(MetaData::PHI); ss_holder.dihSearch_.SearchFor(MetaData::PSI); secstruct_.push_back( ss_holder ); } else { mprinterr("Error: SS arg type [%s] not recognized.\n", ss_arg[0].c_str()); return Action::ERR; } ss_expr = actionArgs.GetStringNext(); } // End loop over args if (secstruct_.empty()) { mprinterr("Error: No SS types defined.\n"); return Action::ERR; } mprintf(" MAKESTRUCTURE:\n"); for (std::vector<SecStructHolder>::iterator ss = secstruct_.begin(); ss != secstruct_.end(); ++ss) { if (ss->sstype_idx != SS_EMPTY) { const SS_TYPE& myType = SS[ss->sstype_idx]; switch ( myType.isTurn ) { case 0: mprintf("\tSS type %s will be applied to residue(s) %s\n", myType.type_arg.c_str(), ss->resRange.RangeArg()); break; case 1: mprintf("\tTurn type %s will be applied to residue(s) %s\n", myType.type_arg.c_str(), ss->resRange.RangeArg()); break; case 2: mprintf("\tDihedral value of %.2f will be applied to %s dihedrals in residue(s) %s\n", myType.phi, myType.type_arg.c_str(), ss->resRange.RangeArg()); } } else mprintf("\tBackbone angles from reference will be applied to residue(s) %s\n", ss->resRange.RangeArg()); } return Action::OK; }