예제 #1
0
// DataIO_CCP4::ID_DataFormat()
bool DataIO_CCP4::ID_DataFormat( CpptrajFile& infile ) {
    bool isCCP4 = false;
    if (!infile.OpenFile()) {
        unsigned char MAP[4];
        if (infile.Seek(52 * wSize) == 0) {
            infile.Read( MAP, wSize );
            isCCP4 = MapCharsValid( MAP );
        }
        infile.CloseFile();
    }
    return isCCP4;
}
예제 #2
0
/** \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;
}
예제 #3
0
/** Header is 256 4-byte words. Integer unless otherwise noted. First 56 words are:
  *    0-2: columns, rows, sections (fastest changing to slowest)
  *      3: mode: 0 = envelope stored as signed bytes (from -128 lowest to 127 highest)
  *               1 = Image     stored as Integer*2
  *               2 = Image     stored as Reals
  *               3 = Transform stored as Complex Integer*2
  *               4 = Transform stored as Complex Reals
  *               5 == 0
  *    4-6: Column, row, and section offsets
  *    7-9: Intervals along X, Y, Z
  *  10-15: float; 3x cell lengths (Ang) and 3x cell angles (deg)
  *  16-18: Map of which axes correspond to cols, rows, sections (1,2,3 = x,y,z)
  *  19-21: float; Min, max, and mean density
  *  22-24: Space group, bytes used for storing symm ops, flag for skew transform
  *         If skew flag != 0, skew transformation is from standard orthogonal
  *         coordinate frame (as used for atoms) to orthogonal map frame, as:
  *             Xo(map) = S * (Xo(atoms) - t)
  *  25-33: Skew matrix 'S' (in order S11, S12, S13, S21 etc)
  *  34-36: Skew translation 't'
  *  37-51: For future use and can be skipped.
  *     52: char; 'MAP '
  *     53: char; machine stamp for determining endianness
  *     54: float; RMS deviation of map from mean
  *     55: Number of labels
  */
int DataIO_CCP4::ReadData(FileName const& fname,
                          DataSetList& datasetlist, std::string const& dsname)
{
    CpptrajFile infile;
    if (infile.OpenRead( fname )) return 1;
    // Read first 56 words of the header into a buffer.
    headerbyte buffer;
    if (infile.Read(buffer.i, 224*sizeof(unsigned char)) < 1) {
        mprinterr("Error: Could not buffer CCP4 header.\n");
        return 1;
    }
    if (debug_ > 0)
        mprintf("DEBUG: MAP= '%c %c %c %c'  MACHST= '%x %x %x %x'\n",
                buffer.c[208], buffer.c[209], buffer.c[210], buffer.c[211],
                buffer.c[212], buffer.c[213], buffer.c[214], buffer.c[215]);
    // SANITY CHECK
    if (!MapCharsValid(buffer.c + 208)) {
        mprinterr("Error: CCP4 file missing 'MAP ' string at word 53\n");
        return 1;
    }
    // Check endianess
    bool isBigEndian = (buffer.c[212] == 0x11 && buffer.c[213] == 0x11 &&
                        buffer.c[214] == 0x00 && buffer.c[215] == 0x00);
    if (!isBigEndian) {
        if (debug_ > 0) mprintf("DEBUG: Little endian.\n");
        // SANITY CHECK
        if ( !(buffer.c[212] == 0x44 && buffer.c[213] == 0x41 &&
                buffer.c[214] == 0x00 && buffer.c[215] == 0x00) )
            mprintf("Warning: Invalid machine stamp: %x %x %x %x : assuming little endian.\n",
                    buffer.c[212], buffer.c[213], buffer.c[214], buffer.c[215]);
    } else {
        if (debug_ > 0) mprintf("DEBUG: Big endian.\n");
        // Perform endian swapping on header if necessary
        endian_swap(buffer.i, 56);
    }

    // Print DEBUG info
    if (debug_ > 0) {
        mprintf("DEBUG: Columns=%i  Rows=%i  Sections=%i\n", buffer.i[0], buffer.i[1], buffer.i[2]);
        mprintf("DEBUG: Mode=%i\n", buffer.i[3]);
        mprintf("DEBUG: Offsets: C=%i  R=%i  S=%i\n", buffer.i[4], buffer.i[5], buffer.i[6]);
        mprintf("DEBUG: NXYZ={ %i %i %i }\n", buffer.i[7], buffer.i[8], buffer.i[9]);
        mprintf("DEBUG: Box XYZ={ %f %f %f }  ABG={ %f %f %f }\n",
                buffer.f[10], buffer.f[11], buffer.f[12],
                buffer.f[13], buffer.f[14], buffer.f[15]);
        mprintf("DEBUG: Map: ColAxis=%i  RowAxis=%i  SecAxis=%i\n",
                buffer.i[16], buffer.i[17], buffer.i[18]);
        mprintf("DEBUG: SpaceGroup#=%i  SymmOpBytes=%i  SkewFlag=%i\n",
                buffer.i[22], buffer.i[23], buffer.i[24]);
        const int* MSKEW = buffer.i + 25;
        mprintf("DEBUG: Skew matrix: %i %i %i\n"
                "                    %i %i %i\n"
                "                    %i %i %i\n", MSKEW[0], MSKEW[1], MSKEW[2], MSKEW[3],
                MSKEW[4], MSKEW[5], MSKEW[6], MSKEW[7], MSKEW[8]);
        const int* TSKEW = buffer.i + 34;
        mprintf("DEBUG: Skew translation: %i %i %i\n", TSKEW[0], TSKEW[1], TSKEW[2]);
        mprintf("DEBUG: Nlabels=%i\n", buffer.i[55]);
    }
    // Check input data. Only support mode 2 for now.
    if (buffer.i[3] != 2) {
        mprinterr("Error: Mode %i; currently only mode 2 for CCP4 files is supported.\n", buffer.i[3]);
        return 1;
    }
    // Check offsets.
    if (buffer.i[4] != 0 || buffer.i[5] != 0 || buffer.i[6] != 0)
        mprintf("Warning: Non-zero offsets present. This is not yet supported and will be ignored.\n");
    // Check that mapping is col=x row=y section=z
    if (buffer.i[16] != 1 || buffer.i[17] != 2 || buffer.i[18] != 3) {
        mprinterr("Error: Currently only support cols=X, rows=Y, sections=Z\n");
        return 1;
    }
    if (buffer.i[24] != 0) {
        mprintf("Warning: Skew information present but not yet supported and will be ignored.\n");
        return 1;
    }

    // Read 10 80 character text labels
    char Labels[801];
    Labels[800] = '\0';
    infile.Read( Labels, 200*wSize );
    mprintf("\t%s\n", Labels);
    // Symmetry records: operators separated by * and grouped into 'lines' of 80 characters
    int NsymmRecords = buffer.i[23] / 80;
    if (NsymmRecords > 0) {
        char symBuffer[81];
        mprintf("\t%i symmetry records.\n", NsymmRecords);
        for (int ib = 0; ib != NsymmRecords; ib++) {
            infile.Gets( symBuffer, 80 );
            mprintf("\t%s\n", symBuffer);
        }
    }

    // Add grid data set. Default to float for now.
    DataSet* gridDS = datasetlist.AddSet( DataSet::GRID_FLT, dsname, "GRID" );
    if (gridDS == 0) return 1;
    DataSet_GridFlt& grid = static_cast<DataSet_GridFlt&>( *gridDS );
    // Allocate grid from dims and spacing. FIXME OK to assume zero origin?
    if (grid.Allocate_N_O_Box( buffer.i[7], buffer.i[8], buffer.i[9],
                               Vec3(0.0), Box(buffer.f + 10) ) != 0)
    {
        mprinterr("Error: Could not allocate grid.\n");
        return 1;
    }
    // FIXME: Grids are currently indexed so Z is fastest changing.
    //        Should be able to change indexing in grid DataSet.
    size_t mapSize = buffer.i[7] * buffer.i[8] * buffer.i[9];
    mprintf("\tCCP4 map has %zu elements\n", mapSize);
    mprintf("\tDensity: Min=%f  Max=%f  Mean=%f  RMS=%f\n",
            buffer.f[19], buffer.f[20], buffer.f[21], buffer.f[54]);
    std::vector<float> mapbuffer( mapSize );
    int mapBytes = mapSize * wSize;
    int numRead = infile.Read( &mapbuffer[0], mapBytes );
    if (numRead < 1) {
        mprinterr("Error: Could not read CCP4 map data.\n");
        return 1;
    } else if (numRead < mapBytes)
        mprintf("Warning: Expected %i bytes, read only %i bytes\n", mapBytes, numRead);
    if (isBigEndian) endian_swap(&mapbuffer[0], mapSize);

    // FIXME: Place data into grid DataSet with correct ordering.
    int gidx = 0;
    int NXY = buffer.i[7] * buffer.i[8];
    for (int ix = 0; ix != buffer.i[7]; ix++)
        for (int iy = 0; iy != buffer.i[8]; iy++)
            for (int iz = 0; iz != buffer.i[9]; iz++) {
                int midx = (iz * NXY) + (iy * buffer.i[7]) + ix;
                grid[gidx++] = mapbuffer[midx];
            }

    infile.CloseFile();
    return 0;
}