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

CoorPluginData.C

Go to the documentation of this file.
00001 /***************************************************************************
00002 *cr
00003 *cr (C) Copyright 1995-2019 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.34 $ $Date: 2020年06月11日 08:17:38 $
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 
00046 // ensure ts_page_alignment flag is cleared by default
00047 ts_page_align_sz=0;
00048 
00050 kbytesperframe=0;
00051 totalframes=0;
00052 
00053 // make sure frame data is correct
00054 if(begFrame < 0)
00055 begFrame = 0;
00056 if(endFrame < begFrame)
00057 endFrame = (-1);
00058 if(frameSkip <= 0)
00059 frameSkip = 1;
00060 recentFrame = -1;
00061 
00062 // make sure frame data is valid
00063 if(!m || (!is_input && 
00064 ( m->numframes() < begFrame || endFrame >= m->numframes() ) 
00065 ) ) {
00066 msgErr << "Illegal frames requested for coordinate file I/O" << sendmsg;
00067 return;
00068 }
00069 if (is_input) {
00070 // Checks for and reject attempts to use selections when reading
00071 // coordinates. The most useful thing to do would be to allow coordinate
00072 // files to contain whatever number of atoms you want, and then use the
00073 // selection to filter those atoms. However, one could go a number of ways
00074 // with this. Should the selection be reparsed using the structure and/or
00075 // coordinate data in the new file in order to determine which atoms to
00076 // read, or should one simply use the already-computed atom indices? I can
00077 // think of situations where both of those behaviors would be desirable.
00078 if (sel) {
00079 msgErr << "Internal error: cannot read selection of coordinates"
00080 << sendmsg;
00081 return;
00082 }
00083 // make sure that the number of atoms in the coordinate file is either valid
00084 // or unknown.
00085 if (p->natoms() != m->nAtoms) {
00086 if (p->natoms() == -1) {
00087 p->set_natoms(m->nAtoms);
00088 } else {
00089 msgErr << "Incorrect number of atoms (" << p->natoms() << ") in" 
00090 << sendmsg;
00091 msgErr << "coordinate file " << nm << sendmsg;
00092 msgErr << "Mismatch between existing molecule or structure file atom count and coordinate or trajectory file atom count." << sendmsg;
00093 return;
00094 } 
00095 } 
00096 }
00097 
00098 // make plugin and selection information valid
00099 plugin = p;
00100 if (sel) {
00101 selection = new int[m->nAtoms];
00102 memcpy(selection, sel, m->nAtoms * sizeof(int));
00103 }
00104 
00105 tm=wkf_timer_create();
00106 wkf_timer_start(tm);
00107 
00108 // If this is output, write the structure now. 
00109 if (!is_input && plugin->can_write_structure()) {
00110 if (plugin->write_structure(m, selection) == MOLFILE_SUCCESS) {
00111 totalframes++;
00112 } else {
00113 plugin = NULL;
00114 }
00115 }
00116 
00117 if (is_input) {
00118 kbytesperframe = (long(p->natoms()) * 12L) / 1024L;
00119 } else {
00120 kbytesperframe = (long(m->nAtoms) * 12L) / 1024L;
00121 }
00122 
00123 // Check if VMD has to use page-aligned memory allocations for
00124 // timestep data, to allow for fast kernel-bypass unbuffered I/O APIs
00125 if (plugin->can_read_pagealigned_timesteps()) {
00126 #if vmdplugin_ABIVERSION > 17
00127 ts_page_align_sz = plugin->read_timestep_pagealign_size();
00128 #else
00129 #if 1
00130 ts_page_align_sz = 1; // assume non-blocked I/O
00131 #else
00132 // Enable VMD to cope with hard-coded revs of jsplugin if we want
00133 ts_page_align_sz = MOLFILE_DIRECTIO_MAX_BLOCK_SIZE;
00134 #endif
00135 #endif
00136 } else {
00137 ts_page_align_sz = 1; // set page alignment flag to indicate normal I/O
00138 }
00139 }
00140 
00141 CoorPluginData::~CoorPluginData() {
00142 delete plugin;
00143 plugin = NULL;
00144 
00145 if (tm) {
00146 wkf_timer_destroy(tm);
00147 tm=NULL;
00148 }
00149 
00150 delete [] selection;
00151 }
00152 
00153 CoorData::CoorDataState CoorPluginData::next(Molecule *m) {
00154 if (!plugin) 
00155 return DONE;
00156 
00157 if (is_input) {
00158 if (recentFrame < 0) {
00159 recentFrame = 0;
00160 while (recentFrame < begFrame) {
00161 plugin->skip(m);
00162 recentFrame++;
00163 }
00164 } else {
00165 for (int i=1; i<frameSkip; i++) 
00166 plugin->skip(m);
00167 recentFrame += frameSkip;
00168 }
00169 if (endFrame < 0 || recentFrame <= endFrame) {
00170 Timestep *ts = plugin->next(m, ts_page_align_sz); 
00171 if (ts) {
00172 m->append_frame(ts);
00173 totalframes++;
00174 return NOTDONE;
00175 }
00176 }
00177 } else if (m->numframes() > 0) { // output
00178 if (recentFrame < 0)
00179 recentFrame = begFrame;
00180 else
00181 recentFrame += frameSkip;
00182 
00183 // get next frame, and write to file
00184 if ((endFrame < 0 || recentFrame <= endFrame) 
00185 && m->numframes() > recentFrame) {
00186 Timestep *ts = m->get_frame(recentFrame);
00187 if (ts) {
00188 if (!plugin->write_timestep(ts, selection)) {
00189 totalframes++;
00190 return NOTDONE;
00191 } else {
00192 msgErr << "write_timestep returned nonzero" << sendmsg;
00193 }
00194 } 
00195 }
00196 }
00197 
00198 if (tm != NULL && totalframes > 0) {
00199 double iotime = wkf_timer_timenow(tm);
00200 // emit I/O stats if requested, or it took more than 3 seconds
00201 if ((getenv("VMDTSTIMER") != NULL) || (iotime > 3.0)) {
00202 float framerate = (float) (((double) totalframes) / iotime);
00203 char tmbuf[1024], frameratebuf[1024];
00204 sprintf(tmbuf, "%.1f", iotime);
00205 if (framerate > 10)
00206 sprintf(frameratebuf, "%.1f", framerate);
00207 else
00208 sprintf(frameratebuf, "%.2f", framerate);
00209 msgInfo << "Coordinate I/O rate " 
00210 << frameratebuf << " frames/sec, "
00211 << (int) ((totalframes / iotime) * (kbytesperframe / 1024.0)) 
00212 << " MB/sec, "
00213 << tmbuf << " sec" << sendmsg;
00214 }
00215 }
00216 
00217 // we're done; close file and stop reading/writing
00218 delete plugin;
00219 plugin = NULL;
00220 return DONE;
00221 }
00222 

Generated on Mon Nov 17 02:45:58 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /