'ElMo-Knock'

enumeffknocks.cpp

Go to the documentation of this file.
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 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines