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

ChemicalTimeSeriesData.cpp

Go to the documentation of this file.
00001 // ChemicalTimeSeriesData.cpp: implementation of the ChemicalTimeSeriesData class.
00002 //
00004 
00005 #include "ChemicalTimeSeriesData.h"
00006 
00008 // Construction/Destruction
00010 
00011 // the single-argument constructor + AttachNewTimeSeries combination can
00012 // eventually replace the two-argument constructor
00013 // KSB 10/11/00
00014 
00015 ChemicalTimeSeriesData::ChemicalTimeSeriesData(ReactionNetwork *reactionNetwork)
00016 {
00017         this->nChem = reactionNetwork->GetNumberOfChemicals();
00018         chemData.resize(0);
00019         for(int i = 0; i < nChem; i++)
00020         {
00021                 std::vector<DataPoint *> localVector;
00022                 chemData.push_back(localVector);
00023         }
00024 
00025 }
00026 
00028 // Chemical time series data is read in from a file, with the format
00029 //              time            Chemical Name           value           error
00030 // You must put something for the "error" column even if there are 
00031 // no errors in your data (i.e. if it is fake test data); errors of
00032 // 1.0 are fine.  Data does not have to be ordered in any way; entries
00033 // in the above format should be input with no separating whitespace
00034 //              The constructor has to take a "ReactionNetwork" argument 
00035 // because otherwise it can't look up where the chemicals are
00037 
00038 ChemicalTimeSeriesData::ChemicalTimeSeriesData(ReactionNetwork *reactionNetwork, std::string fileName)
00039 {
00040         this->nChem = reactionNetwork->GetNumberOfChemicals();
00041 
00042         // used for reading in the data
00043         int whereAmI;
00044         int i;
00045         char lineBuf[1000];
00046         double time;
00047         char name[100];
00048         double value;
00049         double error;
00050 
00051         this->nChem = reactionNetwork->GetNumberOfChemicals();
00052         chemData.resize(0);
00053         for(i = 0; i < nChem; i++)
00054         {
00055                 std::vector<DataPoint *> localVector;
00056                 chemData.push_back(localVector);
00057         }
00058 
00059         // open the file for reading
00060         ifstream dataFile(fileName.c_str());
00061         assert(dataFile);
00062         
00063         // put the data line by line into the linebuffer and then parse it
00064         // for right now, this is really slow 
00065         // We could (and should) speed this up by allowing
00066         // a search of the chemicals vector to find the chemical number based
00067         // on the name
00068         while(dataFile.getline(lineBuf,sizeof(lineBuf)))
00069         {
00070                 if(lineBuf[0] == '%') {continue;}
00071                 std::istringstream dataStream(lineBuf);
00072                 dataStream >> time >> name >> value >> error;
00073                 
00074                 // find the number the network has assigned to this chemical
00075                 std::string nameString(name);
00076                 for(whereAmI = 0; whereAmI < nChem; whereAmI++)
00077                 {       
00078                         bool isEqual = ( nameString == (reactionNetwork->GetChemical(whereAmI)->GetName()) );
00079                         if(isEqual) {break;}    
00080                 }
00081                 // create a data point and put it in the right place
00082                 DataPoint *dp = new DataPoint(time,value,error);
00083                 chemData[whereAmI].push_back(dp);
00084         }
00085         // sort the chemData
00086         SortChemTimeSeriesData();
00087         // create the time vector and synchronize it to the data
00088         TimeVectorSynchronize();
00089         
00090         // set the number of time series we have data for
00091         int counter = 0;
00092         for(i = 0; i < nChem; i++)
00093         {
00094                 if(chemData[i].size() > 0) {counter++;}
00095         }
00096         nTimeSeries = counter;
00097         
00098         return;
00099 }
00100 
00102 // This reads a new time series from fileName and adds it to the cTSD.
00103 // As of now, there is no safety mechanism to ensure you don't contra-
00104 // dict existing data!  You should be careful that each new file adds
00105 // data for chemicals for which you have no previous data (for now).
00106 // - K.S.B.
00108 
00109 void ChemicalTimeSeriesData::AttachNewTimeSeries(ReactionNetwork *reactionNetwork, std::string fileName)
00110 {
00111         this->nChem = reactionNetwork->GetNumberOfChemicals();
00112 
00113         // used for reading in the data
00114         int whereAmI;
00115         char lineBuf[1000];
00116         double time;
00117         char name[100];
00118         double value;
00119         double error;
00120 
00121 
00122         // open the file for reading
00123         ifstream dataFile(fileName.c_str());
00124         assert(dataFile);
00125         
00126         // put the data line by line into the linebuffer and then parse it
00127         while(dataFile.getline(lineBuf,sizeof(lineBuf)))
00128         {
00129                 if(lineBuf[0] == '%') {continue;}
00130                 std::istringstream dataStream(lineBuf);
00131                 dataStream >> time >> name >> value >> error;
00132                 // find the number the network has assigned to this chemical
00133                 std::string nameString(name);
00134                 for(whereAmI = 0; whereAmI < nChem; whereAmI++)
00135                 {       
00136                         bool isEqual = ( nameString == (reactionNetwork->GetChemical(whereAmI)->GetName()) );
00137                         if(isEqual) {break;}    
00138                 }
00139                 // create a data point and put it in the right place
00140                 //DataPoint *dp = new DataPoint(time,value,error);
00141                 chemData[whereAmI].push_back(new DataPoint(time,value,error));
00142         }
00143         // sort the chemData
00144         SortChemTimeSeriesData();
00145         // recreate and synchronize the time vector
00146         TimeVectorSynchronize();
00147         
00148         // set the number of time series 
00149         // you can't just increment nTimeSeries because the new files
00150         // you add can have any number of new time series in them
00151         int counter = 0;
00152         for(int i = 0; i < nChem; i++)
00153         {
00154                 //if( chemData[i] != (std::vector<DataPoint *>)NULL ) {counter++;}
00155                 //if( chemData[i] != NULL ) {counter++;}
00156                 if(chemData[i].size() > 0) {counter++;}
00157         }
00158         nTimeSeries = counter;
00159 
00160         
00161         return;
00162 }
00163 
00164 void ChemicalTimeSeriesData::TimeVectorSynchronize()
00165 {
00166         // erase the old time vector
00167         timeVector.erase(timeVector.begin(),timeVector.end());
00168         // run through the data and create the time vector
00169         for(int i = 0; i < nChem; i++)
00170         {
00171                 if(chemData[i].size() > 0)
00172                 {
00173                         for(int pos = 0; pos < chemData[i].size(); pos++)
00174                         {
00175                                 double time = (chemData[i])[pos]->GetTime();
00176                                 TimeVectorPoint *tp = new TimeVectorPoint(time,pos,i);
00177                                 timeVector.push_back(tp);
00178                         }
00179                 }
00180         }
00181         // sort the newly created time vector
00182         SortTimeVector();
00183 }
00184 
00185 
00186 ChemicalTimeSeriesData::~ChemicalTimeSeriesData()
00187 {
00188         int i,j;
00189         // cleanup
00190         for(i = 0; i < nChem; i++)
00191         {
00192                 for(j = 0; j < chemData[i].size(); j++)
00193                 {
00194                         delete chemData[i][j];
00195                 }
00196         }
00197         for(i = 0; i < timeVector.size(); i++)
00198         {
00199                 delete timeVector[i];
00200         }
00201 }
00202 
00203 std::vector<DataPoint *> ChemicalTimeSeriesData::GetTimeSeries(int chemIndex)
00204 {
00205         return chemData[chemIndex];
00206 }
00207 
00208 void ChemicalTimeSeriesData::SortChemTimeSeriesData()
00209 {
00210         // use STL sort with a comparator that accepts pointers
00211         DataPoint::DataPointComparator comparator;
00212         for(int i = 0; i < nChem; i++)
00213         {
00214                 if( chemData[i].size() > 0 )
00215                 {
00216                         std::sort(chemData[i].begin(),chemData[i].end(),comparator);
00217                 }
00218         }
00219 }
00220 
00221 void ChemicalTimeSeriesData::SortTimeVector()
00222 {
00223         // use STL sort with the correct comparator
00224         TimeVectorPoint::TimeVectorPointComparator comparator;
00225         std::sort(timeVector.begin(),timeVector.end(),comparator);
00226 }
00227 
00228 int ChemicalTimeSeriesData::GetNDataPoints()
00229 {
00230         return timeVector.size();
00231 }
00232 
00233 int ChemicalTimeSeriesData::GetNTimeSeries()
00234 {
00235         return nTimeSeries;
00236 }
00237 
00238 int ChemicalTimeSeriesData::GetNChemicals()
00239 {
00240         return nChem;
00241 }
00242 
00243 double ChemicalTimeSeriesData::GetNextDataTime(double time)
00244 {
00245         // STL algorithm
00246         // define an iterator for the timeVector
00247         std::vector<TimeVectorPoint *>::iterator it;
00248         // the comparator is defined in terms of TimeVectorPoint *, so
00249         // that's the value we need (it's a dummy in terms of everything
00250         // except time
00251         TimeVectorPoint *tp = new TimeVectorPoint(time,0,0);
00252         // comparator
00253         TimeVectorPoint::TimeVectorPointComparator comparator;
00254         // get the iterator
00255         it = std::lower_bound(timeVector.begin(),timeVector.end(),tp,comparator); 
00256         // iterator points to a data point; if it's at the end the comparison
00257         // time is off-the-end of the vector
00258         if( it != timeVector.end() )
00259         {
00260                 return (*it)->GetTime();
00261         }
00262         else
00263         {
00264                 // throwing an exception is just temporary
00265                 throw std::runtime_error("Trial value is past final data point");
00266         }
00267         
00268         // cleanup
00269         delete tp;
00270 //      delete it;
00271 }
00272 
00274 // The function GetLatestDataTime() sorts the timeVector and returns
00275 // the latest time at which any chemical data is present.  This is of
00276 // use in deciding how long the ReactionMover moves the network. 
00277 // - K.S.B.
00279 
00280 double ChemicalTimeSeriesData::GetLatestDataTime()
00281 {
00282         SortTimeVector();
00283         double latestTime = (timeVector[timeVector.size() - 1])->GetTime();
00284         return latestTime;
00285 }

Generated on Mon Nov 3 09:37:40 2003 by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002