// Action_ClusterDihedral::ReadDihedrals()
int Action_ClusterDihedral::ReadDihedrals(std::string const& fname) {
  CpptrajFile infile;
  char buffer[256];
  int a1, a2, a3, a4, bins;
  double min;

  if ( infile.OpenRead( fname ) ) return 1;
  mprintf("\tReading dihedral information from %s\n", fname.c_str());
  while (infile.Gets(buffer, 256)==0) {
    // Expected line format: At#1 At#2 At#3 At#4 Bins Min
    // ATOM NUMBERS SHOULD START FROM 1!
    int nvals = sscanf(buffer, "%i %i %i %i %i %lf", &a1, &a2, &a3, &a4, &bins, &min);
    if (nvals < 5) {
      mprinterr("Error: Dihedral file %s: Expected at least 5 values, got %i\n", 
                fname.c_str(), nvals);
      mprinterr("Error: Problem line: [%s]\n",buffer);
      mprinterr("Error: Expected format: At#1 At#2 At#3 At#4 Bins [Min]\n");
      return 1; // This should automatically close infile through destructor.
    }
    if (nvals < 6)
      min = minimum_;
    DCmasks_.push_back( DCmask(a1-1, a2-1, a3-1, a4-1, bins, min ) );
    mprintf("\t\t(%i)-(%i)-(%i)-(%i) Bins=%i Min=%.3f\n",a1,a2,a3,a4,bins,min);
  }
  mprintf("\tRead %zu dihedrals.\n", DCmasks_.size());
  infile.CloseFile();
  return 0;
}
Exemple #2
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;
}
/** Load Karplus parameters from input file.
  * Expected format:
  * - {type}<+|-| ><a[4]><+|-| ><b[4]><+|-| ><c[4]><+|-| ><d[4]><A[6]><B[6]><C[6]>{<D[6]>}
  *   <reslabel[4]>* 
  * \return 0 on success, 1 on error
  */
int Action_Jcoupling::loadKarplus(std::string filename) {
  char buffer[512],residue[5];
  char *end, *ptr;
  int i;
  CpptrajFile KarplusFile;
  karplusConstant KC;
  karplusConstantList* currentResList=0;
  std::string CurrentRes;
  karplusConstantMap::iterator reslist;

  if (filename.empty()) {
    mprinterr("Error: jcoupling: Could not find Karplus parameter file.\n");
    return 1;
  }
  if (KarplusFile.OpenRead( filename )) {
    mprinterr("Error: jcoupling: Could not read Karplus parameter file %s\n",
              filename.c_str());
    mprinterr("Error: Ensure the file exists and is readable.\n");
    return 1;
  }
  // residue is only for reading in 4 chars for residue names
  residue[4]='\0'; 
  // Read through all lines of the file
  while (KarplusFile.Gets(buffer,512)==0) {
    // Skip newlines and comments
    if (buffer[0]=='\n' || buffer[0]=='#') continue;
    ptr=buffer;
    // First char is optional type. If optional type is C, then the Karplus 
    // function specified in Perez et al. JACS (2001) 123 will be used, and 
    // A, B, and C will be taken as C0, C1, and C2.
    if(ptr[0]=='C') {
      KC.type=1;
      ptr++;
    } else {
      KC.type=0;
    }
    // Read atom names with optional preceding character (+, -)
    for (i=0; i<4; i++) {
      if      (*ptr=='+') KC.offset[i]=1;
      else if (*ptr=='-') KC.offset[i]=-1;
      else                     KC.offset[i]=0;
      ++ptr;
      char *endchar = ptr + 4;
      char savechar = *endchar;
      *endchar = '\0';
      KC.atomName[i] = ptr;
      *endchar = savechar;
      ptr += 4;
      //mprintf("DEBUG:\tAtomName %i [%s]\n",i,KC.atomName[i]);
    }
    // Read parameters
    // NOTE: Using sscanf here instead of atof since the 4th parameter is
    //       optional, behavior is undefined for accessing uninitialized
    //       portion of buffer.
    i = sscanf(ptr, "%6lf%6lf%6lf%6lf",KC.C,KC.C+1,KC.C+2,KC.C+3);
    if (i<3) {
      mprintf("Error: jcoupling: Expected at least 3 Karplus parameters, got %i\n",i);
      mprintf("       Line: [%s]\n",buffer);
      return 1;
    } else if (i==3) KC.C[3]=0.0;
    KC.C[3]*=Constants::DEGRAD;
    // Place the read-in karplus constants in a map indexed by residue name 
    // so that all karplus constants for a given residue are in one place. 
    KarplusFile.Gets(buffer,512);
    // end will hold the end of the read-in buffer string
    end = buffer + strlen(buffer);
    for (ptr = buffer; ptr < end; ptr+=4) {
      if (*ptr=='\n') continue;
      residue[0] = ptr[0];
      residue[1] = ptr[1];
      residue[2] = ptr[2];
      residue[3] = ptr[3];
      CurrentRes.assign(residue);
      //mprintf("DEBUG:\t[%s]\n",CurrentRes.c_str());
      reslist = KarplusConstants_.find(CurrentRes);
      if (reslist == KarplusConstants_.end() ) {
        // List does not exist for residue yet, create it.
        currentResList = new karplusConstantList;
        KarplusConstants_.insert( reslist, 
                                  std::pair<std::string,karplusConstantList*>(
                                    CurrentRes,currentResList) );
      } else
        // Retrieve list for residue.
        currentResList = (*reslist).second;

      currentResList->push_back(KC);
      ++Nconstants_;
    } // END loop over residues in residue line 
  } // END Gets over input file
  KarplusFile.CloseFile();
  // DEBUG - Print out all parameters
  if (debug_>0) {
      mprintf("    KARPLUS PARAMETERS:\n");
      for (reslist=KarplusConstants_.begin(); reslist!=KarplusConstants_.end(); ++reslist) 
      {
        mprintf("\t[%4s]\n",(*reslist).first.c_str());
        for (karplusConstantList::iterator kc = currentResList->begin();
                                           kc != currentResList->end(); ++kc) 
        {
          mprintf("\t\t%1i",(*kc).type);
          mprintf(" %4s",*((*kc).atomName[0]));
          mprintf(" %4s",*((*kc).atomName[1]));
          mprintf(" %4s",*((*kc).atomName[2]));
          mprintf(" %4s",*((*kc).atomName[3]));
          mprintf(" %i %i %i %i",(*kc).offset[0],(*kc).offset[1],(*kc).offset[2],(*kc).offset[3]);
          mprintf(" %6.2lf %6.2lf %6.2lf %6.2lf\n",(*kc).C[0],(*kc).C[1],(*kc).C[2],(*kc).C[3]);
        }
      }
  }
  return 0;
}