|
'ElMo-Knock'
|
00001 #include <iostream> 00002 #include <fstream> // file I/O 00003 #include <sstream> 00004 #include <stdlib.h> 00005 #include <iomanip> 00006 #include <algorithm> 00007 #include <deque> 00008 #include <list> 00009 #include <queue> 00010 #include <set> 00011 #include <time.h> 00012 #include <math.h> 00013 #include <assert.h> 00014 #include "enumeffknocks.h" 00015 #include "ufes.h" 00016 #include "rk.h" 00017 #include "util.h" 00018 #include "options.h" 00019 #include "general_hash_functions.h" 00020 using namespace std; 00021 00022 00023 00028 EnumEffKnocks::EnumEffKnocks() {} 00029 00036 EnumEffKnocks::EnumEffKnocks(MetabolicNetwork *metab_network) { 00037 00038 this->metab_network=metab_network; 00039 this->erk_enum_time=0; 00040 this->ufes_enum_time=0; 00041 this->max_rk_length=this->metab_network->get_options().get_max_reac_subset_length(); 00042 00043 } 00044 00053 void EnumEffKnocks::enum_ufes() { 00054 00055 vector<long>& eff_efm_indices=this->metab_network->get_eff_efm_indices(); 00056 long first,last; 00057 00058 00059 int nump=1,proc_id=0; 00060 util::get_proc_id_nump(proc_id,nump); 00061 first=(proc_id)*(eff_efm_indices.size()/nump); 00062 if (proc_id<nump-1) 00063 last= (proc_id+1)*(eff_efm_indices.size()/nump); 00064 else 00065 last= eff_efm_indices.size(); 00066 00067 if (proc_id==0) { 00068 cout << endl << "\t"<<util::get_time_str()<<": # of modes explored: " << this->metab_network->get_num_modes(); 00069 cout << endl << "\t"<<util::get_time_str() <<": enumerating UFES...."; 00070 } 00071 00072 for (long i=first;i<last;i++) { 00073 if (i%50==0 & proc_id==0) 00074 cout << endl <<"\t"<<util::get_time_str() <<": crunching efm index "<<i<<" ...."; 00075 enum_ufes_from_single(i); 00076 } 00077 00078 if (proc_id==0) { 00079 cout << endl << "\t"<<util::get_time_str() << ": # of UFES: "<<this->ufes_map.size(); 00080 //cout << endl << "\t"<<util::get_time_str() << ": # of UFES (hash): "<<this->ufes_hash.size(); 00081 } 00082 00083 } 00091 void EnumEffKnocks::enum_ufes_from_single(long eff_efm_index) { 00092 //enumerate ufes and add to this->ufes_set 00093 00094 double total_time,start,end; 00095 this-> portion_time=0; 00096 queue<UFES> q; 00097 vector<long>& eff_efm_indices=this->metab_network->get_eff_efm_indices(); 00098 00099 util::current_time(&start); 00100 total_time=start; 00101 vector<unsigned char> bit_sets_table256; 00102 00103 bit_sets_table256.resize(256,0); 00104 00105 for (int i=0;i<=255;i++) 00106 for (int j=0,mask=1;j<8;j++) { 00107 bit_sets_table256[i]+=((i & mask)>0); 00108 mask<<=1; 00109 } 00110 00111 //create UFES from single eff_efm_indices[ind] mode 00112 vector<long> sv; 00113 sv.push_back(eff_efm_indices[eff_efm_index]); 00114 UFES s(sv); 00115 //is s FES? if it is not return, else continue; but no need to check this. every single EFM is a FES 00116 00117 //add UFES to q 00118 00119 q.push(s); 00120 00121 //warning! noo point in placing subsets that are not feasible to queue. make sure 00122 00123 while (!q.empty()) { 00124 //fetch UFES from queue 00125 UFES v=q.front(); 00126 q.pop(); 00127 00128 if (v.get_efm_indices().size()==this->max_ufes_length) { 00129 //append v to ufes_set 00130 this->ufes_map[v.get_key()]=v; 00131 //this->ufes_hash[v.get_key().c_str()]=v; 00132 continue; 00133 } 00134 00135 //fetch index of last element in v 00136 vector<long> curr_efm_indices=v.get_efm_indices(); 00137 00138 vector<long>::reverse_iterator ri=curr_efm_indices.rbegin(); 00139 long last_efm_index=*ri;//curr_efm_indices[curr_efm_indices.size()-1]; 00140 00141 //vector<long>::iterator qi=find(eff_efm_indices.begin(),eff_efm_indices.end(), last_efm_index); 00142 vector<long>::iterator qi=lower_bound(eff_efm_indices.begin(),eff_efm_indices.end(), last_efm_index); 00143 long range_start=qi-(eff_efm_indices.begin()); 00144 range_start++; 00145 long range_end=eff_efm_indices.end()-eff_efm_indices.begin(); 00146 00147 //rank modes in array this->eff_efm_indices[last_efm_index+1 ... this->eff_efm_indices->size()-1] 00148 00149 curr_efm_indices.push_back(0); //add an extra element 00150 00151 multimap<int,long> ranked_efms; //ranked modes, where key is equal to rank, and value to index of the mode 00152 00153 compute_ranks_vector_bitwise(v, range_start, range_end, ranked_efms,bit_sets_table256); 00154 //util::current_time(&end); 00155 //portion_time+=end; 00156 int k=0; 00157 int not_expanding=1; 00158 00159 int curr_max_efm_cands=this->metab_network->get_options().get_max_efm_cands(); 00160 00161 int curr_ufes_length=curr_efm_indices.size(); 00162 if ((curr_max_efm_cands>>curr_ufes_length)>=1) 00163 curr_max_efm_cands>>=curr_ufes_length; 00164 else 00165 curr_max_efm_cands=1; 00166 00167 00168 for (multimap<int,long>::iterator mi=ranked_efms.begin();mi!=ranked_efms.end() && k<curr_max_efm_cands; mi++,k++) { 00169 curr_efm_indices[curr_efm_indices.size()-1]=mi->second; 00170 if (!is_fes(curr_efm_indices)) 00171 continue; 00172 not_expanding=0; 00173 UFES v_new(curr_efm_indices); 00174 q.push(v_new); 00175 } 00176 if (not_expanding) { 00177 this->ufes_map[v.get_key()]=v; 00178 //this->ufes_hash[v.get_key().c_str()]=v; 00179 } 00180 00181 } 00182 00183 util::current_time(&end); 00184 total_time=end-total_time; 00185 //cout << endl <<"\t total_time, portion_time: "<<total_time<<","<<this->portion_time; 00186 } 00187 00194 int EnumEffKnocks::communicate_ufes_map() { 00195 00196 //serialize this->ufes_map into vector<long>. keep two datastructures. ufes_map_srl, ufes_map_srl_lengths 00197 00198 00199 vector<unsigned long> ufes_cnts; 00200 unsigned long local_ufes_cnt=this->ufes_map.size(); 00201 //unsigned long local_ufes_cnt=this->ufes_hash.size(); 00202 00203 int nump=1,proc_id=0; 00204 #ifdef PARALLEL 00205 util::get_proc_id_nump(proc_id,nump); 00206 00207 //communicate size of ufes_map to every compute node 00208 ufes_cnts.resize(nump); 00209 00210 MPI_Allgather(&local_ufes_cnt, 1, MPI_UNSIGNED_LONG, &ufes_cnts[0], 1, MPI_UNSIGNED_LONG, MPI_COMM_WORLD ); 00211 00212 vector<int> rcv_count, rcv_displs; 00213 00214 rcv_count.resize(nump); 00215 rcv_displs.resize(nump); 00216 00217 unsigned long total_ufes_cnt=0; 00218 for (int i=0;i<nump;i++) { 00219 00220 rcv_displs[i]=total_ufes_cnt; 00221 rcv_count[i]=ufes_cnts[i]; 00222 total_ufes_cnt+=ufes_cnts[i]; 00223 00224 } 00225 00226 //allocate array to store the sizes of ufes_map at each compute node 00227 vector<unsigned long> all_ufes_lengths, local_ufes_lengths; 00228 00229 all_ufes_lengths.resize(total_ufes_cnt); 00230 00231 00232 unsigned long total_local_ufes_lengths=0; 00233 00234 for (map<string,UFES>::iterator it=this->ufes_map.begin();it!=this->ufes_map.end();it++) { 00235 UFES u=it->second; 00236 local_ufes_lengths.push_back(u.get_efm_indices().size()); 00237 total_local_ufes_lengths+=u.get_efm_indices().size(); 00238 } 00239 00240 MPI_Allgatherv(&local_ufes_lengths[0],local_ufes_lengths.size(),MPI_UNSIGNED_LONG, &all_ufes_lengths[0], &rcv_count[0], &rcv_displs[0],MPI_UNSIGNED_LONG,MPI_COMM_WORLD); 00241 00242 unsigned long all_ufes_length=0; 00243 for (unsigned long i=0;i<total_ufes_cnt;i++) 00244 all_ufes_length+=all_ufes_lengths[i]; 00245 00246 vector<unsigned long> all_ufes,local_ufes; 00247 all_ufes.resize(all_ufes_length); 00248 local_ufes.resize(total_local_ufes_lengths); 00249 00250 unsigned long k=0; 00251 for (map<string,UFES>::iterator it=this->ufes_map.begin();it!=this->ufes_map.end();it++) { 00252 UFES u=it->second; 00253 vector<long>& efm_indices=u.get_efm_indices(); 00254 for (int j=0;j<efm_indices.size();j++) 00255 local_ufes[k++]=efm_indices[j]; 00256 } 00257 rcv_count.clear(); 00258 rcv_displs.clear(); 00259 rcv_count.resize(nump,0); 00260 rcv_displs.resize(nump,0); 00261 00262 unsigned long curr_index=0, total_length=0; 00263 for (int i=0;i<nump;i++) { 00264 00265 rcv_displs[i]=total_length; 00266 for (unsigned long j=0;j<ufes_cnts[i];j++) { 00267 rcv_count[i]+=all_ufes_lengths[curr_index]; 00268 curr_index++; 00269 } 00270 total_length+=rcv_count[i]; 00271 00272 } 00273 00274 //cout << endl << "\t"<<util::get_time_str() << ": total length: "<<total_length; 00275 //cout << endl << "\t"<<util::get_time_str() << ": total local ufes length: "<<total_local_ufes_lengths; 00276 00277 MPI_Allgatherv(&local_ufes[0],local_ufes.size(),MPI_UNSIGNED_LONG, &all_ufes[0], &rcv_count[0], &rcv_displs[0],MPI_UNSIGNED_LONG,MPI_COMM_WORLD); 00278 00279 //communicate arrays of lengths of ufes_map to each communicate node 00280 curr_index=0; 00281 unsigned long ind_all_ufes=0; 00282 for (int i=0;i<nump;i++) { 00283 for (unsigned long j=0;j<ufes_cnts[i];j++) { 00284 vector<long> ufes_indices; 00285 for (unsigned long k=0;k<all_ufes_lengths[curr_index];k++) 00286 ufes_indices.push_back(all_ufes[ind_all_ufes++]); 00287 00288 UFES q(ufes_indices); 00289 this->ufes_map[q.get_key()]=q; 00290 curr_index++; 00291 } 00292 } 00293 00294 //communicate serialized ufes_map to each compute node 00295 #endif 00296 return 0; 00297 } 00298 00305 int EnumEffKnocks::communicate_erk_map() { 00306 00307 //serialize this->ufes_map into vector<long>. keep two datastructures. ufes_map_srl, ufes_map_srl_lengths 00308 00309 vector<string> reacs_names=this->metab_network->get_reacs_names(); 00310 vector<unsigned long> erk_cnts; 00311 unsigned long local_erk_cnt=this->erk_map.size(); 00312 00313 int nump=1,proc_id=0; 00314 #ifdef PARALLEL 00315 util::get_proc_id_nump(proc_id,nump); 00316 00317 //communicate size of ufes_map to every compute node 00318 erk_cnts.resize(nump); 00319 MPI_Allgather(&local_erk_cnt, 1, MPI_UNSIGNED_LONG, &erk_cnts[0], 1, MPI_UNSIGNED_LONG, MPI_COMM_WORLD ); 00320 00321 vector<int> rcv_count, rcv_displs; 00322 00323 rcv_count.resize(nump); 00324 rcv_displs.resize(nump); 00325 00326 unsigned long total_erk_cnt=0; 00327 for (int i=0;i<nump;i++) { 00328 00329 rcv_displs[i]=total_erk_cnt; 00330 rcv_count[i]=erk_cnts[i]; 00331 total_erk_cnt+=erk_cnts[i]; 00332 00333 } 00334 00335 00336 //allocate array to store the sizes of ufes_map at each compute node 00337 vector<unsigned long> all_erk_lengths, local_erk_lengths; 00338 00339 all_erk_lengths.resize(total_erk_cnt); 00340 00341 00342 unsigned long total_local_erk_lengths=0; 00343 00344 for (map<string,RK>::iterator it=this->erk_map.begin();it!=this->erk_map.end();it++) { 00345 RK u=it->second; 00346 local_erk_lengths.push_back(u.get_knock_reacs().size()); 00347 total_local_erk_lengths+=u.get_knock_reacs().size(); 00348 } 00349 00350 MPI_Allgatherv(&local_erk_lengths[0],local_erk_lengths.size(),MPI_UNSIGNED_LONG, &all_erk_lengths[0], &rcv_count[0], &rcv_displs[0],MPI_UNSIGNED_LONG,MPI_COMM_WORLD); 00351 00352 unsigned long all_erk_length=0; 00353 for (unsigned long i=0;i<total_erk_cnt;i++) 00354 all_erk_length+=all_erk_lengths[i]; 00355 00356 vector<int> all_erk,local_erk; 00357 all_erk.resize(all_erk_length); 00358 local_erk.resize(total_local_erk_lengths); 00359 00360 unsigned long k=0; 00361 for (map<string,RK>::iterator it=this->erk_map.begin();it!=this->erk_map.end();it++) { 00362 RK u=it->second; 00363 map<int,string>& knock_reacs=u.get_knock_reacs(); 00364 for (map<int,string>::iterator mit=knock_reacs.begin();mit!=knock_reacs.end();mit++) 00365 local_erk[k++]=mit->first; 00366 } 00367 00368 rcv_count.clear(); 00369 rcv_displs.clear(); 00370 rcv_count.resize(nump,0); 00371 rcv_displs.resize(nump,0); 00372 00373 unsigned long curr_index=0, total_length=0; 00374 for (int i=0;i<nump;i++) { 00375 00376 rcv_displs[i]=total_length; 00377 for (unsigned long j=0;j<erk_cnts[i];j++) { 00378 rcv_count[i]+=all_erk_lengths[curr_index]; 00379 curr_index++; 00380 } 00381 total_length+=rcv_count[i]; 00382 00383 } 00384 00385 00386 MPI_Allgatherv(&local_erk[0],local_erk.size(),MPI_INT, &all_erk[0], &rcv_count[0],&rcv_displs[0],MPI_INT,MPI_COMM_WORLD); 00387 00388 //communicate arrays of lengths of erk_map to each communicate node 00389 curr_index=0; 00390 00391 unsigned long ind_all_erk=0; 00392 for (int i=0;i<nump;i++) { 00393 for (unsigned long j=0;j<erk_cnts[i];j++) { 00394 00395 map<int,string> knock_reacs; 00396 for (unsigned long k=0;k<all_erk_lengths[curr_index];k++) { 00397 knock_reacs[all_erk[ind_all_erk]]=reacs_names[all_erk[ind_all_erk]]; 00398 ind_all_erk++; 00399 } 00400 RK rk(knock_reacs,this->metab_network); 00401 00402 this->erk_map[rk.get_key()]=rk; 00403 curr_index++; 00404 } 00405 } 00406 00407 //communicate serialized ufes_map to each compute node 00408 #endif 00409 return 0; 00410 } 00411 00412 00413 void EnumEffKnocks::enum_erk() { 00414 map<string,UFES>::iterator pi; 00415 map<unsigned int,UFES>::iterator qi; 00416 //hash_map<const char*, UFES, hash<const char*>, eqstr>::iterator pi; 00417 int nump=1,proc_id=0; 00418 long first, last; 00419 util::get_proc_id_nump(proc_id,nump); 00420 00421 map<unsigned int,UFES> unique_ufes_map; 00422 00423 for (pi=this->ufes_map.begin();pi!=this->ufes_map.end();pi++) { 00424 //get available reactions from pi->second 00425 vector<int> avail_reacs; 00426 stringstream reac_str; 00427 00428 //cout << endl << "\t"<<util::get_time_str()<<": reacs_for_knock(begin) " << erk_map.size()<<" ERK sets"; 00429 reacs_for_knock(pi->second, avail_reacs); 00430 for (int i=0;i<avail_reacs.size();i++) 00431 reac_str<<avail_reacs[i]; 00432 unique_ufes_map[JSHash(reac_str.str())]=pi->second; 00433 } 00434 cout << endl << "\t"<<util::get_time_str()<<": size of ufes_map: "<<this->ufes_map.size(); 00435 cout << endl << "\t"<<util::get_time_str()<<": size of unique_ufes_map: "<<unique_ufes_map.size(); 00436 long ufes_length=unique_ufes_map.size(); 00437 //long ufes_length=ufes_hash.size(); 00438 //proc_id=0;nump=1; 00439 first=proc_id*(ufes_length/nump); 00440 if (proc_id==nump-1) 00441 last=ufes_length; 00442 else 00443 last=(proc_id+1)*(ufes_length/nump); 00444 00445 if (proc_id==0) 00446 cout << endl << "\t"<<util::get_time_str()<<": (pid="<<proc_id<<") Exploring "<< (last-first) << " UFES ..."<<endl; 00447 long j=0; 00448 00449 00450 for (qi=unique_ufes_map.begin();qi!=unique_ufes_map.end();qi++,j++) 00451 if (j>=first && j<last) { 00452 enum_erk_from_single_ufes(qi->second); 00453 if (j%20==0) 00454 cout << endl <<"\t"<<util::get_time_str() <<": crunching ufes no. "<<j<<" ...."; 00455 } 00456 00457 if (proc_id==0) 00458 cout << endl << "\t"<<util::get_time_str()<<": (pid="<<proc_id<<") Enumerated " << erk_map.size()<<" ERK sets"; 00459 00460 } 00461 00462 00463 00464 00465 void EnumEffKnocks::enum_erk_direct() { 00466 00467 queue<RK> q; 00468 //all reactions in the network 00469 vector<string> reacs_names=this->metab_network->get_reacs_names(); 00470 //vector<long>& ems_to_collapse=this->metab_network->get_ineff_efm_indices(); 00471 00472 //vector<long>& eff_ems_to_collapse=this->metab_network->get_eff_efm_indices(); 00473 //vector<long>& ineff_ems_to_collapse=this->metab_network->get_ineff_efm_indices(); 00474 00475 //reactions availabel for knockout for the given ufes 00476 vector<int> avail_reacs; 00477 //cout << endl << "\t"<<util::get_time_str()<<": reacs_for_knock(begin) " << erk_map.size()<<" ERK sets"; 00478 00479 UFES empty_ufes; 00480 reacs_for_knock(empty_ufes, avail_reacs); 00481 //cout << endl << "\t"<<util::get_time_str()<<": reacs_for_knock(end) " << erk_map.size()<<" ERK sets"; 00482 00483 //initialize emtpy RK object 00484 map<int,string> knock_reacs; 00485 //initialize empty RK object; 00486 RK rk(knock_reacs,this->metab_network); 00487 00488 q.push(rk); 00489 00490 while (!q.empty()) { 00491 00492 //fetch UFES from queue 00493 RK curr_rk=q.front(); 00494 q.pop(); 00495 00496 //cout << endl <<"\t"<<util::get_time_str() <<": crunching.."; 00497 00498 //if (curr_rk.get_knock_reacs().size()<this->metab_network->get_options().get_l1_height()) 00499 // this->max_rk_cands=this->metab_network->get_options().get_max_rk_cands_l1(); 00500 //else 00501 // this->max_rk_cands=this->metab_network->get_options().get_max_rk_cands_l2(); 00502 00503 int curr_max_rk_cands=this->metab_network->get_options().get_max_rk_cands(); 00504 if ((curr_max_rk_cands>>curr_rk.get_knock_reacs().size())>=1) 00505 curr_max_rk_cands>>=curr_rk.get_knock_reacs().size(); 00506 else 00507 curr_max_rk_cands=1; 00508 00509 //if core EFMs are all collapsed, then continue loop 00510 int cnt_not_collapsed; 00511 curr_rk.is_core_collapsed(cnt_not_collapsed); 00512 00513 if (cnt_not_collapsed==0) { 00514 continue; 00515 } 00516 00517 //find how many non-core and inefficient EFMs are collapsed. 00518 //vector<long> uncollapsed_ems; 00519 vector<long> &uncollapsed_eff_ems=curr_rk.get_uncollapsed_eff_efm_indices(); 00520 vector<long> &uncollapsed_ineff_ems=curr_rk.get_uncollapsed_ineff_efm_indices(); 00521 //uncollapsed_ems.resize(0); 00522 //collapse_ems(curr_rk, ems_to_collapse, uncollapsed_ems); 00523 //collapse_ems(curr_rk, eff_ems_to_collapse, uncollapsed_eff_ems); 00524 //collapse_ems(curr_rk, ineff_ems_to_collapse, uncollapsed_ineff_ems); 00525 00526 00527 00528 //if curr_rk collapses all modes in ems_to_collapse then add it to table of ERKs 00529 00530 00531 //have all the inefficient modes been collapsed. if so, stop the iteration and add the reaction subset to collection 00532 if (uncollapsed_ineff_ems.empty()) { 00533 if (!uncollapsed_eff_ems.empty()) 00534 erk_map[curr_rk.get_key()]=curr_rk; 00535 continue; 00536 } 00537 //if curr_rk reached maximal allowed length then continue loop 00538 if (curr_rk.get_knock_reacs().size()==this->max_rk_length) { 00539 continue; 00540 } 00541 00542 //find index in reacs_names of v[v.size()-1] 00543 map<int,string>& curr_knock_reacs=curr_rk.get_knock_reacs(); 00544 00545 //explore reactions in curr_avail_reacs=(avail_reacs-curr_knock_reacs) 00546 //find 00547 vector<int> curr_avail_reacs; 00548 for (vector<int>::iterator ai=avail_reacs.begin();ai!=avail_reacs.end();ai++) { 00549 // is avail_reacs[i] in curr_knock_reacs 00550 map<int,string>::iterator mi=curr_knock_reacs.find(*ai); 00551 if (mi==curr_knock_reacs.end()) //not found 00552 curr_avail_reacs.push_back(*ai); 00553 } 00554 00555 //multimap<long,int> ranked_reacs; //ranked modes, where key is equal to rank, and value to index of the mode 00556 //reac_buckets stores reactions in buckets with equal rank value 00557 map<double, vector<int> > reac_buckets; 00558 for (vector<int>::iterator vi=curr_avail_reacs.begin();vi!=curr_avail_reacs.end();vi++) { 00559 00560 //for the given subset of efficient modes, determine the rank, and if it is FES 00561 00562 //compute the effect of reaction 'i' when added to poolset v.get_knock_reacs() on ufes. 00563 //rank is found as number of inefficient modes that are collapsed 00564 00565 //long rank=compute_reac_rank(curr_knock_reacs,*vi,uncollapsed_ems); 00566 //long rank=rank_reacs_for_direct_enumeration(curr_knock_reacs,*vi,uncollapsed_ems); 00567 double rank=rank_reac_for_direct_enumeration(curr_knock_reacs,*vi, uncollapsed_ineff_ems,uncollapsed_eff_ems); 00568 //if (rank>=0) 00569 //cout << endl <<"\t"<<util::get_time_str() <<": rank "<<rank; 00570 //long rank=0; 00571 //don't consider reactions with rank=0 for knockout. no purpose. 00572 if (rank==0) 00573 continue; 00574 //ranked_reacs.insert(pair<long,int>(rank,*vi)); 00575 reac_buckets[rank].push_back(*vi); 00576 } 00577 /* 00578 //define iterator to traverse map of ranked reacs (i.e. pairs (rank,reaction_cand_name)) 00579 multimap<long,int>::reverse_iterator pi; 00580 //explore only the top this->max_rk_cands reaction candidates 00581 int k=0; 00582 00583 //pi->first: rank value; pi->second: reaction # 00584 for (pi=ranked_reacs.rbegin();pi!=ranked_reacs.rend() && k<this->max_rk_cands;pi++,k++) { 00585 RK new_rk(curr_rk); 00586 long rank; 00587 new_rk.add_reac(pi->second,rank); 00588 q.push(new_rk); 00589 } 00590 */ 00591 map<double, vector<int> >::reverse_iterator rmi; 00592 int kk=0; 00593 //for (rmi=reac_buckets.rbegin();rmi!=reac_buckets.rend() && kk<this->max_rk_cands;rmi++) { 00594 for (rmi=reac_buckets.rbegin();rmi!=reac_buckets.rend() && kk<curr_max_rk_cands;rmi++) { 00595 vector<int> vv=rmi->second; 00596 sort(vv.begin(),vv.end()); 00597 //for (vector<int>::iterator vvi=vv.begin();vvi!=vv.end() && kk<this->max_rk_cands;vvi++,kk++) { 00598 for (vector<int>::iterator vvi=vv.begin();vvi!=vv.end() && kk<curr_max_rk_cands;vvi++,kk++) { 00599 RK new_rk(curr_rk); 00600 double rank; 00601 new_rk.add_reac_direct(*vvi,rank); 00602 q.push(new_rk); 00603 } 00604 } 00605 00606 } 00607 00608 00609 } 00610 00611 void EnumEffKnocks::enum_erk_from_single_ufes(UFES ufes) { 00612 00613 queue<RK> q; 00614 //all reactions in the network 00615 vector<string> reacs_names=this->metab_network->get_reacs_names(); 00616 //vector<long>& ems_to_collapse=this->metab_network->get_ineff_efm_indices(); 00617 //reactions availabel for knockout for the given ufes 00618 vector<int> avail_reacs; 00619 //cout << endl << "\t"<<util::get_time_str()<<": reacs_for_knock(begin) " << erk_map.size()<<" ERK sets"; 00620 reacs_for_knock(ufes, avail_reacs); 00621 //cout << endl << "\t"<<util::get_time_str()<<": reacs_for_knock(end) " << erk_map.size()<<" ERK sets"; 00622 00623 //initialize emtpy RK object 00624 map<int,string> knock_reacs; 00625 //initialize empty RK object; 00626 RK rk(knock_reacs,this->metab_network); 00627 assert(knock_reacs.size()==0); 00628 00629 double start, end, portion_time=0, portion_start, portion_end; 00630 util::current_time(&start); 00631 q.push(rk); 00632 00633 while (!q.empty()) { 00634 //fetch UFES from queue 00635 RK curr_rk=q.front(); 00636 q.pop(); 00637 00638 //if (curr_rk.get_knock_reacs().size()<this->metab_network->get_options().get_l1_height()) 00639 // this->max_rk_cands=this->metab_network->get_options().get_max_rk_cands_l1(); 00640 //else 00641 // this->max_rk_cands=this->metab_network->get_options().get_max_rk_cands_l2(); 00642 00643 int curr_max_rk_cands=this->metab_network->get_options().get_max_rk_cands(); 00644 if ((curr_max_rk_cands>>curr_rk.get_knock_reacs().size())>=1) 00645 curr_max_rk_cands>>=curr_rk.get_knock_reacs().size(); 00646 else 00647 curr_max_rk_cands=1; 00648 00649 //if core EFMs are all collapsed, then continue loop 00650 int cnt_not_collapsed; 00651 curr_rk.is_core_collapsed(cnt_not_collapsed); 00652 00653 if (cnt_not_collapsed==0) { 00654 continue; 00655 } 00656 00657 //find how many non-core and inefficient EFMs are collapsed. 00658 vector<long> &uncollapsed_ems=curr_rk.get_uncollapsed_ineff_efm_indices(); // zzzzP 00659 00660 //collapse_ems(curr_rk, ems_to_collapse, uncollapsed_ems); 00661 assert(uncollapsed_ems.size()==curr_rk.get_uncollapsed_ineff_efm_indices().size()); 00662 //cout << endl << uncollapsed_ems.size()<<","<<curr_rk.get_uncollapsed_ineff_efm_indices().size(); 00663 00664 //if curr_rk collapses all modes in ems_to_collapse then add it to table of ERKs 00665 //if (uncollapsed_ems.size()==0) { 00666 if (uncollapsed_ems.empty()) { 00667 erk_map[curr_rk.get_key()]=curr_rk; 00668 continue; 00669 } 00670 //if curr_rk reached maximal allowed length then continue loop 00671 if (curr_rk.get_knock_reacs().size()==this->max_rk_length) { 00672 continue; 00673 } 00674 00675 //find index in reacs_names of v[v.size()-1] 00676 map<int,string>& curr_knock_reacs=curr_rk.get_knock_reacs(); 00677 00678 //explore reactions in curr_avail_reacs=(avail_reacs-curr_knock_reacs) 00679 //find 00680 vector<int> curr_avail_reacs; 00681 for (vector<int>::iterator ai=avail_reacs.begin();ai!=avail_reacs.end();ai++) { 00682 // is avail_reacs[i] in curr_knock_reacs 00683 map<int,string>::iterator mi=curr_knock_reacs.find(*ai); 00684 if (mi==curr_knock_reacs.end()) //not found 00685 curr_avail_reacs.push_back(*ai); 00686 } 00687 00688 //multimap<long,int> ranked_reacs; //ranked modes, where key is equal to rank, and value to index of the mode 00689 //reac_buckets stores reactions in buckets with equal rank value 00690 map<long, vector<int> > reac_buckets; 00691 for (vector<int>::iterator vi=curr_avail_reacs.begin();vi!=curr_avail_reacs.end();vi++) { 00692 00693 //for the given subset of efficient modes, determine the rank, and if it is FES 00694 00695 //compute the effect of reaction 'i' when added to poolset v.get_knock_reacs() on ufes. 00696 //rank is found as number of inefficient modes that are collapsed 00697 long rank=compute_reac_rank(curr_knock_reacs,*vi,uncollapsed_ems); 00698 //don't consider reactions with rank=0 for knockout. no purpose. 00699 if (rank==0) 00700 continue; 00701 //ranked_reacs.insert(pair<long,int>(rank,*vi)); 00702 reac_buckets[rank].push_back(*vi); 00703 } 00704 /* 00705 //define iterator to traverse map of ranked reacs (i.e. pairs (rank,reaction_cand_name)) 00706 multimap<long,int>::reverse_iterator pi; 00707 //explore only the top this->max_rk_cands reaction candidates 00708 int k=0; 00709 00710 //pi->first: rank value; pi->second: reaction # 00711 for (pi=ranked_reacs.rbegin();pi!=ranked_reacs.rend() && k<this->max_rk_cands;pi++,k++) { 00712 RK new_rk(curr_rk); 00713 long rank; 00714 new_rk.add_reac(pi->second,rank); 00715 q.push(new_rk); 00716 } 00717 */ 00718 00719 map<long, vector<int> >::reverse_iterator rmi; 00720 int kk=0; 00721 //for (rmi=reac_buckets.rbegin();rmi!=reac_buckets.rend() && kk<this->max_rk_cands;rmi++) { 00722 for (rmi=reac_buckets.rbegin();rmi!=reac_buckets.rend() && kk<curr_max_rk_cands;rmi++) { 00723 vector<int> vv=rmi->second; 00724 sort(vv.begin(),vv.end()); 00725 //for (vector<int>::iterator vvi=vv.begin();vvi!=vv.end() && kk<this->max_rk_cands;vvi++,kk++) { 00726 util::current_time(&portion_start); 00727 for (vector<int>::iterator vvi=vv.begin();vvi!=vv.end() && kk<curr_max_rk_cands;vvi++,kk++) { 00728 00729 RK new_rk(curr_rk); 00730 long rank; 00731 new_rk.add_reac(*vvi,rank); 00732 00733 q.push(new_rk); 00734 } 00735 util::current_time(&portion_end); 00736 } 00737 00738 portion_time+=portion_end-portion_start; 00739 00740 } 00741 00742 util::current_time(&end); 00743 double total_time=end-start; 00744 //cout << endl <<"\t total_time, portion_time: "<<total_time<<","<<portion_time; 00745 00746 } 00747 bool EnumEffKnocks::can_collapse_ineff_modes(vector<int> reac_knockout) { 00748 00749 return true; 00750 } 00751 /* 00752 Description: Find out the rank of the knockout if mode with index cand_efm_index is appended to efm_indices 00753 00754 return: if it is not FES, return -1, else return some value [0,1] 00755 */ 00756 int EnumEffKnocks::compute_rank(vector<long> efm_indices,long cand_efm_index) { 00757 //which reactions cannot be collapsed to preserve efms[efm_indices] 00758 //see how many reactions are added to that pool with addition to efms[cand_efm_index] 00759 00760 vector<string>& reacs_names=this->metab_network->get_reacs_names(); 00761 //vector< vector<double> >& efms=this->metab_network->get_efms(); 00762 00763 set<int> cand_reacs;//, used_reacs; 00764 00765 for (int i=0;i<reacs_names.size();i++) { 00766 int reac_used=0; 00767 for (long j=0;j<efm_indices.size();j++) { 00768 int is_zero; 00769 this->metab_network->is_efm_elem_zero(efm_indices[j],i, is_zero); 00770 if (!is_zero) { 00771 reac_used=1; 00772 break; 00773 } 00774 } 00775 if (reac_used) 00776 ;//used_reacs.insert(i); 00777 else 00778 cand_reacs.insert(i); 00779 } 00780 00781 set<int> cand_efm_nnz(cand_reacs); 00782 for (int i=0;i<reacs_names.size();i++) { 00783 int is_zero; 00784 this->metab_network->is_efm_elem_zero(cand_efm_index,i, is_zero); 00785 if (!is_zero) { 00786 cand_efm_nnz.insert(i); 00787 } 00788 } 00789 int rank=cand_efm_nnz.size()-cand_reacs.size(); 00790 00791 return rank; 00792 } 00793 00794 void EnumEffKnocks::print_ufes(string ufes_fname) { 00795 00796 00797 ofstream fp_out; 00798 00799 00800 fp_out.open(ufes_fname.c_str(), ios::out); 00801 if (fp_out.fail()) { 00802 cerr << endl << "\tunable to open file "<<ufes_fname<<" for reading" << endl; 00803 exit(1); 00804 } 00805 vector< vector<double> >& efm_yields=this->metab_network->get_efm_yields(); 00806 vector<string> reacs_names=this->metab_network->get_reacs_names(); 00807 00808 00809 for (map<string,UFES>::iterator it=ufes_map.begin();it!=ufes_map.end();it++) { 00810 //for (hash_map<const char*, UFES, hash<const char*>, eqstr>::iterator it=ufes_hash.begin();it!=ufes_hash.end();it++) { 00811 UFES ufes=it->second; 00812 //map<int,string>& knock_reacs rk.get_knock_reacs(); 00813 vector<long>& efm_indices=ufes.get_efm_indices(); 00814 fp_out<< efm_indices.size()<<" | "; 00815 for (int i=0;i<efm_indices.size();i++) { 00816 00817 fp_out << efm_indices[i]<<"("; 00818 for (int j=0;j<efm_yields.size();j++) { 00819 fp_out<< efm_yields[j][efm_indices[i]]; 00820 if (j<efm_yields.size()-1) 00821 fp_out<<","; 00822 } 00823 fp_out<<") "; 00824 } 00825 fp_out << endl; 00826 } 00827 fp_out.close(); 00828 00829 } 00830 00831 //find reactions availabel for knockout (not used for ufes, not substrate, not targets, not init knocks 00832 int EnumEffKnocks::reacs_for_knock(UFES ufes, vector<int> &avail_reacs) { 00833 //find which reactions are non-zero in subset ufes 00834 00835 //vector< vector<double> >& efms=this->metab_network->get_efms(); 00836 vector<long> efm_indices=ufes.get_efm_indices(); 00837 vector<string>& reacs_names=this->metab_network->get_reacs_names(); 00838 vector<long>& knock_cand_reacs=this->metab_network->get_knock_cand_reacs(); 00839 for (vector<long>::iterator it=knock_cand_reacs.begin(); it!=knock_cand_reacs.end();it++) { 00840 int not_used=1; 00841 for (vector<long>::iterator vi=efm_indices.begin();vi!=efm_indices.end();vi++) { 00842 int is_zero; 00843 //this->metab_network->is_efm_elem_zero(*vi,i, is_zero); 00844 this->metab_network->is_efm_elem_zero(*vi,*it, is_zero); 00845 if (!is_zero) { 00846 not_used=0; 00847 break; 00848 } 00849 } 00850 if (not_used) 00851 avail_reacs.push_back(*it); 00852 } 00853 return 0; 00854 } 00855 00856 double EnumEffKnocks::rank_reac_for_direct_enumeration(map<int,string> reac_knocks, int reac, vector<long>& remain_ineff_efm_indices,vector<long>& remain_eff_efm_indices) { 00857 00858 char *buffer=this->metab_network->get_bit_efm().get_buffer(); 00859 int bytes_per_efm=this->metab_network->get_bit_efm().get_bytes_per_efm(), word_index=reac/8; 00860 char bit_mask=1<<(reac%8); 00861 00862 long num_ineff_collapsed=0; 00863 for (vector<long>::iterator vi=remain_ineff_efm_indices.begin();vi!=remain_ineff_efm_indices.end();vi++){ 00864 00865 if (buffer[(*vi)*bytes_per_efm+word_index] & bit_mask) 00866 num_ineff_collapsed++; 00867 } 00868 00869 00870 long num_eff_collapsed=0; 00871 for (vector<long>::iterator vi=remain_eff_efm_indices.begin();vi!=remain_eff_efm_indices.end();vi++){ 00872 00873 if (buffer[(*vi)*bytes_per_efm+word_index] & bit_mask) 00874 num_eff_collapsed++; 00875 } 00876 00877 //if (num_eff_collapsed==0) 00878 // return -1.0; 00879 00880 00881 map<int,string> lc_reac_knocks; 00882 lc_reac_knocks=reac_knocks; 00883 lc_reac_knocks[reac]=""; 00884 int cnt_not_collapsed; 00885 int cores_collapsed=this->metab_network->is_core_efms_collapsed(lc_reac_knocks,cnt_not_collapsed); 00886 double rank; 00887 if (this->metab_network->get_options().get_network_capacity().compare("high")==0) { 00888 // compute score for reaction 00889 double frac_ineff_collapsed=num_ineff_collapsed*1.0/remain_ineff_efm_indices.size(); 00890 double frac_eff_collapsed=num_eff_collapsed*1.0/remain_eff_efm_indices.size(); 00891 rank=frac_ineff_collapsed*(1-frac_eff_collapsed)*(!cores_collapsed); //or frac_ineff_collapsed*frac_eff_collapsed 00892 00893 } else if (this->metab_network->get_options().get_network_capacity().compare("low")==0) { 00894 00895 int not_all_eff_collapsed=(remain_eff_efm_indices.size()!=num_eff_collapsed); 00896 rank=((num_ineff_collapsed+num_eff_collapsed)*1.0/(remain_eff_efm_indices.size()+remain_ineff_efm_indices.size()))*not_all_eff_collapsed*(!cores_collapsed); //or frac_ineff_collapsed*frac_eff_collapsed 00897 00898 } 00899 return rank; 00900 } 00901 00902 int EnumEffKnocks::compute_reac_rank(map<int,string> reac_knocks, int reac, vector<long>& remain_ineff_efm_indices) { 00903 00904 //long rank=0; 00905 //vector< vector<double> >& efms=this->metab_network->get_efms(); 00906 00907 //store in remain_ineff_efm_indices the indices of those modes which are collapsed when reactions from reac_knocks are deleted 00908 00909 //now find what fraction of modes indexed by remain_ineff_efm_indices are collapsed if 'reac' is deleted 00910 long num_collapsed=0; 00911 char *buffer=this->metab_network->get_bit_efm().get_buffer(); 00912 int bytes_per_efm=this->metab_network->get_bit_efm().get_bytes_per_efm(), word_index=reac/8; 00913 char bit_mask=1<<(reac%8); 00914 00915 for (vector<long>::iterator vi=remain_ineff_efm_indices.begin();vi!=remain_ineff_efm_indices.end();vi++){ 00916 /* 00917 int is_zero; 00918 this->metab_network->is_efm_elem_zero(*vi,reac, is_zero); 00919 if (!is_zero) 00920 num_collapsed++; 00921 */ 00922 if (buffer[(*vi)*bytes_per_efm+word_index] & bit_mask) 00923 num_collapsed++; 00924 00925 } 00926 00927 00928 //rank=num_collapsed; //*1.0/remain_ineff_efm_indices.size(); 00929 return num_collapsed; 00930 } 00931 /* 00932 Description: Rank the reaction 'reac' by how many remaining inefficient modes it collapses if deleted. 00933 00934 Return: value in the range (0,1) representing the ratio of collapsed ineff. modes vs. total 00935 00936 00937 */ 00938 void EnumEffKnocks::print_erk(string erk_fname) { 00939 00940 00941 this->erk_fname=erk_fname; 00942 00943 map<string,int>& target_names=this->metab_network->get_target_names(); 00944 map<string,double>& max_yields=this->metab_network->get_max_yields(); 00945 00946 ofstream fp_out; 00947 fp_out.open(this->erk_fname.c_str(), ios::out); 00948 if (fp_out.fail()) { 00949 cerr << endl << "\tunable to open file "<<this->erk_fname<<" for reading" << endl; 00950 exit(1); 00951 } 00952 00953 //fp_out << this->metab_network->get_options(); 00954 this->metab_network->get_options().print_to_file(fp_out); 00955 00956 00957 fp_out << "\tenumerated "<<this->ufes_map.size()<<" MFES subsets"<<endl; 00958 fp_out << "\tenumerated "<<this->erk_map.size()<<" ERK subsets"<<endl; 00959 fp_out << "\t# of efficient modes: "<<this->metab_network->get_eff_efm_indices().size()<<endl; 00960 fp_out << "\t# of inefficient modes: "<<this->metab_network->get_ineff_efm_indices().size()<<endl; 00961 fp_out << "\t# of core modes: "<<this->metab_network->get_core_efm_indices().size()<<endl; 00962 fp_out << "\t# of all modes (w/o core modes): "<<this->metab_network-> get_num_modes()<<endl; 00963 00964 00965 00966 00967 fp_out << "LEGEND:"<<endl; 00968 fp_out << "\tKO_size - number of reactions in knockout subset"<<endl; 00969 fp_out << "\t# eff - number of remaining efficient modes (with positive target fluxes) after knockout"<<endl; 00970 fp_out << "\t# ineff - number of remaining inefficient modes after knockout"<<endl; 00971 fp_out << "\tmin path length - minimal number of active reactions in remaining modes"<<endl; 00972 fp_out << "\tmax path length - maximal number of active reactions in remaining modes"<<endl; 00973 fp_out << "\t# core EFMs - number of remaining core elementary modes after knockout"<<endl; 00974 fp_out << "\tIR - reactions that are implicitly deactivated after deletion of knockout subset"<<endl; 00975 00976 fp_out << endl << endl; 00977 00978 map<int, vector<RK> > rk_by_length; 00979 00980 for (map<string,RK>::iterator it=erk_map.begin();it!=erk_map.end();it++) { 00981 RK rk=it->second; 00982 00983 rk_by_length[rk.get_knock_reacs().size()].push_back(rk); 00984 } 00985 for (map<int, vector<RK> >::iterator rbli=rk_by_length.begin();rbli!=rk_by_length.end();rbli++) { 00986 vector<RK> rks=rbli->second; 00987 fp_out << endl<<"\tsubset length:"<<rbli->first << "\t# of subsets:"<<rks.size(); 00988 } 00989 00990 fp_out << endl << endl; 00991 fp_out << "\tenumerating MFES time: "<<this->ufes_enum_time; 00992 fp_out << "\tenumerating ERK time: "<<this->erk_enum_time; 00993 00994 fp_out << endl << endl; 00995 00996 fp_out << "\t\t\t\t# eff."; 00997 fp_out << "\t# ineff."; 00998 fp_out << "\tmin path length"; 00999 fp_out << "\tmax path length"; 01000 fp_out << "\t# core EFMs"; 01001 01002 01003 for (map<string,int>::iterator mpi=target_names.begin();mpi!=target_names.end();mpi++) 01004 fp_out << "\tmin yield("<<mpi->first<<")"; 01005 01006 fp_out << "\tknockout subset(s)"; 01007 fp_out << "\tinactive reactions"<<endl; 01008 01009 01010 for (map<int, vector<RK> >::iterator rbli=rk_by_length.begin();rbli!=rk_by_length.end();rbli++) { 01011 vector<RK> rks=rbli->second; 01012 fp_out << endl<<"\t\tsubset length:"<<rbli->first << "\t# of subsets:"<<rks.size()<<endl; 01013 for (vector<RK>::iterator rksi=rks.begin();rksi!=rks.end();rksi++) { 01014 01015 vector<double> min_yields; 01016 long num_eff_efm_rem, num_ineff_efm_rem; 01017 rksi->test_knock_reacs2(rksi->get_knock_reacs(), min_yields, num_eff_efm_rem, num_ineff_efm_rem); 01018 fp_out<< "\t\t\t\t"<<num_eff_efm_rem<<"\t"<<num_ineff_efm_rem; 01019 01020 fp_out<< "\t"<<rksi->get_min_path_length()<<"\t"<<rksi->get_max_path_length(); 01021 01022 //how many core modes remain 01023 int cnt_not_collapsed; 01024 01025 rksi->is_core_collapsed(cnt_not_collapsed); 01026 fp_out << "\t" << cnt_not_collapsed; 01027 int i=0; 01028 fp_out << ""; 01029 map<string,double>::iterator iit; 01030 01031 for (iit=max_yields.begin();iit!=max_yields.end();iit++,i++) 01032 fp_out << "\t"<<setprecision(2)<<min_yields[i]*100/(iit->second) <<"%"; 01033 01034 fp_out << "\t"<<*rksi; 01035 fp_out << endl; 01036 } 01037 //int num_shared_efms; 01038 //find_common_efm(rks, num_shared_efms); 01039 //fp_out << endl<<" # shared efms "<<num_shared_efms <<endl; 01040 01041 } 01042 01043 fp_out.close(); 01044 } 01045 /* 01046 01047 */ 01048 int EnumEffKnocks::is_fes(vector<long> efm_indices) { 01049 01050 //is this->efm_indices a feasible set. UFES or FES 01051 //find reactions that participate in modes indexed by this->efm_indices 01052 vector<long>& ineff_efm_indices=this->metab_network->get_ineff_efm_indices(); 01053 double start, end; 01054 01055 set<int> reacs_used; //reactions that are not used in efms[efm_indices] modes 01056 util::current_time(&start); 01057 //knockoutReactionCandidates=find(~any(net.ems(:,newSubsetEms),2))'; 01058 for (int i=0;i<this->metab_network->get_num_reacs();i++) { 01059 //if reaction i is not used in effms[efm_indices] add it to ko_cand_reacs 01060 int used=0; 01061 for (vector<long>::iterator it=efm_indices.begin();it!=efm_indices.end();it++) { 01062 01063 int is_zero; 01064 this->metab_network->is_efm_elem_zero(*it,i,is_zero); 01065 01066 if (!is_zero) { 01067 used=1; 01068 break; 01069 } 01070 } 01071 if (used) 01072 reacs_used.insert(i); 01073 01074 } 01075 01076 01077 01078 int ret_val=this->metab_network->get_bit_efm().fast_is_fes(ineff_efm_indices, reacs_used); 01079 return ret_val; 01080 01081 return 1; 01082 } 01083 int EnumEffKnocks::is_all_ems_collapsed(RK rk, vector<long> ems_to_collapse) { 01084 01085 01086 map<int,string>& knock_reacs=rk.get_knock_reacs(); 01087 long num_collapsed=0; 01088 01089 //find those modes indexed by ems_to_collapse that are not deleted with knock_reacs 01090 for (vector<long>::iterator it=ems_to_collapse.begin();it!=ems_to_collapse.end();it++) { 01091 int not_collapsed=1; //indicator for current mode that it is not collapsed 01092 for (map<int,string>::iterator mi=knock_reacs.begin();mi!=knock_reacs.end();mi++) { 01093 01094 int is_zero; 01095 this->metab_network->is_efm_elem_zero(*it,mi->first, is_zero); 01096 01097 if (!is_zero) { 01098 not_collapsed=0; 01099 break; 01100 } 01101 } 01102 if (!not_collapsed) 01103 num_collapsed++; 01104 } 01105 if (num_collapsed==ems_to_collapse.size()) 01106 return 1; 01107 01108 return 0; 01109 01110 } 01111 01112 long EnumEffKnocks::collapse_ems(RK rk, vector<long> ems_to_collapse, vector<long>& uncollapsed_ems) { 01113 01114 map<int,string>& knock_reacs=rk.get_knock_reacs(); 01115 01116 uncollapsed_ems.reserve(ems_to_collapse.size()); 01117 //find those modes indexed by ems_to_collapse that are not deleted with knock_reacs 01118 for (vector<long>::iterator it=ems_to_collapse.begin();it!=ems_to_collapse.end();it++) { 01119 int not_collapsed=1; 01120 for (map<int,string>::iterator mi=knock_reacs.begin();mi!=knock_reacs.end();mi++) { 01121 int is_zero; 01122 this->metab_network->is_efm_elem_zero(*it,mi->first, is_zero); 01123 01124 if (!is_zero) { 01125 not_collapsed=0; 01126 break; 01127 } 01128 } 01129 if (not_collapsed) 01130 uncollapsed_ems.push_back(*it); 01131 } 01132 return 0; 01133 } 01134 01135 int EnumEffKnocks::compute_ranks_vector(UFES v, long range_start, long range_end, multimap<int,long>& ranked_efms) { 01136 01137 vector<long>& eff_efm_indices=this->metab_network->get_eff_efm_indices(); 01138 vector<string>& reacs_names=this->metab_network->get_reacs_names(); 01139 vector<long> efm_indices=v.get_efm_indices(); 01140 01141 set<int> cand_reacs; 01142 01143 for (int i=0;i<reacs_names.size();i++) { 01144 int reac_used=0; 01145 for (long j=0;j<efm_indices.size();j++) { 01146 int is_zero; 01147 this->metab_network->is_efm_elem_zero(efm_indices[j],i, is_zero); 01148 if (!is_zero) { 01149 reac_used=1; 01150 break; 01151 } 01152 } 01153 if (!reac_used) 01154 cand_reacs.insert(i); 01155 } 01156 for (long ii=range_start;ii<range_end;ii++) { 01157 01158 long cand_efm_index=eff_efm_indices[ii]; 01159 01160 //which reactions cannot be collapsed to preserve efms[efm_indices] 01161 //see how many reactions are added to that pool with addition to efms[cand_efm_index] 01162 set<int> cand_efm_nnz(cand_reacs); 01163 for (int i=0;i<reacs_names.size();i++) { 01164 int is_zero; 01165 this->metab_network->is_efm_elem_zero(cand_efm_index,i, is_zero); 01166 if (!is_zero) 01167 cand_efm_nnz.insert(i); 01168 } 01169 int rank=cand_efm_nnz.size()-cand_reacs.size(); 01170 ranked_efms.insert(pair<int,long>(rank,cand_efm_index)); 01171 } 01172 } 01173 01174 int EnumEffKnocks::compute_ranks_vector_bitwise(UFES v, long range_start, long range_end, multimap<int,long>& ranked_efms,vector<unsigned char> &bit_sets_table256) { 01175 01176 vector<long>& eff_efm_indices=this->metab_network->get_eff_efm_indices(); 01177 int num_reacs=this->metab_network->get_num_reacs(); 01178 vector<long> efm_indices=v.get_efm_indices(); 01179 01180 vector<unsigned char> used_reacs_bits; 01181 used_reacs_bits.resize(num_reacs/8+1,0); 01182 for (int i=0;i<num_reacs;i++) { 01183 int reac_used=0; 01184 for (long j=0;j<efm_indices.size();j++) { 01185 int is_zero; 01186 this->metab_network->is_efm_elem_zero(efm_indices[j],i, is_zero); 01187 if (!is_zero) { 01188 reac_used=1; 01189 break; 01190 } 01191 } 01192 if (!reac_used) 01193 used_reacs_bits[i/8] |= 1<<(i%8); 01194 } 01195 01196 char *buffer=this->metab_network->get_bit_efm().get_buffer(); 01197 int bytes_per_efm=this->metab_network->get_bit_efm().get_bytes_per_efm(); 01198 int rank; 01199 for (long ii=range_start;ii<range_end;ii++) { 01200 01201 //int rank=compute_rank(v.get_efm_indices(),eff_efm_indices[i]); 01202 long cand_efm_index=eff_efm_indices[ii]; 01203 rank=0; 01204 for (int i=0;i<num_reacs/8+1;i++) { 01205 unsigned char w=(used_reacs_bits[i]|buffer[cand_efm_index*bytes_per_efm+i])^(used_reacs_bits[i]); 01206 rank+=bit_sets_table256[w]; 01207 } 01208 ranked_efms.insert(pair<int,long>(rank,cand_efm_index)); 01209 } 01210 } 01211