[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.2, Fri Dec 11 21:37:02 2009 UTC revision 1.19, Wed Jun 2 08:05:35 2010 UTC
# Line 1  Line 1 
 package FIGMODELmodel;  
1  use strict;  use strict;
2    package FIGMODELmodel;
3    
4  =head1 FIGMODELmodel object  =head1 FIGMODELmodel object
5  =head2 Introduction  =head2 Introduction
# Line 14  Line 14 
14  =cut  =cut
15  sub new {  sub new {
16          my ($class,$figmodel,$id) = @_;          my ($class,$figmodel,$id) = @_;
17    
18          #Error checking first          #Error checking first
19          if (!defined($figmodel)) {          if (!defined($figmodel)) {
20                  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 27  Line 28 
28          }          }
29    
30          #Checking that the id exists          #Checking that the id exists
31          my $tbl = $self->figmodel()->database()->GetDBTable("MODELS");          my $modelHandle = $self->figmodel()->database()->get_object_manager("model");
32          if (!defined($tbl)) {          if (!defined($modelHandle)) {
33                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not load MODELS table. Check database!");                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not load MODELS table. Check database!");
34                  return undef;                  return undef;
35          }          }
36    
37          #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;  
38          if ($id =~ m/^\d+$/) {          if ($id =~ m/^\d+$/) {
39                  $self->{_data} = $tbl->get_row($id);                  my $objects = $modelHandle->get_objects();
40          } else {                  $self->{_data} = $objects->[$id];
41                  $self->{_data} = $tbl->get_row_by_key($id,"id");                  $self->figmodel()->{_models}->{$id} = $self;
42                  if (defined($self->{_data})) {          } else {
43                          $index = $tbl->row_index($self->{_data});                  my $objects = $modelHandle->get_objects({id => $id});
44                    if (!defined($objects->[0]) && $id =~ m/(.+)(V[^V]+)/) {
45                            $objects = $modelHandle->get_objects({id => $1});
46                            if (!defined($objects->[0])) {
47                                    $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find model ".$id." in database!");
48                                    return undef;
49                            }
50                            $self->{_selectedversion} = $2;
51                    } elsif (!defined($objects->[0])) {
52                            $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find model ".$id." in database!");
53                            return undef;
54                  }                  }
55                    $self->{_data} = $objects->[0];
56          }          }
57          if (!defined($self->{_data})) {          if (!defined($self->{_data})) {
58                  $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 specified id in database!");
59                  return undef;                  return undef;
60          }          }
         $self->{_index} = $index;  
61          $self->figmodel()->{_models}->{$self->id()} = $self;          $self->figmodel()->{_models}->{$self->id()} = $self;
         $self->figmodel()->{_models}->{$self->index()} = $self;  
62    
63          return $self;          return $self;
64  }  }
# Line 107  Line 116 
116  =cut  =cut
117  sub fig {  sub fig {
118          my ($self) = @_;          my ($self) = @_;
   
119          if (!defined($self->{_fig}) && $self->source() !~ /^MGRAST/) {          if (!defined($self->{_fig}) && $self->source() !~ /^MGRAST/) {
120                  if ($self->source() =~ /^RAST/) {                  if ($self->source() =~ /^RAST/) {
121                          $self->{"_fig"} = $self->figmodel()->fig();#$self->genome());                          $self->{"_fig"} = $self->figmodel()->fig();#$self->genome());
# Line 115  Line 123 
123                          $self->{"_fig"} = $self->figmodel()->fig();                          $self->{"_fig"} = $self->figmodel()->fig();
124                  }                  }
125          }          }
   
126          return $self->{"_fig"};          return $self->{"_fig"};
127  }  }
128    
129    =head3 aquireModelLock
130    
131    Definition:
132    
133            FIGMODELmodel->aquireModelLock();
134    
135    Description:
136    
137            Locks the database for alterations relating to the current model object
138    
139    =cut
140    sub aquireModelLock {
141            my ($self) = @_;
142            $self->figmodel()->database()->genericLock($self->id());
143    }
144    
145    =head3 releaseModelLock
146    
147    Definition:
148    
149            FIGMODELmodel->releaseModelLock();
150    
151    Description:
152    
153            Unlocks the database for alterations relating to the current model object
154    
155    =cut
156    sub releaseModelLock {
157            my ($self) = @_;
158            $self->figmodel()->database()->genericUnlock($self->id());
159    }
160    
161  =head3 mgdata  =head3 mgdata
162  Definition:  Definition:
163          FIGMODEL = FIGMODELmodel->mgdata();          FIGMODEL = FIGMODELmodel->mgdata();
# Line 127  Line 166 
166  =cut  =cut
167  sub mgdata {  sub mgdata {
168          my ($self) = @_;          my ($self) = @_;
   
169          if (!defined($self->{_mgdata}) && $self->source() =~ /^MGRAST/) {          if (!defined($self->{_mgdata}) && $self->source() =~ /^MGRAST/) {
170                  require MGRAST;                  require MGRAST;
171                  $self->{_mgdata} = $self->figmodel()->mgrast()->Job->get_objects( { 'genome_id' => $self->genome() } )                  $self->{_mgdata} = $self->figmodel()->mgrast()->Job->get_objects( { 'genome_id' => $self->genome() } )
172          }          }
   
173          return $self->{_mgdata};          return $self->{_mgdata};
174  }  }
175    
# Line 144  Line 181 
181  =cut  =cut
182  sub id {  sub id {
183          my ($self) = @_;          my ($self) = @_;
184          return $self->{_data}->{id}->[0];          return $self->{_data}->id();
185  }  }
186    
187  =head3 owner  =head3 owner
# Line 155  Line 192 
192  =cut  =cut
193  sub owner {  sub owner {
194          my ($self) = @_;          my ($self) = @_;
195          return $self->{_data}->{owner}->[0];          return $self->{_data}->owner();
 }  
   
 =head3 index  
 Definition:  
         string = FIGMODELmodel->index();  
 Description:  
         Returns model index  
 =cut  
 sub index {  
         my ($self) = @_;  
         return $self->{_index};  
196  }  }
197    
198  =head3 name  =head3 name
# Line 185  Line 211 
211                          if (defined($self->mgdata())) {                          if (defined($self->mgdata())) {
212                                  $self->{_name} = $self->mgdata()->genome_name;                                  $self->{_name} = $self->mgdata()->genome_name;
213                          }                          }
                 } elsif (defined($self->stats())) {  
                         $self->{_name} = $self->stats()->{'Organism name'}->[0];  
214                  } elsif ($source !~ /^RAST/) {                  } elsif ($source !~ /^RAST/) {
215                          $self->{_name} = $self->fig()->orgname_of_orgid($self->genome());                          $self->{_name} = $self->fig()->orgname_of_orgid($self->genome());
216                    } else {
217                            $self->{_name} = $self->figmodel()->get_genome_stats($self->genome())->{NAME}->[0];
218                  }                  }
219          }          }
220    
221          return $self->{_name};          return $self->{_name};
222  }  }
223    
 =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};  
 }  
   
224  =head3 get_reaction_class  =head3 get_reaction_class
225  Definition:  Definition:
226          string = FIGMODELmodel->get_reaction_class(string::reaction ID);          string = FIGMODELmodel->get_reaction_class(string::reaction ID);
# Line 217  Line 228 
228          Returns reaction class          Returns reaction class
229  =cut  =cut
230  sub get_reaction_class {  sub get_reaction_class {
231          my ($self,$reaction,$nohtml) = @_;          my ($self,$reaction,$nohtml,$brief_flux) = @_;
232    
233          if (!-e $self->directory()."ReactionClassification-".$self->id().".tbl") {          if (!-e $self->directory()."ReactionClassification-".$self->id().".tbl") {
234                  if (!defined($self->{_reaction_classes})) {                  if (!defined($self->{_reaction_classes})) {
# Line 230  Line 241 
241                  my $ClassRow = $self->{_reaction_classes}->get_row_by_key($reaction,"REACTION");                  my $ClassRow = $self->{_reaction_classes}->get_row_by_key($reaction,"REACTION");
242                  if (defined($ClassRow) && defined($ClassRow->{CLASS})) {                  if (defined($ClassRow) && defined($ClassRow->{CLASS})) {
243                          my $class;                          my $class;
244                            my $min = $ClassRow->{MIN}->[0];
245                            my $max = $ClassRow->{MAX}->[0];
246                          if ($ClassRow->{CLASS}->[0] eq "Positive") {                          if ($ClassRow->{CLASS}->[0] eq "Positive") {
247                                  $class = "Essential =>";                                  $class = "Essential =>";
248                                    $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
249                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative") {
250                                  $class = "Essential <=";                                  $class = "Essential <=";
251                                    $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
252                          } elsif ($ClassRow->{CLASS}->[0] eq "Positive variable") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Positive variable") {
253                                  $class = "Active =>";                                  $class = "Active =>";
254                                    $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
255                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative variable") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative variable") {
256                                  $class = "Active <=";                                  $class = "Active <=";
257                                    $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
258                          } elsif ($ClassRow->{CLASS}->[0] eq "Variable") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Variable") {
259                                  $class = "Active <=>";                                  $class = "Active <=>";
260                                    $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
261                          } elsif ($ClassRow->{CLASS}->[0] eq "Blocked") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Blocked") {
262                                  $class = "Inactive";                                  $class = "Inactive";
263                          } elsif ($ClassRow->{CLASS}->[0] eq "Dead") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Dead") {
264                                  $class = "Disconnected";                                  $class = "Disconnected";
265                          }                          }
266    
267                          if (!defined($nohtml) || $nohtml ne "1") {                          if (!defined($nohtml) || $nohtml ne "1") {
268                                  $class = "<span title=\"Flux:".$ClassRow->{MIN}->[0]." to ".$ClassRow->{MAX}->[0]."\">".$class."</span>";                                  $class = "<span title=\"Flux:".$min." to ".$max."\">".$class."</span>";
269                          }                          }
270    
271                          return $class;                          return $class;
272                  }                  }
273                  return undef;                  return undef;
# Line 268  Line 288 
288                                  $classstring .= "<br>";                                  $classstring .= "<br>";
289                          }                          }
290                          my $NewClass;                          my $NewClass;
291                            my $min = $ClassRow->{MIN}->[$i];
292                            my $max = $ClassRow->{MAX}->[$i];
293                          if ($ClassRow->{CLASS}->[$i] eq "Positive") {                          if ($ClassRow->{CLASS}->[$i] eq "Positive") {
294                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential =>";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential =>";
295                                  if (!defined($nohtml) || $nohtml ne "1") {                                  $brief_flux ? $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $NewClass.="<br>[Flux: ".$min." to ".$max."]<br>";
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
296                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative") {
297                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential <=";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential <=";
298                                  if (!defined($nohtml) || $nohtml ne "1") {                                  $brief_flux ? $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $NewClass.="<br>[Flux: ".$min." to ".$max."]<br>";
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
299                          } elsif ($ClassRow->{CLASS}->[$i] eq "Positive variable") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Positive variable") {
300                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active =>";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active =>";
301                                  if (!defined($nohtml) || $nohtml ne "1") {                                  $brief_flux ? $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $NewClass.="<br>[Flux: ".$min." to ".$max."]<br>";
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
302                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative variable") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative variable") {
303                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=";
304                                  if (!defined($nohtml) || $nohtml ne "1") {                                  $brief_flux ? $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $NewClass.="<br>[Flux: ".$min." to ".$max."]<br>";
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
305                          } elsif ($ClassRow->{CLASS}->[$i] eq "Variable") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Variable") {
306                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=>";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=>";
307                                  if (!defined($nohtml) || $nohtml ne "1") {                                  $brief_flux ? $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $NewClass.="<br>[Flux: ".$min." to ".$max."]<br>";
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
308                          } elsif ($ClassRow->{CLASS}->[$i] eq "Blocked") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Blocked") {
309                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Inactive";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Inactive";
                                 if (!defined($nohtml) || $nohtml ne "1") {  
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
310                          } elsif ($ClassRow->{CLASS}->[$i] eq "Dead") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Dead") {
311                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Disconnected";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Disconnected";
                                 if (!defined($nohtml) || $nohtml ne "1") {  
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
312                                  }                                  }
313    
314                            if (!defined($nohtml) || $nohtml ne "1") {
315                                    $NewClass = "<span title=\"Flux:".$min." to ".$max."\">".$NewClass."</span>";
316                          }                          }
317                          $classstring .= $NewClass;                          $classstring .= $NewClass;
318                  }                  }
# Line 321  Line 331 
331    
332          if (!defined($self->{_biomass})) {          if (!defined($self->{_biomass})) {
333                  my $rxntbl = $self->reaction_table();                  my $rxntbl = $self->reaction_table();
334                    if (defined($rxntbl)) {
335                  for (my $i=0; $i < $rxntbl->size(); $i++) {                  for (my $i=0; $i < $rxntbl->size(); $i++) {
336                          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/) {
337                                  $self->{_biomass} = $rxntbl->get_row($i)->{"LOAD"}->[0];                                  $self->{_biomass} = $rxntbl->get_row($i)->{"LOAD"}->[0];
# Line 328  Line 339 
339                          }                          }
340                  }                  }
341          }          }
342            }
343    
344          return $self->get_reaction_data($self->{_biomass});          return $self->get_reaction_data($self->{_biomass});
345  }  }
# Line 366  Line 378 
378          return $Data->{LOAD}->[0];          return $Data->{LOAD}->[0];
379  }  }
380    
381    =head3 load_model_table
382    
383    Definition: FIGMODELTable = FIGMODELmodel->load_model_table(string:table name,0/1:refresh the table));
384    
385    Description: Returns the table specified by the input filename. Table will be stored in a file in the model directory.
386    
387    =cut
388    sub load_model_table {
389            my ($self,$name,$refresh) = @_;
390            if (defined($refresh) && $refresh == 1) {
391                    delete $self->{"_".$name};
392            }
393            if (!defined($self->{"_".$name})) {
394                    my $tbldef = $self->figmodel()->config($name);
395                    if (!defined($tbldef)) {
396                            return undef;
397                    }
398                    my $itemDelim = "|";
399                    if (defined($tbldef->{itemdelimiter}->[0])) {
400                            $itemDelim = $tbldef->{itemdelimiter}->[0];
401                            if ($itemDelim eq "SC") {
402                                    $itemDelim = ";";
403                            }
404                    }
405                    my $columnDelim = "\t";
406                    if (defined($tbldef->{columndelimiter}->[0])) {
407                            $columnDelim = $tbldef->{columndelimiter}->[0];
408                            if ($columnDelim eq "SC") {
409                                    $columnDelim = ";";
410                            }
411                    }
412                    my $suffix = ".tbl";
413                    if (defined($tbldef->{filename_suffix}->[0])) {
414                            $suffix = $tbldef->{filename_suffix}->[0];
415                    }
416                    my $filename = $self->directory().$name."-".$self->id().$self->selected_version().$suffix;
417                    if (defined($tbldef->{filename_prefix}->[0])) {
418                            if ($tbldef->{filename_prefix}->[0] eq "NONE") {
419                                    $filename = $self->directory().$self->id().$self->selected_version().$suffix;
420                            } else {
421                                    $filename = $self->directory().$tbldef->{filename_prefix}->[0]."-".$self->id().$self->selected_version().$suffix;
422                            }
423                    }
424                    if (-e $filename) {
425                            $self->{"_".$name} = $self->figmodel()->database()->load_table($filename,$columnDelim,$itemDelim,$tbldef->{headingline}->[0],$tbldef->{hashcolumns});
426                    } else {
427                            if (defined($tbldef->{prefix})) {
428                                    $self->{"_".$name} = FIGMODELTable->new($tbldef->{columns},$filename,$tbldef->{hashcolumns},$columnDelim,$itemDelim,join(@{$tbldef->{prefix}},"\n"));
429                            } else {
430                                    $self->{"_".$name} = FIGMODELTable->new($tbldef->{columns},$filename,$tbldef->{hashcolumns},$columnDelim,$itemDelim);
431                            }
432                    }
433            }
434            return $self->{"_".$name};
435    }
436    
437    =head3 create_table_prototype
438    
439    Definition:
440            FIGMODELTable::table = FIGMODELmodel->create_table_prototype(string::table);
441    Description:
442            Returns a empty FIGMODELTable with all the metadata associated with the input table name
443    
444    =cut
445    sub create_table_prototype {
446            my ($self,$TableName) = @_;
447    
448            #Checking if the table definition exists in the FIGMODELconfig file
449            if (!defined($self->figmodel()->config($TableName))) {
450                    $self->figmodel()->error_message("FIGMODELdatabase:create_table_prototype:Definition not found for ".$TableName);
451                    return undef;
452            }
453            #Checking that this is a database table
454            if (!defined($self->config($TableName)->{tabletype}) || $self->config($TableName)->{tabletype}->[0] ne "ModelTable") {
455                    $self->figmodel()->error_message("FIGMODELdatabase:create_table_prototype:".$TableName." is not a model table!");
456                    return undef;
457            }
458            if (!defined($self->config($TableName)->{delimiter})) {
459                    $self->config($TableName)->{delimiter}->[0] = ";";
460            }
461            if (!defined($self->config($TableName)->{itemdelimiter})) {
462                    $self->config($TableName)->{itemdelimiter}->[0] = "|";
463            }
464            my $prefix;
465            if (defined($self->config($TableName)->{prefix})) {
466                    $prefix = join("\n",@{$self->config($TableName)->{prefix}});
467            }
468            my $tbl = FIGMODELTable->new($self->config($TableName)->{columns},$self->directory().$self->config($TableName)->{filename_prefix}->[0]."-".$self->id().$self->selected_version().".txt",$self->config($TableName)->{hashcolumns},$self->config($TableName)->{delimiter}->[0],$self->config($TableName)->{itemdelimiter}->[0],$prefix);
469            return $tbl;
470    }
471    
472  =head3 get_reaction_number  =head3 get_reaction_number
473  Definition:  Definition:
474          int = FIGMODELmodel->get_reaction_number();          int = FIGMODELmodel->get_reaction_number();
# Line 374  Line 477 
477  =cut  =cut
478  sub get_reaction_number {  sub get_reaction_number {
479          my ($self) = @_;          my ($self) = @_;
   
480          if (!defined($self->reaction_table())) {          if (!defined($self->reaction_table())) {
481                  return 0;                  return 0;
482          }          }
   
483          return $self->reaction_table()->size();          return $self->reaction_table()->size();
484  }  }
485    
# Line 389  Line 490 
490          Returns FIGMODELTable with the reaction list for the model          Returns FIGMODELTable with the reaction list for the model
491  =cut  =cut
492  sub reaction_table {  sub reaction_table {
493          my ($self) = @_;          my ($self,$clear) = @_;
494            my $tbl = $self->load_model_table("ModelReactions",$clear);
495          if (!defined($self->{_reaction_data})) {          my $classTbl = $self->reaction_class_table();
496                  $self->{_reaction_data} = $self->figmodel()->database()->GetDBModel($self->id());          if (defined($classTbl)) {
497                    for (my $i=0; $i < $classTbl->size(); $i++) {
498                            my $row = $classTbl->get_row($i);
499                            if (defined($row->{REACTION})) {
500                                    my $rxnRow = $tbl->get_row_by_key($row->{"REACTION"}->[0],"LOAD");
501                                    if (defined($row->{MEDIA})) {
502                                            for (my $j=0; $j < @{$row->{MEDIA}};$j++) {
503                                                    my $class = "Active <=>";
504                                                    if ($row->{CLASS}->[$j] eq "Positive") {
505                                                            $class = "Essential =>";
506                                                    } elsif ($row->{CLASS}->[$j] eq "Negative") {
507                                                            $class = "Essential <=";
508                                                    } elsif ($row->{CLASS}->[$j] eq "Blocked") {
509                                                            $class = "Inactive";
510                                                    } elsif ($row->{CLASS}->[$j] eq "Positive variable") {
511                                                            $class = "Active =>";
512                                                    } elsif ($row->{CLASS}->[$j] eq "Negative variable") {
513                                                            $class = "Active <=";
514                                                    } elsif ($row->{CLASS}->[$j] eq "Variable") {
515                                                            $class = "Active <=>";
516                                                    } elsif ($row->{CLASS}->[$j] eq "Dead") {
517                                                            $class = "Dead";
518                                                    }
519                                                    push(@{$rxnRow->{PREDICTIONS}},$row->{MEDIA}->[$j].":".$class);
520                                            }
521                                    }
522                            }
523                    }
524            }
525            return $tbl;
526          }          }
527    
528          return $self->{_reaction_data};  =head3 model_history
529    Definition:
530            FIGMODELTable = FIGMODELmodel->model_history();
531    Description:
532            Returns FIGMODELTable with the history of model changes
533    =cut
534    sub model_history {
535            my ($self,$clear) = @_;
536            return $self->load_model_table("ModelHistory",$clear);
537  }  }
538    
539  =head3 reaction_class_table  =head3 feature_table
540  Definition:  Definition:
541          FIGMODELTable = FIGMODELmodel->reaction_class_table();          FIGMODELTable = FIGMODELmodel->feature_table();
542  Description:  Description:
543          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
544  =cut  =cut
545  sub reaction_class_table {  sub feature_table {
546          my ($self) = @_;          my ($self) = @_;
547    
548          if (!defined($self->{_reaction_class_table})) {          if (!defined($self->{_feature_data})) {
549                  if (-e $self->directory()."ReactionClassification-".$self->id().$self->selected_version().".tbl") {                  #Getting the genome feature list
550                          $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());
551                    if (!defined($FeatureTable)) {
552                            print STDERR "FIGMODELmodel:feature_table:Could not get features for genome ".$self->genome()." in database!";
553                            return undef;
554                    }
555                    #Getting the reaction table for the model
556                    my $rxnTable = $self->reaction_table();
557                    if (!defined($rxnTable)) {
558                    print STDERR "FIGMODELmodel:feature_table:Could not get reaction table for model ".$self->id()." in database!";
559                            return undef;
560                }
561                    #Cloning the feature table
562                    $self->{_feature_data} = $FeatureTable->clone_table_def();
563                    $self->{_feature_data}->add_headings(($self->id()."REACTIONS",$self->id()."PREDICTIONS"));
564                for (my $i=0; $i < $rxnTable->size(); $i++) {
565                    my $Row = $rxnTable->get_row($i);
566                    if (defined($Row) && defined($Row->{"ASSOCIATED PEG"})) {
567                            foreach my $GeneSet (@{$Row->{"ASSOCIATED PEG"}}) {
568                                    my $temp = $GeneSet;
569                                    $temp =~ s/\+/|/g;
570                                    $temp =~ s/\sAND\s/|/gi;
571                                    $temp =~ s/\sOR\s/|/gi;
572                                    $temp =~ s/[\(\)\s]//g;
573                                    my @GeneList = split(/\|/,$temp);
574                                    foreach my $Gene (@GeneList) {
575                                    my $FeatureRow = $self->{_feature_data}->get_row_by_key("fig|".$self->genome().".".$Gene,"ID");
576                                                    if (!defined($FeatureRow)) {
577                                                            $FeatureRow = $FeatureTable->get_row_by_key("fig|".$self->genome().".".$Gene,"ID");
578                                                            if (defined($FeatureRow)) {
579                                                                    $self->{_feature_data}->add_row($FeatureRow);
580                                                            }
581                                                    }
582                                                    if (defined($FeatureRow)) {
583                                                            $self->{_feature_data}->add_data($FeatureRow,$self->id()."REACTIONS",$Row->{"LOAD"}->[0],1);
584                                                    }
585                                    }
586                            }
587                    }
588                }
589                #Loading predictions
590                my @files = glob($self->directory()."EssentialGenes-".$self->id()."-*");
591                foreach my $file (@files) {
592                    if ($file =~ m/\-([^\-]+)\.tbl/) {
593                            my $media = $1;
594                            my $list = $self->figmodel()->database()->load_single_column_file($file,"");
595                            my $hash;
596                            foreach my $gene (@{$list}) {
597                                    $hash->{$gene} = 1;
598                            }
599                            for (my $i=0; $i < $self->{_feature_data}->size(); $i++) {
600                                    my $Row = $self->{_feature_data}->get_row($i);
601                                    if ($Row->{ID}->[0] =~ m/(peg\.\d+)/) {
602                                            my $gene = $1;
603                                            if (defined($hash->{$gene})) {
604                                                    push(@{$Row->{$self->id()."PREDICTIONS"}},$media.":essential");
605                  } else {                  } else {
606                          $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"}},$media.":nonessential");
607                                            }
608                                    }
609                            }
610                    }
611                }
612                  }                  }
613            return $self->{_feature_data};
614          }          }
615    
616          return $self->{_reaction_class_table};  =head3 reaction_class_table
617    Definition:
618            FIGMODELTable = FIGMODELmodel->reaction_class_table();
619    Description:
620            Returns FIGMODELTable with the reaction class data, and creates the table file  if it does not exist
621    =cut
622    sub reaction_class_table {
623            my ($self,$clear) = @_;
624            return $self->load_model_table("ModelReactionClasses",$clear);
625  }  }
626    
627  =head3 compound_class_table  =head3 compound_class_table
# Line 425  Line 631 
631          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
632  =cut  =cut
633  sub compound_class_table {  sub compound_class_table {
634          my ($self) = @_;          my ($self,$clear) = @_;
635            return $self->load_model_table("ModelCompoundClasses",$clear);
636    }
637    
638          if (!defined($self->{_compound_class_table})) {  =head3 get_essential_genes
639                  if (-e $self->directory()."CompoundClassification-".$self->id().$self->selected_version().".tbl") {  Definition:
640                          $self->{_compound_class_table} = $self->figmodel()->database()->load_table($self->directory()."CompoundClassification-".$self->id().$self->selected_version().".tbl",";","|",0,["COMPOUND","CLASS","MEDIA"]);          [string::peg ID] = FIGMODELmodel->get_essential_genes(string::media condition);
641                  } else {  Description:
642                          $self->{_compound_class_table} = FIGMODELTable->new(["COMPOUND","MEDIA","CLASS","MIN","MAX"],$self->directory()."CompoundClassification-".$self->id().$self->selected_version().".tbl",["COMPOUND","CLASS","MEDIA"],";","|",undef);          Returns an reference to an array of the predicted essential genes during growth in the input media condition
643    =cut
644    sub get_essential_genes {
645            my ($self,$media) = @_;
646    
647            if (!defined($media)) {
648                    $media = "Complete";
649            }
650            if (!defined($self->{_essential_genes}->{$media})) {
651                    $self->{_essential_genes}->{$media} = undef;
652                    if (-e $self->directory()."EssentialGenes-".$self->id().$self->selected_version()."-".$media.".tbl") {
653                            $self->{_essential_genes}->{$media} = $self->figmodel()->database()->load_single_column_file($self->directory()."EssentialGenes-".$self->id().$self->selected_version()."-".$media.".tbl","");
654                  }                  }
655          }          }
656    
657          return $self->{_compound_class_table};          return $self->{_essential_genes}->{$media};
658  }  }
659    
660  =head3 compound_table  =head3 compound_table
# Line 456  Line 675 
675    
676  =head3 get_compound_data  =head3 get_compound_data
677  Definition:  Definition:
678          string = FIGMODELmodel->get_compound_data(string::compound ID);          {string:key=>[string]:values} = FIGMODELmodel->get_compound_data(string::compound ID);
679  Description:  Description:
680          Returns model compound data          Returns model compound data
681  =cut  =cut
# Line 467  Line 686 
686                  return undef;                  return undef;
687          }          }
688          if ($compound =~ m/^\d+$/) {          if ($compound =~ m/^\d+$/) {
689                  $self->compound_table()->get_row($compound);                  return $self->compound_table()->get_row($compound);
690          }          }
691          return $self->compound_table()->get_row_by_key($compound,"DATABASE");          return $self->compound_table()->get_row_by_key($compound,"DATABASE");
692  }  }
693    
694    =head3 get_feature_data
695    Definition:
696            {string:key=>[string]:values} = FIGMODELmodel->get_feature_data(string::feature ID);
697    Description:
698            Returns model feature data
699    =cut
700    sub get_feature_data {
701            my ($self,$feature) = @_;
702            if (!defined($self->feature_table())) {
703                    return undef;
704            }
705            if ($feature =~ m/^\d+$/) {
706                    return $self->feature_table()->get_row($feature);
707            }
708            if ($feature =~ m/(peg\.\d+)/) {
709                    $feature = $1;
710            }
711            return $self->feature_table()->get_row_by_key("fig|".$self->genome().".".$feature,"ID");
712    }
713    
714  =head3 genome  =head3 genome
715  Definition:  Definition:
716          string = FIGMODELmodel->genome();          string = FIGMODELmodel->genome();
# Line 480  Line 719 
719  =cut  =cut
720  sub genome {  sub genome {
721          my ($self) = @_;          my ($self) = @_;
722          return $self->{_data}->{genome}->[0];          return $self->{_data}->genome();
723  }  }
724    
725  =head3 source  =head3 source
# Line 491  Line 730 
730  =cut  =cut
731  sub source {  sub source {
732          my ($self) = @_;          my ($self) = @_;
733          return $self->{_data}->{source}->[0];          return $self->{_data}->source();
734  }  }
735    
736  =head3 rights  =head3 rights
# Line 502  Line 741 
741  =cut  =cut
742  sub rights {  sub rights {
743          my ($self,$username) = @_;          my ($self,$username) = @_;
   
744          if ($self->public()) {          if ($self->public()) {
745                  return 1;                  return 1;
746          }          }
# Line 510  Line 748 
748                  return 0;                  return 0;
749          }          }
750          if (!defined($self->{_userrights}->{$username})) {          if (!defined($self->{_userrights}->{$username})) {
751                  if (defined($self->{_data}->{master})) {                  $self->{_userrights}->{$self->{_data}->owner()} = 1;
752                          for (my $i=0; $i < @{$self->{_data}->{master}};$i++) {                  my @users = split(/\|/,$self->{_data}->users());
753                                  $self->{_userrights}->{$self->{_data}->{master}->[$i]} = 1;                  for (my $i=0; $i < @users;$i++) {
754                          }                          $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;  
                         }  
755                  }                  }
756          }          }
757          return $self->{_userrights}->{$username};          return $self->{_userrights}->{$username};
# Line 532  Line 765 
765  =cut  =cut
766  sub public {  sub public {
767          my ($self) = @_;          my ($self) = @_;
768            if ($self->{_data}->users() eq "all") {
769          if (!defined($self->{_public})) {                  return 1;
                 $self->{_public} = 0;  
                 if (defined($self->{_data}->{users}->[0]) && $self->{_data}->{users}->[0] eq "all") {  
                         $self->{_public} = 1;  
                 }  
770          }          }
771          return $self->{_public};          return 0;
772  }  }
773    
774  =head3 directory  =head3 directory
# Line 587  Line 816 
816          return $self->directory().$self->id().$self->selected_version().".txt";          return $self->directory().$self->id().$self->selected_version().".txt";
817  }  }
818    
 =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};  
         }  
 }  
   
819  =head3 version  =head3 version
820  Definition:  Definition:
821          string = FIGMODELmodel->version();          string = FIGMODELmodel->version();
# Line 638  Line 827 
827    
828          if (!defined($self->{_version})) {          if (!defined($self->{_version})) {
829                  if (!defined($self->{_selectedversion})) {                  if (!defined($self->{_selectedversion})) {
830                          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];  
                         }  
831                  } else {                  } else {
832                          $self->{_version} = $self->{_selectedversion};                          $self->{_version} = $self->{_selectedversion};
833                  }                  }
# Line 671  Line 858 
858  =cut  =cut
859  sub modification_time {  sub modification_time {
860          my ($self) = @_;          my ($self) = @_;
861          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} = 0;  
                 }  
         }  
         return $self->{_modification_time};  
862  }  }
863    
864  =head3 gene_reactions  =head3 gene_reactions
# Line 695  Line 869 
869  =cut  =cut
870  sub gene_reactions {  sub gene_reactions {
871          my ($self) = @_;          my ($self) = @_;
872            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};  
873  }  }
874    
875  =head3 total_compounds  =head3 total_compounds
# Line 714  Line 880 
880  =cut  =cut
881  sub total_compounds {  sub total_compounds {
882          my ($self) = @_;          my ($self) = @_;
883            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};  
884  }  }
885    
886  =head3 gapfilling_reactions  =head3 gapfilling_reactions
# Line 733  Line 891 
891  =cut  =cut
892  sub gapfilling_reactions {  sub gapfilling_reactions {
893          my ($self) = @_;          my ($self) = @_;
894            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};  
895  }  }
896    
897  =head3 total_reactions  =head3 total_reactions
# Line 752  Line 902 
902  =cut  =cut
903  sub total_reactions {  sub total_reactions {
904          my ($self) = @_;          my ($self) = @_;
905            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};  
906  }  }
907    
908  =head3 model_genes  =head3 model_genes
# Line 771  Line 913 
913  =cut  =cut
914  sub model_genes {  sub model_genes {
915          my ($self) = @_;          my ($self) = @_;
916            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};  
917  }  }
918    
919  =head3 class  =head3 class
# Line 790  Line 924 
924  =cut  =cut
925  sub class {  sub class {
926          my ($self) = @_;          my ($self) = @_;
927            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];  
                 }  
928          }          }
929          return $self->{_class};  
930    sub autocompleteMedia {
931            my ($self) = @_;
932            return $self->{_data}->autoCompleteMedia();
933  }  }
934    
935  =head3 taxonomy  =head3 taxonomy
# Line 866  Line 997 
997                          if (defined($self->mgdata())) {                          if (defined($self->mgdata())) {
998                                  $self->{_genome_genes} = $self->mgdata()->genome_contig_count;                                  $self->{_genome_genes} = $self->mgdata()->genome_contig_count;
999                          }                          }
1000                  } elsif (defined($self->stats())) {                  } else {
1001                          $self->{_genome_genes} = $self->stats()->{'Total genes'}->[0];                          $self->{_genome_genes} = $self->figmodel()->get_genome_stats($self->genome())->{"TOTAL GENES"}->[0];
1002                  }                  }
1003          }          }
1004    
# Line 892  Line 1023 
1023          #Checking that the table is defined and the output file exists          #Checking that the table is defined and the output file exists
1024          if (defined($result) && defined($result->get_row(0)->{"ESSENTIALGENES"})) {          if (defined($result) && defined($result->get_row(0)->{"ESSENTIALGENES"})) {
1025                  $self->figmodel()->database()->print_array_to_file($self->directory()."EssentialGenes-".$self->id()."-".$Media.".tbl",[join("\n",@{$result->get_row(0)->{"ESSENTIALGENES"}})]);                  $self->figmodel()->database()->print_array_to_file($self->directory()."EssentialGenes-".$self->id()."-".$Media.".tbl",[join("\n",@{$result->get_row(0)->{"ESSENTIALGENES"}})]);
1026            } else {
1027                    $self->figmodel()->error_message("FIGMODELmodel:run_default_model_predictions:could not identify essential reactions for model ".$self->id().$self->selected_version().".");
1028                    return $self->figmodel()->fail();
1029          }          }
1030    
1031          #Classifying reactions and compounds          #Classifying reactions and compounds
1032          my $tbl = $self->classify_model_reactions($Media);          my $tbl = $self->classify_model_reactions($Media);
1033            if (!defined($tbl)) {
1034                    $self->figmodel()->error_message("FIGMODELmodel:run_default_model_predictions:could not classify reactions for model ".$self->id().$self->selected_version().".");
1035                    return $self->figmodel()->fail();
1036            }
1037          $tbl->save();          $tbl->save();
1038    
1039          return $self->figmodel()->success();          return $self->figmodel()->success();
1040  }  }
1041    
 =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();  
         }  
 }  
   
1042  =head3 update_stats_for_gap_filling  =head3 update_stats_for_gap_filling
1043  Definition:  Definition:
1044          {string => [string]} = FIGMODELmodel->update_stats_for_gap_filling(int::gapfill time);          {string => [string]} = FIGMODELmodel->update_stats_for_gap_filling(int::gapfill time);
# Line 925  Line 1046 
1046  =cut  =cut
1047  sub update_stats_for_gap_filling {  sub update_stats_for_gap_filling {
1048          my ($self,$gapfilltime) = @_;          my ($self,$gapfilltime) = @_;
1049            $self->{_data}->autoCompleteTime($gapfilltime);
1050          #preserving the stats for the now obselete model          $self->{_data}->autocompleteDate(time());
1051          $self->save_obsolete_stats();          $self->{_data}->modificationDate(time());
1052          my $stats = $self->update_model_stats(0);          my $version = $self->{_data}->autocompleteVersion();
1053          $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;  
1054  }  }
1055    
1056  =head3 update_stats_for_build  =head3 update_stats_for_build
# Line 948  Line 1060 
1060  =cut  =cut
1061  sub update_stats_for_build {  sub update_stats_for_build {
1062          my ($self) = @_;          my ($self) = @_;
1063            $self->{_data}->builtDate(time());
1064          #preserving the stats for the now obselete model          $self->{_data}->modificationDate(time());
1065          $self->save_obsolete_stats();          my $version = $self->{_data}->version();
1066          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;  
1067  }  }
1068    
1069  =head3 update_model_stats  =head3 update_model_stats
# Line 979  Line 1082 
1082          }          }
1083          my $cpdtbl = $self->compound_table();          my $cpdtbl = $self->compound_table();
1084    
1085          #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];  
         }  
   
1086          my %GeneHash;          my %GeneHash;
1087          my %NonpegHash;          my %NonpegHash;
1088          my %CompoundHash;          my %CompoundHash;
1089            my $spontaneousReactions = 0;
1090            my $gapFillReactions = 0;
1091            my $biologReactions = 0;
1092            my $transporters = 0;
1093            my $autoCompleteReactions = 0;
1094            my $associatedSubsystemGenes = 0;
1095          for (my $i=0; $i < $rxntbl->size(); $i++) {          for (my $i=0; $i < $rxntbl->size(); $i++) {
1096                  my $Row = $rxntbl->get_row($i);                  my $Row = $rxntbl->get_row($i);
1097                  if (defined($Row) && defined($Row->{"ASSOCIATED PEG"})) {                  if (defined($Row) && defined($Row->{"ASSOCIATED PEG"})) {
# Line 1037  Line 1099 
1099                          if (defined($ReactionRow->{"EQUATION"}->[0])) {                          if (defined($ReactionRow->{"EQUATION"}->[0])) {
1100                                  #Checking for extracellular metabolites which indicate that this is a transporter                                  #Checking for extracellular metabolites which indicate that this is a transporter
1101                                  if ($ReactionRow->{"EQUATION"}->[0] =~ m/\[e\]/) {                                  if ($ReactionRow->{"EQUATION"}->[0] =~ m/\[e\]/) {
1102                                          $CurrentStats->{"Transport reaction"}->[0]++;                                          $transporters++;
1103                                  }                                  }
1104                          }                          }
1105                          #Identifying spontaneous/biolog/gapfilling/gene associated reactions                          #Identifying spontaneous/biolog/gapfilling/gene associated reactions
1106                          if ($Row->{"ASSOCIATED PEG"}->[0] =~ m/BIOLOG/i) {                          if ($Row->{"ASSOCIATED PEG"}->[0] =~ m/BIOLOG/i) {
1107                                  $CurrentStats->{"Biolog gap filling reactions"}->[0]++;                                  $biologReactions++;
1108                            } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/GROW/i) {
1109                                    $gapFillReactions++;
1110                          } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/SPONTANEOUS/i) {                          } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/SPONTANEOUS/i) {
1111                                  $CurrentStats->{"Spontaneous"}->[0]++;                                  $spontaneousReactions++;
1112                          } 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) {
1113                                  $CurrentStats->{"Gap filling reactions"}->[0]++;                                  $autoCompleteReactions++;
1114                          } else {                          } else {
1115                                  foreach my $GeneSet (@{$Row->{"ASSOCIATED PEG"}}) {                                  foreach my $GeneSet (@{$Row->{"ASSOCIATED PEG"}}) {
1116                                          my @GeneList = split(/\+/,$GeneSet);                                          $_ = $GeneSet;
1117                                            my @GeneList = /(peg\.\d+)/g;
1118                                          foreach my $Gene (@GeneList) {                                          foreach my $Gene (@GeneList) {
1119                                                  if ($Gene =~ m/(peg\.\d+)/) {                                                  if ($Gene =~ m/(peg\.\d+)/) {
1120                                                          $GeneHash{$1} = 1;                                                          $GeneHash{$1} = 1;
# Line 1063  Line 1128 
1128          }          }
1129          my @genes = keys(%GeneHash);          my @genes = keys(%GeneHash);
1130          my @othergenes = keys(%NonpegHash);          my @othergenes = keys(%NonpegHash);
         $CurrentStats->{"Genes with reactions"}->[0] = @genes + @othergenes;  
1131    
1132          #Updating the stats stored in the table          #Setting the reaction count
1133          $self->figmodel()->database()->update_row("MODEL STATS",$CurrentStats,"Model ID");          $self->{_data}->reactions($rxntbl->size());
1134          $self->{_stats} = $CurrentStats;          #Setting the metabolite count
1135          return $CurrentStats;          $self->{_data}->compounds($rxntbl->size());
1136            #Setting the gene count
1137            my $geneCount = @genes + @othergenes;
1138            $self->{_data}->associatedGenes($geneCount);
1139            #Setting remaining stats
1140            $self->{_data}->spontaneousReactions($spontaneousReactions);
1141            $self->{_data}->gapFillReactions($gapFillReactions);
1142            $self->{_data}->biologReactions($biologReactions);
1143            $self->{_data}->transporters($transporters);
1144            $self->{_data}->autoCompleteReactions($autoCompleteReactions);
1145            $self->{_data}->associatedSubsystemGenes($associatedSubsystemGenes);
1146            #Setting the model class
1147            my $class = "";
1148            for (my $i=0; $i < @{$self->figmodel()->config("class list")}; $i++) {
1149                    if (defined($self->figmodel()->config($self->figmodel()->config("class list")->[$i]))) {
1150                            if (defined($self->figmodel()->config($self->figmodel()->config("class list")->[$i])->{$self->id()})) {
1151                                    $class = $self->figmodel()->config("class list")->[$i];
1152                                    last;
1153                            }
1154                            if ($class eq "" && defined($self->figmodel()->config($self->figmodel()->config("class list")->[$i])->{$self->genome()})) {
1155                                    $class = $self->figmodel()->config("class list")->[$i];
1156                            }
1157                    }
1158            }
1159            if ($class eq "") {
1160                    $class = $self->figmodel()->get_genome_stats($self->genome())->{CLASS}->[0];
1161            }
1162            if ($class eq "") {
1163                    $class = "unknown";
1164            }
1165            $self->{_data}->cellwalltype($class);
1166  }  }
1167    
1168  =head3 GapFillModel  =head3 GapFillModel
# Line 1088  Line 1182 
1182          my $UniqueFilename = $self->figmodel()->filename();          my $UniqueFilename = $self->figmodel()->filename();
1183          my $StartTime = time();          my $StartTime = time();
1184    
1185          #Archiving the existing model          #Reading original reaction table
1186          $self->ArchiveModel();          my $OriginalRxn = $self->reaction_table();
1187            #Clearing the table
1188            $self->reaction_table(1);
1189    
1190          #Removing any gapfilling reactions that may be currently present in the model          #Removing any gapfilling reactions that may be currently present in the model
1191          if (!defined($donotclear) || $donotclear != 1) {          if (!defined($donotclear) || $donotclear != 1) {
1192                  my $ModelTable = $self->reaction_table();                  my $ModelTable = $self->reaction_table();
1193                  for (my $i=0; $i < $ModelTable->size(); $i++) {                  for (my $i=0; $i < $ModelTable->size(); $i++) {
1194                          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/) {
1195                                  $ModelTable->delete_row($i);                                  $ModelTable->delete_row($i);
1196                                  $i--;                                  $i--;
1197                          }                          }
# Line 1119  Line 1215 
1215                          }                          }
1216                  }                  }
1217                  $MediaTable->save($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");                  $MediaTable->save($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");
1218                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$UniqueFilename."TestMedia",["GapFilling"],{"Default max drain flux" => 0},"GapFill".$self->id().".log",undef));                  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));
1219                  unlink($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");                  unlink($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");
1220          } else {          } else {
1221                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),undef,["GapFilling"],undef,"GapFill".$self->id().".log",undef));                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),undef,["GapFilling"],{"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0]},"GapFill".$self->id().".log",undef));
1222          }          }
1223    
1224          #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
1225          my $SolutionData = $self->figmodel()->LoadProblemReport($UniqueFilename);          my $SolutionData = $self->figmodel()->LoadProblemReport($UniqueFilename);
1226    
1227          #Clearing the mfatoolkit output and log file          #Clearing the mfatoolkit output and log file
1228          $self->figmodel()->clearing_output($UniqueFilename,"GapFill".$self->id().".log");          $self->figmodel()->clearing_output($UniqueFilename,"GapFill".$self->id().".log");
1229          if (!defined($SolutionData) || $SolutionData->size() == 0) {          if (!defined($SolutionData) || $SolutionData->size() == 0) {
# Line 1140  Line 1237 
1237          for (my $i=($SolutionData->size()-1); $i >=0; $i--) {          for (my $i=($SolutionData->size()-1); $i >=0; $i--) {
1238                  if (defined($SolutionData->get_row($i)->{"Notes"}) && $SolutionData->get_row($i)->{"Notes"}->[0] =~ m/^Recursive/) {                  if (defined($SolutionData->get_row($i)->{"Notes"}) && $SolutionData->get_row($i)->{"Notes"}->[0] =~ m/^Recursive/) {
1239                          my $AllSolutions = substr($SolutionData->get_row($i)->{"Notes"}->[0],15);                          my $AllSolutions = substr($SolutionData->get_row($i)->{"Notes"}->[0],15);
                         print "Solution:".$AllSolutions."\n";  
1240                          my @TempThree = split(/\|/,$AllSolutions);                          my @TempThree = split(/\|/,$AllSolutions);
1241                          if (@TempThree > 0 && $TempThree[0] =~ m/.+:(.+)/) {                          if (@TempThree > 0 && $TempThree[0] =~ m/.+:(.+)/) {
1242                                  my @TempFour = split(/,/,$1);                                  my @TempFour = split(/,/,$1);
# Line 1163  Line 1259 
1259                                                  push(@{$ReactionList},$ID);                                                  push(@{$ReactionList},$ID);
1260                                          }                                          }
1261                                  }                                  }
1262                                  print "Solution:".$TempThree[0]."\n";                                  $self->figmodel()->IntegrateGrowMatchSolution($self->id(),undef,$ReactionList,$DirectionList,"AUTOCOMPLETION",0,1);
                                 $self->figmodel()->IntegrateGrowMatchSolution($self->id(),undef,$ReactionList,$DirectionList,"GAP FILLING",0,1);  
1263                          }                          }
1264                          last;                          last;
1265                  }                  }
1266          }          }
1267    
1268          #Updating model stats with gap filling results          #Updating model stats with gap filling results
1269          my $ElapsedTime = time() - $StartTime;          my $ElapsedTime = time() - $StartTime;
1270          $self->figmodel()->ClearDBModel($self->id(),1);          $self->reaction_table(1);
1271            $self->calculate_model_changes($OriginalRxn,"AUTOCOMPLETION");
1272    
1273          #Determining why each gap filling reaction was added          #Determining why each gap filling reaction was added
1274          $self->figmodel()->IdentifyDependancyOfGapFillingReactions($self->id(),$Media);          $self->figmodel()->IdentifyDependancyOfGapFillingReactions($self->id(),$Media);
1275          if (!defined($donotclear) || $donotclear != 1) {          if (!defined($donotclear) || $donotclear != 1) {
# Line 1191  Line 1289 
1289          return $self->success();          return $self->success();
1290  }  }
1291    
1292    =head3 calculate_model_changes
1293    Definition:
1294            FIGMODELmodel->calculate_model_changes(FIGMODELTable:original reaction table,string:modification cause);
1295    Description:
1296    
1297    =cut
1298    
1299    sub calculate_model_changes {
1300            my ($self,$originalReactions,$cause) = @_;
1301            my $modTime = time();
1302            my $version = $self->selected_version();
1303            my $user = $self->figmodel()->user();
1304            #Getting the history table
1305            my $histTbl = $self->model_history();
1306            #Checking for differences
1307            my $tbl = $self->reaction_table();
1308            for (my $i=0; $i < $tbl->size(); $i++) {
1309                    my $row = $tbl->get_row($i);
1310                    my $orgRow = $originalReactions->get_row_by_key($row->{LOAD}->[0],"LOAD");
1311                    if (!defined($orgRow)) {
1312                            $histTbl->add_row({Reaction => [$row->{LOAD}->[0]], DirectionChange => $row->{DIRECTIONALITY}, GeneChange => $row->{"ASSOCIATED PEG"}, Action => ["ADDED"], ModificationTime => [$modTime], ModifcationCause => [$cause], User => [$user], Version => [$version]});
1313                    } else {
1314                            my $geneChanges;
1315                            my $directionChange;
1316                            if ($orgRow->{"DIRECTIONALITY"}->[0] ne $row->{"DIRECTIONALITY"}->[0]) {
1317                                    $directionChange = $orgRow->{"DIRECTIONALITY"}->[0]." to ".$row->{"DIRECTIONALITY"}->[0];
1318                            }
1319                            for (my $j=0; $j < @{$row->{"ASSOCIATED PEG"}}; $j++) {
1320                                    my $match = 0;
1321                                    for (my $k=0; $k < @{$orgRow->{"ASSOCIATED PEG"}}; $k++) {
1322                                            if ($row->{"ASSOCIATED PEG"}->[$j] eq $orgRow->{"ASSOCIATED PEG"}->[$k]) {
1323                                                    $match = 1;
1324                                            }
1325                                    }
1326                                    if ($match == 0) {
1327                                            push(@{$geneChanges},"Added ".$row->{"ASSOCIATED PEG"}->[$j]);
1328                                    }
1329                            }
1330                            for (my $k=0; $k < @{$orgRow->{"ASSOCIATED PEG"}}; $k++) {
1331                                    my $match = 0;
1332                                    for (my $j=0; $j < @{$row->{"ASSOCIATED PEG"}}; $j++) {
1333                                            if ($row->{"ASSOCIATED PEG"}->[$j] eq $orgRow->{"ASSOCIATED PEG"}->[$k]) {
1334                                                    $match = 1;
1335                                            }
1336                                    }
1337                                    if ($match == 0) {
1338                                            push(@{$geneChanges},"Removed ".$orgRow->{"ASSOCIATED PEG"}->[$k]);
1339                                    }
1340                            }
1341                            if ((defined($directionChange) && length($directionChange) > 0) || defined($geneChanges) && @{$geneChanges} > 0) {
1342                                    $histTbl->add_row({Reaction => [$row->{LOAD}->[0]], DirectionChange => [$directionChange], GeneChange => $geneChanges, Action => ["CHANGE"], ModificationTime => [$modTime], ModifcationCause => [$cause], User => [$user], Version => [$version]});
1343                            }
1344                    }
1345            }
1346            #Looking for removed reactions
1347            for (my $i=0; $i < $originalReactions->size(); $i++) {
1348                    my $row = $originalReactions->get_row($i);
1349                    my $orgRow = $tbl->get_row_by_key($row->{LOAD}->[0],"LOAD");
1350                    if (!defined($orgRow)) {
1351                            $histTbl->add_row({Reaction => [$row->{LOAD}->[0]], DirectionChange => $row->{DIRECTIONALITY}, GeneChange => $row->{"ASSOCIATED PEG"}, Action => ["REMOVED"], ModificationTime => [$modTime], ModifcationCause => [$cause], User => [$user], Version => [$version]});
1352                    }
1353            }
1354            $histTbl->save();
1355    }
1356    
1357    =head3 GapGenModel
1358    Definition:
1359            FIGMODELmodel->GapGenModel();
1360    Description:
1361            Runs the gap generation algorithm to correct a single false positive prediction. Results are loaded into a table.
1362    =cut
1363    
1364    sub GapGenModel {
1365            my ($self,$Media,$KOList,$NoKOList,$Experiment,$SolutionLimit) = @_;
1366    
1367            #Enforcing nonoptional arguments
1368            if (!defined($Media)) {
1369                    return undef;
1370            }
1371            if (!defined($KOList)) {
1372                    $KOList->[0] = "none";
1373            }
1374            if (!defined($NoKOList)) {
1375                    $NoKOList->[0] = "none";
1376            }
1377            if (!defined($Experiment)) {
1378                    $Experiment= "ReactionKO";
1379            }
1380            if (!defined($SolutionLimit)) {
1381                    $SolutionLimit = "10";
1382            }
1383    
1384            #Translating the KO lists into arrays
1385            if (ref($KOList) ne "ARRAY") {
1386                    my $temp = $KOList;
1387                    $KOList = ();
1388                    push(@{$KOList},split(/[,;]/,$temp));
1389            }
1390            my $noKOHash;
1391            if (defined($NoKOList) && ref($NoKOList) ne "ARRAY") {
1392                    my $temp = $NoKOList;
1393                    $NoKOList = ();
1394                    push(@{$NoKOList},split(/[,;]/,$temp));
1395                    foreach my $rxn (@{$NoKOList}) {
1396                            $noKOHash->{$rxn} = 1;
1397                    }
1398            }
1399    
1400            #Checking if solutions exist for the input parameters
1401            $self->aquireModelLock();
1402            my $tbl = $self->load_model_table("GapGenSolutions");
1403            my $solutionRow = $tbl->get_table_by_key($Experiment,"Experiment")->get_table_by_key($Media,"Media")->get_row_by_key(join(",",@{$KOList}),"KOlist");
1404            my $solutions;
1405            if (defined($solutionRow)) {
1406                    #Checking if any solutions conform to the no KO list
1407                    foreach my $solution (@{$solutionRow->{Solutions}}) {
1408                            my @reactions = split(/,/,$solution);
1409                            my $include = 1;
1410                            foreach my $rxn (@reactions) {
1411                                    if ($rxn =~ m/(rxn\d\d\d\d\d)/) {
1412                                            if (defined($noKOHash->{$1})) {
1413                                                    $include = 0;
1414                                            }
1415                                    }
1416                            }
1417                            if ($include == 1) {
1418                                    push(@{$solutions},$solution);
1419                            }
1420                    }
1421            } else {
1422                    $solutionRow = {Media => [$Media],Experiment => [$Experiment],KOlist => [join(",",@{$KOList})]};
1423                    $tbl->add_row($solutionRow);
1424                    $self->figmodel()->database()->save_table($tbl);
1425            }
1426            $self->releaseModelLock();
1427    
1428            #Returning solution list of solutions were found
1429            if (defined($solutions) && @{$solutions} > 0) {
1430                    return $solutions;
1431            }
1432    
1433            #Getting unique filename
1434            my $Filename = $self->figmodel()->filename();
1435    
1436            #Running the gap generation
1437            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));
1438            my $ProblemReport = $self->figmodel()->LoadProblemReport($Filename);
1439            if (!defined($ProblemReport)) {
1440                    $self->figmodel()->error_message("FIGMODEL:GapGenerationAlgorithm;No problem report;".$Filename.";".$self->id().$self->selected_version().";".$Media.";".$KOList.";".$NoKOList);
1441                    return undef;
1442            }
1443    
1444            #Clearing the output folder and log file
1445            $self->figmodel()->clearing_output($Filename,"Gapgeneration-".$self->id().$self->selected_version()."-".$Filename.".log");
1446    
1447            #Saving the solution
1448            $self->aquireModelLock();
1449            $tbl = $self->load_model_table("GapGenSolutions");
1450            $solutionRow = $tbl->get_table_by_key($Experiment,"Experiment")->get_table_by_key($Media,"Media")->get_row_by_key(join(",",@{$KOList}),"KOlist");
1451            for (my $j=0; $j < $ProblemReport->size(); $j++) {
1452                    if ($ProblemReport->get_row($j)->{"Notes"}->[0] =~ m/^Recursive\sMILP\s([^)]+)/) {
1453                            my @SolutionList = split(/\|/,$1);
1454                            for (my $k=0; $k < @SolutionList; $k++) {
1455                                    if ($SolutionList[$k] =~ m/(\d+):(.+)/) {
1456                                            push(@{$solutionRow->{Solutions}},$2);
1457                                            push(@{$solutions},$2);
1458                                    }
1459                            }
1460                    }
1461            }
1462            $self->figmodel()->database()->save_table($tbl);
1463            $self->releaseModelLock();
1464    
1465            return $solutions;
1466    }
1467    
1468  =head3 datagapfill  =head3 datagapfill
1469  Definition:  Definition:
1470          success()/fail() = FIGMODELmodel->datagapfill();          success()/fail() = FIGMODELmodel->datagapfill();
# Line 1201  Line 1475 
1475          my ($self,$GapFillingRunSpecs,$TansferFileSuffix) = @_;          my ($self,$GapFillingRunSpecs,$TansferFileSuffix) = @_;
1476          my $UniqueFilename = $self->figmodel()->filename();          my $UniqueFilename = $self->figmodel()->filename();
1477          if (defined($GapFillingRunSpecs) && @{$GapFillingRunSpecs} > 0) {          if (defined($GapFillingRunSpecs) && @{$GapFillingRunSpecs} > 0) {
                 print "Gap filling specs:\n".join("\n",@{$GapFillingRunSpecs})."\n\n";  
1478                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id().$self->selected_version(),"NoBounds",["DataGapFilling"],{"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0],"Gap filling runs" => join(";",@{$GapFillingRunSpecs})},"GapFilling-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,undef));                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id().$self->selected_version(),"NoBounds",["DataGapFilling"],{"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0],"Gap filling runs" => join(";",@{$GapFillingRunSpecs})},"GapFilling-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,undef));
   
1479                  #Checking that the solution exists                  #Checking that the solution exists
1480                  if (!-e $self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingSolutionTable.txt") {                  if (!-e $self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingSolutionTable.txt") {
1481                          $self->figmodel()->error_message("FIGMODEL:GapFillingAlgorithm: Could not find MFA output file!");                          $self->figmodel()->error_message("FIGMODEL:GapFillingAlgorithm: Could not find MFA output file!");
# Line 1213  Line 1485 
1485                  my $GapFillResultTable = $self->figmodel()->database()->load_table($self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingSolutionTable.txt",";","",0,undef);                  my $GapFillResultTable = $self->figmodel()->database()->load_table($self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingSolutionTable.txt",";","",0,undef);
1486                  if (defined($TansferFileSuffix)) {                  if (defined($TansferFileSuffix)) {
1487                          system("cp ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingSolutionTable.txt ".$self->directory().$self->id().$self->selected_version()."-".$TansferFileSuffix.".txt");                          system("cp ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingSolutionTable.txt ".$self->directory().$self->id().$self->selected_version()."-".$TansferFileSuffix.".txt");
                         system("cp ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingReport.txt ".$self->directory().$self->id().$self->selected_version()."-".$TansferFileSuffix.".txt");  
1488                  }                  }
   
1489                  #If the system is not configured to preserve all logfiles, then the mfatoolkit output folder is deleted                  #If the system is not configured to preserve all logfiles, then the mfatoolkit output folder is deleted
1490                  $self->figmodel()->clearing_output($UniqueFilename,"GapFilling-".$self->id().$self->selected_version()."-".$UniqueFilename.".log");                  $self->figmodel()->clearing_output($UniqueFilename,"GapFilling-".$self->id().$self->selected_version()."-".$UniqueFilename.".log");
1491                  return $GapFillingRunSpecs;                  return $GapFillResultTable;
1492          }          }
1493          if (defined($TansferFileSuffix)) {          if (defined($TansferFileSuffix)) {
1494                  $self->figmodel()->database()->print_array_to_file($self->directory().$self->id().$self->selected_version()."-".$TansferFileSuffix.".txt",["Experiment;Solution index;Solution cost;Solution reactions"]);                  $self->figmodel()->database()->print_array_to_file($self->directory().$self->id().$self->selected_version()."-".$TansferFileSuffix.".txt",["Experiment;Solution index;Solution cost;Solution reactions"]);
# Line 1284  Line 1554 
1554                          push(@{$DirectionArray},$SolutionHash{$ReactionList[$k]});                          push(@{$DirectionArray},$SolutionHash{$ReactionList[$k]});
1555                  }                  }
1556                  print "Integrating solution!\n";                  print "Integrating solution!\n";
1557                  $self->IntegrateGrowMatchSolution($self->id().$self->selected_version(),$self->directory().$self->id().$TempVersion.".txt",$ReactionArray,$DirectionArray,"Gapfilling ".$GapFillResultTable->get_row($i)->{"Experiment"}->[0],1,1);                  $self->figmodel()->IntegrateGrowMatchSolution($self->id().$self->selected_version(),$self->directory().$self->id().$TempVersion.".txt",$ReactionArray,$DirectionArray,"Gapfilling ".$GapFillResultTable->get_row($i)->{"Experiment"}->[0],1,1);
1558                  my $model = $self->get_model($self->id().$TempVersion);                  $self->PrintModelLPFile();
                 $model->PrintModelLPFile();  
1559                  #Running the model against all available experimental data                  #Running the model against all available experimental data
1560                  print "Running test model!\n";                  print "Running test model!\n";
1561                  my ($FalsePostives,$FalseNegatives,$CorrectNegatives,$CorrectPositives,$Errorvector,$HeadingVector) = $self->RunAllStudiesWithDataFast("All");                  my ($FalsePostives,$FalseNegatives,$CorrectNegatives,$CorrectPositives,$Errorvector,$HeadingVector) = $self->RunAllStudiesWithDataFast("All");
# Line 1322  Line 1591 
1591  =cut  =cut
1592  sub status {  sub status {
1593          my ($self) = @_;          my ($self) = @_;
1594          return $self->{_data}->{status}->[0];          return $self->{_data}->status();
1595  }  }
1596    
1597  =head3 message  =head3 message
# Line 1333  Line 1602 
1602  =cut  =cut
1603  sub message {  sub message {
1604          my ($self) = @_;          my ($self) = @_;
1605          return $self->{_data}->{message}->[0];          return $self->{_data}->message();
1606  }  }
1607    
1608  =head3 set_status  =head3 set_status
# Line 1348  Line 1617 
1617  =cut  =cut
1618  sub set_status {  sub set_status {
1619          my ($self,$NewStatus,$Message) = @_;          my ($self,$NewStatus,$Message) = @_;
1620            $self->{_data}->status($NewStatus);
1621          #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");  
1622          return $self->config("SUCCESS")->[0];          return $self->config("SUCCESS")->[0];
1623  }  }
1624    
# Line 1367  Line 1633 
1633  sub CreateSingleGenomeReactionList {  sub CreateSingleGenomeReactionList {
1634          my ($self,$RunGapFilling) = @_;          my ($self,$RunGapFilling) = @_;
1635    
1636            #Creating directory
1637            if ($self->owner() ne "master" && !-d $self->figmodel()->config("organism directory")->[0].$self->owner()."/") {
1638                    system("mkdir ".$self->figmodel()->config("organism directory")->[0].$self->owner()."/");
1639            } elsif ($self->owner() eq "master" && !-d $self->figmodel()->config("organism directory")->[0].$self->genome()."/") {
1640                    system("mkdir ".$self->figmodel()->config("organism directory")->[0].$self->genome()."/");
1641            }
1642            if ($self->owner() ne "master" && !-d $self->figmodel()->config("organism directory")->[0].$self->owner()."/".$self->genome()."/") {
1643                    system("mkdir ".$self->figmodel()->config("organism directory")->[0].$self->owner()."/".$self->genome()."/");
1644            }
1645    
1646          #Getting genome stats          #Getting genome stats
1647          my $genomestats = $self->figmodel()->get_genome_stats($self->genome());          my $genomestats = $self->figmodel()->get_genome_stats($self->genome());
1648          my $FeatureTable = $self->figmodel()->GetGenomeFeatureTable($self->genome());          my $FeatureTable = $self->figmodel()->GetGenomeFeatureTable($self->genome());
# Line 1381  Line 1657 
1657          }          }
1658          #Setting up needed variables          #Setting up needed variables
1659          my $OriginalModelTable = undef;          my $OriginalModelTable = undef;
1660          #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) {  
1661                  $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");  
1662                  return $self->fail();                  return $self->fail();
1663          }elsif ($Row->{status}->[0] == 1) {          }elsif ($self->status() == 1) {
1664                  $OriginalModelTable = $self->reaction_table();                  $OriginalModelTable = $self->reaction_table();
1665                  $self->ArchiveModel();                  $self->set_status(0,"Rebuilding preliminary reconstruction");
                 $Row->{status}->[0] = 0;  
                 $Row->{message}->[0] = "Rebuilding preliminary reconstruction";  
1666          } else {          } else {
1667                  $Row->{status}->[0] = 0;                  $self->set_status(0,"Preliminary reconstruction");
                 $Row->{message}->[0] = "Preliminary reconstruction";  
1668          }          }
         #Updating the status table  
         $self->figmodel()->database()->save_table($ModelTable);  
         $self->figmodel()->database()->UnlockDBTable("MODELS");  
1669          #Sorting GenomeData by gene location on the chromosome          #Sorting GenomeData by gene location on the chromosome
1670          $FeatureTable->sort_rows("MIN LOCATION");          $FeatureTable->sort_rows("MIN LOCATION");
1671          my ($ComplexHash,$SuggestedMappings,$UnrecognizedReactions,$ReactionHash);          my ($ComplexHash,$SuggestedMappings,$UnrecognizedReactions,$ReactionHash);
# Line 1601  Line 1863 
1863          }          }
1864    
1865          #Checking if a biomass reaction already exists          #Checking if a biomass reaction already exists
1866          my $BiomassReactionRow = $self->figmodel()->database()->get_row_by_key("BIOMASS TABLE",$self->id(),"MODELS");          my $BiomassReactionRow = $self->BuildSpecificBiomassReaction();
         if (!defined($BiomassReactionRow)) {  
                 $BiomassReactionRow = $self->BuildSpecificBiomassReaction();  
1867                  if (!defined($BiomassReactionRow)) {                  if (!defined($BiomassReactionRow)) {
1868                          $self->set_status(-2,"Preliminary reconstruction failed: could not generate biomass reaction");                          $self->set_status(-2,"Preliminary reconstruction failed: could not generate biomass reaction");
1869                          $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()."!");
1870                          return $self->fail();                          return $self->fail();
1871                  }                  }
         }  
1872          my $ReactionList = $BiomassReactionRow->{"ESSENTIAL REACTIONS"};          my $ReactionList = $BiomassReactionRow->{"ESSENTIAL REACTIONS"};
1873          push(@{$ReactionList},$BiomassReactionRow->{DATABASE}->[0]);          push(@{$ReactionList},$BiomassReactionRow->{DATABASE}->[0]);
1874    
# Line 1700  Line 1959 
1959          #Saving the new model to file          #Saving the new model to file
1960          $self->set_status(1,"Preliminary reconstruction complete");          $self->set_status(1,"Preliminary reconstruction complete");
1961          $self->figmodel()->database()->save_table($NewModelTable);          $self->figmodel()->database()->save_table($NewModelTable);
1962          $self->{_reaction_data} = $NewModelTable;          $self->reaction_table(1);
         #Clearing the previous model from the cache  
         $self->figmodel()->ClearDBModel($self->id(),1);  
1963          #Updating the model stats table          #Updating the model stats table
1964          $self->update_stats_for_build();          $self->update_stats_for_build();
1965          $self->PrintSBMLFile();          $self->PrintSBMLFile();
1966            if (defined($OriginalModelTable)) {
1967                    $self->calculate_model_changes($OriginalModelTable,"REBUILD");
1968            }
1969    
1970          #Adding model to gapfilling queue          #Adding model to gapfilling queue
1971          if (defined($RunGapFilling) && $RunGapFilling == 1) {          if (defined($RunGapFilling) && $RunGapFilling == 1) {
# Line 1823  Line 2083 
2083          }          }
2084    
2085          #Clearing the previous model from the cache          #Clearing the previous model from the cache
2086          $self->figmodel()->ClearDBModel($self->id(),1);          $self->figmodel()->database()->ClearDBModel($self->id(),1);
2087          $ModelTable->save();          $ModelTable->save();
2088    
2089          return $self->success();          return $self->success();
# Line 1839  Line 2099 
2099  sub ArchiveModel {  sub ArchiveModel {
2100          my ($self) = @_;          my ($self) = @_;
2101    
         #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();  
         }  
   
2102          #Checking that the model file exists          #Checking that the model file exists
2103          if (!(-e $self->filename())) {          if (!(-e $self->filename())) {
2104                  $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 1895  Line 2149 
2149          Runs microarray analysis attempting to turn off genes that are inactive in the microarray          Runs microarray analysis attempting to turn off genes that are inactive in the microarray
2150  =cut  =cut
2151  sub run_microarray_analysis {  sub run_microarray_analysis {
2152          my ($self,$media,$jobid,$index,$genecall) = @_;          my ($self,$media,$label,$index,$genecall) = @_;
2153          $genecall =~ s/_/:/g;          $genecall =~ s/_/:/g;
2154          $genecall =~ s/\//;/g;          $genecall =~ s/\//;/g;
2155          #print "\n\n".$genecall."\n\n";          my $uniqueFilename = $self->figmodel()->filename();
2156          my $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($jobid,$self->id(),$media,["MFA","MicroarrayAssertions"],{"Microarray assertions" => $self->id().";".$index.";".$genecall,"MFASolver" => "CPLEX","Network output location" => "/scratch/"},"MicroarrayAnalysis-".$jobid.".txt",undef,$self->selected_version());          my $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($uniqueFilename,$self->id(),$media,["ProductionMFA","ShewenellaExperiment"],{"Microarray assertions" => $label.";".$index.";".$genecall,"MFASolver" => "CPLEX","Network output location" => "/scratch/"},"MicroarrayAnalysis-".$uniqueFilename.".txt",undef,$self->selected_version());
         #print $command."\n";  
2157          system($command);          system($command);
2158          #system("/home/chenry/Software/MFAToolkitRepository/Linux/mfatoolkit resetparameter \"user bounds filename\" \"Carbon-D-Glucose.txt\" resetparameter output_folder \"32749.354149.0/\" resetparameter \"Microarray assertions\" \"Seed83333.1;0;peg.3130:-1;peg.4035:-1\" resetparameter \"MFASolver\" \"CPLEX\" resetparameter \"Network output location\" \"/scratch/\" LoadCentralSystem \"/vol/model-dev/MODEL_DEV_DB/Models/83333.1/Seed83333.1.txt\" > \"/vol/model-dev/MODEL_DEV_DB/ReactionDB/log/MicroarrayAnalysis-32749.354149.0.txt\"");          my $filename = $self->figmodel()->config("MFAToolkit output directory")->[0].$uniqueFilename."/MicroarrayOutput-".$index.".txt";
2159        if (-e $filename) {
2160            my $output = $self->figmodel()->database()->load_single_column_file($filename);
2161            if (defined($output->[0])) {
2162                    my @array = split(/;/,$output->[0]);
2163                    $self->figmodel()->clearing_output($uniqueFilename,"MicroarrayAnalysis-".$uniqueFilename.".txt");
2164                    return ($array[0],$array[1],$array[8].":".$array[2],$array[9].":".$array[3],$array[10].":".$array[4],$array[11].":".$array[5],$array[12].":".$array[6],$array[13].":".$array[7]);
2165            }
2166            print STDERR $filename." is empty!";
2167        }
2168        print STDERR $filename." not found!";
2169        $self->figmodel()->clearing_output($uniqueFilename,"MicroarrayAnalysis-".$uniqueFilename.".txt");
2170    
2171            return undef;
2172  }  }
2173    
2174  =head3 find_minimal_pathways  =head3 find_minimal_pathways
# Line 1912  Line 2178 
2178          Runs microarray analysis attempting to turn off genes that are inactive in the microarray          Runs microarray analysis attempting to turn off genes that are inactive in the microarray
2179  =cut  =cut
2180  sub find_minimal_pathways {  sub find_minimal_pathways {
2181          my ($self,$media,$objective,$solutionnum) = @_;          my ($self,$media,$objective,$solutionnum,$AllReversible,$additionalexchange) = @_;
2182    
2183            #Setting default media
2184            if (!defined($media)) {
2185                    $media = "Complete";
2186            }
2187    
2188            #Setting default solution number
2189            if (!defined($solutionnum)) {
2190                    $solutionnum = "5";
2191            }
2192    
2193            #Setting additional exchange fluxes
2194            if (!defined($additionalexchange) || length($additionalexchange) == 0) {
2195                    if ($self->id() eq "iAF1260") {
2196                            $additionalexchange = "cpd03422[c]:-100:100;cpd01997[c]:-100:100;cpd11416[c]:-100:0;cpd15378[c]:-100:0;cpd15486[c]:-100:0";
2197                    } else {
2198                            $additionalexchange = $self->figmodel()->config("default exchange fluxes")->[0];
2199                    }
2200            }
2201    
2202            #Translating objective
2203            my $objectivestring;
2204            if ($objective eq "ALL") {
2205                    #Getting the list of universal building blocks
2206                    my $buildingblocks = $self->config("universal building blocks");
2207                    my @objectives = keys(%{$buildingblocks});
2208                    #Getting the nonuniversal building blocks
2209                    my $otherbuildingblocks = $self->config("nonuniversal building blocks");
2210                    my @array = keys(%{$otherbuildingblocks});
2211                    if (defined($self->get_biomass()) && defined($self->figmodel()->get_reaction($self->get_biomass()->{"LOAD"}->[0]))) {
2212                            my $equation = $self->figmodel()->get_reaction($self->get_biomass()->{"LOAD"}->[0])->{"EQUATION"}->[0];
2213                            if (defined($equation)) {
2214                                    for (my $i=0; $i < @array; $i++) {
2215                                            if (CORE::index($equation,$array[$i]) > 0) {
2216                                                    push(@objectives,$array[$i]);
2217                                            }
2218                                    }
2219                            }
2220                    }
2221                    for (my $i=0; $i < @objectives; $i++) {
2222                            $self->find_minimal_pathways($media,$objectives[$i]);
2223                    }
2224                    return;
2225            } elsif ($objective eq "ENERGY") {
2226                    $objectivestring = "MAX;FLUX;rxn00062;c;1";
2227            } elsif ($objective =~ m/cpd\d\d\d\d\d/) {
2228                    if ($objective =~ m/\[(\w)\]/) {
2229                            $objectivestring = "MIN;DRAIN_FLUX;".$objective.";".$1.";1";
2230                            $additionalexchange .= ";".$objective."[".$1."]:-100:0";
2231                    } else {
2232                            $objectivestring = "MIN;DRAIN_FLUX;".$objective.";c;1";
2233                            $additionalexchange .= ";".$objective."[c]:-100:0";
2234                    }
2235            } elsif ($objective =~ m/(rxn\d\d\d\d\d)/) {
2236                    my ($Reactants,$Products) = $self->figmodel()->GetReactionSubstrateData($objective);
2237                    for (my $i=0; $i < @{$Products};$i++) {
2238                            my $temp = $Products->[$i]->{"DATABASE"}->[0];
2239                            if ($additionalexchange !~ m/$temp/) {
2240                                    #$additionalexchange .= ";".$temp."[c]:-100:0";
2241                            }
2242                    }
2243                    for (my $i=0; $i < @{$Reactants};$i++) {
2244                            print $Reactants->[$i]->{"DATABASE"}->[0]." started\n";
2245                            $self->find_minimal_pathways($media,$Reactants->[$i]->{"DATABASE"}->[0],$additionalexchange);
2246                            print $Reactants->[$i]->{"DATABASE"}->[0]." done\n";
2247                    }
2248                    return;
2249            }
2250    
2251            #Adding additional drains
2252            if (($objective eq "cpd15665" || $objective eq "cpd15667" || $objective eq "cpd15668" || $objective eq "cpd15669") && $additionalexchange !~ m/cpd15666/) {
2253                    $additionalexchange .= ";cpd15666[c]:0:100";
2254            } elsif ($objective eq "cpd11493" && $additionalexchange !~ m/cpd12370/) {
2255                    $additionalexchange .= ";cpd12370[c]:0:100";
2256            } elsif ($objective eq "cpd00166" && $additionalexchange !~ m/cpd01997/) {
2257                    $additionalexchange .= ";cpd01997[c]:0:100;cpd03422[c]:0:100";
2258            }
2259    
2260            #Running MFAToolkit
2261            my $filename = $self->figmodel()->filename();
2262            my $command;
2263            if (defined($AllReversible) && $AllReversible == 1) {
2264                    $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($filename,$self->id(),$media,["ProductionMFA"],{"Make all reactions reversible in MFA"=>1, "Recursive MILP solution limit" => $solutionnum,"Generate pathways to objective" => 1,"MFASolver" => "CPLEX","objective" => $objectivestring,"exchange species" => $additionalexchange},"MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",undef,$self->selected_version());
2265            } else {
2266                    $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($filename,$self->id(),$media,["ProductionMFA"],{"Make all reactions reversible in MFA"=>0, "Recursive MILP solution limit" => $solutionnum,"Generate pathways to objective" => 1,"MFASolver" => "CPLEX","objective" => $objectivestring,"exchange species" => $additionalexchange},"MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",undef,$self->selected_version());
2267            }
2268            system($command);
2269    
2270            #Loading problem report
2271            my $results = $self->figmodel()->LoadProblemReport($filename);
2272            #Clearing output
2273            $self->figmodel()->clearing_output($filename,"MinimalPathways-".$media."-".$self->id()."-".$objective.".txt");
2274            if (!defined($results)) {
2275                    print STDERR $objective." pathway results not found!\n";
2276                    return;
2277            }
2278    
2279            #Parsing output
2280            my @Array;
2281            my $row = $results->get_row(1);
2282            if (defined($row->{"Notes"}->[0])) {
2283                    $_ = $row->{"Notes"}->[0];
2284                    @Array = /\d+:([^\|]+)\|/g;
2285            }
2286    
2287            #Writing output to file
2288            $self->figmodel()->database()->print_array_to_file($self->directory()."MinimalPathways-".$media."-".$objective."-".$self->id()."-".$AllReversible."-".$self->selected_version().".txt",[join("|",@Array)]);
2289    }
2290    
2291    =head3 find_minimal_pathways
2292    Definition:
2293            int::status = FIGMODEL->find_minimal_pathways(string::media,string::objective);
2294    Description:
2295            Runs microarray analysis attempting to turn off genes that are inactive in the microarray
2296    =cut
2297    sub find_minimal_pathways_two {
2298            my ($self,$media,$objective,$solutionnum,$AllReversible,$additionalexchange) = @_;
2299    
2300          #Setting default media          #Setting default media
2301          if (!defined($media)) {          if (!defined($media)) {
# Line 1924  Line 2307 
2307                  $solutionnum = "5";                  $solutionnum = "5";
2308          }          }
2309    
2310            #Setting additional exchange fluxes
2311            if (!defined($additionalexchange) || length($additionalexchange) == 0) {
2312                    if ($self->id() eq "iAF1260") {
2313                            $additionalexchange = "cpd03422[c]:-100:100;cpd01997[c]:-100:100;cpd11416[c]:-100:0;cpd15378[c]:-100:0;cpd15486[c]:-100:0";
2314                    } else {
2315                            $additionalexchange = $self->figmodel()->config("default exchange fluxes")->[0];
2316                    }
2317            }
2318    
2319          #Translating objective          #Translating objective
2320          my $objectivestring;          my $objectivestring;
2321          if ($objective eq "ALL") {          if ($objective eq "ALL") {
# Line 1944  Line 2336 
2336                          }                          }
2337                  }                  }
2338                  for (my $i=0; $i < @objectives; $i++) {                  for (my $i=0; $i < @objectives; $i++) {
2339                          $self->find_minimal_pathways($media,$objectives[$i])                          $self->find_minimal_pathways($media,$objectives[$i]);
2340                  }                  }
2341                    return;
2342          } elsif ($objective eq "ENERGY") {          } elsif ($objective eq "ENERGY") {
2343                  $objectivestring = "MAX;FLUX;rxn00062;c;1";                  $objectivestring = "MAX;FLUX;rxn00062;c;1";
2344          } elsif ($objective =~ m/cpd\d\d\d\d\d/) {          } elsif ($objective =~ m/cpd\d\d\d\d\d/) {
2345                    if ($objective =~ m/\[(\w)\]/) {
2346                            $objectivestring = "MIN;DRAIN_FLUX;".$objective.";".$1.";1";
2347                            $additionalexchange .= ";".$objective."[".$1."]:-100:0";
2348                    } else {
2349                  $objectivestring = "MIN;DRAIN_FLUX;".$objective.";c;1";                  $objectivestring = "MIN;DRAIN_FLUX;".$objective.";c;1";
2350                            $additionalexchange .= ";".$objective."[c]:-100:0";
2351                    }
2352            } elsif ($objective =~ m/(rxn\d\d\d\d\d)/) {
2353                    my ($Reactants,$Products) = $self->figmodel()->GetReactionSubstrateData($objective);
2354                    for (my $i=0; $i < @{$Products};$i++) {
2355                            my $temp = $Products->[$i]->{"DATABASE"}->[0];
2356                            if ($additionalexchange !~ m/$temp/) {
2357                                    #$additionalexchange .= ";".$temp."[c]:-100:0";
2358                            }
2359                    }
2360                    for (my $i=0; $i < @{$Reactants};$i++) {
2361                            print $Reactants->[$i]->{"DATABASE"}->[0]." started\n";
2362                            $self->find_minimal_pathways($media,$Reactants->[$i]->{"DATABASE"}->[0],$additionalexchange);
2363                            print $Reactants->[$i]->{"DATABASE"}->[0]." done\n";
2364                    }
2365                    return;
2366          }          }
2367    
2368          #Setting additional exchange fluxes          #Adding additional drains
2369          my $additionalexchange = $self->config("default exchange fluxes")->[0];          if (($objective eq "cpd15665" || $objective eq "cpd15667" || $objective eq "cpd15668" || $objective eq "cpd15669") && $additionalexchange !~ m/cpd15666/) {
         if ($objective eq "cpd15665" || $objective eq "cpd15667" || $objective eq "cpd15668" || $objective eq "cpd15669") {  
2370                  $additionalexchange .= ";cpd15666[c]:0:100";                  $additionalexchange .= ";cpd15666[c]:0:100";
2371          } elsif ($objective eq "cpd11493") {          } elsif ($objective eq "cpd11493" && $additionalexchange !~ m/cpd12370/) {
2372                  $additionalexchange .= ";cpd12370[c]:0:100";                  $additionalexchange .= ";cpd12370[c]:0:100";
2373          } elsif ($objective eq "cpd00166") {          } elsif ($objective eq "cpd00166" && $additionalexchange !~ m/cpd01997/) {
2374                  $additionalexchange .= ";cpd01997[c]:0:100;cpd03422[c]:0:100";                  $additionalexchange .= ";cpd01997[c]:0:100;cpd03422[c]:0:100";
2375          }          }
2376    
2377          #Running MFAToolkit          #Running MFAToolkit
2378          my $filename = $self->figmodel()->filename();          my $filename = $self->figmodel()->filename();
2379          my $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($filename,$self->id(),$media,["MFA"],{"Recursive MILP solution limit" => $solutionnum,"Generate pathways to objective" => 1,"MFASolver" => "CPLEX","objective" => $objectivestring,"exchange species" => $additionalexchange},"MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",undef,$self->selected_version());          my $command;
2380            if (defined($AllReversible) && $AllReversible == 1) {
2381                    $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($filename,$self->id(),$media,["ProductionMFA"],{"use simple variable and constraint names"=>1,"Make all reactions reversible in MFA"=>1, "Recursive MILP solution limit" => $solutionnum,"Generate pathways to objective" => 1,"MFASolver" => "SCIP","objective" => $objectivestring,"exchange species" => $additionalexchange},"MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",undef,$self->selected_version());
2382            } else {
2383                    $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($filename,$self->id(),$media,["ProductionMFA"],{"use simple variable and constraint names"=>1,"Make all reactions reversible in MFA"=>0, "Recursive MILP solution limit" => $solutionnum,"Generate pathways to objective" => 1,"MFASolver" => "SCIP","objective" => $objectivestring,"exchange species" => $additionalexchange},"MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",undef,$self->selected_version());
2384            }
2385            print $command."\n";
2386          system($command);          system($command);
2387    
2388          #Loading problem report          #Loading problem report
# Line 1972  Line 2390 
2390          #Clearing output          #Clearing output
2391          $self->figmodel()->clearing_output($filename,"MinimalPathways-".$media."-".$self->id()."-".$objective.".txt");          $self->figmodel()->clearing_output($filename,"MinimalPathways-".$media."-".$self->id()."-".$objective.".txt");
2392          if (!defined($results)) {          if (!defined($results)) {
2393                    print STDERR $objective." pathway results not found!\n";
2394                  return;                  return;
2395          }          }
2396    
# Line 1983  Line 2402 
2402                  @Array = /\d+:([^\|]+)\|/g;                  @Array = /\d+:([^\|]+)\|/g;
2403          }          }
2404    
2405          # Storing data in a figmodel table          #Writing output to file
2406          my $TableObject;          $self->figmodel()->database()->print_array_to_file($self->directory()."MinimalPathways-".$media."-".$objective."-".$self->id()."-".$AllReversible."-".$self->selected_version().".txt",[join("|",@Array)]);
2407          if (-e $self->directory()."MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt") {  }
2408                  $TableObject->load_table($self->directory()."MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",";","|",0,["OBJECTIVE"]);  
2409          } else {  sub combine_minimal_pathways {
2410                  $TableObject = FIGMODELTable->new(["OBJECTIVE","REACTIONS"],$self->directory()."MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",["OBJECTIVE"],";","|",undef);          my ($self) = @_;
2411          }  
2412          my $tablerow = $TableObject->get_row_by_key($objective,"OBJECTIVE",1);          my $tbl;
2413          push(@{$tablerow->{"REACTIONS"}},@Array);          if (-e $self->directory()."MinimalPathwayTable-".$self->id().$self->selected_version().".tbl") {
2414          $TableObject->save();                  $tbl = FIGMODELTable::load_table($self->directory()."MinimalPathwayTable-".$self->id().$self->selected_version().".tbl",";","|",0,["Objective","Media","Reversible"]);
2415            } else {
2416                    $tbl = FIGMODELTable->new(["Objective","Media","Reactions","Reversible","Shortest path","Number of essentials","Essentials","Length"],$self->directory()."MinimalPathwayTable-".$self->id().$self->selected_version().".tbl",["Objective","Media","Reversible"],";","|");
2417            }
2418            my @files = glob($self->directory()."MinimalPathways-*");
2419            for (my $i=0; $i < @files;$i++) {
2420                    if ($files[$i] =~ m/MinimalPathways\-(\S+)\-(cpd\d\d\d\d\d)\-(\w+)\-(\d)\-/ || $files[$i] =~ m/MinimalPathways\-(\S+)\-(ENERGY)\-(\w+)\-(\d)\-/) {
2421                            my $reactions = $self->figmodel()->database()->load_single_column_file($files[$i],"");
2422                            if (defined($reactions) && @{$reactions} > 0 && length($reactions->[0]) > 0) {
2423                                    my $newrow = {"Objective"=>[$2],"Media"=>[$1],"Reversible"=>[$4]};
2424                                    my $row = $tbl->get_table_by_key($newrow->{"Objective"}->[0],"Objective")->get_table_by_key($newrow->{"Media"}->[0],"Media")->get_row_by_key($newrow->{"Reversible"}->[0],"Reversible");
2425                                    if (!defined($row)) {
2426                                            $row = $tbl->add_row($newrow);
2427                                    }
2428                                    $row->{Reactions} = $self->figmodel()->database()->load_single_column_file($files[$i],"");
2429                                    delete($row->{"Shortest path"});
2430                                    delete($row->{"Number of essentials"});
2431                                    delete($row->{"Essentials"});
2432                                    delete($row->{"Length"});
2433                                    for (my $j=0; $j < @{$row->{Reactions}}; $j++) {
2434                                            my @array = split(/,/,$row->{Reactions}->[$j]);
2435                                            $row->{"Length"}->[$j] = @array;
2436                                            if (!defined($row->{"Shortest path"}->[0]) || $row->{"Length"}->[$j] < $row->{"Shortest path"}->[0]) {
2437                                                    $row->{"Shortest path"}->[0] = $row->{"Length"}->[$j];
2438                                            }
2439                                            $row->{"Number of essentials"}->[0] = 0;
2440                                            for (my $k=0; $k < @array;$k++) {
2441                                                    if ($array[$k] =~ m/(rxn\d\d\d\d\d)/) {
2442                                                            my $class = $self->get_reaction_class($1,1);
2443                                                            my $temp = $row->{Media}->[0].":Essential";
2444                                                            if ($class =~ m/$temp/) {
2445                                                                    $row->{"Number of essentials"}->[$j]++;
2446                                                                    if (!defined($row->{"Essentials"}->[$j]) && length($row->{"Essentials"}->[$j]) > 0) {
2447                                                                            $row->{"Essentials"}->[$j] = $array[$k];
2448                                                                    } else {
2449                                                                            $row->{"Essentials"}->[$j] .= ",".$array[$k];
2450                                                                    }
2451                                                            }
2452                                                    }
2453                                            }
2454                                    }
2455                            }
2456                    }
2457            }
2458            $tbl->save();
2459  }  }
2460    
2461  =head3 calculate_growth  =head3 calculate_growth
# Line 2002  Line 2465 
2465          Calculating growth in the input media          Calculating growth in the input media
2466  =cut  =cut
2467  sub calculate_growth {  sub calculate_growth {
2468          my ($self,$Media) = @_;          my ($self,$Media,$outputDirectory,$InParameters,$saveLPFile) = @_;
2469            #Setting the Media
2470            if (!defined($Media) || length($Media) == 0) {
2471                    $Media = $self->autocompleteMedia();
2472            }
2473            #Setting parameters for the run
2474            my $DefaultParameters = $self->figmodel()->defaultParameters();
2475            if (defined($InParameters)) {
2476                    my @parameters = keys(%{$InParameters});
2477                    for (my $i=0; $i < @parameters; $i++) {
2478                            $DefaultParameters->{$parameters[$i]} = $InParameters->{$parameters[$i]};
2479                    }
2480            }
2481            $DefaultParameters->{"optimize metabolite production if objective is zero"} = 1;
2482            #Setting filenames
2483          my $UniqueFilename = $self->figmodel()->filename();          my $UniqueFilename = $self->figmodel()->filename();
2484          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)) {
2485                    $outputDirectory = $self->config("database message file directory")->[0];
2486            }
2487            my $fluxFilename = $outputDirectory."Fluxes-".$self->id()."-".$Media.".txt";
2488            my $cpdFluxFilename = $outputDirectory."CompoundFluxes-".$self->id()."-".$Media.".txt";
2489            #Running FBA
2490            system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$Media,["ProductionMFA"],$DefaultParameters,$self->id()."-".$Media."-GrowthTest.txt",undef,$self->selected_version()));
2491            #Saving LP file if requested
2492            if (defined($saveLPFile) && $saveLPFile == 1 && -e $self->figmodel()->{"MFAToolkit output directory"}->[0].$UniqueFilename."/CurrentProblem.lp") {
2493                    system("cp ".$self->figmodel()->config("MFAToolkit output directory")->[0].$UniqueFilename."/CurrentProblem.lp ".$self->figmodel()->config("SBML files")->[0].$self->id().".lp");
2494            }
2495          my $ProblemReport = $self->figmodel()->LoadProblemReport($UniqueFilename);          my $ProblemReport = $self->figmodel()->LoadProblemReport($UniqueFilename);
2496          my $Result;          my $Result;
2497          if (defined($ProblemReport)) {          if (defined($ProblemReport)) {
2498                  my $Row = $ProblemReport->get_row(0);                  my $Row = $ProblemReport->get_row(0);
2499                  if (defined($Row) && defined($Row->{"Objective"}->[0])) {                  if (defined($Row) && defined($Row->{"Objective"}->[0])) {
2500                          if ($Row->{"Objective"}->[0] < 0.00000001) {                          if ($Row->{"Objective"}->[0] < 0.00000001 || $Row->{"Objective"}->[0] == 1e7) {
2501                                  $Result = "NOGROWTH:".$Row->{"Individual metabolites with zero production"}->[0];                                  $Result = "NOGROWTH";
2502                                    if (defined($Row->{"Individual metabolites with zero production"}->[0]) && $Row->{"Individual metabolites with zero production"}->[0] =~ m/cpd\d\d\d\d\d/) {
2503                                            $Result .= ":".$Row->{"Individual metabolites with zero production"}->[0];
2504                                    }
2505                          } else {                          } else {
2506                                    if (-e $self->figmodel()->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/SolutionReactionData0.txt") {
2507                                            system("cp ".$self->figmodel()->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/SolutionReactionData0.txt ".$fluxFilename);
2508                                            system("cp ".$self->figmodel()->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/SolutionCompoundData0.txt ".$cpdFluxFilename);
2509                                    }
2510                                  $Result = $Row->{"Objective"}->[0];                                  $Result = $Row->{"Objective"}->[0];
2511                          }                          }
2512                  }                  }
2513          }          }
2514            #Deleting files if necessary
2515            if ($self->figmodel()->config("preserve all log files")->[0] ne "yes") {
2516                    $self->figmodel()->cleardirectory($UniqueFilename);
2517                    unlink($self->figmodel()->config("database message file directory")->[0].$self->id()."-".$Media."-GrowthTest.txt");
2518            }
2519            #Returning result
2520          return $Result;          return $Result;
2521  }  }
2522    
# Line 2036  Line 2536 
2536          7.) Dead: these reactions are disconnected from the network.          7.) Dead: these reactions are disconnected from the network.
2537  =cut  =cut
2538  sub classify_model_reactions {  sub classify_model_reactions {
2539          my ($self,$Media) = @_;          my ($self,$Media,$SaveChanges) = @_;
2540    
2541          #Getting unique file for printing model output          #Getting unique file for printing model output
2542          my $UniqueFilename = $self->figmodel()->filename();          my $UniqueFilename = $self->figmodel()->filename();
# Line 2123  Line 2623 
2623                                  $CpdRow->{MEDIA}->[$index] = $Media;                                  $CpdRow->{MEDIA}->[$index] = $Media;
2624                          }                          }
2625                  }                  }
2626                    if (!defined($SaveChanges) || $SaveChanges == 1) {
2627                  $cpdclasstable->save();                  $cpdclasstable->save();
2628          }          }
2629            }
2630          if (defined($ReactionTB)) {          if (defined($ReactionTB)) {
2631                  for (my $i=0; $i < $ReactionTB->size(); $i++) {                  for (my $i=0; $i < $ReactionTB->size(); $i++) {
2632                          my $Row = $ReactionTB->get_row($i);                          my $Row = $ReactionTB->get_row($i);
# Line 2179  Line 2681 
2681                                  $RxnRow->{MEDIA}->[$index] = $Media;                                  $RxnRow->{MEDIA}->[$index] = $Media;
2682                          }                          }
2683                  }                  }
2684                    if (!defined($SaveChanges) || $SaveChanges == 1) {
2685                  $rxnclasstable->save();                  $rxnclasstable->save();
2686          }          }
2687            }
2688          return ($rxnclasstable,$cpdclasstable);          return ($rxnclasstable,$cpdclasstable);
2689  }  }
2690    
# Line 2212  Line 2716 
2716    
2717          #Running simulations          #Running simulations
2718          system($self->config("mfalite executable")->[0]." ".$self->config("Reaction database directory")->[0]."masterfiles/MediaTable.txt ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/Jobfile.txt ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/Output.txt");          system($self->config("mfalite executable")->[0]." ".$self->config("Reaction database directory")->[0]."masterfiles/MediaTable.txt ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/Jobfile.txt ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/Output.txt");
         print "simulation complete for ".$self->id().$self->selected_version()."\n";  
2719          #Parsing the results          #Parsing the results
2720          my $Results = $self->figmodel()->database()->load_table($self->config("MFAToolkit output directory")->[0].$UniqueFilename."/Output.txt",";","\\|",0,undef);          my $Results = $self->figmodel()->database()->load_table($self->config("MFAToolkit output directory")->[0].$UniqueFilename."/Output.txt",";","\\|",0,undef);
2721          if (!defined($Results)) {          if (!defined($Results)) {
# Line 2619  Line 3122 
3122                                          if (length($GapFillingRunSpecs) > 0) {                                          if (length($GapFillingRunSpecs) > 0) {
3123                                                  $GapFillingRunSpecs .= ";";                                                  $GapFillingRunSpecs .= ";";
3124                                          }                                          }
3125                                          $GapFillingRunSpecs .= $HeadingDataArray[2].":".$HeadingDataArray[1].".txt:".$HeadingDataArray[3];                                          $GapFillingRunSpecs .= $HeadingDataArray[2].":".$HeadingDataArray[1].":".$HeadingDataArray[3];
3126                                  } else {                                  } else {
3127                                          $SolutionExistedCount++;                                          $SolutionExistedCount++;
3128                                  }                                  }
# Line 2644  Line 3147 
3147          my $SolutionsFound = 0;          my $SolutionsFound = 0;
3148          my $GapFillingArray;          my $GapFillingArray;
3149          push(@{$GapFillingArray},split(/;/,$GapFillingRunSpecs));          push(@{$GapFillingArray},split(/;/,$GapFillingRunSpecs));
3150          $self->datagapfill($GapFillingArray);          my $GapFillingResults = $self->datagapfill($GapFillingArray,"GFS");
3151            if (defined($GapFillingResults)) {
3152                    $SolutionsFound = 1;
3153            }
3154    
3155          if (defined($RescuedPreviousResults) && @{$RescuedPreviousResults} > 0) {          if (defined($RescuedPreviousResults) && @{$RescuedPreviousResults} > 0) {
3156                  #Printing previous solutions to GFS file                  #Printing previous solutions to GFS file
# Line 2667  Line 3173 
3173          return $self->success();          return $self->success();
3174  }  }
3175    
3176    =head3 SolutionReconciliation
3177    Definition:
3178            FIGMODELmodel->SolutionReconciliation();
3179    Description:
3180            This is a wrapper for running the solution reconciliation algorithm on any model in the database.
3181            The algorithm performs a reconciliation of any gap filling solutions to identify the combination of solutions that results in the optimal model.
3182            This function prints out one output file in the Model directory: ReconciliationOutput.txt: this is a summary of the results of the reconciliation analysis
3183    =cut
3184    
3185    sub SolutionReconciliation {
3186            my ($self,$GapFill,$Stage) = @_;
3187    
3188            #Setting the output filenames
3189            my $OutputFilename;
3190            my $OutputFilenameTwo;
3191            if ($GapFill == 1) {
3192                    $OutputFilename = $self->directory().$self->id().$self->selected_version()."-GFReconciliation.txt";
3193                    $OutputFilenameTwo = $self->directory().$self->id().$self->selected_version()."-GFSRS.txt";
3194            } else {
3195                    $OutputFilename = $self->directory().$self->id().$self->selected_version()."-GGReconciliation.txt";
3196                    $OutputFilenameTwo = $self->directory().$self->id().$self->selected_version()."-GGSRS.txt";
3197            }
3198    
3199            #In stage one, we run the reconciliation and create a test file to check combined solution performance
3200            if (!defined($Stage) || $Stage == 1) {
3201                    my $GrowMatchTable = $self->figmodel()->database()->LockDBTable("GROWMATCH TABLE");
3202                    my $Row = $GrowMatchTable->get_row_by_key($self->genome(),"ORGANISM",1);
3203                    $Row->{"GF RECONCILATION TIMING"}->[0] = time()."-";
3204                    $GrowMatchTable->save();
3205                    $self->figmodel()->database()->UnlockDBTable("GROWMATCH TABLE");
3206    
3207                    #Getting a unique filename
3208                    my $UniqueFilename = $self->figmodel()->filename();
3209    
3210                    #Copying over the necessary files
3211                    if ($GapFill == 1) {
3212                            if (!-e $self->directory().$self->id().$self->selected_version()."-GFEM.txt") {
3213                                    print STDERR "FIGMODEL:SolutionReconciliation:".$self->directory().$self->id().$self->selected_version()."-GFEM.txt file not found. Could not reconcile!";
3214                                    return 0;
3215                            }
3216                            if (!-e $self->directory().$self->id().$self->selected_version()."-OPEM.txt") {
3217                                    print STDERR "FIGMODEL:SolutionReconciliation:".$self->directory().$self->id().$self->selected_version()."-OPEM.txt file not found. Could not reconcile!";
3218                                    return 0;
3219                            }
3220                            system("cp ".$self->directory().$self->id().$self->selected_version()."-GFEM.txt ".$self->figmodel()->config("MFAToolkit input files")->[0].$UniqueFilename."-GFEM.txt");
3221                            system("cp ".$self->directory().$self->id().$self->selected_version()."-OPEM.txt ".$self->figmodel()->config("MFAToolkit input files")->[0].$UniqueFilename."-OPEM.txt");
3222                            #Backing up and deleting the existing reconciliation file
3223                            if (-e $OutputFilename) {
3224                                    system("cp ".$OutputFilename." ".$self->directory().$self->id().$self->selected_version()."-OldGFReconciliation.txt");
3225                                    unlink($OutputFilename);
3226                            }
3227                    } else {
3228                            if (!-e $self->directory().$self->id().$self->selected_version()."-GGEM.txt") {
3229                                    print STDERR "FIGMODEL:SolutionReconciliation:".$self->directory().$self->id().$self->selected_version()."-GGEM.txt file not found. Could not reconcile!";
3230                                    return 0;
3231                            }
3232                            if (!-e $self->directory().$self->id().$self->selected_version()."-GGOPEM.txt") {
3233                                    print STDERR "FIGMODEL:SolutionReconciliation:".$self->directory().$self->id().$self->selected_version()."-GGOPEM.txt file not found. Could not reconcile!";
3234                                    return 0;
3235                            }
3236                            system("cp ".$self->directory().$self->id().$self->selected_version()."-GGEM.txt ".$self->figmodel()->config("MFAToolkit input files")->[0].$UniqueFilename."-GGEM.txt");
3237                            system("cp ".$self->directory().$self->id().$self->selected_version()."-GGOPEM.txt ".$self->figmodel()->config("MFAToolkit input files")->[0].$UniqueFilename."-OPEM.txt");
3238                            #Backing up and deleting the existing reconciliation file
3239                            if (-e $OutputFilename) {
3240                                    system("cp ".$OutputFilename." ".$self->directory().$self->id().$self->selected_version()."-OldGGReconciliation.txt");
3241                                    unlink($OutputFilename);
3242                            }
3243                    }
3244    
3245                    #Running the reconciliation
3246                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),"NONE",["SolutionReconciliation"],{"Solution data for model optimization" => $UniqueFilename},"Reconciliation".$UniqueFilename.".log",undef,$self->selected_version()));
3247                    $GrowMatchTable = $self->figmodel()->database()->LockDBTable("GROWMATCH TABLE");
3248                    $Row = $GrowMatchTable->get_row_by_key($self->genome(),"ORGANISM",1);
3249                    $Row->{"GF RECONCILATION TIMING"}->[0] .= time();
3250                    $GrowMatchTable->save();
3251                    $self->figmodel()->database()->UnlockDBTable("GROWMATCH TABLE");
3252    
3253                    #Loading the problem report from the reconciliation run
3254                    my $ReconciliatonOutput = $self->figmodel()->LoadProblemReport($UniqueFilename);
3255                    print $UniqueFilename."\n";
3256                    #Clearing output files
3257                    $self->figmodel()->clearing_output($UniqueFilename,"Reconciliation".$UniqueFilename.".log");
3258                    $ReconciliatonOutput->save("/home/chenry/Test.txt");
3259    
3260                    #Checking the a problem report was found and was loaded
3261                    if (!defined($ReconciliatonOutput) || $ReconciliatonOutput->size() < 1 || !defined($ReconciliatonOutput->get_row(0)->{"Notes"}->[0])) {
3262                            print STDERR "FIGMODEL:SolutionReconciliation: MFAToolkit output from SolutionReconciliation of ".$self->id()." not found!\n\n";
3263                            return 0;
3264                    }
3265    
3266                    #Processing the solutions
3267                    my $SolutionCount = 0;
3268                    my $ReactionSetHash;
3269                    my $SingleReactionHash;
3270                    my $ReactionDataHash;
3271                    for (my $n=0; $n < $ReconciliatonOutput->size(); $n++) {
3272                            if (defined($ReconciliatonOutput->get_row($n)->{"Notes"}->[0]) && $ReconciliatonOutput->get_row($n)->{"Notes"}->[0] =~ m/^Recursive\sMILP\s([^;]+)/) {
3273                                    #Breaking up the solution into reaction sets
3274                                    my @ReactionSets = split(/\|/,$1);
3275                                    #Creating reaction lists for each set
3276                                    my $SolutionHash;
3277                                    for (my $i=0; $i < @ReactionSets; $i++) {
3278                                            if (length($ReactionSets[$i]) > 0) {
3279                                                    my @Alternatives = split(/:/,$ReactionSets[$i]);
3280                                                    for (my $j=1; $j < @Alternatives; $j++) {
3281                                                            if (length($Alternatives[$j]) > 0) {
3282                                                                    push(@{$SolutionHash->{$Alternatives[$j]}},$Alternatives[0]);
3283                                                            }
3284                                                    }
3285                                                    if (@Alternatives == 1) {
3286                                                            $SingleReactionHash->{$Alternatives[0]}->{$SolutionCount} = 1;
3287                                                            if (!defined($SingleReactionHash->{$Alternatives[0]}->{"COUNT"})) {
3288                                                                    $SingleReactionHash->{$Alternatives[0]}->{"COUNT"} = 0;
3289                                                            }
3290                                                            $SingleReactionHash->{$Alternatives[0]}->{"COUNT"}++;
3291                                                    }
3292                                            }
3293                                    }
3294                                    #Identifying reactions sets and storing the sets in the reactions set hash
3295                                    foreach my $Solution (keys(%{$SolutionHash})) {
3296                                            my $SetKey = join(",",sort(@{$SolutionHash->{$Solution}}));
3297                                            if (!defined($ReactionSetHash->{$SetKey}->{$SetKey}->{$SolutionCount})) {
3298                                                    $ReactionSetHash->{$SetKey}->{$SetKey}->{$SolutionCount} = 1;
3299                                                    if (!defined($ReactionSetHash->{$SetKey}->{$SetKey}->{"COUNT"})) {
3300                                                            $ReactionSetHash->{$SetKey}->{$SetKey}->{"COUNT"} = 0;
3301                                                    }
3302                                                    $ReactionSetHash->{$SetKey}->{$SetKey}->{"COUNT"}++;
3303                                            }
3304                                            $ReactionSetHash->{$SetKey}->{$Solution}->{$SolutionCount} = 1;
3305                                            if (!defined($ReactionSetHash->{$SetKey}->{$Solution}->{"COUNT"})) {
3306                                                    $ReactionSetHash->{$SetKey}->{$Solution}->{"COUNT"} = 0;
3307                                            }
3308                                            $ReactionSetHash->{$SetKey}->{$Solution}->{"COUNT"}++;
3309                                    }
3310                                    $SolutionCount++;
3311                            }
3312                    }
3313    
3314                    #Handling the scenario where no solutions were found
3315                    if ($SolutionCount == 0) {
3316                            print STDERR "FIGMODEL:SolutionReconciliation: Reconciliation unsuccessful. No solution found.\n\n";
3317                            return 0;
3318                    }
3319    
3320                    #Printing results without solution performance figures. Also printing solution test file
3321                    open (RECONCILIATION, ">$OutputFilename");
3322                    #Printing the file heading
3323                    print RECONCILIATION "DATABASE;DEFINITION;REVERSIBLITY;DELTAG;DIRECTION;NUMBER OF SOLUTIONS";
3324                    for (my $i=0; $i < $SolutionCount; $i++) {
3325                            print RECONCILIATION ";Solution ".$i;
3326                    }
3327                    print RECONCILIATION "\n";
3328                    #Printing the singlet reactions first
3329                    my $Solutions;
3330                    print RECONCILIATION "SINGLET REACTIONS\n";
3331                    my @SingletReactions = keys(%{$SingleReactionHash});
3332                    for (my $j=0; $j < $SolutionCount; $j++) {
3333                            $Solutions->[$j]->{"BASE"} = $j;
3334                    }
3335                    for (my $i=0; $i < @SingletReactions; $i++) {
3336                            my $ReactionData;
3337                            if (defined($ReactionDataHash->{$SingletReactions[$i]})) {
3338                                    $ReactionData = $ReactionDataHash->{$SingletReactions[$i]};
3339                            } else {
3340                                    my $Direction = substr($SingletReactions[$i],0,1);
3341                                    if ($Direction eq "+") {
3342                                            $Direction = "=>";
3343                                    } else {
3344                                            $Direction = "<=";
3345                                    }
3346                                    my $Reaction = substr($SingletReactions[$i],1);
3347                                    $ReactionData = FIGMODELObject->load($self->figmodel()->config("reaction directory")->[0].$Reaction,"\t");
3348                                    $ReactionData->{"DIRECTIONS"}->[0] = $Direction;
3349                                    $ReactionData->{"REACTIONS"}->[0] = $Reaction;
3350                                    if (!defined($ReactionData->{"DEFINITION"}->[0])) {
3351                                            $ReactionData->{"DEFINITION"}->[0] = "UNKNOWN";
3352                                    }
3353                                    if (!defined($ReactionData->{"THERMODYNAMIC REVERSIBILITY"}->[0])) {
3354                                            $ReactionData->{"THERMODYNAMIC REVERSIBILITY"}->[0] = "UNKNOWN";
3355                                    }
3356                                    if (!defined($ReactionData->{"DELTAG"}->[0])) {
3357                                            $ReactionData->{"DELTAG"}->[0] = "UNKNOWN";
3358                                    }
3359                                    $ReactionDataHash->{$SingletReactions[$i]} = $ReactionData;
3360                            }
3361                            print RECONCILIATION $ReactionData->{"REACTIONS"}->[0].";".$ReactionData->{"DEFINITION"}->[0].";".$ReactionData->{"THERMODYNAMIC REVERSIBILITY"}->[0].";".$ReactionData->{"DELTAG"}->[0].";".$ReactionData->{"DIRECTIONS"}->[0].";".$SingleReactionHash->{$SingletReactions[$i]}->{"COUNT"};
3362                            for (my $j=0; $j < $SolutionCount; $j++) {
3363                                    print RECONCILIATION ";";
3364                                    if (defined($SingleReactionHash->{$SingletReactions[$i]}->{$j})) {
3365                                            $Solutions->[$j]->{$SingletReactions[$i]} = 1;
3366                                            $Solutions->[$j]->{"BASE"} = $j;
3367                                            print RECONCILIATION "|".$j."|";
3368                                    }
3369                            }
3370                            print RECONCILIATION "\n";
3371                    }
3372                    #Printing the reaction sets with alternatives
3373                    print RECONCILIATION "Reaction sets with alternatives\n";
3374                    my @ReactionSets = keys(%{$ReactionSetHash});
3375                    foreach my $ReactionSet (@ReactionSets) {
3376                            my $NewSolutions;
3377                            my $BaseReactions;
3378                            my $AltList = [$ReactionSet];
3379                            push(@{$AltList},keys(%{$ReactionSetHash->{$ReactionSet}}));
3380                            for (my $j=0; $j < @{$AltList}; $j++) {
3381                                    my $CurrentNewSolutions;
3382                                    my $Index;
3383                                    if ($j == 0) {
3384                                            print RECONCILIATION "NEW SET\n";
3385                                    } elsif ($AltList->[$j] ne $ReactionSet) {
3386                                            print RECONCILIATION "ALTERNATIVE SET\n";
3387                                            #For each base solution in which this set is represented, we copy the base solution to the new solution
3388                                            my $NewSolutionCount = 0;
3389                                            for (my $k=0; $k < $SolutionCount; $k++) {
3390                                                    if (defined($ReactionSetHash->{$ReactionSet}->{$AltList->[$j]}->{$k})) {
3391                                                            if (defined($Solutions)) {
3392                                                                    $Index->{$k} = @{$Solutions} + $NewSolutionCount;
3393                                                            } else {
3394                                                                    $Index->{$k} = $NewSolutionCount;
3395                                                            }
3396                                                            if (defined($NewSolutions) && @{$NewSolutions} > 0) {
3397                                                                    $Index->{$k} += @{$NewSolutions};
3398                                                            }
3399                                                            $CurrentNewSolutions->[$NewSolutionCount] = {};
3400                                                            foreach my $Reaction (keys(%{$Solutions->[$k]})) {
3401                                                                    $CurrentNewSolutions->[$NewSolutionCount]->{$Reaction} = $Solutions->[$k]->{$Reaction};
3402                                                            }
3403                                                            $NewSolutionCount++;
3404                                                    }
3405                                            }
3406                                    }
3407                                    if ($j == 0 || $AltList->[$j] ne $ReactionSet) {
3408                                            my @SingletReactions = split(/,/,$AltList->[$j]);
3409                                            for (my $i=0; $i < @SingletReactions; $i++) {
3410                                                    #Adding base reactions to base solutions and set reactions the new solutions
3411                                                    if ($j == 0) {
3412                                                            push(@{$BaseReactions},$SingletReactions[$i]);
3413                                                    } else {
3414                                                            for (my $k=0; $k < @{$CurrentNewSolutions}; $k++) {
3415                                                                    $CurrentNewSolutions->[$k]->{$SingletReactions[$i]} = 1;
3416                                                            }
3417                                                    }
3418                                                    #Getting reaction data and printing reaction in output file
3419                                                    my $ReactionData;
3420                                                    if (defined($ReactionDataHash->{$SingletReactions[$i]})) {
3421                                                            $ReactionData = $ReactionDataHash->{$SingletReactions[$i]};
3422                                                    } else {
3423                                                            my $Direction = substr($SingletReactions[$i],0,1);
3424                                                            if ($Direction eq "+") {
3425                                                                    $Direction = "=>";
3426                                                            } else {
3427                                                                    $Direction = "<=";
3428                                                            }
3429                                                            my $Reaction = substr($SingletReactions[$i],1);
3430                                                            $ReactionData = FIGMODELObject->load($self->figmodel()->config("reaction directory")->[0].$Reaction,"\t");
3431                                                            $ReactionData->{"DIRECTIONS"}->[0] = $Direction;
3432                                                            $ReactionData->{"REACTIONS"}->[0] = $Reaction;
3433                                                            if (!defined($ReactionData->{"DEFINITION"}->[0])) {
3434                                                                    $ReactionData->{"DEFINITION"}->[0] = "UNKNOWN";
3435                                                            }
3436                                                            if (!defined($ReactionData->{"THERMODYNAMIC REVERSIBILITY"}->[0])) {
3437                                                                    $ReactionData->{"THERMODYNAMIC REVERSIBILITY"}->[0] = "UNKNOWN";
3438                                                            }
3439                                                            if (!defined($ReactionData->{"DELTAG"}->[0])) {
3440                                                                    $ReactionData->{"DELTAG"}->[0] = "UNKNOWN";
3441                                                            }
3442                                                            $ReactionDataHash->{$SingletReactions[$i]} = $ReactionData;
3443                                                    }
3444                                                    print RECONCILIATION $ReactionData->{"REACTIONS"}->[0].";".$ReactionData->{"DEFINITION"}->[0].";".$ReactionData->{"THERMODYNAMIC REVERSIBILITY"}->[0].";".$ReactionData->{"DELTAG"}->[0].";".$ReactionData->{"DIRECTIONS"}->[0].";".$ReactionSetHash->{$ReactionSet}->{$AltList->[$j]}->{"COUNT"};
3445                                                    for (my $k=0; $k < $SolutionCount; $k++) {
3446                                                            print RECONCILIATION ";";
3447                                                            if (defined($ReactionSetHash->{$ReactionSet}->{$AltList->[$j]}->{$k})) {
3448                                                                    if ($j == 0) {
3449                                                                            print RECONCILIATION "|".$k."|";
3450                                                                    } else {
3451                                                                            print RECONCILIATION "|".$Index->{$k}."|";
3452                                                                    }
3453                                                            }
3454                                                    }
3455                                                    print RECONCILIATION "\n";
3456                                            }
3457                                            #Adding the current new solutions to the new solutions array
3458                                            if (defined($CurrentNewSolutions) && @{$CurrentNewSolutions} > 0) {
3459                                                    push(@{$NewSolutions},@{$CurrentNewSolutions});
3460                                            }
3461                                    }
3462                            }
3463                            #Adding the base reactions to all existing solutions
3464                            for (my $j=0; $j < @{$Solutions}; $j++) {
3465                                    if (defined($ReactionSetHash->{$ReactionSet}->{$ReactionSet}->{$Solutions->[$j]->{"BASE"}})) {
3466                                            foreach my $SingleReaction (@{$BaseReactions}) {
3467                                                    $Solutions->[$j]->{$SingleReaction} = 1;
3468                                            }
3469                                    }
3470                            }
3471                            #Adding the new solutions to the set of existing solutions
3472                            push(@{$Solutions},@{$NewSolutions});
3473                    }
3474                    close(RECONCILIATION);
3475                    #Now printing a file that defines all of the solutions in a format the testsolutions function understands
3476                    open (RECONCILIATION, ">$OutputFilenameTwo");
3477                    print RECONCILIATION "Experiment;Solution index;Solution cost;Solution reactions\n";
3478                    for (my $i=0; $i < @{$Solutions}; $i++) {
3479                            delete($Solutions->[$i]->{"BASE"});
3480                            print RECONCILIATION "SR".$i.";".$i.";10;".join(",",keys(%{$Solutions->[$i]}))."\n";
3481                    }
3482                    close(RECONCILIATION);
3483    
3484                    $GrowMatchTable = $self->figmodel()->database()->LockDBTable("GROWMATCH TABLE");
3485                    $Row = $GrowMatchTable->get_row_by_key($self->genome(),"ORGANISM",1);
3486                    $Row->{"GF RECON TESTING TIMING"}->[0] = time()."-";
3487                    $Row->{"GF RECON SOLUTIONS"}->[0] = @{$Solutions};
3488                    $GrowMatchTable->save();
3489                    $self->figmodel()->database()->UnlockDBTable("GROWMATCH TABLE");
3490    
3491                    #Scheduling the solution testing
3492                    if ($GapFill == 1) {
3493                            system($self->figmodel()->config("scheduler executable")->[0]." \"add:testsolutions?".$self->id().$self->selected_version()."?-1?GFSR:BACK:fast:QSUB\"");
3494                    } else {
3495                            system($self->figmodel()->config("scheduler executable")->[0]." \"add:testsolutions?".$self->id().$self->selected_version()."?-1?GGSR:BACK:fast:QSUB\"");
3496                    }
3497            } else {
3498                    #Reading in the solution testing results
3499                    my $Data;
3500                    if ($GapFill == 1) {
3501                            $Data = $self->figmodel()->database()->load_single_column_file($self->directory().$self->id().$self->selected_version()."-GFSREM.txt","");
3502                    } else {
3503                            $Data = $self->figmodel()->database()->load_single_column_file($self->directory().$self->id().$self->selected_version()."-GGSREM.txt","");
3504                    }
3505    
3506                    #Reading in the preliminate reconciliation report
3507                    my $OutputData = $self->figmodel()->database()->load_single_column_file($OutputFilename,"");
3508                    #Replacing the file tags with actual performance data
3509                    my $Count = 0;
3510                    for (my $i=0; $i < @{$Data}; $i++) {
3511                            if ($Data->[$i] =~ m/^SR(\d+);.+;(\d+\/\d+);/) {
3512                                    my $Index = $1;
3513                                    my $Performance = $Index."/".$2;
3514                                    for (my $j=0; $j < @{$OutputData}; $j++) {
3515                                            $OutputData->[$j] =~ s/\|$Index\|/$Performance/g;
3516                                    }
3517                            }
3518                    }
3519                    $self->figmodel()->database()->print_array_to_file($OutputFilename,$OutputData);
3520    
3521                    my $GrowMatchTable = $self->figmodel()->database()->LockDBTable("GROWMATCH TABLE");
3522                    my $Row = $GrowMatchTable->get_row_by_key($self->genome(),"ORGANISM",1);
3523                    $Row->{"GF RECON TESTING TIMING"}->[0] .= time();
3524                    $GrowMatchTable->save();
3525                    $self->figmodel()->database()->UnlockDBTable("GROWMATCH TABLE");
3526            }
3527    
3528            return 1;
3529    }
3530    
3531  =head3 BuildSpecificBiomassReaction  =head3 BuildSpecificBiomassReaction
3532  Definition:  Definition:
3533          FIGMODELmodel->BuildSpecificBiomassReaction();          FIGMODELmodel->BuildSpecificBiomassReaction();
# Line 2679  Line 3540 
3540          my $OrganismID = $self->genome();          my $OrganismID = $self->genome();
3541          #Checking for a biomass override          #Checking for a biomass override
3542          if (defined($self->config("biomass reaction override")->{$OrganismID})) {          if (defined($self->config("biomass reaction override")->{$OrganismID})) {
3543                  $biomassrxn = $self->config("biomass reaction override")->{$OrganismID};                  my $biomassID = $self->config("biomass reaction override")->{$OrganismID};
3544                  print "Overriding biomass template and selecting ".$biomassrxn." for ".$OrganismID.".\n";                  my $tbl = $self->database()->get_table("BIOMASS",1);
3545                    $biomassrxn = $tbl->get_row_by_key($biomassID,"DATABASE");
3546                    print "Overriding biomass template and selecting ".$biomassID." for ".$OrganismID.".\n";
3547          } else {#Creating biomass reaction from the template          } else {#Creating biomass reaction from the template
3548                  #Getting the genome stats                  #Getting the genome stats
3549                  my $genomestats = $self->figmodel()->get_genome_stats($self->genome());                  my $genomestats = $self->figmodel()->get_genome_stats($self->genome());
# Line 2971  Line 3834 
3834    
3835                  #Adding the biomass equation to the biomass table                  #Adding the biomass equation to the biomass table
3836                  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());
3837                  $biomassrxn = $NewRow->{DATABASE}->[0];                  $biomassrxn = $NewRow;
                 print $biomassrxn."\n";  
3838          }          }
3839          print $biomassrxn."\n";          return $biomassrxn;
         my $BiomassRow = $self->figmodel()->add_model_to_biomass_reaction($biomassrxn,$self->id());  
         return $BiomassRow;  
3840  }  }
3841    
3842  =head3 PrintSBMLFile  =head3 PrintSBMLFile
# Line 3263  Line 4123 
4123          close(SBMLOUTPUT);          close(SBMLOUTPUT);
4124  }  }
4125    
4126    =head3 PrintModelSimpleReactionTable
4127    Definition:
4128            success()/fail() FIGMODELmodel->PrintModelSimpleReactionTable();
4129    Description:
4130            Prints the table of model data
4131    =cut
4132    sub PrintModelSimpleReactionTable {
4133            my ($self) = @_;
4134    
4135            my $rxntbl = $self->reaction_table();
4136            my $tbl = $self->create_table_prototype("ModelSimpleReactionTable");
4137            for (my $i=0; $i < $rxntbl->size(); $i++) {
4138                    my $row = $rxntbl->get_row($i);
4139                    $row->{DATABASE} = $row->{LOAD};
4140                    $tbl->add_row($row);
4141            }
4142            $tbl->save();
4143            system("cp ".$tbl->filename()." ".$self->figmodel()->config("Model table download directory")->[0].$self->figmodel()->config("ModelSimpleReactionTable")->{filename_prefix}->[0]."-".$self->id().".txt");
4144    }
4145    
4146  =head3 PrintModelLPFile  =head3 PrintModelLPFile
4147  Definition:  Definition:
4148          success()/fail() FIGMODELmodel->PrintModelLPFile();          success()/fail() FIGMODELmodel->PrintModelLPFile();
# Line 3287  Line 4167 
4167          $self->figmodel()->clearing_output($UniqueFilename,"FBA-".$self->id().$self->selected_version().".lp");          $self->figmodel()->clearing_output($UniqueFilename,"FBA-".$self->id().$self->selected_version().".lp");
4168  }  }
4169    
4170    =head3 patch_model
4171    Definition:
4172            FIGMODELTable:patch results = FIGMODELmodel->patch_model(FIGMODELTable:patch table);
4173    Description:
4174    =cut
4175    sub patch_model {
4176            my ($self,$tbl) = @_;
4177    
4178            #Instantiating table
4179            my $results = FIGMODELTable->new(["Reactions","New genes","Old genes","Genes","Roles","Status"],$self->directory()."PatchResults-".$self->id().$self->selected_version().".tbl",["Reaction"],"\t",";",undef);
4180            #Getting genome annotations
4181            my $features = $self->figmodel()->database()->get_genome_feature_table($self->genome());
4182            #Gettubg reaction table
4183            my $reactions = $self->reaction_table();
4184            #Checking for patched roles
4185            for (my $i=0; $i < $tbl->size(); $i++) {
4186                    my $row = $tbl->get_row($i);
4187                    my @genes = $features->get_rows_by_key($row->{ROLE}->[0],"ROLES");
4188                    if (@genes > 0) {
4189                            for (my $j=0; $j < @{$row->{REACTIONS}};$j++) {
4190                                    my $resultrxn = $results->get_row_by_key($row->{REACTIONS}->[$j],"Reactions");
4191                                    if (!defined($resultrxn)) {
4192                                            $resultrxn = $results->add_row({"Reactions"=>[$row->{REACTIONS}->[$j]],"Roles"=>[$row->{ROLE}->[0]]});
4193                                    }
4194                                    my $rxnrow = $reactions->get_row_by_key($row->{REACTIONS}->[$j],"LOAD");
4195                                    if (defined($rxnrow) && !defined($resultrxn->{"Old genes"})) {
4196                                            $resultrxn->{"Old genes"} = $rxnrow->{"ASSOCIATED PEG"};
4197                                            if ($resultrxn->{"Old genes"}->[0] !~ m/GAP|BOF|UNIVERSAL|SPONTANEOUS/) {
4198                                                    push(@{$resultrxn->{"Genes"}},@{$resultrxn->{"Old genes"}});
4199                                            }
4200                                    }
4201                                    delete $resultrxn->{"Current gene set"};
4202                                    if (defined($resultrxn->{"Genes"})) {
4203                                            push(@{$resultrxn->{"Current gene set"}},@{$resultrxn->{"Genes"}});
4204                                    }
4205                                    for (my $k=0; $k < @genes; $k++) {
4206                                            if ($genes[$k]->{ID}->[0] =~ m/(peg\.\d+)/) {
4207                                                    my $gene = $1;
4208                                                    my $addgene = 1;
4209                                                    if (defined($resultrxn->{"Old genes"})) {
4210                                                            for (my $m=0; $m < @{$resultrxn->{"Old genes"}}; $m++) {
4211                                                                    if ($resultrxn->{"Old genes"}->[$m] =~ m/$gene/) {
4212                                                                            $addgene = 0;
4213                                                                    }
4214                                                            }
4215                                                    }
4216                                                    if ($addgene == 1) {
4217                                                            push(@{$resultrxn->{"New genes"}},$gene);
4218                                                            if ($row->{COMPLEX}->[0] ne "0" && defined($resultrxn->{"Current gene set"})) {
4219                                                                    my $added = 0;
4220                                                                    for (my $m=0; $m < @{$resultrxn->{"Current gene set"}}; $m++) {
4221                                                                            if ($row->{COMPLEX}->[0] eq "1") {
4222                                                                                    $resultrxn->{"Current gene set"}->[$m] = $resultrxn->{"Current gene set"}->[$m]."+".$gene;
4223                                                                                    $added = 1;
4224                                                                            } else {
4225                                                                                    my @geneset = split(/\+/,$resultrxn->{"Current gene set"}->[$m]);
4226                                                                                    for (my $n=0; $n < @geneset;$n++) {
4227                                                                                            if ($self->figmodel()->colocalized_genes($geneset[$n],$gene,$self->genome()) == 1) {
4228                                                                                                    $resultrxn->{"Current gene set"}->[$m] = $resultrxn->{"Current gene set"}->[$m]."+".$gene;
4229                                                                                                    $added = 1;
4230                                                                                                    last;
4231                                                                                            }
4232                                                                                    }
4233                                                                            }
4234                                                                    }
4235                                                                    if ($added == 0) {
4236                                                                            push(@{$resultrxn->{"Current gene set"}},$gene);
4237                                                                    }
4238                                                            } else {
4239                                                                    push(@{$resultrxn->{"Current gene set"}},$gene);
4240                                                            }
4241                                                    }
4242                                            }
4243                                    }
4244                                    delete $resultrxn->{"Genes"};
4245                                    push(@{$resultrxn->{"Genes"}},@{$resultrxn->{"Current gene set"}});
4246                            }
4247                    }
4248            }
4249    
4250            #Ensuring that the old model is preserved
4251            $self->ArchiveModel();
4252            #Modifing the reaction list
4253            for (my $i=0; $i < $results->size();$i++) {
4254                    my $row = $results->get_row($i);
4255                    my $rxnrow = $reactions->get_row_by_key($row->{"Reactions"}->[0],"LOAD");
4256                    if (defined($rxnrow)) {
4257                            $rxnrow->{"ASSOCIATED PEG"} = $row->{"Genes"};
4258                    } else {
4259                            $reactions->add_row({LOAD=>[$row->{"Reactions"}->[0]],DIRECTIONALITY=>[$self->figmodel()->reversibility_of_reaction($row->{"Reactions"}->[0])],COMPARTMENT=>["c"],"ASSOCIATED PEG"=>$row->{"Genes"},SUBSYSTEM=>["NONE"],CONFIDENCE=>[2],REFERENCE=>["NONE"],NOTES=>["PATCH"]});
4260                    }
4261            }
4262            $reactions->save();
4263            $results->save();
4264            $self->update_model_stats();
4265            $self->PrintModelLPFile();
4266            $self->run_default_model_predictions();
4267            #Returning results
4268            return $results;
4269    }
4270    
4271    =head3 translate_genes
4272    Definition:
4273            FIGMODELmodel->translate_genes();
4274    Description:
4275    =cut
4276    sub translate_genes {
4277            my ($self) = @_;
4278    
4279            #Loading gene translations
4280            if (!defined($self->{_gene_aliases})) {
4281                    #Loading gene aliases from feature table
4282                    my $tbl = $self->figmodel()->GetGenomeFeatureTable($self->genome());
4283                    if (defined($tbl)) {
4284                            for (my $i=0; $i < $tbl->size(); $i++) {
4285                                    my $row = $tbl->get_row($i);
4286                                    if ($row->{ID}->[0] =~ m/(peg\.\d+)/) {
4287                                            my $geneID = $1;
4288                                            for (my $j=0; $j < @{$row->{ALIASES}}; $j++) {
4289                                                    $self->{_gene_aliases}->{$row->{ALIASES}->[$j]} = $geneID;
4290                                            }
4291                                    }
4292                            }
4293                    }
4294                    #Loading additional gene aliases from the database
4295                    if (-e $self->figmodel()->config("Translation directory")->[0]."AdditionalAliases/".$self->genome().".txt") {
4296                            my $AdditionalAliases = $self->figmodel()->database()->load_multiple_column_file($self->figmodel()->config("Translation directory")->[0]."AdditionalAliases/".$self->genome().".txt","\t");
4297                            for (my $i=0; $i < @{$AdditionalAliases}; $i++) {
4298                                    $self->{_gene_aliases}->{$AdditionalAliases->[$i]->[1]} = $AdditionalAliases->[$i]->[0];
4299                            }
4300                    }
4301            }
4302    
4303            #Cycling through reactions and translating genes
4304            for (my $i=0; $i < $self->reaction_table()->size(); $i++) {
4305                    my $row = $self->reaction_table()->get_row($i);
4306                    if (defined($row->{"ASSOCIATED PEG"})) {
4307                            for (my $j=0; $j < @{$row->{"ASSOCIATED PEG"}}; $j++) {
4308                                    my $Original = $row->{"ASSOCIATED PEG"}->[$j];
4309                                    $Original =~ s/\sand\s/:/g;
4310                                    $Original =~ s/\sor\s/;/g;
4311                                    my @GeneNames = split(/[,\+\s\(\):;]/,$Original);
4312                                    foreach my $Gene (@GeneNames) {
4313                                            if (length($Gene) > 0 && defined($self->{_gene_aliases}->{$Gene})) {
4314                                                    my $Replace = $self->{_gene_aliases}->{$Gene};
4315                                                    $Original =~ s/([^\w])$Gene([^\w])/$1$Replace$2/g;
4316                                                    $Original =~ s/^$Gene([^\w])/$Replace$1/g;
4317                                                    $Original =~ s/([^\w])$Gene$/$1$Replace/g;
4318                                                    $Original =~ s/^$Gene$/$Replace/g;
4319                                            }
4320                                    }
4321                                    $Original =~ s/:/ and /g;
4322                                    $Original =~ s/;/ or /g;
4323                                    $row->{"ASSOCIATED PEG"}->[$j] = $Original;
4324                            }
4325                    }
4326            }
4327    
4328            #Archiving model and saving reaction table
4329            $self->ArchiveModel();
4330            $self->reaction_table()->save();
4331    }
4332    
4333    =head3 feature_web_data
4334    Definition:
4335            string:web output for feature/model connection = FIGMODELmodel->feature_web_data(FIGMODELfeature:feature);
4336    Description:
4337    =cut
4338    sub feature_web_data {
4339            my ($self,$feature) = @_;
4340    
4341            #First checking if the feature is in the model
4342            my $featureGenome = $feature->{GENOME}->[0];
4343            if ($feature->{GENOME}->[0] =~ m/\>(\d+\.\d+)\</) {
4344                    $featureGenome = $1;
4345            }
4346            if ($featureGenome ne $self->genome()) {
4347                    return "Not in model";
4348            }
4349            my $data = $self->get_feature_data($feature->{ID}->[0]);
4350            if (!defined($data)) {
4351                    return "Not in model";
4352            }
4353    
4354            my $output;
4355            #Printing predictions
4356            if (defined($data->{$self->id()."PREDICTIONS"})) {
4357                    #Parsing essentiality data
4358                    my $essentialityData;
4359                    if (defined($feature->{ESSENTIALITY})) {
4360                            for (my $i=0; $i < @{$feature->{ESSENTIALITY}};$i++) {
4361                                    my @temp = split(/:/,$feature->{ESSENTIALITY}->[$i]);
4362                                    $essentialityData->{$temp[0]} = $temp[1];
4363                            }
4364                    }
4365                    my $predictionHash;
4366                    for (my $i=0; $i < @{$data->{$self->id()."PREDICTIONS"}};$i++) {
4367                            my @temp = split(/:/,$data->{$self->id()."PREDICTIONS"}->[$i]);
4368                            if (defined($essentialityData->{$temp[0]})) {
4369                                    if ($temp[1] eq "essential" && $essentialityData->{$temp[0]} eq "essential") {
4370                                            push(@{$predictionHash->{"Correct negative"}},$temp[0]);
4371                                    } elsif ($temp[1] eq "nonessential" && $essentialityData->{$temp[0]} eq "essential") {
4372                                            push(@{$predictionHash->{"False positive"}},$temp[0]);
4373                                    } elsif ($temp[1] eq "essential" && $essentialityData->{$temp[0]} eq "nonessential") {
4374                                            push(@{$predictionHash->{"False negative"}},$temp[0]);
4375                                    } elsif ($temp[1] eq "nonessential" && $essentialityData->{$temp[0]} eq "nonessential") {
4376                                            push(@{$predictionHash->{"Correct positive"}},$temp[0]);
4377                                    }
4378                            } else {
4379                                    push(@{$predictionHash->{$temp[1]}},$temp[0]);
4380                            }
4381                    }
4382                    foreach my $key (keys(%{$predictionHash})) {
4383                            my $string = $key;
4384                            $string = ucfirst($string);
4385                            push(@{$output},'<span title="'.join(", ",@{$predictionHash->{$key}}).'">'.$string.'</span>');
4386                    }
4387            }
4388    
4389            #Printing reactions
4390            if (defined($data->{$self->id()."REACTIONS"})) {
4391                    for (my $i=0; $i < @{$data->{$self->id()."REACTIONS"}};$i++) {
4392                            my $rxnData = $self->get_reaction_data($data->{$self->id()."REACTIONS"}->[$i]);
4393                            my $reactionString = $self->figmodel()->web()->create_reaction_link($data->{$self->id()."REACTIONS"}->[$i],join(" or ",@{$rxnData->{"ASSOCIATED PEG"}}),$self->id());
4394                            if (defined($rxnData->{PREDICTIONS})) {
4395                                    my $predictionHash;
4396                                    for (my $i=0; $i < @{$rxnData->{PREDICTIONS}};$i++) {
4397                                            my @temp = split(/:/,$rxnData->{PREDICTIONS}->[$i]);
4398                                            push(@{$predictionHash->{$temp[1]}},$temp[0]);
4399                                    }
4400                                    $reactionString .= "(";
4401                                    foreach my $key (keys(%{$predictionHash})) {
4402                                            if ($key eq "Essential =>") {
4403                                                    $reactionString .= '<span title="Essential in '.join(",",@{$predictionHash->{$key}}).'">E=></span>,';
4404                                            } elsif ($key eq "Essential <=") {
4405                                                    $reactionString .= '<span title="Essential in '.join(",",@{$predictionHash->{$key}}).'">E<=</span>,';
4406                                            } elsif ($key eq "Active =>") {
4407                                                    $reactionString .= '<span title="Active in '.join(",",@{$predictionHash->{$key}}).'">A=></span>,';
4408                                            } elsif ($key eq "Active <=") {
4409                                                    $reactionString .= '<span title="Active in '.join(",",@{$predictionHash->{$key}}).'">A<=</span>,';
4410                                            } elsif ($key eq "Active <=>") {
4411                                                    $reactionString .= '<span title="Active in '.join(",",@{$predictionHash->{$key}}).'">A</span>,';
4412                                            } elsif ($key eq "Inactive") {
4413                                                    $reactionString .= '<span title="Inactive in '.join(",",@{$predictionHash->{$key}}).'">I</span>,';
4414                                            } elsif ($key eq "Dead") {
4415                                                    $reactionString .= '<span title="Dead">D</span>,';
4416                                            }
4417                                    }
4418                                    $reactionString =~ s/,$/)/;
4419                            }
4420                            push(@{$output},$reactionString);
4421                    }
4422            }
4423    
4424            #Returning output
4425            return join("<br>",@{$output});
4426    }
4427    
4428    =head3 remove_obsolete_reactions
4429    Definition:
4430            void FIGMODELmodel->remove_obsolete_reactions();
4431    Description:
4432    =cut
4433    sub remove_obsolete_reactions {
4434            my ($self) = @_;
4435    
4436            (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"));
4437            my $rxnTbl = $self->reaction_table();
4438            if (defined($rxnTbl)) {
4439                    for (my $i=0; $i < $rxnTbl->size(); $i++) {
4440                            my $row = $rxnTbl->get_row($i);
4441                            if (defined($translation->{$row->{LOAD}->[0]}) || defined($translation->{$row->{LOAD}->[0]."r"})) {
4442                                    my $direction = $row->{DIRECTION}->[0];
4443                                    my $newRxn;
4444                                    if (defined($translation->{$row->{LOAD}->[0]."r"})) {
4445                                            $newRxn = $translation->{$row->{LOAD}->[0]."r"};
4446                                            if ($direction eq "<=") {
4447                                                    $direction = "=>";
4448                                            } elsif ($direction eq "=>") {
4449                                                    $direction = "<=";
4450                                            }
4451                                    } else {
4452                                            $newRxn = $translation->{$row->{LOAD}->[0]};
4453                                    }
4454                                    #Checking if the new reaction is already in the model
4455                                    my $newRow = $rxnTbl->get_row_by_key($newRxn,"LOAD");
4456                                    if (defined($newRow)) {
4457                                            #Handling direction
4458                                            if ($newRow->{DIRECTION}->[0] ne $direction) {
4459                                                    $newRow->{DIRECTION}->[0] = "<=>";
4460                                            }
4461                                            push(@{$row->{"ASSOCIATED PEG"}},@{$rxnTbl->get_row($i)->{"ASSOCIATED PEG"}});
4462                                    } else {
4463                                            $rxnTbl->get_row($i)->{LOAD}->[0] = $newRxn;
4464                                            $rxnTbl->get_row($i)->{DIRECTION}->[0] = $direction;
4465                                    }
4466                            }
4467                    }
4468                    $rxnTbl->save();
4469            }
4470    }
4471    
4472  1;  1;

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.19

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3