/** Special version of AddSet that does NOT check if set already exists. * Intended for use in Action Setup/DoAction where it is assumed that * the Action is setting up DataSets in such a way that there will not * be name conflicts, i.e. the DataSet name at least is unique. * \param inType type of DataSet to add. * \param metaIn DataSet MetaData. * \return pointer to successfully set-up DataSet or 0 if error. */ DataSet* DataSetList::AddSet_NoCheck(DataSet::DataType inType, MetaData const& metaIn) { // TODO Pass in Nframes? // Assume list does NOT have copies. MetaData meta( metaIn ); meta.SetEnsembleNum( ensembleNum_ ); // Allocate DataSet TokenPtr token = &(DataArray[inType]); if ( token->Alloc == 0) { mprinterr("Internal Error: No allocator for DataSet type [%s]\n", token->Description); return 0; } DataSet* DS = (DataSet*)token->Alloc(); if (DS==0) { mprinterr("Internal Error: DataSet %s memory allocation failed.\n", meta.PrintName().c_str()); return 0; } // If 1 dim set and time series status not set, set to true, allocate for frames. if (meta.TimeSeries() == MetaData::UNKNOWN_TS && DS->Ndim() == 1) { meta.SetTimeSeries( MetaData::IS_TS ); // Also set dimension default DS->SetDim(Dimension::X, Dimension(1.0, 1.0, "Frame") ); //DS->Allocate( DataSet::SizeArray(1, Nframes) ); } // Set up DataSet MetaData if ( DS->SetMeta( meta ) ) { mprinterr("Error setting up data set %s.\n", meta.PrintName().c_str()); delete DS; return 0; } # ifdef MPI if (newSetsNeedSync_) DS->SetNeedsSync( true ); # endif // Add to list Push_Back(DS); return DS; }
// Action_Density::Init() Action::RetType Action_Density::Init(ArgList& actionArgs, ActionInit& init, int debugIn) { # ifdef MPI trajComm_ = init.TrajComm(); # endif DataFile* outfile = init.DFL().AddDataFile(actionArgs.GetStringKey("out"), actionArgs); std::string dsname = actionArgs.GetStringKey("name"); if (actionArgs.hasKey("x") ) { axis_ = DX; area_coord_[0] = DY; area_coord_[1] = DZ; } else if (actionArgs.hasKey("y") ) { axis_ = DY; area_coord_[0] = DX; area_coord_[1] = DZ; } else if (actionArgs.hasKey("z") ) { axis_ = DZ; area_coord_[0] = DX; area_coord_[1] = DY; } property_ = NUMBER; if (actionArgs.hasKey("number") ) property_ = NUMBER; else if (actionArgs.hasKey("mass") ) property_ = MASS; else if (actionArgs.hasKey("charge") ) property_ = CHARGE; else if (actionArgs.hasKey("electron") ) property_ = ELECTRON; binType_ = CENTER; if (actionArgs.hasKey("bincenter")) binType_ = CENTER; else if (actionArgs.hasKey("binedge") ) binType_ = EDGE; delta_ = actionArgs.getKeyDouble("delta", 0.01); if (delta_ <= 0) { mprinterr("Error: Delta must be > 0.0\n"); return Action::ERR; } // for compatibility with ptraj, ignored because we rely on the atom code to // do the right thing, see Atom.{h,cpp} if (actionArgs.hasKey("efile")) mprintf("Warning: The 'efile' keyword is deprecated.\n"); // read the rest of the command line as a series of masks std::string maskstr; unsigned int idx = 1; while ( (maskstr = actionArgs.GetMaskNext() ) != emptystring) { masks_.push_back( AtomMask(maskstr) ); if (dsname.empty()) dsname = init.DSL().GenerateDefaultName("DENSITY"); MetaData MD(dsname, "avg", idx); MD.SetTimeSeries( MetaData::NOT_TS ); // Hold average density DataSet* ads = init.DSL().AddSet( DataSet::DOUBLE, MD ); if (ads == 0) return Action::ERR; ads->SetLegend( NoWhitespace(masks_.back().MaskExpression()) ); AvSets_.push_back( ads ); if (outfile != 0) outfile->AddDataSet( ads ); // Hold SD density MD.SetAspect("sd"); DataSet* sds = init.DSL().AddSet( DataSet::DOUBLE, MD ); if (sds == 0) return Action::ERR; sds->SetLegend( NoWhitespace("sd(" + masks_.back().MaskExpression() + ")") ); SdSets_.push_back( sds ); if (outfile != 0) outfile->AddDataSet( sds ); # ifdef MPI ads->SetNeedsSync( false ); // Populated in Print() sds->SetNeedsSync( false ); # endif idx++; } if (masks_.empty()) { // If no masks assume we want total system density. if (dsname.empty()) dsname = actionArgs.GetStringNext(); density_ = init.DSL().AddSet(DataSet::DOUBLE, dsname, "DENSITY"); if (density_ == 0) return Action::ERR; if (outfile != 0) outfile->AddDataSet( density_ ); image_.InitImaging( true ); // Hijack delta for storing sum of masses delta_ = 0.0; } else { // Density selected by mask(s) along an axis density_ = 0; histograms_.resize(masks_.size() ); } mprintf(" DENSITY:"); if (density_ == 0) { const char* binStr[] = {"center", "edge"}; mprintf(" Determining %s density for %zu masks.\n", PropertyStr_[property_], masks_.size()); mprintf("\troutine version: %s\n", ROUTINE_VERSION_STRING); mprintf("\tDelta is %f\n", delta_); mprintf("\tAxis is %s\n", AxisStr_[axis_]); mprintf("\tData set name is '%s'\n", dsname.c_str()); mprintf("\tData set aspect [avg] holds the mean, aspect [sd] holds standard deviation.\n"); mprintf("\tBin coordinates will be to bin %s.\n", binStr[binType_]); } else { mprintf(" No masks specified, calculating total system density in g/cm^3.\n"); mprintf("\tData set name is '%s'\n", density_->legend()); } if (outfile != 0) mprintf("\tOutput to '%s'\n", outfile->DataFilename().full()); return Action::OK; }
/** Add a DataSet of specified type, set it up and return pointer to it. * \param inType type of DataSet to add. * \param metaIn DataSet MetaData. * \return pointer to successfully set-up DataSet or 0 if error. */ DataSet* DataSetList::AddSet(DataSet::DataType inType, MetaData const& metaIn) { // TODO Always generate default name if empty? # ifdef TIMER time_total_.Start(); # endif // Do not add to a list with copies if (hasCopies_) { mprinterr("Internal Error: Attempting to add DataSet (%s) to DataSetList with copies.\n", metaIn.PrintName().c_str()); return 0; } MetaData meta( metaIn ); meta.SetEnsembleNum( ensembleNum_ ); # ifdef TIMER time_check_.Start(); # endif // Check if DataSet with same attributes already present. DataSet* DS = CheckForSet(meta); # ifdef TIMER time_check_.Stop(); # endif if (DS != 0) { mprintf("Warning: DataSet '%s' already present.\n", DS->Meta().PrintName().c_str()); // NOTE: Should return found dataset? return 0; } TokenPtr token = &(DataArray[inType]); if ( token->Alloc == 0) { mprinterr("Internal Error: No allocator for DataSet type [%s]\n", token->Description); return 0; } # ifdef TIMER time_setup_.Start(); # endif DS = (DataSet*)token->Alloc(); if (DS==0) { mprinterr("Internal Error: DataSet %s memory allocation failed.\n", meta.PrintName().c_str()); return 0; } // If 1 dim set and time series status not set, set to true. if (meta.TimeSeries() == MetaData::UNKNOWN_TS && DS->Ndim() == 1) { meta.SetTimeSeries( MetaData::IS_TS ); // Also set dimension default DS->SetDim(Dimension::X, Dimension(1.0, 1.0, "Frame") ); } // Set up dataset if ( DS->SetMeta( meta ) ) { mprinterr("Error setting up data set %s.\n", meta.PrintName().c_str()); delete DS; return 0; } # ifdef MPI if (newSetsNeedSync_) DS->SetNeedsSync( true ); # endif # ifdef TIMER time_setup_.Stop(); time_push_.Start(); # endif Push_Back(DS); # ifdef TIMER time_push_.Stop(); # endif //fprintf(stderr,"ADDED dataset %s\n",dsetName); return DS; }
// Action_Density::Init() Action::RetType Action_Density::Init(ArgList& actionArgs, ActionInit& init, int debugIn) { # ifdef MPI if (init.TrajComm().Size() > 1) { mprinterr("Error: 'density' action does not work with > 1 thread (%i threads currently).\n", init.TrajComm().Size()); return Action::ERR; } # endif DataFile* outfile = init.DFL().AddDataFile(actionArgs.GetStringKey("out"), actionArgs); std::string dsname = actionArgs.GetStringKey("name"); if (dsname.empty()) dsname = init.DSL().GenerateDefaultName("DENSITY"); if (actionArgs.hasKey("x") ) { axis_ = DX; area_coord_[0] = DY; area_coord_[1] = DZ; } else if (actionArgs.hasKey("y") ) { axis_ = DY; area_coord_[0] = DX; area_coord_[1] = DZ; } else if (actionArgs.hasKey("z") ) { axis_ = DZ; area_coord_[0] = DX; area_coord_[1] = DY; } property_ = NUMBER; if (actionArgs.hasKey("number") ) property_ = NUMBER; if (actionArgs.hasKey("mass") ) property_ = MASS; if (actionArgs.hasKey("charge") ) property_ = CHARGE; if (actionArgs.hasKey("electron") ) property_ = ELECTRON; delta_ = actionArgs.getKeyDouble("delta", 0.01); // for compatibility with ptraj, ignored because we rely on the atom code to // do the right thing, see Atom.{h,cpp} if (actionArgs.hasKey("efile")) mprintf("Warning: The 'efile' keyword is deprecated.\n"); // read the rest of the command line as a series of masks std::string maskstr; unsigned int idx = 1; while ( (maskstr = actionArgs.GetMaskNext() ) != emptystring) { masks_.push_back( AtomMask(maskstr) ); MetaData MD(dsname, "avg", idx); MD.SetTimeSeries( MetaData::NOT_TS ); // Hold average density DataSet* ads = init.DSL().AddSet( DataSet::DOUBLE, MD ); if (ads == 0) return Action::ERR; ads->SetLegend( NoWhitespace(masks_.back().MaskExpression()) ); AvSets_.push_back( ads ); if (outfile != 0) outfile->AddDataSet( ads ); // Hold SD density MD.SetAspect("sd"); DataSet* sds = init.DSL().AddSet( DataSet::DOUBLE, MD ); if (sds == 0) return Action::ERR; sds->SetLegend( NoWhitespace("sd(" + masks_.back().MaskExpression() + ")") ); SdSets_.push_back( sds ); if (outfile != 0) outfile->AddDataSet( sds ); # ifdef MPI ads->SetNeedsSync( false ); // Populated in Print() sds->SetNeedsSync( false ); # endif idx++; } if (masks_.empty()) { mprinterr("Error: No masks specified.\n"); return Action::ERR; } minus_histograms_.resize(masks_.size() ); plus_histograms_.resize(masks_.size() ); mprintf(" DENSITY: Determining %s density for %zu masks.\n", PropertyStr_[property_], masks_.size()); mprintf("\troutine version: %s\n", ROUTINE_VERSION_STRING); mprintf("\tDelta is %f\n", delta_); mprintf("\tAxis is %s\n", AxisStr_[axis_]); mprintf("\tData set name is '%s'\n", dsname.c_str()); if (outfile != 0) mprintf("\tOutput to '%s'\n", outfile->DataFilename().full()); return Action::OK; }