[Bio] / FigKernelPackages / FIGMODELmodel.pm Repository:
ViewVC logotype

Diff of /FigKernelPackages/FIGMODELmodel.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.9, Wed Apr 7 13:17:07 2010 UTC revision 1.21, Sat Jul 10 22:43:52 2010 UTC
# Line 13  Line 13 
13          This is the constructor for the FIGMODELmodel object.          This is the constructor for the FIGMODELmodel object.
14  =cut  =cut
15  sub new {  sub new {
16          my ($class,$figmodel,$id) = @_;          my ($class,$figmodel,$id,$metagenome) = @_;
   
17          #Error checking first          #Error checking first
18          if (!defined($figmodel)) {          if (!defined($figmodel)) {
19                  print STDERR "FIGMODELmodel->new(undef,".$id."):figmodel must be defined to create a model object!\n";                  print STDERR "FIGMODELmodel->new(undef,".$id."):figmodel must be defined to create a model object!\n";
# Line 26  Line 25 
25                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,undef):id must be defined to create a model object");                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,undef):id must be defined to create a model object");
26                  return undef;                  return undef;
27          }          }
   
28          #Checking that the id exists          #Checking that the id exists
29          my $tbl = $self->figmodel()->database()->GetDBTable("MODELS");          if (!defined($metagenome) || $metagenome != 1) {
30          if (!defined($tbl)) {                  my $modelHandle = $self->figmodel()->database()->get_object_manager("model");
31                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not load MODELS table. Check database!");                  if (defined($modelHandle)) {
                 return undef;  
         }  
   
32          #If the id is a number, we get the model row by index          #If the id is a number, we get the model row by index
         my $index = $id;  
33          if ($id =~ m/^\d+$/) {          if ($id =~ m/^\d+$/) {
34                  $self->{_data} = $tbl->get_row($id);                                  my $objects = $modelHandle->get_objects();
35                                    if (defined($objects->[$id])) {
36                                            $self->{_data} = $objects->[$id];
37                                            $self->figmodel()->{_models}->{$id} = $self;
38                                    }
39          } else {          } else {
40                  $self->{_data} = $tbl->get_row_by_key($id,"id");                                  my $objects = $modelHandle->get_objects({id => $id});
41                  if (!defined($self->{_data})) {                                  if (defined($objects->[0])) {
42                          if ($id =~ m/(.+)(V[^V]+)/) {                                          $self->{_data} = $objects->[0];
43                                  $self->{_data} = $tbl->get_row_by_key($1,"id");                                  } elsif (!defined($objects->[0]) && $id =~ m/(.+)(V[^V]+)/) {
44                                            $objects = $modelHandle->get_objects({id => $1});
45                                            if (defined($objects->[0])) {
46                                                    $self->{_selectedversion} = $2;
47                                                    $self->{_data} = $objects->[0];
48                                            }
49                                    }
50                            }
51                    }
52                    if (defined($self->{_data})) {
53                            $self->{_modeltype} = "genome";
54                    }
55            }
56                                  if (!defined($self->{_data})) {                                  if (!defined($self->{_data})) {
57                                          $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find model ".$id." in database!");                  my $modelHandle = $self->figmodel()->database()->get_object_manager("mgmodel");
58                                          return undef;                  if (defined($modelHandle)) {
59                            #If the id is a number, we get the model row by index
60                            if ($id =~ m/^\d+$/) {
61                                    my $objects = $modelHandle->get_objects();
62                                    if (defined($objects->[$id])) {
63                                            $self->{_data} = $objects->[$id];
64                                            $self->figmodel()->{_models}->{"MG".$id} = $self;
65                                  }                                  }
                                 $self->{_selectedversion} = $2;  
66                          } else {                          } else {
67                                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find model ".$id." in database!");                                  my $objects = $modelHandle->get_objects({id => $id});
68                                  return undef;                                  if (defined($objects->[0])) {
69                                            $self->{_data} = $objects->[0];
70                                    } elsif (!defined($objects->[0]) && $id =~ m/(.+)(V[^V]+)/) {
71                                            $objects = $modelHandle->get_objects({id => $1});
72                                            if (defined($objects->[0])) {
73                                                    $self->{_selectedversion} = $2;
74                                                    $self->{_data} = $objects->[0];
75                          }                          }
76                  }                  }
77                  $index = $tbl->row_index($self->{_data});                          }
78                    }
79                    if (defined($self->{_data})) {
80                            $self->{_modeltype} = "metagenome";
81                    }
82          }          }
83          if (!defined($self->{_data})) {          if (!defined($self->{_data})) {
84                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find specified id in database!");                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find model ".$id." in database!");
85                  return undef;                  return undef;
86          }          }
         $self->{_index} = $index;  
87          $self->figmodel()->{_models}->{$self->id()} = $self;          $self->figmodel()->{_models}->{$self->id()} = $self;
         $self->figmodel()->{_models}->{$self->index()} = $self;  
88          return $self;          return $self;
89  }  }
90    
# Line 118  Line 141 
141  =cut  =cut
142  sub fig {  sub fig {
143          my ($self) = @_;          my ($self) = @_;
   
144          if (!defined($self->{_fig}) && $self->source() !~ /^MGRAST/) {          if (!defined($self->{_fig}) && $self->source() !~ /^MGRAST/) {
145                  if ($self->source() =~ /^RAST/) {                  if ($self->source() =~ /^RAST/) {
146                          $self->{"_fig"} = $self->figmodel()->fig();#$self->genome());                          $self->{"_fig"} = $self->figmodel()->fig();#$self->genome());
# Line 126  Line 148 
148                          $self->{"_fig"} = $self->figmodel()->fig();                          $self->{"_fig"} = $self->figmodel()->fig();
149                  }                  }
150          }          }
   
151          return $self->{"_fig"};          return $self->{"_fig"};
152  }  }
153    
154    =head3 aquireModelLock
155    
156    Definition:
157    
158            FIGMODELmodel->aquireModelLock();
159    
160    Description:
161    
162            Locks the database for alterations relating to the current model object
163    
164    =cut
165    sub aquireModelLock {
166            my ($self) = @_;
167            $self->figmodel()->database()->genericLock($self->id());
168    }
169    
170    =head3 releaseModelLock
171    
172    Definition:
173    
174            FIGMODELmodel->releaseModelLock();
175    
176    Description:
177    
178            Unlocks the database for alterations relating to the current model object
179    
180    =cut
181    sub releaseModelLock {
182            my ($self) = @_;
183            $self->figmodel()->database()->genericUnlock($self->id());
184    }
185    
186  =head3 mgdata  =head3 mgdata
187  Definition:  Definition:
188          FIGMODEL = FIGMODELmodel->mgdata();          FIGMODEL = FIGMODELmodel->mgdata();
# Line 138  Line 191 
191  =cut  =cut
192  sub mgdata {  sub mgdata {
193          my ($self) = @_;          my ($self) = @_;
   
194          if (!defined($self->{_mgdata}) && $self->source() =~ /^MGRAST/) {          if (!defined($self->{_mgdata}) && $self->source() =~ /^MGRAST/) {
195                  require MGRAST;                  require MGRAST;
196                  $self->{_mgdata} = $self->figmodel()->mgrast()->Job->get_objects( { 'genome_id' => $self->genome() } )                  $self->{_mgdata} = $self->figmodel()->mgrast()->Job->get_objects( { 'genome_id' => $self->genome() } )
197          }          }
   
198          return $self->{_mgdata};          return $self->{_mgdata};
199  }  }
200    
# Line 155  Line 206 
206  =cut  =cut
207  sub id {  sub id {
208          my ($self) = @_;          my ($self) = @_;
209          return $self->{_data}->{id}->[0];          return $self->{_data}->id();
210  }  }
211    
212  =head3 owner  =head3 get_model_type
213  Definition:  Definition:
214          string = FIGMODELmodel->owner();          string = FIGMODELmodel->get_model_type();
215  Description:  Description:
216          Returns the username for the model owner          Returns the type of the model
217  =cut  =cut
218  sub owner {  sub get_model_type {
219          my ($self) = @_;          my ($self) = @_;
220          return $self->{_data}->{owner}->[0];          return $self->{_modeltype};
221  }  }
222    
223  =head3 index  =head3 owner
224  Definition:  Definition:
225          string = FIGMODELmodel->index();          string = FIGMODELmodel->owner();
226  Description:  Description:
227          Returns model index          Returns the username for the model owner
228  =cut  =cut
229  sub index {  sub owner {
230          my ($self) = @_;          my ($self) = @_;
231          return $self->{_index};          return $self->{_data}->owner();
232  }  }
233    
234  =head3 name  =head3 name
# Line 196  Line 247 
247                          if (defined($self->mgdata())) {                          if (defined($self->mgdata())) {
248                                  $self->{_name} = $self->mgdata()->genome_name;                                  $self->{_name} = $self->mgdata()->genome_name;
249                          }                          }
                 } elsif (defined($self->stats())) {  
                         $self->{_name} = $self->stats()->{'Organism name'}->[0];  
250                  } elsif ($source !~ /^RAST/) {                  } elsif ($source !~ /^RAST/) {
251                          $self->{_name} = $self->fig()->orgname_of_orgid($self->genome());                          $self->{_name} = $self->fig()->orgname_of_orgid($self->genome());
252                    } else {
253                            $self->{_name} = $self->figmodel()->get_genome_stats($self->genome())->{NAME}->[0];
254                  }                  }
255          }          }
256    
257          return $self->{_name};          return $self->{_name};
258  }  }
259    
 =head3 stats  
 Definition:  
         string = FIGMODELmodel->stats();  
 Description:  
         Returns model stats  
 =cut  
 sub stats {  
         my ($self) = @_;  
   
         if (!defined($self->{_stats})) {  
                 $self->{_stats} = $self->figmodel()->database()->GetDBTable("MODEL STATS")->get_row_by_key($self->id(),"Model ID");  
         }  
         return $self->{_stats};  
 }  
   
260  =head3 get_reaction_class  =head3 get_reaction_class
261  Definition:  Definition:
262          string = FIGMODELmodel->get_reaction_class(string::reaction ID);          string = FIGMODELmodel->get_reaction_class(string::reaction ID);
# Line 228  Line 264 
264          Returns reaction class          Returns reaction class
265  =cut  =cut
266  sub get_reaction_class {  sub get_reaction_class {
267          my ($self,$reaction,$nohtml) = @_;          my ($self,$reaction,$nohtml,$brief_flux) = @_;
268    
269          if (!-e $self->directory()."ReactionClassification-".$self->id().".tbl") {          if (!-e $self->directory()."ReactionClassification-".$self->id().".tbl") {
270                  if (!defined($self->{_reaction_classes})) {                  if (!defined($self->{_reaction_classes})) {
# Line 245  Line 281 
281                          my $max = $ClassRow->{MAX}->[0];                          my $max = $ClassRow->{MAX}->[0];
282                          if ($ClassRow->{CLASS}->[0] eq "Positive") {                          if ($ClassRow->{CLASS}->[0] eq "Positive") {
283                                  $class = "Essential =>";                                  $class = "Essential =>";
284                                  $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]";                                  $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
285                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative") {
286                                  $class = "Essential <=";                                  $class = "Essential <=";
287                                  $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]";                                  $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
288                          } elsif ($ClassRow->{CLASS}->[0] eq "Positive variable") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Positive variable") {
289                                  $class = "Active =>";                                  $class = "Active =>";
290                                  $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]";                                  $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
291                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative variable") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative variable") {
292                                  $class = "Active <=";                                  $class = "Active <=";
293                                  $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]";                                  $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
294                          } elsif ($ClassRow->{CLASS}->[0] eq "Variable") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Variable") {
295                                  $class = "Active <=>";                                  $class = "Active <=>";
296                                  $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]";                                  $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
297                          } elsif ($ClassRow->{CLASS}->[0] eq "Blocked") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Blocked") {
298                                  $class = "Inactive";                                  $class = "Inactive";
299                          } elsif ($ClassRow->{CLASS}->[0] eq "Dead") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Dead") {
# Line 292  Line 328 
328                          my $max = $ClassRow->{MAX}->[$i];                          my $max = $ClassRow->{MAX}->[$i];
329                          if ($ClassRow->{CLASS}->[$i] eq "Positive") {                          if ($ClassRow->{CLASS}->[$i] eq "Positive") {
330                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential =>";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential =>";
331                                  $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]";                                  $brief_flux ? $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $NewClass.="<br>[Flux: ".$min." to ".$max."]<br>";
332                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative") {
333                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential <=";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential <=";
334                                  $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]";                                  $brief_flux ? $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $NewClass.="<br>[Flux: ".$min." to ".$max."]<br>";
335                          } elsif ($ClassRow->{CLASS}->[$i] eq "Positive variable") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Positive variable") {
336                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active =>";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active =>";
337                                  $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]";                                  $brief_flux ? $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $NewClass.="<br>[Flux: ".$min." to ".$max."]<br>";
338                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative variable") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative variable") {
339                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=";
340                                  $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]";                                  $brief_flux ? $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $NewClass.="<br>[Flux: ".$min." to ".$max."]<br>";
341                          } elsif ($ClassRow->{CLASS}->[$i] eq "Variable") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Variable") {
342                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=>";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=>";
343                                  $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]";                                  $brief_flux ? $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $NewClass.="<br>[Flux: ".$min." to ".$max."]<br>";
344                          } elsif ($ClassRow->{CLASS}->[$i] eq "Blocked") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Blocked") {
345                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Inactive";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Inactive";
346                          } elsif ($ClassRow->{CLASS}->[$i] eq "Dead") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Dead") {
# Line 331  Line 367 
367    
368          if (!defined($self->{_biomass})) {          if (!defined($self->{_biomass})) {
369                  my $rxntbl = $self->reaction_table();                  my $rxntbl = $self->reaction_table();
370                    if (defined($rxntbl)) {
371                  for (my $i=0; $i < $rxntbl->size(); $i++) {                  for (my $i=0; $i < $rxntbl->size(); $i++) {
372                          if ($rxntbl->get_row($i)->{"LOAD"}->[0] =~ m/bio\d\d\d\d\d/) {                          if ($rxntbl->get_row($i)->{"LOAD"}->[0] =~ m/bio\d\d\d\d\d/) {
373                                  $self->{_biomass} = $rxntbl->get_row($i)->{"LOAD"}->[0];                                  $self->{_biomass} = $rxntbl->get_row($i)->{"LOAD"}->[0];
# Line 338  Line 375 
375                          }                          }
376                  }                  }
377          }          }
378            }
379    
380          return $self->get_reaction_data($self->{_biomass});          return $self->get_reaction_data($self->{_biomass});
381  }  }
# Line 350  Line 388 
388  =cut  =cut
389  sub get_reaction_data {  sub get_reaction_data {
390          my ($self,$reaction) = @_;          my ($self,$reaction) = @_;
   
391          if (!defined($self->reaction_table())) {          if (!defined($self->reaction_table())) {
392                  return undef;                  return undef;
393          }          }
394          if ($reaction =~ m/^\d+$/) {          if ($reaction =~ m/^\d+$/) {
395                  $self->reaction_table()->get_row($reaction);                  return $self->reaction_table()->get_row($reaction);
396          }          }
397          return $self->reaction_table()->get_row_by_key($reaction,"LOAD");          return $self->reaction_table()->get_row_by_key($reaction,"LOAD");
398  }  }
# Line 376  Line 413 
413          return $Data->{LOAD}->[0];          return $Data->{LOAD}->[0];
414  }  }
415    
416    =head3 load_model_table
417    
418    Definition: FIGMODELTable = FIGMODELmodel->load_model_table(string:table name,0/1:refresh the table));
419    
420    Description: Returns the table specified by the input filename. Table will be stored in a file in the model directory.
421    
422    =cut
423    sub load_model_table {
424            my ($self,$name,$refresh) = @_;
425            if (defined($refresh) && $refresh == 1) {
426                    delete $self->{"_".$name};
427            }
428            if (!defined($self->{"_".$name})) {
429                    my $tbldef = $self->figmodel()->config($name);
430                    if (!defined($tbldef)) {
431                            return undef;
432                    }
433                    my $itemDelim = "|";
434                    if (defined($tbldef->{itemdelimiter}->[0])) {
435                            $itemDelim = $tbldef->{itemdelimiter}->[0];
436                            if ($itemDelim eq "SC") {
437                                    $itemDelim = ";";
438                            }
439                    }
440                    my $columnDelim = "\t";
441                    if (defined($tbldef->{columndelimiter}->[0])) {
442                            $columnDelim = $tbldef->{columndelimiter}->[0];
443                            if ($columnDelim eq "SC") {
444                                    $columnDelim = ";";
445                            }
446                    }
447                    my $suffix = ".tbl";
448                    if (defined($tbldef->{filename_suffix}->[0])) {
449                            $suffix = $tbldef->{filename_suffix}->[0];
450                    }
451                    my $filename = $self->directory().$name."-".$self->id().$self->selected_version().$suffix;
452                    if (defined($tbldef->{filename_prefix}->[0])) {
453                            if ($tbldef->{filename_prefix}->[0] eq "NONE") {
454                                    $filename = $self->directory().$self->id().$self->selected_version().$suffix;
455                            } else {
456                                    $filename = $self->directory().$tbldef->{filename_prefix}->[0]."-".$self->id().$self->selected_version().$suffix;
457                            }
458                    }
459                    if (-e $filename) {
460                            $self->{"_".$name} = $self->figmodel()->database()->load_table($filename,$columnDelim,$itemDelim,$tbldef->{headingline}->[0],$tbldef->{hashcolumns});
461                    } else {
462                            if (defined($tbldef->{prefix})) {
463                                    $self->{"_".$name} = FIGMODELTable->new($tbldef->{columns},$filename,$tbldef->{hashcolumns},$columnDelim,$itemDelim,join(@{$tbldef->{prefix}},"\n"));
464                            } else {
465                                    $self->{"_".$name} = FIGMODELTable->new($tbldef->{columns},$filename,$tbldef->{hashcolumns},$columnDelim,$itemDelim);
466                            }
467                    }
468            }
469            return $self->{"_".$name};
470    }
471    
472    =head3 create_table_prototype
473    
474    Definition:
475            FIGMODELTable::table = FIGMODELmodel->create_table_prototype(string::table);
476    Description:
477            Returns a empty FIGMODELTable with all the metadata associated with the input table name
478    
479    =cut
480    sub create_table_prototype {
481            my ($self,$TableName) = @_;
482            #Checking if the table definition exists in the FIGMODELconfig file
483            my $tbldef = $self->figmodel()->config($TableName);
484            if (!defined($tbldef)) {
485                    $self->figmodel()->error_message("FIGMODELdatabase:create_table_prototype:Definition not found for ".$TableName);
486                    return undef;
487            }
488            #Checking that this is a database table
489            if (!defined($tbldef->{tabletype}) || $tbldef->{tabletype}->[0] ne "ModelTable") {
490                    $self->figmodel()->error_message("FIGMODELdatabase:create_table_prototype:".$TableName." is not a model table!");
491                    return undef;
492            }
493            #Setting default values for table parameters
494            my $prefix;
495            if (defined($tbldef->{prefix})) {
496                    $prefix = join("\n",@{$self->config($TableName)->{prefix}})."\n";
497            }
498            my $itemDelim = "|";
499            if (defined($tbldef->{itemdelimiter}->[0])) {
500                    $itemDelim = $tbldef->{itemdelimiter}->[0];
501                    if ($itemDelim eq "SC") {
502                            $itemDelim = ";";
503                    }
504            }
505            my $columnDelim = "\t";
506            if (defined($tbldef->{columndelimiter}->[0])) {
507                    $columnDelim = $tbldef->{columndelimiter}->[0];
508                    if ($columnDelim eq "SC") {
509                            $columnDelim = ";";
510                    }
511            }
512            my $suffix = ".tbl";
513            if (defined($tbldef->{filename_suffix}->[0])) {
514                    $suffix = $tbldef->{filename_suffix}->[0];
515            }
516            my $filename = $self->directory().$TableName."-".$self->id().$self->selected_version().$suffix;
517            if (defined($tbldef->{filename_prefix}->[0])) {
518                    if ($tbldef->{filename_prefix}->[0] eq "NONE") {
519                            $filename = $self->directory().$self->id().$self->selected_version().$suffix;
520                    } else {
521                            $filename = $self->directory().$tbldef->{filename_prefix}->[0]."-".$self->id().$self->selected_version().$suffix;
522                    }
523            }
524            #Creating the table prototype
525            my $tbl = FIGMODELTable->new($tbldef->{columns},$filename,$tbldef->{hashcolumns},$columnDelim,$itemDelim,$prefix);
526            return $tbl;
527    }
528    
529  =head3 get_reaction_number  =head3 get_reaction_number
530  Definition:  Definition:
531          int = FIGMODELmodel->get_reaction_number();          int = FIGMODELmodel->get_reaction_number();
# Line 384  Line 534 
534  =cut  =cut
535  sub get_reaction_number {  sub get_reaction_number {
536          my ($self) = @_;          my ($self) = @_;
   
537          if (!defined($self->reaction_table())) {          if (!defined($self->reaction_table())) {
538                  return 0;                  return 0;
539          }          }
   
540          return $self->reaction_table()->size();          return $self->reaction_table()->size();
541  }  }
542    
# Line 399  Line 547 
547          Returns FIGMODELTable with the reaction list for the model          Returns FIGMODELTable with the reaction list for the model
548  =cut  =cut
549  sub reaction_table {  sub reaction_table {
550          my ($self) = @_;          my ($self,$clear) = @_;
551            if (defined($self->{_reaction_table})) {
552                    return $self->{_reaction_table};
553            }
554            $self->{_reaction_table} = $self->load_model_table("ModelReactions",$clear);
555            my $classTbl = $self->reaction_class_table();
556            if (defined($classTbl)) {
557                    for (my $i=0; $i < $classTbl->size(); $i++) {
558                            my $row = $classTbl->get_row($i);
559                            if (defined($row->{REACTION})) {
560                                    my $rxnRow = $self->{_reaction_table}->get_row_by_key($row->{"REACTION"}->[0],"LOAD");
561                                    if (defined($row->{MEDIA})) {
562                                            for (my $j=0; $j < @{$row->{MEDIA}};$j++) {
563                                                    my $class = "Active <=>";
564                                                    if ($row->{CLASS}->[$j] eq "Positive") {
565                                                            $class = "Essential =>";
566                                                    } elsif ($row->{CLASS}->[$j] eq "Negative") {
567                                                            $class = "Essential <=";
568                                                    } elsif ($row->{CLASS}->[$j] eq "Blocked") {
569                                                            $class = "Inactive";
570                                                    } elsif ($row->{CLASS}->[$j] eq "Positive variable") {
571                                                            $class = "Active =>";
572                                                    } elsif ($row->{CLASS}->[$j] eq "Negative variable") {
573                                                            $class = "Active <=";
574                                                    } elsif ($row->{CLASS}->[$j] eq "Variable") {
575                                                            $class = "Active <=>";
576                                                    } elsif ($row->{CLASS}->[$j] eq "Dead") {
577                                                            $class = "Dead";
578                                                    }
579                                                    push(@{$rxnRow->{PREDICTIONS}},$row->{MEDIA}->[$j].":".$class);
580                                            }
581                                    }
582                            }
583                    }
584            }
585            return $self->{_reaction_table};
586    }
587    
588          if (!defined($self->{_reaction_data})) {  =head3 essentials_table
589                  $self->{_reaction_data} = $self->figmodel()->database()->GetDBModel($self->id());  Definition:
590            FIGMODELTable = FIGMODELmodel->essentials_table();
591    Description:
592            Returns FIGMODELTable with the essential genes for the model
593    =cut
594    sub essentials_table {
595            my ($self,$clear) = @_;
596            my $tbl = $self->load_model_table("ModelEssentialGenes",$clear);
597            return $tbl;
598          }          }
599    
600          return $self->{_reaction_data};  =head3 model_history
601    Definition:
602            FIGMODELTable = FIGMODELmodel->model_history();
603    Description:
604            Returns FIGMODELTable with the history of model changes
605    =cut
606    sub model_history {
607            my ($self,$clear) = @_;
608            return $self->load_model_table("ModelHistory",$clear);
609  }  }
610    
611  =head3 reaction_class_table  =head3 feature_table
612  Definition:  Definition:
613          FIGMODELTable = FIGMODELmodel->reaction_class_table();          FIGMODELTable = FIGMODELmodel->feature_table();
614  Description:  Description:
615          Returns FIGMODELTable with the reaction class data, and creates the table file  if it does not exist          Returns FIGMODELTable with the feature list for the model
616  =cut  =cut
617  sub reaction_class_table {  sub feature_table {
618          my ($self) = @_;          my ($self) = @_;
619    
620          if (!defined($self->{_reaction_class_table})) {          if (!defined($self->{_feature_data})) {
621                  if (-e $self->directory()."ReactionClassification-".$self->id().$self->selected_version().".tbl") {                  #Getting the genome feature list
622                          $self->{_reaction_class_table} = $self->figmodel()->database()->load_table($self->directory()."ReactionClassification-".$self->id().$self->selected_version().".tbl",";","|",0,["REACTION","CLASS","MEDIA"]);                  my $FeatureTable = $self->figmodel()->GetGenomeFeatureTable($self->genome());
623                    if (!defined($FeatureTable)) {
624                            print STDERR "FIGMODELmodel:feature_table:Could not get features for genome ".$self->genome()." in database!";
625                            return undef;
626                    }
627                    #Getting the reaction table for the model
628                    my $rxnTable = $self->reaction_table();
629                    if (!defined($rxnTable)) {
630                            print STDERR "FIGMODELmodel:feature_table:Could not get reaction table for model ".$self->id()." in database!";
631                            return undef;
632                    }
633                    #Cloning the feature table
634                    $self->{_feature_data} = $FeatureTable->clone_table_def();
635                    $self->{_feature_data}->add_headings(($self->id()."REACTIONS",$self->id()."PREDICTIONS"));
636                    for (my $i=0; $i < $rxnTable->size(); $i++) {
637                            my $Row = $rxnTable->get_row($i);
638                            if (defined($Row) && defined($Row->{"ASSOCIATED PEG"})) {
639                                    foreach my $GeneSet (@{$Row->{"ASSOCIATED PEG"}}) {
640                                            my $temp = $GeneSet;
641                                            $temp =~ s/\+/|/g;
642                                            $temp =~ s/\sAND\s/|/gi;
643                                            $temp =~ s/\sOR\s/|/gi;
644                                            $temp =~ s/[\(\)\s]//g;
645                                            my @GeneList = split(/\|/,$temp);
646                                            foreach my $Gene (@GeneList) {
647                                                    my $FeatureRow = $self->{_feature_data}->get_row_by_key("fig|".$self->genome().".".$Gene,"ID");
648                                                    if (!defined($FeatureRow)) {
649                                                            $FeatureRow = $FeatureTable->get_row_by_key("fig|".$self->genome().".".$Gene,"ID");
650                                                            if (defined($FeatureRow)) {
651                                                                    $self->{_feature_data}->add_row($FeatureRow);
652                                                            }
653                                                    }
654                                                    if (defined($FeatureRow)) {
655                                                            $self->{_feature_data}->add_data($FeatureRow,$self->id()."REACTIONS",$Row->{"LOAD"}->[0],1);
656                                                    }
657                                            }
658                                    }
659                            }
660                    }
661                    #Loading predictions
662                    my $esstbl = $self->essentials_table();
663                    for (my $i=0; $i < $self->{_feature_data}->size(); $i++) {
664                            my $Row = $self->{_feature_data}->get_row($i);
665                            if ($Row->{ID}->[0] =~ m/(peg\.\d+)/) {
666                                    my $gene = $1;
667                                    my @rows = $esstbl->get_rows_by_key($gene,"ESSENTIAL GENES");
668                                    my $mediahash;
669                                    for (my $j=0; $j < $esstbl->size(); $j++) {
670                                            $mediahash->{$esstbl->get_row($j)->{MEDIA}->[0]} = 0;
671                                    }
672                                    for (my $j=0; $j < @rows; $j++) {
673                                            $mediahash->{$rows[$j]->{MEDIA}->[0]} = 1;
674                                    }
675                                    my @mediaList = keys(%{$mediahash});
676                                    for (my $j=0; $j < @mediaList; $j++) {
677                                            if ($mediahash->{$mediaList[$j]} == 1) {
678                                                    push(@{$Row->{$self->id()."PREDICTIONS"}},$mediaList[$j].":essential");
679                  } else {                  } else {
680                          $self->{_reaction_class_table} = FIGMODELTable->new(["REACTION","MEDIA","CLASS","MIN","MAX"],$self->directory()."ReactionClassification-".$self->id().$self->selected_version().".tbl",["REACTION","CLASS","MEDIA"],";","|",undef);                                                  push(@{$Row->{$self->id()."PREDICTIONS"}},$mediaList[$j].":nonessential");
681                                            }
682                  }                  }
683          }          }
684                    }
685            }
686            return $self->{_feature_data};
687    }
688    
689          return $self->{_reaction_class_table};  =head3 reaction_class_table
690    Definition:
691            FIGMODELTable = FIGMODELmodel->reaction_class_table();
692    Description:
693            Returns FIGMODELTable with the reaction class data, and creates the table file  if it does not exist
694    =cut
695    sub reaction_class_table {
696            my ($self,$clear) = @_;
697            return $self->load_model_table("ModelReactionClasses",$clear);
698  }  }
699    
700  =head3 compound_class_table  =head3 compound_class_table
# Line 435  Line 704 
704          Returns FIGMODELTable with the compound class data, and creates the table file  if it does not exist          Returns FIGMODELTable with the compound class data, and creates the table file  if it does not exist
705  =cut  =cut
706  sub compound_class_table {  sub compound_class_table {
707          my ($self) = @_;          my ($self,$clear) = @_;
708            return $self->load_model_table("ModelCompoundClasses",$clear);
         if (!defined($self->{_compound_class_table})) {  
                 if (-e $self->directory()."CompoundClassification-".$self->id().$self->selected_version().".tbl") {  
                         $self->{_compound_class_table} = $self->figmodel()->database()->load_table($self->directory()."CompoundClassification-".$self->id().$self->selected_version().".tbl",";","|",0,["COMPOUND","CLASS","MEDIA"]);  
                 } else {  
                         $self->{_compound_class_table} = FIGMODELTable->new(["COMPOUND","MEDIA","CLASS","MIN","MAX"],$self->directory()."CompoundClassification-".$self->id().$self->selected_version().".tbl",["COMPOUND","CLASS","MEDIA"],";","|",undef);  
                 }  
         }  
   
         return $self->{_compound_class_table};  
709  }  }
710    
711  =head3 get_essential_genes  =head3 get_essential_genes
# Line 456  Line 716 
716  =cut  =cut
717  sub get_essential_genes {  sub get_essential_genes {
718          my ($self,$media) = @_;          my ($self,$media) = @_;
719            my $tbl = $self->essentials_table();
720          if (!defined($media)) {          my $row = $tbl->get_row_by_key($media,"MEDIA");
721                  $media = "Complete";          if (defined($row)) {
722          }                  return $row->{"ESSENTIAL GENES"};
         if (!defined($self->{_essential_genes}->{$media})) {  
                 $self->{_essential_genes}->{$media} = undef;  
                 if (-e $self->directory()."EssentialGenes-".$self->id().$self->selected_version()."-".$media.".tbl") {  
                         $self->{_essential_genes}->{$media} = $self->figmodel()->database()->load_single_column_file($self->directory()."EssentialGenes-".$self->id().$self->selected_version()."-".$media.".tbl","");  
723                  }                  }
724          }          return undef;
   
         return $self->{_essential_genes}->{$media};  
725  }  }
726    
727  =head3 compound_table  =head3 compound_table
# Line 480  Line 734 
734          my ($self) = @_;          my ($self) = @_;
735    
736          if (!defined($self->{_compound_table})) {          if (!defined($self->{_compound_table})) {
737                  $self->{_compound_table} = $self->figmodel()->database()->GetDBModelCompounds($self->id());                  $self->{_compound_table} = $self->create_table_prototype("ModelCompounds");
738                    #Loading the reactions
739                    my $ReactionTable = $self->figmodel()->database()->get_table("REACTIONS");
740                    my $BiomassTable = $self->figmodel()->database()->get_table("BIOMASS");
741                    #Loading the model
742                    my $ModelTable = $self->reaction_table();
743                    #Checking that the tables were loaded
744                    if (!defined($ModelTable) || !defined($ReactionTable)) {
745                            return undef;
746                    }
747                    #Finding the biomass reaction
748                    for (my $i=0; $i < $ModelTable->size(); $i++) {
749                            my $ID = $ModelTable->get_row($i)->{"LOAD"}->[0];
750                            my $Row = $ReactionTable->get_row_by_key($ID,"DATABASE");
751                            my $IsBiomass = 0;
752                            if (!defined($Row)) {
753                                    $Row = $BiomassTable->get_row_by_key($ID,"DATABASE");
754                                    $IsBiomass = 1;
755                            }
756                            if (defined($Row->{"EQUATION"}->[0])) {
757                                    $_ = $Row->{"EQUATION"}->[0];
758                                    my @OriginalArray = /(cpd\d\d\d\d\d[\[\w]*)/g;
759                                    foreach my $Compound (@OriginalArray) {
760                                            my $ID = substr($Compound,0,8);
761                                            my $NewRow = $self->{_compound_table}->get_row_by_key($ID,"DATABASE",1);
762                                            if ($IsBiomass == 1) {
763                                                    $self->{_compound_table}->add_data($NewRow,"BIOMASS",$Row->{"DATABASE"}->[0],1);
764                                            }
765                                            if (length($Compound) > 8) {
766                                                    #print $Compound."\t".$Row->{"EQUATION"}->[0]."\t".$Row->{"DATABASE"}->[0]."\n";
767                                                    my $Compartment = substr($Compound,8,1);
768                                                    $self->{_compound_table}->add_data($NewRow,"COMPARTMENTS",$Compartment,1);
769                                                    $self->{_compound_table}->add_data($NewRow,"TRANSPORTERS",$Row->{"DATABASE"}->[0],1);
770                                            }
771                                    }
772                            }
773                    }
774          }          }
775    
776          return $self->{_compound_table};          return $self->{_compound_table};
# Line 488  Line 778 
778    
779  =head3 get_compound_data  =head3 get_compound_data
780  Definition:  Definition:
781          string = FIGMODELmodel->get_compound_data(string::compound ID);          {string:key=>[string]:values} = FIGMODELmodel->get_compound_data(string::compound ID);
782  Description:  Description:
783          Returns model compound data          Returns model compound data
784  =cut  =cut
# Line 499  Line 789 
789                  return undef;                  return undef;
790          }          }
791          if ($compound =~ m/^\d+$/) {          if ($compound =~ m/^\d+$/) {
792                  $self->compound_table()->get_row($compound);                  return $self->compound_table()->get_row($compound);
793          }          }
794          return $self->compound_table()->get_row_by_key($compound,"DATABASE");          return $self->compound_table()->get_row_by_key($compound,"DATABASE");
795  }  }
796    
797    =head3 get_feature_data
798    Definition:
799            {string:key=>[string]:values} = FIGMODELmodel->get_feature_data(string::feature ID);
800    Description:
801            Returns model feature data
802    =cut
803    sub get_feature_data {
804            my ($self,$feature) = @_;
805            if (!defined($self->feature_table())) {
806                    return undef;
807            }
808            if ($feature =~ m/^\d+$/) {
809                    return $self->feature_table()->get_row($feature);
810            }
811            if ($feature =~ m/(peg\.\d+)/) {
812                    $feature = $1;
813            }
814            return $self->feature_table()->get_row_by_key("fig|".$self->genome().".".$feature,"ID");
815    }
816    
817  =head3 genome  =head3 genome
818  Definition:  Definition:
819          string = FIGMODELmodel->genome();          string = FIGMODELmodel->genome();
# Line 512  Line 822 
822  =cut  =cut
823  sub genome {  sub genome {
824          my ($self) = @_;          my ($self) = @_;
825          return $self->{_data}->{genome}->[0];          return $self->{_data}->genome();
826  }  }
827    
828  =head3 source  =head3 source
# Line 523  Line 833 
833  =cut  =cut
834  sub source {  sub source {
835          my ($self) = @_;          my ($self) = @_;
836          return $self->{_data}->{source}->[0];          return $self->{_data}->source();
837  }  }
838    
839  =head3 rights  =head3 rights
# Line 534  Line 844 
844  =cut  =cut
845  sub rights {  sub rights {
846          my ($self,$username) = @_;          my ($self,$username) = @_;
   
847          if ($self->public()) {          if ($self->public()) {
848                  return 1;                  return 1;
849          }          }
# Line 542  Line 851 
851                  return 0;                  return 0;
852          }          }
853          if (!defined($self->{_userrights}->{$username})) {          if (!defined($self->{_userrights}->{$username})) {
854                  if (defined($self->{_data}->{master})) {                  $self->{_userrights}->{$self->{_data}->owner()} = 1;
855                          for (my $i=0; $i < @{$self->{_data}->{master}};$i++) {                  my @users = split(/\|/,$self->{_data}->users());
856                                  $self->{_userrights}->{$self->{_data}->{master}->[$i]} = 1;                  for (my $i=0; $i < @users;$i++) {
857                          }                          $self->{_userrights}->{$users[$i]} = 1;
                 }  
                 if (defined($self->{_data}->{users})) {  
                         for (my $i=0; $i < @{$self->{_data}->{users}};$i++) {  
                                 $self->{_userrights}->{$self->{_data}->{users}->[$i]} = 1;  
                         }  
858                  }                  }
859          }          }
860          return $self->{_userrights}->{$username};          return $self->{_userrights}->{$username};
# Line 564  Line 868 
868  =cut  =cut
869  sub public {  sub public {
870          my ($self) = @_;          my ($self) = @_;
871            if ($self->{_data}->users() eq "all") {
872          if (!defined($self->{_public})) {                  return 1;
                 $self->{_public} = 0;  
                 if (defined($self->{_data}->{users}->[0]) && $self->{_data}->{users}->[0] eq "all") {  
                         $self->{_public} = 1;  
                 }  
873          }          }
874          return $self->{_public};          return 0;
875  }  }
876    
877  =head3 directory  =head3 directory
# Line 590  Line 890 
890                  }                  }
891                  my $source = $self->source();                  my $source = $self->source();
892                  if ($source =~ /^MGRAST/) {                  if ($source =~ /^MGRAST/) {
893                          $self->{_directory} = $self->figmodel()->config("organism directory")->[0].$userdirectory.$self->genome()."/";                          $self->{_directory} = $self->figmodel()->config("mgrast model directory")->[0].$userdirectory.$self->genome()."/";
894                  } elsif ($source =~ /^RAST/) {                  } elsif ($source =~ /^RAST/) {
895                          $self->{_directory} = $self->figmodel()->config("organism directory")->[0].$userdirectory.$self->genome()."/";                          $self->{_directory} = $self->figmodel()->config("organism directory")->[0].$userdirectory.$self->genome()."/";
896                  } elsif ($source =~ /^SEED/) {                  } elsif ($source =~ /^SEED/) {
# Line 619  Line 919 
919          return $self->directory().$self->id().$self->selected_version().".txt";          return $self->directory().$self->id().$self->selected_version().".txt";
920  }  }
921    
 =head3 set_metagenome_stats  
 Definition:  
         string = FIGMODELmodel->set_metagenome_stats();  
 Description:  
         Sets the values of many model stats for a metagenome  
 =cut  
 sub set_metagenome_stats {  
         my ($self) = @_;  
   
         $self->{_total_compounds} = 0;  
         if (defined($self->compound_table())) {  
                 $self->{_total_compounds} = $self->compound_table()->size();  
         }  
         $self->{_gene_reactions} = 0;  
         $self->{_gapfilling_reactions} = 0;  
         $self->{_model_genes} = 0;  
         $self->{_total_reactions} = 0;  
         if (defined($self->reaction_table())) {  
                 $self->{_total_reactions} = $self->reaction_table()->size();  
                 my $tbl = $self->reaction_table();  
                 my $spontaneous = 0;  
                 for (my $i=0; $i < $tbl->size(); $i++) {  
                         my $row = $tbl->get_row($i);  
                         if (!defined($row->{"ASSOCIATED PEG"}->[0]) || $row->{"ASSOCIATED PEG"}->[0] !~ m/peg/) {  
                                 if ($row->{"ASSOCIATED PEG"}->[0] =~ m/SPONTANEOUS/) {  
                                         $spontaneous++;  
                                 } else {  
                                         $self->{_gapfilling_reactions}++;  
                                 }  
                         } else {  
                                 for (my $j=0; $j < @{$row->{"CONFIDENCE"}}; $j++) {  
                                         my @ecores = split(/;/,$row->{"CONFIDENCE"}->[$j]);  
                                         $self->{_model_genes} += @ecores;  
                                 }  
                         }  
                 }  
                 $self->{_gene_reactions} = $tbl->size() - $spontaneous - $self->{_gapfilling_reactions};  
         }  
 }  
   
922  =head3 version  =head3 version
923  Definition:  Definition:
924          string = FIGMODELmodel->version();          string = FIGMODELmodel->version();
# Line 670  Line 930 
930    
931          if (!defined($self->{_version})) {          if (!defined($self->{_version})) {
932                  if (!defined($self->{_selectedversion})) {                  if (!defined($self->{_selectedversion})) {
933                          if (defined($self->stats())) {                          $self->{_version} = "V".$self->{_data}->version().".".$self->{_data}->autocompleteVersion();
                                 $self->{_version} = "V".$self->stats()->{"Version"}->[0].".".$self->stats()->{"Gap fill version"}->[0];  
                         }  
934                  } else {                  } else {
935                          $self->{_version} = $self->{_selectedversion};                          $self->{_version} = $self->{_selectedversion};
936                  }                  }
# Line 703  Line 961 
961  =cut  =cut
962  sub modification_time {  sub modification_time {
963          my ($self) = @_;          my ($self) = @_;
964          if (!defined($self->{_modification_time})) {          return $self->{_data}->modificationDate();
                 my $stats = $self->stats();  
                 if (defined($stats)) {  
                         $self->{_modification_time} = 0;  
                         if (defined($stats->{"Build date"}->[0]) && $self->{_modification_time} < $stats->{"Build date"}->[0]) {  
                                 $self->{_modification_time} = $stats->{"Build date"}->[0];  
                         } elsif (defined($stats->{"Gap fill date"}->[0]) && $self->{_modification_time} < $stats->{"Gap fill date"}->[0]) {  
                                 $self->{_modification_time} = $stats->{"Gap fill date"}->[0];  
                         }  
                 } else {  
                         $self->{_modification_time} = $self->{_data}->{date}->[0];  
                 }  
         }  
         return $self->{_modification_time};  
965  }  }
966    
967  =head3 gene_reactions  =head3 gene_reactions
# Line 727  Line 972 
972  =cut  =cut
973  sub gene_reactions {  sub gene_reactions {
974          my ($self) = @_;          my ($self) = @_;
975            return ($self->{_data}->reactions() - $self->{_data}->autoCompleteReactions() - $self->{_data}->spontaneousReactions() - $self->{_data}->gapFillReactions());
         if (!defined($self->{_gene_reactions})) {  
                 if ($self->source() =~ /^MGRAST/) {  
                         $self->set_metagenome_stats();  
                 } elsif (defined($self->stats())) {  
                         $self->{_gene_reactions} = $self->total_reactions() - $self->gapfilling_reactions() - $self->stats()->{'Spontaneous'}->[0] - $self->stats()->{'Growmatch reactions'}->[0] - $self->stats()->{'Biolog gap filling reactions'}->[0];  
                 }  
         }  
         return $self->{_gene_reactions};  
976  }  }
977    
978  =head3 total_compounds  =head3 total_compounds
# Line 746  Line 983 
983  =cut  =cut
984  sub total_compounds {  sub total_compounds {
985          my ($self) = @_;          my ($self) = @_;
986            return $self->{_data}->compounds();
         if (!defined($self->{_total_compounds})) {  
                 if ($self->source() =~ /^MGRAST/) {  
                         $self->set_metagenome_stats();  
                 } elsif (defined($self->stats())) {  
                         $self->{_total_compounds} = $self->stats()->{'Metabolites'}->[0];  
                 }  
         }  
         return $self->{_total_compounds};  
987  }  }
988    
989  =head3 gapfilling_reactions  =head3 gapfilling_reactions
# Line 765  Line 994 
994  =cut  =cut
995  sub gapfilling_reactions {  sub gapfilling_reactions {
996          my ($self) = @_;          my ($self) = @_;
997            return ($self->{_data}->autoCompleteReactions()+$self->{_data}->gapFillReactions());
         if (!defined($self->{_gapfilling_reactions})) {  
                 if ($self->source() =~ /^MGRAST/) {  
                         $self->set_metagenome_stats();  
                 } elsif (defined($self->stats())) {  
                         $self->{_gapfilling_reactions} = $self->stats()->{'Gap filling reactions'}->[0];  
                 }  
         }  
         return $self->{_gapfilling_reactions};  
998  }  }
999    
1000  =head3 total_reactions  =head3 total_reactions
# Line 784  Line 1005 
1005  =cut  =cut
1006  sub total_reactions {  sub total_reactions {
1007          my ($self) = @_;          my ($self) = @_;
1008            return $self->{_data}->reactions();
         if (!defined($self->{_total_reactions})) {  
                 if ($self->source() =~ /^MGRAST/) {  
                         $self->set_metagenome_stats();  
                 } elsif (defined($self->stats())) {  
                         $self->{_total_reactions} = $self->stats()->{'Number of reactions'}->[0];  
                 }  
         }  
         return $self->{_total_reactions};  
1009  }  }
1010    
1011  =head3 model_genes  =head3 model_genes
# Line 803  Line 1016 
1016  =cut  =cut
1017  sub model_genes {  sub model_genes {
1018          my ($self) = @_;          my ($self) = @_;
1019            return $self->{_data}->associatedGenes();
         if (!defined($self->{_model_genes})) {  
                 if ($self->source() =~ /^MGRAST/) {  
                         $self->set_metagenome_stats();  
                 } elsif (defined($self->stats())) {  
                         $self->{_model_genes} = $self->stats()->{'Genes with reactions'}->[0];  
                 }  
         }  
         return $self->{_model_genes};  
1020  }  }
1021    
1022  =head3 class  =head3 class
# Line 822  Line 1027 
1027  =cut  =cut
1028  sub class {  sub class {
1029          my ($self) = @_;          my ($self) = @_;
1030            return $self->{_data}->cellwalltype();
         if (!defined($self->{_class})) {  
                 if ($self->source() =~ /^MGRAST/) {  
                         $self->{_class} = "Other";  
                 } elsif (defined($self->stats())) {  
                         $self->{_class} = $self->stats()->{Class}->[0];  
                 }  
1031          }          }
1032          return $self->{_class};  
1033    sub autocompleteMedia {
1034            my ($self) = @_;
1035            return $self->{_data}->autoCompleteMedia();
1036  }  }
1037    
1038  =head3 taxonomy  =head3 taxonomy
# Line 898  Line 1100 
1100                          if (defined($self->mgdata())) {                          if (defined($self->mgdata())) {
1101                                  $self->{_genome_genes} = $self->mgdata()->genome_contig_count;                                  $self->{_genome_genes} = $self->mgdata()->genome_contig_count;
1102                          }                          }
1103                  } elsif (defined($self->stats())) {                  } else {
1104                          $self->{_genome_genes} = $self->stats()->{'Total genes'}->[0];                          $self->{_genome_genes} = $self->figmodel()->get_genome_stats($self->genome())->{"TOTAL GENES"}->[0];
1105                  }                  }
1106          }          }
1107    
# Line 916  Line 1118 
1118    
1119          #Assuming complete media if none is provided          #Assuming complete media if none is provided
1120          if (!defined($Media)) {          if (!defined($Media)) {
1121                  $Media = "Complete";                  $Media = $self->autocompleteMedia();
1122          }          }
1123    
1124          #Predicting essentiality          #Predicting essentiality
1125          my $result = $self->figmodel()->RunFBASimulation($self->id(),"SINGLEKO",undef,undef,[$self->id()],[$Media]);          my $result = $self->figmodel()->RunFBASimulation($self->id(),"SINGLEKO",undef,undef,[$self->id()],[$Media]);
1126          #Checking that the table is defined and the output file exists          #Checking that the table is defined and the output file exists
1127          if (defined($result) && defined($result->get_row(0)->{"ESSENTIALGENES"})) {          if (defined($result) && defined($result->get_row(0)->{"ESSENTIALGENES"})) {
1128                  $self->figmodel()->database()->print_array_to_file($self->directory()."EssentialGenes-".$self->id()."-".$Media.".tbl",[join("\n",@{$result->get_row(0)->{"ESSENTIALGENES"}})]);                  my $tbl = $self->essentials_table();
1129                    my $row = $tbl->get_row_by_key($Media,"MEDIA",1);
1130                    $row->{"ESSENTIAL GENES"} = $result->get_row(0)->{"ESSENTIALGENES"};
1131                    $tbl->save();
1132          } else {          } else {
1133                  $self->figmodel()->error_message("FIGMODELmodel:run_default_model_predictions:could not identify essential reactions for model ".$self->id().$self->selected_version().".");                  $self->figmodel()->error_message("FIGMODELmodel:run_default_model_predictions:could not identify essential reactions for model ".$self->id().$self->selected_version().".");
1134                  return $self->figmodel()->fail();                  return $self->figmodel()->fail();
# Line 940  Line 1145 
1145          return $self->figmodel()->success();          return $self->figmodel()->success();
1146  }  }
1147    
 =head3 save_obsolete_stats  
 Definition:  
         FIGMODELmodel->save_obsolete_stats();  
 Description:  
 =cut  
 sub save_obsolete_stats {  
         my ($self) = @_;  
   
         #checking if stats exists  
         my $stats = $self->stats();  
         if (defined($stats)) {  
                 $stats->{"Model ID"}->[0] = $self->id()."V".$stats->{"Version"}->[0].".".$stats->{"Gap fill version"}->[0];  
                 $self->figmodel()->database()->update_row("OBSOLETE MODEL STATS",$stats,"Model ID");  
                 $stats->{"Model ID"}->[0] = $self->id();  
         }  
 }  
   
1148  =head3 update_stats_for_gap_filling  =head3 update_stats_for_gap_filling
1149  Definition:  Definition:
1150          {string => [string]} = FIGMODELmodel->update_stats_for_gap_filling(int::gapfill time);          {string => [string]} = FIGMODELmodel->update_stats_for_gap_filling(int::gapfill time);
# Line 964  Line 1152 
1152  =cut  =cut
1153  sub update_stats_for_gap_filling {  sub update_stats_for_gap_filling {
1154          my ($self,$gapfilltime) = @_;          my ($self,$gapfilltime) = @_;
1155            $self->{_data}->autoCompleteTime($gapfilltime);
1156          #preserving the stats for the now obselete model          $self->{_data}->autocompleteDate(time());
1157          $self->save_obsolete_stats();          $self->{_data}->modificationDate(time());
1158          my $stats = $self->update_model_stats(0);          my $version = $self->{_data}->autocompleteVersion();
1159          $stats->{"Gap filling time"}->[0] = $gapfilltime;          $self->{_data}->autocompleteVersion($version+1);
         $stats->{"Gap fill date"}->[0] = time();  
         if (!defined($stats->{"Gap fill version"}->[0])) {  
                 $stats->{"Gap fill version"}->[0] = 0;  
         }  
         $stats->{"Gap fill version"}->[0]++;  
   
         #Updating the stats stored in the table  
         $self->figmodel()->database()->update_row("MODEL STATS",$stats,"Model ID");  
         return $stats;  
1160  }  }
1161    
1162  =head3 update_stats_for_build  =head3 update_stats_for_build
# Line 987  Line 1166 
1166  =cut  =cut
1167  sub update_stats_for_build {  sub update_stats_for_build {
1168          my ($self) = @_;          my ($self) = @_;
1169            $self->{_data}->builtDate(time());
1170          #preserving the stats for the now obselete model          $self->{_data}->modificationDate(time());
1171          $self->save_obsolete_stats();          my $version = $self->{_data}->version();
1172          my $stats = $self->update_model_stats(0);          $self->{_data}->version($version+1);
         $stats->{"Build date"}->[0] = time();  
         if (!defined($stats->{"Version"}->[0])) {  
                 $stats->{"Version"}->[0] = 0;  
         }  
         $stats->{"Version"}->[0]++;  
   
         #Updating the stats stored in the table  
         $self->figmodel()->database()->update_row("MODEL STATS",$stats,"Model ID");  
         return $stats;  
1173  }  }
1174    
1175  =head3 update_model_stats  =head3 update_model_stats
# Line 1018  Line 1188 
1188          }          }
1189          my $cpdtbl = $self->compound_table();          my $cpdtbl = $self->compound_table();
1190    
1191          #Creating empty status row          #Calculating all necessary stats
         my $CurrentStats = {"Genes with reactions" => [0],  
                                                  "Metabolites" => [$cpdtbl->size()],  
                                                  "Growmatch reactions" => [0],  
                                                  "Spontaneous" => [0],  
                                                  "Biolog gap filling reactions" => [0],  
                                                  "Number of reactions" => [$rxntbl->size()],  
                                                  "Transport reaction"=>[0],  
                                                  "Gap filling reactions" => [0],  
                                                  "Model ID" => [$self->id()],  
                                                  "Subsystem genes with reactions" => [0],  
                                                  "Nonsubsystem genes with reactions" => [0],  
                                                  Version => [0],  
                                                  "Gap fill version" => [0],  
                                                  Source => [$self->source()],  
                                                  "Genes with one reaction" => [0],  
                                                  "Genome ID" => [$self->genome()]};  
   
         my $genomestats = $self->figmodel()->get_genome_stats($self->genome());  
         if (defined($genomestats)) {  
                 $CurrentStats->{SOURCE}->[0] = $genomestats->{SOURCE}->[0];  
                 $CurrentStats->{"Organism name"}->[0] = $genomestats->{NAME}->[0];  
                 $CurrentStats->{"Total genes"}->[0] = $genomestats->{"TOTAL GENES"}->[0];  
                 $CurrentStats->{"Gram positive genes"}->[0] = $genomestats->{"GRAM POSITIVE GENES"}->[0];  
                 $CurrentStats->{"Gram negative genes"}->[0] = $genomestats->{"GRAM NEGATIVE GENES"}->[0];  
                 $CurrentStats->{"Class"}->[0] = $genomestats->{CLASS}->[0];  
                 $CurrentStats->{"Genes with functions"}->[0] = $genomestats->{"GENES WITH FUNCTIONS"}->[0];  
                 $CurrentStats->{"Subsystem genes"}->[0] = $genomestats->{"SUBSYSTEM GENES"}->[0];  
                 $CurrentStats->{"Nonsubsystem genes"}->[0] = $genomestats->{"NON SUBSYSTEM GENES"}->[0];  
                 if (defined($genomestats->{TAXONOMY})) {  
                         $CurrentStats->{"Taxonomy 0"}->[0] = $genomestats->{TAXONOMY}->[0];  
                         $CurrentStats->{"Taxonomy 1"}->[0] = $genomestats->{TAXONOMY}->[1];  
                         $CurrentStats->{"Taxonomy 2"}->[0] = $genomestats->{TAXONOMY}->[2];  
                         $CurrentStats->{"Taxonomy 3"}->[0] = $genomestats->{TAXONOMY}->[3];  
                         $CurrentStats->{"Taxonomy 4"}->[0] = $genomestats->{TAXONOMY}->[4];  
                         $CurrentStats->{"Taxonomy 5"}->[0] = $genomestats->{TAXONOMY}->[5];  
                 }  
         }  
   
         #Transfering build, version, and gap fill data from existing stats  
         if (defined($self->stats())) {  
                 $CurrentStats->{Version}->[0] = $self->stats()->{Version}->[0];  
                 $CurrentStats->{"Gap fill version"}->[0] = $self->stats()->{"Gap fill version"}->[0];  
                 $CurrentStats->{"Gap filling time"}->[0] = $self->stats()->{"Gap filling time"}->[0];  
                 $CurrentStats->{"Gap fill date"}->[0] = $self->stats()->{"Gap fill date"}->[0];  
                 $CurrentStats->{"Build date"}->[0] = $self->stats()->{"Build date"}->[0];  
         }  
   
1192          my %GeneHash;          my %GeneHash;
1193          my %NonpegHash;          my %NonpegHash;
1194          my %CompoundHash;          my %CompoundHash;
1195            my $spontaneousReactions = 0;
1196            my $gapFillReactions = 0;
1197            my $biologReactions = 0;
1198            my $transporters = 0;
1199            my $autoCompleteReactions = 0;
1200            my $associatedSubsystemGenes = 0;
1201          for (my $i=0; $i < $rxntbl->size(); $i++) {          for (my $i=0; $i < $rxntbl->size(); $i++) {
1202                  my $Row = $rxntbl->get_row($i);                  my $Row = $rxntbl->get_row($i);
1203                  if (defined($Row) && defined($Row->{"ASSOCIATED PEG"})) {                  if (defined($Row) && defined($Row->{"ASSOCIATED PEG"})) {
# Line 1076  Line 1205 
1205                          if (defined($ReactionRow->{"EQUATION"}->[0])) {                          if (defined($ReactionRow->{"EQUATION"}->[0])) {
1206                                  #Checking for extracellular metabolites which indicate that this is a transporter                                  #Checking for extracellular metabolites which indicate that this is a transporter
1207                                  if ($ReactionRow->{"EQUATION"}->[0] =~ m/\[e\]/) {                                  if ($ReactionRow->{"EQUATION"}->[0] =~ m/\[e\]/) {
1208                                          $CurrentStats->{"Transport reaction"}->[0]++;                                          $transporters++;
1209                                  }                                  }
1210                          }                          }
1211                          #Identifying spontaneous/biolog/gapfilling/gene associated reactions                          #Identifying spontaneous/biolog/gapfilling/gene associated reactions
1212                          if ($Row->{"ASSOCIATED PEG"}->[0] =~ m/BIOLOG/i) {                          if ($Row->{"ASSOCIATED PEG"}->[0] =~ m/BIOLOG/i) {
1213                                  $CurrentStats->{"Biolog gap filling reactions"}->[0]++;                                  $biologReactions++;
1214                            } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/GROW/i) {
1215                                    $gapFillReactions++;
1216                          } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/SPONTANEOUS/i) {                          } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/SPONTANEOUS/i) {
1217                                  $CurrentStats->{"Spontaneous"}->[0]++;                                  $spontaneousReactions++;
1218                          } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/GAP/ || $Row->{"ASSOCIATED PEG"}->[0] =~ m/UNIVERSAL/i || $Row->{"ASSOCIATED PEG"}->[0] =~ m/UNKNOWN/i) {                          } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/GAP/ || $Row->{"ASSOCIATED PEG"}->[0] =~ m/UNIVERSAL/i || $Row->{"ASSOCIATED PEG"}->[0] =~ m/UNKNOWN/i) {
1219                                  $CurrentStats->{"Gap filling reactions"}->[0]++;                                  $autoCompleteReactions++;
1220                          } else {                          } else {
1221                                  foreach my $GeneSet (@{$Row->{"ASSOCIATED PEG"}}) {                                  foreach my $GeneSet (@{$Row->{"ASSOCIATED PEG"}}) {
1222                                          $_ = $GeneSet;                                          $_ = $GeneSet;
# Line 1103  Line 1234 
1234          }          }
1235          my @genes = keys(%GeneHash);          my @genes = keys(%GeneHash);
1236          my @othergenes = keys(%NonpegHash);          my @othergenes = keys(%NonpegHash);
         $CurrentStats->{"Genes with reactions"}->[0] = @genes + @othergenes;  
1237    
1238          #Updating the stats stored in the table          #Setting the reaction count
1239          $self->figmodel()->database()->update_row("MODEL STATS",$CurrentStats,"Model ID");          $self->{_data}->reactions($rxntbl->size());
1240          $self->{_stats} = $CurrentStats;          #Setting the metabolite count
1241          return $CurrentStats;          $self->{_data}->compounds($cpdtbl->size());
1242            #Setting the gene count
1243            my $geneCount = @genes + @othergenes;
1244            $self->{_data}->associatedGenes($geneCount);
1245            #Setting remaining stats
1246            $self->{_data}->spontaneousReactions($spontaneousReactions);
1247            $self->{_data}->gapFillReactions($gapFillReactions);
1248            $self->{_data}->biologReactions($biologReactions);
1249            $self->{_data}->transporters($transporters);
1250            $self->{_data}->autoCompleteReactions($autoCompleteReactions);
1251            $self->{_data}->associatedSubsystemGenes($associatedSubsystemGenes);
1252            #Setting the model class
1253            my $class = "";
1254            for (my $i=0; $i < @{$self->figmodel()->config("class list")}; $i++) {
1255                    if (defined($self->figmodel()->config($self->figmodel()->config("class list")->[$i]))) {
1256                            if (defined($self->figmodel()->config($self->figmodel()->config("class list")->[$i])->{$self->id()})) {
1257                                    $class = $self->figmodel()->config("class list")->[$i];
1258                                    last;
1259                            }
1260                            if ($class eq "" && defined($self->figmodel()->config($self->figmodel()->config("class list")->[$i])->{$self->genome()})) {
1261                                    $class = $self->figmodel()->config("class list")->[$i];
1262                            }
1263                    }
1264            }
1265            if ($class eq "") {
1266                    $class = $self->figmodel()->get_genome_stats($self->genome())->{CLASS}->[0];
1267            }
1268            if ($class eq "") {
1269                    $class = "unknown";
1270            }
1271            $self->{_data}->cellwalltype($class);
1272  }  }
1273    
1274  =head3 GapFillModel  =head3 GapFillModel
# Line 1128  Line 1288 
1288          my $UniqueFilename = $self->figmodel()->filename();          my $UniqueFilename = $self->figmodel()->filename();
1289          my $StartTime = time();          my $StartTime = time();
1290    
1291          #Archiving the existing model          #Reading original reaction table
1292          $self->ArchiveModel();          my $OriginalRxn = $self->reaction_table();
1293            #Clearing the table
1294            $self->reaction_table(1);
1295    
1296          #Removing any gapfilling reactions that may be currently present in the model          #Removing any gapfilling reactions that may be currently present in the model
1297          if (!defined($donotclear) || $donotclear != 1) {          if (!defined($donotclear) || $donotclear != 1) {
1298                  my $ModelTable = $self->reaction_table();                  my $ModelTable = $self->reaction_table();
1299                  for (my $i=0; $i < $ModelTable->size(); $i++) {                  for (my $i=0; $i < $ModelTable->size(); $i++) {
1300                          if (!defined($ModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0]) || $ModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0] eq "GAP FILLING" || $ModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0] =~ m/BIOLOG/ || $ModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0] =~ m/GROWMATCH/) {                          if (!defined($ModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0]) || $ModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0] eq "AUTOCOMPLETION" || $ModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0] eq "GAP FILLING" || $ModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0] =~ m/BIOLOG/ || $ModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0] =~ m/GROWMATCH/) {
1301                                  $ModelTable->delete_row($i);                                  $ModelTable->delete_row($i);
1302                                  $i--;                                  $i--;
1303                          }                          }
# Line 1159  Line 1321 
1321                          }                          }
1322                  }                  }
1323                  $MediaTable->save($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");                  $MediaTable->save($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");
1324                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$UniqueFilename."TestMedia",["GapFilling"],{"Default max drain flux" => 0},"GapFill".$self->id().".log",undef));                  #print $self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$UniqueFilename."TestMedia",["GapFilling"],{"Default max drain flux" => 0,"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0]},"GapFill".$self->id().".log",undef)."\n";
1325                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$UniqueFilename."TestMedia",["GapFilling"],{"Default max drain flux" => 0,"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0]},"GapFill".$self->id().".log",undef));
1326                  unlink($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");                  unlink($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");
1327          } else {          } else {
1328                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),undef,["GapFilling"],undef,"GapFill".$self->id().".log",undef));                  #print $self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),undef,["GapFilling"],{"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0]},"GapFill".$self->id().".log",undef)."\n";
1329                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),undef,["GapFilling"],{"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0]},"GapFill".$self->id().".log",undef));
1330          }          }
1331    
1332          #Parse the solutions file for the model and get the reaction list from it          #Parse the solutions file for the model and get the reaction list from it
1333          my $SolutionData = $self->figmodel()->LoadProblemReport($UniqueFilename);          my $SolutionData = $self->figmodel()->LoadProblemReport($UniqueFilename);
1334    
1335          #Clearing the mfatoolkit output and log file          #Clearing the mfatoolkit output and log file
1336          $self->figmodel()->clearing_output($UniqueFilename,"GapFill".$self->id().".log");          $self->figmodel()->clearing_output($UniqueFilename,"GapFill".$self->id().".log");
1337          if (!defined($SolutionData) || $SolutionData->size() == 0) {          if (!defined($SolutionData) || $SolutionData->size() == 0) {
# Line 1202  Line 1367 
1367                                                  push(@{$ReactionList},$ID);                                                  push(@{$ReactionList},$ID);
1368                                          }                                          }
1369                                  }                                  }
1370                                  $self->figmodel()->IntegrateGrowMatchSolution($self->id(),undef,$ReactionList,$DirectionList,"GAP FILLING",0,1);                                  $self->figmodel()->IntegrateGrowMatchSolution($self->id(),undef,$ReactionList,$DirectionList,"AUTOCOMPLETION",0,1);
1371                          }                          }
1372                          last;                          last;
1373                  }                  }
1374          }          }
1375    
1376          #Updating model stats with gap filling results          #Updating model stats with gap filling results
1377          my $ElapsedTime = time() - $StartTime;          my $ElapsedTime = time() - $StartTime;
1378          $self->figmodel()->database()->ClearDBModel($self->id(),1);          $self->reaction_table(1);
1379            $self->calculate_model_changes($OriginalRxn,"AUTOCOMPLETION");
1380    
1381          #Determining why each gap filling reaction was added          #Determining why each gap filling reaction was added
1382          $self->figmodel()->IdentifyDependancyOfGapFillingReactions($self->id(),$Media);          $self->figmodel()->IdentifyDependancyOfGapFillingReactions($self->id(),$Media);
1383          if (!defined($donotclear) || $donotclear != 1) {          if (!defined($donotclear) || $donotclear != 1) {
                 $self->figmodel()->AddBiologTransporters($self->id());  
1384                  if ($self->id() !~ m/MGRast/) {                  if ($self->id() !~ m/MGRast/) {
1385                          $self->update_stats_for_gap_filling($ElapsedTime);                          $self->update_stats_for_gap_filling($ElapsedTime);
1386                  }                  }
1387          } else {          } else {
1388                  $self->update_model_stats();                  $self->update_model_stats();
1389            }
1390            #Printing the updated SBML file
1391            $self->PrintSBMLFile();
1392            $self->PrintModelLPFile($self->id());
1393            $self->set_status(1,"Auto completion successfully finished");
1394            $self->run_default_model_predictions();
1395    
1396            return $self->success();
1397    }
1398    
1399    =head3 calculate_model_changes
1400    Definition:
1401            FIGMODELmodel->calculate_model_changes(FIGMODELTable:original reaction table,string:modification cause);
1402    Description:
1403    
1404    =cut
1405    
1406    sub calculate_model_changes {
1407            my ($self,$originalReactions,$cause,$tbl,$version) = @_;
1408            my $modTime = time();
1409            if (!defined($version)) {
1410                    $version = $self->selected_version();
1411            }
1412            my $user = $self->figmodel()->user();
1413            #Getting the history table
1414            my $histTbl = $self->model_history();
1415            #Checking for differences
1416            if (!defined($tbl)) {
1417                    $tbl = $self->reaction_table();
1418            }
1419            for (my $i=0; $i < $tbl->size(); $i++) {
1420                    my $row = $tbl->get_row($i);
1421                    my $orgRow = $originalReactions->get_row_by_key($row->{LOAD}->[0],"LOAD");
1422                    if (!defined($orgRow)) {
1423                            $histTbl->add_row({Reaction => [$row->{LOAD}->[0]], DirectionChange => $row->{DIRECTIONALITY}, GeneChange => $row->{"ASSOCIATED PEG"}, Action => ["ADDED"], ModificationTime => [$modTime], ModifcationCause => [$cause], User => [$user], Version => [$version]});
1424                    } else {
1425                            my $geneChanges;
1426                            my $directionChange;
1427                            if ($orgRow->{"DIRECTIONALITY"}->[0] ne $row->{"DIRECTIONALITY"}->[0]) {
1428                                    $directionChange = $orgRow->{"DIRECTIONALITY"}->[0]." to ".$row->{"DIRECTIONALITY"}->[0];
1429                            }
1430                            for (my $j=0; $j < @{$row->{"ASSOCIATED PEG"}}; $j++) {
1431                                    my $match = 0;
1432                                    if (defined($orgRow->{"ASSOCIATED PEG"})) {
1433                                            for (my $k=0; $k < @{$orgRow->{"ASSOCIATED PEG"}}; $k++) {
1434                                                    if ($row->{"ASSOCIATED PEG"}->[$j] eq $orgRow->{"ASSOCIATED PEG"}->[$k]) {
1435                                                            $match = 1;
1436                                                    }
1437                                            }
1438                                    }
1439                                    if ($match == 0) {
1440                                            push(@{$geneChanges},"Added ".$row->{"ASSOCIATED PEG"}->[$j]);
1441                                    }
1442                            }
1443                            if (defined($orgRow->{"ASSOCIATED PEG"})) {
1444                                    for (my $k=0; $k < @{$orgRow->{"ASSOCIATED PEG"}}; $k++) {
1445                                            my $match = 0;
1446                                            if (defined($row->{"ASSOCIATED PEG"})) {
1447                                                    for (my $j=0; $j < @{$row->{"ASSOCIATED PEG"}}; $j++) {
1448                                                            if ($row->{"ASSOCIATED PEG"}->[$j] eq $orgRow->{"ASSOCIATED PEG"}->[$k]) {
1449                                                                    $match = 1;
1450                                                            }
1451                                                    }
1452                                            }
1453                                            if ($match == 0) {
1454                                                    push(@{$geneChanges},"Removed ".$orgRow->{"ASSOCIATED PEG"}->[$k]);
1455                                            }
1456                                    }
1457                            }
1458                            if ((defined($directionChange) && length($directionChange) > 0) || defined($geneChanges) && @{$geneChanges} > 0) {
1459                                    $histTbl->add_row({Reaction => [$row->{LOAD}->[0]], DirectionChange => [$directionChange], GeneChange => $geneChanges, Action => ["CHANGE"], ModificationTime => [$modTime], ModifcationCause => [$cause], User => [$user], Version => [$version]});
1460                            }
1461                    }
1462            }
1463            #Looking for removed reactions
1464            for (my $i=0; $i < $originalReactions->size(); $i++) {
1465                    my $row = $originalReactions->get_row($i);
1466                    my $orgRow = $tbl->get_row_by_key($row->{LOAD}->[0],"LOAD");
1467                    if (!defined($orgRow)) {
1468                            $histTbl->add_row({Reaction => [$row->{LOAD}->[0]], DirectionChange => $row->{DIRECTIONALITY}, GeneChange => $row->{"ASSOCIATED PEG"}, Action => ["REMOVED"], ModificationTime => [$modTime], ModifcationCause => [$cause], User => [$user], Version => [$version]});
1469                    }
1470            }
1471            $histTbl->save();
1472    }
1473    
1474    =head3 GapGenModel
1475    Definition:
1476            FIGMODELmodel->GapGenModel();
1477    Description:
1478            Runs the gap generation algorithm to correct a single false positive prediction. Results are loaded into a table.
1479    =cut
1480    
1481    sub GapGenModel {
1482            my ($self,$Media,$KOList,$NoKOList,$Experiment,$SolutionLimit) = @_;
1483    
1484            #Enforcing nonoptional arguments
1485            if (!defined($Media)) {
1486                    return undef;
1487            }
1488            if (!defined($KOList)) {
1489                    $KOList->[0] = "none";
1490            }
1491            if (!defined($NoKOList)) {
1492                    $NoKOList->[0] = "none";
1493            }
1494            if (!defined($Experiment)) {
1495                    $Experiment= "ReactionKO";
1496            }
1497            if (!defined($SolutionLimit)) {
1498                    $SolutionLimit = "10";
1499            }
1500    
1501            #Translating the KO lists into arrays
1502            if (ref($KOList) ne "ARRAY") {
1503                    my $temp = $KOList;
1504                    $KOList = ();
1505                    push(@{$KOList},split(/[,;]/,$temp));
1506            }
1507            my $noKOHash;
1508            if (defined($NoKOList) && ref($NoKOList) ne "ARRAY") {
1509                    my $temp = $NoKOList;
1510                    $NoKOList = ();
1511                    push(@{$NoKOList},split(/[,;]/,$temp));
1512                    foreach my $rxn (@{$NoKOList}) {
1513                            $noKOHash->{$rxn} = 1;
1514                    }
1515            }
1516    
1517            #Checking if solutions exist for the input parameters
1518            $self->aquireModelLock();
1519            my $tbl = $self->load_model_table("GapGenSolutions");
1520            my $solutionRow = $tbl->get_table_by_key($Experiment,"Experiment")->get_table_by_key($Media,"Media")->get_row_by_key(join(",",@{$KOList}),"KOlist");
1521            my $solutions;
1522            if (defined($solutionRow)) {
1523                    #Checking if any solutions conform to the no KO list
1524                    foreach my $solution (@{$solutionRow->{Solutions}}) {
1525                            my @reactions = split(/,/,$solution);
1526                            my $include = 1;
1527                            foreach my $rxn (@reactions) {
1528                                    if ($rxn =~ m/(rxn\d\d\d\d\d)/) {
1529                                            if (defined($noKOHash->{$1})) {
1530                                                    $include = 0;
1531                                            }
1532                                    }
1533                            }
1534                            if ($include == 1) {
1535                                    push(@{$solutions},$solution);
1536                            }
1537                    }
1538            } else {
1539                    $solutionRow = {Media => [$Media],Experiment => [$Experiment],KOlist => [join(",",@{$KOList})]};
1540                    $tbl->add_row($solutionRow);
1541                    $self->figmodel()->database()->save_table($tbl);
1542            }
1543            $self->releaseModelLock();
1544    
1545            #Returning solution list of solutions were found
1546            if (defined($solutions) && @{$solutions} > 0) {
1547                    return $solutions;
1548            }
1549    
1550            #Getting unique filename
1551            my $Filename = $self->figmodel()->filename();
1552    
1553            #Running the gap generation
1554            system($self->figmodel()->GenerateMFAToolkitCommandLineCall($Filename,$self->id().$self->selected_version(),$Media,["GapGeneration"],{"Recursive MILP solution limit" => $SolutionLimit ,"Reactions that should always be active" => join(";",@{$NoKOList}),"Reactions to knockout" => join(";",@{$KOList}),"Reactions that are always blocked" => "none"},"Gapgeneration-".$self->id().$self->selected_version()."-".$Filename.".log",undef,undef));
1555            my $ProblemReport = $self->figmodel()->LoadProblemReport($Filename);
1556            if (!defined($ProblemReport)) {
1557                    $self->figmodel()->error_message("FIGMODEL:GapGenerationAlgorithm;No problem report;".$Filename.";".$self->id().$self->selected_version().";".$Media.";".$KOList.";".$NoKOList);
1558                    return undef;
1559            }
1560    
1561            #Clearing the output folder and log file
1562            $self->figmodel()->clearing_output($Filename,"Gapgeneration-".$self->id().$self->selected_version()."-".$Filename.".log");
1563    
1564            #Saving the solution
1565            $self->aquireModelLock();
1566            $tbl = $self->load_model_table("GapGenSolutions");
1567            $solutionRow = $tbl->get_table_by_key($Experiment,"Experiment")->get_table_by_key($Media,"Media")->get_row_by_key(join(",",@{$KOList}),"KOlist");
1568            for (my $j=0; $j < $ProblemReport->size(); $j++) {
1569                    if ($ProblemReport->get_row($j)->{"Notes"}->[0] =~ m/^Recursive\sMILP\s([^)]+)/) {
1570                            my @SolutionList = split(/\|/,$1);
1571                            for (my $k=0; $k < @SolutionList; $k++) {
1572                                    if ($SolutionList[$k] =~ m/(\d+):(.+)/) {
1573                                            push(@{$solutionRow->{Solutions}},$2);
1574                                            push(@{$solutions},$2);
1575                                    }
1576                            }
1577                    }
1578          }          }
1579          #Printing the updated SBML file          $self->figmodel()->database()->save_table($tbl);
1580          $self->PrintSBMLFile();          $self->releaseModelLock();
         $self->PrintModelLPFile($self->id());  
         $self->set_status(1,"Auto completion successfully finished");  
         $self->run_default_model_predictions();  
1581    
1582          return $self->success();          return $solutions;
1583  }  }
1584    
1585  =head3 datagapfill  =head3 datagapfill
# Line 1260  Line 1613 
1613          return undef;          return undef;
1614  }  }
1615    
 =head3 datagapgen  
 Definition:  
         $model->datagapgen($NumberOfProcessors,$ProcessorIndex,$Filename);  
 =cut  
   
 sub datagapgen {  
         my ($self,$Media,$KOList,$NoKOList,$suffix) = @_;  
         #Setting default values for inputs  
         if (!defined($NoKOList)) {  
                 $NoKOList = "none";  
         }  
         if (!defined($KOList)) {  
                 $KOList = "none";  
         }  
         #Getting unique filename  
         my $Filename = $self->figmodel()->filename();  
         if (!defined($suffix)) {  
                 $suffix = "-".$Media."-".$KOList."-S";  
         }  
         $KOList =~ s/,/;/g;  
         $NoKOList =~ s/,/;/g;  
         #Running the gap generation  
         system($self->figmodel()->GenerateMFAToolkitCommandLineCall($Filename,$self->id().$self->selected_version(),$Media,["GapGeneration"],{"Reactions that should always be active" => $NoKOList,"Reactions to knockout" => $KOList,"Reactions that are always blocked" => "none"},"Gapgeneration-".$self->id().$self->selected_version()."-".$Filename.".log",undef,undef));  
         my $ProblemReport = $self->figmodel()->LoadProblemReport($Filename);  
         if (!defined($ProblemReport)) {  
                 $self->figmodel()->error_message("FIGMODEL:GapGenerationAlgorithm;No problem report;".$Filename.";".$self->id().$self->selected_version().";".$Media.";".$KOList.";".$NoKOList);  
                 return undef;  
         }  
         #Clearing the output folder and log file  
         $self->figmodel()->clearing_output($Filename,$self->directory()."Gapgeneration-".$self->id().$self->selected_version()."-".$Filename.".log");  
         #Scheduling the testing of this gap filling solution  
         my $Tbl = FIGMODELTable->new(["Experiment","Solution index","Solution cost","Solution reactions"],$self->directory().$self->id().$self->selected_version()."-GG".$suffix.".txt",undef,";","|",undef);  
         for (my $j=0; $j < $ProblemReport->size(); $j++) {  
                 if ($ProblemReport->get_row($j)->{"Notes"}->[0] =~ m/^Recursive\sMILP\s([^)]+)/) {  
                         my @SolutionList = split(/\|/,$1);  
                         for (my $k=0; $k < @SolutionList; $k++) {  
                                 if ($SolutionList[$k] =~ m/(\d+):(.+)/) {  
                                         $Tbl->add_row({"Experiment"=>[$Media],"Solution index"=>[$k],"Solution cost"=>[$1],"Solution reactions"=>[$2]});  
                                 }  
                         }  
                 }  
         }  
         return $Tbl;  
 }  
   
1616  =head3 TestSolutions  =head3 TestSolutions
1617  Definition:  Definition:
1618          $model->TestSolutions($ModelID,$NumProcessors,$ProcessorIndex,$GapFill);          $model->TestSolutions($ModelID,$NumProcessors,$ProcessorIndex,$GapFill);
# Line 1400  Line 1708 
1708  =cut  =cut
1709  sub status {  sub status {
1710          my ($self) = @_;          my ($self) = @_;
1711          return $self->{_data}->{status}->[0];          return $self->{_data}->status();
1712  }  }
1713    
1714  =head3 message  =head3 message
# Line 1411  Line 1719 
1719  =cut  =cut
1720  sub message {  sub message {
1721          my ($self) = @_;          my ($self) = @_;
1722          return $self->{_data}->{message}->[0];          return $self->{_data}->message();
1723  }  }
1724    
1725  =head3 set_status  =head3 set_status
# Line 1426  Line 1734 
1734  =cut  =cut
1735  sub set_status {  sub set_status {
1736          my ($self,$NewStatus,$Message) = @_;          my ($self,$NewStatus,$Message) = @_;
1737            $self->{_data}->status($NewStatus);
1738          #Getting the model row from the MODELS table          $self->{_data}->message($Message);
         $self->{_data}->{status}->[0] = $NewStatus;  
         $self->{_data}->{message}->[0] = $Message;  
         $self->figmodel()->database()->update_row("MODELS",$self->{_data},"id");  
1739          return $self->config("SUCCESS")->[0];          return $self->config("SUCCESS")->[0];
1740  }  }
1741    
# Line 1469  Line 1774 
1774          }          }
1775          #Setting up needed variables          #Setting up needed variables
1776          my $OriginalModelTable = undef;          my $OriginalModelTable = undef;
1777          #Locking model status table          if ($self->status() == 0) {
         my $ModelTable = $self->figmodel()->database()->LockDBTable("MODELS");  
         my $Row = $ModelTable->get_row_by_key($self->id(),"id");  
         if (!defined($Row) || !defined($Row->{status}->[0])) {  
                 $self->figmodel()->database()->UnlockDBTable("MODELS");  
                 $self->figmodel()->error_message("FIGMODEL:CreateSingleGenomeReactionList: ".$self->id()." has no row in models table!");  
                 return $self->fail();  
         } elsif ($Row->{status}->[0] == 0) {  
1778                  $self->figmodel()->error_message("FIGMODEL:CreateSingleGenomeReactionList:Model is already being built. Canceling current build.");                  $self->figmodel()->error_message("FIGMODEL:CreateSingleGenomeReactionList:Model is already being built. Canceling current build.");
                 $self->figmodel()->database()->UnlockDBTable("MODELS");  
1779                  return $self->fail();                  return $self->fail();
1780          }elsif ($Row->{status}->[0] == 1) {          }elsif ($self->status() == 1) {
1781                  $OriginalModelTable = $self->reaction_table();                  $OriginalModelTable = $self->reaction_table();
1782                  $self->ArchiveModel();                  $self->set_status(0,"Rebuilding preliminary reconstruction");
                 $Row->{status}->[0] = 0;  
                 $Row->{message}->[0] = "Rebuilding preliminary reconstruction";  
1783          } else {          } else {
1784                  $Row->{status}->[0] = 0;                  $self->set_status(0,"Preliminary reconstruction");
                 $Row->{message}->[0] = "Preliminary reconstruction";  
1785          }          }
         #Updating the status table  
         $self->figmodel()->database()->save_table($ModelTable);  
         $self->figmodel()->database()->UnlockDBTable("MODELS");  
1786          #Sorting GenomeData by gene location on the chromosome          #Sorting GenomeData by gene location on the chromosome
1787            my $ftrTbl = $self->figmodel()->database()->get_table("ROLERXNMAPPING");
1788          $FeatureTable->sort_rows("MIN LOCATION");          $FeatureTable->sort_rows("MIN LOCATION");
1789          my ($ComplexHash,$SuggestedMappings,$UnrecognizedReactions,$ReactionHash);          my ($ComplexHash,$SuggestedMappings,$UnrecognizedReactions,$ReactionHash);
1790          my %LastGenePosition;          my %LastGenePosition;
# Line 1564  Line 1856 
1856                          }                          }
1857                  }                  }
1858          }          }
   
1859          #Creating nonadjacent complexes          #Creating nonadjacent complexes
1860          my @ReactionList = keys(%{$ReactionHash});          my @ReactionList = keys(%{$ReactionHash});
1861          foreach my $Reaction (@ReactionList) {          foreach my $Reaction (@ReactionList) {
# Line 1670  Line 1961 
1961                  $NewModelTable->add_row({"LOAD" => [$ReactionID],"DIRECTIONALITY" => [$Directionality],"COMPARTMENT" => ["c"],"ASSOCIATED PEG" => [join("|",@{$ReactionHash->{$ReactionID}->{"GENES"}})],"SUBSYSTEM" => [$Subsystem],"CONFIDENCE" => [$ReactionHash->{$ReactionID}->{"CONFIDENCE"}->[0]],"REFERENCE" => [$Source],"NOTES" => ["NONE"]});                  $NewModelTable->add_row({"LOAD" => [$ReactionID],"DIRECTIONALITY" => [$Directionality],"COMPARTMENT" => ["c"],"ASSOCIATED PEG" => [join("|",@{$ReactionHash->{$ReactionID}->{"GENES"}})],"SUBSYSTEM" => [$Subsystem],"CONFIDENCE" => [$ReactionHash->{$ReactionID}->{"CONFIDENCE"}->[0]],"REFERENCE" => [$Source],"NOTES" => ["NONE"]});
1962          }          }
1963    
1964            #Getting feature rows for features that are lumped
1965            my @rows = $ftrTbl->get_rows_by_key("2","MASTER");
1966            for (my $i=0; $i < @rows; $i++) {
1967                    my $rxn = $rows[$i]->{REACTION}->[0];
1968                    my $role = $rows[$i]->{ROLE}->[0];
1969                    my @orgrows = $FeatureTable->get_rows_by_key($role,"ROLES");
1970                    my $genes;
1971                    for (my $j=0; $j < @orgrows; $j++) {
1972                            if ($orgrows[$j]->{ID}->[0] =~ m/(peg\.\d+)/) {
1973                                    push(@{$genes},$1);
1974                            }
1975                    }
1976                    if (defined($genes) && @{$genes} > 0) {
1977                            my $row = $NewModelTable->get_row_by_key($rxn,"LOAD");
1978                            my $newGeneAssociations;
1979                            for (my $k=0; $k < @{$genes}; $k++) {
1980                                    for (my $j=0; $j < @{$row->{"ASSOCIATED PEG"}}; $j++) {
1981                                            my $peg = $genes->[$k];
1982                                            if ($row->{"ASSOCIATED PEG"}->[$j] !~ m/$peg/) {
1983                                                    push(@{$newGeneAssociations},$row->{"ASSOCIATED PEG"}->[$j]."+".$peg);
1984                                            }
1985                                    }
1986                            }
1987                            $row->{"ASSOCIATED PEG"} = $newGeneAssociations;
1988                    }
1989            }
1990    
1991          #Adding the spontaneous and universal reactions          #Adding the spontaneous and universal reactions
1992          foreach my $ReactionID (@{$self->config("spontaneous reactions")}) {          foreach my $ReactionID (@{$self->config("spontaneous reactions")}) {
1993                  #Getting the thermodynamic reversibility from the database                  #Getting the thermodynamic reversibility from the database
# Line 1689  Line 2007 
2007          }          }
2008    
2009          #Checking if a biomass reaction already exists          #Checking if a biomass reaction already exists
2010          my $BiomassReactionRow = $self->figmodel()->database()->get_row_by_key("BIOMASS TABLE",$self->id(),"MODELS");          my $BiomassReactionRow = $self->BuildSpecificBiomassReaction();
         if (!defined($BiomassReactionRow)) {  
                 $BiomassReactionRow = $self->BuildSpecificBiomassReaction();  
2011                  if (!defined($BiomassReactionRow)) {                  if (!defined($BiomassReactionRow)) {
2012                          $self->set_status(-2,"Preliminary reconstruction failed: could not generate biomass reaction");                          $self->set_status(-2,"Preliminary reconstruction failed: could not generate biomass reaction");
2013                          $self->figmodel()->error_message("FIGMODEL:CreateModelReactionList: Could not generate biomass function for ".$self->id()."!");                          $self->figmodel()->error_message("FIGMODEL:CreateModelReactionList: Could not generate biomass function for ".$self->id()."!");
2014                          return $self->fail();                          return $self->fail();
2015                  }                  }
         }  
2016          my $ReactionList = $BiomassReactionRow->{"ESSENTIAL REACTIONS"};          my $ReactionList = $BiomassReactionRow->{"ESSENTIAL REACTIONS"};
2017          push(@{$ReactionList},$BiomassReactionRow->{DATABASE}->[0]);          push(@{$ReactionList},$BiomassReactionRow->{DATABASE}->[0]);
2018    
# Line 1729  Line 2044 
2044                  }                  }
2045          }          }
2046    
2047            #If an original model exists, we copy the gap filling solution from that model
2048            if (defined($OriginalModelTable)) {
2049                    for (my $i=0; $i < $OriginalModelTable->size(); $i++) {
2050                            if ($OriginalModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0] =~ m/GAP/ && $OriginalModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0] ne "INITIAL GAP FILLING") {
2051                                    my $Row = $NewModelTable->get_row_by_key($OriginalModelTable->get_row($i)->{"LOAD"}->[0],"LOAD");
2052                                    if (!defined($Row)) {
2053                                            $NewModelTable->add_row($OriginalModelTable->get_row($i));
2054                                    }
2055                            }
2056                    }
2057            }
2058    
2059          #Now we compare the model to the previous model to determine if any differences exist that aren't gap filling reactions          #Now we compare the model to the previous model to determine if any differences exist that aren't gap filling reactions
2060          if (defined($OriginalModelTable)) {          if (defined($OriginalModelTable)) {
2061                  my $PerfectMatch = 1;                  my $PerfectMatch = 1;
# Line 1788  Line 2115 
2115          #Saving the new model to file          #Saving the new model to file
2116          $self->set_status(1,"Preliminary reconstruction complete");          $self->set_status(1,"Preliminary reconstruction complete");
2117          $self->figmodel()->database()->save_table($NewModelTable);          $self->figmodel()->database()->save_table($NewModelTable);
2118          $self->{_reaction_data} = $NewModelTable;          $self->reaction_table(1);
         #Clearing the previous model from the cache  
         $self->figmodel()->database()->ClearDBModel($self->id(),1);  
2119          #Updating the model stats table          #Updating the model stats table
2120          $self->update_stats_for_build();          $self->update_stats_for_build();
2121          $self->PrintSBMLFile();          $self->PrintSBMLFile();
2122            if (defined($OriginalModelTable)) {
2123                    $self->calculate_model_changes($OriginalModelTable,"REBUILD");
2124            }
2125    
2126          #Adding model to gapfilling queue          #Adding model to gapfilling queue
2127          if (defined($RunGapFilling) && $RunGapFilling == 1) {          if (defined($RunGapFilling) && $RunGapFilling == 1) {
# Line 1812  Line 2140 
2140    
2141  sub CreateMetaGenomeReactionList {  sub CreateMetaGenomeReactionList {
2142          my ($self) = @_;          my ($self) = @_;
   
2143          #Checking if the metagenome file exists          #Checking if the metagenome file exists
2144          if (!-e $self->config("raw MGRAST directory")->[0].$self->genome().".summary") {          if (!-e $self->config("raw MGRAST directory")->[0].$self->genome().".summary") {
2145                  $self->error_message("FIGMODEL:CreateMetaGenomeReactionList: could not find raw data file for metagenome ".$self->genome());                  $self->error_message("FIGMODEL:CreateMetaGenomeReactionList: could not find raw data file for metagenome ".$self->genome());
2146                    return $self->fail();
2147          }          }
2148          #Loading metagenome data          #Loading metagenome data
2149          my $MGRASTData = $self->figmodel()->database()->load_multiple_column_file($self->config("raw MGRAST directory")->[0].$self->genome().".summary","\t");          my $MGRASTData = $self->figmodel()->database()->load_multiple_column_file($self->config("raw MGRAST directory")->[0].$self->genome().".summary","\t");
2150          if (!defined($MGRASTData)) {          if (!defined($MGRASTData)) {
2151                  $self->error_message("FIGMODEL:CreateMetaGenomeReactionList: could not find raw data file for metagenome ".$self->genome());                  $self->error_message("FIGMODEL:CreateMetaGenomeReactionList: could not find raw data file for metagenome ".$self->genome());
2152                    return $self->fail();
2153          }          }
   
2154          #Setting up needed variables          #Setting up needed variables
2155          my $OriginalModelTable = undef;          my $OriginalModelTable = undef;
   
2156          #Checking status          #Checking status
2157          if ($self->status() < 0) {          if ($self->status() < 0) {
2158                  $self->set_status(0,"Preliminary reconstruction");                  $self->set_status(0,"Preliminary reconstruction");
# Line 1837  Line 2164 
2164                  $self->ArchiveModel();                  $self->ArchiveModel();
2165                  $self->set_status(0,"Rebuilding preliminary reconstruction");                  $self->set_status(0,"Rebuilding preliminary reconstruction");
2166          }          }
2167            #Creating a hash of escores and pegs associated with each role
2168            my $rolePegHash;
2169            my $roleEscores;
2170            for (my $i=0; $i < @{$MGRASTData};$i++) {
2171                    #MD5,PEG,number of sims,role,sim e-scores,max escore,min escore,ave escore,stdev escore,ave exponent,stddev exponent
2172                    $rolePegHash->{$MGRASTData->[$i]->[3]}->{substr($MGRASTData->[$i]->[1],4)} = 1;
2173                    push(@{$roleEscores->{$MGRASTData->[$i]->[3]}},split(/;/,$MGRASTData->[$i]->[4]));
2174            }
2175          #Getting the reaction table          #Getting the reaction table
2176          my $ReactionTable = $self->figmodel()->database()->GetDBTable("REACTIONS");          my $ReactionTable = $self->figmodel()->database()->get_table("REACTIONS");
2177          #Creating model table          #Creating model table
2178          my $ModelTable = FIGMODELTable->new(["LOAD","DIRECTIONALITY","COMPARTMENT","ASSOCIATED PEG","SUBSYSTEM","CONFIDENCE","REFERENCE","NOTES"],$self->directory().$self->id().".txt",["LOAD"],";","|","REACTIONS\n");          my $ModelTable = $self->create_table_prototype("ModelReactions");
2179          for (my $i=0; $i < @{$MGRASTData};$i++) {          print $ModelTable->filename();
2180                  #MD5,PEG,number of sims,role,sim e-scores          my @roles = keys(%{$rolePegHash});
2181                  my $Role = $MGRASTData->[$i]->[3];          for (my $i=0; $i < @roles; $i++) {
2182                  my $MD5 = $MGRASTData->[$i]->[0];                  my $min = -1;
2183                  my $peg = $MGRASTData->[$i]->[1];                  my $max = -1;
2184                  my $sims = $MGRASTData->[$i]->[4];                  my $count = @{$roleEscores->{$roles[$i]}};
2185                  $sims =~ s/;/,/g;                  my $ave = 0;
2186                    my $stdev = 0;
2187                    my $aveexp = 0;
2188                    my $stdevexp = 0;
2189                    for (my $j=0; $j < @{$roleEscores->{$roles[$i]}}; $j++) {
2190                            if ($roleEscores->{$roles[$i]} < $min || $min == -1) {
2191                                    $min = $roleEscores->{$roles[$i]};
2192                            }
2193                            if ($roleEscores->{$roles[$i]} > $max || $max == -1) {
2194                                    $max = $roleEscores->{$roles[$i]};
2195                            }
2196                            $ave += $roleEscores->{$roles[$i]}->[$j];
2197                            if ($roleEscores->{$roles[$i]}->[$j] =~ m/e(-\d+$)/) {
2198                                    $aveexp += $1;
2199                            }
2200                    }
2201                    $ave = $ave/$count;
2202                    $aveexp = $aveexp/$count;
2203                    for (my $j=0; $j < @{$roleEscores->{$roles[$i]}}; $j++) {
2204                            $stdev += ($roleEscores->{$roles[$i]}->[$j]-$ave)*($roleEscores->{$roles[$i]}->[$j]-$ave);
2205                            if ($roleEscores->{$roles[$i]}->[$j] =~ m/e(-\d+$)/) {
2206                                    $stdevexp += ($1-$aveexp)*($1-$aveexp);
2207                            }
2208                    }
2209                    $stdev = sqrt($stdev/$count);
2210                    $stdevexp = sqrt($stdevexp/$count);
2211                  #Checking for subsystems                  #Checking for subsystems
2212                  my $GeneSubsystems = $self->figmodel()->subsystems_of_role($Role);                  my $GeneSubsystems = $self->figmodel()->subsystems_of_role($roles[$i]);
2213                  #Checking if there are reactions associated with this role                  #Checking if there are reactions associated with this role
2214                  my $ReactionHashArrayRef = $self->figmodel()->reactions_of_role($Role);                  my $ReactionHashArrayRef = $self->figmodel()->reactions_of_role($roles[$i]);
2215                  if ($ReactionHashArrayRef != 0) {                  if ($ReactionHashArrayRef != 0) {
2216                          foreach my $Mapping (@{$ReactionHashArrayRef}) {                          foreach my $Mapping (@{$ReactionHashArrayRef}) {
2217                                  if (defined($Mapping->{"REACTION"}) && defined($Mapping->{"MASTER"}) && defined($Mapping->{"SUBSYSTEM"}) && defined($Mapping->{"SOURCE"})) {                                  if (defined($Mapping->{"REACTION"}) && defined($Mapping->{"MASTER"}) && defined($Mapping->{"SUBSYSTEM"}) && defined($Mapping->{"SOURCE"})) {
# Line 1865  Line 2223 
2223                                                                  $ReactionRow = {"LOAD" => [$Mapping->{"REACTION"}->[0]],"DIRECTIONALITY" => [$self->figmodel()->reversibility_of_reaction($Mapping->{"REACTION"}->[0])],"COMPARTMENT" => ["c"]};                                                                  $ReactionRow = {"LOAD" => [$Mapping->{"REACTION"}->[0]],"DIRECTIONALITY" => [$self->figmodel()->reversibility_of_reaction($Mapping->{"REACTION"}->[0])],"COMPARTMENT" => ["c"]};
2224                                                                  $ModelTable->add_row($ReactionRow);                                                                  $ModelTable->add_row($ReactionRow);
2225                                                          }                                                          }
2226                                                          push(@{$ReactionRow->{"ASSOCIATED PEG"}},substr($peg,4));                                                          my %pegHash = %{$rolePegHash->{$roles[$i]}};
2227                                                          push(@{$ReactionRow->{"REFERENCE"}},$MD5.":".$Role);                                                          if (defined($ReactionRow->{"ASSOCIATED PEG"})) {
2228                                                          push(@{$ReactionRow->{"CONFIDENCE"}},$sims);                                                                  for (my $j=0; $j < @{$ReactionRow->{"ASSOCIATED PEG"}}; $j++) {
2229                                                                            $pegHash{$ReactionRow->{"ASSOCIATED PEG"}->[$j]} = 1;
2230                                                                    }
2231                                                            }
2232                                                            delete $ReactionRow->{"ASSOCIATED PEG"};
2233                                                            push(@{$ReactionRow->{"ASSOCIATED PEG"}},keys(%pegHash));
2234                                                            push(@{$ReactionRow->{"REFERENCE"}},$count.":".$ave.":".$stdev.":".$aveexp.":".$stdevexp.":".$min.":".$max);
2235                                                          if (defined($GeneSubsystems)) {                                                          if (defined($GeneSubsystems)) {
2236                                                                  push(@{$ReactionRow->{"SUBSYSTEM"}},@{$GeneSubsystems});                                                                  push(@{$ReactionRow->{"SUBSYSTEM"}},@{$GeneSubsystems});
2237                                                          }                                                          }
# Line 1927  Line 2291 
2291  sub ArchiveModel {  sub ArchiveModel {
2292          my ($self) = @_;          my ($self) = @_;
2293    
         #Making sure the model exists  
         if (!defined($self->stats())) {  
                 $self->figmodel()->error_message("FIGMODEL:ArchiveModel: Could not find specified ".$self->id()." in database!");  
                 return $self->fail();  
         }  
   
2294          #Checking that the model file exists          #Checking that the model file exists
2295          if (!(-e $self->filename())) {          if (!(-e $self->filename())) {
2296                  $self->figmodel()->error_message("FIGMODEL:ArchiveModel: Model file ".$self->filename()." not found!");                  $self->figmodel()->error_message("FIGMODEL:ArchiveModel: Model file ".$self->filename()." not found!");
# Line 2299  Line 2657 
2657          Calculating growth in the input media          Calculating growth in the input media
2658  =cut  =cut
2659  sub calculate_growth {  sub calculate_growth {
2660          my ($self,$Media) = @_;          my ($self,$Media,$outputDirectory,$InParameters,$saveLPFile) = @_;
2661            #Setting the Media
2662            if (!defined($Media) || length($Media) == 0) {
2663                    $Media = $self->autocompleteMedia();
2664            }
2665            #Setting parameters for the run
2666            my $DefaultParameters = $self->figmodel()->defaultParameters();
2667            if (defined($InParameters)) {
2668                    my @parameters = keys(%{$InParameters});
2669                    for (my $i=0; $i < @parameters; $i++) {
2670                            $DefaultParameters->{$parameters[$i]} = $InParameters->{$parameters[$i]};
2671                    }
2672            }
2673            $DefaultParameters->{"optimize metabolite production if objective is zero"} = 1;
2674            #Setting filenames
2675          my $UniqueFilename = $self->figmodel()->filename();          my $UniqueFilename = $self->figmodel()->filename();
2676          system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$Media,["ProductionMFA"],{"optimize metabolite production if objective is zero" => 1},$self->id()."-".$Media."-GrowthTest.txt",undef,$self->selected_version()));          if (!defined($outputDirectory)) {
2677                    $outputDirectory = $self->config("database message file directory")->[0];
2678            }
2679            my $fluxFilename = $outputDirectory."Fluxes-".$self->id()."-".$Media.".txt";
2680            my $cpdFluxFilename = $outputDirectory."CompoundFluxes-".$self->id()."-".$Media.".txt";
2681            #Running FBA
2682            #print $self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$Media,["ProductionMFA"],$DefaultParameters,$self->id()."-".$Media."-GrowthTest.txt",undef,$self->selected_version())."\n";
2683            system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$Media,["ProductionMFA"],$DefaultParameters,$self->id()."-".$Media."-GrowthTest.txt",undef,$self->selected_version()));
2684            #Saving LP file if requested
2685            if (defined($saveLPFile) && $saveLPFile == 1 && -e $self->figmodel()->{"MFAToolkit output directory"}->[0].$UniqueFilename."/CurrentProblem.lp") {
2686                    system("cp ".$self->figmodel()->config("MFAToolkit output directory")->[0].$UniqueFilename."/CurrentProblem.lp ".$self->directory().$self->id().".lp");
2687            }
2688          my $ProblemReport = $self->figmodel()->LoadProblemReport($UniqueFilename);          my $ProblemReport = $self->figmodel()->LoadProblemReport($UniqueFilename);
2689          my $Result;          my $Result;
2690          if (defined($ProblemReport)) {          if (defined($ProblemReport)) {
2691                  my $Row = $ProblemReport->get_row(0);                  my $Row = $ProblemReport->get_row(0);
2692                  if (defined($Row) && defined($Row->{"Objective"}->[0])) {                  if (defined($Row) && defined($Row->{"Objective"}->[0])) {
2693                          if ($Row->{"Objective"}->[0] < 0.00000001) {                          if ($Row->{"Objective"}->[0] < 0.00000001 || $Row->{"Objective"}->[0] == 1e7) {
2694                                  $Result = "NOGROWTH:".$Row->{"Individual metabolites with zero production"}->[0];                                  $Result = "NOGROWTH";
2695                                    if (defined($Row->{"Individual metabolites with zero production"}->[0]) && $Row->{"Individual metabolites with zero production"}->[0] =~ m/cpd\d\d\d\d\d/) {
2696                                            $Result .= ":".$Row->{"Individual metabolites with zero production"}->[0];
2697                                    }
2698                          } else {                          } else {
2699                                    if (-e $self->figmodel()->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/SolutionReactionData0.txt") {
2700                                            system("cp ".$self->figmodel()->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/SolutionReactionData0.txt ".$fluxFilename);
2701                                            system("cp ".$self->figmodel()->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/SolutionCompoundData0.txt ".$cpdFluxFilename);
2702                                    }
2703                                  $Result = $Row->{"Objective"}->[0];                                  $Result = $Row->{"Objective"}->[0];
2704                          }                          }
2705                  }                  }
2706          }          }
2707            #Deleting files if necessary
2708            if ($self->figmodel()->config("preserve all log files")->[0] ne "yes") {
2709                    $self->figmodel()->cleardirectory($UniqueFilename);
2710                    unlink($self->figmodel()->config("database message file directory")->[0].$self->id()."-".$Media."-GrowthTest.txt");
2711            }
2712            #Returning result
2713          return $Result;          return $Result;
2714  }  }
2715    
# Line 3337  Line 3733 
3733          my $OrganismID = $self->genome();          my $OrganismID = $self->genome();
3734          #Checking for a biomass override          #Checking for a biomass override
3735          if (defined($self->config("biomass reaction override")->{$OrganismID})) {          if (defined($self->config("biomass reaction override")->{$OrganismID})) {
3736                  $biomassrxn = $self->config("biomass reaction override")->{$OrganismID};                  my $biomassID = $self->config("biomass reaction override")->{$OrganismID};
3737                  print "Overriding biomass template and selecting ".$biomassrxn." for ".$OrganismID.".\n";                  my $tbl = $self->database()->get_table("BIOMASS",1);
3738                    $biomassrxn = $tbl->get_row_by_key($biomassID,"DATABASE");
3739                    print "Overriding biomass template and selecting ".$biomassID." for ".$OrganismID.".\n";
3740          } else {#Creating biomass reaction from the template          } else {#Creating biomass reaction from the template
3741                  #Getting the genome stats                  #Getting the genome stats
3742                  my $genomestats = $self->figmodel()->get_genome_stats($self->genome());                  my $genomestats = $self->figmodel()->get_genome_stats($self->genome());
# Line 3629  Line 4027 
4027    
4028                  #Adding the biomass equation to the biomass table                  #Adding the biomass equation to the biomass table
4029                  my $NewRow = $self->figmodel()->add_biomass_reaction($Equation,$self->id(),"Template:".$self->genome());                  my $NewRow = $self->figmodel()->add_biomass_reaction($Equation,$self->id(),"Template:".$self->genome());
4030                  $biomassrxn = $NewRow->{DATABASE}->[0];                  $biomassrxn = $NewRow;
                 print $biomassrxn."\n";  
4031          }          }
4032          print $biomassrxn."\n";          return $biomassrxn;
         my $BiomassRow = $self->figmodel()->add_model_to_biomass_reaction($biomassrxn,$self->id());  
         return $BiomassRow;  
4033  }  }
4034    
4035  =head3 PrintSBMLFile  =head3 PrintSBMLFile
# Line 3647  Line 4042 
4042          my($self) = @_;          my($self) = @_;
4043    
4044          #Opening the SBML file for printing          #Opening the SBML file for printing
4045          my $Filename = $self->config("SBML files")->[0].$self->id().".xml";          my $Filename = $self->directory().$self->id().".xml";
         if ($self->owner() ne "master") {  
                 if (!-d $self->config("SBML files")->[0].$self->owner()."/") {  
                         system("mkdir ".$self->config("SBML files")->[0].$self->owner()."/");  
                 }  
                 $Filename = $self->config("SBML files")->[0].$self->owner()."/".$self->id().".xml";  
         }  
4046          if (!open (SBMLOUTPUT, ">$Filename")) {          if (!open (SBMLOUTPUT, ">$Filename")) {
4047                  return;                  return;
4048          }          }
4049    
4050          #Loading and parsing the model data          #Loading and parsing the model data
4051          my $ModelTable = $self->reaction_table();          my $mdlTbl = $self->reaction_table();
4052          if (!defined($ModelTable) || !defined($ModelTable->{"array"})) {          if (!defined($mdlTbl) || !defined($mdlTbl->{"array"})) {
4053                  print "Failed to load ".$self->id()."\n";                  return $self->fail();
                 return;  
4054          }          }
4055            my $rxnTbl = $self->figmodel()->database()->get_table("REACTIONS");
4056            my $bioTbl = $self->figmodel()->database()->get_table("BIOMASS");
4057            my $cpdTbl = $self->figmodel()->database()->get_table("COMPOUNDS");
4058            my $cmpTbl = $self->figmodel()->database()->get_table("COMPARTMENTS");
4059    
4060          #Adding intracellular metabolites that also need exchange fluxes to the exchange hash          #Adding intracellular metabolites that also need exchange fluxes to the exchange hash
4061          my $ExchangeHash = {"cpd11416" => "c"};          my $ExchangeHash = {"cpd11416" => "c"};
   
4062          my %CompartmentsPresent;          my %CompartmentsPresent;
4063          $CompartmentsPresent{"c"} = 1;          $CompartmentsPresent{"c"} = 1;
4064          my %CompoundList;          my %CompoundList;
4065          my @ReactionList;          my @ReactionList;
4066          my $ReactionTable = $self->figmodel()->database()->GetDBTable("REACTIONS");          for (my $i=0; $i < $mdlTbl->size(); $i++) {
4067          for (my $i=0; $i < $ModelTable->size(); $i++) {                  my $Reaction = $mdlTbl->get_row($i)->{"LOAD"}->[0];
4068                  my $Reaction = $ModelTable->get_row($i)->{"LOAD"}->[0];                  my $row = $rxnTbl->get_row_by_key($Reaction,"DATABASE");
4069                  if (defined($ReactionTable->get_row_by_key($Reaction,"DATABASE")) && defined($ReactionTable->get_row_by_key($Reaction,"DATABASE")->{"EQUATION"}->[0])) {                  if (!defined($row)) {
4070                            $row = $bioTbl->get_row_by_key($Reaction,"DATABASE");
4071                            if (!defined($row)) {
4072                                    next;
4073                            }
4074                    }
4075                    if (!defined($row->{"EQUATION"}->[0])) {
4076                            next;
4077                    }
4078                          push(@ReactionList,$Reaction);                          push(@ReactionList,$Reaction);
4079                          $_ = $ReactionTable->get_row_by_key($Reaction,"DATABASE")->{"EQUATION"}->[0];                  $_ = $row->{"EQUATION"}->[0];
4080                          my @MatchArray = /(cpd\d\d\d\d\d)/g;                          my @MatchArray = /(cpd\d\d\d\d\d)/g;
4081                          for (my $j=0; $j < @MatchArray; $j++) {                          for (my $j=0; $j < @MatchArray; $j++) {
4082                                  $CompoundList{$MatchArray[$j]}->{"c"} = 1;                                  $CompoundList{$MatchArray[$j]}->{"c"} = 1;
4083                          }                          }
4084                          $_ = $ReactionTable->get_row_by_key($Reaction,"DATABASE")->{"EQUATION"}->[0];                  $_ = $row->{"EQUATION"}->[0];
4085                          @MatchArray = /(cpd\d\d\d\d\d\[\D\])/g;                          @MatchArray = /(cpd\d\d\d\d\d\[\D\])/g;
4086                          for (my $j=0; $j < @MatchArray; $j++) {                          for (my $j=0; $j < @MatchArray; $j++) {
4087                                  if ($MatchArray[$j] =~ m/(cpd\d\d\d\d\d)\[(\D)\]/) {                                  if ($MatchArray[$j] =~ m/(cpd\d\d\d\d\d)\[(\D)\]/) {
# Line 3691  Line 4090 
4090                                  }                                  }
4091                          }                          }
4092                  }                  }
         }  
4093    
4094          #Printing header to SBML file          #Printing header to SBML file
4095          my $ModelName = $self->id();          my $ModelName = $self->id().$self->selected_version();
4096          $ModelName =~ s/\./_/;          $ModelName =~ s/\./_/;
4097          print SBMLOUTPUT '<?xml version="1.0" encoding="UTF-8"?>'."\n";          print SBMLOUTPUT '<?xml version="1.0" encoding="UTF-8"?>'."\n";
4098      print SBMLOUTPUT '<sbml xmlns="http://www.sbml.org/sbml/level2" level="2" version="1" xmlns:html="http://www.w3.org/1999/xhtml">' . "\n";      print SBMLOUTPUT '<sbml xmlns="http://www.sbml.org/sbml/level2" level="2" version="1" xmlns:html="http://www.w3.org/1999/xhtml">' . "\n";
4099      if (defined($self->figmodel()->database()->GetDBTable("MODEL STATS")->{$self->id()}->[0]->{"Organism name"}->[0])) {          if (defined($self->name())) {
4100          print SBMLOUTPUT '<model id="'.$ModelName.'" name="'.$self->figmodel()->database()->GetDBTable("MODEL STATS")->{$self->id()}->[0]->{"Organism name"}->[0].' SEED model">'."\n";                  print SBMLOUTPUT '<model id="'.$ModelName.'" name="'.$self->name().' SEED model">'."\n";
4101      } else {      } else {
4102          print SBMLOUTPUT '<model id="'.$ModelName.'" name="'.$self->id().' SEED model">'."\n";                  print SBMLOUTPUT '<model id="'.$ModelName.'" name="'.$self->id().$self->selected_version().' SEED model">'."\n";
4103      }      }
4104    
4105          #Printing the unit data          #Printing the unit data
# Line 3718  Line 4116 
4116      #Printing compartments for SBML file      #Printing compartments for SBML file
4117      print SBMLOUTPUT '<listOfCompartments>'."\n";      print SBMLOUTPUT '<listOfCompartments>'."\n";
4118      foreach my $Compartment (keys(%CompartmentsPresent)) {      foreach my $Compartment (keys(%CompartmentsPresent)) {
4119          if (defined($self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Compartment}->[0]->{"Name"}->[0])) {                  my $row = $cmpTbl->get_row_by_key($Compartment,"Abbreviation");
4120                  my @OutsideList = split(/\//,$self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Compartment}->[0]->{"Outside"}->[0]);                  if (!defined($row) && !defined($row->{"Name"}->[0])) {
4121                            next;
4122                    }
4123                    my @OutsideList = split(/\//,$row->{"Outside"}->[0]);
4124                  my $Printed = 0;                  my $Printed = 0;
4125                  foreach my $Outside (@OutsideList) {                  foreach my $Outside (@OutsideList) {
4126                                  if (defined($CompartmentsPresent{$Outside}) && defined($self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Outside}->[0]->{"Name"}->[0])) {                          if (defined($CompartmentsPresent{$Outside}) && defined($row->{"Name"}->[0])) {
4127                                  print SBMLOUTPUT '<compartment id="'.$self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Compartment}->[0]->{"Name"}->[0].'" outside="'.$self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Outside}->[0]->{"Name"}->[0].'"/>'."\n";                                  print SBMLOUTPUT '<compartment id="'.$row->{"Name"}->[0].'" outside="'.$row->{"Name"}->[0].'"/>'."\n";
4128                                  $Printed = 1;                                  $Printed = 1;
4129                                  last;                                  last;
4130                          }                          }
4131                  }                  }
4132                  if ($Printed eq 0) {                  if ($Printed eq 0) {
4133                          print SBMLOUTPUT '<compartment id="'.$self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Compartment}->[0]->{"Name"}->[0].'"/>'."\n";                          print SBMLOUTPUT '<compartment id="'.$row->{"Name"}->[0].'"/>'."\n";
                         }  
4134          }          }
4135      }      }
4136      print SBMLOUTPUT '</listOfCompartments>'."\n";      print SBMLOUTPUT '</listOfCompartments>'."\n";
# Line 3738  Line 4138 
4138      #Printing the list of metabolites involved in the model      #Printing the list of metabolites involved in the model
4139          print SBMLOUTPUT '<listOfSpecies>'."\n";          print SBMLOUTPUT '<listOfSpecies>'."\n";
4140      foreach my $Compound (keys(%CompoundList)) {      foreach my $Compound (keys(%CompoundList)) {
4141                    my $row = $cpdTbl->get_row_by_key($Compound,"DATABASE");
4142                    if (!defined($row)) {
4143                            next;
4144                    }
4145          my $Name = $Compound;          my $Name = $Compound;
4146                  my $Formula = "";                  my $Formula = "";
4147                  if (defined($self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"FORMULA"}->[0])) {                  if (defined($row->{"FORMULA"}->[0])) {
4148                          $Formula = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"FORMULA"}->[0];                          $Formula = $row->{"FORMULA"}->[0];
4149                  }                  }
4150                  if (defined($self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"NAME"}->[0])) {                  if (defined($row->{"NAME"}->[0])) {
4151                          $Name = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"NAME"}->[0];                          $Name = $row->{"NAME"}->[0];
4152                          $Name =~ s/\s/_/;                          $Name =~ s/\s/_/;
4153                          $Name .= "_".$Formula;                          $Name .= "_".$Formula;
4154                  }                  }
4155                  $Name =~ s/[<>;&\*]//;                  $Name =~ s/[<>;&\*]//;
4156                  my $Charge = 0;                  my $Charge = 0;
4157                  if (defined($self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"CHARGE"}->[0])) {                  if (defined($row->{"CHARGE"}->[0])) {
4158                          $Charge = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"CHARGE"}->[0];                          $Charge = $row->{"CHARGE"}->[0];
4159                  }                  }
4160                  foreach my $Compartment (keys(%{$CompoundList{$Compound}})) {                  foreach my $Compartment (keys(%{$CompoundList{$Compound}})) {
4161                  if ($Compartment eq "e") {                  if ($Compartment eq "e") {
4162                          $ExchangeHash->{$Compound} = "e";                          $ExchangeHash->{$Compound} = "e";
4163                  }                  }
4164                  print SBMLOUTPUT '<species id="'.$Compound.'_'.$Compartment.'" name="'.$Name.'" compartment="'.$self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Compartment}->[0]->{"Name"}->[0].'" charge="'.$Charge.'" boundaryCondition="false"/>'."\n";                          my $cmprow = $cmpTbl->get_row_by_key($Compartment,"Abbreviation");
4165                            print SBMLOUTPUT '<species id="'.$Compound.'_'.$Compartment.'" name="'.$Name.'" compartment="'.$cmprow->{"Name"}->[0].'" charge="'.$Charge.'" boundaryCondition="false"/>'."\n";
4166          }          }
4167      }      }
4168    
4169          #Printing the boundary species          #Printing the boundary species
4170          foreach my $Compound (keys(%{$ExchangeHash})) {          foreach my $Compound (keys(%{$ExchangeHash})) {
4171                  my $Name = $Compound;                  my $Name = $Compound;
4172                  my $Formula = "";                  my $Formula = "";
4173                  if (defined($self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"FORMULA"}->[0])) {                  my $row = $cpdTbl->get_row_by_key($Compound,"DATABASE");
4174                          $Formula = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"FORMULA"}->[0];                  if (!defined($row)) {
4175                            next;
4176                    }
4177                    if (defined($row->{"FORMULA"}->[0])) {
4178                            $Formula = $row->{"FORMULA"}->[0];
4179                  }                  }
4180                  if (defined($self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"NAME"}->[0])) {                  if (defined($row->{"NAME"}->[0])) {
4181                          $Name = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"NAME"}->[0];                          $Name = $row->{"NAME"}->[0];
4182                          $Name =~ s/\s/_/;                          $Name =~ s/\s/_/;
4183                          $Name .= "_".$Formula;                          $Name .= "_".$Formula;
4184                  }                  }
4185                  $Name =~ s/[<>;&\*]//;                  $Name =~ s/[<>;&\*]//;
4186                  my $Charge = 0;                  my $Charge = 0;
4187                  if (defined($self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"CHARGE"}->[0])) {                  if (defined($row->{"CHARGE"}->[0])) {
4188                          $Charge = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"CHARGE"}->[0];                          $Charge = $row->{"CHARGE"}->[0];
4189                  }                  }
4190                  print SBMLOUTPUT '<species id="'.$Compound.'_b" name="'.$Name.'" compartment="Extracellular" charge="'.$Charge.'" boundaryCondition="true"/>'."\n";                  print SBMLOUTPUT '<species id="'.$Compound.'_b" name="'.$Name.'" compartment="Extracellular" charge="'.$Charge.'" boundaryCondition="true"/>'."\n";
4191          }          }
# Line 3784  Line 4194 
4194      #Printing the list of reactions involved in the model      #Printing the list of reactions involved in the model
4195          my $ObjectiveCoef;          my $ObjectiveCoef;
4196      print SBMLOUTPUT '<listOfReactions>'."\n";      print SBMLOUTPUT '<listOfReactions>'."\n";
4197    
4198          foreach my $Reaction (@ReactionList) {          foreach my $Reaction (@ReactionList) {
4199          $ObjectiveCoef = "0.0";          $ObjectiveCoef = "0.0";
4200                  if (defined($self->figmodel()->database()->GetDBTable("REACTIONS")->{$Reaction}->[0]->{"EQUATION"}->[0])) {                  my $mdlrow = $mdlTbl->get_row_by_key($Reaction,"LOAD");
4201                    my $Reaction = $mdlrow->{"LOAD"}->[0];
4202                    my $row = $rxnTbl->get_row_by_key($Reaction,"DATABASE");
4203                    if (!defined($row)) {
4204                            $row = $bioTbl->get_row_by_key($Reaction,"DATABASE");
4205                            if (!defined($row)) {
4206                                    next;
4207                            }
4208                    }
4209                    if (!defined($row->{"EQUATION"}->[0])) {
4210                            next;
4211                    }
4212                  if ($Reaction =~ m/^bio/) {                  if ($Reaction =~ m/^bio/) {
4213                                  $ObjectiveCoef = "1.0";                                  $ObjectiveCoef = "1.0";
4214                          }                          }
4215                          my $LowerBound = -10000;                          my $LowerBound = -10000;
4216                  my $UpperBound = 10000;                  my $UpperBound = 10000;
4217                          my ($Reactants,$Products) = $self->figmodel()->GetReactionSubstrateData($Reaction);                  my ($Reactants,$Products) = $self->figmodel()->GetReactionSubstrateDataFromEquation($row->{"EQUATION"}->[0]);
4218                  my $Name = $Reaction;                  my $Name = $Reaction;
4219                  if (defined($self->figmodel()->database()->GetDBTable("REACTIONS")->{$Reaction}->[0]->{"NAME"}->[0])) {                  if (defined($row->{"NAME"}->[0])) {
4220                          $Name = $self->figmodel()->database()->GetDBTable("REACTIONS")->{$Reaction}->[0]->{"NAME"}->[0];                          $Name = $row->{"NAME"}->[0];
4221                                  $Name =~ s/[<>;&]//g;                                  $Name =~ s/[<>;&]//g;
4222                  }                  }
4223                  my $Reversibility = "true";                  my $Reversibility = "true";
4224                  if (defined($ModelTable->{$Reaction}->[0]->{"DIRECTIONALITY"}->[0])) {                  if (defined($mdlrow->{"DIRECTIONALITY"}->[0])) {
4225                          if ($ModelTable->{$Reaction}->[0]->{"DIRECTIONALITY"}->[0] ne "<=>") {                          if ($mdlrow->{"DIRECTIONALITY"}->[0] ne "<=>") {
4226                                  $LowerBound = 0;                                  $LowerBound = 0;
4227                                          $Reversibility = "false";                                          $Reversibility = "false";
4228                          }                          }
4229                          if ($ModelTable->{$Reaction}->[0]->{"DIRECTIONALITY"}->[0] eq "<=") {                          if ($mdlrow->{"DIRECTIONALITY"}->[0] eq "<=") {
4230                                  my $Temp = $Products;                                  my $Temp = $Products;
4231                                  $Products = $Reactants;                                  $Products = $Reactants;
4232                                  $Reactants = $Temp;                                  $Reactants = $Temp;
# Line 3813  Line 4235 
4235                          print SBMLOUTPUT '<reaction id="'.$Reaction.'" name="'.$Name.'" reversible="'.$Reversibility.'">'."\n";                          print SBMLOUTPUT '<reaction id="'.$Reaction.'" name="'.$Name.'" reversible="'.$Reversibility.'">'."\n";
4236                          print SBMLOUTPUT "<notes>\n";                          print SBMLOUTPUT "<notes>\n";
4237                          my $ECData = "";                          my $ECData = "";
4238                          if (defined($self->figmodel()->database()->GetDBTable("REACTIONS")->{$Reaction}->[0]->{"ENZYME"}->[0])) {                  if (defined($row->{"ENZYME"}->[0])) {
4239                                  $ECData = $self->figmodel()->database()->GetDBTable("REACTIONS")->{$Reaction}->[0]->{"ENZYME"}->[0];                          $ECData = $row->{"ENZYME"}->[0];
4240                          }                          }
4241                          my $SubsystemData = "";                          my $SubsystemData = "";
4242                          if (defined($ModelTable->{$Reaction}->[0]->{"SUBSYSTEM"}->[0])) {                  if (defined($mdlrow->{"SUBSYSTEM"}->[0])) {
4243                                  $SubsystemData = $ModelTable->{$Reaction}->[0]->{"SUBSYSTEM"}->[0];                          $SubsystemData = $mdlrow->{"SUBSYSTEM"}->[0];
4244                          }                          }
4245                          my $GeneAssociation = "";                          my $GeneAssociation = "";
4246                          my $ProteinAssociation = "";                          my $ProteinAssociation = "";
4247                          if (defined($ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}->[0])) {                  if (defined($mdlrow->{"ASSOCIATED PEG"}->[0])) {
4248                                  if (@{$ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}} == 1 && $ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}->[0] !~ m/\+/) {                          if (@{$mdlrow->{"ASSOCIATED PEG"}} == 1 && $mdlrow->{"ASSOCIATED PEG"}->[0] !~ m/\+/) {
4249                                          $GeneAssociation = $ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}->[0];                                  $GeneAssociation = $mdlrow->{"ASSOCIATED PEG"}->[0];
4250                                  } else {                                  } else {
4251                                          if (@{$ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}} > 1) {                                  if (@{$mdlrow->{"ASSOCIATED PEG"}} > 1) {
4252                                                  $GeneAssociation = "( ";                                                  $GeneAssociation = "( ";
4253                                          }                                          }
4254                                          for (my $i=0; $i < @{$ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}}; $i++) {                                  for (my $i=0; $i < @{$mdlrow->{"ASSOCIATED PEG"}}; $i++) {
4255                                                  if ($i > 0) {                                                  if ($i > 0) {
4256                                                          $GeneAssociation .= " )  or  ( ";                                                          $GeneAssociation .= " )  or  ( ";
4257                                                  }                                                  }
4258                                                  $GeneAssociation .= $ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}->[$i];                                          $GeneAssociation .= $mdlrow->{"ASSOCIATED PEG"}->[$i];
4259                                          }                                          }
4260                                          if (@{$ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}} > 1) {                                  if (@{$mdlrow->{"ASSOCIATED PEG"}} > 1) {
4261                                                  $GeneAssociation .= " )";                                                  $GeneAssociation .= " )";
4262                                          }                                          }
4263                                  }                                  }
# Line 3844  Line 4266 
4266                                          $GeneAssociation = "( ".$GeneAssociation." )";                                          $GeneAssociation = "( ".$GeneAssociation." )";
4267                                  }                                  }
4268                                  $ProteinAssociation = $GeneAssociation;                                  $ProteinAssociation = $GeneAssociation;
4269                                  if (defined($self->figmodel()->database()->GetDBTable("MODEL STATS")->{$self->id()}->[0]->{"Genome ID"}->[0])) {                          if (defined($self->genome())) {
4270                                          $ProteinAssociation = $self->figmodel()->translate_gene_to_protein($ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}->[0],$self->figmodel()->database()->GetDBTable("MODEL STATS")->{$self->id()}->[0]->{"Genome ID"}->[0]);                                  $ProteinAssociation = $self->figmodel()->translate_gene_to_protein($mdlrow->{"ASSOCIATED PEG"}->[0],$self->genome());
4271                                  }                                  }
4272                          }                          }
4273                          print SBMLOUTPUT "<html:p>GENE_ASSOCIATION:".$GeneAssociation."</html:p>\n";                          print SBMLOUTPUT "<html:p>GENE_ASSOCIATION:".$GeneAssociation."</html:p>\n";
# Line 3876  Line 4298 
4298              print SBMLOUTPUT "</kineticLaw>\n";              print SBMLOUTPUT "</kineticLaw>\n";
4299                          print SBMLOUTPUT '</reaction>'."\n";                          print SBMLOUTPUT '</reaction>'."\n";
4300                  }                  }
         }  
4301    
4302          my @ExchangeList = keys(%{$ExchangeHash});          my @ExchangeList = keys(%{$ExchangeHash});
4303          foreach my $ExCompound (@ExchangeList) {          foreach my $ExCompound (@ExchangeList) {
4304                  my $ExCompoundName = $ExCompound;                  my $ExCompoundName = $ExCompound;
4305                  my $Row = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->get_row_by_key($ExCompound,"DATABASE");                  my $Row = $cpdTbl->get_row_by_key($ExCompound,"DATABASE");
4306                  if (defined($Row) && defined($Row->{"NAME"}->[0])) {                  if (defined($Row) && defined($Row->{"NAME"}->[0])) {
4307                          $ExCompoundName = $Row->{"NAME"}->[0];                          $ExCompoundName = $Row->{"NAME"}->[0];
4308                          $ExCompoundName =~ s/[<>;&]//g;                          $ExCompoundName =~ s/[<>;&]//g;
# Line 3921  Line 4342 
4342          close(SBMLOUTPUT);          close(SBMLOUTPUT);
4343  }  }
4344    
4345    =head3 PrintModelSimpleReactionTable
4346    Definition:
4347            success()/fail() FIGMODELmodel->PrintModelSimpleReactionTable();
4348    Description:
4349            Prints the table of model data
4350    =cut
4351    sub PrintModelSimpleReactionTable {
4352            my ($self) = @_;
4353    
4354            my $rxntbl = $self->reaction_table();
4355            my $tbl = $self->create_table_prototype("ModelSimpleReactionTable");
4356            for (my $i=0; $i < $rxntbl->size(); $i++) {
4357                    my $row = $rxntbl->get_row($i);
4358                    $row->{DATABASE} = $row->{LOAD};
4359                    $tbl->add_row($row);
4360            }
4361            $tbl->save();
4362    }
4363    
4364  =head3 PrintModelLPFile  =head3 PrintModelLPFile
4365  Definition:  Definition:
4366          success()/fail() FIGMODELmodel->PrintModelLPFile();          success()/fail() FIGMODELmodel->PrintModelLPFile();
# Line 4108  Line 4548 
4548          $self->reaction_table()->save();          $self->reaction_table()->save();
4549  }  }
4550    
4551    =head3 feature_web_data
4552    Definition:
4553            string:web output for feature/model connection = FIGMODELmodel->feature_web_data(FIGMODELfeature:feature);
4554    Description:
4555    =cut
4556    sub feature_web_data {
4557            my ($self,$feature) = @_;
4558    
4559            #First checking if the feature is in the model
4560            my $featureGenome = $feature->{GENOME}->[0];
4561            if ($feature->{GENOME}->[0] =~ m/\>(\d+\.\d+)\</) {
4562                    $featureGenome = $1;
4563            }
4564            if ($featureGenome ne $self->genome()) {
4565                    return "Not in model";
4566            }
4567            my $data = $self->get_feature_data($feature->{ID}->[0]);
4568            if (!defined($data)) {
4569                    return "Not in model";
4570            }
4571    
4572            my $output;
4573            #Printing predictions
4574            if (defined($data->{$self->id()."PREDICTIONS"})) {
4575                    #Parsing essentiality data
4576                    my $essentialityData;
4577                    if (defined($feature->{ESSENTIALITY})) {
4578                            for (my $i=0; $i < @{$feature->{ESSENTIALITY}};$i++) {
4579                                    my @temp = split(/:/,$feature->{ESSENTIALITY}->[$i]);
4580                                    $essentialityData->{$temp[0]} = $temp[1];
4581                            }
4582                    }
4583                    my $predictionHash;
4584                    for (my $i=0; $i < @{$data->{$self->id()."PREDICTIONS"}};$i++) {
4585                            my @temp = split(/:/,$data->{$self->id()."PREDICTIONS"}->[$i]);
4586                            if (defined($essentialityData->{$temp[0]})) {
4587                                    if ($temp[1] eq "essential" && $essentialityData->{$temp[0]} eq "essential") {
4588                                            push(@{$predictionHash->{"Correct negative"}},$temp[0]);
4589                                    } elsif ($temp[1] eq "nonessential" && $essentialityData->{$temp[0]} eq "essential") {
4590                                            push(@{$predictionHash->{"False positive"}},$temp[0]);
4591                                    } elsif ($temp[1] eq "essential" && $essentialityData->{$temp[0]} eq "nonessential") {
4592                                            push(@{$predictionHash->{"False negative"}},$temp[0]);
4593                                    } elsif ($temp[1] eq "nonessential" && $essentialityData->{$temp[0]} eq "nonessential") {
4594                                            push(@{$predictionHash->{"Correct positive"}},$temp[0]);
4595                                    }
4596                            } else {
4597                                    push(@{$predictionHash->{$temp[1]}},$temp[0]);
4598                            }
4599                    }
4600                    foreach my $key (keys(%{$predictionHash})) {
4601                            my $string = $key;
4602                            $string = ucfirst($string);
4603                            push(@{$output},'<span title="'.join(", ",@{$predictionHash->{$key}}).'">'.$string.'</span>');
4604                    }
4605            }
4606    
4607            #Printing reactions
4608            if (defined($data->{$self->id()."REACTIONS"})) {
4609                    for (my $i=0; $i < @{$data->{$self->id()."REACTIONS"}};$i++) {
4610                            my $rxnData = $self->get_reaction_data($data->{$self->id()."REACTIONS"}->[$i]);
4611                            my $reactionString = $self->figmodel()->web()->create_reaction_link($data->{$self->id()."REACTIONS"}->[$i],join(" or ",@{$rxnData->{"ASSOCIATED PEG"}}),$self->id());
4612                            if (defined($rxnData->{PREDICTIONS})) {
4613                                    my $predictionHash;
4614                                    for (my $i=0; $i < @{$rxnData->{PREDICTIONS}};$i++) {
4615                                            my @temp = split(/:/,$rxnData->{PREDICTIONS}->[$i]);
4616                                            push(@{$predictionHash->{$temp[1]}},$temp[0]);
4617                                    }
4618                                    $reactionString .= "(";
4619                                    foreach my $key (keys(%{$predictionHash})) {
4620                                            if ($key eq "Essential =>") {
4621                                                    $reactionString .= '<span title="Essential in '.join(",",@{$predictionHash->{$key}}).'">E=></span>,';
4622                                            } elsif ($key eq "Essential <=") {
4623                                                    $reactionString .= '<span title="Essential in '.join(",",@{$predictionHash->{$key}}).'">E<=</span>,';
4624                                            } elsif ($key eq "Active =>") {
4625                                                    $reactionString .= '<span title="Active in '.join(",",@{$predictionHash->{$key}}).'">A=></span>,';
4626                                            } elsif ($key eq "Active <=") {
4627                                                    $reactionString .= '<span title="Active in '.join(",",@{$predictionHash->{$key}}).'">A<=</span>,';
4628                                            } elsif ($key eq "Active <=>") {
4629                                                    $reactionString .= '<span title="Active in '.join(",",@{$predictionHash->{$key}}).'">A</span>,';
4630                                            } elsif ($key eq "Inactive") {
4631                                                    $reactionString .= '<span title="Inactive in '.join(",",@{$predictionHash->{$key}}).'">I</span>,';
4632                                            } elsif ($key eq "Dead") {
4633                                                    $reactionString .= '<span title="Dead">D</span>,';
4634                                            }
4635                                    }
4636                                    $reactionString =~ s/,$/)/;
4637                            }
4638                            push(@{$output},$reactionString);
4639                    }
4640            }
4641    
4642            #Returning output
4643            return join("<br>",@{$output});
4644    }
4645    
4646    =head3 remove_obsolete_reactions
4647    Definition:
4648            void FIGMODELmodel->remove_obsolete_reactions();
4649    Description:
4650    =cut
4651    sub remove_obsolete_reactions {
4652            my ($self) = @_;
4653    
4654            (my $dummy,my $translation) = $self->figmodel()->put_two_column_array_in_hash($self->figmodel()->database()->load_multiple_column_file($self->figmodel()->config("Translation directory")->[0]."ObsoleteRxnIDs.txt","\t"));
4655            my $rxnTbl = $self->reaction_table();
4656            if (defined($rxnTbl)) {
4657                    for (my $i=0; $i < $rxnTbl->size(); $i++) {
4658                            my $row = $rxnTbl->get_row($i);
4659                            if (defined($translation->{$row->{LOAD}->[0]}) || defined($translation->{$row->{LOAD}->[0]."r"})) {
4660                                    my $direction = $row->{DIRECTION}->[0];
4661                                    my $newRxn;
4662                                    if (defined($translation->{$row->{LOAD}->[0]."r"})) {
4663                                            $newRxn = $translation->{$row->{LOAD}->[0]."r"};
4664                                            if ($direction eq "<=") {
4665                                                    $direction = "=>";
4666                                            } elsif ($direction eq "=>") {
4667                                                    $direction = "<=";
4668                                            }
4669                                    } else {
4670                                            $newRxn = $translation->{$row->{LOAD}->[0]};
4671                                    }
4672                                    #Checking if the new reaction is already in the model
4673                                    my $newRow = $rxnTbl->get_row_by_key($newRxn,"LOAD");
4674                                    if (defined($newRow)) {
4675                                            #Handling direction
4676                                            if ($newRow->{DIRECTION}->[0] ne $direction) {
4677                                                    $newRow->{DIRECTION}->[0] = "<=>";
4678                                            }
4679                                            push(@{$row->{"ASSOCIATED PEG"}},@{$rxnTbl->get_row($i)->{"ASSOCIATED PEG"}});
4680                                    } else {
4681                                            $rxnTbl->get_row($i)->{LOAD}->[0] = $newRxn;
4682                                            $rxnTbl->get_row($i)->{DIRECTION}->[0] = $direction;
4683                                    }
4684                            }
4685                    }
4686                    $rxnTbl->save();
4687            }
4688    }
4689    
4690    =pod
4691    
4692    =item * [string]:I<list of essential genes> = B<run_geneKO_slow> (string:I<media>,0/1:I<max growth>,0/1:I<save results>);
4693    
4694    =cut
4695    
4696    sub run_geneKO_slow {
4697            my ($self,$media,$maxGrowth,$save) = @_;
4698            my $output;
4699            my $UniqueFilename = $self->figmodel()->filename();
4700            if (defined($maxGrowth) && $maxGrowth == 1) {
4701                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$media,["ProductionMFA"],{"perform single KO experiments" => 1,"MFASolver" => "GLPK","Constrain objective to this fraction of the optimal value" => 0.999},"SlowGeneKO-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,$self->selected_version()));
4702            } else {
4703                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$media,["ProductionMFA"],{"perform single KO experiments" => 1,"MFASolver" => "GLPK","Constrain objective to this fraction of the optimal value" => 0.1},"SlowGeneKO-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,$self->selected_version()));
4704            }
4705            if (!-e $self->config("MFAToolkit output directory")->[0].$UniqueFilename."DeletionStudyResults.txt") {
4706                    print "Deletion study file not found!.\n";
4707                    return undef;
4708            }
4709            my $deltbl = $self->figmodel()->database()->load_table($self->config("MFAToolkit output directory")->[0].$UniqueFilename."DeletionStudyResults.txt",";","|",1,["Experiment"]);
4710            for (my $i=0; $i < $deltbl->size(); $i++) {
4711                    my $row = $deltbl->get_row($i);
4712                    if ($row->{"Insilico growth"}->[0] < 0.0000001) {
4713                            push(@{$output},$row->{Experiment}->[0]);
4714                    }
4715            }
4716            if (defined($output)) {
4717                    if (defined($save) && $save == 1) {
4718                            my $tbl = $self->essentials_table();
4719                            my $row = $tbl->get_row_by_key($media,"MEDIA",1);
4720                            $row->{"ESSENTIAL GENES"} = $output;
4721                            $tbl->save();
4722                    }
4723            }
4724            return $output;
4725    }
4726    
4727    =pod
4728    
4729    =item * [string]:I<list of minimal genes> = B<run_gene_minimization> (string:I<media>,0/1:I<max growth>,0/1:I<save results>);
4730    
4731    =cut
4732    
4733    sub run_gene_minimization {
4734            my ($self,$media,$maxGrowth,$save) = @_;
4735            my $output;
4736    
4737            #Running the MFAToolkit
4738            my $UniqueFilename = $self->figmodel()->filename();
4739            if (defined($maxGrowth) && $maxGrowth == 1) {
4740                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$media,["ProductionMFA"],{"optimize organism genes" => 1,"MFASolver" => "CPLEX","Constrain objective to this fraction of the optimal value" => 0.999},"MinimizeGenes-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,$self->selected_version()));
4741            } else {
4742                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$media,["ProductionMFA"],{"optimize organism genes" => 1,"MFASolver" => "CPLEX","Constrain objective to this fraction of the optimal value" => 0.1},"MinimizeGenes-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,$self->selected_version()));
4743            }
4744            my $tbl = $self->figmodel()->LoadProblemReport($UniqueFilename);
4745            if (!defined($tbl)) {
4746                    return undef;
4747            }
4748            for (my $i=0; $i < $tbl->size(); $i++) {
4749                    my $row = $tbl->get_row($i);
4750                    if ($row->{Notes}->[0] =~ m/Recursive\sMILP\sGENE_USE\soptimization/) {
4751                            my @array = split(/\|/,$row->{Notes}->[0]);
4752                            my $solution = $array[0];
4753                            $_ = $solution;
4754                            my @OriginalArray = /(peg\.\d+)/g;
4755                            push(@{$output},@OriginalArray);
4756                            last;
4757                    }
4758            }
4759    
4760            if (defined($output)) {
4761                    if (defined($save) && $save == 1) {
4762                            my $tbl = $self->load_model_table("MinimalGenes");
4763                            my $row = $tbl->get_table_by_key("MEDIA",$media)->get_row_by_key("MAXGROWTH",$maxGrowth);
4764                            if (defined($row)) {
4765                                    $row->{GENES} = $output;
4766                            } else {
4767                                    $tbl->add_row({GENES => $output,MEDIA => [$media],MAXGROWTH => [$maxGrowth]});
4768                            }
4769                            $tbl->save();
4770                    }
4771            }
4772            return $output;
4773    }
4774    
4775    =pod
4776    
4777    =item * [string]:I<list of inactive genes> = B<identify_inactive_genes> (string:I<media>,0/1:I<max growth>,0/1:I<save results>);
4778    
4779    =cut
4780    
4781    sub identify_inactive_genes {
4782            my ($self,$media,$maxGrowth,$save) = @_;
4783            my $output;
4784            #Running the MFAToolkit
4785            my $UniqueFilename = $self->figmodel()->filename();
4786            if (defined($maxGrowth) && $maxGrowth == 1) {
4787                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$media,["ProductionMFA"],{"find tight bounds" => 1,"MFASolver" => "GLPK","Constrain objective to this fraction of the optimal value" => 0.999},"Classify-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,$self->selected_version()));
4788            } else {
4789                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$media,["ProductionMFA"],{"find tight bounds" => 1,"MFASolver" => "GLPK","Constrain objective to this fraction of the optimal value" => 0.1},"Classify-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,$self->selected_version()));
4790            }
4791            #Reading in the output bounds file
4792            my $ReactionTB;
4793            if (-e $self->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/TightBoundsReactionData0.txt") {
4794                    $ReactionTB = $self->figmodel()->database()->load_table($self->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/TightBoundsReactionData0.txt",";","|",1,["DATABASE ID"]);
4795            }
4796            if (!defined($ReactionTB)) {
4797                    print STDERR "FIGMODEL:ClassifyModelReactions: Classification file not found when classifying reactions in ".$self->id().$self->selected_version()." with ".$media." media. Most likely the model did not grow.\n";
4798                    return undef;
4799            }
4800            #Clearing output
4801            $self->figmodel()->clearing_output($UniqueFilename,"Classify-".$self->id().$self->selected_version()."-".$UniqueFilename.".log");
4802            my $geneHash;
4803            my $activeGeneHash;
4804            for (my $i=0; $i < $ReactionTB->size(); $i++) {
4805                    my $Row = $ReactionTB->get_row($i);
4806                    if (defined($Row->{"Min FLUX"}) && defined($Row->{"Max FLUX"}) && defined($Row->{"DATABASE ID"}) && $Row->{"DATABASE ID"}->[0] =~ m/rxn\d\d\d\d\d/) {
4807                            my $data = $self->get_reaction_data($Row->{"DATABASE ID"}->[0]);
4808                            if (defined($data->{"ASSOCIATED PEG"})) {
4809                                    my $active = 0;
4810                                    if ($Row->{"Min FLUX"}->[0] > 0.00000001 || $Row->{"Max FLUX"}->[0] < -0.00000001 || ($Row->{"Max FLUX"}->[0]-$Row->{"Min FLUX"}->[0]) > 0.00000001) {
4811                                            $active = 1;
4812                                    }
4813                                    for (my $j=0; $j < @{$data->{"ASSOCIATED PEG"}}; $j++) {
4814                                            $_ = $data->{"ASSOCIATED PEG"}->[$j];
4815                                            my @OriginalArray = /(peg\.\d+)/g;
4816                                            for (my $k=0; $k < @OriginalArray; $k++) {
4817                                                    if ($active == 1) {
4818                                                            $activeGeneHash->{$OriginalArray[$k]} = 1;
4819                                                    }
4820                                                    $geneHash->{$OriginalArray[$k]} = 1;
4821                                            }
4822                                    }
4823                            }
4824                    }
4825            }
4826            my @allGenes = keys(%{$geneHash});
4827            for (my $i=0; $i < @allGenes; $i++) {
4828                    if (!defined($activeGeneHash->{$allGenes[$i]})) {
4829                            push(@{$output},$allGenes[$i]);
4830                    }
4831            }
4832            if (defined($output)) {
4833                    if (defined($save) && $save == 1) {
4834                            my $tbl = $self->load_model_table("InactiveGenes");
4835                            my $row = $tbl->get_table_by_key("MEDIA",$media)->get_row_by_key("MAXGROWTH",$maxGrowth);
4836                            if (defined($row)) {
4837                                    $row->{GENES} = $output;
4838                            } else {
4839                                    $tbl->add_row({GENES => $output,MEDIA => [$media],MAXGROWTH => [$maxGrowth]});
4840                            }
4841                            $tbl->save();
4842                    }
4843            }
4844            return $output;
4845    }
4846    
4847    sub ConvertVersionsToHistoryFile {
4848            my ($self) = @_;
4849            my $vone = 0;
4850            my $vtwo = 0;
4851            my $continue = 1;
4852            my $lastTable;
4853            my $currentTable;
4854            my $cause;
4855            my $lastChanged = 0;
4856            my $noHitCount = 0;
4857            while ($continue == 1) {
4858                    $cause = "NONE";
4859                    $currentTable = undef;
4860                    if (-e $self->directory().$self->id()."V".($vone+1).".".$vtwo.".txt") {
4861                            $noHitCount = 0;
4862                            $lastChanged = 0;
4863                            $vone = $vone+1;
4864                            $currentTable = $self->figmodel()->database()->load_table($self->directory().$self->id()."V".$vone.".".$vtwo.".txt",";","|",1,["LOAD","DIRECTIONALITY","COMPARTMENT","ASSOCIATED PEG"]);
4865                            $cause = "RECONSTRUCTION";
4866                    } elsif (-e $self->directory().$self->id()."V".$vone.".".($vtwo+1).".txt") {
4867                            $noHitCount = 0;
4868                            $lastChanged = 0;
4869                            $vtwo = $vtwo+1;
4870                            $currentTable = $self->figmodel()->database()->load_table($self->directory().$self->id()."V".$vone.".".$vtwo.".txt",";","|",1,["LOAD","DIRECTIONALITY","COMPARTMENT","ASSOCIATED PEG"]);
4871                            $cause = "AUTOCOMPLETION";
4872                    } elsif ($lastChanged == 0) {
4873                            $lastChanged = 1;
4874                            $vone = $vone+1;
4875                            $cause = "RECONSTRUCTION";
4876                    } elsif ($lastChanged == 1) {
4877                            $lastChanged = 2;
4878                            $vone = $vone-1;
4879                            $vtwo = $vtwo+1;
4880                            $cause = "AUTOCOMPLETION";
4881                    } elsif ($lastChanged == 2) {
4882                            $lastChanged = 0;
4883                            $vone = $vone+1;
4884                            $cause = "RECONSTRUCTION";
4885                    }
4886                    if (defined($currentTable)) {
4887                            if (defined($lastTable)) {
4888                                    print $cause."\t".$self->directory().$self->id()."V".$vone.".".$vtwo.".txt\n";
4889                                    $self->calculate_model_changes($lastTable,$cause,$currentTable,"V".$vone.".".$vtwo);
4890                            }
4891                            $lastTable = $currentTable;
4892                    } else {
4893                            $noHitCount++;
4894                            if ($noHitCount >= 40) {
4895                                    last;
4896                            }
4897                    }
4898            }
4899    }
4900    
4901  1;  1;

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.21

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3