// DataIO_Std::WriteData3D() int DataIO_Std::WriteData3D( CpptrajFile& file, DataSetList const& setList) { int err = 0; for (DataSetList::const_iterator set = setList.begin(); set != setList.end(); ++set) { if (set != setList.begin()) file.Printf("\n"); err += WriteSet3D( *(*set), file ); } 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; }
// Array1D::AddDataSets() int Array1D::AddDataSets(DataSetList const& SetList) { for (DataSetList::const_iterator ds = SetList.begin(); ds != SetList.end(); ++ds) if ( push_back( *ds ) ) { array_.clear(); return 1; } return 0; }
// 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; }
// DataSetList::GetSetsOfType() DataSetList DataSetList::GetSetsOfType( std::string const& dsargIn, DataSet::DataType typeIn ) const { DataSetList dsetOut; dsetOut.hasCopies_ = true; DataSetList selected = SelectSets(dsargIn); for (const_iterator ds = selected.begin(); ds != selected.end(); ++ds) if ( (*ds)->Type() == typeIn ) dsetOut.Push_Back( *ds ); return dsetOut; }
// DataSetList::SetPrecisionOfDataSets() void DataSetList::SetPrecisionOfDataSets(std::string const& nameIn, int widthIn, int precisionIn) { if (widthIn < 1) mprinterr("Error: Invalid data width (%i)\n", widthIn); else { DataSetList Sets = GetMultipleSets( nameIn ); for (DataSetList::const_iterator ds = Sets.begin(); ds != Sets.end(); ++ds) (*ds)->SetupFormat().SetFormatWidthPrecision(widthIn, precisionIn); } }
// Array1D::AddTorsionSets() int Array1D::AddTorsionSets(DataSetList const& SetList) { // Ensure data sets are 1D and periodic for (DataSetList::const_iterator ds = SetList.begin(); ds != SetList.end(); ++ds) { if ( (*ds)->Meta().IsTorsionArray()) { if ( push_back( *ds ) ) { array_.clear(); return 1; } } else mprintf("Warning: Set '%s' is not periodic, skipping.\n", (*ds)->legend()); } return 0; }
// DataIO_CCP4::WriteData() int DataIO_CCP4::WriteData(FileName const& fname, DataSetList const& setList) { // Open output file CpptrajFile outfile; if (outfile.OpenWrite(fname)) { mprinterr("Error: Could not open CCP4 output file '%s'.\n", fname.full()); return 1; } // Warn about writing multiple sets if (setList.size() > 1) mprintf("Warning: %s: Writing multiple 3D sets in CCP4 format not supported.\n" "Warning: Only writing first set.\n", fname.full()); return WriteSet3D( setList.begin(), outfile ); }
// DataIO_OpenDx::WriteData() int DataIO_OpenDx::WriteData(FileName const& fname, DataSetList const& setList) { // Open output file CpptrajFile outfile; if (outfile.OpenWrite(fname)) { mprinterr("Error: Could not open OpenDX output file.\n"); return 1; } // Warn about writing multiple sets if (setList.size() > 1) mprintf("Warning: %s: Writing multiple 3D sets in OpenDX format may result in unexpected behavior\n", fname.full()); int err = 0; for (DataSetList::const_iterator set = setList.begin(); set != setList.end(); ++set) err += WriteSet3D( *(*set), outfile ); return err; }
// 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; }
// DataIO_Std::WriteCmatrix() int DataIO_Std::WriteCmatrix(CpptrajFile& file, DataSetList const& Sets) { for (DataSetList::const_iterator ds = Sets.begin(); ds != Sets.end(); ++ds) { if ( (*ds)->Group() != DataSet::CLUSTERMATRIX) { mprinterr("Error: Write of cluster matrix and other sets to same file not supported.\n" "Error: Skipping '%s'\n", (*ds)->legend()); continue; } DataSet_Cmatrix const& cm = static_cast<DataSet_Cmatrix const&>( *(*ds) ); int nrows = cm.OriginalNframes(); int col_width = std::max(3, DigitWidth( nrows ) + 1); int dat_width = std::max(cm.Format().Width(), (int)cm.Meta().Legend().size()) + 1; WriteNameToBuffer(file, "F1", col_width, true); WriteNameToBuffer(file, "F2", col_width, false); WriteNameToBuffer(file, cm.Meta().Legend(), dat_width, false); if (cm.SieveType() != ClusterSieve::NONE) file.Printf(" nframes %i", cm.OriginalNframes()); file.Printf("\n"); TextFormat col_fmt(TextFormat::INTEGER, col_width); TextFormat dat_fmt = cm.Format(); dat_fmt.SetFormatAlign(TextFormat::RIGHT); dat_fmt.SetFormatWidth( dat_width ); std::string total_fmt = col_fmt.Fmt() + col_fmt.Fmt() + dat_fmt.Fmt() + "\n"; //mprintf("DEBUG: format '%s'\n", total_fmt.c_str()); ClusterSieve::SievedFrames const& frames = cm.FramesToCluster(); int ntotal = (int)frames.size(); for (int idx1 = 0; idx1 != ntotal; idx1++) { int row = frames[idx1]; for (int idx2 = idx1 + 1; idx2 != ntotal; idx2++) { int col = frames[idx2]; file.Printf(total_fmt.c_str(), row+1, col+1, cm.GetFdist(col, row)); } } } return 0; }
// 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; }
Analysis::RetType Analysis_AutoCorr::Setup(ArgList& analyzeArgs, AnalysisSetup& setup, int debugIn) { const char* calctype; std::string setname = analyzeArgs.GetStringKey("name"); DataFile* outfile = setup.DFL().AddDataFile( analyzeArgs.GetStringKey("out"), analyzeArgs ); lagmax_ = analyzeArgs.getKeyInt("lagmax",-1); calc_covar_ = !analyzeArgs.hasKey("nocovar"); usefft_ = !analyzeArgs.hasKey("direct"); // Select datasets from remaining args dsets_.clear(); ArgList dsetArgs = analyzeArgs.RemainingArgs(); for (ArgList::const_iterator dsa = dsetArgs.begin(); dsa != dsetArgs.end(); ++dsa) { DataSetList setsIn = setup.DSL().GetMultipleSets( *dsa ); for (DataSetList::const_iterator ds = setsIn.begin(); ds != setsIn.end(); ++ds) { if ( (*ds)->Group() != DataSet::SCALAR_1D && (*ds)->Type() != DataSet::VECTOR ) mprintf("Warning: Set '%s' type not supported in AUTOCORR - skipping.\n", (*ds)->legend()); else dsets_.push_back( *ds ); } } if (dsets_.empty()) { mprinterr("Error: No data sets selected.\n"); return Analysis::ERR; } // If setname is empty generate a default name if (setname.empty()) setname = setup.DSL().GenerateDefaultName( "autocorr" ); // Setup output datasets MetaData md( setname ); for (unsigned int idx = 0; idx != dsets_.size(); idx++) { md.SetIdx( idx ); DataSet* dsout = setup.DSL().AddSet( DataSet::DOUBLE, md ); if (dsout==0) return Analysis::ERR; dsout->SetLegend( dsets_[idx]->Meta().Legend() ); outputData_.push_back( dsout ); // Add set to output file if (outfile != 0) outfile->AddDataSet( outputData_.back() ); } if (calc_covar_) calctype = "covariance"; else calctype = "correlation"; mprintf(" AUTOCORR: Calculating auto-%s for %i data sets:\n\t", calctype, dsets_.size()); for (unsigned int idx = 0; idx != dsets_.size(); ++idx) mprintf(" %s", dsets_[idx]->legend()); mprintf("\n"); if (lagmax_!=-1) mprintf("\tLag max= %i\n", lagmax_); if ( !setname.empty() ) mprintf("\tSet name: %s\n", setname.c_str() ); if ( outfile != 0 ) mprintf("\tOutfile name: %s\n", outfile->DataFilename().base()); if (usefft_) mprintf("\tUsing FFT to calculate %s.\n", calctype); else mprintf("\tUsing direct method to calculate %s.\n", calctype); return Analysis::OK; }
// Exec_SortEnsembleData::Sort_pH_Data() int Exec_SortEnsembleData::Sort_pH_Data(DataSetList const& setsToSort, DataSetList& OutputSets, unsigned int maxFrames) const { // Cast sets back to DataSet_PHREMD typedef std::vector<DataSet_PHREMD*> Parray; Parray PHsets; for (DataSetList::const_iterator ds = setsToSort.begin(); ds != setsToSort.end(); ++ds) PHsets.push_back( (DataSet_PHREMD*)*ds ); // Gather initial pH data values, ensure no duplicates typedef std::vector<double> Darray; Darray pHvalues; # ifdef MPI pHvalues.resize( Parallel::Ensemble_Size() ); Darray phtmp; for (Parray::const_iterator ds = PHsets.begin(); ds != PHsets.end(); ++ds) phtmp.push_back( (*ds)->Initial_pH() ); if (comm_.AllGather(&phtmp[0], phtmp.size(), MPI_DOUBLE, &pHvalues[0])) { rprinterr("Error: Gathering pH values.\n"); return 1; } # else for (Parray::const_iterator ds = PHsets.begin(); ds != PHsets.end(); ++ds) pHvalues.push_back( (*ds)->Initial_pH() ); # endif ReplicaInfo::Map<double> pH_map; if (pH_map.CreateMap( pHvalues )) { rprinterr("Error: Duplicate pH value detected (%.2f) in ensemble.\n", pH_map.Duplicate()); return 1; } Darray sortedPH; mprintf("\tInitial pH values:"); for (ReplicaInfo::Map<double>::const_iterator ph = pH_map.begin(); ph != pH_map.end(); ++ph) { mprintf(" %6.2f", ph->first); sortedPH.push_back( ph->first ); } mprintf("\n"); // Create sets to hold sorted pH values. Create a set for each pH value // and each residue. Final output sets will be PH0R0, PH0R1, PH1R0, ... // TODO check that residue info all the same DataSet_PHREMD::Rarray const& Residues = PHsets[0]->Residues(); int defaultState = 0; # ifdef MPI if ( PHsets[0]->Type() == DataSet::PH_IMPL) defaultState = -1; # endif if (debug_ > 0) rprintf("DEBUG: Sorting %u frames for %zu sets, %zu pH values.\n", maxFrames, PHsets.size(), sortedPH.size()); for (unsigned int idx = 0; idx != sortedPH.size(); idx++) { OutputSets.SetEnsembleNum( idx ); for (unsigned int res = 0; res != Residues.size(); ++res) { MetaData md(PHsets[0]->Meta().Name(), Residues[res].Name().Truncated(), Residues[res].Num()); DataSet_pH* out = (DataSet_pH*)OutputSets.AddSet( DataSet::PH, md ); if (out==0) return 1; //out->SetLegend( "pH " + doubleToString( sortedPH[idx] ) ); out->Set_Solvent_pH( sortedPH[idx] ); out->SetResidueInfo( Residues[res] ); out->SetTimeValues(PHsets[0]->Time()); out->Resize( maxFrames, defaultState ); } } // --------------------------------------------- if ( PHsets[0]->Type() == DataSet::PH_EXPL) { // Loop over unsorted sets for (Parray::const_iterator ds = PHsets.begin(); ds != PHsets.end(); ++ds) { DataSet_PHREMD_Explicit* in = (DataSet_PHREMD_Explicit*)*ds; unsigned int phidx = 0; for (unsigned int n = 0; n < maxFrames; n++) { float phval = in->pH_Values()[n]; int setidx = pH_map.FindIndex( phval ) * Residues.size(); //rprintf("DEBUG: %6u Set %10s pH= %6.2f going to %2i\n", n+1, in->legend(), phval, idx); //mflush(); for (unsigned int res = 0; res < in->Residues().size(); res++, setidx++, phidx++) { DataSet_pH* out = (DataSet_pH*)OutputSets[setidx]; //if (res == 0 && idx == 0) { // rprintf("DEBUG: Frame %3u res %2u State %2i pH %6.2f\n", // n, res, in->Res(res).State(n), phval); // mflush(); //} out->SetState(n, in->ResStates()[phidx], in->RecordType(n)); } } } // END loop over unsorted sets # ifdef MPI // Now we need to reduce down each set onto the thread where it belongs. if (Parallel::World().Size() > 1) { for (int idx = 0; idx != (int)OutputSets.size(); idx++) { DataSet_pH* out = (DataSet_pH*)OutputSets[idx]; int ensembleRank = Parallel::MemberEnsCommRank( out->Meta().EnsembleNum() ); //rprintf("DEBUG: Reduce set %s to rank %i\n", out->legend(), ensembleRank); out->Reduce( comm_, ensembleRank ); } // Remove sets that do not belong on this rank for (int idx = (int)OutputSets.size() - 1; idx > -1; idx--) { DataSet* out = OutputSets[idx]; int ensembleRank = Parallel::MemberEnsCommRank( out->Meta().EnsembleNum() ); if (ensembleRank != comm_.Rank()) { //rprintf("DEBUG: Remove set %s (%i) from rank %i\n", out->legend(), // idx, comm_.Rank()); OutputSets.RemoveSet( out ); } } } # endif // --------------------------------------------- } else if ( PHsets[0]->Type() == DataSet::PH_IMPL) { # ifdef MPI typedef std::vector<int> Iarray; typedef std::vector<Iarray> Iarray2; typedef std::vector<bool> Barray; // True if I have this pH value Barray isMyPh( sortedPH.size(), false ); // Which rank in ensemble has which pH Iarray pHrank( sortedPH.size(), 0 ); for (int phidx = 0; phidx != (int)sortedPH.size(); phidx++) { int ensembleRank = Parallel::MemberEnsCommRank( phidx ); pHrank[phidx] = ensembleRank; isMyPh[phidx] = (ensembleRank == comm_.Rank()); } // DEBUG for (unsigned int idx = 0; idx != pHrank.size(); idx++) mprintf("\tpH %6.2f on rank %i\n", sortedPH[idx], pHrank[idx]); // Hold frame-residue-state for each pH not on this rank. Iarray2 FrmResState( sortedPH.size() ); // Loop over unsorted sets for (Parray::const_iterator ds = PHsets.begin(); ds != PHsets.end(); ++ds) { DataSet_PHREMD_Implicit* in = (DataSet_PHREMD_Implicit*)*ds; // Loop over frames for (unsigned int n = 0; n < maxFrames; n++) { DataSet_PHREMD_Implicit::Record const& Rec = in->Records()[n]; float phval = Rec.pH(); int phidx = pH_map.FindIndex( phval ); if (isMyPh[phidx]) { // This pH belongs to me. Set value. int setidx = phidx * Residues.size(); if (Rec.RecType() == Cph::FULL_RECORD) { // Info for all residues for (unsigned int res = 0; res < in->Residues().size(); res++, setidx++) ((DataSet_pH*)OutputSets[setidx])->SetState(n, Rec.ResStates()[res], Rec.RecType()); } else if (Rec.RecType() > -1) { // Info for single residue, record type for all residues //rprintf("\tSetting my pH %6.2f frame %8i state %2i idx %6i res %6i '%s'\n", sortedPH[phidx], n, Rec.ResStates()[0], setidx, Rec.RecType(), OutputSets[setidx+Rec.RecType()]->legend()); for (int res = 0; res < (int)in->Residues().size(); res++, setidx++) if (res == Rec.RecType()) ((DataSet_pH*)OutputSets[setidx])->SetState(n, Rec.ResStates()[0], Rec.RecType()); else ((DataSet_pH*)OutputSets[setidx])->SetRecType(n, Rec.RecType()); } } else { // This pH belongs to another rank. Save it. if (Rec.RecType() > -1) { // Info for a single residue present FrmResState[phidx].push_back( n ); FrmResState[phidx].push_back( Rec.RecType() ); FrmResState[phidx].push_back( Rec.ResStates()[0] ); } else { // Info for all residues present FrmResState[phidx].push_back( n ); FrmResState[phidx].push_back( Rec.RecType() ); for (unsigned int res = 0; res < in->Residues().size(); res++) FrmResState[phidx].push_back( Rec.ResStates()[res] ); } } } // END loop over frames } // END loop over sets // DEBUG /* comm_.Barrier(); for (int rank = 0; rank < comm_.Size(); rank++) { if (rank == comm_.Rank()) { for (unsigned int phidx = 0; phidx != sortedPH.size(); phidx++) { rprintf("DEBUG: pH %6.2f: %8s %6s %2s\n", sortedPH[phidx], "Frm", "Res", "St"); Iarray const& FRS = FrmResState[phidx]; unsigned int idx = 0; while (idx < FRS.size()) { int rec = FRS[idx+1]; if (rec > -1) { rprintf(" %8i %6i %2i\n", FRS[idx], rec, FRS[idx+2]); idx += 3; } else { rprintf(" %8i %6i All Residues\n", FRS[idx], rec); idx += (2 + Residues.size()); } } } } comm_.Barrier(); } */ // Communicate states to other ranks typedef std::vector<unsigned int> Uarray; Uarray sizeOnRank( comm_.Size() ); for (unsigned int phidx = 0; phidx != sortedPH.size(); phidx++) { // Each rank says how many frames of this pH they have collected and // send to rank the pH belongs to. unsigned int nph = FrmResState[phidx].size(); comm_.Gather(&nph, 1, MPI_UNSIGNED, &sizeOnRank[0], pHrank[phidx]); if (pHrank[phidx] == comm_.Rank()) { // This pH belongs to me. I should have no frames at this pH. if (sizeOnRank[comm_.Rank()] > 0) { rprinterr("Internal Error: Rank has frames to communicate at its pH\n"); Parallel::Abort(1); } unsigned int totalSize = 0; for (unsigned int idx = 0; idx != sizeOnRank.size(); idx++) { totalSize += sizeOnRank[idx]; //rprintf("DEBUG: Rank %4u has %8u frames of pH %6.2f\n", // idx, sizeOnRank[idx], sortedPH[phidx]); } //rprintf("DEBUG: Total incoming size: %u\n", totalSize); FrmResState[phidx].resize( totalSize ); // Receive state info for this pH from other ranks int* frsArray = &(FrmResState[phidx][0]); for (int rank = 0; rank != comm_.Size(); rank++) { if (rank != comm_.Rank()) { comm_.Recv(frsArray, sizeOnRank[rank], MPI_INT, rank, 1600+rank); frsArray += sizeOnRank[rank]; } } } else { // This pH belongs to another rank. Send my info there. int* frsArray = &(FrmResState[phidx][0]); comm_.Send(frsArray, nph, MPI_INT, pHrank[phidx], 1600+comm_.Rank()); } comm_.Barrier(); } // Fill in state info std::vector<DataSet*> ToRemove; for (unsigned int phidx = 0; phidx != sortedPH.size(); phidx++) { int setidx = phidx * Residues.size(); if (pHrank[phidx] == comm_.Rank()) { Iarray const& FRS = FrmResState[phidx]; // This pH belongs to me. Fill in the information received from // other ranks. unsigned int idx = 0; while (idx < FRS.size()) { int rec = FRS[idx+1]; if (rec > -1) { // Info for single residue, record type for all residues //rprintf("\tSetting pH %6.2f frame %8i state %2i idx %6i res %6i '%s'\n", sortedPH[phidx], FRS[idx], FRS[idx+2], setidx, rec, OutputSets[setidx+rec]->legend()); for (int res = 0; res != (int)Residues.size(); res++) { DataSet_pH* out = (DataSet_pH*)OutputSets[setidx + res]; if (rec == res) out->SetState( FRS[idx], FRS[idx+2], rec ); else out->SetRecType( FRS[idx], rec ); } idx += 3; } else { //rprintf(" %8i %6i All Residues\n", FRS[idx], rec); int frm = FRS[idx]; idx += 2; for (unsigned int res = 0; res != Residues.size(); res++, idx++) { DataSet_pH* out = (DataSet_pH*)OutputSets[setidx + res]; out->SetState( frm, FRS[idx], rec ); } } } // Fill in any remaining data. FIXME safe to assume first frame is set? for (unsigned int res = 0; res != Residues.size(); res++) { DataSet_pH* out = (DataSet_pH*)OutputSets[setidx + res]; for (unsigned int n = 1; n < maxFrames; n++) if (out->State(n) == -1) out->SetState(n, out->State(n-1), out->RecordType(n)); } } else { // This pH does not belong to me. Mark associated data sets to be removed. for (unsigned int res = 0; res != Residues.size(); res++) ToRemove.push_back( OutputSets[setidx + res] ); } } // Remove data sets that do not belong to me. for (std::vector<DataSet*>::reverse_iterator it = ToRemove.rbegin(); it != ToRemove.rend(); ++it) { //rprintf("DEBUG: '%s' does not belong to me.\n", (*it)->legend()); OutputSets.RemoveSet( *it ); } # else /* if not MPI */ // Loop over frames for (unsigned int n = 0; n < maxFrames; n++) { // Loop over unsorted sets for (Parray::const_iterator ds = PHsets.begin(); ds != PHsets.end(); ++ds) { DataSet_PHREMD_Implicit* in = (DataSet_PHREMD_Implicit*)*ds; DataSet_PHREMD_Implicit::Record const& Rec = in->Records()[n]; float phval = Rec.pH(); int setidx = pH_map.FindIndex( phval ) * Residues.size(); if (Rec.RecType() == Cph::FULL_RECORD) { for (unsigned int res = 0; res < in->Residues().size(); res++, setidx++) { DataSet_pH* out = (DataSet_pH*)OutputSets[setidx]; //if (res == 0 && idx == 0) { // rprintf("DEBUG: Frame %3u res %2u State %2i pH %6.2f\n", // n, res, in->Res(res).State(n), phval); // mflush(); //} out->SetState(n, Rec.ResStates()[res], Rec.RecType()); } } else { for (int res = 0; res < (int)in->Residues().size(); res++, setidx++) { DataSet_pH* out = (DataSet_pH*)OutputSets[setidx]; if (res == Rec.RecType()) out->SetState(n, Rec.ResStates()[0], Rec.RecType()); else // State for this residue not recorded - use previous state. // Should be fine since first state always has all residues. out->SetState(n, out->State(n-1), Rec.RecType()); } } } // END loop over unsorted sets } // END loop over frames # endif /* MPI */ // --------------------------------------------- } else { return 1; // Sanity check } return 0; }
// 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; }
// 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::ModifyPoints() Exec::RetType Exec_DataSetCmd::ModifyPoints(CpptrajState& State, ArgList& argIn, bool drop) { const char* mode; if (drop) mode = "Drop"; else mode = "Kee"; // Keywords std::string name = argIn.GetStringKey("name"); int start = argIn.getKeyInt("start", 0) - 1; int stop = argIn.getKeyInt("stop", -1); int offset = argIn.getKeyInt("offset", -1); Range points; if (start < 0 && stop < 0 && offset < 0) { std::string rangearg = argIn.GetStringKey("range"); if (rangearg.empty()) { mprinterr("Error: Must specify range or start/stop/offset.\n"); return CpptrajState::ERR; } points.SetRange( rangearg ); if (points.Empty()) { mprinterr("Error: Range '%s' is empty.\n", rangearg.c_str()); return CpptrajState::ERR; } mprintf("\t%sping points in range %s\n", mode, rangearg.c_str()); // User args start from 1 points.ShiftBy(-1); } // Get data set to drop/keep points from // Loop over all DataSet arguments std::string ds_arg = argIn.GetStringNext(); while (!ds_arg.empty()) { DataSetList dsl = State.DSL().GetMultipleSets( ds_arg ); for (DataSetList::const_iterator it = dsl.begin(); it != dsl.end(); ++it) { DataSet* DS = *it; if (DS->Size() < 1) { mprinterr("Error: Set '%s' is empty.\n", DS->legend()); return CpptrajState::ERR; } // Restrict to 1D sets for now TODO more types if (DS->Group() != DataSet::SCALAR_1D) { mprinterr("Error: Currently only works for 1D scalar data sets.\n"); return CpptrajState::ERR; } DataSet_1D* ds1 = (DataSet_1D*)DS; // Output data set DataSet* out = 0; if (name.empty()) { // Modifying this set. Create new temporary set. out = State.DSL().Allocate( ds1->Type() ); if (out == 0) return CpptrajState::ERR; *out = *ds1; mprintf("\tOverwriting set '%s'\n", ds1->legend()); } else { // Write to new set MetaData md = ds1->Meta(); md.SetName( name ); out = State.DSL().AddSet(ds1->Type(), md); if (out == 0) return CpptrajState::ERR; mprintf("\tNew set is '%s'\n", out->Meta().PrintName().c_str()); } out->Allocate(DataSet::SizeArray(1, ds1->Size())); if (points.Empty()) { // Drop by start/stop/offset. Set defaults if needed if (start < 0) start = 0; if (stop < 0) stop = ds1->Size(); if (offset < 0) offset = 1; mprintf("\t%sping points from %i to %i, step %i\n", mode, start+1, stop, offset); for (int idx = start; idx < stop; idx += offset) points.AddToRange( idx ); } // TODO check that range values are valid? if (State.Debug() > 0) mprintf("DEBUG: Keeping points:"); Range::const_iterator pt = points.begin(); int idx = 0; int odx = 0; if (drop) { // Drop points for (; idx < (int)ds1->Size(); idx++) { if (pt == points.end()) break; if (*pt != idx) { if (State.Debug() > 0) mprintf(" %i", idx + 1); KeepPoint(ds1, out, idx, odx); } else ++pt; } // Keep all remaining points for (; idx < (int)ds1->Size(); idx++) { if (State.Debug() > 0) mprintf(" %i", idx + 1); KeepPoint(ds1, out, idx, odx); } } else { // Keep points for (; pt != points.end(); pt++) { if (*pt >= (int)ds1->Size()) break; if (State.Debug() > 0) mprintf(" %i", *pt + 1); KeepPoint(ds1, out, *pt, odx); } } if (State.Debug() > 0) mprintf("\n"); if (name.empty()) { // Replace old set with new set State.DSL().RemoveSet( ds1 ); State.DSL().AddSet( out ); } } // END loop over sets ds_arg = argIn.GetStringNext(); } // END loop over set args return CpptrajState::OK; }
// Analysis_HausdorffDistance::Setup() Analysis::RetType Analysis_HausdorffDistance::Setup(ArgList& analyzeArgs, AnalysisSetup& setup, int debugIn) { // Keywords int nrows = -1; int ncols = -1; std::string outtypearg = analyzeArgs.GetStringKey("outtype"); if (!outtypearg.empty()) { if (outtypearg == "basic") outType_ = BASIC; else if (outtypearg == "trimatrix") { outType_ = UPPER_TRI_MATRIX; nrows = analyzeArgs.getKeyInt("nrows", -1); if (nrows < 1) { mprinterr("Error: 'nrows' must be specified and > 0 for 'trimatrix'\n"); return Analysis::ERR; } } else if (outtypearg == "fullmatrix") { outType_ = FULL_MATRIX; nrows = analyzeArgs.getKeyInt("nrows", -1); if (nrows < 1) { mprinterr("Error: 'nrows' must be specified and > 0 for 'fullmatrix'\n"); return Analysis::ERR; } ncols = analyzeArgs.getKeyInt("ncols", nrows); if (ncols < 1) { mprinterr("Error: 'ncols' must be > 0 for 'fullmatrix'\n"); return Analysis::ERR; } } else { mprinterr("Error: Unrecognized keyword for 'outtype': %s\n", outtypearg.c_str()); return Analysis::ERR; } } else outType_ = BASIC; std::string dsname = analyzeArgs.GetStringKey("name"); DataFile* df = setup.DFL().AddDataFile( analyzeArgs.GetStringKey("out"), analyzeArgs ); DataFile* dfab = setup.DFL().AddDataFile( analyzeArgs.GetStringKey("outab"), analyzeArgs ); DataFile* dfba = setup.DFL().AddDataFile( analyzeArgs.GetStringKey("outba"), analyzeArgs ); // Get input data sets std::string dsarg = analyzeArgs.GetStringNext(); while (!dsarg.empty()) { DataSetList selected = setup.DSL().GetMultipleSets( dsarg ); for (DataSetList::const_iterator set = selected.begin(); set != selected.end(); ++set) { if ((*set)->Group() == DataSet::MATRIX_2D) inputSets_.AddCopyOfSet( *set ); else mprintf("Warning: Currently only 2D matrices supported; skipping set '%s'\n", (*set)->legend()); } //inputSets_ += setup.DSL().GetMultipleSets( dsarg ); dsarg = analyzeArgs.GetStringNext(); } if (inputSets_.empty()) { mprinterr("Error: No data sets specified.\n"); return Analysis::ERR; } // Output data set out_ = 0; if (outType_ == BASIC) { out_ = setup.DSL().AddSet(DataSet::FLOAT, dsname, "HAUSDORFF"); if (out_ == 0) return Analysis::ERR; // Directed sets ab_out_ = setup.DSL().AddSet(DataSet::FLOAT, MetaData(out_->Meta().Name(),"AB")); if (ab_out_ == 0) return Analysis::ERR; ba_out_ = setup.DSL().AddSet(DataSet::FLOAT, MetaData(out_->Meta().Name(),"BA")); if (ba_out_ == 0) return Analysis::ERR; } else if (outType_ == UPPER_TRI_MATRIX || outType_ == FULL_MATRIX) { out_ = setup.DSL().AddSet(DataSet::MATRIX_FLT, dsname, "HAUSDORFF"); ab_out_ = setup.DSL().AddSet(DataSet::MATRIX_FLT, MetaData(out_->Meta().Name(),"AB")); ba_out_ = setup.DSL().AddSet(DataSet::MATRIX_FLT, MetaData(out_->Meta().Name(),"BA")); if (out_ == 0 || ab_out_ == 0 || ba_out_ == 0) return Analysis::ERR; if (outType_ == UPPER_TRI_MATRIX) { if (((DataSet_2D*)out_)->AllocateTriangle( nrows )) return Analysis::ERR; if (((DataSet_2D*)ab_out_)->AllocateTriangle( nrows )) return Analysis::ERR; if (((DataSet_2D*)ba_out_)->AllocateTriangle( nrows )) return Analysis::ERR; } else if (outType_ == FULL_MATRIX) { if (((DataSet_2D*)out_)->Allocate2D( nrows,ncols )) return Analysis::ERR; if (((DataSet_2D*)ab_out_)->Allocate2D( nrows,ncols )) return Analysis::ERR; if (((DataSet_2D*)ba_out_)->Allocate2D( nrows,ncols )) return Analysis::ERR; } if (out_->Size() != inputSets_.size()) { mprinterr("Warning: Number of input data sets (%zu) != number of expected" " sets in matrix (%zu)\n", inputSets_.size(), out_->Size()); return Analysis::ERR; } // Directed sets } if (df != 0) df->AddDataSet( out_ ); if (dfab != 0) df->AddDataSet( ab_out_ ); if (dfba != 0) df->AddDataSet( ba_out_ ); mprintf(" HAUSDORFF:\n"); mprintf("\tCalculating Hausdorff distances from the following 2D distance matrices:\n\t "); for (DataSetList::const_iterator it = inputSets_.begin(); it != inputSets_.end(); ++it) mprintf(" %s", (*it)->legend()); mprintf("\n"); if (outType_ == BASIC) mprintf("\tOutput will be stored in 1D array set '%s'\n", out_->legend()); else if (outType_ == UPPER_TRI_MATRIX) mprintf("\tOutput will be stored in upper-triangular matrix set '%s' with %i rows.\n", out_->legend(), nrows); else if (outType_ == FULL_MATRIX) mprintf("\tOutput will be stored in matrix set '%s' with %i rows, %i columns.\n", out_->legend(), nrows, ncols); mprintf("\tDirected A->B distance output set: %s\n", ab_out_->legend()); mprintf("\tDirected B->A distance output set: %s\n", ba_out_->legend()); if (df != 0) mprintf("\tOutput set written to '%s'\n", df->DataFilename().full()); if (dfab != 0) mprintf("\tA->B output set written to '%s'\n", dfab->DataFilename().full()); if (dfba != 0) mprintf("\tB->A output set written to '%s'\n", dfba->DataFilename().full()); return Analysis::OK; }
// 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; }
/** 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; }
// 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; }
// 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; }