|
'ElMo-Knock'
|
00001 #include <iostream> 00002 #include <fstream> // file I/O 00003 #include <sstream> 00004 #include <stdlib.h> 00005 #include <vector> 00006 #include <algorithm> 00007 #include <math.h> 00008 #include <sys/types.h> 00009 #include <iomanip> 00010 #include "options.h" 00011 #include "util.h" 00012 #include "mpi_utils.h" 00013 00014 00015 string trimlr(const string &t) 00016 { 00017 string str = t; 00018 size_t found; 00019 found = str.find_last_not_of(" \t"); 00020 if (found != string::npos) 00021 str.erase(found+1); 00022 else 00023 str.clear(); // str is all whitespace 00024 00025 return str; 00026 } 00027 00028 Options::Options(string config_fname) { 00029 00030 this->config_fname=config_fname; 00031 00032 } 00033 void Options::load(string config_fname) { 00034 00035 00036 00037 ifstream fp_in; // file for reading 00038 int num_lines=0; 00039 string line; 00040 int nump=1, proc_id=0; 00041 string ko_fname; 00042 00043 00044 util::get_proc_id_nump(proc_id,nump); 00045 00046 this->config_fname=config_fname; 00047 00048 //parse the config_fname file 00049 //open config_fname 00050 00051 //parse each line in file to reaad metatool_fname, targets, substrates, yields, core_yields, init knocks 00052 //load efm from matrix (initialize num_mods, num_reacs, efms 00053 00054 if (proc_id==0) { 00055 fp_in.open(this->config_fname.c_str(), ios::in); 00056 if (fp_in.fail()) { 00057 cerr << endl << " unable to open file "<<this->config_fname<<"for reading" << endl; 00058 exit(1); 00059 } 00060 00061 while(!getline(fp_in, line, '\n').eof()) { 00062 00063 //parse line to read left and right side from : character 00064 vector<string> result; 00065 //skip comments 00066 line=util::trim(line); 00067 if (line.at(0)=='#') 00068 continue; 00069 00070 parse_string(line, ':', result); 00071 if (result.size()!=2) 00072 continue; 00073 string lhs,rhs; 00074 lhs=result[0]; rhs=result[1]; 00075 00076 std::stringstream trimmer; 00077 trimmer << lhs; 00078 lhs.clear(); 00079 trimmer >> lhs; 00080 00081 rhs=util::trim(rhs); 00082 00083 if (!lhs.compare("algorithm")) { 00084 if (rhs.compare("direct")!=0 && rhs.compare("indirect")!=0) { 00085 cout << endl << "\t"<<util::get_time_str()<<": algorithm (direct, indirect) is incorrectly specified in config file "<< config_fname<<endl<<endl; 00086 exit(1); 00087 } 00088 this->algorithm=rhs; 00089 } 00090 00091 if (!lhs.compare("network_capacity")) { 00092 if (rhs.compare("low")!=0 && rhs.compare("high")!=0 ) { 00093 cout << endl << "\t"<<util::get_time_str()<<": network_capacity (low, high) is incorrectly specified in config file "<< config_fname<<endl<<endl; 00094 exit(1); 00095 } 00096 this->network_capacity=rhs; 00097 } 00098 00099 if (!lhs.compare("efm_compressed_file")) { 00100 00101 this->efm_bit_fname=rhs; 00102 } 00103 if (!lhs.compare("efm_meta_file")) { 00104 00105 this->efm_meta_fname=rhs; 00106 bool ret_val=util::file_exists(this->efm_meta_fname); 00107 if (ret_val==false) { 00108 cout << endl << "\t"<<util::get_time_str()<<": meta file '"<< this->efm_meta_fname<<"' does not exist"<<endl<<endl; 00109 exit(1); 00110 } 00111 00112 } 00113 if (!lhs.compare("use_xchg_reacs")) { 00114 if (util::strcmp_ignore_case(rhs,"yes")==false && util::strcmp_ignore_case(rhs,"no")==false) { 00115 cout << endl << "\t"<<util::get_time_str()<<": 'use of exchange reactions' field value is incorrect. yes/no required "<< config_fname<<endl<<endl; 00116 exit(1); 00117 } 00118 this->use_xchg_reacs=rhs; 00119 } 00120 00121 if (!lhs.compare("output_file")) { 00122 00123 this->output_fname=rhs; 00124 } 00125 00126 if (!lhs.compare("max_efm_cands")) { 00127 00128 int max_efm_cands; 00129 stringstream ss; 00130 ss << rhs; 00131 ss >> max_efm_cands; 00132 this->max_efm_cands=max_efm_cands; 00133 } 00134 00135 if (!lhs.compare("max_rk_cands")) { 00136 int max_rk_cands; 00137 stringstream ss; 00138 ss << rhs; 00139 ss >> max_rk_cands; 00140 this->max_rk_cands=max_rk_cands; 00141 } 00142 if (!lhs.compare("max_reaction_knockout_subset_length")) { 00143 int max_reac_subset_length; 00144 stringstream ss; 00145 ss << rhs; 00146 ss >> max_reac_subset_length; 00147 this->max_reac_subset_length=max_reac_subset_length; 00148 } 00149 00150 if (!lhs.compare("init_knocks")) { 00151 //parse rhs 00152 parse_string(rhs, ' ', this->init_knock_reacs); 00153 } 00154 00155 if (!lhs.compare("substrates")) { 00156 //parse rhs 00157 parse_string(rhs, ' ', this->substrate_reacs); 00158 } 00159 00160 if (!lhs.compare("targets")) { 00161 //parse rhs 00162 parse_string(rhs, ' ', this->target_reacs); 00163 } 00164 00165 if (!lhs.compare("growth_eff_min_yield")) { 00166 //parse rhs 00167 vector<string> yields_str; 00168 parse_string(rhs, ' ', yields_str); 00169 00170 for (vector<string>::iterator it=yields_str.begin();it!=yields_str.end();it++) { 00171 string s_tmp=trimlr(*it); 00172 if (s_tmp.size()==0) 00173 continue; 00174 00175 double dd; 00176 stringstream ss; 00177 ss << *it; 00178 ss >> dd; 00179 this->min_yields.push_back(dd); 00180 00181 } 00182 } 00183 00184 if (!lhs.compare("transport_reacs")) { 00185 parse_string(rhs, ' ', this->transport_reacs); 00186 00187 } 00188 if (!lhs.compare("production_eff_min_yield")) { 00189 //parse rhs 00190 vector<string> yields_str; 00191 parse_string(rhs, ' ', yields_str); 00192 00193 for (vector<string>::iterator it=yields_str.begin();it!=yields_str.end();it++) { 00194 string s_tmp=trimlr(*it); 00195 if (s_tmp.size()==0) 00196 continue; 00197 00198 double dd; 00199 stringstream ss; 00200 ss << *it; 00201 ss >> dd; 00202 this->min_core_yields.push_back(dd); 00203 00204 } 00205 } 00206 00207 if (!lhs.compare("yields_file")) { 00208 00209 this->yields_fname=rhs; 00210 } 00211 00212 } 00213 00214 fp_in.close(); 00215 00216 } 00217 00218 mpi_bcast_string(this->algorithm); 00219 mpi_bcast_string(this->network_capacity); 00220 00221 mpi_bcast_string(this->efm_bit_fname); 00222 mpi_bcast_string(this->efm_meta_fname); 00223 00224 mpi_bcast_string(this->use_xchg_reacs); 00225 mpi_bcast_string(this->output_fname); 00226 mpi_bcast_scalar(this->max_efm_cands); 00227 00228 mpi_bcast_scalar(this->max_rk_cands); 00229 00230 mpi_bcast_vector_of_strings(this->init_knock_reacs) ; 00231 mpi_bcast_vector_of_strings(this->substrate_reacs); 00232 mpi_bcast_vector_of_strings(this->target_reacs); 00233 mpi_bcast_vector(this->min_yields); 00234 mpi_bcast_vector_of_strings(this->transport_reacs); 00235 mpi_bcast_string(this->yields_fname); 00236 mpi_bcast_vector(this->min_core_yields); 00237 00238 //broadcast 00239 //close config_fname 00240 //check consistency 00241 //test 1: length of arrays min_core_yields, min_yields, targets has to be same. value also has to be >0 and <num_reacs 00242 00243 //test 2: min_core_yield and min_yields has to be (0,1] 00244 00245 //test 3: use_xchg_reacs has to be yes/no and case insensitive 00246 00247 //test 4: meta file has to be given and it has to exist (be able to open it) 00248 00249 //test 5: at least one of two files has to be given with valid path: efm_full_fname, efm_bit_fname 00250 00251 } 00252 00253 00254 void Options::print() { 00255 00256 cout << "\t\t options" << endl; 00257 00258 cout << "\talgorithm: "<<this->algorithm<<endl; 00259 00260 cout << "\tnetwork_capacity: "<<this->network_capacity<<endl; 00261 00262 00263 cout << "\tEFM compressed file name:"<<this->efm_bit_fname<<endl; 00264 cout << "\tEFM meta file name:"<<this->efm_meta_fname<<endl; 00265 cout << "\tyields file: "<<this->yields_fname<< endl; 00266 cout << "\tinitial reaction knockouts: "; 00267 for (vector<string>::iterator it=this->init_knock_reacs.begin(); it!=this->init_knock_reacs.end();it++) 00268 cout << *it <<" "; 00269 cout <<endl; 00270 cout << "\tsubstrate reactions: "; 00271 for (vector<string>::iterator it=this->substrate_reacs.begin(); it!=this->substrate_reacs.end();it++) 00272 cout << *it <<" "; 00273 cout <<endl; 00274 cout << "\ttarget reactions: "; 00275 for (vector<string>::iterator it=this->target_reacs.begin(); it!=this->target_reacs.end();it++) 00276 cout << *it <<" "; 00277 cout <<endl; 00278 cout << "\ttransport reactions: "; 00279 for (vector<string>::iterator it=this->transport_reacs.begin(); it!=this->transport_reacs.end();it++) 00280 cout << *it <<" "; 00281 cout <<endl; 00282 00283 cout << endl<<"\tmax efm candidates:"<<this->max_efm_cands; 00284 cout << endl<<"\tmax erk candidates:"<<this->max_rk_cands; 00285 cout << endl<<"\tmax reaction subset length:"<<this->max_reac_subset_length; 00286 00287 cout << endl<< "\tminimum growth-efficient mode yields [0-1]: "; 00288 for (vector<double>::iterator it=this->min_yields.begin(); it!=this->min_yields.end();it++) 00289 cout << *it <<" "; 00290 cout <<endl; 00291 cout << endl<< "\tminimum production-efficient mode yields [0-1]: "; 00292 for (vector<double>::iterator it=this->min_core_yields.begin(); it!=this->min_core_yields.end();it++) 00293 cout << *it <<" "; 00294 cout <<endl; 00295 cout << "\tuse exchange reactions in knockout subset enumeration: "<<this->use_xchg_reacs <<endl; 00296 cout << "\toutput file: "<<this->output_fname<< endl; 00297 //cout << "\tbit-compressed EFM files: "<<this->ems_bit_fname<< "/"<<this->ems_bit_meta_fname<<endl; 00298 00299 } 00300 void parse_string( const string& str, const char separator, vector<string>& result ) { 00301 00302 if( str.size() ) { 00303 string::const_iterator last = str.begin(); 00304 for( string::const_iterator i=str.begin(); i!=str.end(); ++i ) { 00305 if( *i == separator ) { 00306 const string str_tmp(last,i); 00307 //string token = str_tmp; 00308 result.push_back(str_tmp); 00309 last = i; 00310 ++ last; 00311 } 00312 } 00313 if( last != str.end() ) 00314 result.push_back(&*last); 00315 } 00316 } 00317 00318 void Options::load_efm_meta_file(vector< vector<double> > &stoich, vector<string> &reacs_names, t_UnsignedInt &num_ems) { 00319 00320 00321 ifstream fp_in; // file for reading 00322 00323 int num_lines=0, num_metabs,num_reacs; 00324 00325 int proc_id=0,nump=1; 00326 util::get_proc_id_nump(proc_id,nump); 00327 00328 string line; 00329 00330 num_ems=0; 00331 00332 if (proc_id==0) { 00333 00334 fp_in.open(this->efm_meta_fname.c_str(), ios::in); 00335 00336 if (fp_in.fail()) { 00337 cerr << endl << " unable to open file "<<this->efm_meta_fname<<" for reading" << endl; 00338 return; 00339 } 00340 00341 while(!getline(fp_in, line, '\n').eof()) { 00342 00343 if (num_lines==0) { 00344 00345 vector<string> words; 00346 parse_string(line, ' ', words); 00347 num_metabs=atoi(words[0].c_str()); 00348 num_reacs=atoi(words[1].c_str()); 00349 stoich.resize(atoi(words[0].c_str()),vector<double>(atoi(words[1].c_str()))); 00350 num_ems=atol(words[2].c_str()); //numems 00351 } 00352 00353 00354 if (num_lines>0 && num_lines<=stoich.size()) { 00355 00356 //parse line 00357 vector<string> words; 00358 00359 parse_string(line, ' ', words); 00360 for (int i=0;i<words.size();i++) { 00361 double val=atof(words[i].c_str()); 00362 stoich[num_lines-1][i]=val; 00363 } 00364 } 00365 00366 if (num_lines>stoich.size()) { 00367 00368 vector<string> words; 00369 00370 parse_string(line, ' ', words); 00371 for (int i=0;i<words.size();i++) { 00372 reacs_names.push_back(words[i]); 00373 } 00374 00375 } 00376 num_lines++; 00377 00378 00379 } 00380 fp_in.close(); 00381 cout << endl << "\t"<<util::get_time_str()<<": Loaded EFM meta file..."<<endl; 00382 } 00383 mpi_bcast_scalar(num_ems) ; 00384 mpi_bcast_scalar(num_metabs); 00385 mpi_bcast_scalar(num_reacs); 00386 00387 mpi_bcast_vector_of_strings(reacs_names); 00388 mpi_bcast_matrix(stoich); 00389 00390 } 00391 00392 /* 00393 ostream& operator<<(ostream& out, const Options& option){ 00394 00395 Options opt=option; 00396 out << "\t\t options" << endl; 00397 out << "\tMETATOOL file name: "<<opt.metatool_fname<<endl; 00398 out << "\tEFM file name:"<<opt.efm_fname<<endl; 00399 out << "\tinit reaction knockouts: "; 00400 for (vector<string>::iterator it=opt.init_knock_reacs.begin(); it!=opt.init_knock_reacs.end();it++) 00401 out << *it <<" "; 00402 out <<endl; 00403 out << "\tsubstrate reactions: "; 00404 for (vector<string>::iterator it=opt.substrate_reacs.begin(); it!=opt.substrate_reacs.end();it++) 00405 out << *it <<" "; 00406 out <<endl; 00407 out << "\ttarget reactions: "; 00408 for (vector<string>::iterator it=opt.target_reacs.begin(); it!=opt.target_reacs.end();it++) 00409 out << *it <<" "; 00410 out <<endl; 00411 out << "\ttransport reactions: "; 00412 for (vector<string>::iterator it=opt.transport_reacs.begin(); it!=opt.transport_reacs.end();it++) 00413 out << *it <<" "; 00414 out <<endl; 00415 //max_efm_cands,max_rk_cands_l1,max_rk_cands_l2,l1_height; 00416 out << endl<<"\tmax efm candidates:"<<opt.max_efm_cands; 00417 out << endl<<"\tmax erk candidaates (level 1):"<<opt.max_rk_cands_l1; 00418 out << endl<<"\tmax erk candidaates (level 2):"<<opt.max_rk_cands_l2; 00419 out << endl<<"\theight (level 1):"<<opt.l1_height<<endl; 00420 00421 out << "\tyields: "; 00422 for (vector<double>::iterator it=opt.min_yields.begin(); it!=opt.min_yields.end();it++) 00423 out << *it <<" "; 00424 out <<endl; 00425 out << "\tcore yields: "; 00426 for (vector<double>::iterator it=opt.min_core_yields.begin(); it!=opt.min_core_yields.end();it++) 00427 out << *it <<" "; 00428 out <<endl; 00429 out << "\tuse exchange reactionsin knockout: "<<opt.use_xchg_reacs <<endl; 00430 out << "\toutput file: "<<opt.output_fname<< endl; 00431 out << "\tbit-compressed EFM files: "<<opt.ems_bit_fname<< "/"<<opt.ems_bit_meta_fname<<endl; 00432 return out; 00433 00434 } 00435 */ 00436 00437 void Options::print_to_file(ostream &out) { 00438 out << "PROGRAM OPTIONS" << endl; 00439 00440 out << "\talgorithm: "<<this->algorithm<<endl; 00441 if (this->algorithm.compare("direct")==0) { 00442 out << "\tnetwork_capacity: "<<this->network_capacity<<endl; 00443 } 00444 00445 //out << "\tEFM expanded file name:"<<this->efm_full_fname<<endl;; 00446 out << "\tEFM compressed file name:"<<this->efm_bit_fname<<endl; 00447 out << "\tEFM meta file name:"<<this->efm_meta_fname<<endl; 00448 out << "\tyields file: "<<this->yields_fname<< endl; 00449 out << "\tinitial reaction knockouts: "; 00450 for (vector<string>::iterator it=this->init_knock_reacs.begin(); it!=this->init_knock_reacs.end();it++) 00451 out << *it <<" "; 00452 out <<endl; 00453 out << "\tsubstrate reactions: "; 00454 for (vector<string>::iterator it=this->substrate_reacs.begin(); it!=this->substrate_reacs.end();it++) 00455 out << *it <<" "; 00456 out <<endl; 00457 out << "\ttarget reactions: "; 00458 for (vector<string>::iterator it=this->target_reacs.begin(); it!=this->target_reacs.end();it++) 00459 out << *it <<" "; 00460 out <<endl; 00461 out << "\ttransport reactions: "; 00462 for (vector<string>::iterator it=this->transport_reacs.begin(); it!=this->transport_reacs.end();it++) 00463 out << *it <<" "; 00464 00465 00466 out << endl<<"\tmax efm candidates:"<<this->max_efm_cands; 00467 out << endl<<"\tmax erk candidates:"<<this->max_rk_cands; 00468 out << endl<<"\tmax reaction subset length:"<<this->max_reac_subset_length; 00469 00470 out << endl<<endl<<"\tminimum growth-efficient mode yields [0-1]: "; 00471 for (vector<double>::iterator it=this->min_yields.begin(); it!=this->min_yields.end();it++) 00472 out << *it <<" "; 00473 out <<endl; 00474 out << "\tminimum production-efficient mode yields [0-1]: "; 00475 for (vector<double>::iterator it=this->min_core_yields.begin(); it!=this->min_core_yields.end();it++) 00476 out << *it <<" "; 00477 out <<endl; 00478 out << "\tuse exchange reactions in knockout subset enumeration: "<<this->use_xchg_reacs <<endl; 00479 out << "\toutput file: "<<this->output_fname<< endl; 00480 00481 00482 out << endl; 00483 00484 } 00485 00486 00487 00488