Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

CoorPluginData.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2011 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: CoorPluginData.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.27 $       $Date: 2012/03/20 15:39:55 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *  Interface code that manages loading and saving of coordinate data via 
00019  *  plugin interfaces.  Uses MolFilePlugin to do the file loading.
00020  ***************************************************************************/
00021 
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 
00026 #include "CoorPluginData.h"
00027 #include "MolFilePlugin.h"
00028 #include "Inform.h"
00029 #include "Molecule.h"
00030 #include "WKFUtils.h"
00031 
00032 CoorPluginData::CoorPluginData(const char *nm, Molecule *m, MolFilePlugin *p,
00033     int input, int first, int stride, int last, const int *sel) 
00034 : CoorData(nm), is_input(input), begFrame(first), frameSkip(stride), 
00035   endFrame(last) {
00036 
00038   selection = NULL;
00039 
00041   plugin = NULL;
00042 
00044   tm=NULL;
00045 
00047   kbytesperframe=0;
00048   totalframes=0;
00049 
00050   // make sure frame data is correct
00051   if(begFrame < 0)
00052     begFrame = 0;
00053   if(endFrame < begFrame)
00054     endFrame = (-1);
00055   if(frameSkip <= 0)
00056     frameSkip = 1;
00057   recentFrame = -1;
00058 
00059   // make sure frame data is valid
00060   if(!m || (!is_input && 
00061               ( m->numframes() < begFrame || endFrame >= m->numframes() ) 
00062            ) ) {
00063     msgErr << "Illegal frames requested for coordinate file I/O" << sendmsg;
00064     return;
00065   }
00066   if (is_input) {
00067     // Checks for and reject attempts to use selections when reading
00068     // coordinates.  The most useful thing to do would be to allow coordinate
00069     // files to contain whatever number of atoms you want, and then use the
00070     // selection to filter those atoms.  However, one could go a number of ways
00071     // with this.  Should the selection be reparsed using the structure and/or
00072     // coordinate data in the new file in order to determine which atoms to
00073     // read, or should one simply use the already-computed atom indices?  I can
00074     // think of situations where both of those behaviors would be desirable.
00075     if (sel) {
00076       msgErr << "Internal error: cannot read selection of coordinates"
00077              << sendmsg;
00078       return;
00079     }
00080     // make sure that the number of atoms in the coordinate file is either valid
00081     // or unknown.
00082     if (p->natoms() != m->nAtoms) {
00083       if (p->natoms() == -1) {
00084         p->set_natoms(m->nAtoms);
00085       } else {
00086         msgErr << "Incorrect number of atoms (" << p->natoms() << ") in" 
00087                << sendmsg;
00088         msgErr << "coordinate file " << nm << sendmsg;
00089         return;
00090       } 
00091     } 
00092   }
00093 
00094   // make plugin and selection information valid
00095   plugin = p;
00096   if (sel) {
00097     selection = new int[m->nAtoms];
00098     memcpy(selection, sel, m->nAtoms * sizeof(int));
00099   }
00100 
00101   tm=wkf_timer_create();
00102   wkf_timer_start(tm);
00103 
00104   // If this is output, write the structure now.  
00105   if (!is_input && plugin->can_write_structure()) {
00106     if (plugin->write_structure(m, selection) == MOLFILE_SUCCESS) {
00107       totalframes++;
00108     } else {
00109       plugin = NULL;
00110     }
00111   }
00112 
00113   if (is_input) {
00114     kbytesperframe = (p->natoms() * 12) / 1024;
00115   } else {
00116     kbytesperframe = (m->nAtoms * 12) / 1024;
00117   }
00118 }
00119 
00120 CoorPluginData::~CoorPluginData() {
00121   delete plugin;
00122   plugin = NULL;
00123 
00124   if (tm) {
00125     wkf_timer_destroy(tm);
00126     tm=NULL;
00127   }
00128 
00129   delete [] selection;
00130 }
00131 
00132 CoorData::CoorDataState CoorPluginData::next(Molecule *m) {
00133   if (!plugin) 
00134     return DONE;
00135 
00136   if (is_input) {
00137     if (recentFrame < 0) {
00138       recentFrame = 0;
00139       while (recentFrame < begFrame) {
00140         plugin->skip(m);
00141         recentFrame++;
00142       }
00143     } else {
00144       for (int i=1; i<frameSkip; i++) 
00145         plugin->skip(m);
00146       recentFrame += frameSkip;
00147     }
00148     if (endFrame < 0 || recentFrame <= endFrame) {
00149       Timestep *ts = plugin->next(m); 
00150       if (ts) {
00151         m->append_frame(ts);
00152         totalframes++;
00153         return NOTDONE;
00154       }
00155     }
00156   } else if (m->numframes() > 0) {  // output
00157     if (recentFrame < 0)
00158       recentFrame = begFrame;
00159     else
00160       recentFrame += frameSkip;
00161 
00162     // get next frame, and write to file
00163     if ((endFrame < 0 || recentFrame <= endFrame) 
00164         && m->numframes() > recentFrame) {
00165       Timestep *ts = m->get_frame(recentFrame);
00166       if (ts) {
00167         if (!plugin->write_timestep(ts, selection)) {
00168           totalframes++;
00169           return NOTDONE;
00170         } else {
00171           msgErr << "write_timestep returned nonzero" << sendmsg;
00172         }
00173       }      
00174     }
00175   }
00176 
00177   if (tm != NULL && totalframes > 0) {
00178     double iotime = wkf_timer_timenow(tm);
00179     // emit I/O stats if requested, or it took more than 3 seconds
00180     if ((getenv("VMDTSTIMER") != NULL) || (iotime > 3.0)) {
00181       float framerate = (float) (((double) totalframes) / iotime);
00182       char tmbuf[1024], frameratebuf[1024];
00183       sprintf(tmbuf, "%.1f", iotime);
00184       if (framerate > 10)
00185         sprintf(frameratebuf, "%.1f", framerate);
00186       else
00187         sprintf(frameratebuf, "%.2f", framerate);
00188       msgInfo << "Coordinate I/O rate " 
00189               << frameratebuf << " frames/sec, "
00190               << (int) (((totalframes * kbytesperframe) / 1024.0) / iotime) 
00191               << " MB/sec, "
00192               << tmbuf << " sec" << sendmsg;
00193     }
00194   }
00195 
00196   // we're done; close file and stop reading/writing
00197   delete plugin;
00198   plugin = NULL;
00199   return DONE;
00200 }
00201 

Generated on Wed May 16 01:49:08 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002