#include "fileio.h"
/* ----------------------------------------------------
NOTICE OF COPYRIGHT AND OWNERSHIP OF SOFTWARE
Copyright 2004, The Johns Hopkins University
School of Medicine. All rights reserved.
For research use only; commercial use prohibited.
Distribution without permission of Raimond L. Winslow
not permitted. rwinslow@bme.jhu.edu
Name of Program: Guinea Pig C++: Coupled, Algbraic, BB, MCA
Version: Documented Version, version 1.0.1
Date: August 2004
-----------------------------------------------------
*/
fileIO::fileIO(void) {
writeDependent = true;
writeDerivatives = false;
writestates = true;
lastState = NULL;
separator = char(9);
sample_size = 0;
}
fileIO::~fileIO(void) {
}
//New data storage stuff
const double& fileIO::operator[](const string ¶m) {
realDataType::iterator p = realData.find(param);
if (p != realData.end())
return p->second;
//Might want to throw an exception in the future, but for now error and and pause
cout << "An error has occured in 'fileIO::operator[]', numeric data: " << param << " parameter was not found." << endl;
exit(-1);
}
//New data accessors
double fileIO::getReal(const string ¶m) { return operator[](param); }
int fileIO::getInteger(const string ¶m) {
double d = operator[](param);
if ( (floor(d) - d) == 0 )
return (int)(operator[](param));
//Might want to throw an exception in the future, but for now error and and pause
//Could also right round code using modf
cout << "An error has occured in 'fileIO::operator[]', numeric data: " << param << " was: " << d << " not integer." << endl;
exit(-1);
}
const string& fileIO::getKeyword(const string ¶m) {
keywordDataType::iterator p = keywordData.find(param);
if (p != keywordData.end())
return p->second;
//Might want to throw an exception in the future, but for now error and and pause
cout << "An error has occured in 'fileIO::operator[]', keyword data: " << param << " parameter was not found." << endl;
exit(-1);
}
bool fileIO::getBoolean(const string ¶m) {
keywordDataType::iterator p = keywordData.find(param);
if (p == keywordData.end()) {
//Might want to throw an exception in the future, but for now error and and pause
cout << "An error has occured in 'fileIO::operator[]', keyword data: " << param << " parameter was not found." << endl;
exit(-1);
}
if( _strnicmp(p->second.c_str(), "true", 4) == 0 )
return true;
if( _strnicmp(p->second.c_str(), "false", 4) == 0 )
return false;
//Again with exceptions
cout << "An error has occured in 'fileIO::operator[]', keyword data: " << param << " was: " << p->second << " not boolean." << endl;
exit(-1);
}
//Test to see if a value is loaded
bool fileIO::parameterExists(const string ¶m) {
keywordDataType::iterator p = keywordData.find(param);
if (p == keywordData.end()) {
realDataType::iterator r = realData.find(param);
if (r == realData.end()) {
return false;
}
}
return true;
}
//readFile reads all the initial conditions in from an input file called "ini.txt"
void fileIO::loadFile(const char *ParameterFileName) {
//Open the file and set up the iterators for the parsers
file_iterator<> start(ParameterFileName);
if (!start) {
cerr << "No such file as" << ParameterFileName << "." << endl;
exit(-1);
}
file_iterator<> end = start.make_end();
parameterFileGrammer pfg(this);
if (!(parse(start,end, pfg)).full) {//True if good parse, so the !
cout << "Invalid file format for file: " << ParameterFileName << endl;
exit(-1);
}
}
// Writing Functions **************************************************
//Write the steadystate conditions file
//Might be useful: Form sci8; sci8.scientific().precision(8), instead of set with, see page 633
void fileIO::writeInitialConditionsFile(const char *filename, Model &model) {
if (lastState == NULL) return;
return writeInitialConditionsFile(filename, model, lastState);
}
void fileIO::writeInitialConditionsFile(const char *filename, Model &model, const double *states) {
//Write file only if the flag is set
if (getBoolean("write_end_initial_conditions")) {
ofstream out(filename, ios::out);
if( !out.is_open() ) {
cout << "Error opening: " << filename << " for output." << endl;
exit(-10);
}
time_t rawtime;
tm *timenow;
time(&rawtime);
timenow = localtime(&rawtime);
int year = 1900 + timenow->tm_year;
int month = timenow->tm_mon;
int day = timenow->tm_mday;
int hour = timenow->tm_hour;
int min = timenow->tm_min;
out <<"/*"<<endl
<< "Initial conditions file." << endl
<< "Date: " << year << "." << month << "." << day << " at " << hour << ":" << min << " (ISO format: Year.Month.Date)" << endl
<< endl
<< "Format of the parameter file:" << endl
<< char(9) << "Comment lines start with //, !, %, Or block" << endl
<< char(9) << "Initial conditions are in the following format:" << endl
<< char(9) << "[variable] = [value]" << endl
<<"*/"<<endl;
//setw(14)
//ios_base:: scientific, ios_base:: floatfield
//ios_base::boolalpha
// ios_base::dec, ios_base::adjustfield
out.setf(ios_base::scientific, ios_base:: floatfield);
out.setf(ios_base::boolalpha);
out.setf(ios_base::dec, ios_base::adjustfield);
out.precision(16);
const double *s = model.getInitialConditions(states);
for(int i = 0; i < model.getInitialConditionsSize(); i++) {
out << model.getInitialConditionLabel(i) << char(9) << "= " << s[i] << endl;
}
out.close();
}
}
//printstates outputs to 3 separate files depending on the input file.
//Each file contains either the states, currents, or derivatives.
void fileIO::openOutputFiles(Model* model, const char * statesFilename, const char * currentsFilename, const char * derivativeFilename) {
if (writestates) {
if( outStates.is_open() )
outStates.close();
outStates.open(statesFilename, ios::out );
if( !outStates.is_open() ) {
cout << "Error opening: " << statesFilename << " for output." << endl;
exit(-1);
}
outStates.setf(ios_base::scientific, ios_base:: floatfield);
outStates.setf(ios_base::boolalpha);
outStates.setf(ios_base::dec, ios_base::adjustfield);
outStates.precision(getInteger("States_Precision"));
keywordList *stateList = &(keywordListData["Ouput_State_List"]);
keywordList::iterator b = stateList->begin();
stateIndexes.resize(stateList->size());
if(outputMode == MCA) {
outStates << "Sample_Size";
outStates << separator << "Parameter";
outStates << separator << "Percent";
} else if (outputMode == Average) {
outStates << "Metric";
outStates << separator << "Sample_Size";
} else {
outStates << "Time";
}
for ( unsigned int i = 0; i < stateList->size(); i++) {
outStates << separator << *b;
stateIndexes[i] = model->getStateIndex( (*b).c_str() );
b++;
}
outStates << endl;
}
if (writeDependent) {
if( outCurrents.is_open() )
outCurrents.close();
outCurrents.open(currentsFilename, ios::out);
if( !outCurrents.is_open() ) {
cout << "Error opening: " << currentsFilename << " for output." << endl;
exit(-1);
}
outCurrents.setf(ios_base::scientific, ios_base:: floatfield);
outCurrents.setf(ios_base::boolalpha);
outCurrents.setf(ios_base::dec, ios_base::adjustfield);
outCurrents.precision(getInteger("Dependent_Precision"));
keywordList *dependentList = &(keywordListData["Ouput_Dependent_List"]);
keywordList::iterator b = dependentList->begin();
dependentIndexes.resize(dependentList->size());
if(outputMode == MCA) {
outCurrents << "Sample_Size";
outCurrents << separator << "Parameter";
outCurrents << separator << "Percent";
} else if (outputMode == Average) {
outCurrents << "Metric" << separator;
outCurrents << "Sample_Size";
} else {
outCurrents << "Time";
}
for ( unsigned int i = 0; i < dependentList->size(); i++) {
outCurrents << separator << *b;
dependentIndexes[i] = model->getDependentVariableIndex( (*b).c_str() );
b++;
}
outCurrents << endl;
}
if (writeDerivatives) {
if( outDerivatives.is_open() )
outDerivatives.close();
outDerivatives.open(derivativeFilename, ios::out);
if( !outDerivatives.is_open() ) {
cout << "Error opening: " << derivativeFilename << " for output." << endl;
exit(-1);
}
outDerivatives.setf(ios_base::scientific, ios_base:: floatfield);
outDerivatives.setf(ios_base::boolalpha);
outDerivatives.setf(ios_base::dec, ios_base::adjustfield);
outDerivatives.precision(getInteger("Derivatives_Precision"));
keywordList *derivativeList = &(keywordListData["Ouput_Derivative_List"]);
keywordList::iterator b = derivativeList->begin();
derivativeIndexes.resize(derivativeList->size());
outDerivatives << "Time";
for ( unsigned int i = 0; i < derivativeList->size(); i++) {
outDerivatives << separator << *b;
derivativeIndexes[i] = model->getStateIndex( (*b).c_str() );
b++;
}
outDerivatives << endl;
}
}
//Setup the various output file variables before writting
void fileIO::setupFileOut() {
//Setup file output
string out_mode = getKeyword("Output_Mode");
if (out_mode == "numeric")
outputMode = Numeric;
if (out_mode == "average")
outputMode = Average;
if (out_mode == "MCA")
outputMode = MCA;
writeDependent = getBoolean("Write_Dependent");
writestates = getBoolean("Write_States");
writeDerivatives = getBoolean("Write_Derivatives");
}
//Ouput averages etc
void fileIO::finalizeFileOut() {
if(outputMode==Average) {
int s_size = sample_size;
MCA_AverageData();
if (!outStates.is_open() && writestates) {
cout << "Attempting to output to the states file without opening." << endl;
exit(-1);
} else if (writestates) { //Actually output all the states
outStates << "Mean" << separator;
outStates << s_size;
for ( unsigned int i = 0; i < stateAverage.size(); i++) { outStates << separator << stateAverage[ i ]; }
outStates << endl << "Max" << separator << s_size;
for ( unsigned int i = 0; i < stateMax.size(); i++) { outStates << separator << stateMax[ i ]; }
outStates << endl << "Min" << separator << s_size;
for ( unsigned int i = 0; i < stateMin.size(); i++) { outStates << separator << stateMin[ i ]; }
outStates << endl;
}
if (!outCurrents.is_open() && writeDependent) {
cout << "Attempting to output to the currents file without opening." << endl;
exit(-1);
} else if (writeDependent) { //Actually output all the states
outCurrents << "Mean" << separator;
outCurrents << s_size;
for ( unsigned int i = 0; i < dependentAverage.size(); i++) { outCurrents << separator << dependentAverage[ i ]; }
outCurrents << endl << "Max" << separator << s_size;
for ( unsigned int i = 0; i < dependentMax.size(); i++) { outCurrents << separator << dependentMax[ i ]; }
outCurrents << endl << "Min" << separator << s_size;
for ( unsigned int i = 0; i < dependentMin.size(); i++) { outCurrents << separator << dependentMin[ i ]; }
outCurrents << endl;
}
if (!outDerivatives.is_open() && writeDerivatives) {
cout << "Attempting to output to the Derivatives file without opening." << endl;
exit(-1);
} else if (writeDerivatives) { //Actually output all the states
outDerivatives << time;
for ( unsigned int i = 0; i < derivativeIndexes.size(); i++) {
outDerivatives << separator << dependentAverage[ i ];
}
outDerivatives << endl;
}
}
}
//Close any open file handles
void fileIO::closeOutputFiles() {
if (outStates.is_open())
outStates.close();
if (outCurrents.is_open())
outCurrents.close();
if (outDerivatives.is_open())
outDerivatives.close();
}
// write incremental output
//Fundamental flaw: CAN NOT use the model for output variables, CVode interpolates back to get y.
//CVode has a built in function for derivatives
void fileIO::writeLnOutputFiles(double * states, double time, Model* model) {
//Save the last state for IC
lastState = states;
sample_size++;
model->F(time, model->getStatesDerivatives(), states);
const double *derivs = model->getStatesDerivatives();
//const double *vars = model.getDependentVariables(); //Need to write this, old currents
//Output the states
//[ V, Nai, Ki, Cai, CaNSR, CaSS, CaJSR, ATPi, Cam, ADPm, Dpsi, NADH, ISOC, AKG, SCoA, Succ, FUM, MAL, Oaa ]
if(writestates) {
if (!outStates.is_open() ) {
cout << "Attempting to output to the states file without opening." << endl;
exit(-1);
} //Actually output all the states
switch(outputMode) {
case Numeric:
outStates << time;
//outStates.write( (char*)(&time), sizeof(double) );
for ( unsigned int i = 0; i < stateIndexes.size(); i++) {
outStates << separator << states[ stateIndexes[i] ];
//outStates.write( (char*)(&states[ stateIndexes[i] ]), sizeof(double) );
}
outStates << endl;
break;
case MCA:
case Average:
for ( unsigned int i = 0; i < stateIndexes.size(); i++) {
stateAverage[i] += states[ stateIndexes[i] ];
stateMin[i] = __min( stateMin[i], states[ stateIndexes[i] ] );
stateMax[i] = __max( stateMax[i], states[ stateIndexes[i] ] );
}
break;
}
}
if (writeDependent) {
if (!outCurrents.is_open() ) {
cout << "Attempting to output to the currents file without opening." << endl;
exit(-1);
} //Actually output all the states
switch(outputMode) {
case Numeric:
outCurrents << time;
for ( unsigned int i = 0; i < dependentIndexes.size(); i++) {
outCurrents << separator << model->getDependentVariable( dependentIndexes[i] );
}
outCurrents << endl;
break;
case MCA:
case Average:
for ( unsigned int i = 0; i < dependentIndexes.size(); i++) {
dependentAverage[i] += model->getDependentVariable( dependentIndexes[i] );
dependentMin[i] = __min( dependentMin[i], model->getDependentVariable( dependentIndexes[i] ) );
dependentMax[i] = __max( dependentMax[i], model->getDependentVariable( dependentIndexes[i] ) );
}
break;
}
}
//Output the derivatives
//[ V, Nai, Ki, Cai, CaNSR, CaSS, CaJSR, ATPi, Cam, ADPm, Dpsi, NADH, ISOC, AKG, SCoA, Succ, FUM, MAL, Oaa ]
if (writeDerivatives) {
if (!outDerivatives.is_open()) {
cout << "Attempting to output to the Derivatives file without opening." << endl;
exit(-1);
} //Actually output all the states
switch(outputMode) {
case Numeric:
outDerivatives << time;
for ( unsigned int i = 0; i < derivativeIndexes.size(); i++) {
outDerivatives << separator << derivs[ derivativeIndexes[i] ];
}
outDerivatives << endl;
break;
case MCA:
case Average:
for ( unsigned int i = 0; i < derivativeIndexes.size(); i++) {
derivativeAverage[i] += derivs[ stateIndexes[i] ];
}
break;
}
}
}
// ******************************************************************
// ****************** MCA Specific Functions ************************
// ******************************************************************
void fileIO::MCA_Setup(Model* model) {
//Make sure the sample size is 0 to start
sample_size = 0;
stateAverage.resize(stateIndexes.size());
stateMin.resize(stateIndexes.size());
stateMax.resize(stateIndexes.size());
derivativeAverage.resize(derivativeIndexes.size());
dependentMin.resize(dependentIndexes.size());
dependentMax.resize(dependentIndexes.size());
dependentAverage.resize(dependentIndexes.size());
for ( unsigned int i = 0; i < stateAverage.size(); i++) { stateAverage[i] = 0; }
for ( unsigned int i = 0; i < stateMin.size(); i++) { stateMin[i] = DBL_MAX; }
for ( unsigned int i = 0; i < stateMax.size(); i++) { stateMax[i] = DBL_MIN; }
for ( unsigned int i = 0; i < derivativeAverage.size(); i++) { derivativeAverage[i] = 0; }
for ( unsigned int i = 0; i < dependentMin.size(); i++) { dependentMin[i] = DBL_MAX; }
for ( unsigned int i = 0; i < dependentMax.size(); i++) { dependentMax[i] = DBL_MIN; }
for ( unsigned int i = 0; i < dependentAverage.size(); i++) { dependentAverage[i] = 0; }
writestates = getBoolean("Write_States");
writeDependent = getBoolean("Write_Dependent");
writeDerivatives= getBoolean("Write_Derivatives");
stateOldAverage.resize(stateIndexes.size());
derivativeOldAverage.resize(derivativeIndexes.size());
dependentOldAverage.resize(dependentIndexes.size());
// Load the percent and parameter lists
//realList MCA_percents;
//keywordList MCA_Params;
keywordList *paramList = &(keywordListData["MCA_Params"]);
MCA_Params.resize( paramList->size() );
for ( unsigned int i = 0; i < paramList->size(); i++ ) {
MCA_Params[i] = paramList->at(i);
}
realList *percentList = &(realListData["MCA_percents"]);
MCA_percents.resize(percentList->size());
for ( unsigned int i = 0; i < percentList->size(); i++ ) {
MCA_percents[i] = percentList->at(i);
}
}
//Average the data over the sample size
void fileIO::MCA_AverageData() {
//Calculate Means
for(unsigned int i = 0; i < stateAverage.size(); i++) {
stateAverage[i] /= sample_size;
}
for(unsigned int i = 0; i < derivativeAverage.size(); i++) {
derivativeAverage[i] /= sample_size;
}
for(unsigned int i = 0; i < dependentAverage.size(); i++) {
dependentAverage[i] /= sample_size;
}
//Reset sample size
sample_size = 0;
}
void fileIO::MCA_Analyze(Model* model, int param, int percent) {
//Is this not the first trail of this parameter?
if( percent != 0 ) {
//Perform the MCA analysis and output
double inv_flux = 1.0 / ( log(MCA_percent)-log(MCA_percent_old) );
//Ouput header info stuff including sample size
int n = sample_size;
//Average the current data set
MCA_AverageData();
//Ouput data
if(writestates) {
outStates << n;
outStates << separator << MCA_Params[param].c_str();
outStates << separator << MCA_percents[percent];
cout << "writestates " << stateAverage.size() << endl;
for ( unsigned int i = 0; i < stateAverage.size(); i++) {
outStates << separator << ( log(stateAverage[i]) - log(stateOldAverage[i]) ) * inv_flux ;
}
outStates << endl;
}
if(writeDerivatives) {
outDerivatives << n;
outDerivatives << separator << MCA_Params[param].c_str();
outDerivatives << separator << MCA_percents[percent];
for ( unsigned int i = 0; i < derivativeAverage.size(); i++) {
outDerivatives << separator << ( log(derivativeAverage[i]) - log(derivativeOldAverage[i]) ) * inv_flux ;
}
outDerivatives << endl;
}
if(writeDependent) {
outCurrents << n;
outCurrents << separator << MCA_Params[param].c_str();
outCurrents << separator << MCA_percents[percent];
for ( unsigned int i = 0; i < dependentAverage.size(); i++) {
outCurrents << separator << ( log(dependentAverage[i]) - log(dependentOldAverage[i]) ) * inv_flux ;
}
outCurrents << endl;
}
} else {
MCA_AverageData();
if (param != 0) {
if(writestates)
outStates << endl;
if(writeDependent)
outCurrents << endl;
if(writeDerivatives)
outDerivatives << endl;
}
}
//Update Old average and reset average
MCA_percent_old = MCA_percent;
for ( unsigned int i = 0; i < stateAverage.size(); i++) {
stateOldAverage[i] = stateAverage[i];
stateAverage[i] = 0;
}
for ( unsigned int i = 0; i < derivativeAverage.size(); i++) {
derivativeOldAverage[i] = derivativeAverage[i];
derivativeAverage[i] = 0;
}
for ( unsigned int i = 0; i < dependentAverage.size(); i++) {
dependentOldAverage[i] = dependentAverage[i];
dependentAverage[i] = 0;
}
//Reset parameters from saved data
model->setParamater(MCA_Params[param].c_str(), MCA_param_value );
}
int fileIO::MCA_GetNumberOfParameters() { return MCA_Params.size(); }
int fileIO::MCA_GetNumberOfPercents() { return MCA_percents.size(); }
void fileIO::MCA_Update(Model* model, int param, int percent) {
// Determine the percentage change
MCA_percent = (100.0+MCA_percents[percent])/100.0;
//Find the default value
MCA_param_value = getReal(MCA_Params[param].c_str());
//Update the model with a modified parameter
model->setParamater(MCA_Params[param].c_str(), MCA_percent * MCA_param_value );
}
bool fileIO::MCA_isEnabled() { return outputMode == MCA; }