// WriteNameToBuffer() void DataIO_Std::WriteNameToBuffer(CpptrajFile& fileIn, std::string const& label, int width, bool isLeftCol) { std::string temp_name = label; // If left aligning, add '#' to name; if (isLeftCol) { if (temp_name[0]!='#') { temp_name.insert(0,"#"); // Ensure that name will not be larger than column width. if ((int)temp_name.size() > width) temp_name.resize( width ); } } // Replace any spaces with underscores for (std::string::iterator tc = temp_name.begin(); tc != temp_name.end(); ++tc) if ( *tc == ' ' ) *tc = '_'; if (width >= (int)CpptrajFile::BUF_SIZE) // Protect against CpptrajFile buffer overflow fileIn.Write(temp_name.c_str(), temp_name.size()); else { // Set up header format string TextFormat::AlignType align; if (isLeftCol) align = TextFormat::LEFT; else align = TextFormat::RIGHT; TextFormat header_format(TextFormat::STRING, width, align); fileIn.Printf(header_format.fmt(), temp_name.c_str()); } }
// 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; }