The RigidCLL library


testRigidCLL.cpp

Go to the documentation of this file.
00001 #include "RigidCLL.h"
00002 
00003 #include <iostream>
00004 #include <algorithm> 
00005 #include <stdlib.h>    
00006 #include <time.h> 
00007 #include <math.h>
00008 #include <unistd.h>
00009 #include <sys/resource.h>
00010 
00025 #define RAND_DOUBLE(s) (((double)rand()*2*s)/(double)RAND_MAX-s)
00026 
00033 #define N_EXPERIMENTS 50
00034 
00041 #define REPETITIONS 10000
00042 
00048 double getTime();
00049 
00063 void RandomTranslation(double sx,double sy,double sz,RigidTransform *t);
00064 
00077 void PrintInteractions(const string &label,list<AtomPair> *interactions);
00078 
00091 bool CmpInteractions(list<AtomPair> *interactions1,list<AtomPair> *interactions2);
00092 
00093 
00094 
00095 /********************************************************************************/
00096 /********************************************************************************/
00097 /********************************************************************************/
00098 
00099 double getTime()
00100 {
00101   struct rusage usage;
00102 
00103   getrusage(RUSAGE_SELF,&usage);
00104 
00105   /* Accumulate the user and system time and convert to miliseconds */
00106   return((double)(usage.ru_utime.tv_sec +usage.ru_stime.tv_sec )*1000.0+
00107          (double)(usage.ru_utime.tv_usec+usage.ru_stime.tv_usec)/1000.0);
00108 }
00109 
00110 void RandomTranslation(double sx,double sy,double sz,RigidTransform *t)
00111 {
00112   (*t)[0][0]=1;(*t)[0][1]=0;(*t)[0][2]=0;(*t)[0][3]=RAND_DOUBLE(sx);
00113   (*t)[1][0]=0;(*t)[1][1]=1;(*t)[1][2]=0;(*t)[1][3]=RAND_DOUBLE(sy);
00114   (*t)[2][0]=0;(*t)[2][1]=0;(*t)[2][2]=1;(*t)[2][3]=RAND_DOUBLE(sz);
00115   (*t)[3][0]=0;(*t)[3][1]=0;(*t)[3][2]=0;(*t)[3][3]=1;
00116 }
00117 
00118 void PrintInteractions(const string &label,list<AtomPair> *interactions)
00119 {
00120   unsigned int i,ni;
00121   list<AtomPair>::iterator it;
00122 
00123   cout << "  " << label << "\n";
00124   interactions->sort();
00125   ni=interactions->size();
00126   cout << "    Number of interactions: " << ni << "\n    Interactions:";
00127   it=interactions->begin();
00128   if (ni<20)
00129     {
00130       for(i=0;i<ni;i++,++it)
00131         cout << (*it);
00132     }
00133   else
00134     {
00135       for(i=0;i<ni;i++,++it)
00136         {
00137           if (i<5)
00138             cout << (*it);
00139           else
00140             {
00141               if (i==5)
00142                 cout << "   .....  ";
00143               else
00144                 {
00145                   if (i>ni-6)
00146                     cout << (*it);
00147                 }
00148             }
00149         }
00150     }
00151   cout << "\n\n";
00152 }
00153 
00154 bool CmpInteractions(list<AtomPair> *interactions1,list<AtomPair> *interactions2)
00155 {
00156   unsigned int n1,n2,i;
00157   bool equal;
00158   list<AtomPair>::iterator it1,it2;
00159 
00160   interactions1->sort();
00161   interactions2->sort();
00162 
00163   n1=interactions1->size();
00164   n2=interactions2->size();
00165 
00166   equal=(n1==n2);
00167   it1=interactions1->begin();
00168   it2=interactions2->begin();
00169   for(i=0;((equal)&&(i<n1));i++,++it1,++it2)
00170     equal=((*it1)==(*it2));
00171 
00172   return(equal);
00173 }
00174 
00194 int main(int argc, char **arg)
00195 {
00196   if (argc>1)
00197     {      
00198       RigidCLL molecule(arg[1]); /* reads the rigid information from a file */
00199       unsigned int i,nr;
00200       double sx,sy,sz;
00201       RigidTransform *t;
00202       bool clashRCLL,clashCLL,clashBF;
00203       list<AtomPair> interactionsRCLL;
00204       list<AtomPair> interactionsCLL;
00205       list<AtomPair> interactionsBF;
00206       double cutoff;
00207       unsigned int ne,rep;
00208       double start,end;
00209       double time1,time2;
00210       double ts;
00211       unsigned int rs;
00212       
00213       ts=(double)sysconf(_SC_CLK_TCK); /*tics per second*/
00214       
00215       /* Init the random number generator */
00216       rs=(unsigned int)time(NULL);
00217       srand(rs);
00218 
00219       /* Set up RigidCLL for steric clash */
00220       molecule.SetCutOff(0.0);
00221 
00222       /* Get information about the size of the problem and the enviroment */
00223       nr=molecule.GetNumRigids();
00224   
00225       /* Initialize the transform. */
00226       t=new RigidTransform[nr];
00227       for(i=0;i<nr;i++)
00228         RandomTranslation(0,0,0,&(t[i])); 
00229       
00230       /* initialize the collision system. Wee need this to have the
00231          bounding box available */
00232       molecule.WarmUp(t);
00233 
00234       /* Get information about the bounding box to adjust
00235          the size of the random perturbations */
00236       sx=molecule.GetBBSize(0);
00237       sy=molecule.GetBBSize(1);
00238       sz=molecule.GetBBSize(2);
00239 
00240       /* First we detect steric clashes */
00241 
00242       /* Random motion of all rigids but the 'fixed'. */
00243       for(i=1;i<nr;i++)
00244         RandomTranslation(0.05*sx,0.05*sy,0.05*sz,&(t[i])); 
00245 
00246       /* Now determine if there is a collision */
00247       /* First using the RigidCLL algorihtm */
00248       cout << "************************************************\n";
00249       cout << "Steric clash test\n\n";
00250       cout << "  RigidCLL   : ";
00251       clashRCLL=molecule.StericClash(t);
00252       if (clashRCLL)
00253         cout << "  Steric clash detected between the rigids\n";
00254       else
00255         cout << "  No steric clash detected between the rigids\n";
00256 
00257      /* now using the CLL approach */
00258       cout << "  CLL        : ";
00259       clashCLL=molecule.CLLStericClash(t);
00260       if (clashCLL)
00261         cout << "  Steric clash detected between the rigids\n";
00262       else
00263         cout << "  No steric clash detected between the rigids\n";
00264 
00265       /* and now the brute force approach to verify the results */
00266       cout << "  Brute force: ";
00267       clashBF=molecule.BruteForceStericClash(t);
00268       if (clashBF)
00269         cout << "  Steric clash detected between the rigids\n\n";
00270       else
00271         cout << "  No steric clash detected between the rigids\n\n";
00272 
00273       /* Verify the output */
00274       if (clashRCLL!=clashBF)
00275         cout << "  ERROR: discrepancy between RigidCLL and Brute Force \n";
00276       if (clashCLL!=clashBF)
00277         cout << "  ERROR: discrepancy between CLL and Brute Force \n";
00278 
00279       /* Repeat the execution many times with different perturbations
00280          to get average execution time */
00281 
00282       cout << "  Computing average execution time: " ;
00283       cout.flush();
00284       time1=0.0;
00285       time2=0.0;
00286       for(ne=0;ne<N_EXPERIMENTS;ne++)
00287         {
00288           for(i=1;i<nr;i++)
00289             RandomTranslation(0.05*sx,0.05*sy,0.05*sz,&(t[i])); 
00290           
00291           /* ensure a clean grid and remove the time to generate
00292              the grid out of the query time */
00293           molecule.WarmUp(t);
00294 
00295           start=getTime();
00296           for(rep=0;rep<REPETITIONS;rep++)
00297             molecule.StericClash(t);
00298           end=getTime();
00299           time1+=(end-start);
00300 
00301           /* ensure a clean grid and remove the time to generate
00302              the grid out of the query time */
00303           molecule.WarmUp(t);
00304 
00305           start=getTime();
00306           for(rep=0;rep<REPETITIONS;rep++)
00307             molecule.CLLStericClash(t);
00308           end=getTime();
00309           time2+=(end-start);
00310 
00311           cout << ".";cout.flush();
00312         }
00313       cout << "\n";
00314 
00315       time1/=(double)(N_EXPERIMENTS*REPETITIONS);
00316       cout<<"    Execution time RigidCLL (ms): " << time1 << "\n";
00317 
00318       time2/=(double)(N_EXPERIMENTS*REPETITIONS);
00319       cout<<"    Execution time CLL      (ms): " << time2 << "\n";
00320 
00321       cout<<"  Time ratio RigidCLL/CLL       : " << time1/time2*100 << " %\n";
00322 
00323       /* Now detect interactions within a given cutoff */
00324 
00325       cout << "\n************************************************\n";
00326 
00327       /* Set up RigidCLL for interaction detection */
00328       /* get the user provide cutOff or use the default one */
00329       if (argc>2)
00330         cutoff=atof(arg[2]);
00331       else
00332         cutoff=2.0;
00333       /* avoid degenerate cutoff values */
00334       if (cutoff<=0)
00335         cutoff=2;
00336 
00337       /* Set the new cutoff. This will re-initialize the problem */
00338       molecule.SetCutOff(cutoff);
00339 
00340       cout << "Interaction test with cutoff=" << molecule.GetCutOff() << "\n\n";
00341       
00342       /* Set up a new random perturbation for the interaction test */
00343       for(i=1;i<nr;i++)
00344         RandomTranslation(0.05*sx,0.05*sy,0.05*sz,&(t[i]));
00345       
00346       /* remove the time to create the grid out of the query */
00347       molecule.WarmUp(t);
00348 
00349       /* First detect the interactions using the RigidCLL algorithm */
00350       molecule.Interactions(t,&interactionsRCLL);
00351       PrintInteractions("RigidCLL",&interactionsRCLL);
00352 
00353      /* now using the original CLL algorithm */
00354       molecule.CLLInteractions(t,&interactionsCLL);
00355       PrintInteractions("CLL (without considering rigid clusters at all)",&interactionsCLL);
00356 
00357       /* and finally the brute force approach to verify the results */
00358       molecule.BruteForceInteractions(t,&interactionsBF);
00359       PrintInteractions("Brute Force (taking into account the rigid clusters)",&interactionsBF);
00360 
00361       /* Verify the output assuming that Brute Force is correct */
00362       cout << "  Verifying the outputs:\n";
00363       if (CmpInteractions(&interactionsRCLL,&interactionsBF))
00364         cout << "    The output of RigidCLL is correct (equal to Brute Force)\n\n";
00365       else
00366         cout << "    ERROR: discrepancy between RigidCLL and Brute Force\n\n";
00367 
00368       interactionsRCLL.clear();
00369       interactionsCLL.clear();
00370       interactionsBF.clear();
00371 
00372       /* Repeat the execution many times with different perturbations
00373          to get average execution time */
00374       cout << "  Computing average execution time: " ;
00375       cout.flush();
00376 
00377       time1=0.0;
00378       time2=0.0;
00379       for(ne=0;ne<N_EXPERIMENTS;ne++)
00380         {
00381           for(i=1;i<nr;i++)
00382             RandomTranslation(0.05*sx,0.05*sy,0.05*sz,&(t[i]));
00383 
00384           /* ensure a clean grid and remove the time to generate
00385              the grid out of the query time */
00386           molecule.WarmUp(t);
00387         
00388           for(rep=0;rep<REPETITIONS;rep++)
00389             {
00390               start=getTime();
00391               molecule.Interactions(t,&interactionsRCLL);
00392               end=getTime();
00393               time1+=(end-start);
00394               interactionsRCLL.clear();
00395             }
00396 
00397           /* ensure a clean grid and remove the time to generate
00398              the grid out of the query time */
00399           molecule.WarmUp(t); 
00400 
00401           for(rep=0;rep<REPETITIONS;rep++)
00402             {
00403               start=getTime();
00404               molecule.CLLInteractions(t,&interactionsCLL); 
00405               end=getTime();
00406               time2+=(end-start);
00407               interactionsCLL.clear();
00408             }
00409           
00410           cout << ".";cout.flush();
00411         }
00412       cout << "\n";
00413 
00414       time1/=(double)(N_EXPERIMENTS*REPETITIONS);
00415       cout<<"    Execution time RigidCLL (ms): " << time1 << "\n";
00416 
00417       time2/=(double)(N_EXPERIMENTS*REPETITIONS);
00418       cout<<"    Execution time CLL      (ms): " << time2 << "\n";
00419 
00420       cout<<"    Time ratio                  : " << time1/time2*100 << " %\n";
00421 
00422       cout << "\n************************************************\n\n";
00423 
00424       /* Release the allocated memory */
00425       delete [] t;
00426 
00427       /* and exit */
00428       return(EXIT_SUCCESS);
00429     }
00430   else
00431     {
00432       cerr << "Wrong number of parameters\n";
00433       cerr << "Use\n";
00434       cerr << "    testRigidCLL filename [cutoff]\n";
00435       cerr << "where 'filename' is the file with the atom/rigid information\n";
00436       cerr << "      'cutoff' is the theshold to use when detecting interacting atoms\n";
00437       cerr << "               This parameter is optional. If not give, 2 is used.\n";
00438       return(EXIT_FAILURE);
00439     }
00440 }