Пример #1
0
// 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()); 
  }
}
Пример #2
0
// 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;
}