// TODO: Accept const ArgList so arguments are not reset? CpptrajFile* DataFileList::AddCpptrajFile(FileName const& nameIn, std::string const& descrip, CFtype typeIn, bool allowStdout) { // If no filename and stdout not allowed, no output desired. if (nameIn.empty() && !allowStdout) return 0; FileName name; CpptrajFile* Current = 0; int currentIdx = -1; if (!nameIn.empty()) { name = nameIn; // Append ensemble number if set. if (ensembleNum_ != -1) name.Append( "." + integerToString(ensembleNum_) ); // Check if filename in use by DataFile. DataFile* df = GetDataFile(name); if (df != 0) { mprinterr("Error: Text output file name '%s' already in use by data file '%s'.\n", nameIn.full(), df->DataFilename().full()); return 0; } // Check if this filename already in use currentIdx = GetCpptrajFileIdx( name ); if (currentIdx != -1) Current = cfList_[currentIdx]; } // If no CpptrajFile associated with name, create new CpptrajFile if (Current==0) { switch (typeIn) { case TEXT: Current = new CpptrajFile(); break; case PDB: Current = (CpptrajFile*)(new PDBfile()); break; } Current->SetDebug(debug_); // Set up file for writing. //if (Current->SetupWrite( name, debug_ )) if (Current->OpenWrite( name )) { mprinterr("Error: Setting up text output file %s\n", name.full()); delete Current; return 0; } cfList_.push_back( Current ); cfData_.push_back( CFstruct(descrip, typeIn) ); } else { // If Current type does not match typeIn do not allow. if (typeIn != cfData_[currentIdx].Type()) { mprinterr("Error: Cannot change type of text output for '%s'.\n", Current->Filename().full()); return 0; } Current->SetDebug(debug_); // Update description if (!descrip.empty()) cfData_[currentIdx].UpdateDescrip( descrip ); } return Current; }
//------------------------------------------------------------------------ bool Traj_Conflib::ID_TrajFormat(CpptrajFile& fileIn) { // If the file name is conflib.dat, assume this is a conflib.dat file // from LMOD. Cant think of a better way to detect this since there is no // magic number but the file is binary. if ( fileIn.Filename().Base() == "conflib.dat" ) { mprintf(" LMOD CONFLIB file\n"); return true; } return false; }
/** Create new DataFile, or return existing DataFile. */ DataFile* DataFileList::AddDataFile(FileName const& nameIn, ArgList& argIn, DataFile::DataFormatType typeIn) { // If no filename, no output desired if (nameIn.empty()) return 0; FileName fname( nameIn ); // Append ensemble number if set. //rprintf("DEBUG: Setting up data file '%s' with ensembleNum %i\n", nameIn.base(), ensembleNum_); if (ensembleNum_ != -1) fname.Append( "." + integerToString(ensembleNum_) ); // Check if filename in use by CpptrajFile. CpptrajFile* cf = GetCpptrajFile(fname); if (cf != 0) { mprinterr("Error: Data file name '%s' already in use by text output file '%s'.\n", fname.full(), cf->Filename().full()); return 0; } // Check if this filename already in use DataFile* Current = GetDataFile(fname); // If no DataFile associated with name, create new DataFile if (Current==0) { Current = new DataFile(); if (Current->SetupDatafile(fname, argIn, typeIn, debug_)) { mprinterr("Error: Setting up data file %s\n", fname.full()); delete Current; return 0; } fileList_.push_back(Current); } else { // Set debug level Current->SetDebug(debug_); // If a type was specified, make sure it matches. if (typeIn != DataFile::UNKNOWN_DATA && typeIn != Current->Type()) { mprinterr("Error: '%s' is type %s but has been requested as type %s.\n", Current->DataFilename().full(), Current->FormatString(), DataFile::FormatString( typeIn )); return 0; } // Check for keywords that do not match file type DataFile::DataFormatType kType = DataFile::GetFormatFromArg( argIn ); if (kType != DataFile::UNKNOWN_DATA && kType != Current->Type()) mprintf("Warning: %s is type %s but type %s keyword specified; ignoring keyword.\n", Current->DataFilename().full(), Current->FormatString(), DataFile::FormatString( kType )); // Process Arguments if (!argIn.empty()) Current->ProcessArgs( argIn ); } return Current; }
/** \return true if TRR/TRJ file. Determine endianness. */ bool Traj_GmxTrX::IsTRX(CpptrajFile& infile) { int magic; if ( infile.Read( &magic, 4 ) != 4 ) return 1; if (magic != Magic_) { // See if this is big endian endian_swap( &magic, 1 ); if (magic != Magic_) return false; else isBigEndian_ = true; } else isBigEndian_ = false; // TODO: At this point file is trX, but not sure how best to differentiate // between TRR and TRJ. For now do it based on extension. Default TRR. if (infile.Filename().Ext() == ".trr") format_ = TRR; else if (infile.Filename().Ext() == ".trj") format_ = TRJ; else format_ = TRR; return true; }
// DataIO_OpenDx::WriteSet3D() int DataIO_OpenDx::WriteSet3D(DataSet const& setIn, CpptrajFile& outfile) const { if (setIn.Ndim() != 3) { mprinterr("Internal Error: DataSet %s in DataFile %s has %zu dimensions, expected 3.\n", setIn.legend(), outfile.Filename().full(), setIn.Ndim()); return 1; } int err = 0; switch ( gridWriteMode_ ) { case BIN_CORNER: case BIN_CENTER: err = WriteGrid( setIn, outfile ); break; case WRAP: case EXTENDED : err = WriteGridWrap( setIn, outfile ); break; } // Print tail if (err == 0) { // TODO: Make this an option //if (mode_ == CENTER) // outfile.Printf("\nobject \"density (%s) [A^-3]\" class field\n", // centerMask_.MaskString()); //else outfile.Printf("\nobject \"density [A^-3]\" class field\n"); } return err; }
// Traj_NcEnsemble::ID_TrajFormat() bool Traj_NcEnsemble::ID_TrajFormat(CpptrajFile& fileIn) { return ( GetNetcdfConventions( fileIn.Filename().full() ) == NC_AMBERENSEMBLE ); }
bool Traj_AmberNetcdf::ID_TrajFormat(CpptrajFile& fileIn) { if ( GetNetcdfConventions( fileIn.Filename().full() ) == NC_AMBERTRAJ ) return true; return false; }
// Action_AtomMap::Init() Action::RetType Action_AtomMap::Init(ArgList& actionArgs, ActionInit& init, int debugIn) { DataFile* rmsout = 0; int refatom,targetatom; debug_ = debugIn; RefMap_.SetDebug(debug_); TgtMap_.SetDebug(debug_); // Get Args CpptrajFile* outputfile = init.DFL().AddCpptrajFile(actionArgs.GetStringKey("mapout"), "Atom Map"); maponly_ = actionArgs.hasKey("maponly"); rmsfit_ = actionArgs.hasKey("rmsfit"); if (rmsfit_) rmsout = init.DFL().AddDataFile( actionArgs.GetStringKey("rmsout"), actionArgs ); std::string targetName = actionArgs.GetStringNext(); std::string refName = actionArgs.GetStringNext(); if (targetName.empty()) { mprinterr("Error: No target specified.\n"); return Action::ERR; } if (refName.empty()) { mprinterr("Error: No reference specified.\n"); return Action::ERR; } // Get Reference RefFrame_ = (DataSet_Coords_REF*)init.DSL().FindSetOfType( refName, DataSet::REF_FRAME ); if (RefFrame_ == 0) { mprinterr("Error: Could not get reference frame %s\n",refName.c_str()); return Action::ERR; } // Get Target TgtFrame_ = (DataSet_Coords_REF*)init.DSL().FindSetOfType( targetName, DataSet::REF_FRAME ); if (TgtFrame_ == 0) { mprinterr("Error: Could not get target frame %s\n",targetName.c_str()); return Action::ERR; } mprintf(" ATOMMAP: Atoms in trajectories associated with parm %s will be\n", TgtFrame_->Top().c_str()); mprintf(" mapped according to parm %s.\n",RefFrame_->Top().c_str()); if (outputfile != 0) mprintf(" Map will be written to %s\n",outputfile->Filename().full()); if (maponly_) mprintf(" maponly: Map will only be written, not used in trajectory read.\n"); if (!maponly_ && rmsfit_) { mprintf(" rmsfit: Will rms fit mapped atoms in tgt to reference.\n"); if (rmsout != 0) { rmsdata_ = init.DSL().AddSet(DataSet::DOUBLE, actionArgs.GetStringNext(), "RMSD"); if (rmsdata_==0) return Action::ERR; rmsout->AddDataSet(rmsdata_); } } // For each map, set up (get element for each atom, initialize map mem), // determine what atoms are bonded to each other via simple distance // cutoffs, the give each atom an ID based on what atoms are bonded to // it, noting which IDs are unique for that map. if (RefMap_.Setup(RefFrame_->Top())!=0) return Action::ERR; //RefMap_.WriteMol2((char*)"RefMap.mol2\0"); // DEBUG RefMap_.DetermineAtomIDs(); if (TgtMap_.Setup(TgtFrame_->Top())!=0) return Action::ERR; //TgtMap_.WriteMol2((char*)"TgtMap.mol2\0"); // DEBUG TgtMap_.DetermineAtomIDs(); // Check if number of atoms in each map is equal if (RefMap_.Natom() != TgtMap_.Natom()) { mprintf("Warning: # atoms in reference (%i) not equal\n", RefMap_.Natom()); mprintf("Warning:\tto # atoms in target (%i).\n",TgtMap_.Natom()); } // Set up RMS frames to be able to hold max # of possible atoms rmsRefFrame_.SetupFrame(RefMap_.Natom()); rmsTgtFrame_.SetupFrame(RefMap_.Natom()); // Allocate memory for atom map // AMap_[reference]=target AMap_.resize( RefMap_.Natom(), -1); // Map unique atoms int numMappedAtoms = MapUniqueAtoms(RefMap_, TgtMap_); if (debug_>0) mprintf("* MapUniqueAtoms: %i atoms mapped.\n",numMappedAtoms); // If no unique atoms mapped system is highly symmetric and needs to be // iteratively mapped. Otherwise just map remaining atoms. if (numMappedAtoms==0) { if (MapWithNoUniqueAtoms(RefMap_,TgtMap_)) return Action::ERR; } else { if (MapAtoms(RefMap_,TgtMap_)) return Action::ERR; } // Print atom map and count # mapped atoms numMappedAtoms = 0; outputfile->Printf("%-6s %4s %6s %4s\n","#TgtAt","Tgt","RefAt","Ref"); for (refatom=0; refatom < RefMap_.Natom(); refatom++) { targetatom = AMap_[refatom]; if (targetatom < 0) outputfile->Printf("%6s %4s %6i %4s\n","---","---",refatom+1,RefMap_[refatom].c_str()); else outputfile->Printf("%6i %4s %6i %4s\n",targetatom+1,TgtMap_[targetatom].c_str(), refatom+1, RefMap_[refatom].c_str()); if (targetatom>=0) { //mprintf("* TargetAtom %6i(%4s) maps to RefAtom %6i(%4s)\n", // targetatom,TgtMap_.P->names[targetatom], // refatom,RefMap_.P->names[refatom]); ++numMappedAtoms; } //else { // mprintf("* Could not map any TargetAtom to RefAtom %6i(%4s)\n", // refatom,RefMap_.P->names[refatom]); //} } mprintf(" %i total atoms were mapped.\n",numMappedAtoms); if (maponly_) return Action::OK; // If rmsfit is specified, an rms fit of target to reference will be // performed using all atoms that were successfully mapped from // target to reference. if (rmsfit_) { // Set up a reference frame containing only mapped reference atoms rmsRefFrame_.StripUnmappedAtoms(RefFrame_->RefFrame(), AMap_); mprintf(" rmsfit: Will rms fit %i atoms from target to reference.\n",numMappedAtoms); return Action::OK; } // Check if not all atoms could be mapped if (numMappedAtoms != RefMap_.Natom()) { // If the number of mapped atoms is less than the number of reference // atoms but equal to the number of target atoms, can modify the reference // frame to only include mapped atoms if (numMappedAtoms<RefMap_.Natom() && numMappedAtoms==TgtMap_.Natom()) { // Create mask that includes only reference atoms that could be mapped AtomMask M1; for (refatom = 0; refatom < RefMap_.Natom(); refatom++) { if (AMap_[refatom] != -1) M1.AddAtom(refatom); } // Strip reference parm mprintf(" Modifying reference '%s' topology and frame to match mapped atoms.\n", RefFrame_->legend()); if (RefFrame_->StripRef( M1 )) return Action::ERR; // Since AMap[ ref ] = tgt but ref is now missing any stripped atoms, // the indices of AMap must be shifted to match int refIndex = 0; // The new index for (refatom = 0; refatom < RefMap_.Natom(); refatom++) { targetatom = AMap_[refatom]; if (targetatom<0) continue; else AMap_[refIndex++]=targetatom; } } else { mprintf("Warning: AtomMap: Not all atoms were mapped. Frames will not be modified.\n"); maponly_=true; } } if (!maponly_) { // Set up new Frame newFrame_ = new Frame(); newFrame_->SetupFrameM( TgtFrame_->Top().Atoms() ); // Set up new Parm newParm_ = TgtFrame_->Top().ModifyByMap(AMap_); } return Action::OK; }
/** Open the Charmm PSF file specified by filename and set up topology data. * Mask selection requires natom, nres, names, resnames, resnums. */ int Parm_CharmmPsf::ReadParm(FileName const& fname, Topology &parmOut) { const size_t TAGSIZE = 10; char tag[TAGSIZE]; tag[0]='\0'; CpptrajFile infile; if (infile.OpenRead(fname)) return 1; mprintf(" Reading Charmm PSF file %s as topology file.\n",infile.Filename().base()); // Read the first line, should contain PSF... const char* buffer = 0; if ( (buffer=infile.NextLine()) == 0 ) return 1; // Advance to <ntitle> !NTITLE int ntitle = FindTag(tag, "!NTITLE", 7, infile); // Only read in 1st title. Skip any asterisks. std::string psftitle; if (ntitle > 0) { buffer = infile.NextLine(); const char* ptr = buffer; while (*ptr != '\0' && (*ptr == ' ' || *ptr == '*')) ++ptr; psftitle.assign( ptr ); } parmOut.SetParmName( NoTrailingWhitespace(psftitle), infile.Filename() ); // Advance to <natom> !NATOM int natom = FindTag(tag, "!NATOM", 6, infile); if (debug_>0) mprintf("\tPSF: !NATOM tag found, natom=%i\n", natom); // If no atoms, probably issue with PSF file if (natom < 1) { mprinterr("Error: No atoms in PSF file.\n"); return 1; } // Read the next natom lines int psfresnum = 0; char psfresname[6]; char psfname[6]; char psftype[6]; double psfcharge; double psfmass; for (int atom=0; atom < natom; atom++) { if ( (buffer=infile.NextLine()) == 0 ) { mprinterr("Error: ReadParmPSF(): Reading atom %i\n",atom+1); return 1; } // Read line // ATOM# SEGID RES# RES ATNAME ATTYPE CHRG MASS (REST OF COLUMNS ARE LIKELY FOR CMAP AND CHEQ) sscanf(buffer,"%*i %*s %i %s %s %s %lf %lf",&psfresnum, psfresname, psfname, psftype, &psfcharge, &psfmass); parmOut.AddTopAtom( Atom( psfname, psfcharge, psfmass, psftype), Residue( psfresname, psfresnum, ' ', ' '), 0 ); } // END loop over atoms // Advance to <nbond> !NBOND int bondatoms[9]; int nbond = FindTag(tag, "!NBOND", 6, infile); if (nbond > 0) { if (debug_>0) mprintf("\tPSF: !NBOND tag found, nbond=%i\n", nbond); int nlines = nbond / 4; if ( (nbond % 4) != 0) nlines++; for (int bondline=0; bondline < nlines; bondline++) { if ( (buffer=infile.NextLine()) == 0 ) { mprinterr("Error: ReadParmPSF(): Reading bond line %i\n",bondline+1); return 1; } // Each line has 4 pairs of atom numbers int nbondsread = sscanf(buffer,"%i %i %i %i %i %i %i %i",bondatoms,bondatoms+1, bondatoms+2,bondatoms+3, bondatoms+4,bondatoms+5, bondatoms+6,bondatoms+7); // NOTE: Charmm atom nums start from 1 for (int bondidx=0; bondidx < nbondsread; bondidx+=2) parmOut.AddBond(bondatoms[bondidx]-1, bondatoms[bondidx+1]-1); } } else mprintf("Warning: PSF has no bonds.\n"); // Advance to <nangles> !NTHETA int nangle = FindTag(tag, "!NTHETA", 7, infile); if (nangle > 0) { if (debug_>0) mprintf("\tPSF: !NTHETA tag found, nangle=%i\n", nangle); int nlines = nangle / 3; if ( (nangle % 3) != 0) nlines++; for (int angleline=0; angleline < nlines; angleline++) { if ( (buffer=infile.NextLine()) == 0) { mprinterr("Error: Reading angle line %i\n", angleline+1); return 1; } // Each line has 3 groups of 3 atom numbers int nanglesread = sscanf(buffer,"%i %i %i %i %i %i %i %i %i",bondatoms,bondatoms+1, bondatoms+2,bondatoms+3, bondatoms+4,bondatoms+5, bondatoms+6,bondatoms+7, bondatoms+8); for (int angleidx=0; angleidx < nanglesread; angleidx += 3) parmOut.AddAngle( bondatoms[angleidx ]-1, bondatoms[angleidx+1]-1, bondatoms[angleidx+2]-1 ); } } else mprintf("Warning: PSF has no angles.\n"); // Advance to <ndihedrals> !NPHI int ndihedral = FindTag(tag, "!NPHI", 5, infile); if (ndihedral > 0) { if (debug_>0) mprintf("\tPSF: !NPHI tag found, ndihedral=%i\n", ndihedral); int nlines = ndihedral / 2; if ( (ndihedral % 2) != 0) nlines++; for (int dihline = 0; dihline < nlines; dihline++) { if ( (buffer=infile.NextLine()) == 0) { mprinterr("Error: Reading dihedral line %i\n", dihline+1); return 1; } // Each line has 2 groups of 4 atom numbers int ndihread = sscanf(buffer,"%i %i %i %i %i %i %i %i",bondatoms,bondatoms+1, bondatoms+2,bondatoms+3, bondatoms+4,bondatoms+5, bondatoms+6,bondatoms+7); for (int dihidx=0; dihidx < ndihread; dihidx += 4) parmOut.AddDihedral( bondatoms[dihidx ]-1, bondatoms[dihidx+1]-1, bondatoms[dihidx+2]-1, bondatoms[dihidx+3]-1 ); } } else mprintf("Warning: PSF has no dihedrals.\n"); mprintf("\tPSF contains %i atoms, %i residues.\n", parmOut.Natom(), parmOut.Nres()); infile.CloseFile(); return 0; }
bool Traj_AmberRestartNC::ID_TrajFormat(CpptrajFile& fileIn) { if ( GetNetcdfConventions( fileIn.Filename().full() ) == NC_AMBERRESTART ) return true; return false; }
// DataIO_CCP4::WriteSet3D() int DataIO_CCP4::WriteSet3D( DataSetList::const_iterator const& setIn, CpptrajFile& outfile ) { if ((*setIn)->Size() < 1) return 1; // SANITY CHECK: No empty grid allowed if ((*setIn)->Ndim() != 3) { mprinterr("Internal Error: DataSet %s in DataFile %s has %zu dimensions, expected 3.\n", (*setIn)->legend(), outfile.Filename().full(), (*setIn)->Ndim()); return 1; } DataSet_3D const& grid = static_cast<DataSet_3D const&>( *(*setIn) ); // Check input grid Vec3 OXYZ = grid.GridOrigin(); if (OXYZ[0] < 0.0 || OXYZ[1] < 0.0 || OXYZ[2] < 0.0 || OXYZ[0] > 0.0 || OXYZ[1] > 0.0 || OXYZ[2] > 0.0) mprintf("Warning: Grid '%s' origin is not 0.0, 0.0, 0.0\n" "Warning: Origin other than 0.0 not yet supported for CCP4 write.\n"); // Set default title if none set if (title_.empty()) title_.assign("CPPTRAJ CCP4 map volumetric data, set '" + grid.Meta().Legend() + "'. Format revision A."); // Check that title is not too big if (title_.size() > 800) { mprintf("Warning: CCP4 title is too large, truncating.\n"); title_.resize( 800 ); } // Set up and write header headerbyte buffer; buffer.i[0] = (int)grid.NX(); buffer.i[1] = (int)grid.NY(); buffer.i[2] = (int)grid.NZ(); buffer.i[3] = 2; // Only mode 2 supported buffer.i[4] = 0; // No offsets buffer.i[5] = 0; buffer.i[6] = 0; buffer.i[7] = (int)grid.NX(); buffer.i[8] = (int)grid.NY(); buffer.i[9] = (int)grid.NZ(); Box box( grid.Ucell() ); buffer.f[10] = (float)box[0]; buffer.f[11] = (float)box[1]; buffer.f[12] = (float)box[2]; buffer.f[13] = (float)box[3]; buffer.f[14] = (float)box[4]; buffer.f[15] = (float)box[5]; buffer.i[16] = 1; // Cols = X buffer.i[17] = 2; // Rows = Y buffer.i[18] = 3; // Secs = Z // Determine min, max, and mean of data double mean = grid[0]; double gmin = grid[0]; double gmax = grid[0]; double rmsd = grid[0] * grid[0]; for (unsigned int i = 1; i < grid.Size(); i++) { gmin = std::min(grid[i], gmin); gmax = std::max(grid[i], gmax); mean += grid[i]; rmsd += grid[i] * grid[i]; } mean /= (double)grid.Size(); rmsd /= (double)grid.Size(); rmsd = rmsd - (mean * mean); if (rmsd > 0.0) rmsd = sqrt(rmsd); else rmsd = 0.0; mprintf("\t%s\n", title_.c_str()); mprintf("\tDensity: Min=%f Max=%f Mean=%f RMS=%f\n", gmin, gmax, mean, rmsd); buffer.f[19] = (float)gmin; buffer.f[20] = (float)gmax; buffer.f[21] = (float)mean; buffer.i[22] = 1; // Assume P1 buffer.i[23] = 0; // No bytes for symmetry ops buffer.i[24] = 0; // No skew transform // Skew matrix (S11, S12, S13, S21, ...) and translation; 12 total, followed // by 15 'future use'; zero all. std::fill( buffer.i+25, buffer.i+52, 0 ); // MAP and machine precision. FIXME determine endianness! buffer.c[208] = 'M'; buffer.c[209] = 'A'; buffer.c[210] = 'P'; buffer.c[211] = ' '; buffer.c[212] = 0x44; // little endian buffer.c[213] = 0x41; buffer.c[214] = 0x00; buffer.c[215] = 0x00; // Determine RMS deviation from mean. buffer.f[54] = (float)rmsd; // Determine number of labels being used buffer.i[55] = (int)title_.size() / 80; if ( ((int)title_.size() % 80) != 0) buffer.i[55]++; outfile.Write( buffer.c, 224*sizeof(unsigned char) ); // Write labels; 10 lines, 80 chars each outfile.Write( title_.c_str(), title_.size() ); // FIXME this seems wasteful. std::vector<char> remainder( 800 - title_.size(), 0 ); outfile.Write( &remainder[0], remainder.size() ); remainder.clear(); // No symmetry bytes // Store data in buffer, then write. X changes fastest. // SANITY CHECK; This will result in invalid files if size of float is not 4. if (sizeof(float) != wSize) mprintf("Warning: Size of float on this system is %zu, not 4.\n" "Warning: Resulting CCP4 file data will not conform to standard.\n", sizeof(float)); std::vector<float> mapbuffer( grid.Size() ); std::vector<float>::iterator it = mapbuffer.begin(); for (unsigned int iz = 0; iz != grid.NZ(); iz++) for (unsigned int iy = 0; iy != grid.NY(); iy++) for (unsigned int ix = 0; ix != grid.NX(); ix++) *(it++) = grid.GetElement( ix, iy, iz ); outfile.Write( &mapbuffer[0], mapbuffer.size() * sizeof(float) ); outfile.CloseFile(); return 0; }
// DataIO_Std::WriteSet3D() int DataIO_Std::WriteSet3D( DataSet const& setIn, CpptrajFile& file ) { if (setIn.Ndim() != 3) { mprinterr("Internal Error: DataSet %s in DataFile %s has %zu dimensions, expected 3.\n", setIn.legend(), file.Filename().full(), setIn.Ndim()); return 1; } DataSet_3D const& set = static_cast<DataSet_3D const&>( setIn ); Dimension const& Xdim = static_cast<Dimension const&>(set.Dim(0)); Dimension const& Ydim = static_cast<Dimension const&>(set.Dim(1)); Dimension const& Zdim = static_cast<Dimension const&>(set.Dim(2)); //if (Xdim.Step() == 1.0) xcol_precision = 0; if (sparse_) mprintf("\tOnly writing voxels with value > %g\n", cut_); // Print X Y Z Values // x y z val(x,y,z) DataSet::SizeArray pos(3); if (writeHeader_) { file.Printf("#counts %zu %zu %zu\n", set.NX(), set.NY(), set.NZ()); file.Printf("#origin %12.7f %12.7f %12.7f\n", set.Bin().GridOrigin()[0], set.Bin().GridOrigin()[1], set.Bin().GridOrigin()[2]); if (set.Bin().IsOrthoGrid()) { GridBin_Ortho const& b = static_cast<GridBin_Ortho const&>( set.Bin() ); file.Printf("#delta %12.7f %12.7f %12.7f\n", b.DX(), b.DY(), b.DZ()); } else { GridBin_Nonortho const& b = static_cast<GridBin_Nonortho const&>( set.Bin() ); file.Printf("#delta %12.7f %12.7f %12.7f %12.7f %12.7f %12.7f %12.7f %12.7f %12.7f\n", b.Ucell()[0]/set.NX(), b.Ucell()[1]/set.NX(), b.Ucell()[2]/set.NX(), b.Ucell()[3]/set.NY(), b.Ucell()[4]/set.NY(), b.Ucell()[5]/set.NY(), b.Ucell()[6]/set.NZ(), b.Ucell()[7]/set.NZ(), b.Ucell()[8]/set.NZ()); } file.Printf("#%s %s %s %s\n", Xdim.Label().c_str(), Ydim.Label().c_str(), Zdim.Label().c_str(), set.legend()); } std::string xyz_fmt; if (XcolPrecSet()) { TextFormat nfmt( XcolFmt(), XcolWidth(), XcolPrec() ); xyz_fmt = nfmt.Fmt() + " " + nfmt.Fmt() + " " + nfmt.Fmt() + " "; } else { TextFormat xfmt( XcolFmt(), set.NX(), Xdim.Min(), Xdim.Step(), 8, 3 ); TextFormat yfmt( XcolFmt(), set.NY(), Ydim.Min(), Ydim.Step(), 8, 3 ); TextFormat zfmt( XcolFmt(), set.NZ(), Zdim.Min(), Zdim.Step(), 8, 3 ); xyz_fmt = xfmt.Fmt() + " " + yfmt.Fmt() + " " + zfmt.Fmt() + " "; } if (sparse_) { for (pos[2] = 0; pos[2] < set.NZ(); ++pos[2]) { for (pos[1] = 0; pos[1] < set.NY(); ++pos[1]) { for (pos[0] = 0; pos[0] < set.NX(); ++pos[0]) { double val = set.GetElement(pos[0], pos[1], pos[2]); if (val > cut_) { Vec3 xyz = set.Bin().Corner(pos[0], pos[1], pos[2]); file.Printf( xyz_fmt.c_str(), xyz[0], xyz[1], xyz[2] ); set.WriteBuffer( file, pos ); file.Printf("\n"); } } } } } else { for (pos[2] = 0; pos[2] < set.NZ(); ++pos[2]) { for (pos[1] = 0; pos[1] < set.NY(); ++pos[1]) { for (pos[0] = 0; pos[0] < set.NX(); ++pos[0]) { Vec3 xyz = set.Bin().Corner(pos[0], pos[1], pos[2]); file.Printf( xyz_fmt.c_str(), xyz[0], xyz[1], xyz[2] ); set.WriteBuffer( file, pos ); file.Printf("\n"); } } } } return 0; }
// DataIO_Std::WriteSet2D() int DataIO_Std::WriteSet2D( DataSet const& setIn, CpptrajFile& file ) { if (setIn.Ndim() != 2) { mprinterr("Internal Error: DataSet %s in DataFile %s has %zu dimensions, expected 2.\n", setIn.legend(), file.Filename().full(), setIn.Ndim()); return 1; } DataSet_2D const& set = static_cast<DataSet_2D const&>( setIn ); int xcol_width = 8; int xcol_precision = 3; Dimension const& Xdim = static_cast<Dimension const&>(set.Dim(0)); Dimension const& Ydim = static_cast<Dimension const&>(set.Dim(1)); if (Xdim.Step() == 1.0) xcol_precision = 0; DataSet::SizeArray positions(2); TextFormat ycoord_fmt(XcolFmt()), xcoord_fmt(XcolFmt()); if (square2d_) { // Print XY values in a grid: // x0y0 x1y0 x2y0 // x0y1 x1y1 x2y1 // x0y2 x1y2 x2y2 // If file has header, top-left value will be '#<Xlabel>-<Ylabel>', // followed by X coordinate values. if (writeHeader_) { ycoord_fmt.SetCoordFormat( set.Nrows(), Ydim.Min(), Ydim.Step(), xcol_width, xcol_precision ); std::string header; if (Xdim.Label().empty() && Ydim.Label().empty()) header = "#Frame"; else header = "#" + Xdim.Label() + "-" + Ydim.Label(); WriteNameToBuffer( file, header, xcol_width, true ); xcoord_fmt.SetCoordFormat( set.Ncols(), Xdim.Min(), Xdim.Step(), set.Format().ColumnWidth(), xcol_precision ); for (size_t ix = 0; ix < set.Ncols(); ix++) file.Printf( xcoord_fmt.fmt(), set.Coord(0, ix) ); file.Printf("\n"); } for (positions[1] = 0; positions[1] < set.Nrows(); positions[1]++) { if (writeHeader_) file.Printf( ycoord_fmt.fmt(), set.Coord(1, positions[1]) ); for (positions[0] = 0; positions[0] < set.Ncols(); positions[0]++) set.WriteBuffer( file, positions ); file.Printf("\n"); } } else { // Print X Y Values // x y val(x,y) if (writeHeader_) file.Printf("#%s %s %s\n", Xdim.Label().c_str(), Ydim.Label().c_str(), set.legend()); if (XcolPrecSet()) { xcoord_fmt = TextFormat(XcolFmt(), XcolWidth(), XcolPrec()); ycoord_fmt = xcoord_fmt; } else { xcoord_fmt.SetCoordFormat( set.Ncols(), Xdim.Min(), Xdim.Step(), 8, 3 ); ycoord_fmt.SetCoordFormat( set.Nrows(), Ydim.Min(), Ydim.Step(), 8, 3 ); } std::string xy_fmt = xcoord_fmt.Fmt() + " " + ycoord_fmt.Fmt() + " "; for (positions[1] = 0; positions[1] < set.Nrows(); ++positions[1]) { for (positions[0] = 0; positions[0] < set.Ncols(); ++positions[0]) { file.Printf( xy_fmt.c_str(), set.Coord(0, positions[0]), set.Coord(1, positions[1]) ); set.WriteBuffer( file, positions ); file.Printf("\n"); } } } return 0; }