PeriodicVmdReporter.h

Go to the documentation of this file.
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: Christopher Bruns                                                 *
00011  * Contributors:                                                              *
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 #ifndef SimTK_MOLMODEL_PERIODICVMDREPORTER_H_
00033 #define SimTK_MOLMODEL_PERIODICVMDREPORTER_H_
00034 
00035 #include "SimTKsimbody.h"
00036 #include "molmodel/internal/Compound.h"
00037 #include "molmodel/internal/VmdConnection.h"
00038 #include <iostream>
00039 #include <iomanip>
00040 #include <vector>
00041 
00042 namespace SimTK {
00043 
00046 class PeriodicVmdReporter : public PeriodicEventReporter {
00047 public:
00048     PeriodicVmdReporter(
00049         const CompoundSystem& system, 
00050         Real interval,
00051         int localSocketNumber,
00052         bool blockWaitingForVmdConnection = false
00053         ) 
00054         : PeriodicEventReporter(interval), 
00055           system(system), 
00056           vmdConnection(localSocketNumber),
00057           blockWaitingForVmdConnection(blockWaitingForVmdConnection)
00058     {}
00059 
00060     void handleEvent(const State& state) const 
00061     {
00062         // checkForConnection() can be slow when there is none
00063         // so only check every so often
00064         static int timeStepNumber = 0;
00065         int checkFrequency = 20;
00066         
00067         // Try our best to connect to vmd
00068         if (! vmdConnection.clientIsConnected() )
00069         {
00070             if (blockWaitingForVmdConnection)
00071             {
00072                 while ( ! vmdConnection.clientIsConnected() ) 
00073                 {
00074                     std::cerr << "Waiting for vmd IMD connection on port " << vmdConnection.getSocketNumber() << "..." << std::endl;
00075 
00076                     vmdConnection.checkForConnection();
00077 
00078                     sleep(1);
00079 
00080                 }  
00081             }
00082             else
00083             {
00084                 if ( 0 == (timeStepNumber % checkFrequency) )
00085                 vmdConnection.checkForConnection();
00086             } 
00087         }
00088 
00089         // Write the coordinates, if we are connected to vmd
00090         if ( vmdConnection.clientIsConnected() )
00091         {
00092             system.realize(state, Stage::Position);
00093             
00094             // To ensure that the atom coordinates are in the same order as PDB output,
00095             // create PDB output, and parse that to generate the coordinates
00096             std::stringstream pdbString;
00097             
00098             // 1) Write pdb coordinates into the string
00099             int nextAtomSerialNumber = 1; // atom serial number for each compound picks up where previous compound left off
00100             for (SimTK::Compound::Index c(0); c < system.getNumCompounds(); ++c)
00101                 system.getCompound(c).writePdb(state, pdbString, nextAtomSerialNumber);
00102             
00103             // 2) Read pdb coordinates from the string
00104             std::vector<VmdFloat3> vmdCoordinates;
00105             char lineBuffer[102];
00106             while ( ! pdbString.eof() )
00107             {
00108                 pdbString.getline(lineBuffer, 100);
00109                 std::string line(lineBuffer);
00110                 
00111                 if ( (line.length() > 55) && ((line.substr(0, 6) == "ATOM  ") || (line.substr(0, 6) == "HETATM")) )
00112                 {
00113                     float x, y, z;
00114                     std::istringstream(line.substr(30, 8)) >> x;
00115                     std::istringstream(line.substr(38, 8)) >> y;
00116                     std::istringstream(line.substr(46, 8)) >> z;
00117                     vmdCoordinates.push_back(VmdFloat3(x, y, z));
00118                 }
00119             }
00120             
00121             vmdConnection.sendCoordinates(vmdCoordinates);
00122         }
00123 
00124         ++timeStepNumber;
00125         
00126     }
00127 
00128 private:
00129     const CompoundSystem& system;
00130     mutable VmdConnection vmdConnection;
00131     bool blockWaitingForVmdConnection;
00132 };
00133 
00134 } // namespace SimTK
00135 
00136 #endif // SimTK_MOLMODEL_PERIODICVMDREPORTER_H_

Generated on Fri Sep 26 07:44:15 2008 for SimTKcore by  doxygen 1.5.6