|
'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 <iomanip> 00009 #include "options.h" 00010 #include "bitefm.h" 00011 #include "util.h" 00012 #include "mpi_utils.h" 00013 00014 00015 BitEfm::BitEfm() { 00016 00017 } 00028 int BitEfm::load_efm_bit(string efm_bit_fname, t_UnsignedInt num_ems, vector< vector<double> > &stoich) { 00029 00030 ifstream fp_in; // file for reading 00031 int nump=1,proc_id=0; 00032 util::get_proc_id_nump(proc_id,nump); 00033 00034 this->efm_bit_fname=util::trim(efm_bit_fname); 00035 this->num_ems=num_ems; 00036 this->stoich=stoich; 00037 this->num_reacs=stoich[0].size(); 00038 this->stoich.resize(stoich.size(),vector<double>(stoich[0].size(),0)); 00039 for (int i=0;i<stoich.size();i++) 00040 for (int j=0;j<stoich[0].size();j++) 00041 this->stoich[i][j]=stoich[i][j]; 00042 00043 00044 //initialization finished 00045 00046 //load bit efm matrix into buffer 00047 if (efm_bit_fname=="") { 00048 00049 return 0; 00050 } 00051 00052 long file_length; 00053 if (proc_id==0) { 00054 fp_in.open(efm_bit_fname.c_str(), ios::in|ios::binary); 00055 00056 if (fp_in.fail()) { 00057 cerr << endl << " unable to open file "<<efm_bit_fname<<"for reading" << endl; 00058 this->num_ems=0; 00059 return 0; 00060 } 00061 00062 // get length of file: 00063 fp_in.seekg (0, ios::end); 00064 this->file_length = fp_in.tellg(); 00065 file_length=this->file_length; 00066 fp_in.seekg (0, ios::beg); 00067 //this->bytes_per_efm=this->file_length/this->num_ems; 00068 00069 //load entire bit compressed matrix 00070 // allocate memory: 00071 this->buffer = new char [this->file_length]; 00072 00073 // read data as a block: 00074 fp_in.read(this->buffer,this->file_length); 00075 fp_in.close(); 00076 } 00077 mpi_bcast_scalar(file_length); 00078 00079 this->bytes_per_efm=file_length/this->num_ems; 00080 /* 00081 #ifdef PARALLEL 00082 MPI_Bcast(&file_length,1,MPI_LONG,0,MPI_COMM_WORLD); 00083 #endif 00084 00085 this->bytes_per_efm=file_length/this->num_ems; 00086 */ 00087 if (proc_id!=0) 00088 this->buffer=new char[file_length]; 00089 00090 #ifdef PARALLEL 00091 MPI_Bcast(this->buffer,file_length,MPI_CHAR,0,MPI_COMM_WORLD); 00092 #endif 00093 00094 if (proc_id==0) { 00095 cout << endl << "\t"<<util::get_time_str()<<": loaded bit efm matrix."<<endl; 00096 cout << endl << "\t"<<util::get_time_str()<<": num modes."<<this->num_ems; 00097 } 00098 return 0; 00099 } 00112 int BitEfm::fast_is_fes(vector<long> &ineff_efm_indices, set<int> &reacs) { 00113 vector<unsigned char> reac_map; 00114 reac_map.resize((this->num_reacs/8)+1,0); 00115 for (set<int>::iterator sit=reacs.begin();sit!=reacs.end();sit++) { 00116 reac_map[(*sit)/8]|= 1<<((*sit)%8); 00117 } 00118 for (vector<long>::iterator it=ineff_efm_indices.begin();it!=ineff_efm_indices.end();it++) { 00119 int contained=1; 00120 for (int i=0;i<this->bytes_per_efm;i++) { 00121 //is this->buffer[(*it)*this->bytes_per_efm+i] equal to this->buffer[index*this->bytes_per_efm+i] || reac_map[i] 00122 unsigned char w=this->buffer[(*it)*this->bytes_per_efm+i]; 00123 if (reac_map[i] != (w | reac_map[i])) { 00124 contained=0; 00125 break; 00126 } 00127 } 00128 // 00129 if (contained) 00130 return 0; 00131 00132 } 00133 return 1; 00134 00135 } 00136 00147 int BitEfm::is_efm_elem_zero(unsigned long efm_index, int reac, int &is_zero) { 00148 00149 00150 unsigned char w=this->buffer[efm_index*this->bytes_per_efm+reac/8]; 00151 unsigned char mask=1<<(reac%8); 00152 if (mask & w) 00153 is_zero=0; 00154 else 00155 is_zero=1; 00156 00157 return 0; 00158 00159 } 00160 00170 int BitEfm::read_single_efm(unsigned long efm_index, vector<double> &efm) { 00171 00172 vector<int> indices; 00173 indices.resize(this->stoich[0].size(),0); 00174 00175 int num_nnz=0; 00176 for(int j=0;j<stoich[0].size()/8+1;j++){ 00177 //indices((j-1)*8+1:j*8)=bitget(results.bit_ems(em_no(i)*bytes_per_em+j),1:8); 00178 //explore byte buffer[index*this->bytes_per_em+j] 00179 unsigned char w=buffer[efm_index*this->bytes_per_efm+j]; 00180 unsigned char mask=1; 00181 for (int i=0;i<8 && j*8+i<stoich[0].size();i++) { 00182 if (mask & w) { 00183 indices[j*8+i]=1; 00184 num_nnz++; 00185 } 00186 mask<<=1; 00187 } 00188 } 00189 //find kernel of the matrix 00190 vector< vector<double> > nnz_cols; 00191 nnz_cols.resize(stoich.size(),vector<double>(num_nnz)); 00192 for (int i=0;i<this->stoich.size();i++) { 00193 int k=0; 00194 for (int j=0;j<this->stoich[0].size();j++) 00195 if (indices[j]) { 00196 nnz_cols[i][k++]=this->stoich[i][j]; 00197 } 00198 } 00199 00200 00201 vector< vector<double> > nsp; 00202 util::right_nullspace_nonint(nnz_cols, nsp); 00203 00204 efm.resize(this->num_reacs,0); 00205 for (int i=0;i<this->num_reacs;i++) 00206 efm[i]=0; 00207 if (nsp.size()==1) { 00208 00209 00210 for (int i=0,k=0;i<efm.size();i++) 00211 if (indices[i]) 00212 efm[i]=nsp[0][k++]; 00213 } else { 00214 cerr << endl <<"error: nullity equal to "<<nsp.size(); 00215 //exit(1); 00216 } 00217 return 0; 00218 00219 00220 } 00221 int BitEfm::print_efm(unsigned long index, vector<string> &reacs_names) { 00222 vector<double> efm; 00223 read_single_efm(index, efm); 00224 //vector<string> reacs_names=this->metab_network->get_reacs_names(); 00225 for (int i=0;i<efm.size();i++) 00226 cout << " "<<setprecision(2)<<efm[i]<<" "<<reacs_names[i]; 00227 } 00228 00229 int BitEfm::get_num_reacs() { 00230 return this->num_reacs; 00231 } 00232 t_UnsignedInt BitEfm::get_num_modes() { 00233 return this->num_ems; 00234 } 00235 00236 00247 int BitEfm::retain_efm(vector<long> efm_indices2retain, vector< vector<double> > &yields) { 00248 00249 char* new_buffer; 00250 00251 //this->bytes_per_efm=this->file_length/this->num_ems; 00252 new_buffer=new char[(efm_indices2retain.size())*this->bytes_per_efm]; 00253 00254 vector< vector<double> > new_yields; 00255 new_yields.resize(yields.size(), vector<double>((efm_indices2retain.size()),0)); 00256 00257 00258 //scan efms to find 00259 unsigned long k=0; 00260 //for (long i=0;i<this->num_ems;i++) { 00261 for (vector<long>::iterator it=efm_indices2retain.begin();it!=efm_indices2retain.end();it++) { 00262 00263 //if i is not found put in efm_indices 00264 for (int j=0;j<this->bytes_per_efm;j++) 00265 new_buffer[k*this->bytes_per_efm+j]=this->buffer[(*it)*this->bytes_per_efm+j]; 00266 for (int j=0;j<yields.size();j++) 00267 new_yields[j][k]=yields[j][(*it)]; 00268 k++; 00269 } 00270 delete [] this->buffer; 00271 this->buffer=new_buffer; 00272 for (int j=0;j<yields.size();j++) 00273 yields[j].assign(new_yields[j].begin(),new_yields[j].end()); 00274 00275 this->num_ems=efm_indices2retain.size(); 00276 00277 return 0; 00278 } 00279 00290 int BitEfm::remove_efm(vector<long> efm_indices2remove, vector< vector<double> > &yields) { 00291 00292 char* new_buffer; 00293 00294 //this->bytes_per_efm=this->file_length/this->num_ems; 00295 new_buffer=new char[(this->num_ems-efm_indices2remove.size())*this->bytes_per_efm]; 00296 vector< vector<double> > new_yields; 00297 new_yields.resize(yields.size(), vector<double>((this->num_ems-efm_indices2remove.size()),0)); 00298 00299 //scan efms to find 00300 unsigned long k=0; 00301 for (long i=0;i<this->num_ems;i++) { 00302 //is i in efm_indices2remove 00303 vector<long>::iterator p=find(efm_indices2remove.begin(),efm_indices2remove.end(),i); 00304 //if i is not found put in efm_indices 00305 if (p==efm_indices2remove.end()) { 00306 for (int j=0;j<this->bytes_per_efm;j++) 00307 new_buffer[k*this->bytes_per_efm+j]=this->buffer[i*this->bytes_per_efm+j]; 00308 00309 for (int j=0;j<yields.size();j++) 00310 new_yields[j][k]=yields[j][i]; 00311 k++; 00312 00313 } 00314 00315 } 00316 for (int j=0;j<yields.size();j++) 00317 yields[j].assign(new_yields[j].begin(),new_yields[j].end()); 00318 00319 delete [] this->buffer; 00320 this->buffer=new_buffer; 00321 this->num_ems=this->num_ems-efm_indices2remove.size(); 00322 00323 } 00324 00336 int BitEfm::knock_efms(map<string,int> knock_reacs, vector< vector<double> > &yields) { 00337 00338 //vector< vector<double> > &efms=efms(); 00339 00340 //for reaction p->second remove elementary modes which have non-zero value in respective row 00341 vector<long> indices2remove; 00342 //vector<double> efm; 00343 //efm.resize(this->num_reacs); 00344 /* 00345 for (long i=0;i<this->num_ems;i++) { 00346 //read_single_efm(i,efm); 00347 if (i%1000==0) 00348 cout << endl<<"\t examining index i :"<<i; 00349 map<string,int>::iterator p; 00350 for (p=knock_reacs.begin();p!=knock_reacs.end();p++) { 00351 00352 int is_zero; 00353 is_efm_elem_zero(i,p->second, is_zero); 00354 if (!is_zero) { 00355 //if (efm[p->second]!=0) { 00356 indices2remove.push_back(i); 00357 break; 00358 } 00359 } 00360 } 00361 00362 00363 remove_efm(indices2remove); 00364 */ 00365 00366 vector<long> indices2retain; 00367 00368 for (long i=0;i<this->num_ems;i++) { 00369 map<string,int>::iterator p; 00370 int all_zero=1; 00371 for (p=knock_reacs.begin();p!=knock_reacs.end();p++) { 00372 int is_zero; 00373 is_efm_elem_zero(i,p->second, is_zero); 00374 if (!is_zero) { 00375 all_zero=0; 00376 break; 00377 } 00378 } 00379 if (all_zero) 00380 indices2retain.push_back(i); 00381 } 00382 00383 retain_efm(indices2retain, yields); 00384 00385 return 0; 00386 }