mFES - molecular Finite Element Solver
0.4
|
00001 00013 #include <fstream> 00014 #include <sstream> 00015 #include <math.h> 00016 #include <vector> 00017 00018 #include "VCG.h" 00019 00020 typedef boost::property_tree::ptree INI; 00021 00022 00023 #include "LSMS/molTypes.h" 00024 #include "LSMS/gridTypes.h" 00025 #include "LSMS/grid.h" 00026 #include "LSMS/pdbLoader.h" 00027 #include "LSMS/sceneBuilder.h" 00028 00029 00030 Molecule mol = NULL; // molecule 00031 float minx,miny,minz,maxx,maxy,maxz; 00032 double s; 00033 00046 class STLFacet 00047 { 00048 public: 00049 Point3f n; 00050 Point3f v[3]; 00051 }; 00052 00053 typedef typename mMesh::FaceIterator FaceIterator; 00054 typedef typename mMesh::VertexIterator VertexIterator; 00055 00071 class LSMS { 00072 public: 00073 int calcMC(mMesh &mSurface, vector<Atom> &atomList, INI& ini, string mode = "protein") { 00074 00075 string debug = ini.get<string>("model.debug"); 00076 double probeRadius = atof(ini.get_optional<string>("experiment.probe_radius").get_value_or("1.4").c_str()); 00077 double ionExclR = atof(ini.get_optional<string>("experiment.ionr").get_value_or("2").c_str()); 00078 bool calc_cavity = false; 00079 unsigned int gridSize = 512; 00080 float extendR = 0; 00081 00082 if (mode == "protein") { 00083 gridSize = ini.get<unsigned int>("model.grid_resolution"); 00084 } else if (mode == "residue") { 00085 gridSize = ini.get<unsigned int>("model.grid_residue_resolution"); 00086 } else if (mode == "exclusion") { 00087 gridSize = ini.get<unsigned int>("model.grid_resolution"); 00088 extendR = ionExclR; // ion exclusion layer distance [Angstroem] 00089 probeRadius = atof(ini.get_optional<string>("experiment.exclusion_probe_radius").get_value_or("0.3").c_str()); 00090 } else if (mode == "residue_exclusion") { 00091 gridSize = ini.get<unsigned int>("model.grid_residue_resolution"); 00092 extendR = ionExclR; // ion exclusion layer distance [Angstroem] 00093 probeRadius = atof(ini.get_optional<string>("experiment.exclusion_probe_radius").get_value_or("0.3").c_str()); 00094 } else { 00095 // cavity calculation is turned on 00096 calc_cavity = true; 00097 probeRadius = atof(ini.get_optional<string>("experiment.cavity_probe_radius").get_value_or("0.5").c_str()); 00098 gridSize = ini.get_optional<unsigned int>("model.grid_cavity_resolution").get_value_or(512); 00099 } 00100 00101 cout << "grid size: " << gridSize << endl; 00102 cout << "probe radius: " << probeRadius << endl; 00103 cout << "atom list size: " << atomList.size() << endl; 00104 00105 Molecule mol = (Molecule)malloc(sizeof(struct prot)); 00106 mol->npoints = atomList.size(); 00107 mol->xpoints = (float *)malloc(mol->npoints*sizeof(float)); 00108 mol->ypoints = (float *)malloc(mol->npoints*sizeof(float)); 00109 mol->zpoints = (float *)malloc(mol->npoints*sizeof(float)); 00110 mol->rpoints = (float *)malloc(mol->npoints*sizeof(float)); 00111 00112 for (unsigned int i = 0; i<atomList.size() ; i++) { 00113 Atom currentAtom = atomList.at(i); 00114 Point3<float> currentCoord = currentAtom.getCoord(); 00115 mol->xpoints[i] = currentCoord.X(); 00116 mol->ypoints[i] = currentCoord.Y(); 00117 mol->zpoints[i] = currentCoord.Z(); 00118 mol->rpoints[i] = currentAtom.getRadius() + extendR; 00119 if (debug == "yes") 00120 cout << "x, y, z, r: " << mol->xpoints[i] << ", " << mol->ypoints[i] << ", " << mol->zpoints[i] << ", " << mol->rpoints[i] << endl; 00121 } 00122 00123 00124 char inner = 0; 00125 float k = 0; 00126 00127 if (calc_cavity) 00128 inner = 1; //calc_cavity-'0'; 00129 else 00130 inner = 0; 00131 00132 s = centerMolecule(mol,gridSize); 00133 00134 probeRadius = probeRadius*s; 00135 00136 //grid = createGrid(N); 00137 short s2; 00138 // int i = N; 00139 int i = gridSize; 00140 int halfLength = 256; 00141 short m2,n2,k2; 00142 lGrid g = (lGrid)malloc(sizeof(struct g)); 00143 // g->N = N; 00144 g->N = gridSize; 00145 00146 if (gridSize <= 512){ 00147 s2 = 512/i; 00148 halfLength = 256; 00149 } else { 00150 s2 = gridSize/i; 00151 halfLength = gridSize/2; 00152 } 00153 g->stepSize = s2; 00154 00155 g->matrix = (GridPoint***)malloc(i*sizeof(GridPoint**)); 00156 for (m2=0;m2<i;m2++) 00157 g->matrix[m2] = (GridPoint**)malloc(i*sizeof(GridPoint*)); 00158 for (m2=0;m2<i;m2++) 00159 for (n2=0;n2<i;n2++) 00160 g->matrix[m2][n2] = (GridPoint*)malloc(i*sizeof(GridPoint)); 00161 00162 for(m2=0;m2<i;m2++) 00163 for (n2=0;n2<i;n2++) 00164 for (k2=0;k2<i;k2++) 00165 { 00166 g->matrix[m2][n2][k2].point.x = -halfLength+m2*s2; 00167 g->matrix[m2][n2][k2].point.y = -halfLength+n2*s2; 00168 g->matrix[m2][n2][k2].point.z = -halfLength+k2*s2; 00169 g->matrix[m2][n2][k2].phi = 1; // everything is outside surface 00170 g->matrix[m2][n2][k2].from=-2; 00171 g->matrix[m2][n2][k2].dist= 0; 00172 } 00173 00174 signDistanceGridMol(g,mol,probeRadius,gridSize); 00175 00176 // Don't do shrinking, if probe radius is 0 00177 if (probeRadius == 0) 00178 printf("Not shrinking because probe radius is 0.\n"); 00179 else 00180 shrink(g,probeRadius,gridSize); 00181 00182 // k = s/(512/N); 00183 if (gridSize <= 512) 00184 k = s/(512/gridSize); 00185 else 00186 k = s; 00187 00188 k = k * k * k; 00189 00190 vector<Triangle> result; 00191 00192 float volume = fastMarching(g,inner)/k; 00193 printf("\nTotal cavity/molecule volume = %f A^3\n", volume); 00194 00195 if (calc_cavity && volume == 0){ 00196 cout << "no cavity found!" << endl; 00197 return 0; 00198 } 00199 init(result, g); 00200 00201 cout << "Counting " << result.size() << " triangles." << endl; 00202 00203 float minMaxX = minx + maxx; 00204 float minMaxY = miny + maxy; 00205 float minMaxZ = minz + maxz; 00206 00207 for (unsigned int i = 0; i < result.size(); i++){ 00208 Triangle currentTriangle = result.at(i); 00209 STLFacet f; 00210 00211 f.n = currentTriangle.normal; 00212 currentTriangle.t1.X() = (currentTriangle.t1.X()*1/(s) + (minMaxX/2)); 00213 currentTriangle.t1.Y() = (currentTriangle.t1.Y()*1/(s) + (minMaxY/2)); 00214 currentTriangle.t1.Z() = (currentTriangle.t1.Z()*1/(s) + (minMaxZ/2)); 00215 currentTriangle.t2.X() = (currentTriangle.t2.X()*1/(s) + (minMaxX/2)); 00216 currentTriangle.t2.Y() = (currentTriangle.t2.Y()*1/(s) + (minMaxY/2)); 00217 currentTriangle.t2.Z() = (currentTriangle.t2.Z()*1/(s) + (minMaxZ/2)); 00218 currentTriangle.t3.X() = (currentTriangle.t3.X()*1/(s) + (minMaxX/2)); 00219 currentTriangle.t3.Y() = (currentTriangle.t3.Y()*1/(s) + (minMaxY/2)); 00220 currentTriangle.t3.Z() = (currentTriangle.t3.Z()*1/(s) + (minMaxZ/2)); 00221 00222 f.v[0] = currentTriangle.t1; 00223 f.v[1] = currentTriangle.t2; 00224 f.v[2] = currentTriangle.t3; 00225 00226 FaceIterator fi=Allocator<mMesh>::AddFaces(mSurface,1); 00227 VertexIterator vi=Allocator<mMesh>::AddVertices(mSurface,3); 00228 for(int k=0;k<3;++k) 00229 { 00230 (*vi).P().Import(f.v[k]); 00231 (*fi).V(k)=&*vi; 00232 ++vi; 00233 } 00234 } 00235 00236 free(mol); 00237 // for (int i = 0; i<N; i++) { 00238 for (int i = 0; i<gridSize; i++) { 00239 // for (int j = 0; j<N; j++) { 00240 for (int j = 0; j<gridSize; j++) { 00241 free(g->matrix[i][j]); 00242 } 00243 } 00244 // for (int i = 0; i<N; i++) { 00245 for (int i = 0; i<gridSize; i++) { 00246 free(g->matrix[i]); 00247 } 00248 free(g); 00249 00250 return 1; 00251 } 00252 00253 private: 00254 00255 void init(vector<Triangle>& result, lGrid &grid){ 00256 buildScene(result, grid); 00257 } 00258 00259 double centerMolecule(Molecule mol, int gridSize) 00260 { 00261 double sx,sy,sz; 00262 double max=0; 00263 int i; 00264 double rmax = 0; 00265 00266 // set starting point 00267 minx = mol->xpoints[0]; 00268 maxx = mol->xpoints[0]; 00269 miny = mol->ypoints[0]; 00270 maxy = mol->ypoints[0]; 00271 minz = mol->zpoints[0]; 00272 maxz = mol->zpoints[0]; 00273 00274 00275 for (i=0;i<mol->npoints;i++){ 00276 if (mol->xpoints[i]-mol->rpoints[i]<minx) minx=mol->xpoints[i]-mol->rpoints[i]; 00277 if (mol->xpoints[i]+mol->rpoints[i]>maxx) maxx=mol->xpoints[i]+mol->rpoints[i]; 00278 if (mol->ypoints[i]-mol->rpoints[i]<miny) miny=mol->ypoints[i]-mol->rpoints[i]; 00279 if (mol->ypoints[i]+mol->rpoints[i]>maxy) maxy=mol->ypoints[i]+mol->rpoints[i]; 00280 if (mol->zpoints[i]-mol->rpoints[i]<minz) minz=mol->zpoints[i]-mol->rpoints[i]; 00281 if (mol->zpoints[i]+mol->rpoints[i]>maxz) maxz=mol->zpoints[i]+mol->rpoints[i]; 00282 if (rmax < mol->rpoints[i]) rmax=ceil(mol->rpoints[i]); 00283 } 00284 00285 sx = gridSize/(maxx-minx+2*rmax); 00286 sy = gridSize/(maxy-miny+2*rmax); 00287 sz = gridSize/(maxz-minz+2*rmax); 00288 00289 s = 0.0f; 00290 if (sx<sy && sx<sz){ max=(maxx-minx); s=sx; } 00291 else if (sy<sx && sy<sz){ max=(maxy-miny); s=sy;} 00292 else { max=(maxz-minz); s=sz; } 00293 00294 00295 for (i=0;i<mol->npoints;i++){ 00296 // printf("x y z r before %f %f %f %f\n", mol->xpoints[i], mol->ypoints[i], mol->zpoints[i], mol->rpoints[i]); 00297 mol->xpoints[i]=(s*(mol->xpoints[i]-((minx+maxx)/2))); 00298 mol->ypoints[i]=(s*(mol->ypoints[i]-((miny+maxy)/2))); 00299 mol->zpoints[i]=(s*(mol->zpoints[i]-((minz+maxz)/2))); 00300 // printf("x y z r after %f %f %f %f\n", mol->xpoints[i], mol->ypoints[i], mol->zpoints[i], mol->rpoints[i]); 00301 mol->rpoints[i]=mol->rpoints[i]*s; 00302 } 00303 00304 cout << "min: " << minx << ", " << miny << ", " << minz << "; max: " << maxx << ", " << maxy << ", " << maxz << endl; 00305 cout << "abs (x, y, z): (" << (maxx-minx) << ", " << (maxy-miny) << ", " << (maxz-minz) << ")" << endl; 00306 cout << "scaling: " << s << endl; 00307 cout << "grid size: " << gridSize << endl; 00308 cout << "r_max: " << rmax << endl; 00309 00310 /* double h_eff = 512/gridSize* max/gridSize; 00311 if (gridSize > 512) 00312 h_eff = max/gridSize; 00313 cout << "h_eff: " << h_eff << endl; 00314 */ 00315 00316 return s; 00317 } 00318 00319 };