// DataIO_Std::WriteData() int DataIO_Std::WriteData(FileName const& fname, DataSetList const& SetList) { int err = 0; if (!SetList.empty()) { // Open output file. CpptrajFile file; if (file.OpenWrite( fname )) return 1; // Base write type off first data set dimension FIXME if (SetList[0]->Group() == DataSet::CLUSTERMATRIX) { // Special case of 2D - may have sieved frames. err = WriteCmatrix(file, SetList); } else if (SetList[0]->Ndim() == 1) { if (group_ == NO_TYPE) { if (isInverted_) err = WriteDataInverted(file, SetList); else err = WriteDataNormal(file, SetList); } else err = WriteByGroup(file, SetList, group_); } else if (SetList[0]->Ndim() == 2) err = WriteData2D(file, SetList); else if (SetList[0]->Ndim() == 3) err = WriteData3D(file, SetList); file.CloseFile(); } return err; }
// DataSetList::GetMultipleSets() DataSetList DataSetList::GetMultipleSets( std::string const& dsargIn ) const { DataSetList dsetOut = SelectSets(dsargIn); if ( dsetOut.empty() ) { mprintf("Warning: '%s' selects no data sets.\n", dsargIn.c_str()); PendingWarning(); } return dsetOut; }
// DataSetList::FindSetOfType() DataSet* DataSetList::FindSetOfType(std::string const& nameIn, DataSet::DataType typeIn) const { DataSetList dsetOut = SelectSets( nameIn, typeIn ); if (dsetOut.empty()) return 0; else if (dsetOut.size() > 1) mprintf("Warning: '%s' selects multiple sets. Only using first.\n"); return dsetOut[0]; }
// DataSetList::GetDataSet() DataSet* DataSetList::GetDataSet( std::string const& nameIn ) const { DataSetList dsetOut = SelectSets( nameIn ); if (dsetOut.empty()) { mprintf("Warning: Data set '%s' not found.\n", nameIn.c_str()); PendingWarning(); return 0; } else if (dsetOut.size() > 1) mprintf("Warning: '%s' selects multiple sets, only using first set.\n"); return dsetOut[0]; }
/** Search for a COORDS DataSet. If no name specified, create a default * COORDS DataSet named _DEFAULTCRD_. */ DataSet* DataSetList::FindCoordsSet(std::string const& setname) { DataSet* outset = 0; if (setname.empty()) { // crdset not given, search for the default set outset = FindSetOfType("_DEFAULTCRD_", DataSet::COORDS); if (outset == 0) { // No default set; create one. outset = AddSet(DataSet::COORDS, "_DEFAULTCRD_", "CRD"); } } else { DataSetList dslist = SelectGroupSets(setname, DataSet::COORDINATES); if (!dslist.empty()) outset = dslist[0]; } return outset; }
// DataIO_Std::WriteDataInverted() int DataIO_Std::WriteDataInverted(CpptrajFile& file, DataSetList const& Sets) { if (Sets.empty() || CheckAllDims(Sets, 1)) return 1; // Determine size of largest DataSet. size_t maxFrames = DetermineMax( Sets ); // Write each set to a line. DataSet::SizeArray positions(1); // Set up x column format DataSetList::const_iterator set = Sets.begin(); TextFormat x_col_format; if (hasXcolumn_) x_col_format = XcolFmt(); else x_col_format = (*set)->Format(); for (; set != Sets.end(); ++set) { // Write dataset name as first column. WriteNameToBuffer( file, (*set)->Meta().Legend(), x_col_format.ColumnWidth(), false); // Write each frame to subsequent columns for (positions[0] = 0; positions[0] < maxFrames; positions[0]++) (*set)->WriteBuffer(file, positions); file.Printf("\n"); } return 0; }
// Exec_SortEnsembleData::SortData() int Exec_SortEnsembleData::SortData(DataSetList const& setsToSort, DataSetList& OutputSets) const { int err = 0; if (setsToSort.empty()) { rprinterr("Error: No sets selected.\n"); err = 1; } if (CheckError(err)) return 1; mprintf("\tSorting the following sets:\n"); setsToSort.List(); # ifdef MPI // Number of sets to sort should be equal to # members I am responsible for. if (Parallel::N_Ens_Members() != (int)setsToSort.size()) { rprinterr("Internal Error: Number of ensemble members (%i) != # sets to sort (%zu)\n", Parallel::N_Ens_Members(), setsToSort.size()); return 1; } # endif DataSet::DataType dtype = setsToSort[0]->Type(); unsigned int maxSize = 0; for (DataSetList::const_iterator ds = setsToSort.begin(); ds != setsToSort.end(); ++ds) { if ((*ds)->Size() < 1) { //TODO check sizes match rprinterr("Error: Set '%s' is empty.\n", (*ds)->legend()); err = 1; break; } if (ds == setsToSort.begin()) maxSize = (*ds)->Size(); else if ((*ds)->Size() < maxSize) { rprintf("Warning: Set '%s' has fewer frames (%zu) than previous set(s) (%u)\n" "Warning: Only using the first %zu frames of all sets.\n", (*ds)->legend(), (*ds)->Size(), maxSize, (*ds)->Size()); maxSize = (unsigned int)(*ds)->Size(); } else if ((*ds)->Size() > maxSize) { rprintf("Warning: Set '%s' has more frames (%zu) than previous set(s) (%u)\n" "Warning: Only using the first %u frames of all sets.\n", (*ds)->legend(), (*ds)->Size(), maxSize, maxSize); } if (dtype != (*ds)->Type()) { rprinterr("Error: Set '%s' has different type than first set.\n", (*ds)->legend()); err = 1; break; } } if (CheckError(err)) return 1; # ifdef MPI unsigned int threadSize = maxSize; comm_.AllReduce( &maxSize, &threadSize, 1, MPI_UNSIGNED, MPI_MIN ); typedef std::vector<int> Iarray; Iarray Dtypes( comm_.Size(), -1 ); if ( comm_.AllGather( &dtype, 1, MPI_INT, &Dtypes[0] ) ) return 1; for (int rank = 1; rank < comm_.Size(); rank++) if (Dtypes[0] != Dtypes[rank]) { rprinterr("Error: Set types on rank %i do not match types on rank 0.\n", rank); err = 1; break; } if (comm_.CheckError( err )) return 1; # endif // Only work for pH data for now. if (dtype != DataSet::PH_EXPL && dtype != DataSet::PH_IMPL) { rprinterr("Error: Only works for pH REMD data for now.\n"); return 1; } err = Sort_pH_Data( setsToSort, OutputSets, maxSize ); return err; }
// 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::WriteDataNormal() int DataIO_Std::WriteDataNormal(CpptrajFile& file, DataSetList const& Sets) { // Assume all 1D data sets. if (Sets.empty() || CheckAllDims(Sets, 1)) return 1; // For this output to work the X-dimension of all sets needs to match. // The most important things for output are min and step so just check that. // Use X dimension of set 0 for all set dimensions. CheckXDimension( Sets ); // TODO: Check for empty dim. DataSet* Xdata = Sets[0]; Dimension const& Xdim = static_cast<Dimension const&>( Xdata->Dim(0) ); int xcol_width = Xdim.Label().size() + 1; // Only used if hasXcolumn_ if (xcol_width < 8) xcol_width = 8; int xcol_precision = 3; // Determine size of largest DataSet. size_t maxFrames = DetermineMax( Sets ); // Set up X column. TextFormat x_col_format(XcolFmt()); if (hasXcolumn_) { if (XcolPrecSet()) { xcol_width = XcolWidth(); x_col_format = TextFormat(XcolFmt(), XcolWidth(), XcolPrec()); } else { // Create format string for X column based on dimension in first data set. // Adjust X col precision as follows: if the step is set and has a // fractional component set the X col width/precision to either the data // width/precision or the current width/precision, whichever is larger. If // the set is XYMESH but step has not been set (so we do not know spacing // between X values) use default precision. Otherwise the step has no // fractional component so make the precision zero. double step_i; double step_f = modf( Xdim.Step(), &step_i ); double min_f = modf( Xdim.Min(), &step_i ); if (Xdim.Step() > 0.0 && (step_f > 0.0 || min_f > 0.0)) { xcol_precision = std::max(xcol_precision, Xdata->Format().Precision()); xcol_width = std::max(xcol_width, Xdata->Format().Width()); } else if (Xdata->Type() != DataSet::XYMESH) xcol_precision = 0; x_col_format.SetCoordFormat( maxFrames, Xdim.Min(), Xdim.Step(), xcol_width, xcol_precision ); } } else { // If not writing an X-column, no leading space for the first dataset. Xdata->SetupFormat().SetFormatAlign( TextFormat::RIGHT ); } // Write header to buffer std::vector<int> Original_Column_Widths; if (writeHeader_) { // If x-column present, write x-label if (hasXcolumn_) WriteNameToBuffer( file, Xdim.Label(), xcol_width, true ); // To prevent truncation of DataSet legends, adjust the width of each // DataSet if necessary. for (DataSetList::const_iterator ds = Sets.begin(); ds != Sets.end(); ++ds) { // Record original column widths in case they are changed. Original_Column_Widths.push_back( (*ds)->Format().Width() ); int colLabelSize; if (ds == Sets.begin() && !hasXcolumn_) colLabelSize = (int)(*ds)->Meta().Legend().size() + 1; else colLabelSize = (int)(*ds)->Meta().Legend().size(); //mprintf("DEBUG: Set '%s', fmt width= %i, colWidth= %i, colLabelSize= %i\n", // (*ds)->legend(), (*ds)->Format().Width(), (*ds)->Format().ColumnWidth(), // colLabelSize); if (colLabelSize >= (*ds)->Format().ColumnWidth()) (*ds)->SetupFormat().SetFormatWidth( colLabelSize ); } // Write dataset names to header, left-aligning first set if no X-column DataSetList::const_iterator set = Sets.begin(); if (!hasXcolumn_) WriteNameToBuffer( file, (*set)->Meta().Legend(), (*set)->Format().ColumnWidth(), true ); else WriteNameToBuffer( file, (*set)->Meta().Legend(), (*set)->Format().ColumnWidth(), false ); ++set; for (; set != Sets.end(); ++set) WriteNameToBuffer( file, (*set)->Meta().Legend(), (*set)->Format().ColumnWidth(), false ); file.Printf("\n"); } // Write Data DataSet::SizeArray positions(1); for (positions[0] = 0; positions[0] < maxFrames; positions[0]++) { // Output Frame for each set if (hasXcolumn_) file.Printf( x_col_format.fmt(), Xdata->Coord(0, positions[0]) ); for (DataSetList::const_iterator set = Sets.begin(); set != Sets.end(); ++set) (*set)->WriteBuffer(file, positions); file.Printf("\n"); } // Restore original column widths if necessary if (!Original_Column_Widths.empty()) for (unsigned int i = 0; i != Original_Column_Widths.size(); i++) Sets[i]->SetupFormat().SetFormatWidth( Original_Column_Widths[i] ); return 0; }