// 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; }
/** 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; }