/** Determine what atoms each mask pertains to for the current parm file. */ Action::RetType Action_ReplicateCell::Setup(ActionSetup& setup) { if (setup.Top().SetupIntegerMask( Mask1_ )) return Action::ERR; mprintf("\t%s (%i atoms)\n",Mask1_.MaskString(), Mask1_.Nselected()); if (Mask1_.None()) { mprintf("Warning: One or both masks have no atoms.\n"); return Action::SKIP; } // Set up imaging info for this parm image_.SetupImaging( setup.CoordInfo().TrajBox().Type() ); if (!image_.ImagingEnabled()) { mprintf("Warning: Imaging cannot be performed for topology %s\n", setup.Top().c_str()); return Action::SKIP; } // Create combined topology. if (combinedTop_.Natom() > 0) { // Topology already set up. Check that # atoms matches. if (Mask1_.Nselected() * ncopies_ != combinedTop_.Natom()) { mprintf("Warning: Unit cell can currently only be replicated for" " topologies with same # atoms.\n"); return Action::SKIP; } // Otherwise assume top does not change. } else { // Set up topology and frame. Topology* stripParm = setup.Top().modifyStateByMask( Mask1_ ); if (stripParm == 0) return Action::ERR; for (int cell = 0; cell != ncopies_; cell++) combinedTop_.AppendTop( *stripParm ); combinedTop_.Brief("Combined parm:"); delete stripParm; if (!parmfilename_.empty()) { ParmFile pfile; if (pfile.WriteTopology(combinedTop_, parmfilename_, ParmFile::UNKNOWN_PARM, 0)) { mprinterr("Error: Topology file %s not written.\n", parmfilename_.c_str()); return Action::ERR; } } // Only coordinates for now. FIXME combinedFrame_.SetupFrameM(combinedTop_.Atoms()); // Set up COORDS / output traj if necessary. if (coords_ != 0) coords_->CoordsSetup( combinedTop_, CoordinateInfo() ); if (!trajfilename_.empty()) { if ( outtraj_.PrepareEnsembleTrajWrite(trajfilename_, trajArgs_, &combinedTop_, CoordinateInfo(), setup.Nframes(), TrajectoryFile::UNKNOWN_TRAJ, ensembleNum_) ) return Action::ERR; } } return Action::OK; }
// Analysis_Hist::Analyze() Analysis::RetType Analysis_Hist::Analyze() { // Set up dimensions // Size of histdata and dimensionArgs should be the same size_t total_bins = 0UL; for (unsigned int hd = 0; hd < N_dimensions_; hd++) { if ( setupDimension(dimensionArgs_[hd], *(histdata_[hd]), total_bins) ) return Analysis::ERR; } // dimensionArgs no longer needed dimensionArgs_.clear(); // Check that the number of data points in each dimension are equal std::vector<DataSet_1D*>::iterator ds = histdata_.begin(); size_t Ndata = (*ds)->Size(); ++ds; for (; ds != histdata_.end(); ++ds) { //mprintf("DEBUG: DS %s size %i\n",histdata[hd]->Name(),histdata[hd]->Xmax()+1); if (Ndata != (*ds)->Size()) { mprinterr("Error: Hist: Dataset %s has inconsistent # data points (%zu), expected %zu.\n", (*ds)->legend(), (*ds)->Size(), Ndata); return Analysis::ERR; } } mprintf("\tHist: %zu data points in each dimension.\n", Ndata); if (calcAMD_ && Ndata != amddata_->Size()) { mprinterr("Error: Hist: AMD data set size (%zu) does not match # expected data points (%zu).\n", amddata_->Size(), Ndata); return Analysis::ERR; } // Allocate bins mprintf("\tHist: Allocating histogram, total bins = %zu\n", total_bins); Bins_.resize( total_bins, 0.0 ); // Bin data for (size_t n = 0; n < Ndata; n++) { long int index = 0; HdimType::const_iterator dim = dimensions_.begin(); OffType::const_iterator bOff = binOffsets_.begin(); for (std::vector<DataSet_1D*>::iterator ds = histdata_.begin(); ds != histdata_.end(); ++ds, ++dim, ++bOff) { double dval = (*ds)->Dval( n ); // Check if data is out of bounds for this dimension. if (dval > dim->Max() || dval < dim->Min()) { index = -1L; break; } // Calculate index for this particular dimension (idx) long int idx = (long int)((dval - dim->Min()) / dim->Step()); if (debug_>1) mprintf(" [%s:%f (%li)],", dim->label(), dval, idx); // Calculate overall index in Bins, offset has already been calcd. index += (idx * (*bOff)); } // If index was successfully calculated, populate bin if (index > -1L && index < (long int)Bins_.size()) { if (debug_ > 1) mprintf(" |index=%li",index); if (calcAMD_) Bins_[index] += exp( amddata_->Dval(n) ); else Bins_[index]++; } else { mprintf("\tWarning: Frame %zu Coordinates out of bounds (%li)\n", n+1, index); } if (debug_>1) mprintf("}\n"); } // Calc free energy if requested if (calcFreeE_) CalcFreeE(); // Normalize if requested if (normalize_ != NO_NORM) Normalize(); if (nativeOut_) { // Use Histogram built-in output PrintBins(); } else { // Using DataFileList framework, set-up labels etc. if (N_dimensions_ == 1) { DataSet_double& dds = static_cast<DataSet_double&>( *hist_ ); // Since Allocate1D only reserves data, use assignment op. dds = Bins_; hist_->SetDim(Dimension::X, dimensions_[0]); } else if (N_dimensions_ == 2) { DataSet_MatrixDbl& mds = static_cast<DataSet_MatrixDbl&>( *hist_ ); mds.Allocate2D( dimensions_[0].Bins(), dimensions_[1].Bins() ); std::copy( Bins_.begin(), Bins_.end(), mds.begin() ); hist_->SetDim(Dimension::X, dimensions_[0]); hist_->SetDim(Dimension::Y, dimensions_[1]); outfile_->ProcessArgs("noxcol usemap nolabels"); } else if (N_dimensions_ == 3) { DataSet_GridFlt& gds = static_cast<DataSet_GridFlt&>( *hist_ ); //gds.Allocate3D( dimensions_[0].Bins(), dimensions_[1].Bins(), dimensions_[2].Bins() ); gds.Allocate_N_O_D( dimensions_[0].Bins(), dimensions_[1].Bins(), dimensions_[2].Bins(), Vec3(dimensions_[0].Min(), dimensions_[1].Min(), dimensions_[2].Min()), Vec3(dimensions_[0].Step(), dimensions_[1].Step(), dimensions_[2].Step()) ); //std::copy( Bins_.begin(), Bins_.end(), gds.begin() ); // FIXME: Copy will not work since in grids data is ordered with Z // changing fastest. Should the ordering in grid be changed? size_t idx = 0; for (size_t z = 0; z < gds.NZ(); z++) for (size_t y = 0; y < gds.NY(); y++) for (size_t x = 0; x < gds.NX(); x++) gds.SetElement( x, y, z, (float)Bins_[idx++] ); hist_->SetDim(Dimension::X, dimensions_[0]); hist_->SetDim(Dimension::Y, dimensions_[1]); hist_->SetDim(Dimension::Z, dimensions_[2]); outfile_->ProcessArgs("noxcol usemap nolabels"); // Create pseudo-topology/trajectory if (!traj3dName_.empty()) { Topology pseudo; pseudo.AddTopAtom(Atom("H3D", 0), Residue("H3D", 1, ' ', ' ')); pseudo.CommonSetup(); if (!parmoutName_.empty()) { ParmFile pfile; if (pfile.WriteTopology( pseudo, parmoutName_, ParmFile::UNKNOWN_PARM, 0 )) mprinterr("Error: Could not write pseudo topology to '%s'\n", parmoutName_.c_str()); } Trajout_Single out; if (out.PrepareTrajWrite(traj3dName_, ArgList(), &pseudo, CoordinateInfo(), Ndata, traj3dFmt_) == 0) { Frame outFrame(1); for (size_t i = 0; i < Ndata; ++i) { outFrame.ClearAtoms(); outFrame.AddVec3( Vec3(histdata_[0]->Dval(i), histdata_[1]->Dval(i), histdata_[2]->Dval(i)) ); out.WriteSingle(i, outFrame); } out.EndTraj(); } else mprinterr("Error: Could not set up '%s' for write.\n", traj3dName_.c_str()); } } } return Analysis::OK; }