mFES - molecular Finite Element Solver  0.4
LSMS.h
Go to the documentation of this file.
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 };