00001 #include "RigidCLL.h"
00002
00013 #include <iostream>
00014 #include <fstream>
00015 #include <stdlib.h>
00016 #include <math.h>
00017 #include <limits>
00018
00039 #define BB_MARGIN 2
00040
00046 #define MAX_UINT std::numeric_limits<unsigned int>::max()
00047
00055 #define ERROR(s) {cerr<<s<<"\n";exit(0);}
00056
00062 #define INF std::numeric_limits<double>::max()
00063
00070 #define MANHATTAN_DISTANCE(dx,dy,dz,a1,a2) dx=a1->cp[0]-a2->cp[0];dy=a1->cp[1]-a2->cp[1];dz=a1->cp[2]-a2->cp[2]
00071
00072
00073
00074
00075
00076
00077
00078 AtomInfo::AtomInfo(unsigned int identifier,unsigned int rigid,double x,double y,double z,double radius)
00079 {
00080 if (radius<=0)
00081 ERROR("The atom radius must be positive.");
00082
00083 id=identifier;
00084 rID=rigid;
00085
00086
00087 cp[0]=op[0]=x;
00088 cp[1]=op[1]=y;
00089 cp[2]=op[2]=z;
00090
00091 r=radius;
00092
00093
00094 c[0]=c[1]=c[2]=0;
00095 }
00096
00097 void AtomInfo::move(RigidTransform t)
00098 {
00099 cp[0]=t[0][0]*op[0]+t[0][1]*op[1]+t[0][2]*op[2]+t[0][3];
00100 cp[1]=t[1][0]*op[0]+t[1][1]*op[1]+t[1][2]*op[2]+t[1][3];
00101 cp[2]=t[2][0]*op[0]+t[2][1]*op[1]+t[2][2]*op[2]+t[2][3];
00102 }
00103
00104 double AtomInfo::distance(AtomInfo *a)
00105 {
00106 double dx,dy,dz;
00107
00108 MANHATTAN_DISTANCE(dx,dy,dz,this,a);
00109
00110 return(sqrt(dx*dx+dy*dy+dz*dz));
00111 }
00112
00113 ostream& operator<<(ostream& os,const AtomInfo &a)
00114 {
00115 os << "id:" << a.id ;
00116 os << " r:" << a.rID ;
00117 os << " op:(" << a.op[0] << "," << a.op[1] << "," << a.op[2] << ")";
00118 os << " cp:(" << a.cp[0] << "," << a.cp[1] << "," << a.cp[2] << ")";
00119
00120 return(os);
00121 }
00122
00123
00124
00125
00126
00127
00128
00129 AtomPair::AtomPair(AtomInfo *atom1,AtomInfo *atom2,double dst2)
00130 {
00131 a1=atom1->id;
00132 r1=atom1->rID;
00133 a2=atom2->id;
00134 r2=atom2->rID;
00135 d2=dst2;
00136 }
00137
00138 bool AtomPair::operator<(const AtomPair a) const
00139 {
00140 unsigned int min1,min2,max1,max2;
00141
00142 min1=(this->a1<this->a2?this->a1:this->a2);
00143 max1=(this->a1<this->a2?this->a2:this->a1);
00144
00145 min2=(a.a1<a.a2?a.a1:a.a2);
00146 max2=(a.a1<a.a2?a.a2:a.a1);
00147
00148 return((min1<min2)||((min1==min2)&&(max1<max2)));
00149 }
00150
00151 ostream& operator<<(ostream& os,const AtomPair &a)
00152 {
00153 if (a.a1<a.a2)
00154 os << " (" << a.a1 << "[" << a.r1 << "]," << a.a2 << "[" << a.r2 << "])";
00155 else
00156 os << " (" << a.a2 << "[" << a.r2 << "]," << a.a1 << "[" << a.r1 << "])";
00157
00158 os << " d: " << sqrt(a.d2);
00159 return(os);
00160 }
00161
00162 bool AtomPair::operator==(AtomPair &a)
00163 {
00164
00165 return(((this->a1==a.a1)&&(this->a2==a.a2))||
00166 ((this->a1==a.a2)&&(this->a2==a.a1)));
00167 }
00168
00169
00170
00171
00172
00173
00174
00175 CellInfo::CellInfo()
00176 {
00177 mobileID=MAX_UINT;
00178 fixedID=MAX_UINT;
00179 }
00180
00181 void CellInfo::Reset()
00182 {
00183 mobileID=MAX_UINT;
00184 }
00185
00186 void CellInfo::AddFixedAtom(unsigned int id,unsigned int *fixedLL)
00187 {
00188 fixedLL[id]=fixedID;
00189 fixedID=id;
00190 }
00191
00192 void CellInfo::AddMobileAtom(unsigned int id,unsigned int *mobileLL)
00193 {
00194 mobileLL[id]=mobileID;
00195 mobileID=id;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204 void RigidCLL::InitRigidCLL()
00205 {
00206 o[0]=o[1]=o[2]=0.0;
00207 s[0]=s[1]=s[2]=0;
00208 grid=NULL;
00209 fixedLL=NULL;
00210 mobileLL=NULL;
00211 cutoff=0.0;
00212 d=0.0;
00213 cr.firstAtom=cr.lastAtom=MAX_UINT;
00214 nFixed=0;
00215 nMobile=0;
00216 rID=0;
00217 lastInGrid=MAX_UINT;
00218 checkInteraction=NULL;
00219 }
00220
00221 void RigidCLL::UpdateCell(AtomInfo *a)
00222 {
00223 unsigned int i;
00224
00225 for(i=0;i<3;i++)
00226 {
00227 a->c[i]=(unsigned int)floor((a->cp[i]-o[i])/d);
00228 #if (RIGIDCLL_DEBUG)
00229
00230
00231 if ((a->c[i]<=0)||(a->c[i]>=s[i]-1))
00232 ERROR("Cell out of range in UpdateCell");
00233 #endif
00234 }
00235 }
00236
00237 void RigidCLL::InsertFixedInGrid(unsigned int n)
00238 {
00239 AtomInfo *a;
00240
00241 #if (RIGIDCLL_DEBUG)
00242 if (grid==NULL)
00243 ERROR("Inserting atom in an empty grid. Use the WarmUp method.");
00244 #endif
00245
00246 a=&(fixedAtoms[n]);
00247
00248
00249 UpdateCell(a);
00250
00251 grid[a->c[0]][a->c[1]][a->c[2]].AddFixedAtom(n,fixedLL);
00252
00253
00254
00255 }
00256
00257 void RigidCLL::InsertMobileInGrid(unsigned int n)
00258 {
00259 AtomInfo *a;
00260
00261 #if (RIGIDCLL_DEBUG)
00262 if (grid==NULL)
00263 ERROR("Inserting atom in an empty grid. Use the WarmUp method.");
00264 #endif
00265
00266
00267
00268 a=&(mobileAtoms[n]);
00269
00270 grid[a->c[0]][a->c[1]][a->c[2]].AddMobileAtom(n,mobileLL);
00271
00272
00273
00274
00275 lastInGrid=n;
00276 }
00277
00278 void RigidCLL::DeleteGrid()
00279 {
00280 if (grid!=NULL)
00281 {
00282
00283
00284
00285
00286
00287 unsigned int i,j;
00288
00289 for(i=0;i<s[0];i++)
00290 {
00291 for(j=0;j<s[1];j++)
00292 {
00293 delete[] grid[i][j];
00294 }
00295 delete[] grid[i];
00296 }
00297 delete[] grid;
00298
00299 delete[] fixedLL;
00300 delete[] mobileLL;
00301
00302 grid=NULL;
00303 fixedLL=NULL;
00304 mobileLL=NULL;
00305 }
00306 }
00307
00308 void RigidCLL::DeleteInteractions()
00309 {
00310 if (checkInteraction!=NULL)
00311 {
00312 unsigned int i,nr;
00313
00314 nr=rID+1;
00315 for(i=0;i<nr;i++)
00316 {
00317 delete [] checkInteraction[i];
00318 }
00319 delete [] checkInteraction;
00320
00321 checkInteraction=NULL;
00322 }
00323 }
00324
00325 void RigidCLL::InitInteractions()
00326 {
00327 unsigned int i,j,nr;
00328
00329
00330 if (cr.firstAtom!=MAX_UINT)
00331 EndRigid();
00332
00333
00334 nr=rID+1;
00335 checkInteraction=new bool*[nr];
00336 for(i=0;i<nr;i++)
00337 {
00338 checkInteraction[i]=new bool[nr];
00339 for(j=0;j<nr;j++)
00340 checkInteraction[i][j]=(i!=j);
00341 }
00342 }
00343
00344
00345 void RigidCLL::ResetQuery()
00346 {
00347 unsigned int j;
00348 AtomInfo *a1;
00349
00350 if (lastInGrid!=MAX_UINT)
00351 {
00352 for(j=0;j<=lastInGrid;j++)
00353 {
00354 a1=&(mobileAtoms[j]);
00355 grid[a1->c[0]][a1->c[1]][a1->c[2]].Reset();
00356 }
00357 lastInGrid=MAX_UINT;
00358 }
00359 }
00360
00361 void RigidCLL::Move(RigidTransform *t)
00362 {
00363 unsigned int j;
00364 AtomInfo *a1;
00365
00366
00367 for(j=0;j<nMobile;j++)
00368 {
00369 a1=&(mobileAtoms[j]);
00370 a1->move(t[a1->rID]);
00371 }
00372 }
00373
00374 bool RigidCLL::Check27(AtomInfo *a1)
00375 {
00376 AtomInfo *a2;
00377 unsigned int ix,iy,iz,aID;
00378 double dx,dy,dz,r;
00379 bool collision=false;
00380
00381
00382 ix=a1->c[0]-1;
00383 while((!collision)&&(ix<=a1->c[0]+1))
00384 {
00385 iy=a1->c[1]-1;
00386 while((!collision)&&(iy<=a1->c[1]+1))
00387 {
00388 iz=a1->c[2]-1;
00389 while((!collision)&&(iz<=a1->c[2]+1))
00390 {
00391
00392
00393 if (checkInteraction[a1->rID][0])
00394 {
00395
00396 aID=grid[ix][iy][iz].fixedID;
00397 while((!collision)&&(aID!=MAX_UINT))
00398 {
00399 a2=&(fixedAtoms[aID]);
00400
00401 MANHATTAN_DISTANCE(dx,dy,dz,a1,a2);
00402 r=a1->r+a2->r;
00403
00404 collision=(dx*dx+dy*dy+dz*dz<=r*r);
00405
00406 aID=fixedLL[aID];
00407 }
00408 }
00409
00410 aID=grid[ix][iy][iz].mobileID;
00411 while((!collision)&&(aID!=MAX_UINT))
00412 {
00413 a2=&(mobileAtoms[aID]);
00414
00415 if (checkInteraction[a1->rID][a2->rID])
00416 {
00417 MANHATTAN_DISTANCE(dx,dy,dz,a1,a2);
00418 r=a1->r+a2->r;
00419
00420 collision=(dx*dx+dy*dy+dz*dz<=r*r);
00421 }
00422 aID=mobileLL[aID];
00423 }
00424 iz++;
00425 }
00426 iy++;
00427 }
00428 ix++;
00429 }
00430
00431 return(collision);
00432 }
00433
00434
00435
00436
00437
00438
00439
00440 RigidCLL::RigidCLL():fixedAtoms(),mobileAtoms(),rigids()
00441 {
00442 InitRigidCLL();
00443 }
00444
00445 RigidCLL::RigidCLL(char *name):fixedAtoms(),mobileAtoms(),rigids()
00446 {
00447 ifstream file;
00448 unsigned int nr,na,i,j,k;
00449 double x,y,z,r;
00450 bool f;
00451
00452
00453 InitRigidCLL();
00454
00455
00456 file.open(name);
00457
00458 file>>nr;
00459
00460 k=0;
00461 for(i=0;i<nr;i++)
00462 {
00463 file >> na;
00464 file >> f;
00465
00466 if (!f)
00467 NewRigid();
00468
00469 for(j=0;j<na;j++)
00470 {
00471 file >> x;
00472 file >> y;
00473 file >> z;
00474 file >> r;
00475
00476 if (f)
00477 AddFixedAtom(k,x,y,z,r);
00478 else
00479 AddAtom(k,x,y,z,r);
00480 k++;
00481 }
00482
00483 if (!f)
00484 EndRigid();
00485 }
00486
00487 file.close();
00488
00489
00490 InitInteractions();
00491 }
00492
00493 unsigned int RigidCLL::GetNumRigids()
00494 {
00495
00496 return(rID+1);
00497 }
00498
00499 void RigidCLL::SetCutOff(double c)
00500 {
00501 if (c<0.0)
00502 ERROR("The cutoff must be possitive");
00503
00504 cutoff=c;
00505
00506
00507
00508 DeleteGrid();
00509 }
00510
00511 double RigidCLL::GetCutOff()
00512 {
00513 return(cutoff);
00514 }
00515
00516 double RigidCLL::GetBBSize(unsigned int axis)
00517 {
00518 if ((axis<0)||(axis>2))
00519 ERROR("Axis out of range in GetBBSize");
00520
00521 if ((grid==NULL)||(s[axis]==0))
00522 ERROR("Calling GetBBSize on non-initialized RigidCLL object (call the WarmUp method first)");
00523
00524 return(s[axis]*d);
00525 }
00526
00527 RigidCLL::~RigidCLL()
00528 {
00529 Reset();
00530 }
00531
00532 void RigidCLL::AddFixedAtom(unsigned int id,double x,double y,double z,double r)
00533 {
00534 if (checkInteraction!=NULL)
00535 ERROR("Adding atoms to a closed model. Use the Reset method first.");
00536
00537 fixedAtoms.push_back(AtomInfo(id,0,x,y,z,r));
00538 nFixed++;
00539 }
00540
00541 void RigidCLL::AddFixedAtom(unsigned int id,double *p,double r)
00542 {
00543 AddFixedAtom(id,p[0],p[1],p[2],r);
00544 }
00545
00546 unsigned int RigidCLL::NewRigid()
00547 {
00548 if (checkInteraction!=NULL)
00549 ERROR("Adding atoms to a closed model. Use the Reset method first.");
00550
00551
00552 if (cr.firstAtom!=MAX_UINT)
00553 EndRigid();
00554
00555
00556 cr.firstAtom=nMobile;
00557 rID++;
00558
00559 return(rID);
00560 }
00561
00562 void RigidCLL::AddAtom(unsigned int id,double x,double y,double z,double r)
00563 {
00564 if (cr.firstAtom==MAX_UINT)
00565 ERROR("Adding an atom out of a rigid group. Use NewRigid first.");
00566
00567 mobileAtoms.push_back(AtomInfo(id,rID,x,y,z,r));
00568 nMobile++;
00569 }
00570
00571 void RigidCLL::AddAtom(unsigned int id,double *p,double r)
00572 {
00573 AddAtom(id,p[0],p[1],p[2],r);
00574 }
00575
00576 void RigidCLL::EndRigid()
00577 {
00578
00579 if (cr.firstAtom!=MAX_UINT)
00580 {
00581 if (checkInteraction!=NULL)
00582 ERROR("Modifying a closed model. Use the Reset method first.");
00583
00584 cr.lastAtom=nMobile;
00585 rigids.push_back(cr);
00586 cr.firstAtom=cr.lastAtom=MAX_UINT;
00587 }
00588 }
00589
00590 void RigidCLL::ActivateInteraction(unsigned int r1,unsigned int r2)
00591 {
00592 if (checkInteraction==NULL)
00593 InitInteractions();
00594
00595
00596 if ((r1>rID)||(r2>rID))
00597 ERROR("Rigid cluster identifier out of range in ActivateInteraction");
00598
00599 if (r1==r2)
00600 ERROR("Can not activate the self-interaction of a rigid group.");
00601
00602 checkInteraction[r1][r2]=checkInteraction[r2][r1]=true;
00603 }
00604
00605 void RigidCLL::DeactivateInteraction(unsigned int r1,unsigned int r2)
00606 {
00607 if (checkInteraction==NULL)
00608 InitInteractions();
00609
00610 if ((r1>rID)||(r2>rID))
00611 ERROR("Rigid cluster identifier out of range in DeactivateInteraction");
00612
00613 checkInteraction[r1][r2]=checkInteraction[r2][r1]=false;
00614 }
00615
00616 void RigidCLL::WarmUp(RigidTransform *t)
00617 {
00618 unsigned int i,j;
00619 double minC[3],maxC[3],maxR,range;
00620 vector<AtomInfo>::iterator it;
00621
00622 if (t==NULL)
00623 ERROR("The Warmup methods need a valid conformation");
00624
00625
00626 if (checkInteraction==NULL)
00627 InitInteractions();
00628
00629
00630 DeleteGrid();
00631
00632
00633 minC[0]=minC[1]=minC[2]=INF;
00634 maxC[0]=maxC[1]=maxC[2]=-INF;
00635 maxR=0;
00636
00637
00638 for(it=fixedAtoms.begin();it!=fixedAtoms.end();++it)
00639 {
00640 for(j=0;j<3;j++)
00641 {
00642 if (it->cp[j]>maxC[j]) maxC[j]=it->cp[j];
00643 else { if (it->cp[j]<minC[j]) minC[j]=it->cp[j]; }
00644 }
00645
00646 if (it->r>maxR) maxR=it->r;
00647 }
00648
00649
00650
00651 for(it=mobileAtoms.begin();it!=mobileAtoms.end();++it)
00652 {
00653
00654 it->move(t[it->rID]);
00655 for(j=0;j<3;j++)
00656 {
00657 if (it->cp[j]>maxC[j]) maxC[j]=it->cp[j];
00658 else { if (it->cp[j]<minC[j]) minC[j]=it->cp[j]; }
00659 }
00660 if (it->r>maxR) maxR=it->r;
00661 }
00662
00663
00664 if (cutoff==0)
00665 d=2.0*maxR;
00666 else
00667 d=cutoff;
00668 d2=d*d;
00669
00670
00671
00672
00673
00674
00675
00676 for(j=0;j<3;++j)
00677 {
00678 range=maxC[j]-minC[j];
00679 o[j]=minC[j]-(BB_MARGIN)*range;
00680 s[j]=(unsigned int)ceil((1+2*BB_MARGIN)*range/d);
00681 }
00682
00683
00684 grid=new CellInfo **[s[0]];
00685 for(i=0;i<s[0];i++)
00686 {
00687 grid[i]=new CellInfo *[s[1]];
00688 for(j=0;j<s[1];j++)
00689 {
00690 grid[i][j]=new CellInfo [s[2]];
00691 }
00692 }
00693 fixedLL=new unsigned int[nFixed];
00694 mobileLL=new unsigned int[nMobile];
00695
00696
00697 for(i=0;i<nFixed;i++)
00698 InsertFixedInGrid(i);
00699
00700
00701 lastInGrid=MAX_UINT;
00702 }
00703
00704 void RigidCLL::Reset()
00705 {
00706 DeleteGrid();
00707 DeleteInteractions();
00708 }
00709
00710 bool RigidCLL::StericClash(RigidTransform *t)
00711 {
00712 unsigned int i,j;
00713 AtomInfo *a;
00714 bool collision=false;
00715
00716
00717
00718
00719 if ((rID>1)||((rID==1)&&(nFixed>0)))
00720 {
00721 #if (RIGIDCLL_DEBUG)
00722 if (cutoff>0)
00723 ERROR("Using StericClash in a RigidCLL initialized to detect nearby-interactions");
00724 #endif
00725
00726
00727 if (grid==NULL)
00728 WarmUp(t);
00729 else
00730 ResetQuery();
00731
00732
00733 for(i=0;((!collision)&&(i<rID));i++)
00734 {
00735 for(j=rigids[i].firstAtom;((!collision)&&(j<rigids[i].lastAtom));j++)
00736 {
00737 a=&(mobileAtoms[j]);
00738
00739
00740 a->move(t[a->rID]);
00741
00742
00743
00744 UpdateCell(a);
00745
00746
00747
00748 if ((nFixed>0)||(i>0))
00749 collision=Check27(a);
00750 }
00751
00752
00753 if ((!collision)&&(i<rID-1))
00754 {
00755 for(j=rigids[i].firstAtom;j<rigids[i].lastAtom;j++)
00756 InsertMobileInGrid(j);
00757 }
00758 }
00759 }
00760 return(collision);
00761 }
00762
00763 bool RigidCLL::CLLStericClash(RigidTransform *t)
00764 {
00765 unsigned int i;
00766 bool collision=false;
00767
00768 if ((rID>1)||((rID==1)&&(nFixed>0)))
00769 {
00770 #if (RIGIDCLL_DEBUG)
00771 if (cutoff>0)
00772 ERROR("Using CLLStericClash in a RigidCLL initialized to detect nearby-interactions");
00773 #endif
00774
00775
00776 if (grid==NULL)
00777 WarmUp(t);
00778 else
00779 {
00780 ResetQuery();
00781 Move(t);
00782 }
00783
00784
00785
00786
00787 for(i=0;i<nMobile;i++)
00788 {
00789 UpdateCell(&(mobileAtoms[i]));
00790 InsertMobileInGrid(i);
00791 }
00792
00793
00794 for(i=0;((!collision)&&(i<nMobile));i++)
00795 collision=Check27(&(mobileAtoms[i]));
00796 }
00797
00798 return(collision);
00799 }
00800
00801 bool RigidCLL::BruteForceStericClash(RigidTransform *t)
00802 {
00803 unsigned int i,j;
00804 AtomInfo *a1,*a2;
00805 double dx,dy,dz,r;
00806 bool collision=false;
00807
00808 #if (RIGIDCLL_DEBUG)
00809 if (cutoff>0)
00810 ERROR("Using BruteForceStericClash in a RigidCLL initialized to detect nearby-interactions");
00811 #endif
00812
00813 if ((rID>1)||((rID==1)&&(nFixed>0)))
00814 {
00815
00816 if (checkInteraction==NULL)
00817 InitInteractions();
00818
00819
00820 Move(t);
00821
00822 for(i=0;((!collision)&&(i<nMobile));i++)
00823 {
00824 a1=&(mobileAtoms[i]);
00825
00826 if (checkInteraction[a1->rID][0])
00827 {
00828 for(j=0;((!collision)&&(j<nFixed));j++)
00829 {
00830 a2=&(fixedAtoms[j]);
00831
00832 MANHATTAN_DISTANCE(dx,dy,dz,a1,a2);
00833 r=a1->r+a2->r;
00834
00835 collision=(dx*dx+dy*dy+dz*dz<=r*r);
00836 }
00837 }
00838
00839 for(j=i+1;((!collision)&&(j<nMobile));j++)
00840 {
00841 a2=&(mobileAtoms[j]);
00842
00843 if (checkInteraction[a1->rID][a2->rID])
00844 {
00845 MANHATTAN_DISTANCE(dx,dy,dz,a1,a2);
00846 r=a1->r+a2->r;
00847
00848 collision=(dx*dx+dy*dy+dz*dz<=r*r);
00849 }
00850 }
00851 }
00852 }
00853
00854 return(collision);
00855 }
00856
00857 void RigidCLL::Interactions(RigidTransform *t,list<AtomPair> *c)
00858 {
00859 unsigned int i,j,aID,ix,iy,iz;
00860 double dx,dy,dz,d;
00861 AtomInfo *a1,*a2;
00862 RigidInfo *rigid;
00863
00864
00865
00866 if ((rID>1)||((rID==1)&&(nFixed>0)))
00867 {
00868 #if (RIGIDCLL_DEBUG)
00869 if (cutoff==0)
00870 ERROR("Using Interactions in a RigidCLL initialized to detect steric clashes");
00871 #endif
00872
00873
00874 if (grid==NULL)
00875 WarmUp(t);
00876 else
00877 {
00878 ResetQuery();
00879 Move(t);
00880 }
00881
00882
00883 for(i=0;i<rID;i++)
00884 {
00885 rigid=&(rigids[i]);
00886
00887 for(j=rigid->firstAtom;j<rigid->lastAtom;j++)
00888 {
00889 a1=&(mobileAtoms[j]);
00890
00891
00892
00893 UpdateCell(a1);
00894
00895
00896
00897 if ((nFixed>0)||(i>0))
00898 {
00899
00900 for(ix=a1->c[0]-1;ix<=a1->c[0]+1;ix++)
00901 {
00902 for(iy=a1->c[1]-1;iy<=a1->c[1]+1;iy++)
00903 {
00904 for(iz=a1->c[2]-1;iz<=a1->c[2]+1;iz++)
00905 {
00906 if (checkInteraction[a1->rID][0])
00907 {
00908
00909
00910 aID=grid[ix][iy][iz].fixedID;
00911 while(aID!=MAX_UINT)
00912 {
00913 a2=&(fixedAtoms[aID]);
00914
00915 MANHATTAN_DISTANCE(dx,dy,dz,a1,a2);
00916 d=dx*dx+dy*dy+dz*dz;
00917
00918 if (d<=d2)
00919 c->push_back(AtomPair(a1,a2,d));
00920
00921 aID=fixedLL[aID];
00922 }
00923 }
00924
00925
00926 aID=grid[ix][iy][iz].mobileID;
00927 while(aID!=MAX_UINT)
00928 {
00929 a2=&(mobileAtoms[aID]);
00930
00931 if (checkInteraction[a1->rID][a2->rID])
00932 {
00933 MANHATTAN_DISTANCE(dx,dy,dz,a1,a2);
00934 d=dx*dx+dy*dy+dz*dz;
00935
00936 if (d<=d2)
00937 c->push_back(AtomPair(a1,a2,d));
00938 }
00939 aID=mobileLL[aID];
00940 }
00941 }
00942 }
00943 }
00944 }
00945 }
00946
00947
00948 if (i<rID-1)
00949 {
00950
00951 for(j=rigid->firstAtom;j<rigid->lastAtom;j++)
00952 InsertMobileInGrid(j);
00953 }
00954 }
00955 }
00956 }
00957
00958 void RigidCLL::CLLInteractions(RigidTransform *t,list<AtomPair> *c)
00959 {
00960 unsigned int i,aID,ix,iy,iz;
00961 double dx,dy,dz,d;
00962 AtomInfo *a1,*a2;
00963
00964
00965 if ((nMobile>1)||((nMobile==1)&&(nFixed>0)))
00966 {
00967 #if (RIGIDCLL_DEBUG)
00968 if (cutoff==0)
00969 ERROR("Using CLLInteractions in a RigidCLL initialized to detect steric clashes");
00970 #endif
00971
00972
00973 if (grid==NULL)
00974 WarmUp(t);
00975 else
00976 {
00977 ResetQuery();
00978 Move(t);
00979 }
00980
00981
00982 for(i=0;i<nMobile;i++)
00983 {
00984 UpdateCell(&(mobileAtoms[i]));
00985 InsertMobileInGrid(i);
00986 }
00987
00988
00989 for(i=0;i<nMobile;i++)
00990 {
00991 a1=&(mobileAtoms[i]);
00992
00993
00994
00995
00996
00997 for(ix=a1->c[0]-1;ix<=a1->c[0]+1;ix++)
00998 {
00999 for(iy=a1->c[1]-1;iy<=a1->c[1]+1;iy++)
01000 {
01001 for(iz=a1->c[2]-1;iz<=a1->c[2]+1;iz++)
01002 {
01003
01004
01005 aID=grid[ix][iy][iz].fixedID;
01006 while(aID!=MAX_UINT)
01007 {
01008 a2=&(fixedAtoms[aID]);
01009
01010 MANHATTAN_DISTANCE(dx,dy,dz,a1,a2);
01011 d=dx*dx+dy*dy+dz*dz;
01012
01013 if (d<=d2)
01014 c->push_back(AtomPair(a1,a2,d));
01015
01016 aID=fixedLL[aID];
01017 }
01018
01019
01020 aID=grid[ix][iy][iz].mobileID;
01021 while(aID!=MAX_UINT)
01022 {
01023 a2=&(mobileAtoms[aID]);
01024
01025 if (a1->id<a2->id)
01026 {
01027 MANHATTAN_DISTANCE(dx,dy,dz,a1,a2);
01028 d=dx*dx+dy*dy+dz*dz;
01029
01030 if (d<=d2)
01031 c->push_back(AtomPair(a1,a2,d));
01032 }
01033 aID=mobileLL[aID];
01034 }
01035 }
01036 }
01037 }
01038 }
01039 }
01040 }
01041
01042
01043 void RigidCLL::BruteForceInteractions(RigidTransform *t,list<AtomPair> *c)
01044 {
01045 unsigned int i,j;
01046 AtomInfo *a1,*a2;
01047 double dx,dy,dz,d;
01048
01049 #if (RIGIDCLL_DEBUG)
01050 if (cutoff==0)
01051 ERROR("Using BruteForceInteractions in a RigidCLL initialized to detect steric clashes");
01052 #endif
01053
01054 if ((rID>1)||((rID==1)&&(nFixed>0)))
01055 {
01056
01057 if (checkInteraction==NULL)
01058 InitInteractions();
01059
01060
01061 Move(t);
01062
01063
01064 for(i=0;i<nMobile;i++)
01065 {
01066 a1=&(mobileAtoms[i]);
01067
01068 if (checkInteraction[a1->rID][0])
01069 {
01070 for(j=0;j<nFixed;j++)
01071 {
01072 a2=&(fixedAtoms[j]);
01073
01074 MANHATTAN_DISTANCE(dx,dy,dz,a1,a2);
01075 d=dx*dx+dy*dy+dz*dz;
01076
01077 if (d<=d2)
01078 c->push_back(AtomPair(a1,a2,d));
01079 }
01080 }
01081
01082 for(j=i+1;j<nMobile;j++)
01083 {
01084 a2=&(mobileAtoms[j]);
01085
01086 if (checkInteraction[a1->rID][a2->rID])
01087 {
01088 MANHATTAN_DISTANCE(dx,dy,dz,a1,a2);
01089 d=dx*dx+dy*dy+dz*dz;
01090
01091 if (d<=d2)
01092 c->push_back(AtomPair(a1,a2,d));
01093 }
01094 }
01095 }
01096 }
01097 }
Follow us!