Molmodel
|
00001 /* -------------------------------------------------------------------------- * 00002 * SimTK Core: SimTK Molmodel * 00003 * -------------------------------------------------------------------------- * 00004 * This is part of the SimTK Core biosimulation toolkit originating from * 00005 * Simbios, the NIH National Center for Physics-Based Simulation of * 00006 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00007 * Medical Research, grant U54 GM072970. See https://simtk.org. * 00008 * * 00009 * Portions copyright (c) 2008 Stanford University and the Authors. * 00010 * Authors: Samuel Flores * 00011 * Contributors: Christopher Bruns, Peter Eastman * 00012 * * 00013 * Permission is hereby granted, free of charge, to any person obtaining a * 00014 * copy of this software and associated documentation files (the "Software"), * 00015 * to deal in the Software without restriction, including without limitation * 00016 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00017 * and/or sell copies of the Software, and to permit persons to whom the * 00018 * Software is furnished to do so, subject to the following conditions: * 00019 * * 00020 * The above copyright notice and this permission notice shall be included in * 00021 * all copies or substantial portions of the Software. * 00022 * * 00023 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00024 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00025 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00026 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00027 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00028 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00029 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00030 * -------------------------------------------------------------------------- */ 00031 00032 /* This program generates a water droplet based on user-supplied parameters * 00033 * of droplet center, radius, and 'arista' or rectangular grid spacing * 00034 * between water molecules. All of these have default values and can be left * 00035 * out. The program detects steric clashes and removes any waters that are * 00036 * within arista/2 of a solute atom. For this to work you should have adopted * 00037 * all other Compounds before instantiating. * 00038 */ 00039 00040 #include "molmodel/internal/common.h" 00041 #include "molmodel/internal/Compound.h" 00042 #include <iostream> 00043 #include <fstream> 00044 //#include "/Users/samuelflores/rna-dynamics/Water.h" 00045 //#include <ios> 00046 00047 namespace SimTK 00048 { 00049 00050 class WaterDroplet : public Compound { public: 00051 WaterDroplet(CompoundSystem &system 00052 , DuMMForceFieldSubsystem &dumm 00053 , GeneralForceSubsystem& forces 00054 , Vec3 dropletCenter = Vec3(-1.3,2.0,.3) 00055 , float dropletRadius = 2.00 //in nm, of course 00056 , float arista = 0.310433899 00057 ) 00058 { 00059 Vec3 atomLocation; 00060 AtomPathName myAtomName; 00061 //float dropletRadius = 2.00; //nanometers 00062 float shellRadius =10.0; //nanometers 00063 //float arista = 0.310433899; // from nominal density of water // width of water unit cell 00064 int cellsAcross = dropletRadius*2/arista+1; // number of cells across. add 1 b.c. water molecules are at corners of cells. 00065 std::cout<<"cellsAcross = "<<cellsAcross<<std::endl; 00066 //Vec3 dropletCenter(0); 00067 //Vec3 dropletCenter(2,2,2); 00068 //Vec3 dropletCenter(-1.3,2.0,.3); 00069 int totalAtoms =0; 00070 //Water * myWaterVec[cellsAcross][cellsAcross][cellsAcross]; 00071 int myWaterVecOccupation[cellsAcross][cellsAcross][cellsAcross]; 00072 int numWater =0;//lsAcross*cellsAcross*cellsAcross; 00073 00074 VanderWallSphere myVanderWallSphere( forces, dumm,dropletCenter,shellRadius, .1 , 1.0 ); 00075 00076 float myRadius=0.; 00077 for (int xi = 0; xi < cellsAcross; xi++) 00078 for (int yi = 0; yi < cellsAcross; yi++) 00079 for (int zi = 0; zi < cellsAcross; zi++) 00080 { 00081 //myWaterVec[xi][yi][zi] = new Water(dumm); 00082 cout<<"for indices "<<xi<<","<<yi<<","<<zi<<endl; 00083 00084 cout<<" checking condition: "<<dropletCenter[0]<<","<<xi<<" , = "<<pow((dropletCenter[0]-(xi*arista-dropletRadius)),2)<<endl; 00085 myRadius = pow((pow((xi*arista-dropletRadius),float(2))+ pow((yi*arista-dropletRadius),float(2))+ pow((zi*arista-dropletRadius),float(2))),float(.5) ); 00086 cout<<"radius = "<<myRadius<<endl; 00087 if (myRadius <= dropletRadius) //(pow((pow((dropletCenter[0]-(xi*arista+dropletRadius)),2)+ pow((dropletCenter[1]-(yi*arista+dropletRadius)),2)+ pow((dropletCenter[2]-(zi*arista+dropletRadius)),2)),.5 ) <= dropletRadius) 00088 { 00089 00090 numWater++;myWaterVecOccupation[xi][yi][zi] = 1; 00091 } 00092 else 00093 {cout<<"outside of water droplet radius; no water to be placed here."<<endl; myWaterVecOccupation[xi][yi][zi] = 0;} 00094 } 00095 //Count the atoms in the CompoundSystem 00096 00097 for (int i =0 ; i< system.getNumCompounds(); i++) 00098 { 00099 cout<<"counting atoms in compound # "<<i<<endl; 00100 totalAtoms += system.updCompound(Compound::Index(i)).getNumAtoms(); 00101 } 00102 //for (int j = 0; j< system.updCompound(Compound::Index(i)).getNumAtoms(); j++) 00103 // totalAtoms++; 00104 cout<<"counted "<<totalAtoms<<" total atoms."<<endl; 00105 //Create an array to hold their locations 00106 Vec3 atomLocationArray[totalAtoms]; 00107 int myAtomIndex = 0; 00108 //iState state = system.realizeTopology(); 00109 for (int i =0 ; i< system.getNumCompounds(); i++) 00110 { 00111 for (int j = 0; j< system.updCompound(Compound::Index(i)).getNumAtoms(); j++) 00112 { 00113 Compound & myCompound = system.updCompound(Compound::Index(i)); 00114 myAtomName = myCompound.getAtomName(Compound::AtomIndex(j)); 00115 atomLocationArray[myAtomIndex] = myCompound.calcDefaultAtomLocationInGroundFrame(myAtomName); 00116 //atomLocationArray[myAtomIndex] = myCompound.getDefaultAtomLocation(myAtomName); 00117 //atomLocationArray[myAtomIndex] = myCompound.getTopLevelTransform() * atomLocationArray[myAtomIndex] ; 00118 //atomLocationArray[myAtomIndex] = system.updCompound(Compound::Index(i)).calcAtomLocationInGroundFrame(state,Compound::AtomIndex(j)); 00119 cout << "myAtomName= "<<myAtomName<<" atomLocation= "<<atomLocationArray[myAtomIndex]<<endl; 00120 int myxi = (atomLocationArray[myAtomIndex][0]-dropletCenter[0]+dropletRadius)/arista+.5; 00121 int myyi = (atomLocationArray[myAtomIndex][1]-dropletCenter[1]+dropletRadius)/arista+.5; 00122 int myzi = (atomLocationArray[myAtomIndex][2]-dropletCenter[2]+dropletRadius)/arista+.5; 00123 cout<<" indices = "<<myxi<<","<<myyi<<","<<myzi<<endl; 00124 if (((myxi < cellsAcross) && (myxi >=0)) 00125 && ((myyi < cellsAcross) && (myyi >=0)) 00126 && ((myzi < cellsAcross) && (myzi >=0)) 00127 && (myWaterVecOccupation[myxi][myyi][myzi] == 1)) 00128 { 00129 numWater--; 00130 cout<<"setting an occupation to 0"<<endl; 00131 myWaterVecOccupation[myxi][myyi][myzi] = 0; 00132 } 00133 myAtomIndex++; 00134 } 00135 } 00136 00137 cout<<"about to create array of "<<numWater<<" water molecules."<<endl; 00138 Water * myWaterVec[numWater]; 00139 for (int k =0;k<numWater;k++) { 00140 myWaterVec[k]=new Water(dumm); 00141 (*myWaterVec[k]).setPdbResidueName("H2O"); 00142 (*myWaterVec[k]).setPdbResidueNumber(k+1 ); 00143 (*myWaterVec[k]).setPdbChainId('D'); 00144 } 00145 //system.adoptCompound(*myWaterVec[0],Vec3(xi*arista-dropletRadius+dropletCenter[0],yi*arista-dropletRadius+dropletCenter[1],zi*arista-dropletRadius+dropletCenter[2])); 00146 00147 int myWaterIndex =-1; 00148 for (int xi = 0; xi < cellsAcross; xi++) 00149 for (int yi = 0; yi < cellsAcross; yi++) 00150 for (int zi = 0; zi < cellsAcross; zi++) 00151 { 00152 cout<<"checking occupation for "<<xi<<","<<yi<<","<<zi<<endl; 00153 if (myWaterVecOccupation[xi][yi][zi]) 00154 { 00155 myWaterIndex++; 00156 if (myWaterIndex > numWater) {cout << "Attempted to adopt more water than exists in array"<<endl; exit(1);} 00157 cout<<"adopting water at "<< xi*arista-dropletRadius+dropletCenter[0]<<","<<yi*arista-dropletRadius+dropletCenter[1]<<"=,"<<zi*arista-dropletRadius+dropletCenter[2]<<endl; 00158 Rotation myRotation(45.*Deg2Rad, YAxis); 00159 myRotation = myRotation * Rotation(45.*Deg2Rad, XAxis); 00160 Transform myTransform(myRotation,Vec3(xi*arista-dropletRadius+dropletCenter[0],yi*arista-dropletRadius+dropletCenter[1],zi*arista-dropletRadius+dropletCenter[2])); 00161 system.adoptCompound(*myWaterVec[myWaterIndex],myTransform);//Vec3(xi*arista-dropletRadius+dropletCenter[0],yi*arista-dropletRadius+dropletCenter[1],zi*arista-dropletRadius+dropletCenter[2])); 00162 //system.adoptCompound(*myWaterVec[myWaterIndex],Vec3(xi*arista-dropletRadius+dropletCenter[0],yi*arista-dropletRadius+dropletCenter[1],zi*arista-dropletRadius+dropletCenter[2])); 00163 } 00164 } 00165 00166 00167 00168 00169 } 00170 }; 00171 }