//------------------------------------------------------------------------------ bool OBOpenDXCubeFormat::ReadMolecule( OBBase* pOb, OBConversion* pConv ) { OBMol* pmol = pOb->CastAndClear<OBMol>(); if(pmol == 0) return false; istream& ifs = *pConv->GetInStream(); const char* title = pConv->GetTitle(); char buffer[BUFF_SIZE]; stringstream errorMsg; if (!ifs) return false; // We are attempting to read past the end of the file pmol->SetTitle(title); while (ifs.good() && ifs.getline(buffer,BUFF_SIZE)) { if (buffer[0] == '#') continue; // comment line if (EQn(buffer, "object", 6)) break; } if (!ifs) return false; // ran out of lines vector<string> vs; tokenize(vs, buffer); // Number of grid points (voxels) vector<int> voxels(3); if (!EQn(buffer, "object", 6) || vs.size() != 8) return false; else { voxels[0] = atoi(vs[5].c_str()); voxels[1] = atoi(vs[6].c_str()); voxels[2] = atoi(vs[7].c_str()); } double x, y, z; if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "origin", 6)) return false; else { tokenize(vs, buffer); if (vs.size() != 4) return false; x = atof(vs[1].c_str()); y = atof(vs[2].c_str()); z = atof(vs[3].c_str()); } vector3 origin(x, y, z); // now three lines with the x, y, and z axes vector<vector3> axes; for (unsigned int i = 0; i < 3; ++i) { if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "delta", 5)) return false; else { tokenize(vs, buffer); if (vs.size() != 4) return false; x = atof(vs[1].c_str()); y = atof(vs[2].c_str()); z = atof(vs[3].c_str()); axes.push_back(vector3(x, y, z)); } } // Two remaining header lines before the data: /* object 2 class gridconnections counts nx ny nz object 3 class array type double rank 0 times n data follows */ if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "object", 6)) return false; if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "object", 6)) return false; pmol->BeginModify(); pmol->SetDimension(3); OBGridData *gd = new OBGridData; gd->SetAttribute("OpenDX"); // get all values as one vector<double> char *endptr; vector<double> values; int n = voxels[0]*voxels[1]*voxels[2]; int line = 0; values.reserve(n); while (ifs.getline(buffer, BUFF_SIZE)) { ++line; if (EQn(buffer, "attribute", 9)) break; // we're finished with reading data -- although we should probably have a voxel check in here too tokenize(vs, buffer); if (vs.size() == 0) { errorMsg << "Problem reading the OpenDX grid file: cannot" << " read line " << line << ", there does not appear to be any data in it.\n" << buffer << "\n"; obErrorLog.ThrowError(__FUNCTION__, errorMsg.str(), obError); return false; } for (unsigned int l = 0; l < vs.size(); ++l) { values.push_back(strtod(static_cast<const char*>(vs[l].c_str()), &endptr)); } } gd->SetNumberOfPoints(voxels[0], voxels[1], voxels[2]); gd->SetLimits(origin, axes[0], axes[1], axes[2]); gd->SetUnit(OBGridData::ANGSTROM); gd->SetOrigin(fileformatInput); // i.e., is this data from a file or determined by Open Babel gd->SetValues(values); // set the values pmol->SetData(gd); // store the grids in the OBMol pmol->EndModify(); // Trailing control lines /* attribute "dep" string "positions" object "regular positions regular connections" class field component "positions" value 1 component "connections" value 2 component "data" value 3 */ if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "object", 6)) return false; if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "component", 9)) return false; if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "component", 9)) return false; if (!ifs.getline(buffer, BUFF_SIZE) || !EQn(buffer, "component", 9)) return false; // clean out any remaining blank lines std::streampos ipos; do { ipos = ifs.tellg(); ifs.getline(buffer,BUFF_SIZE); } while(strlen(buffer) == 0 && !ifs.eof() ); ifs.seekg(ipos); return true; }
//------------------------------------------------------------------------------ bool OBGaussianCubeFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv) { OBMol* pmol = dynamic_cast<OBMol*>(pOb); if(pmol==NULL) return false; ostream &ofs = *pConv->GetOutStream(); OBMol &mol = *pmol; char buffer[BUFF_SIZE]; string str; stringstream errorMsg; // first two lines are comments str = mol.GetTitle(); if (str.empty()) ofs << "*****" << endl; else ofs << str << endl; ofs << endl; // line 2 OBGridData *gd = (OBGridData*)mol.GetData(OBGenericDataType::GridData); if (gd == NULL) { errorMsg << "The molecule has no grid."; obErrorLog.ThrowError(__FUNCTION__, errorMsg.str(), obWarning); return false; } int nx, ny, nz; double origin[3], xAxis[3], yAxis[3], zAxis[3]; gd->GetAxes(xAxis, yAxis, zAxis); gd->GetNumberOfPoints(nx, ny, nz); gd->GetOriginVector(origin); // line 3: number of atoms, origin x y z snprintf(buffer, BUFF_SIZE,"%5d%12.6f%12.6f%12.6f", - static_cast<signed int> (mol.NumAtoms()), origin[0]*ANGSTROM_TO_BOHR, origin[1]*ANGSTROM_TO_BOHR, origin[2]*ANGSTROM_TO_BOHR); ofs << buffer << endl; // line 4: number of points x direction, axis x direction x y z snprintf(buffer, BUFF_SIZE,"%5d%12.6f%12.6f%12.6f", nx, xAxis[0]*ANGSTROM_TO_BOHR, xAxis[1]*ANGSTROM_TO_BOHR, xAxis[2]*ANGSTROM_TO_BOHR); ofs << buffer << endl; // line 5: number of points y direction, axis y direction x y z snprintf(buffer, BUFF_SIZE,"%5d%12.6f%12.6f%12.6f", ny, yAxis[0]*ANGSTROM_TO_BOHR, yAxis[1]*ANGSTROM_TO_BOHR, yAxis[2]*ANGSTROM_TO_BOHR); ofs << buffer << endl; // line 6: number of points z direction, axis z direction x y z snprintf(buffer, BUFF_SIZE,"%5d%12.6f%12.6f%12.6f", nz, zAxis[0]*ANGSTROM_TO_BOHR, zAxis[1]*ANGSTROM_TO_BOHR, zAxis[2]*ANGSTROM_TO_BOHR); ofs << buffer << endl; // Atom lines: atomic number, ?, X, Y, Z FOR_ATOMS_OF_MOL (atom, mol) { double *coordPtr = atom->GetCoordinate(); snprintf(buffer, BUFF_SIZE,"%5d%12.6f%12.6f%12.6f%12.6f", atom->GetAtomicNum(), static_cast<double>(atom->GetAtomicNum()), coordPtr[0]*ANGSTROM_TO_BOHR, coordPtr[1]*ANGSTROM_TO_BOHR, coordPtr[2]*ANGSTROM_TO_BOHR); ofs << buffer << endl; }
//------------------------------------------------------------------------------ bool OBOpenDXCubeFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv) { OBMol* pmol = dynamic_cast<OBMol*>(pOb); if(pmol==NULL) return false; ostream &ofs = *pConv->GetOutStream(); OBMol &mol = *pmol; char buffer[BUFF_SIZE]; string str; stringstream errorMsg; OBGridData *gd = (OBGridData*)mol.GetData(OBGenericDataType::GridData); if (gd == NULL) { errorMsg << "The molecule has no grid."; obErrorLog.ThrowError(__FUNCTION__, errorMsg.str(), obWarning); return false; } // APBS-style OpenDX Multigrid // First some comments ofs << "# Data from Open Babel " << BABEL_VERSION << "\n"; str = mol.GetTitle(); if (str.empty()) ofs << "# Molecule Title: *****" << "\n"; else ofs << "# Molecule Title: " << str << "\n"; int nx, ny, nz; double origin[3], xAxis[3], yAxis[3], zAxis[3]; gd->GetAxes(xAxis, yAxis, zAxis); gd->GetNumberOfPoints(nx, ny, nz); gd->GetOriginVector(origin); // data line 1: # of points in x, y, z (nx, ny, nz) snprintf(buffer, BUFF_SIZE, "object 1 class gridpositions counts %5d %5d %5d", nx, ny, nz); ofs << buffer << "\n"; // data line 2: origin (x, y, z) snprintf(buffer, BUFF_SIZE,"origin %12.6f %12.6f %12.6f", origin[0], origin[1], origin[2]); ofs << buffer << "\n"; // data line 3: x-displacement snprintf(buffer, BUFF_SIZE,"delta %12.6f %12.6f %12.6f", xAxis[0], xAxis[1], xAxis[2]); ofs << buffer << "\n"; // data line 4: y-displacement snprintf(buffer, BUFF_SIZE,"delta %12.6f %12.6f %12.6f", yAxis[0], yAxis[1], yAxis[2]); ofs << buffer << "\n"; // data line 5: z-displacement snprintf(buffer, BUFF_SIZE,"delta %12.6f %12.6f %12.6f", zAxis[0], zAxis[1], zAxis[2]); ofs << buffer << "\n"; // data line 6: # of points in x, y, z (nx, ny, nz) snprintf(buffer, BUFF_SIZE, "object 2 class gridconnections counts %5d %5d %5d", nx, ny, nz); ofs << buffer << "\n"; // data line 7: total # of points snprintf(buffer, BUFF_SIZE, "object 3 class array type double rank 0 items %5d data follows", nx*ny*nz); ofs << buffer << "\n"; // The cube(s) double value; unsigned int count = 1; for (int i = 0; i < nx; ++i) { for (int j = 0; j < ny; ++j) { for (int k = 0; k < nz; ++k) { value = gd->GetValue(i, j, k); snprintf(buffer, BUFF_SIZE," %12.5E", value); if (count % 3 == 0) ofs << buffer << "\n"; else ofs << buffer; count++; } // z-axis } // y-axis } // x-axis if (count % 3 != 0) ofs << "\n"; ofs << "attribute \"dep\" string \"positions\"\n"; ofs << "object \"regular positions regular connections\" class field\n"; ofs << "component \"positions\" value 1\n"; ofs << "component \"connections\" value 2\n"; ofs << "component \"data\" value 3\n"; return true; }
extern "C" int readgrid_(float *vdata, int *nx, int *ny, int *nz, float *x0, float *y0, float *z0, float *xx, float *yy, float *zz, char *file, int fsize) { float dx,dy,dz; int gsize; float v, vmin, vmax, vavg; int navg = 0; OBMol mol; OBConversion conv; conv.SetInFormat("cube"); std::string fname = file; int blank = fname.find(" "); //printf("%d,'%s'\n", blank, fname.substr(0,blank).c_str()); conv.ReadFile(&mol, fname.substr(0,blank).c_str()); //cout << mol.NumAtoms() << " atoms." << endl; if (mol.HasData(OBGenericDataType::GridData)) { std::vector<OBGenericData*> grids = mol.GetAllData(OBGenericDataType::GridData); OBGridData *grid = dynamic_cast<OBGridData *> (grids[0]); gsize = grid->GetNumberOfPoints(); grid->GetNumberOfPoints(*nx, *ny, *nz); vector3 origin = grid->GetOriginVector(); *x0 = origin[0]; *y0 = origin[1]; *z0 = origin[2]; vector3 maxv = grid->GetMaxVector(); *xx = maxv[0]; *yy = maxv[1]; *zz = maxv[2]; dx=(*xx-*x0)/(*nx-1); dy=(*yy-*y0)/(*ny-1); dz=(*zz-*z0)/(*nz-1); printf("%s %d=%d*%d*%d\n", grid->GetAttribute().c_str(), gsize, *nx, *ny, *nz); printf("%f %f\n", grid->GetMinValue(), grid->GetMaxValue()); printf("%f,%f,%f\n", *x0,*y0,*z0); printf("%f,%f,%f\n", *xx,*yy,*zz); printf("%f,%f,%f\n", dx,dy,dz); //vdata = (float *)calloc(gsize, sizeof(float)); /* this is for fortran, so reverse sense of slowest/fastest moving dimensions */ //for (int i=0; i<*nx; ++i) { vmin = grid->GetValue(0,0,0); vmax = vmin; for (int i=0; i<*nz; ++i) { for (int j=0; j<*ny; ++j) { //for (int k=0; k<*nz; ++k) { for (int k=0; k<*nx; ++k) { //*vdata++ = grid->GetValue(i,j,k); v = grid->GetValue(k,j,i); if (v < 1e30 && v > -1e30) { if (v < vmin) vmin = v; if (v > vmax) vmax = v; ++navg; vavg += v; } else { v = vmax * 1000; // just a guess } *vdata++ = v; } } } } vavg = vavg/navg; printf("min/avg/max = %f/%f/%f\n", vmin, vavg, vmax); return 0; }