[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.5, Mon Mar 8 19:53:15 2010 UTC revision 1.25, Mon Jul 26 15:06:50 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 13  Line 13 
13          This is the constructor for the FIGMODELmodel object.          This is the constructor for the FIGMODELmodel object.
14  =cut  =cut
15  sub new {  sub new {
16          my ($class,$figmodel,$id) = @_;          my ($class,$figmodel,$id,$metagenome) = @_;
17          #Error checking first          #Error checking first
18          if (!defined($figmodel)) {          if (!defined($figmodel)) {
19                  print STDERR "FIGMODELmodel->new(undef,".$id."):figmodel must be defined to create a model object!\n";                  print STDERR "FIGMODELmodel->new(undef,".$id."):figmodel must be defined to create a model object!\n";
# Line 25  Line 25 
25                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,undef):id must be defined to create a model object");                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,undef):id must be defined to create a model object");
26                  return undef;                  return undef;
27          }          }
   
28          #Checking that the id exists          #Checking that the id exists
29          my $tbl = $self->figmodel()->database()->GetDBTable("MODELS");          if (!defined($metagenome) || $metagenome != 1) {
30          if (!defined($tbl)) {                  my $modelHandle = $self->figmodel()->database()->get_object_manager("model");
31                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not load MODELS table. Check database!");                  if (defined($modelHandle)) {
                 return undef;  
         }  
   
32          #If the id is a number, we get the model row by index          #If the id is a number, we get the model row by index
         my $index = $id;  
33          if ($id =~ m/^\d+$/) {          if ($id =~ m/^\d+$/) {
34                  $self->{_data} = $tbl->get_row($id);                                  my $objects = $modelHandle->get_objects();
35                                    if (defined($objects->[$id])) {
36                                            $self->{_data} = $objects->[$id];
37                                            $self->figmodel()->{_models}->{$id} = $self;
38                                    }
39          } else {          } else {
40                  $self->{_data} = $tbl->get_row_by_key($id,"id");                                  my $objects = $modelHandle->get_objects({id => $id});
41                  if (!defined($self->{_data})) {                                  if (defined($objects->[0])) {
42                          if ($id =~ m/(.+)(V[^V]+)/) {                                          $self->{_data} = $objects->[0];
43                                  $self->{_data} = $tbl->get_row_by_key($1,"id");                                  } elsif (!defined($objects->[0]) && $id =~ m/(.+)(V[^V]+)/) {
44                                            $objects = $modelHandle->get_objects({id => $1});
45                                            if (defined($objects->[0])) {
46                                                    $self->{_selectedversion} = $2;
47                                                    $self->{_data} = $objects->[0];
48                                            }
49                                    }
50                            }
51                    }
52                    if (defined($self->{_data})) {
53                            $self->{_modeltype} = "genome";
54                    }
55            }
56                                  if (!defined($self->{_data})) {                                  if (!defined($self->{_data})) {
57                                          $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find model ".$id." in database!");                  my $modelHandle = $self->figmodel()->database()->get_object_manager("mgmodel");
58                                          return undef;                  if (defined($modelHandle)) {
59                            #If the id is a number, we get the model row by index
60                            if ($id =~ m/^\d+$/) {
61                                    my $objects = $modelHandle->get_objects();
62                                    if (defined($objects->[$id])) {
63                                            $self->{_data} = $objects->[$id];
64                                            $self->figmodel()->{_models}->{"MG".$id} = $self;
65                                  }                                  }
                                 $self->{_selectedversion} = $2;  
66                          } else {                          } else {
67                                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find model ".$id." in database!");                                  my $objects = $modelHandle->get_objects({id => $id});
68                                  return undef;                                  if (defined($objects->[0])) {
69                                            $self->{_data} = $objects->[0];
70                                    } elsif (!defined($objects->[0]) && $id =~ m/(.+)(V[^V]+)/) {
71                                            $objects = $modelHandle->get_objects({id => $1});
72                                            if (defined($objects->[0])) {
73                                                    $self->{_selectedversion} = $2;
74                                                    $self->{_data} = $objects->[0];
75                                            }
76                          }                          }
77                  }                  }
78                  $index = $tbl->row_index($self->{_data});                  }
79                    if (defined($self->{_data})) {
80                            $self->{_modeltype} = "metagenome";
81                    }
82          }          }
83          if (!defined($self->{_data})) {          if (!defined($self->{_data})) {
84                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find specified id in database!");                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find model ".$id." in database!");
85                  return undef;                  return undef;
86          }          }
         $self->{_index} = $index;  
87          $self->figmodel()->{_models}->{$self->id()} = $self;          $self->figmodel()->{_models}->{$self->id()} = $self;
         $self->figmodel()->{_models}->{$self->index()} = $self;  
   
88          return $self;          return $self;
89  }  }
90    
# Line 118  Line 141 
141  =cut  =cut
142  sub fig {  sub fig {
143          my ($self) = @_;          my ($self) = @_;
   
144          if (!defined($self->{_fig}) && $self->source() !~ /^MGRAST/) {          if (!defined($self->{_fig}) && $self->source() !~ /^MGRAST/) {
145                  if ($self->source() =~ /^RAST/) {                  if ($self->source() =~ /^RAST/) {
146                          $self->{"_fig"} = $self->figmodel()->fig();#$self->genome());                          $self->{"_fig"} = $self->figmodel()->fig();#$self->genome());
# Line 126  Line 148 
148                          $self->{"_fig"} = $self->figmodel()->fig();                          $self->{"_fig"} = $self->figmodel()->fig();
149                  }                  }
150          }          }
   
151          return $self->{"_fig"};          return $self->{"_fig"};
152  }  }
153    
154    =head3 aquireModelLock
155    
156    Definition:
157    
158            FIGMODELmodel->aquireModelLock();
159    
160    Description:
161    
162            Locks the database for alterations relating to the current model object
163    
164    =cut
165    sub aquireModelLock {
166            my ($self) = @_;
167            $self->figmodel()->database()->genericLock($self->id());
168    }
169    
170    =head3 releaseModelLock
171    
172    Definition:
173    
174            FIGMODELmodel->releaseModelLock();
175    
176    Description:
177    
178            Unlocks the database for alterations relating to the current model object
179    
180    =cut
181    sub releaseModelLock {
182            my ($self) = @_;
183            $self->figmodel()->database()->genericUnlock($self->id());
184    }
185    
186  =head3 mgdata  =head3 mgdata
187  Definition:  Definition:
188          FIGMODEL = FIGMODELmodel->mgdata();          FIGMODEL = FIGMODELmodel->mgdata();
# Line 138  Line 191 
191  =cut  =cut
192  sub mgdata {  sub mgdata {
193          my ($self) = @_;          my ($self) = @_;
194            if (!defined($self->{_mgdata})) {
195          if (!defined($self->{_mgdata}) && $self->source() =~ /^MGRAST/) {                  my $mgrastdbhandle = $self->figmodel()->database()->get_object_manager("mgjob");
196                  require MGRAST;                  my $objects = $mgrastdbhandle->get_objects( { 'genome_id' => $self->genome() } );
197                  $self->{_mgdata} = $self->figmodel()->mgrast()->Job->get_objects( { 'genome_id' => $self->genome() } )                  $self->{_mgdata} = $objects->[0];
198          }          }
   
199          return $self->{_mgdata};          return $self->{_mgdata};
200  }  }
201    
# Line 155  Line 207 
207  =cut  =cut
208  sub id {  sub id {
209          my ($self) = @_;          my ($self) = @_;
210          return $self->{_data}->{id}->[0];          return $self->{_data}->id();
211  }  }
212    
213  =head3 owner  =head3 get_model_type
214  Definition:  Definition:
215          string = FIGMODELmodel->owner();          string = FIGMODELmodel->get_model_type();
216  Description:  Description:
217          Returns the username for the model owner          Returns the type of the model
218  =cut  =cut
219  sub owner {  sub get_model_type {
220          my ($self) = @_;          my ($self) = @_;
221          return $self->{_data}->{owner}->[0];          return $self->{_modeltype};
222  }  }
223    
224  =head3 index  =head3 owner
225  Definition:  Definition:
226          string = FIGMODELmodel->index();          string = FIGMODELmodel->owner();
227  Description:  Description:
228          Returns model index          Returns the username for the model owner
229  =cut  =cut
230  sub index {  sub owner {
231          my ($self) = @_;          my ($self) = @_;
232          return $self->{_index};          return $self->{_data}->owner();
233  }  }
234    
235  =head3 name  =head3 name
# Line 196  Line 248 
248                          if (defined($self->mgdata())) {                          if (defined($self->mgdata())) {
249                                  $self->{_name} = $self->mgdata()->genome_name;                                  $self->{_name} = $self->mgdata()->genome_name;
250                          }                          }
                 } elsif (defined($self->stats())) {  
                         $self->{_name} = $self->stats()->{'Organism name'}->[0];  
251                  } elsif ($source !~ /^RAST/) {                  } elsif ($source !~ /^RAST/) {
252                          $self->{_name} = $self->fig()->orgname_of_orgid($self->genome());                          $self->{_name} = $self->fig()->orgname_of_orgid($self->genome());
253                    } else {
254                            $self->{_name} = $self->figmodel()->get_genome_stats($self->genome())->{NAME}->[0];
255                  }                  }
256          }          }
257    
258          return $self->{_name};          return $self->{_name};
259  }  }
260    
 =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};  
 }  
   
261  =head3 get_reaction_class  =head3 get_reaction_class
262  Definition:  Definition:
263          string = FIGMODELmodel->get_reaction_class(string::reaction ID);          string = FIGMODELmodel->get_reaction_class(string::reaction ID);
# Line 228  Line 265 
265          Returns reaction class          Returns reaction class
266  =cut  =cut
267  sub get_reaction_class {  sub get_reaction_class {
268          my ($self,$reaction,$nohtml) = @_;          my ($self,$reaction,$nohtml,$brief_flux) = @_;
269    
270          if (!-e $self->directory()."ReactionClassification-".$self->id().".tbl") {          if (!-e $self->directory()."ReactionClassification-".$self->id().".tbl") {
271                  if (!defined($self->{_reaction_classes})) {                  if (!defined($self->{_reaction_classes})) {
# Line 241  Line 278 
278                  my $ClassRow = $self->{_reaction_classes}->get_row_by_key($reaction,"REACTION");                  my $ClassRow = $self->{_reaction_classes}->get_row_by_key($reaction,"REACTION");
279                  if (defined($ClassRow) && defined($ClassRow->{CLASS})) {                  if (defined($ClassRow) && defined($ClassRow->{CLASS})) {
280                          my $class;                          my $class;
281                            my $min = $ClassRow->{MIN}->[0];
282                            my $max = $ClassRow->{MAX}->[0];
283                          if ($ClassRow->{CLASS}->[0] eq "Positive") {                          if ($ClassRow->{CLASS}->[0] eq "Positive") {
284                                  $class = "Essential =>";                                  $class = "Essential =>";
285                                    $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
286                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative") {
287                                  $class = "Essential <=";                                  $class = "Essential <=";
288                                    $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$max)." to ".sprintf("%.3g",$min)."]<br>" : $class.="<br>[Flux: ".$max." to ".$min."]<br>";
289                          } elsif ($ClassRow->{CLASS}->[0] eq "Positive variable") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Positive variable") {
290                                  $class = "Active =>";                                  $class = "Active =>";
291                                    $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
292                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative variable") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative variable") {
293                                  $class = "Active <=";                                  $class = "Active <=";
294                                    $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$max)." to ".sprintf("%.3g",$min)."]<br>" : $class.="<br>[Flux: ".$max." to ".$min."]<br>";
295                          } elsif ($ClassRow->{CLASS}->[0] eq "Variable") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Variable") {
296                                  $class = "Active <=>";                                  $class = "Active <=>";
297                                    $brief_flux ? $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>" : $class.="<br>[Flux: ".$min." to ".$max."]<br>";
298                          } elsif ($ClassRow->{CLASS}->[0] eq "Blocked") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Blocked") {
299                                  $class = "Inactive";                                  $class = "Inactive";
300                          } elsif ($ClassRow->{CLASS}->[0] eq "Dead") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Dead") {
301                                  $class = "Disconnected";                                  $class = "Disconnected";
302                          }                          }
303    
304                          if (!defined($nohtml) || $nohtml ne "1") {                          if (!defined($nohtml) || $nohtml ne "1") {
305                                  $class = "<span title=\"Flux:".$ClassRow->{MIN}->[0]." to ".$ClassRow->{MAX}->[0]."\">".$class."</span>";                                  $class = "<span title=\"Flux:".$min." to ".$max."\">".$class."</span>";
306                          }                          }
307    
308                          return $class;                          return $class;
309                  }                  }
310                  return undef;                  return undef;
# Line 279  Line 325 
325                                  $classstring .= "<br>";                                  $classstring .= "<br>";
326                          }                          }
327                          my $NewClass;                          my $NewClass;
328                            my $min = $ClassRow->{MIN}->[$i];
329                            my $max = $ClassRow->{MAX}->[$i];
330                          if ($ClassRow->{CLASS}->[$i] eq "Positive") {                          if ($ClassRow->{CLASS}->[$i] eq "Positive") {
331                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential =>";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential =>";
332                                  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>";  
                                 }  
333                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative") {
334                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential <=";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential <=";
335                                  if (!defined($nohtml) || $nohtml ne "1") {                                  $brief_flux ? $NewClass.="<br>[Flux: ".sprintf("%.3g",$max)." to ".sprintf("%.3g",$min)."]<br>" : $NewClass.="<br>[Flux: ".$max." to ".$min."]<br>";
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
336                          } elsif ($ClassRow->{CLASS}->[$i] eq "Positive variable") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Positive variable") {
337                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active =>";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active =>";
338                                  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>";  
                                 }  
339                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative variable") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative variable") {
340                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=";
341                                  if (!defined($nohtml) || $nohtml ne "1") {                                  $brief_flux ? $NewClass.="<br>[Flux: ".sprintf("%.3g",$max)." to ".sprintf("%.3g",$min)."]<br>" : $NewClass.="<br>[Flux: ".$max." to ".$min."]<br>";
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
342                          } elsif ($ClassRow->{CLASS}->[$i] eq "Variable") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Variable") {
343                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=>";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=>";
344                                  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>";  
                                 }  
345                          } elsif ($ClassRow->{CLASS}->[$i] eq "Blocked") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Blocked") {
346                                  $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>";  
                                 }  
347                          } elsif ($ClassRow->{CLASS}->[$i] eq "Dead") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Dead") {
348                                  $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>";  
349                                  }                                  }
350    
351                            if (!defined($nohtml) || $nohtml ne "1") {
352                                    $NewClass = "<span title=\"Flux:".$min." to ".$max."\">".$NewClass."</span>";
353                          }                          }
354                          $classstring .= $NewClass;                          $classstring .= $NewClass;
355                  }                  }
# Line 332  Line 368 
368    
369          if (!defined($self->{_biomass})) {          if (!defined($self->{_biomass})) {
370                  my $rxntbl = $self->reaction_table();                  my $rxntbl = $self->reaction_table();
371                    if (defined($rxntbl)) {
372                  for (my $i=0; $i < $rxntbl->size(); $i++) {                  for (my $i=0; $i < $rxntbl->size(); $i++) {
373                          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/) {
374                                  $self->{_biomass} = $rxntbl->get_row($i)->{"LOAD"}->[0];                                  $self->{_biomass} = $rxntbl->get_row($i)->{"LOAD"}->[0];
# Line 339  Line 376 
376                          }                          }
377                  }                  }
378          }          }
379            }
380    
381          return $self->get_reaction_data($self->{_biomass});          return $self->get_reaction_data($self->{_biomass});
382  }  }
# Line 351  Line 389 
389  =cut  =cut
390  sub get_reaction_data {  sub get_reaction_data {
391          my ($self,$reaction) = @_;          my ($self,$reaction) = @_;
   
392          if (!defined($self->reaction_table())) {          if (!defined($self->reaction_table())) {
393                  return undef;                  return undef;
394          }          }
395          if ($reaction =~ m/^\d+$/) {          if ($reaction =~ m/^\d+$/) {
396                  $self->reaction_table()->get_row($reaction);                  return $self->reaction_table()->get_row($reaction);
397          }          }
398          return $self->reaction_table()->get_row_by_key($reaction,"LOAD");          return $self->reaction_table()->get_row_by_key($reaction,"LOAD");
399  }  }
# Line 377  Line 414 
414          return $Data->{LOAD}->[0];          return $Data->{LOAD}->[0];
415  }  }
416    
417    =head3 load_model_table
418    
419    Definition: FIGMODELTable = FIGMODELmodel->load_model_table(string:table name,0/1:refresh the table));
420    
421    Description: Returns the table specified by the input filename. Table will be stored in a file in the model directory.
422    
423    =cut
424    sub load_model_table {
425            my ($self,$name,$refresh) = @_;
426            if (defined($refresh) && $refresh == 1) {
427                    delete $self->{"_".$name};
428            }
429            if (!defined($self->{"_".$name})) {
430                    my $tbldef = $self->figmodel()->config($name);
431                    if (!defined($tbldef)) {
432                            return undef;
433                    }
434                    my $itemDelim = "|";
435                    if (defined($tbldef->{itemdelimiter}->[0])) {
436                            $itemDelim = $tbldef->{itemdelimiter}->[0];
437                            if ($itemDelim eq "SC") {
438                                    $itemDelim = ";";
439                            }
440                    }
441                    my $columnDelim = "\t";
442                    if (defined($tbldef->{columndelimiter}->[0])) {
443                            $columnDelim = $tbldef->{columndelimiter}->[0];
444                            if ($columnDelim eq "SC") {
445                                    $columnDelim = ";";
446                            }
447                    }
448                    my $suffix = ".tbl";
449                    if (defined($tbldef->{filename_suffix}->[0])) {
450                            $suffix = $tbldef->{filename_suffix}->[0];
451                    }
452                    my $filename = $self->directory().$name."-".$self->id().$self->selected_version().$suffix;
453                    if (defined($tbldef->{filename_prefix}->[0])) {
454                            if ($tbldef->{filename_prefix}->[0] eq "NONE") {
455                                    $filename = $self->directory().$self->id().$self->selected_version().$suffix;
456                            } else {
457                                    $filename = $self->directory().$tbldef->{filename_prefix}->[0]."-".$self->id().$self->selected_version().$suffix;
458                            }
459                    }
460                    if (-e $filename) {
461                            $self->{"_".$name} = $self->figmodel()->database()->load_table($filename,$columnDelim,$itemDelim,$tbldef->{headingline}->[0],$tbldef->{hashcolumns});
462                    } else {
463                            if (defined($tbldef->{prefix})) {
464                                    $self->{"_".$name} = FIGMODELTable->new($tbldef->{columns},$filename,$tbldef->{hashcolumns},$columnDelim,$itemDelim,join(@{$tbldef->{prefix}},"\n"));
465                            } else {
466                                    $self->{"_".$name} = FIGMODELTable->new($tbldef->{columns},$filename,$tbldef->{hashcolumns},$columnDelim,$itemDelim);
467                            }
468                    }
469            }
470            return $self->{"_".$name};
471    }
472    
473    =head3 create_table_prototype
474    
475    Definition:
476            FIGMODELTable::table = FIGMODELmodel->create_table_prototype(string::table);
477    Description:
478            Returns a empty FIGMODELTable with all the metadata associated with the input table name
479    
480    =cut
481    sub create_table_prototype {
482            my ($self,$TableName) = @_;
483            #Checking if the table definition exists in the FIGMODELconfig file
484            my $tbldef = $self->figmodel()->config($TableName);
485            if (!defined($tbldef)) {
486                    $self->figmodel()->error_message("FIGMODELdatabase:create_table_prototype:Definition not found for ".$TableName);
487                    return undef;
488            }
489            #Checking that this is a database table
490            if (!defined($tbldef->{tabletype}) || $tbldef->{tabletype}->[0] ne "ModelTable") {
491                    $self->figmodel()->error_message("FIGMODELdatabase:create_table_prototype:".$TableName." is not a model table!");
492                    return undef;
493            }
494            #Setting default values for table parameters
495            my $prefix;
496            if (defined($tbldef->{prefix})) {
497                    $prefix = join("\n",@{$self->config($TableName)->{prefix}})."\n";
498            }
499            my $itemDelim = "|";
500            if (defined($tbldef->{itemdelimiter}->[0])) {
501                    $itemDelim = $tbldef->{itemdelimiter}->[0];
502                    if ($itemDelim eq "SC") {
503                            $itemDelim = ";";
504                    }
505            }
506            my $columnDelim = "\t";
507            if (defined($tbldef->{columndelimiter}->[0])) {
508                    $columnDelim = $tbldef->{columndelimiter}->[0];
509                    if ($columnDelim eq "SC") {
510                            $columnDelim = ";";
511                    }
512            }
513            my $suffix = ".tbl";
514            if (defined($tbldef->{filename_suffix}->[0])) {
515                    $suffix = $tbldef->{filename_suffix}->[0];
516            }
517            my $filename = $self->directory().$TableName."-".$self->id().$self->selected_version().$suffix;
518            if (defined($tbldef->{filename_prefix}->[0])) {
519                    if ($tbldef->{filename_prefix}->[0] eq "NONE") {
520                            $filename = $self->directory().$self->id().$self->selected_version().$suffix;
521                    } else {
522                            $filename = $self->directory().$tbldef->{filename_prefix}->[0]."-".$self->id().$self->selected_version().$suffix;
523                    }
524            }
525            #Creating the table prototype
526            my $tbl = FIGMODELTable->new($tbldef->{columns},$filename,$tbldef->{hashcolumns},$columnDelim,$itemDelim,$prefix);
527            return $tbl;
528    }
529    
530  =head3 get_reaction_number  =head3 get_reaction_number
531  Definition:  Definition:
532          int = FIGMODELmodel->get_reaction_number();          int = FIGMODELmodel->get_reaction_number();
# Line 385  Line 535 
535  =cut  =cut
536  sub get_reaction_number {  sub get_reaction_number {
537          my ($self) = @_;          my ($self) = @_;
   
538          if (!defined($self->reaction_table())) {          if (!defined($self->reaction_table())) {
539                  return 0;                  return 0;
540          }          }
   
541          return $self->reaction_table()->size();          return $self->reaction_table()->size();
542  }  }
543    
# Line 400  Line 548 
548          Returns FIGMODELTable with the reaction list for the model          Returns FIGMODELTable with the reaction list for the model
549  =cut  =cut
550  sub reaction_table {  sub reaction_table {
551          my ($self) = @_;          my ($self,$clear) = @_;
552            if (defined($clear) && $clear == 1) {
553                    delete $self->{_reaction_table};
554            }
555            if (!defined($self->{_reaction_table})) {
556                    $self->{_reaction_table} = $self->load_model_table("ModelReactions",$clear);
557                    my $classTbl = $self->reaction_class_table();
558                    if (defined($classTbl)) {
559                            for (my $i=0; $i < $classTbl->size(); $i++) {
560                                    my $row = $classTbl->get_row($i);
561                                    if (defined($row->{REACTION})) {
562                                            my $rxnRow = $self->{_reaction_table}->get_row_by_key($row->{"REACTION"}->[0],"LOAD");
563                                            if (defined($row->{MEDIA})) {
564                                                    for (my $j=0; $j < @{$row->{MEDIA}};$j++) {
565                                                            my $class = "Active <=>";
566                                                            if ($row->{CLASS}->[$j] eq "Positive") {
567                                                                    $class = "Essential =>";
568                                                            } elsif ($row->{CLASS}->[$j] eq "Negative") {
569                                                                    $class = "Essential <=";
570                                                            } elsif ($row->{CLASS}->[$j] eq "Blocked") {
571                                                                    $class = "Inactive";
572                                                            } elsif ($row->{CLASS}->[$j] eq "Positive variable") {
573                                                                    $class = "Active =>";
574                                                            } elsif ($row->{CLASS}->[$j] eq "Negative variable") {
575                                                                    $class = "Active <=";
576                                                            } elsif ($row->{CLASS}->[$j] eq "Variable") {
577                                                                    $class = "Active <=>";
578                                                            } elsif ($row->{CLASS}->[$j] eq "Dead") {
579                                                                    $class = "Dead";
580                                                            }
581                                                            push(@{$rxnRow->{PREDICTIONS}},$row->{MEDIA}->[$j].":".$class);
582                                                    }
583                                            }
584                                    }
585                            }
586                    }
587            }
588            return $self->{_reaction_table};
589    }
590    
591          if (!defined($self->{_reaction_data})) {  =head3 essentials_table
592                  $self->{_reaction_data} = $self->figmodel()->database()->GetDBModel($self->id());  Definition:
593            FIGMODELTable = FIGMODELmodel->essentials_table();
594    Description:
595            Returns FIGMODELTable with the essential genes for the model
596    =cut
597    sub essentials_table {
598            my ($self,$clear) = @_;
599            my $tbl = $self->load_model_table("ModelEssentialGenes",$clear);
600            return $tbl;
601          }          }
602    
603          return $self->{_reaction_data};  =head3 model_history
604    Definition:
605            FIGMODELTable = FIGMODELmodel->model_history();
606    Description:
607            Returns FIGMODELTable with the history of model changes
608    =cut
609    sub model_history {
610            my ($self,$clear) = @_;
611            return $self->load_model_table("ModelHistory",$clear);
612  }  }
613    
614  =head3 reaction_class_table  =head3 feature_table
615  Definition:  Definition:
616          FIGMODELTable = FIGMODELmodel->reaction_class_table();          FIGMODELTable = FIGMODELmodel->feature_table();
617  Description:  Description:
618          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
619  =cut  =cut
620  sub reaction_class_table {  sub feature_table {
621          my ($self) = @_;          my ($self) = @_;
622    
623          if (!defined($self->{_reaction_class_table})) {          if (!defined($self->{_feature_data})) {
624                  if (-e $self->directory()."ReactionClassification-".$self->id().$self->selected_version().".tbl") {                  #Getting the genome feature list
625                          $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());
626                    if (!defined($FeatureTable)) {
627                            print STDERR "FIGMODELmodel:feature_table:Could not get features for genome ".$self->genome()." in database!";
628                            return undef;
629                    }
630                    #Getting the reaction table for the model
631                    my $rxnTable = $self->reaction_table();
632                    if (!defined($rxnTable)) {
633                            print STDERR "FIGMODELmodel:feature_table:Could not get reaction table for model ".$self->id()." in database!";
634                            return undef;
635                    }
636                    #Cloning the feature table
637                    $self->{_feature_data} = $FeatureTable->clone_table_def();
638                    $self->{_feature_data}->add_headings(($self->id()."REACTIONS",$self->id()."PREDICTIONS"));
639                    for (my $i=0; $i < $rxnTable->size(); $i++) {
640                            my $Row = $rxnTable->get_row($i);
641                            if (defined($Row) && defined($Row->{"ASSOCIATED PEG"})) {
642                                    foreach my $GeneSet (@{$Row->{"ASSOCIATED PEG"}}) {
643                                            my $temp = $GeneSet;
644                                            $temp =~ s/\+/|/g;
645                                            $temp =~ s/\sAND\s/|/gi;
646                                            $temp =~ s/\sOR\s/|/gi;
647                                            $temp =~ s/[\(\)\s]//g;
648                                            my @GeneList = split(/\|/,$temp);
649                                            foreach my $Gene (@GeneList) {
650                                                    my $FeatureRow = $self->{_feature_data}->get_row_by_key("fig|".$self->genome().".".$Gene,"ID");
651                                                    if (!defined($FeatureRow)) {
652                                                            $FeatureRow = $FeatureTable->get_row_by_key("fig|".$self->genome().".".$Gene,"ID");
653                                                            if (defined($FeatureRow)) {
654                                                                    $self->{_feature_data}->add_row($FeatureRow);
655                                                            }
656                                                    }
657                                                    if (defined($FeatureRow)) {
658                                                            $self->{_feature_data}->add_data($FeatureRow,$self->id()."REACTIONS",$Row->{"LOAD"}->[0],1);
659                                                    }
660                                            }
661                                    }
662                            }
663                    }
664                    #Loading predictions
665                    my $esstbl = $self->essentials_table();
666                    for (my $i=0; $i < $self->{_feature_data}->size(); $i++) {
667                            my $Row = $self->{_feature_data}->get_row($i);
668                            if ($Row->{ID}->[0] =~ m/(peg\.\d+)/) {
669                                    my $gene = $1;
670                                    my @rows = $esstbl->get_rows_by_key($gene,"ESSENTIAL GENES");
671                                    my $mediahash;
672                                    for (my $j=0; $j < $esstbl->size(); $j++) {
673                                            $mediahash->{$esstbl->get_row($j)->{MEDIA}->[0]} = 0;
674                                    }
675                                    for (my $j=0; $j < @rows; $j++) {
676                                            $mediahash->{$rows[$j]->{MEDIA}->[0]} = 1;
677                                    }
678                                    my @mediaList = keys(%{$mediahash});
679                                    for (my $j=0; $j < @mediaList; $j++) {
680                                            if ($mediahash->{$mediaList[$j]} == 1) {
681                                                    push(@{$Row->{$self->id()."PREDICTIONS"}},$mediaList[$j].":essential");
682                  } else {                  } else {
683                          $self->{_reaction_class_table} = FIGMODELTable->new(["REACTION","MEDIA","CLASS","MIN","MAX"],$self->directory()."ReactionClassification-".$self->id().$self->selected_version().".tbl",["REACTION","CLASS","MEDIA"],";","|",undef);                                                  push(@{$Row->{$self->id()."PREDICTIONS"}},$mediaList[$j].":nonessential");
684                  }                  }
685          }          }
686                            }
687                    }
688            }
689            return $self->{_feature_data};
690    }
691    
692          return $self->{_reaction_class_table};  =head3 reaction_class_table
693    Definition:
694            FIGMODELTable = FIGMODELmodel->reaction_class_table();
695    Description:
696            Returns FIGMODELTable with the reaction class data, and creates the table file  if it does not exist
697    =cut
698    sub reaction_class_table {
699            my ($self,$clear) = @_;
700            return $self->load_model_table("ModelReactionClasses",$clear);
701  }  }
702    
703  =head3 compound_class_table  =head3 compound_class_table
# Line 436  Line 707 
707          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
708  =cut  =cut
709  sub compound_class_table {  sub compound_class_table {
710          my ($self) = @_;          my ($self,$clear) = @_;
711            return $self->load_model_table("ModelCompoundClasses",$clear);
         if (!defined($self->{_compound_class_table})) {  
                 if (-e $self->directory()."CompoundClassification-".$self->id().$self->selected_version().".tbl") {  
                         $self->{_compound_class_table} = $self->figmodel()->database()->load_table($self->directory()."CompoundClassification-".$self->id().$self->selected_version().".tbl",";","|",0,["COMPOUND","CLASS","MEDIA"]);  
                 } else {  
                         $self->{_compound_class_table} = FIGMODELTable->new(["COMPOUND","MEDIA","CLASS","MIN","MAX"],$self->directory()."CompoundClassification-".$self->id().$self->selected_version().".tbl",["COMPOUND","CLASS","MEDIA"],";","|",undef);  
                 }  
         }  
   
         return $self->{_compound_class_table};  
712  }  }
713    
714  =head3 get_essential_genes  =head3 get_essential_genes
# Line 457  Line 719 
719  =cut  =cut
720  sub get_essential_genes {  sub get_essential_genes {
721          my ($self,$media) = @_;          my ($self,$media) = @_;
722            my $tbl = $self->essentials_table();
723          if (!defined($media)) {          my $row = $tbl->get_row_by_key($media,"MEDIA");
724                  $media = "Complete";          if (defined($row)) {
725          }                  return $row->{"ESSENTIAL GENES"};
         if (!defined($self->{_essential_genes}->{$media})) {  
                 $self->{_essential_genes}->{$media} = undef;  
                 if (-e $self->directory()."EssentialGenes-".$self->id().$self->selected_version()."-".$media.".tbl") {  
                         $self->{_essential_genes}->{$media} = $self->figmodel()->database()->load_single_column_file($self->directory()."EssentialGenes-".$self->id().$self->selected_version()."-".$media.".tbl","");  
                 }  
726          }          }
727            return undef;
         return $self->{_essential_genes}->{$media};  
728  }  }
729    
730  =head3 compound_table  =head3 compound_table
# Line 481  Line 737 
737          my ($self) = @_;          my ($self) = @_;
738    
739          if (!defined($self->{_compound_table})) {          if (!defined($self->{_compound_table})) {
740                  $self->{_compound_table} = $self->figmodel()->database()->GetDBModelCompounds($self->id());                  $self->{_compound_table} = $self->create_table_prototype("ModelCompounds");
741                    #Loading the reactions
742                    my $ReactionTable = $self->figmodel()->database()->get_table("REACTIONS");
743                    my $BiomassTable = $self->figmodel()->database()->get_table("BIOMASS");
744                    #Loading the model
745                    my $ModelTable = $self->reaction_table();
746                    #Checking that the tables were loaded
747                    if (!defined($ModelTable) || !defined($ReactionTable)) {
748                            return undef;
749                    }
750                    #Finding the biomass reaction
751                    for (my $i=0; $i < $ModelTable->size(); $i++) {
752                            my $ID = $ModelTable->get_row($i)->{"LOAD"}->[0];
753                            my $Row = $ReactionTable->get_row_by_key($ID,"DATABASE");
754                            my $IsBiomass = 0;
755                            if (!defined($Row)) {
756                                    $Row = $BiomassTable->get_row_by_key($ID,"DATABASE");
757                                    $IsBiomass = 1;
758                            }
759                            if (defined($Row->{"EQUATION"}->[0])) {
760                                    $_ = $Row->{"EQUATION"}->[0];
761                                    my @OriginalArray = /(cpd\d\d\d\d\d[\[\w]*)/g;
762                                    foreach my $Compound (@OriginalArray) {
763                                            my $ID = substr($Compound,0,8);
764                                            my $NewRow = $self->{_compound_table}->get_row_by_key($ID,"DATABASE",1);
765                                            if ($IsBiomass == 1) {
766                                                    $self->{_compound_table}->add_data($NewRow,"BIOMASS",$Row->{"DATABASE"}->[0],1);
767                                            }
768                                            if (length($Compound) > 8) {
769                                                    #print $Compound."\t".$Row->{"EQUATION"}->[0]."\t".$Row->{"DATABASE"}->[0]."\n";
770                                                    my $Compartment = substr($Compound,8,1);
771                                                    $self->{_compound_table}->add_data($NewRow,"COMPARTMENTS",$Compartment,1);
772                                                    $self->{_compound_table}->add_data($NewRow,"TRANSPORTERS",$Row->{"DATABASE"}->[0],1);
773                                            }
774                                    }
775                            }
776                    }
777          }          }
778    
779          return $self->{_compound_table};          return $self->{_compound_table};
# Line 489  Line 781 
781    
782  =head3 get_compound_data  =head3 get_compound_data
783  Definition:  Definition:
784          string = FIGMODELmodel->get_compound_data(string::compound ID);          {string:key=>[string]:values} = FIGMODELmodel->get_compound_data(string::compound ID);
785  Description:  Description:
786          Returns model compound data          Returns model compound data
787  =cut  =cut
# Line 500  Line 792 
792                  return undef;                  return undef;
793          }          }
794          if ($compound =~ m/^\d+$/) {          if ($compound =~ m/^\d+$/) {
795                  $self->compound_table()->get_row($compound);                  return $self->compound_table()->get_row($compound);
796          }          }
797          return $self->compound_table()->get_row_by_key($compound,"DATABASE");          return $self->compound_table()->get_row_by_key($compound,"DATABASE");
798  }  }
799    
800    =head3 get_feature_data
801    Definition:
802            {string:key=>[string]:values} = FIGMODELmodel->get_feature_data(string::feature ID);
803    Description:
804            Returns model feature data
805    =cut
806    sub get_feature_data {
807            my ($self,$feature) = @_;
808            if (!defined($self->feature_table())) {
809                    return undef;
810            }
811            if ($feature =~ m/^\d+$/) {
812                    return $self->feature_table()->get_row($feature);
813            }
814            if ($feature =~ m/(peg\.\d+)/) {
815                    $feature = $1;
816            }
817            return $self->feature_table()->get_row_by_key("fig|".$self->genome().".".$feature,"ID");
818    }
819    
820  =head3 genome  =head3 genome
821  Definition:  Definition:
822          string = FIGMODELmodel->genome();          string = FIGMODELmodel->genome();
# Line 513  Line 825 
825  =cut  =cut
826  sub genome {  sub genome {
827          my ($self) = @_;          my ($self) = @_;
828          return $self->{_data}->{genome}->[0];          return $self->{_data}->genome();
829  }  }
830    
831  =head3 source  =head3 source
# Line 524  Line 836 
836  =cut  =cut
837  sub source {  sub source {
838          my ($self) = @_;          my ($self) = @_;
839          return $self->{_data}->{source}->[0];          return $self->{_data}->source();
840  }  }
841    
842  =head3 rights  =head3 rights
# Line 535  Line 847 
847  =cut  =cut
848  sub rights {  sub rights {
849          my ($self,$username) = @_;          my ($self,$username) = @_;
   
850          if ($self->public()) {          if ($self->public()) {
851                  return 1;                  return 1;
852          }          }
# Line 543  Line 854 
854                  return 0;                  return 0;
855          }          }
856          if (!defined($self->{_userrights}->{$username})) {          if (!defined($self->{_userrights}->{$username})) {
857                  if (defined($self->{_data}->{master})) {                  $self->{_userrights}->{$self->{_data}->owner()} = 1;
858                          for (my $i=0; $i < @{$self->{_data}->{master}};$i++) {                  my @users = split(/\|/,$self->{_data}->users());
859                                  $self->{_userrights}->{$self->{_data}->{master}->[$i]} = 1;                  for (my $i=0; $i < @users;$i++) {
860                          }                          $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;  
                         }  
861                  }                  }
862          }          }
863          return $self->{_userrights}->{$username};          return $self->{_userrights}->{$username};
# Line 565  Line 871 
871  =cut  =cut
872  sub public {  sub public {
873          my ($self) = @_;          my ($self) = @_;
874            if ($self->{_data}->users() eq "all") {
875          if (!defined($self->{_public})) {                  return 1;
                 $self->{_public} = 0;  
                 if (defined($self->{_data}->{users}->[0]) && $self->{_data}->{users}->[0] eq "all") {  
                         $self->{_public} = 1;  
                 }  
876          }          }
877          return $self->{_public};          return 0;
878  }  }
879    
880  =head3 directory  =head3 directory
# Line 591  Line 893 
893                  }                  }
894                  my $source = $self->source();                  my $source = $self->source();
895                  if ($source =~ /^MGRAST/) {                  if ($source =~ /^MGRAST/) {
896                          $self->{_directory} = $self->figmodel()->config("organism directory")->[0].$userdirectory.$self->genome()."/";                          $self->{_directory} = $self->figmodel()->config("mgrast model directory")->[0].$userdirectory.$self->genome()."/";
897                  } elsif ($source =~ /^RAST/) {                  } elsif ($source =~ /^RAST/) {
898                          $self->{_directory} = $self->figmodel()->config("organism directory")->[0].$userdirectory.$self->genome()."/";                          $self->{_directory} = $self->figmodel()->config("organism directory")->[0].$userdirectory.$self->genome()."/";
899                  } elsif ($source =~ /^SEED/) {                  } elsif ($source =~ /^SEED/) {
# Line 620  Line 922 
922          return $self->directory().$self->id().$self->selected_version().".txt";          return $self->directory().$self->id().$self->selected_version().".txt";
923  }  }
924    
 =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};  
         }  
 }  
   
925  =head3 version  =head3 version
926  Definition:  Definition:
927          string = FIGMODELmodel->version();          string = FIGMODELmodel->version();
# Line 671  Line 933 
933    
934          if (!defined($self->{_version})) {          if (!defined($self->{_version})) {
935                  if (!defined($self->{_selectedversion})) {                  if (!defined($self->{_selectedversion})) {
936                          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];  
                         }  
937                  } else {                  } else {
938                          $self->{_version} = $self->{_selectedversion};                          $self->{_version} = $self->{_selectedversion};
939                  }                  }
# Line 704  Line 964 
964  =cut  =cut
965  sub modification_time {  sub modification_time {
966          my ($self) = @_;          my ($self) = @_;
967          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};  
968  }  }
969    
970  =head3 gene_reactions  =head3 gene_reactions
# Line 728  Line 975 
975  =cut  =cut
976  sub gene_reactions {  sub gene_reactions {
977          my ($self) = @_;          my ($self) = @_;
978            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};  
979  }  }
980    
981  =head3 total_compounds  =head3 total_compounds
# Line 747  Line 986 
986  =cut  =cut
987  sub total_compounds {  sub total_compounds {
988          my ($self) = @_;          my ($self) = @_;
989            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};  
990  }  }
991    
992  =head3 gapfilling_reactions  =head3 gapfilling_reactions
# Line 766  Line 997 
997  =cut  =cut
998  sub gapfilling_reactions {  sub gapfilling_reactions {
999          my ($self) = @_;          my ($self) = @_;
1000            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};  
1001  }  }
1002    
1003  =head3 total_reactions  =head3 total_reactions
# Line 785  Line 1008 
1008  =cut  =cut
1009  sub total_reactions {  sub total_reactions {
1010          my ($self) = @_;          my ($self) = @_;
1011            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};  
1012  }  }
1013    
1014  =head3 model_genes  =head3 model_genes
# Line 804  Line 1019 
1019  =cut  =cut
1020  sub model_genes {  sub model_genes {
1021          my ($self) = @_;          my ($self) = @_;
1022            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};  
1023  }  }
1024    
1025  =head3 class  =head3 class
# Line 823  Line 1030 
1030  =cut  =cut
1031  sub class {  sub class {
1032          my ($self) = @_;          my ($self) = @_;
1033            return $self->{_data}->cellwalltype();
1034    }
1035    
1036          if (!defined($self->{_class})) {  sub autocompleteMedia {
1037                  if ($self->source() =~ /^MGRAST/) {          my ($self,$newMedia) = @_;
1038                          $self->{_class} = "Other";          if (defined($newMedia)) {
1039                  } elsif (defined($self->stats())) {                  return $self->{_data}->autoCompleteMedia($newMedia);
1040                          $self->{_class} = $self->stats()->{Class}->[0];          }
1041            return $self->{_data}->autoCompleteMedia();
1042    }
1043    
1044    sub biomassReaction {
1045            my ($self,$newBiomass) = @_;
1046            if (!defined($newBiomass)) {
1047                    return $self->{_data}->biomassReaction();
1048            } else {
1049                    #Figuring out what the old biomass is
1050                    my $oldBiomass = $self->{_data}->biomassReaction();
1051                    if ($newBiomass ne $oldBiomass) {
1052                            #Figuring out if the new biomass exists
1053                            my $handle = $self->database()->get_object_manager("bof");
1054                            my $objects = $handle->get_objects({"DATABASE" => [$newBiomass]});
1055                            if (!defined($objects) || !defined($objects->[0])) {
1056                                    print STDERR "Could not find new biomass reaction ".$newBiomass."\n";
1057                                    return $oldBiomass;
1058                            }
1059                            #Changing the biomass reaction in the model file
1060                            my $rxnTbl = $self->reaction_table();
1061                            for (my $i=0; $i < $rxnTbl->size(); $i++) {
1062                                    my $row = $rxnTbl->get_row($i);
1063                                    if ($row->{LOAD}->[0] =~ m/^bio/) {
1064                                            $row->{LOAD}->[0] = $newBiomass;
1065                                    }
1066                            }
1067                            $rxnTbl->save();
1068                            #Changing the biomass reaction in the database
1069                            return  $self->{_data}->biomassReaction($newBiomass);
1070                  }                  }
1071          }          }
         return $self->{_class};  
1072  }  }
1073    
1074  =head3 taxonomy  =head3 taxonomy
# Line 899  Line 1136 
1136                          if (defined($self->mgdata())) {                          if (defined($self->mgdata())) {
1137                                  $self->{_genome_genes} = $self->mgdata()->genome_contig_count;                                  $self->{_genome_genes} = $self->mgdata()->genome_contig_count;
1138                          }                          }
1139                  } elsif (defined($self->stats())) {                  } else {
1140                          $self->{_genome_genes} = $self->stats()->{'Total genes'}->[0];                          $self->{_genome_genes} = $self->figmodel()->get_genome_stats($self->genome())->{"TOTAL GENES"}->[0];
1141                  }                  }
1142          }          }
1143    
# Line 917  Line 1154 
1154    
1155          #Assuming complete media if none is provided          #Assuming complete media if none is provided
1156          if (!defined($Media)) {          if (!defined($Media)) {
1157                  $Media = "Complete";                  $Media = $self->autocompleteMedia();
1158          }          }
1159    
1160          #Predicting essentiality          #Predicting essentiality
1161          my $result = $self->figmodel()->RunFBASimulation($self->id(),"SINGLEKO",undef,undef,[$self->id()],[$Media]);          my $result = $self->figmodel()->RunFBASimulation($self->id(),"SINGLEKO",undef,undef,[$self->id()],[$Media]);
1162          #Checking that the table is defined and the output file exists          #Checking that the table is defined and the output file exists
1163          if (defined($result) && defined($result->get_row(0)->{"ESSENTIALGENES"})) {          if (defined($result) && defined($result->get_row(0)->{"ESSENTIALGENES"})) {
1164                  $self->figmodel()->database()->print_array_to_file($self->directory()."EssentialGenes-".$self->id()."-".$Media.".tbl",[join("\n",@{$result->get_row(0)->{"ESSENTIALGENES"}})]);                  my $tbl = $self->essentials_table();
1165                    my $row = $tbl->get_row_by_key($Media,"MEDIA",1);
1166                    $row->{"ESSENTIAL GENES"} = $result->get_row(0)->{"ESSENTIALGENES"};
1167                    $tbl->save();
1168          } else {          } else {
1169                  $self->figmodel()->error_message("FIGMODELmodel:run_default_model_predictions:could not identify essential reactions for model ".$self->id().$self->selected_version().".");                  $self->figmodel()->error_message("FIGMODELmodel:run_default_model_predictions:could not identify essential reactions for model ".$self->id().$self->selected_version().".");
1170                  return $self->figmodel()->fail();                  return $self->figmodel()->fail();
# Line 941  Line 1181 
1181          return $self->figmodel()->success();          return $self->figmodel()->success();
1182  }  }
1183    
 =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();  
         }  
 }  
   
1184  =head3 update_stats_for_gap_filling  =head3 update_stats_for_gap_filling
1185  Definition:  Definition:
1186          {string => [string]} = FIGMODELmodel->update_stats_for_gap_filling(int::gapfill time);          {string => [string]} = FIGMODELmodel->update_stats_for_gap_filling(int::gapfill time);
# Line 965  Line 1188 
1188  =cut  =cut
1189  sub update_stats_for_gap_filling {  sub update_stats_for_gap_filling {
1190          my ($self,$gapfilltime) = @_;          my ($self,$gapfilltime) = @_;
1191            $self->{_data}->autoCompleteTime($gapfilltime);
1192          #preserving the stats for the now obselete model          $self->{_data}->autocompleteDate(time());
1193          $self->save_obsolete_stats();          $self->{_data}->modificationDate(time());
1194          my $stats = $self->update_model_stats(0);          my $version = $self->{_data}->autocompleteVersion();
1195          $stats->{"Gap filling time"}->[0] = $gapfilltime;          $self->{_data}->autocompleteVersion($version+1);
1196          $stats->{"Gap fill date"}->[0] = time();          $self->update_model_stats();
         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;  
1197  }  }
1198    
1199  =head3 update_stats_for_build  =head3 update_stats_for_build
# Line 988  Line 1203 
1203  =cut  =cut
1204  sub update_stats_for_build {  sub update_stats_for_build {
1205          my ($self) = @_;          my ($self) = @_;
1206            $self->{_data}->builtDate(time());
1207          #preserving the stats for the now obselete model          $self->{_data}->modificationDate(time());
1208          $self->save_obsolete_stats();          my $version = $self->{_data}->version();
1209          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;  
1210  }  }
1211    
1212  =head3 update_model_stats  =head3 update_model_stats
# Line 1019  Line 1225 
1225          }          }
1226          my $cpdtbl = $self->compound_table();          my $cpdtbl = $self->compound_table();
1227    
1228          #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];  
         }  
   
1229          my %GeneHash;          my %GeneHash;
1230          my %NonpegHash;          my %NonpegHash;
1231          my %CompoundHash;          my %CompoundHash;
1232            my $spontaneousReactions = 0;
1233            my $gapFillReactions = 0;
1234            my $biologReactions = 0;
1235            my $transporters = 0;
1236            my $autoCompleteReactions = 0;
1237            my $associatedSubsystemGenes = 0;
1238          for (my $i=0; $i < $rxntbl->size(); $i++) {          for (my $i=0; $i < $rxntbl->size(); $i++) {
1239                  my $Row = $rxntbl->get_row($i);                  my $Row = $rxntbl->get_row($i);
1240                  if (defined($Row) && defined($Row->{"ASSOCIATED PEG"})) {                  if (defined($Row) && defined($Row->{"ASSOCIATED PEG"})) {
# Line 1077  Line 1242 
1242                          if (defined($ReactionRow->{"EQUATION"}->[0])) {                          if (defined($ReactionRow->{"EQUATION"}->[0])) {
1243                                  #Checking for extracellular metabolites which indicate that this is a transporter                                  #Checking for extracellular metabolites which indicate that this is a transporter
1244                                  if ($ReactionRow->{"EQUATION"}->[0] =~ m/\[e\]/) {                                  if ($ReactionRow->{"EQUATION"}->[0] =~ m/\[e\]/) {
1245                                          $CurrentStats->{"Transport reaction"}->[0]++;                                          $transporters++;
1246                                  }                                  }
1247                          }                          }
1248                          #Identifying spontaneous/biolog/gapfilling/gene associated reactions                          #Identifying spontaneous/biolog/gapfilling/gene associated reactions
1249                          if ($Row->{"ASSOCIATED PEG"}->[0] =~ m/BIOLOG/i) {                          if ($Row->{"ASSOCIATED PEG"}->[0] =~ m/BIOLOG/i) {
1250                                  $CurrentStats->{"Biolog gap filling reactions"}->[0]++;                                  $biologReactions++;
1251                            } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/GROW/i) {
1252                                    $gapFillReactions++;
1253                          } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/SPONTANEOUS/i) {                          } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/SPONTANEOUS/i) {
1254                                  $CurrentStats->{"Spontaneous"}->[0]++;                                  $spontaneousReactions++;
1255                          } 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) {
1256                                  $CurrentStats->{"Gap filling reactions"}->[0]++;                                  $autoCompleteReactions++;
1257                          } else {                          } else {
1258                                  foreach my $GeneSet (@{$Row->{"ASSOCIATED PEG"}}) {                                  foreach my $GeneSet (@{$Row->{"ASSOCIATED PEG"}}) {
1259                                          $_ = $GeneSet;                                          $_ = $GeneSet;
# Line 1104  Line 1271 
1271          }          }
1272          my @genes = keys(%GeneHash);          my @genes = keys(%GeneHash);
1273          my @othergenes = keys(%NonpegHash);          my @othergenes = keys(%NonpegHash);
         $CurrentStats->{"Genes with reactions"}->[0] = @genes + @othergenes;  
1274    
1275          #Updating the stats stored in the table          #Setting the reaction count
1276          $self->figmodel()->database()->update_row("MODEL STATS",$CurrentStats,"Model ID");          $self->{_data}->reactions($rxntbl->size());
1277          $self->{_stats} = $CurrentStats;          #Setting the metabolite count
1278          return $CurrentStats;          $self->{_data}->compounds($cpdtbl->size());
1279            #Setting the gene count
1280            my $geneCount = @genes + @othergenes;
1281            $self->{_data}->associatedGenes($geneCount);
1282            #Setting remaining stats
1283            $self->{_data}->spontaneousReactions($spontaneousReactions);
1284            $self->{_data}->gapFillReactions($gapFillReactions);
1285            $self->{_data}->biologReactions($biologReactions);
1286            $self->{_data}->transporters($transporters);
1287            $self->{_data}->autoCompleteReactions($autoCompleteReactions);
1288            $self->{_data}->associatedSubsystemGenes($associatedSubsystemGenes);
1289            #Setting the model class
1290            my $class = "";
1291            for (my $i=0; $i < @{$self->figmodel()->config("class list")}; $i++) {
1292                    if (defined($self->figmodel()->config($self->figmodel()->config("class list")->[$i]))) {
1293                            if (defined($self->figmodel()->config($self->figmodel()->config("class list")->[$i])->{$self->id()})) {
1294                                    $class = $self->figmodel()->config("class list")->[$i];
1295                                    last;
1296                            }
1297                            if ($class eq "" && defined($self->figmodel()->config($self->figmodel()->config("class list")->[$i])->{$self->genome()})) {
1298                                    $class = $self->figmodel()->config("class list")->[$i];
1299                            }
1300                    }
1301            }
1302            if ($class eq "") {
1303                    $class = $self->figmodel()->get_genome_stats($self->genome())->{CLASS}->[0];
1304            }
1305            if ($class eq "") {
1306                    $class = "unknown";
1307            }
1308            $self->{_data}->cellwalltype($class);
1309  }  }
1310    
1311  =head3 GapFillModel  =head3 GapFillModel
# Line 1129  Line 1325 
1325          my $UniqueFilename = $self->figmodel()->filename();          my $UniqueFilename = $self->figmodel()->filename();
1326          my $StartTime = time();          my $StartTime = time();
1327    
1328          #Archiving the existing model          #Reading original reaction table
1329          $self->ArchiveModel();          my $OriginalRxn = $self->reaction_table();
1330            #Clearing the table
1331            $self->reaction_table(1);
1332    
1333          #Removing any gapfilling reactions that may be currently present in the model          #Removing any gapfilling reactions that may be currently present in the model
1334          if (!defined($donotclear) || $donotclear != 1) {          if (!defined($donotclear) || $donotclear != 1) {
1335                  my $ModelTable = $self->reaction_table();                  my $ModelTable = $self->reaction_table();
1336                  for (my $i=0; $i < $ModelTable->size(); $i++) {                  for (my $i=0; $i < $ModelTable->size(); $i++) {
1337                          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/) {
1338                                  $ModelTable->delete_row($i);                                  $ModelTable->delete_row($i);
1339                                  $i--;                                  $i--;
1340                          }                          }
# Line 1145  Line 1343 
1343          }          }
1344    
1345          #Calling the MFAToolkit to run the gap filling optimization          #Calling the MFAToolkit to run the gap filling optimization
1346          my $MinimalMediaTable = $self->figmodel()->database()->GetDBTable("MINIMAL MEDIA TABLE");          my $Media = $self->autocompleteMedia();
1347          my $Media = "Complete";          if ($Media eq "Complete") {
1348          if (defined($MinimalMediaTable->get_row_by_key($self->genome(),"Organism"))) {                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),undef,["GapFilling"],{"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0]},"GapFill".$self->id().".log",undef));
1349                  $Media = $MinimalMediaTable->get_row_by_key($self->genome(),"Organism")->{"Minimal media"}->[0];          } else {
1350                  #Loading media, changing bounds, saving media as a test media                  #Loading media, changing bounds, saving media as a test media
1351                  my $MediaTable = FIGMODELTable::load_table($self->config("Media directory")->[0].$Media.".txt",";","",0,["VarName"]);                  my $MediaTable = FIGMODELTable::load_table($self->config("Media directory")->[0].$Media.".txt",";","",0,["VarName"]);
1352                  for (my $i=0; $i < $MediaTable->size(); $i++) {                  for (my $i=0; $i < $MediaTable->size(); $i++) {
# Line 1160  Line 1358 
1358                          }                          }
1359                  }                  }
1360                  $MediaTable->save($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");                  $MediaTable->save($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");
1361                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$UniqueFilename."TestMedia",["GapFilling"],{"Default max drain flux" => 0},"GapFill".$self->id().".log",undef));                  #print $self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$UniqueFilename."TestMedia",["GapFilling"],{"Default max drain flux" => 0,"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0]},"GapFill".$self->id().".log",undef)."\n";
1362                    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));
1363                  unlink($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");                  unlink($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");
         } else {  
                 system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),undef,["GapFilling"],undef,"GapFill".$self->id().".log",undef));  
1364          }          }
1365    
1366          #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
1367          my $SolutionData = $self->figmodel()->LoadProblemReport($UniqueFilename);          my $SolutionData = $self->figmodel()->LoadProblemReport($UniqueFilename);
1368    
1369          #Clearing the mfatoolkit output and log file          #Clearing the mfatoolkit output and log file
1370          $self->figmodel()->clearing_output($UniqueFilename,"GapFill".$self->id().".log");          $self->figmodel()->clearing_output($UniqueFilename,"GapFill".$self->id().".log");
1371          if (!defined($SolutionData) || $SolutionData->size() == 0) {          if (!defined($SolutionData) || $SolutionData->size() == 0) {
# Line 1175  Line 1373 
1373                  $self->figmodel()->error_message("FIGMODEL:GapFillModel: Gap filling report not found!");                  $self->figmodel()->error_message("FIGMODEL:GapFillModel: Gap filling report not found!");
1374                  return $self->fail();                  return $self->fail();
1375          }          }
         $SolutionData->save("/home/chenry/Solution.txt");  
1376    
1377          #Looking for the last printed recursive MILP solution          #Looking for the last printed recursive MILP solution
1378          for (my $i=($SolutionData->size()-1); $i >=0; $i--) {          for (my $i=($SolutionData->size()-1); $i >=0; $i--) {
# Line 1203  Line 1400 
1400                                                  push(@{$ReactionList},$ID);                                                  push(@{$ReactionList},$ID);
1401                                          }                                          }
1402                                  }                                  }
1403                                  $self->figmodel()->IntegrateGrowMatchSolution($self->id(),undef,$ReactionList,$DirectionList,"GAP FILLING",0,1);                                  $self->figmodel()->IntegrateGrowMatchSolution($self->id(),undef,$ReactionList,$DirectionList,"AUTOCOMPLETION",0,1);
1404                          }                          }
1405                          last;                          last;
1406                  }                  }
1407          }          }
1408    
1409          #Updating model stats with gap filling results          #Updating model stats with gap filling results
1410          my $ElapsedTime = time() - $StartTime;          my $ElapsedTime = time() - $StartTime;
1411          $self->figmodel()->ClearDBModel($self->id(),1);          $self->reaction_table(1);
1412            $self->calculate_model_changes($OriginalRxn,"AUTOCOMPLETION");
1413    
1414          #Determining why each gap filling reaction was added          #Determining why each gap filling reaction was added
1415          $self->figmodel()->IdentifyDependancyOfGapFillingReactions($self->id(),$Media);          $self->figmodel()->IdentifyDependancyOfGapFillingReactions($self->id(),$Media);
1416          if (!defined($donotclear) || $donotclear != 1) {          if (!defined($donotclear) || $donotclear != 1) {
                 $self->figmodel()->AddBiologTransporters($self->id());  
1417                  if ($self->id() !~ m/MGRast/) {                  if ($self->id() !~ m/MGRast/) {
1418                          $self->update_stats_for_gap_filling($ElapsedTime);                          $self->update_stats_for_gap_filling($ElapsedTime);
1419                  }                  }
1420          } else {          } else {
1421                  $self->update_model_stats();                  $self->update_model_stats();
1422            }
1423            #Printing the updated SBML file
1424            $self->PrintSBMLFile();
1425            $self->PrintModelLPFile($self->id());
1426            $self->set_status(1,"Auto completion successfully finished");
1427            $self->run_default_model_predictions();
1428    
1429            return $self->success();
1430    }
1431    
1432    =head3 calculate_model_changes
1433    Definition:
1434            FIGMODELmodel->calculate_model_changes(FIGMODELTable:original reaction table,string:modification cause);
1435    Description:
1436    
1437    =cut
1438    
1439    sub calculate_model_changes {
1440            my ($self,$originalReactions,$cause,$tbl,$version) = @_;
1441            my $modTime = time();
1442            if (!defined($version)) {
1443                    $version = $self->selected_version();
1444            }
1445            my $user = $self->figmodel()->user();
1446            #Getting the history table
1447            my $histTbl = $self->model_history();
1448            #Checking for differences
1449            if (!defined($tbl)) {
1450                    $tbl = $self->reaction_table();
1451            }
1452            for (my $i=0; $i < $tbl->size(); $i++) {
1453                    my $row = $tbl->get_row($i);
1454                    my $orgRow = $originalReactions->get_row_by_key($row->{LOAD}->[0],"LOAD");
1455                    if (!defined($orgRow)) {
1456                            $histTbl->add_row({Reaction => [$row->{LOAD}->[0]], DirectionChange => $row->{DIRECTIONALITY}, GeneChange => $row->{"ASSOCIATED PEG"}, Action => ["ADDED"], ModificationTime => [$modTime], ModifcationCause => [$cause], User => [$user], Version => [$version]});
1457                    } else {
1458                            my $geneChanges;
1459                            my $directionChange;
1460                            if ($orgRow->{"DIRECTIONALITY"}->[0] ne $row->{"DIRECTIONALITY"}->[0]) {
1461                                    $directionChange = $orgRow->{"DIRECTIONALITY"}->[0]." to ".$row->{"DIRECTIONALITY"}->[0];
1462                            }
1463                            for (my $j=0; $j < @{$row->{"ASSOCIATED PEG"}}; $j++) {
1464                                    my $match = 0;
1465                                    if (defined($orgRow->{"ASSOCIATED PEG"})) {
1466                                            for (my $k=0; $k < @{$orgRow->{"ASSOCIATED PEG"}}; $k++) {
1467                                                    if ($row->{"ASSOCIATED PEG"}->[$j] eq $orgRow->{"ASSOCIATED PEG"}->[$k]) {
1468                                                            $match = 1;
1469                                                    }
1470                                            }
1471                                    }
1472                                    if ($match == 0) {
1473                                            push(@{$geneChanges},"Added ".$row->{"ASSOCIATED PEG"}->[$j]);
1474                                    }
1475                            }
1476                            if (defined($orgRow->{"ASSOCIATED PEG"})) {
1477                                    for (my $k=0; $k < @{$orgRow->{"ASSOCIATED PEG"}}; $k++) {
1478                                            my $match = 0;
1479                                            if (defined($row->{"ASSOCIATED PEG"})) {
1480                                                    for (my $j=0; $j < @{$row->{"ASSOCIATED PEG"}}; $j++) {
1481                                                            if ($row->{"ASSOCIATED PEG"}->[$j] eq $orgRow->{"ASSOCIATED PEG"}->[$k]) {
1482                                                                    $match = 1;
1483                                                            }
1484                                                    }
1485                                            }
1486                                            if ($match == 0) {
1487                                                    push(@{$geneChanges},"Removed ".$orgRow->{"ASSOCIATED PEG"}->[$k]);
1488                                            }
1489                                    }
1490                            }
1491                            if ((defined($directionChange) && length($directionChange) > 0) || defined($geneChanges) && @{$geneChanges} > 0) {
1492                                    $histTbl->add_row({Reaction => [$row->{LOAD}->[0]], DirectionChange => [$directionChange], GeneChange => $geneChanges, Action => ["CHANGE"], ModificationTime => [$modTime], ModifcationCause => [$cause], User => [$user], Version => [$version]});
1493                            }
1494                    }
1495            }
1496            #Looking for removed reactions
1497            for (my $i=0; $i < $originalReactions->size(); $i++) {
1498                    my $row = $originalReactions->get_row($i);
1499                    my $orgRow = $tbl->get_row_by_key($row->{LOAD}->[0],"LOAD");
1500                    if (!defined($orgRow)) {
1501                            $histTbl->add_row({Reaction => [$row->{LOAD}->[0]], DirectionChange => $row->{DIRECTIONALITY}, GeneChange => $row->{"ASSOCIATED PEG"}, Action => ["REMOVED"], ModificationTime => [$modTime], ModifcationCause => [$cause], User => [$user], Version => [$version]});
1502                    }
1503            }
1504            $histTbl->save();
1505    }
1506    
1507    =head3 GapGenModel
1508    Definition:
1509            FIGMODELmodel->GapGenModel();
1510    Description:
1511            Runs the gap generation algorithm to correct a single false positive prediction. Results are loaded into a table.
1512    =cut
1513    
1514    sub GapGenModel {
1515            my ($self,$Media,$KOList,$NoKOList,$Experiment,$SolutionLimit) = @_;
1516    
1517            #Enforcing nonoptional arguments
1518            if (!defined($Media)) {
1519                    return undef;
1520            }
1521            if (!defined($KOList)) {
1522                    $KOList->[0] = "none";
1523            }
1524            if (!defined($NoKOList)) {
1525                    $NoKOList->[0] = "none";
1526            }
1527            if (!defined($Experiment)) {
1528                    $Experiment= "ReactionKO";
1529            }
1530            if (!defined($SolutionLimit)) {
1531                    $SolutionLimit = "10";
1532            }
1533    
1534            #Translating the KO lists into arrays
1535            if (ref($KOList) ne "ARRAY") {
1536                    my $temp = $KOList;
1537                    $KOList = ();
1538                    push(@{$KOList},split(/[,;]/,$temp));
1539            }
1540            my $noKOHash;
1541            if (defined($NoKOList) && ref($NoKOList) ne "ARRAY") {
1542                    my $temp = $NoKOList;
1543                    $NoKOList = ();
1544                    push(@{$NoKOList},split(/[,;]/,$temp));
1545                    foreach my $rxn (@{$NoKOList}) {
1546                            $noKOHash->{$rxn} = 1;
1547                    }
1548            }
1549    
1550            #Checking if solutions exist for the input parameters
1551            $self->aquireModelLock();
1552            my $tbl = $self->load_model_table("GapGenSolutions");
1553            my $solutionRow = $tbl->get_table_by_key($Experiment,"Experiment")->get_table_by_key($Media,"Media")->get_row_by_key(join(",",@{$KOList}),"KOlist");
1554            my $solutions;
1555            if (defined($solutionRow)) {
1556                    #Checking if any solutions conform to the no KO list
1557                    foreach my $solution (@{$solutionRow->{Solutions}}) {
1558                            my @reactions = split(/,/,$solution);
1559                            my $include = 1;
1560                            foreach my $rxn (@reactions) {
1561                                    if ($rxn =~ m/(rxn\d\d\d\d\d)/) {
1562                                            if (defined($noKOHash->{$1})) {
1563                                                    $include = 0;
1564                                            }
1565                                    }
1566                            }
1567                            if ($include == 1) {
1568                                    push(@{$solutions},$solution);
1569                            }
1570                    }
1571            } else {
1572                    $solutionRow = {Media => [$Media],Experiment => [$Experiment],KOlist => [join(",",@{$KOList})]};
1573                    $tbl->add_row($solutionRow);
1574                    $self->figmodel()->database()->save_table($tbl);
1575            }
1576            $self->releaseModelLock();
1577    
1578            #Returning solution list of solutions were found
1579            if (defined($solutions) && @{$solutions} > 0) {
1580                    return $solutions;
1581            }
1582    
1583            #Getting unique filename
1584            my $Filename = $self->figmodel()->filename();
1585    
1586            #Running the gap generation
1587            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));
1588            my $ProblemReport = $self->figmodel()->LoadProblemReport($Filename);
1589            if (!defined($ProblemReport)) {
1590                    $self->figmodel()->error_message("FIGMODEL:GapGenerationAlgorithm;No problem report;".$Filename.";".$self->id().$self->selected_version().";".$Media.";".$KOList.";".$NoKOList);
1591                    return undef;
1592            }
1593    
1594            #Clearing the output folder and log file
1595            $self->figmodel()->clearing_output($Filename,"Gapgeneration-".$self->id().$self->selected_version()."-".$Filename.".log");
1596    
1597            #Saving the solution
1598            $self->aquireModelLock();
1599            $tbl = $self->load_model_table("GapGenSolutions");
1600            $solutionRow = $tbl->get_table_by_key($Experiment,"Experiment")->get_table_by_key($Media,"Media")->get_row_by_key(join(",",@{$KOList}),"KOlist");
1601            for (my $j=0; $j < $ProblemReport->size(); $j++) {
1602                    if ($ProblemReport->get_row($j)->{"Notes"}->[0] =~ m/^Recursive\sMILP\s([^)]+)/) {
1603                            my @SolutionList = split(/\|/,$1);
1604                            for (my $k=0; $k < @SolutionList; $k++) {
1605                                    if ($SolutionList[$k] =~ m/(\d+):(.+)/) {
1606                                            push(@{$solutionRow->{Solutions}},$2);
1607                                            push(@{$solutions},$2);
1608                                    }
1609                            }
1610          }          }
1611          #Printing the updated SBML file          }
1612          $self->PrintSBMLFile();          $self->figmodel()->database()->save_table($tbl);
1613          $self->PrintModelLPFile($self->id());          $self->releaseModelLock();
         $self->set_status(1,"Auto completion successfully finished");  
         $self->run_default_model_predictions();  
1614    
1615          return $self->success();          return $solutions;
1616  }  }
1617    
1618  =head3 datagapfill  =head3 datagapfill
# Line 1261  Line 1646 
1646          return undef;          return undef;
1647  }  }
1648    
 =head3 datagapgen  
 Definition:  
         $model->datagapgen($NumberOfProcessors,$ProcessorIndex,$Filename);  
 =cut  
   
 sub datagapgen {  
         my ($self,$Media,$KOList,$NoKOList,$suffix) = @_;  
         #Setting default values for inputs  
         if (!defined($NoKOList)) {  
                 $NoKOList = "none";  
         }  
         if (!defined($KOList)) {  
                 $KOList = "none";  
         }  
         #Getting unique filename  
         my $Filename = $self->figmodel()->filename();  
         if (!defined($suffix)) {  
                 $suffix = "-".$Media."-".$KOList."-S";  
         }  
         $KOList =~ s/,/;/g;  
         $NoKOList =~ s/,/;/g;  
         #Running the gap generation  
         system($self->figmodel()->GenerateMFAToolkitCommandLineCall($Filename,$self->id().$self->selected_version(),$Media,["GapGeneration"],{"Reactions that should always be active" => $NoKOList,"Reactions to knockout" => $KOList,"Reactions that are always blocked" => "none"},"Gapgeneration-".$self->id().$self->selected_version()."-".$Filename.".log",undef,undef));  
         my $ProblemReport = $self->figmodel()->LoadProblemReport($Filename);  
         if (!defined($ProblemReport)) {  
                 $self->figmodel()->error_message("FIGMODEL:GapGenerationAlgorithm;No problem report;".$Filename.";".$self->id().$self->selected_version().";".$Media.";".$KOList.";".$NoKOList);  
                 return undef;  
         }  
         #Clearing the output folder and log file  
         $self->figmodel()->clearing_output($Filename,$self->directory()."Gapgeneration-".$self->id().$self->selected_version()."-".$Filename.".log");  
         #Scheduling the testing of this gap filling solution  
         my $Tbl = FIGMODELTable->new(["Experiment","Solution index","Solution cost","Solution reactions"],$self->directory().$self->id().$self->selected_version()."-GG".$suffix.".txt",undef,";","|",undef);  
         for (my $j=0; $j < $ProblemReport->size(); $j++) {  
                 if ($ProblemReport->get_row($j)->{"Notes"}->[0] =~ m/^Recursive\sMILP\s([^)]+)/) {  
                         my @SolutionList = split(/\|/,$1);  
                         for (my $k=0; $k < @SolutionList; $k++) {  
                                 if ($SolutionList[$k] =~ m/(\d+):(.+)/) {  
                                         $Tbl->add_row({"Experiment"=>[$Media],"Solution index"=>[$k],"Solution cost"=>[$1],"Solution reactions"=>[$2]});  
                                 }  
                         }  
                 }  
         }  
         return $Tbl;  
 }  
   
1649  =head3 TestSolutions  =head3 TestSolutions
1650  Definition:  Definition:
1651          $model->TestSolutions($ModelID,$NumProcessors,$ProcessorIndex,$GapFill);          $model->TestSolutions($ModelID,$NumProcessors,$ProcessorIndex,$GapFill);
# Line 1401  Line 1741 
1741  =cut  =cut
1742  sub status {  sub status {
1743          my ($self) = @_;          my ($self) = @_;
1744          return $self->{_data}->{status}->[0];          return $self->{_data}->status();
1745  }  }
1746    
1747  =head3 message  =head3 message
# Line 1412  Line 1752 
1752  =cut  =cut
1753  sub message {  sub message {
1754          my ($self) = @_;          my ($self) = @_;
1755          return $self->{_data}->{message}->[0];          return $self->{_data}->message();
1756  }  }
1757    
1758  =head3 set_status  =head3 set_status
# Line 1427  Line 1767 
1767  =cut  =cut
1768  sub set_status {  sub set_status {
1769          my ($self,$NewStatus,$Message) = @_;          my ($self,$NewStatus,$Message) = @_;
1770            $self->{_data}->status($NewStatus);
1771          #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");  
1772          return $self->config("SUCCESS")->[0];          return $self->config("SUCCESS")->[0];
1773  }  }
1774    
# Line 1470  Line 1807 
1807          }          }
1808          #Setting up needed variables          #Setting up needed variables
1809          my $OriginalModelTable = undef;          my $OriginalModelTable = undef;
1810          #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) {  
1811                  $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");  
1812                  return $self->fail();                  return $self->fail();
1813          }elsif ($Row->{status}->[0] == 1) {          }elsif ($self->status() == 1) {
1814                  $OriginalModelTable = $self->reaction_table();                  $OriginalModelTable = $self->reaction_table();
1815                  $self->ArchiveModel();                  $self->set_status(0,"Rebuilding preliminary reconstruction");
                 $Row->{status}->[0] = 0;  
                 $Row->{message}->[0] = "Rebuilding preliminary reconstruction";  
1816          } else {          } else {
1817                  $Row->{status}->[0] = 0;                  $self->set_status(0,"Preliminary reconstruction");
                 $Row->{message}->[0] = "Preliminary reconstruction";  
1818          }          }
         #Updating the status table  
         $self->figmodel()->database()->save_table($ModelTable);  
         $self->figmodel()->database()->UnlockDBTable("MODELS");  
1819          #Sorting GenomeData by gene location on the chromosome          #Sorting GenomeData by gene location on the chromosome
1820            my $ftrTbl = $self->figmodel()->database()->get_table("ROLERXNMAPPING");
1821          $FeatureTable->sort_rows("MIN LOCATION");          $FeatureTable->sort_rows("MIN LOCATION");
1822          my ($ComplexHash,$SuggestedMappings,$UnrecognizedReactions,$ReactionHash);          my ($ComplexHash,$SuggestedMappings,$UnrecognizedReactions,$ReactionHash);
1823          my %LastGenePosition;          my %LastGenePosition;
# Line 1565  Line 1889 
1889                          }                          }
1890                  }                  }
1891          }          }
   
1892          #Creating nonadjacent complexes          #Creating nonadjacent complexes
1893          my @ReactionList = keys(%{$ReactionHash});          my @ReactionList = keys(%{$ReactionHash});
1894          foreach my $Reaction (@ReactionList) {          foreach my $Reaction (@ReactionList) {
# Line 1671  Line 1994 
1994                  $NewModelTable->add_row({"LOAD" => [$ReactionID],"DIRECTIONALITY" => [$Directionality],"COMPARTMENT" => ["c"],"ASSOCIATED PEG" => [join("|",@{$ReactionHash->{$ReactionID}->{"GENES"}})],"SUBSYSTEM" => [$Subsystem],"CONFIDENCE" => [$ReactionHash->{$ReactionID}->{"CONFIDENCE"}->[0]],"REFERENCE" => [$Source],"NOTES" => ["NONE"]});                  $NewModelTable->add_row({"LOAD" => [$ReactionID],"DIRECTIONALITY" => [$Directionality],"COMPARTMENT" => ["c"],"ASSOCIATED PEG" => [join("|",@{$ReactionHash->{$ReactionID}->{"GENES"}})],"SUBSYSTEM" => [$Subsystem],"CONFIDENCE" => [$ReactionHash->{$ReactionID}->{"CONFIDENCE"}->[0]],"REFERENCE" => [$Source],"NOTES" => ["NONE"]});
1995          }          }
1996    
1997            #Getting feature rows for features that are lumped
1998            my @rows = $ftrTbl->get_rows_by_key("2","MASTER");
1999            for (my $i=0; $i < @rows; $i++) {
2000                    my $rxn = $rows[$i]->{REACTION}->[0];
2001                    my $role = $rows[$i]->{ROLE}->[0];
2002                    my @orgrows = $FeatureTable->get_rows_by_key($role,"ROLES");
2003                    my $genes;
2004                    for (my $j=0; $j < @orgrows; $j++) {
2005                            if ($orgrows[$j]->{ID}->[0] =~ m/(peg\.\d+)/) {
2006                                    push(@{$genes},$1);
2007                            }
2008                    }
2009                    if (defined($genes) && @{$genes} > 0) {
2010                            my $row = $NewModelTable->get_row_by_key($rxn,"LOAD");
2011                            my $newGeneAssociations;
2012                            for (my $k=0; $k < @{$genes}; $k++) {
2013                                    for (my $j=0; $j < @{$row->{"ASSOCIATED PEG"}}; $j++) {
2014                                            my $peg = $genes->[$k];
2015                                            if ($row->{"ASSOCIATED PEG"}->[$j] !~ m/$peg/) {
2016                                                    push(@{$newGeneAssociations},$row->{"ASSOCIATED PEG"}->[$j]."+".$peg);
2017                                            }
2018                                    }
2019                            }
2020                            $row->{"ASSOCIATED PEG"} = $newGeneAssociations;
2021                    }
2022            }
2023    
2024          #Adding the spontaneous and universal reactions          #Adding the spontaneous and universal reactions
2025          foreach my $ReactionID (@{$self->config("spontaneous reactions")}) {          foreach my $ReactionID (@{$self->config("spontaneous reactions")}) {
2026                  #Getting the thermodynamic reversibility from the database                  #Getting the thermodynamic reversibility from the database
# Line 1690  Line 2040 
2040          }          }
2041    
2042          #Checking if a biomass reaction already exists          #Checking if a biomass reaction already exists
2043          my $BiomassReactionRow = $self->figmodel()->database()->get_row_by_key("BIOMASS TABLE",$self->id(),"MODELS");          my $BiomassReactionRow = $self->BuildSpecificBiomassReaction();
         if (!defined($BiomassReactionRow)) {  
                 $BiomassReactionRow = $self->BuildSpecificBiomassReaction();  
2044                  if (!defined($BiomassReactionRow)) {                  if (!defined($BiomassReactionRow)) {
2045                          $self->set_status(-2,"Preliminary reconstruction failed: could not generate biomass reaction");                          $self->set_status(-2,"Preliminary reconstruction failed: could not generate biomass reaction");
2046                          $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()."!");
2047                          return $self->fail();                          return $self->fail();
2048                  }                  }
         }  
2049          my $ReactionList = $BiomassReactionRow->{"ESSENTIAL REACTIONS"};          my $ReactionList = $BiomassReactionRow->{"ESSENTIAL REACTIONS"};
2050          push(@{$ReactionList},$BiomassReactionRow->{DATABASE}->[0]);          push(@{$ReactionList},$BiomassReactionRow->{DATABASE}->[0]);
2051    
# Line 1730  Line 2077 
2077                  }                  }
2078          }          }
2079    
2080            #If an original model exists, we copy the gap filling solution from that model
2081            if (defined($OriginalModelTable)) {
2082                    for (my $i=0; $i < $OriginalModelTable->size(); $i++) {
2083                            if ($OriginalModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0] =~ m/GAP/ && $OriginalModelTable->get_row($i)->{"ASSOCIATED PEG"}->[0] ne "INITIAL GAP FILLING") {
2084                                    my $Row = $NewModelTable->get_row_by_key($OriginalModelTable->get_row($i)->{"LOAD"}->[0],"LOAD");
2085                                    if (!defined($Row)) {
2086                                            $NewModelTable->add_row($OriginalModelTable->get_row($i));
2087                                    }
2088                            }
2089                    }
2090            }
2091    
2092          #Now we compare the model to the previous model to determine if any differences exist that aren't gap filling reactions          #Now we compare the model to the previous model to determine if any differences exist that aren't gap filling reactions
2093          if (defined($OriginalModelTable)) {          if (defined($OriginalModelTable)) {
2094                  my $PerfectMatch = 1;                  my $PerfectMatch = 1;
# Line 1789  Line 2148 
2148          #Saving the new model to file          #Saving the new model to file
2149          $self->set_status(1,"Preliminary reconstruction complete");          $self->set_status(1,"Preliminary reconstruction complete");
2150          $self->figmodel()->database()->save_table($NewModelTable);          $self->figmodel()->database()->save_table($NewModelTable);
2151          $self->{_reaction_data} = $NewModelTable;          $self->reaction_table(1);
         #Clearing the previous model from the cache  
         $self->figmodel()->ClearDBModel($self->id(),1);  
2152          #Updating the model stats table          #Updating the model stats table
2153          $self->update_stats_for_build();          $self->update_stats_for_build();
2154          $self->PrintSBMLFile();          $self->PrintSBMLFile();
2155            if (defined($OriginalModelTable)) {
2156                    $self->calculate_model_changes($OriginalModelTable,"REBUILD");
2157            }
2158    
2159          #Adding model to gapfilling queue          #Adding model to gapfilling queue
2160          if (defined($RunGapFilling) && $RunGapFilling == 1) {          if (defined($RunGapFilling) && $RunGapFilling == 1) {
# Line 1813  Line 2173 
2173    
2174  sub CreateMetaGenomeReactionList {  sub CreateMetaGenomeReactionList {
2175          my ($self) = @_;          my ($self) = @_;
   
2176          #Checking if the metagenome file exists          #Checking if the metagenome file exists
2177          if (!-e $self->config("raw MGRAST directory")->[0].$self->genome().".summary") {          if (!-e $self->config("raw MGRAST directory")->[0].$self->genome().".summary") {
2178                  $self->error_message("FIGMODEL:CreateMetaGenomeReactionList: could not find raw data file for metagenome ".$self->genome());                  $self->error_message("FIGMODEL:CreateMetaGenomeReactionList: could not find raw data file for metagenome ".$self->genome());
2179                    return $self->fail();
2180          }          }
2181          #Loading metagenome data          #Loading metagenome data
2182          my $MGRASTData = $self->figmodel()->database()->load_multiple_column_file($self->config("raw MGRAST directory")->[0].$self->genome().".summary","\t");          my $MGRASTData = $self->figmodel()->database()->load_multiple_column_file($self->config("raw MGRAST directory")->[0].$self->genome().".summary","\t");
2183          if (!defined($MGRASTData)) {          if (!defined($MGRASTData)) {
2184                  $self->error_message("FIGMODEL:CreateMetaGenomeReactionList: could not find raw data file for metagenome ".$self->genome());                  $self->error_message("FIGMODEL:CreateMetaGenomeReactionList: could not find raw data file for metagenome ".$self->genome());
2185                    return $self->fail();
2186          }          }
   
2187          #Setting up needed variables          #Setting up needed variables
2188          my $OriginalModelTable = undef;          my $OriginalModelTable = undef;
   
2189          #Checking status          #Checking status
2190          if ($self->status() < 0) {          if ($self->status() < 0) {
2191                  $self->set_status(0,"Preliminary reconstruction");                  $self->set_status(0,"Preliminary reconstruction");
# Line 1838  Line 2197 
2197                  $self->ArchiveModel();                  $self->ArchiveModel();
2198                  $self->set_status(0,"Rebuilding preliminary reconstruction");                  $self->set_status(0,"Rebuilding preliminary reconstruction");
2199          }          }
2200            #Creating a hash of escores and pegs associated with each role
2201            my $rolePegHash;
2202            my $roleEscores;
2203            for (my $i=0; $i < @{$MGRASTData};$i++) {
2204                    #MD5,PEG,number of sims,role,sim e-scores,max escore,min escore,ave escore,stdev escore,ave exponent,stddev exponent
2205                    $rolePegHash->{$MGRASTData->[$i]->[3]}->{substr($MGRASTData->[$i]->[1],4)} = 1;
2206                    push(@{$roleEscores->{$MGRASTData->[$i]->[3]}},split(/;/,$MGRASTData->[$i]->[4]));
2207            }
2208          #Getting the reaction table          #Getting the reaction table
2209          my $ReactionTable = $self->figmodel()->database()->GetDBTable("REACTIONS");          my $ReactionTable = $self->figmodel()->database()->get_table("REACTIONS");
2210          #Creating model table          #Creating model table
2211          my $ModelTable = FIGMODELTable->new(["LOAD","DIRECTIONALITY","COMPARTMENT","ASSOCIATED PEG","SUBSYSTEM","CONFIDENCE","REFERENCE","NOTES"],$self->directory().$self->id().".txt",["LOAD"],";","|","REACTIONS\n");          my $ModelTable = $self->create_table_prototype("ModelReactions");
2212          for (my $i=0; $i < @{$MGRASTData};$i++) {          print $ModelTable->filename();
2213                  #MD5,PEG,number of sims,role,sim e-scores          my @roles = keys(%{$rolePegHash});
2214                  my $Role = $MGRASTData->[$i]->[3];          for (my $i=0; $i < @roles; $i++) {
2215                  my $MD5 = $MGRASTData->[$i]->[0];                  my $min = -1;
2216                  my $peg = $MGRASTData->[$i]->[1];                  my $max = -1;
2217                  my $sims = $MGRASTData->[$i]->[4];                  my $count = @{$roleEscores->{$roles[$i]}};
2218                  $sims =~ s/;/,/g;                  my $ave = 0;
2219                    my $stdev = 0;
2220                    my $aveexp = 0;
2221                    my $stdevexp = 0;
2222                    for (my $j=0; $j < @{$roleEscores->{$roles[$i]}}; $j++) {
2223                            if ($roleEscores->{$roles[$i]} < $min || $min == -1) {
2224                                    $min = $roleEscores->{$roles[$i]};
2225                            }
2226                            if ($roleEscores->{$roles[$i]} > $max || $max == -1) {
2227                                    $max = $roleEscores->{$roles[$i]};
2228                            }
2229                            $ave += $roleEscores->{$roles[$i]}->[$j];
2230                            if ($roleEscores->{$roles[$i]}->[$j] =~ m/e(-\d+$)/) {
2231                                    $aveexp += $1;
2232                            }
2233                    }
2234                    $ave = $ave/$count;
2235                    $aveexp = $aveexp/$count;
2236                    for (my $j=0; $j < @{$roleEscores->{$roles[$i]}}; $j++) {
2237                            $stdev += ($roleEscores->{$roles[$i]}->[$j]-$ave)*($roleEscores->{$roles[$i]}->[$j]-$ave);
2238                            if ($roleEscores->{$roles[$i]}->[$j] =~ m/e(-\d+$)/) {
2239                                    $stdevexp += ($1-$aveexp)*($1-$aveexp);
2240                            }
2241                    }
2242                    $stdev = sqrt($stdev/$count);
2243                    $stdevexp = sqrt($stdevexp/$count);
2244                  #Checking for subsystems                  #Checking for subsystems
2245                  my $GeneSubsystems = $self->figmodel()->subsystems_of_role($Role);                  my $GeneSubsystems = $self->figmodel()->subsystems_of_role($roles[$i]);
2246                  #Checking if there are reactions associated with this role                  #Checking if there are reactions associated with this role
2247                  my $ReactionHashArrayRef = $self->figmodel()->reactions_of_role($Role);                  my $ReactionHashArrayRef = $self->figmodel()->reactions_of_role($roles[$i]);
2248                  if ($ReactionHashArrayRef != 0) {                  if ($ReactionHashArrayRef != 0) {
2249                          foreach my $Mapping (@{$ReactionHashArrayRef}) {                          foreach my $Mapping (@{$ReactionHashArrayRef}) {
2250                                  if (defined($Mapping->{"REACTION"}) && defined($Mapping->{"MASTER"}) && defined($Mapping->{"SUBSYSTEM"}) && defined($Mapping->{"SOURCE"})) {                                  if (defined($Mapping->{"REACTION"}) && defined($Mapping->{"MASTER"}) && defined($Mapping->{"SUBSYSTEM"}) && defined($Mapping->{"SOURCE"})) {
# Line 1866  Line 2256 
2256                                                                  $ReactionRow = {"LOAD" => [$Mapping->{"REACTION"}->[0]],"DIRECTIONALITY" => [$self->figmodel()->reversibility_of_reaction($Mapping->{"REACTION"}->[0])],"COMPARTMENT" => ["c"]};                                                                  $ReactionRow = {"LOAD" => [$Mapping->{"REACTION"}->[0]],"DIRECTIONALITY" => [$self->figmodel()->reversibility_of_reaction($Mapping->{"REACTION"}->[0])],"COMPARTMENT" => ["c"]};
2257                                                                  $ModelTable->add_row($ReactionRow);                                                                  $ModelTable->add_row($ReactionRow);
2258                                                          }                                                          }
2259                                                          push(@{$ReactionRow->{"ASSOCIATED PEG"}},substr($peg,4));                                                          my %pegHash = %{$rolePegHash->{$roles[$i]}};
2260                                                          push(@{$ReactionRow->{"REFERENCE"}},$MD5.":".$Role);                                                          if (defined($ReactionRow->{"ASSOCIATED PEG"})) {
2261                                                          push(@{$ReactionRow->{"CONFIDENCE"}},$sims);                                                                  for (my $j=0; $j < @{$ReactionRow->{"ASSOCIATED PEG"}}; $j++) {
2262                                                                            $pegHash{$ReactionRow->{"ASSOCIATED PEG"}->[$j]} = 1;
2263                                                                    }
2264                                                            }
2265                                                            delete $ReactionRow->{"ASSOCIATED PEG"};
2266                                                            push(@{$ReactionRow->{"ASSOCIATED PEG"}},keys(%pegHash));
2267                                                            push(@{$ReactionRow->{"REFERENCE"}},$count.":".$ave.":".$stdev.":".$aveexp.":".$stdevexp.":".$min.":".$max);
2268                                                          if (defined($GeneSubsystems)) {                                                          if (defined($GeneSubsystems)) {
2269                                                                  push(@{$ReactionRow->{"SUBSYSTEM"}},@{$GeneSubsystems});                                                                  push(@{$ReactionRow->{"SUBSYSTEM"}},@{$GeneSubsystems});
2270                                                          }                                                          }
# Line 1912  Line 2308 
2308          }          }
2309    
2310          #Clearing the previous model from the cache          #Clearing the previous model from the cache
2311          $self->figmodel()->ClearDBModel($self->id(),1);          $self->figmodel()->database()->ClearDBModel($self->id(),1);
2312          $ModelTable->save();          $ModelTable->save();
2313    
2314          return $self->success();          return $self->success();
# Line 1928  Line 2324 
2324  sub ArchiveModel {  sub ArchiveModel {
2325          my ($self) = @_;          my ($self) = @_;
2326    
         #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();  
         }  
   
2327          #Checking that the model file exists          #Checking that the model file exists
2328          if (!(-e $self->filename())) {          if (!(-e $self->filename())) {
2329                  $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 2120  Line 2510 
2510          }          }
2511    
2512          #Writing output to file          #Writing output to file
2513          $self->figmodel()->database()->print_array_to_file($self->directory()."MinimalPathways-".$media."-".$objective."-".$self->id()."-".$AllReversible."-".$self->selected_version().".txt",[join(",",@Array)]);          $self->figmodel()->database()->print_array_to_file($self->directory()."MinimalPathways-".$media."-".$objective."-".$self->id()."-".$AllReversible."-".$self->selected_version().".txt",[join("|",@Array)]);
2514  }  }
2515    
2516  =head3 find_minimal_pathways  =head3 find_minimal_pathways
# Line 2238  Line 2628 
2628          }          }
2629    
2630          #Writing output to file          #Writing output to file
2631          $self->figmodel()->database()->print_array_to_file($self->directory()."MinimalPathways-".$media."-".$objective."-".$self->id()."-".$AllReversible."-".$self->selected_version().".txt",[join(",",@Array)]);          $self->figmodel()->database()->print_array_to_file($self->directory()."MinimalPathways-".$media."-".$objective."-".$self->id()."-".$AllReversible."-".$self->selected_version().".txt",[join("|",@Array)]);
2632  }  }
2633    
2634  sub combine_minimal_pathways {  sub combine_minimal_pathways {
# Line 2300  Line 2690 
2690          Calculating growth in the input media          Calculating growth in the input media
2691  =cut  =cut
2692  sub calculate_growth {  sub calculate_growth {
2693          my ($self,$Media) = @_;          my ($self,$Media,$outputDirectory,$InParameters,$saveLPFile) = @_;
2694            #Setting the Media
2695            if (!defined($Media) || length($Media) == 0) {
2696                    $Media = $self->autocompleteMedia();
2697            }
2698            #Setting parameters for the run
2699            my $DefaultParameters = $self->figmodel()->defaultParameters();
2700            if (defined($InParameters)) {
2701                    my @parameters = keys(%{$InParameters});
2702                    for (my $i=0; $i < @parameters; $i++) {
2703                            $DefaultParameters->{$parameters[$i]} = $InParameters->{$parameters[$i]};
2704                    }
2705            }
2706            $DefaultParameters->{"optimize metabolite production if objective is zero"} = 1;
2707            #Setting filenames
2708          my $UniqueFilename = $self->figmodel()->filename();          my $UniqueFilename = $self->figmodel()->filename();
2709          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)) {
2710                    $outputDirectory = $self->config("database message file directory")->[0];
2711            }
2712            my $fluxFilename = $outputDirectory."Fluxes-".$self->id()."-".$Media.".txt";
2713            my $cpdFluxFilename = $outputDirectory."CompoundFluxes-".$self->id()."-".$Media.".txt";
2714            #Running FBA
2715            #print $self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$Media,["ProductionMFA"],$DefaultParameters,$self->id()."-".$Media."-GrowthTest.txt",undef,$self->selected_version())."\n";
2716            system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$Media,["ProductionMFA"],$DefaultParameters,$self->id()."-".$Media."-GrowthTest.txt",undef,$self->selected_version()));
2717            #Saving LP file if requested
2718            if (defined($saveLPFile) && $saveLPFile == 1 && -e $self->figmodel()->{"MFAToolkit output directory"}->[0].$UniqueFilename."/CurrentProblem.lp") {
2719                    system("cp ".$self->figmodel()->config("MFAToolkit output directory")->[0].$UniqueFilename."/CurrentProblem.lp ".$self->directory().$self->id().".lp");
2720            }
2721          my $ProblemReport = $self->figmodel()->LoadProblemReport($UniqueFilename);          my $ProblemReport = $self->figmodel()->LoadProblemReport($UniqueFilename);
2722          my $Result;          my $Result;
2723          if (defined($ProblemReport)) {          if (defined($ProblemReport)) {
2724                  my $Row = $ProblemReport->get_row(0);                  my $Row = $ProblemReport->get_row(0);
2725                  if (defined($Row) && defined($Row->{"Objective"}->[0])) {                  if (defined($Row) && defined($Row->{"Objective"}->[0])) {
2726                          if ($Row->{"Objective"}->[0] < 0.00000001) {                          if ($Row->{"Objective"}->[0] < 0.00000001 || $Row->{"Objective"}->[0] == 1e7) {
2727                                  $Result = "NOGROWTH:".$Row->{"Individual metabolites with zero production"}->[0];                                  $Result = "NOGROWTH";
2728                                    if (defined($Row->{"Individual metabolites with zero production"}->[0]) && $Row->{"Individual metabolites with zero production"}->[0] =~ m/cpd\d\d\d\d\d/) {
2729                                            $Result .= ":".$Row->{"Individual metabolites with zero production"}->[0];
2730                                    }
2731                          } else {                          } else {
2732                                    if (-e $self->figmodel()->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/SolutionReactionData0.txt") {
2733                                            system("cp ".$self->figmodel()->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/SolutionReactionData0.txt ".$fluxFilename);
2734                                            system("cp ".$self->figmodel()->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/SolutionCompoundData0.txt ".$cpdFluxFilename);
2735                                    }
2736                                  $Result = $Row->{"Objective"}->[0];                                  $Result = $Row->{"Objective"}->[0];
2737                          }                          }
2738                  }                  }
2739          }          }
2740            #Deleting files if necessary
2741            if ($self->figmodel()->config("preserve all log files")->[0] ne "yes") {
2742                    $self->figmodel()->cleardirectory($UniqueFilename);
2743                    unlink($self->figmodel()->config("database message file directory")->[0].$self->id()."-".$Media."-GrowthTest.txt");
2744            }
2745            #Returning result
2746          return $Result;          return $Result;
2747  }  }
2748    
# Line 3338  Line 3766 
3766          my $OrganismID = $self->genome();          my $OrganismID = $self->genome();
3767          #Checking for a biomass override          #Checking for a biomass override
3768          if (defined($self->config("biomass reaction override")->{$OrganismID})) {          if (defined($self->config("biomass reaction override")->{$OrganismID})) {
3769                  $biomassrxn = $self->config("biomass reaction override")->{$OrganismID};                  my $biomassID = $self->config("biomass reaction override")->{$OrganismID};
3770                  print "Overriding biomass template and selecting ".$biomassrxn." for ".$OrganismID.".\n";                  my $tbl = $self->figmodel()->database()->get_table("BIOMASS",1);
3771                    $biomassrxn = $tbl->get_row_by_key($biomassID,"DATABASE");
3772                    print "Overriding biomass template and selecting ".$biomassID." for ".$OrganismID.".\n";
3773          } else {#Creating biomass reaction from the template          } else {#Creating biomass reaction from the template
3774                  #Getting the genome stats                  #Getting the genome stats
3775                  my $genomestats = $self->figmodel()->get_genome_stats($self->genome());                  my $genomestats = $self->figmodel()->get_genome_stats($self->genome());
# Line 3630  Line 4060 
4060    
4061                  #Adding the biomass equation to the biomass table                  #Adding the biomass equation to the biomass table
4062                  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());
4063                  $biomassrxn = $NewRow->{DATABASE}->[0];                  $biomassrxn = $NewRow;
                 print $biomassrxn."\n";  
4064          }          }
4065          print $biomassrxn."\n";          return $biomassrxn;
         my $BiomassRow = $self->figmodel()->add_model_to_biomass_reaction($biomassrxn,$self->id());  
         return $BiomassRow;  
4066  }  }
4067    
4068  =head3 PrintSBMLFile  =head3 PrintSBMLFile
# Line 3648  Line 4075 
4075          my($self) = @_;          my($self) = @_;
4076    
4077          #Opening the SBML file for printing          #Opening the SBML file for printing
4078          my $Filename = $self->config("SBML files")->[0].$self->id().".xml";          my $Filename = $self->directory().$self->id().".xml";
         if ($self->owner() ne "master") {  
                 if (!-d $self->config("SBML files")->[0].$self->owner()."/") {  
                         system("mkdir ".$self->config("SBML files")->[0].$self->owner()."/");  
                 }  
                 $Filename = $self->config("SBML files")->[0].$self->owner()."/".$self->id().".xml";  
         }  
4079          if (!open (SBMLOUTPUT, ">$Filename")) {          if (!open (SBMLOUTPUT, ">$Filename")) {
4080                  return;                  return;
4081          }          }
4082    
4083          #Loading and parsing the model data          #Loading and parsing the model data
4084          my $ModelTable = $self->reaction_table();          my $mdlTbl = $self->reaction_table();
4085          if (!defined($ModelTable) || !defined($ModelTable->{"array"})) {          if (!defined($mdlTbl) || !defined($mdlTbl->{"array"})) {
4086                  print "Failed to load ".$self->id()."\n";                  return $self->fail();
                 return;  
4087          }          }
4088            my $rxnTbl = $self->figmodel()->database()->get_table("REACTIONS");
4089            my $bioTbl = $self->figmodel()->database()->get_table("BIOMASS");
4090            my $cpdTbl = $self->figmodel()->database()->get_table("COMPOUNDS");
4091            my $cmpTbl = $self->figmodel()->database()->get_table("COMPARTMENTS");
4092    
4093          #Adding intracellular metabolites that also need exchange fluxes to the exchange hash          #Adding intracellular metabolites that also need exchange fluxes to the exchange hash
4094          my $ExchangeHash = {"cpd11416" => "c"};          my $ExchangeHash = {"cpd11416" => "c"};
   
4095          my %CompartmentsPresent;          my %CompartmentsPresent;
4096          $CompartmentsPresent{"c"} = 1;          $CompartmentsPresent{"c"} = 1;
4097          my %CompoundList;          my %CompoundList;
4098          my @ReactionList;          my @ReactionList;
4099          my $ReactionTable = $self->figmodel()->database()->GetDBTable("REACTIONS");          for (my $i=0; $i < $mdlTbl->size(); $i++) {
4100          for (my $i=0; $i < $ModelTable->size(); $i++) {                  my $Reaction = $mdlTbl->get_row($i)->{"LOAD"}->[0];
4101                  my $Reaction = $ModelTable->get_row($i)->{"LOAD"}->[0];                  my $row = $rxnTbl->get_row_by_key($Reaction,"DATABASE");
4102                  if (defined($ReactionTable->get_row_by_key($Reaction,"DATABASE")) && defined($ReactionTable->get_row_by_key($Reaction,"DATABASE")->{"EQUATION"}->[0])) {                  if (!defined($row)) {
4103                            $row = $bioTbl->get_row_by_key($Reaction,"DATABASE");
4104                            if (!defined($row)) {
4105                                    next;
4106                            }
4107                    }
4108                    if (!defined($row->{"EQUATION"}->[0])) {
4109                            next;
4110                    }
4111                          push(@ReactionList,$Reaction);                          push(@ReactionList,$Reaction);
4112                          $_ = $ReactionTable->get_row_by_key($Reaction,"DATABASE")->{"EQUATION"}->[0];                  $_ = $row->{"EQUATION"}->[0];
4113                          my @MatchArray = /(cpd\d\d\d\d\d)/g;                          my @MatchArray = /(cpd\d\d\d\d\d)/g;
4114                          for (my $j=0; $j < @MatchArray; $j++) {                          for (my $j=0; $j < @MatchArray; $j++) {
4115                                  $CompoundList{$MatchArray[$j]}->{"c"} = 1;                                  $CompoundList{$MatchArray[$j]}->{"c"} = 1;
4116                          }                          }
4117                          $_ = $ReactionTable->get_row_by_key($Reaction,"DATABASE")->{"EQUATION"}->[0];                  $_ = $row->{"EQUATION"}->[0];
4118                          @MatchArray = /(cpd\d\d\d\d\d\[\D\])/g;                          @MatchArray = /(cpd\d\d\d\d\d\[\D\])/g;
4119                          for (my $j=0; $j < @MatchArray; $j++) {                          for (my $j=0; $j < @MatchArray; $j++) {
4120                                  if ($MatchArray[$j] =~ m/(cpd\d\d\d\d\d)\[(\D)\]/) {                                  if ($MatchArray[$j] =~ m/(cpd\d\d\d\d\d)\[(\D)\]/) {
# Line 3692  Line 4123 
4123                                  }                                  }
4124                          }                          }
4125                  }                  }
         }  
4126    
4127          #Printing header to SBML file          #Printing header to SBML file
4128          my $ModelName = $self->id();          my $ModelName = $self->id().$self->selected_version();
4129          $ModelName =~ s/\./_/;          $ModelName =~ s/\./_/;
4130          print SBMLOUTPUT '<?xml version="1.0" encoding="UTF-8"?>'."\n";          print SBMLOUTPUT '<?xml version="1.0" encoding="UTF-8"?>'."\n";
4131      print SBMLOUTPUT '<sbml xmlns="http://www.sbml.org/sbml/level2" level="2" version="1" xmlns:html="http://www.w3.org/1999/xhtml">' . "\n";      print SBMLOUTPUT '<sbml xmlns="http://www.sbml.org/sbml/level2" level="2" version="1" xmlns:html="http://www.w3.org/1999/xhtml">' . "\n";
4132      if (defined($self->figmodel()->database()->GetDBTable("MODEL STATS")->{$self->id()}->[0]->{"Organism name"}->[0])) {          if (defined($self->name())) {
4133          print SBMLOUTPUT '<model id="'.$ModelName.'" name="'.$self->figmodel()->database()->GetDBTable("MODEL STATS")->{$self->id()}->[0]->{"Organism name"}->[0].' SEED model">'."\n";                  print SBMLOUTPUT '<model id="'.$ModelName.'" name="'.$self->name().' SEED model">'."\n";
4134      } else {      } else {
4135          print SBMLOUTPUT '<model id="'.$ModelName.'" name="'.$self->id().' SEED model">'."\n";                  print SBMLOUTPUT '<model id="'.$ModelName.'" name="'.$self->id().$self->selected_version().' SEED model">'."\n";
4136      }      }
4137    
4138          #Printing the unit data          #Printing the unit data
# Line 3719  Line 4149 
4149      #Printing compartments for SBML file      #Printing compartments for SBML file
4150      print SBMLOUTPUT '<listOfCompartments>'."\n";      print SBMLOUTPUT '<listOfCompartments>'."\n";
4151      foreach my $Compartment (keys(%CompartmentsPresent)) {      foreach my $Compartment (keys(%CompartmentsPresent)) {
4152          if (defined($self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Compartment}->[0]->{"Name"}->[0])) {                  my $row = $cmpTbl->get_row_by_key($Compartment,"Abbreviation");
4153                  my @OutsideList = split(/\//,$self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Compartment}->[0]->{"Outside"}->[0]);                  if (!defined($row) && !defined($row->{"Name"}->[0])) {
4154                            next;
4155                    }
4156                    my @OutsideList = split(/\//,$row->{"Outside"}->[0]);
4157                  my $Printed = 0;                  my $Printed = 0;
4158                  foreach my $Outside (@OutsideList) {                  foreach my $Outside (@OutsideList) {
4159                                  if (defined($CompartmentsPresent{$Outside}) && defined($self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Outside}->[0]->{"Name"}->[0])) {                          if (defined($CompartmentsPresent{$Outside}) && defined($row->{"Name"}->[0])) {
4160                                  print SBMLOUTPUT '<compartment id="'.$self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Compartment}->[0]->{"Name"}->[0].'" outside="'.$self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Outside}->[0]->{"Name"}->[0].'"/>'."\n";                                  print SBMLOUTPUT '<compartment id="'.$row->{"Name"}->[0].'" outside="'.$row->{"Name"}->[0].'"/>'."\n";
4161                                  $Printed = 1;                                  $Printed = 1;
4162                                  last;                                  last;
4163                          }                          }
4164                  }                  }
4165                  if ($Printed eq 0) {                  if ($Printed eq 0) {
4166                          print SBMLOUTPUT '<compartment id="'.$self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Compartment}->[0]->{"Name"}->[0].'"/>'."\n";                          print SBMLOUTPUT '<compartment id="'.$row->{"Name"}->[0].'"/>'."\n";
                         }  
4167          }          }
4168      }      }
4169      print SBMLOUTPUT '</listOfCompartments>'."\n";      print SBMLOUTPUT '</listOfCompartments>'."\n";
# Line 3739  Line 4171 
4171      #Printing the list of metabolites involved in the model      #Printing the list of metabolites involved in the model
4172          print SBMLOUTPUT '<listOfSpecies>'."\n";          print SBMLOUTPUT '<listOfSpecies>'."\n";
4173      foreach my $Compound (keys(%CompoundList)) {      foreach my $Compound (keys(%CompoundList)) {
4174                    my $row = $cpdTbl->get_row_by_key($Compound,"DATABASE");
4175                    if (!defined($row)) {
4176                            next;
4177                    }
4178          my $Name = $Compound;          my $Name = $Compound;
4179                  my $Formula = "";                  my $Formula = "";
4180                  if (defined($self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"FORMULA"}->[0])) {                  if (defined($row->{"FORMULA"}->[0])) {
4181                          $Formula = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"FORMULA"}->[0];                          $Formula = $row->{"FORMULA"}->[0];
4182                  }                  }
4183                  if (defined($self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"NAME"}->[0])) {                  if (defined($row->{"NAME"}->[0])) {
4184                          $Name = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"NAME"}->[0];                          $Name = $row->{"NAME"}->[0];
4185                          $Name =~ s/\s/_/;                          $Name =~ s/\s/_/;
4186                          $Name .= "_".$Formula;                          $Name .= "_".$Formula;
4187                  }                  }
4188                  $Name =~ s/[<>;&\*]//;                  $Name =~ s/[<>;&\*]//;
4189                  my $Charge = 0;                  my $Charge = 0;
4190                  if (defined($self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"CHARGE"}->[0])) {                  if (defined($row->{"CHARGE"}->[0])) {
4191                          $Charge = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"CHARGE"}->[0];                          $Charge = $row->{"CHARGE"}->[0];
4192                  }                  }
4193                  foreach my $Compartment (keys(%{$CompoundList{$Compound}})) {                  foreach my $Compartment (keys(%{$CompoundList{$Compound}})) {
4194                  if ($Compartment eq "e") {                  if ($Compartment eq "e") {
4195                          $ExchangeHash->{$Compound} = "e";                          $ExchangeHash->{$Compound} = "e";
4196                  }                  }
4197                  print SBMLOUTPUT '<species id="'.$Compound.'_'.$Compartment.'" name="'.$Name.'" compartment="'.$self->figmodel()->database()->GetDBTable("COMPARTMENTS")->{$Compartment}->[0]->{"Name"}->[0].'" charge="'.$Charge.'" boundaryCondition="false"/>'."\n";                          my $cmprow = $cmpTbl->get_row_by_key($Compartment,"Abbreviation");
4198                            print SBMLOUTPUT '<species id="'.$Compound.'_'.$Compartment.'" name="'.$Name.'" compartment="'.$cmprow->{"Name"}->[0].'" charge="'.$Charge.'" boundaryCondition="false"/>'."\n";
4199          }          }
4200      }      }
4201    
4202          #Printing the boundary species          #Printing the boundary species
4203          foreach my $Compound (keys(%{$ExchangeHash})) {          foreach my $Compound (keys(%{$ExchangeHash})) {
4204                  my $Name = $Compound;                  my $Name = $Compound;
4205                  my $Formula = "";                  my $Formula = "";
4206                  if (defined($self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"FORMULA"}->[0])) {                  my $row = $cpdTbl->get_row_by_key($Compound,"DATABASE");
4207                          $Formula = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"FORMULA"}->[0];                  if (!defined($row)) {
4208                            next;
4209                    }
4210                    if (defined($row->{"FORMULA"}->[0])) {
4211                            $Formula = $row->{"FORMULA"}->[0];
4212                  }                  }
4213                  if (defined($self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"NAME"}->[0])) {                  if (defined($row->{"NAME"}->[0])) {
4214                          $Name = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"NAME"}->[0];                          $Name = $row->{"NAME"}->[0];
4215                          $Name =~ s/\s/_/;                          $Name =~ s/\s/_/;
4216                          $Name .= "_".$Formula;                          $Name .= "_".$Formula;
4217                  }                  }
4218                  $Name =~ s/[<>;&\*]//;                  $Name =~ s/[<>;&\*]//;
4219                  my $Charge = 0;                  my $Charge = 0;
4220                  if (defined($self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"CHARGE"}->[0])) {                  if (defined($row->{"CHARGE"}->[0])) {
4221                          $Charge = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->{$Compound}->[0]->{"CHARGE"}->[0];                          $Charge = $row->{"CHARGE"}->[0];
4222                  }                  }
4223                  print SBMLOUTPUT '<species id="'.$Compound.'_b" name="'.$Name.'" compartment="Extracellular" charge="'.$Charge.'" boundaryCondition="true"/>'."\n";                  print SBMLOUTPUT '<species id="'.$Compound.'_b" name="'.$Name.'" compartment="Extracellular" charge="'.$Charge.'" boundaryCondition="true"/>'."\n";
4224          }          }
# Line 3785  Line 4227 
4227      #Printing the list of reactions involved in the model      #Printing the list of reactions involved in the model
4228          my $ObjectiveCoef;          my $ObjectiveCoef;
4229      print SBMLOUTPUT '<listOfReactions>'."\n";      print SBMLOUTPUT '<listOfReactions>'."\n";
4230    
4231          foreach my $Reaction (@ReactionList) {          foreach my $Reaction (@ReactionList) {
4232          $ObjectiveCoef = "0.0";          $ObjectiveCoef = "0.0";
4233                  if (defined($self->figmodel()->database()->GetDBTable("REACTIONS")->{$Reaction}->[0]->{"EQUATION"}->[0])) {                  my $mdlrow = $mdlTbl->get_row_by_key($Reaction,"LOAD");
4234                    my $Reaction = $mdlrow->{"LOAD"}->[0];
4235                    my $row = $rxnTbl->get_row_by_key($Reaction,"DATABASE");
4236                    if (!defined($row)) {
4237                            $row = $bioTbl->get_row_by_key($Reaction,"DATABASE");
4238                            if (!defined($row)) {
4239                                    next;
4240                            }
4241                    }
4242                    if (!defined($row->{"EQUATION"}->[0])) {
4243                            next;
4244                    }
4245                  if ($Reaction =~ m/^bio/) {                  if ($Reaction =~ m/^bio/) {
4246                                  $ObjectiveCoef = "1.0";                                  $ObjectiveCoef = "1.0";
4247                          }                          }
4248                          my $LowerBound = -10000;                          my $LowerBound = -10000;
4249                  my $UpperBound = 10000;                  my $UpperBound = 10000;
4250                          my ($Reactants,$Products) = $self->figmodel()->GetReactionSubstrateData($Reaction);                  my ($Reactants,$Products) = $self->figmodel()->GetReactionSubstrateDataFromEquation($row->{"EQUATION"}->[0]);
4251                  my $Name = $Reaction;                  my $Name = $Reaction;
4252                  if (defined($self->figmodel()->database()->GetDBTable("REACTIONS")->{$Reaction}->[0]->{"NAME"}->[0])) {                  if (defined($row->{"NAME"}->[0])) {
4253                          $Name = $self->figmodel()->database()->GetDBTable("REACTIONS")->{$Reaction}->[0]->{"NAME"}->[0];                          $Name = $row->{"NAME"}->[0];
4254                                  $Name =~ s/[<>;&]//g;                                  $Name =~ s/[<>;&]//g;
4255                  }                  }
4256                  my $Reversibility = "true";                  my $Reversibility = "true";
4257                  if (defined($ModelTable->{$Reaction}->[0]->{"DIRECTIONALITY"}->[0])) {                  if (defined($mdlrow->{"DIRECTIONALITY"}->[0])) {
4258                          if ($ModelTable->{$Reaction}->[0]->{"DIRECTIONALITY"}->[0] ne "<=>") {                          if ($mdlrow->{"DIRECTIONALITY"}->[0] ne "<=>") {
4259                                  $LowerBound = 0;                                  $LowerBound = 0;
4260                                          $Reversibility = "false";                                          $Reversibility = "false";
4261                          }                          }
4262                          if ($ModelTable->{$Reaction}->[0]->{"DIRECTIONALITY"}->[0] eq "<=") {                          if ($mdlrow->{"DIRECTIONALITY"}->[0] eq "<=") {
4263                                  my $Temp = $Products;                                  my $Temp = $Products;
4264                                  $Products = $Reactants;                                  $Products = $Reactants;
4265                                  $Reactants = $Temp;                                  $Reactants = $Temp;
# Line 3814  Line 4268 
4268                          print SBMLOUTPUT '<reaction id="'.$Reaction.'" name="'.$Name.'" reversible="'.$Reversibility.'">'."\n";                          print SBMLOUTPUT '<reaction id="'.$Reaction.'" name="'.$Name.'" reversible="'.$Reversibility.'">'."\n";
4269                          print SBMLOUTPUT "<notes>\n";                          print SBMLOUTPUT "<notes>\n";
4270                          my $ECData = "";                          my $ECData = "";
4271                          if (defined($self->figmodel()->database()->GetDBTable("REACTIONS")->{$Reaction}->[0]->{"ENZYME"}->[0])) {                  if (defined($row->{"ENZYME"}->[0])) {
4272                                  $ECData = $self->figmodel()->database()->GetDBTable("REACTIONS")->{$Reaction}->[0]->{"ENZYME"}->[0];                          $ECData = $row->{"ENZYME"}->[0];
4273                          }                          }
4274                          my $SubsystemData = "";                          my $SubsystemData = "";
4275                          if (defined($ModelTable->{$Reaction}->[0]->{"SUBSYSTEM"}->[0])) {                  if (defined($mdlrow->{"SUBSYSTEM"}->[0])) {
4276                                  $SubsystemData = $ModelTable->{$Reaction}->[0]->{"SUBSYSTEM"}->[0];                          $SubsystemData = $mdlrow->{"SUBSYSTEM"}->[0];
4277                          }                          }
4278                          my $GeneAssociation = "";                          my $GeneAssociation = "";
4279                          my $ProteinAssociation = "";                          my $ProteinAssociation = "";
4280                          if (defined($ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}->[0])) {                  if (defined($mdlrow->{"ASSOCIATED PEG"}->[0])) {
4281                                  if (@{$ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}} == 1 && $ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}->[0] !~ m/\+/) {                          if (@{$mdlrow->{"ASSOCIATED PEG"}} == 1 && $mdlrow->{"ASSOCIATED PEG"}->[0] !~ m/\+/) {
4282                                          $GeneAssociation = $ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}->[0];                                  $GeneAssociation = $mdlrow->{"ASSOCIATED PEG"}->[0];
4283                                  } else {                                  } else {
4284                                          if (@{$ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}} > 1) {                                  if (@{$mdlrow->{"ASSOCIATED PEG"}} > 1) {
4285                                                  $GeneAssociation = "( ";                                                  $GeneAssociation = "( ";
4286                                          }                                          }
4287                                          for (my $i=0; $i < @{$ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}}; $i++) {                                  for (my $i=0; $i < @{$mdlrow->{"ASSOCIATED PEG"}}; $i++) {
4288                                                  if ($i > 0) {                                                  if ($i > 0) {
4289                                                          $GeneAssociation .= " )  or  ( ";                                                          $GeneAssociation .= " )  or  ( ";
4290                                                  }                                                  }
4291                                                  $GeneAssociation .= $ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}->[$i];                                          $GeneAssociation .= $mdlrow->{"ASSOCIATED PEG"}->[$i];
4292                                          }                                          }
4293                                          if (@{$ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}} > 1) {                                  if (@{$mdlrow->{"ASSOCIATED PEG"}} > 1) {
4294                                                  $GeneAssociation .= " )";                                                  $GeneAssociation .= " )";
4295                                          }                                          }
4296                                  }                                  }
# Line 3845  Line 4299 
4299                                          $GeneAssociation = "( ".$GeneAssociation." )";                                          $GeneAssociation = "( ".$GeneAssociation." )";
4300                                  }                                  }
4301                                  $ProteinAssociation = $GeneAssociation;                                  $ProteinAssociation = $GeneAssociation;
4302                                  if (defined($self->figmodel()->database()->GetDBTable("MODEL STATS")->{$self->id()}->[0]->{"Genome ID"}->[0])) {                          if (defined($self->genome())) {
4303                                          $ProteinAssociation = $self->figmodel()->translate_gene_to_protein($ModelTable->{$Reaction}->[0]->{"ASSOCIATED PEG"}->[0],$self->figmodel()->database()->GetDBTable("MODEL STATS")->{$self->id()}->[0]->{"Genome ID"}->[0]);                                  $ProteinAssociation = $self->figmodel()->translate_gene_to_protein($mdlrow->{"ASSOCIATED PEG"}->[0],$self->genome());
4304                                  }                                  }
4305                          }                          }
4306                          print SBMLOUTPUT "<html:p>GENE_ASSOCIATION:".$GeneAssociation."</html:p>\n";                          print SBMLOUTPUT "<html:p>GENE_ASSOCIATION:".$GeneAssociation."</html:p>\n";
# Line 3877  Line 4331 
4331              print SBMLOUTPUT "</kineticLaw>\n";              print SBMLOUTPUT "</kineticLaw>\n";
4332                          print SBMLOUTPUT '</reaction>'."\n";                          print SBMLOUTPUT '</reaction>'."\n";
4333                  }                  }
         }  
4334    
4335          my @ExchangeList = keys(%{$ExchangeHash});          my @ExchangeList = keys(%{$ExchangeHash});
4336          foreach my $ExCompound (@ExchangeList) {          foreach my $ExCompound (@ExchangeList) {
4337                  my $ExCompoundName = $ExCompound;                  my $ExCompoundName = $ExCompound;
4338                  my $Row = $self->figmodel()->database()->GetDBTable("COMPOUNDS")->get_row_by_key($ExCompound,"DATABASE");                  my $Row = $cpdTbl->get_row_by_key($ExCompound,"DATABASE");
4339                  if (defined($Row) && defined($Row->{"NAME"}->[0])) {                  if (defined($Row) && defined($Row->{"NAME"}->[0])) {
4340                          $ExCompoundName = $Row->{"NAME"}->[0];                          $ExCompoundName = $Row->{"NAME"}->[0];
4341                          $ExCompoundName =~ s/[<>;&]//g;                          $ExCompoundName =~ s/[<>;&]//g;
# Line 3922  Line 4375 
4375          close(SBMLOUTPUT);          close(SBMLOUTPUT);
4376  }  }
4377    
4378    =head3 PrintModelSimpleReactionTable
4379    Definition:
4380            success()/fail() FIGMODELmodel->PrintModelSimpleReactionTable();
4381    Description:
4382            Prints the table of model data
4383    =cut
4384    sub PrintModelSimpleReactionTable {
4385            my ($self) = @_;
4386    
4387            my $rxntbl = $self->reaction_table();
4388            my $tbl = $self->create_table_prototype("ModelSimpleReactionTable");
4389            for (my $i=0; $i < $rxntbl->size(); $i++) {
4390                    my $row = $rxntbl->get_row($i);
4391                    $row->{DATABASE} = $row->{LOAD};
4392                    $tbl->add_row($row);
4393            }
4394            $tbl->save();
4395    }
4396    
4397  =head3 PrintModelLPFile  =head3 PrintModelLPFile
4398  Definition:  Definition:
4399          success()/fail() FIGMODELmodel->PrintModelLPFile();          success()/fail() FIGMODELmodel->PrintModelLPFile();
# Line 4109  Line 4581 
4581          $self->reaction_table()->save();          $self->reaction_table()->save();
4582  }  }
4583    
4584    =head3 feature_web_data
4585    Definition:
4586            string:web output for feature/model connection = FIGMODELmodel->feature_web_data(FIGMODELfeature:feature);
4587    Description:
4588    =cut
4589    sub feature_web_data {
4590            my ($self,$feature) = @_;
4591    
4592            #First checking if the feature is in the model
4593            my $featureGenome = $feature->{GENOME}->[0];
4594            if ($feature->{GENOME}->[0] =~ m/\>(\d+\.\d+)\</) {
4595                    $featureGenome = $1;
4596            }
4597            if ($featureGenome ne $self->genome()) {
4598                    return "Not in model";
4599            }
4600            my $data = $self->get_feature_data($feature->{ID}->[0]);
4601            if (!defined($data)) {
4602                    return "Not in model";
4603            }
4604    
4605            my $output;
4606            #Printing predictions
4607            if (defined($data->{$self->id()."PREDICTIONS"})) {
4608                    #Parsing essentiality data
4609                    my $essentialityData;
4610                    if (defined($feature->{ESSENTIALITY})) {
4611                            for (my $i=0; $i < @{$feature->{ESSENTIALITY}};$i++) {
4612                                    my @temp = split(/:/,$feature->{ESSENTIALITY}->[$i]);
4613                                    $essentialityData->{$temp[0]} = $temp[1];
4614                            }
4615                    }
4616                    my $predictionHash;
4617                    for (my $i=0; $i < @{$data->{$self->id()."PREDICTIONS"}};$i++) {
4618                            my @temp = split(/:/,$data->{$self->id()."PREDICTIONS"}->[$i]);
4619                            if (defined($essentialityData->{$temp[0]})) {
4620                                    if ($temp[1] eq "essential" && $essentialityData->{$temp[0]} eq "essential") {
4621                                            push(@{$predictionHash->{"Correct negative"}},$temp[0]);
4622                                    } elsif ($temp[1] eq "nonessential" && $essentialityData->{$temp[0]} eq "essential") {
4623                                            push(@{$predictionHash->{"False positive"}},$temp[0]);
4624                                    } elsif ($temp[1] eq "essential" && $essentialityData->{$temp[0]} eq "nonessential") {
4625                                            push(@{$predictionHash->{"False negative"}},$temp[0]);
4626                                    } elsif ($temp[1] eq "nonessential" && $essentialityData->{$temp[0]} eq "nonessential") {
4627                                            push(@{$predictionHash->{"Correct positive"}},$temp[0]);
4628                                    }
4629                            } else {
4630                                    push(@{$predictionHash->{$temp[1]}},$temp[0]);
4631                            }
4632                    }
4633                    foreach my $key (keys(%{$predictionHash})) {
4634                            my $string = $key;
4635                            $string = ucfirst($string);
4636                            push(@{$output},'<span title="'.join(", ",@{$predictionHash->{$key}}).'">'.$string.'</span>');
4637                    }
4638            }
4639    
4640            #Printing reactions
4641            if (defined($data->{$self->id()."REACTIONS"})) {
4642                    for (my $i=0; $i < @{$data->{$self->id()."REACTIONS"}};$i++) {
4643                            my $rxnData = $self->get_reaction_data($data->{$self->id()."REACTIONS"}->[$i]);
4644                            my $reactionString = $self->figmodel()->web()->create_reaction_link($data->{$self->id()."REACTIONS"}->[$i],join(" or ",@{$rxnData->{"ASSOCIATED PEG"}}),$self->id());
4645                            if (defined($rxnData->{PREDICTIONS})) {
4646                                    my $predictionHash;
4647                                    for (my $i=0; $i < @{$rxnData->{PREDICTIONS}};$i++) {
4648                                            my @temp = split(/:/,$rxnData->{PREDICTIONS}->[$i]);
4649                                            push(@{$predictionHash->{$temp[1]}},$temp[0]);
4650                                    }
4651                                    $reactionString .= "(";
4652                                    foreach my $key (keys(%{$predictionHash})) {
4653                                            if ($key eq "Essential =>") {
4654                                                    $reactionString .= '<span title="Essential in '.join(",",@{$predictionHash->{$key}}).'">E=></span>,';
4655                                            } elsif ($key eq "Essential <=") {
4656                                                    $reactionString .= '<span title="Essential in '.join(",",@{$predictionHash->{$key}}).'">E<=</span>,';
4657                                            } elsif ($key eq "Active =>") {
4658                                                    $reactionString .= '<span title="Active in '.join(",",@{$predictionHash->{$key}}).'">A=></span>,';
4659                                            } elsif ($key eq "Active <=") {
4660                                                    $reactionString .= '<span title="Active in '.join(",",@{$predictionHash->{$key}}).'">A<=</span>,';
4661                                            } elsif ($key eq "Active <=>") {
4662                                                    $reactionString .= '<span title="Active in '.join(",",@{$predictionHash->{$key}}).'">A</span>,';
4663                                            } elsif ($key eq "Inactive") {
4664                                                    $reactionString .= '<span title="Inactive in '.join(",",@{$predictionHash->{$key}}).'">I</span>,';
4665                                            } elsif ($key eq "Dead") {
4666                                                    $reactionString .= '<span title="Dead">D</span>,';
4667                                            }
4668                                    }
4669                                    $reactionString =~ s/,$/)/;
4670                            }
4671                            push(@{$output},$reactionString);
4672                    }
4673            }
4674    
4675            #Returning output
4676            return join("<br>",@{$output});
4677    }
4678    
4679    =head3 remove_obsolete_reactions
4680    Definition:
4681            void FIGMODELmodel->remove_obsolete_reactions();
4682    Description:
4683    =cut
4684    sub remove_obsolete_reactions {
4685            my ($self) = @_;
4686    
4687            (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"));
4688            my $rxnTbl = $self->reaction_table();
4689            if (defined($rxnTbl)) {
4690                    for (my $i=0; $i < $rxnTbl->size(); $i++) {
4691                            my $row = $rxnTbl->get_row($i);
4692                            if (defined($translation->{$row->{LOAD}->[0]}) || defined($translation->{$row->{LOAD}->[0]."r"})) {
4693                                    my $direction = $row->{DIRECTION}->[0];
4694                                    my $newRxn;
4695                                    if (defined($translation->{$row->{LOAD}->[0]."r"})) {
4696                                            $newRxn = $translation->{$row->{LOAD}->[0]."r"};
4697                                            if ($direction eq "<=") {
4698                                                    $direction = "=>";
4699                                            } elsif ($direction eq "=>") {
4700                                                    $direction = "<=";
4701                                            }
4702                                    } else {
4703                                            $newRxn = $translation->{$row->{LOAD}->[0]};
4704                                    }
4705                                    #Checking if the new reaction is already in the model
4706                                    my $newRow = $rxnTbl->get_row_by_key($newRxn,"LOAD");
4707                                    if (defined($newRow)) {
4708                                            #Handling direction
4709                                            if ($newRow->{DIRECTION}->[0] ne $direction) {
4710                                                    $newRow->{DIRECTION}->[0] = "<=>";
4711                                            }
4712                                            push(@{$row->{"ASSOCIATED PEG"}},@{$rxnTbl->get_row($i)->{"ASSOCIATED PEG"}});
4713                                    } else {
4714                                            $rxnTbl->get_row($i)->{LOAD}->[0] = $newRxn;
4715                                            $rxnTbl->get_row($i)->{DIRECTION}->[0] = $direction;
4716                                    }
4717                            }
4718                    }
4719                    $rxnTbl->save();
4720            }
4721    }
4722    
4723    =pod
4724    
4725    =item * [string]:I<list of essential genes> = B<run_geneKO_slow> (string:I<media>,0/1:I<max growth>,0/1:I<save results>);
4726    
4727    =cut
4728    
4729    sub run_geneKO_slow {
4730            my ($self,$media,$maxGrowth,$save) = @_;
4731            my $output;
4732            my $UniqueFilename = $self->figmodel()->filename();
4733            if (defined($maxGrowth) && $maxGrowth == 1) {
4734                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$media,["ProductionMFA"],{"perform single KO experiments" => 1,"MFASolver" => "GLPK","Constrain objective to this fraction of the optimal value" => 0.999},"SlowGeneKO-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,$self->selected_version()));
4735            } else {
4736                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$media,["ProductionMFA"],{"perform single KO experiments" => 1,"MFASolver" => "GLPK","Constrain objective to this fraction of the optimal value" => 0.1},"SlowGeneKO-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,$self->selected_version()));
4737            }
4738            if (!-e $self->config("MFAToolkit output directory")->[0].$UniqueFilename."DeletionStudyResults.txt") {
4739                    print "Deletion study file not found!.\n";
4740                    return undef;
4741            }
4742            my $deltbl = $self->figmodel()->database()->load_table($self->config("MFAToolkit output directory")->[0].$UniqueFilename."DeletionStudyResults.txt",";","|",1,["Experiment"]);
4743            for (my $i=0; $i < $deltbl->size(); $i++) {
4744                    my $row = $deltbl->get_row($i);
4745                    if ($row->{"Insilico growth"}->[0] < 0.0000001) {
4746                            push(@{$output},$row->{Experiment}->[0]);
4747                    }
4748            }
4749            if (defined($output)) {
4750                    if (defined($save) && $save == 1) {
4751                            my $tbl = $self->essentials_table();
4752                            my $row = $tbl->get_row_by_key($media,"MEDIA",1);
4753                            $row->{"ESSENTIAL GENES"} = $output;
4754                            $tbl->save();
4755                    }
4756            }
4757            return $output;
4758    }
4759    
4760    =pod
4761    
4762    =item * [string]:I<list of minimal genes> = B<run_gene_minimization> (string:I<media>,0/1:I<max growth>,0/1:I<save results>);
4763    
4764    =cut
4765    
4766    sub run_gene_minimization {
4767            my ($self,$media,$maxGrowth,$save) = @_;
4768            my $output;
4769    
4770            #Running the MFAToolkit
4771            my $UniqueFilename = $self->figmodel()->filename();
4772            if (defined($maxGrowth) && $maxGrowth == 1) {
4773                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$media,["ProductionMFA"],{"optimize organism genes" => 1,"MFASolver" => "CPLEX","Constrain objective to this fraction of the optimal value" => 0.999},"MinimizeGenes-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,$self->selected_version()));
4774            } else {
4775                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$media,["ProductionMFA"],{"optimize organism genes" => 1,"MFASolver" => "CPLEX","Constrain objective to this fraction of the optimal value" => 0.1},"MinimizeGenes-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,$self->selected_version()));
4776            }
4777            my $tbl = $self->figmodel()->LoadProblemReport($UniqueFilename);
4778            if (!defined($tbl)) {
4779                    return undef;
4780            }
4781            for (my $i=0; $i < $tbl->size(); $i++) {
4782                    my $row = $tbl->get_row($i);
4783                    if ($row->{Notes}->[0] =~ m/Recursive\sMILP\sGENE_USE\soptimization/) {
4784                            my @array = split(/\|/,$row->{Notes}->[0]);
4785                            my $solution = $array[0];
4786                            $_ = $solution;
4787                            my @OriginalArray = /(peg\.\d+)/g;
4788                            push(@{$output},@OriginalArray);
4789                            last;
4790                    }
4791            }
4792    
4793            if (defined($output)) {
4794                    if (defined($save) && $save == 1) {
4795                            my $tbl = $self->load_model_table("MinimalGenes");
4796                            my $row = $tbl->get_table_by_key("MEDIA",$media)->get_row_by_key("MAXGROWTH",$maxGrowth);
4797                            if (defined($row)) {
4798                                    $row->{GENES} = $output;
4799                            } else {
4800                                    $tbl->add_row({GENES => $output,MEDIA => [$media],MAXGROWTH => [$maxGrowth]});
4801                            }
4802                            $tbl->save();
4803                    }
4804            }
4805            return $output;
4806    }
4807    
4808    =pod
4809    
4810    =item * [string]:I<list of inactive genes> = B<identify_inactive_genes> (string:I<media>,0/1:I<max growth>,0/1:I<save results>);
4811    
4812    =cut
4813    
4814    sub identify_inactive_genes {
4815            my ($self,$media,$maxGrowth,$save) = @_;
4816            my $output;
4817            #Running the MFAToolkit
4818            my $UniqueFilename = $self->figmodel()->filename();
4819            if (defined($maxGrowth) && $maxGrowth == 1) {
4820                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$media,["ProductionMFA"],{"find tight bounds" => 1,"MFASolver" => "GLPK","Constrain objective to this fraction of the optimal value" => 0.999},"Classify-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,$self->selected_version()));
4821            } else {
4822                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$media,["ProductionMFA"],{"find tight bounds" => 1,"MFASolver" => "GLPK","Constrain objective to this fraction of the optimal value" => 0.1},"Classify-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,$self->selected_version()));
4823            }
4824            #Reading in the output bounds file
4825            my $ReactionTB;
4826            if (-e $self->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/TightBoundsReactionData0.txt") {
4827                    $ReactionTB = $self->figmodel()->database()->load_table($self->config("MFAToolkit output directory")->[0].$UniqueFilename."/MFAOutput/TightBoundsReactionData0.txt",";","|",1,["DATABASE ID"]);
4828            }
4829            if (!defined($ReactionTB)) {
4830                    print STDERR "FIGMODEL:ClassifyModelReactions: Classification file not found when classifying reactions in ".$self->id().$self->selected_version()." with ".$media." media. Most likely the model did not grow.\n";
4831                    return undef;
4832            }
4833            #Clearing output
4834            $self->figmodel()->clearing_output($UniqueFilename,"Classify-".$self->id().$self->selected_version()."-".$UniqueFilename.".log");
4835            my $geneHash;
4836            my $activeGeneHash;
4837            for (my $i=0; $i < $ReactionTB->size(); $i++) {
4838                    my $Row = $ReactionTB->get_row($i);
4839                    if (defined($Row->{"Min FLUX"}) && defined($Row->{"Max FLUX"}) && defined($Row->{"DATABASE ID"}) && $Row->{"DATABASE ID"}->[0] =~ m/rxn\d\d\d\d\d/) {
4840                            my $data = $self->get_reaction_data($Row->{"DATABASE ID"}->[0]);
4841                            if (defined($data->{"ASSOCIATED PEG"})) {
4842                                    my $active = 0;
4843                                    if ($Row->{"Min FLUX"}->[0] > 0.00000001 || $Row->{"Max FLUX"}->[0] < -0.00000001 || ($Row->{"Max FLUX"}->[0]-$Row->{"Min FLUX"}->[0]) > 0.00000001) {
4844                                            $active = 1;
4845                                    }
4846                                    for (my $j=0; $j < @{$data->{"ASSOCIATED PEG"}}; $j++) {
4847                                            $_ = $data->{"ASSOCIATED PEG"}->[$j];
4848                                            my @OriginalArray = /(peg\.\d+)/g;
4849                                            for (my $k=0; $k < @OriginalArray; $k++) {
4850                                                    if ($active == 1) {
4851                                                            $activeGeneHash->{$OriginalArray[$k]} = 1;
4852                                                    }
4853                                                    $geneHash->{$OriginalArray[$k]} = 1;
4854                                            }
4855                                    }
4856                            }
4857                    }
4858            }
4859            my @allGenes = keys(%{$geneHash});
4860            for (my $i=0; $i < @allGenes; $i++) {
4861                    if (!defined($activeGeneHash->{$allGenes[$i]})) {
4862                            push(@{$output},$allGenes[$i]);
4863                    }
4864            }
4865            if (defined($output)) {
4866                    if (defined($save) && $save == 1) {
4867                            my $tbl = $self->load_model_table("InactiveGenes");
4868                            my $row = $tbl->get_table_by_key("MEDIA",$media)->get_row_by_key("MAXGROWTH",$maxGrowth);
4869                            if (defined($row)) {
4870                                    $row->{GENES} = $output;
4871                            } else {
4872                                    $tbl->add_row({GENES => $output,MEDIA => [$media],MAXGROWTH => [$maxGrowth]});
4873                            }
4874                            $tbl->save();
4875                    }
4876            }
4877            return $output;
4878    }
4879    
4880    sub ConvertVersionsToHistoryFile {
4881            my ($self) = @_;
4882            my $vone = 0;
4883            my $vtwo = 0;
4884            my $continue = 1;
4885            my $lastTable;
4886            my $currentTable;
4887            my $cause;
4888            my $lastChanged = 0;
4889            my $noHitCount = 0;
4890            while ($continue == 1) {
4891                    $cause = "NONE";
4892                    $currentTable = undef;
4893                    if (-e $self->directory().$self->id()."V".($vone+1).".".$vtwo.".txt") {
4894                            $noHitCount = 0;
4895                            $lastChanged = 0;
4896                            $vone = $vone+1;
4897                            $currentTable = $self->figmodel()->database()->load_table($self->directory().$self->id()."V".$vone.".".$vtwo.".txt",";","|",1,["LOAD","DIRECTIONALITY","COMPARTMENT","ASSOCIATED PEG"]);
4898                            $cause = "RECONSTRUCTION";
4899                    } elsif (-e $self->directory().$self->id()."V".$vone.".".($vtwo+1).".txt") {
4900                            $noHitCount = 0;
4901                            $lastChanged = 0;
4902                            $vtwo = $vtwo+1;
4903                            $currentTable = $self->figmodel()->database()->load_table($self->directory().$self->id()."V".$vone.".".$vtwo.".txt",";","|",1,["LOAD","DIRECTIONALITY","COMPARTMENT","ASSOCIATED PEG"]);
4904                            $cause = "AUTOCOMPLETION";
4905                    } elsif ($lastChanged == 0) {
4906                            $lastChanged = 1;
4907                            $vone = $vone+1;
4908                            $cause = "RECONSTRUCTION";
4909                    } elsif ($lastChanged == 1) {
4910                            $lastChanged = 2;
4911                            $vone = $vone-1;
4912                            $vtwo = $vtwo+1;
4913                            $cause = "AUTOCOMPLETION";
4914                    } elsif ($lastChanged == 2) {
4915                            $lastChanged = 0;
4916                            $vone = $vone+1;
4917                            $cause = "RECONSTRUCTION";
4918                    }
4919                    if (defined($currentTable)) {
4920                            if (defined($lastTable)) {
4921                                    print $cause."\t".$self->directory().$self->id()."V".$vone.".".$vtwo.".txt\n";
4922                                    $self->calculate_model_changes($lastTable,$cause,$currentTable,"V".$vone.".".$vtwo);
4923                            }
4924                            $lastTable = $currentTable;
4925                    } else {
4926                            $noHitCount++;
4927                            if ($noHitCount >= 40) {
4928                                    last;
4929                            }
4930                    }
4931            }
4932    }
4933    
4934  1;  1;

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.25

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3