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

Diff of /FigKernelPackages/FIGMODELmodel.pm

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

revision 1.2, Fri Dec 11 21:37:02 2009 UTC revision 1.15, Wed May 19 21:02:11 2010 UTC
# Line 1  Line 1 
 package FIGMODELmodel;  
1  use strict;  use strict;
2    package FIGMODELmodel;
3    
4  =head1 FIGMODELmodel object  =head1 FIGMODELmodel object
5  =head2 Introduction  =head2 Introduction
# Line 14  Line 14 
14  =cut  =cut
15  sub new {  sub new {
16          my ($class,$figmodel,$id) = @_;          my ($class,$figmodel,$id) = @_;
17    
18          #Error checking first          #Error checking first
19          if (!defined($figmodel)) {          if (!defined($figmodel)) {
20                  print STDERR "FIGMODELmodel->new(undef,".$id."):figmodel must be defined to create a model object!\n";                  print STDERR "FIGMODELmodel->new(undef,".$id."):figmodel must be defined to create a model object!\n";
# Line 27  Line 28 
28          }          }
29    
30          #Checking that the id exists          #Checking that the id exists
31          my $tbl = $self->figmodel()->database()->GetDBTable("MODELS");          my $modelHandle = $self->figmodel()->database()->get_object_manager("model");
32          if (!defined($tbl)) {          if (!defined($modelHandle)) {
33                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not load MODELS table. Check database!");                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not load MODELS table. Check database!");
34                  return undef;                  return undef;
35          }          }
36    
37          #If the id is a number, we get the model row by index          #If the id is a number, we get the model row by index
         my $index = $id;  
38          if ($id =~ m/^\d+$/) {          if ($id =~ m/^\d+$/) {
39                  $self->{_data} = $tbl->get_row($id);                  my $objects = $modelHandle->get_objects();
40          } else {                  $self->{_data} = $objects->[$id];
41                  $self->{_data} = $tbl->get_row_by_key($id,"id");                  $self->figmodel()->{_models}->{$id} = $self;
42                  if (defined($self->{_data})) {          } else {
43                          $index = $tbl->row_index($self->{_data});                  my $objects = $modelHandle->get_objects({id => $id});
44                    if (!defined($objects->[0]) && $id =~ m/(.+)(V[^V]+)/) {
45                            $objects = $modelHandle->get_objects({id => $1});
46                            if (!defined($objects->[0])) {
47                                    $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find model ".$id." in database!");
48                                    return undef;
49                  }                  }
50                            $self->{_selectedversion} = $2;
51                    } elsif (!defined($objects->[0])) {
52                            $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find model ".$id." in database!");
53                            return undef;
54                    }
55                    $self->{_data} = $objects->[0];
56          }          }
57          if (!defined($self->{_data})) {          if (!defined($self->{_data})) {
58                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find specified id in database!");                  $self->figmodel()->error_message("FIGMODELmodel->new(figmodel,".$id."):could not find specified id in database!");
59                  return undef;                  return undef;
60          }          }
         $self->{_index} = $index;  
61          $self->figmodel()->{_models}->{$self->id()} = $self;          $self->figmodel()->{_models}->{$self->id()} = $self;
         $self->figmodel()->{_models}->{$self->index()} = $self;  
62    
63          return $self;          return $self;
64  }  }
# Line 107  Line 116 
116  =cut  =cut
117  sub fig {  sub fig {
118          my ($self) = @_;          my ($self) = @_;
   
119          if (!defined($self->{_fig}) && $self->source() !~ /^MGRAST/) {          if (!defined($self->{_fig}) && $self->source() !~ /^MGRAST/) {
120                  if ($self->source() =~ /^RAST/) {                  if ($self->source() =~ /^RAST/) {
121                          $self->{"_fig"} = $self->figmodel()->fig();#$self->genome());                          $self->{"_fig"} = $self->figmodel()->fig();#$self->genome());
# Line 115  Line 123 
123                          $self->{"_fig"} = $self->figmodel()->fig();                          $self->{"_fig"} = $self->figmodel()->fig();
124                  }                  }
125          }          }
   
126          return $self->{"_fig"};          return $self->{"_fig"};
127  }  }
128    
129    =head3 aquireModelLock
130    
131    Definition:
132    
133            FIGMODELmodel->aquireModelLock();
134    
135    Description:
136    
137            Locks the database for alterations relating to the current model object
138    
139    =cut
140    sub aquireModelLock {
141            my ($self) = @_;
142            $self->figmodel()->database()->genericLock($self->id());
143    }
144    
145    =head3 releaseModelLock
146    
147    Definition:
148    
149            FIGMODELmodel->releaseModelLock();
150    
151    Description:
152    
153            Unlocks the database for alterations relating to the current model object
154    
155    =cut
156    sub releaseModelLock {
157            my ($self) = @_;
158            $self->figmodel()->database()->genericUnlock($self->id());
159    }
160    
161  =head3 mgdata  =head3 mgdata
162  Definition:  Definition:
163          FIGMODEL = FIGMODELmodel->mgdata();          FIGMODEL = FIGMODELmodel->mgdata();
# Line 127  Line 166 
166  =cut  =cut
167  sub mgdata {  sub mgdata {
168          my ($self) = @_;          my ($self) = @_;
   
169          if (!defined($self->{_mgdata}) && $self->source() =~ /^MGRAST/) {          if (!defined($self->{_mgdata}) && $self->source() =~ /^MGRAST/) {
170                  require MGRAST;                  require MGRAST;
171                  $self->{_mgdata} = $self->figmodel()->mgrast()->Job->get_objects( { 'genome_id' => $self->genome() } )                  $self->{_mgdata} = $self->figmodel()->mgrast()->Job->get_objects( { 'genome_id' => $self->genome() } )
172          }          }
   
173          return $self->{_mgdata};          return $self->{_mgdata};
174  }  }
175    
# Line 144  Line 181 
181  =cut  =cut
182  sub id {  sub id {
183          my ($self) = @_;          my ($self) = @_;
184          return $self->{_data}->{id}->[0];          return $self->{_data}->id();
185  }  }
186    
187  =head3 owner  =head3 owner
# Line 155  Line 192 
192  =cut  =cut
193  sub owner {  sub owner {
194          my ($self) = @_;          my ($self) = @_;
195          return $self->{_data}->{owner}->[0];          return $self->{_data}->owner();
 }  
   
 =head3 index  
 Definition:  
         string = FIGMODELmodel->index();  
 Description:  
         Returns model index  
 =cut  
 sub index {  
         my ($self) = @_;  
         return $self->{_index};  
196  }  }
197    
198  =head3 name  =head3 name
# Line 185  Line 211 
211                          if (defined($self->mgdata())) {                          if (defined($self->mgdata())) {
212                                  $self->{_name} = $self->mgdata()->genome_name;                                  $self->{_name} = $self->mgdata()->genome_name;
213                          }                          }
                 } elsif (defined($self->stats())) {  
                         $self->{_name} = $self->stats()->{'Organism name'}->[0];  
214                  } elsif ($source !~ /^RAST/) {                  } elsif ($source !~ /^RAST/) {
215                          $self->{_name} = $self->fig()->orgname_of_orgid($self->genome());                          $self->{_name} = $self->fig()->orgname_of_orgid($self->genome());
216                    } else {
217                            $self->{_name} = $self->figmodel()->get_genome_stats($self->genome())->{NAME}->[0];
218                  }                  }
219          }          }
220    
221          return $self->{_name};          return $self->{_name};
222  }  }
223    
 =head3 stats  
 Definition:  
         string = FIGMODELmodel->stats();  
 Description:  
         Returns model stats  
 =cut  
 sub stats {  
         my ($self) = @_;  
   
         if (!defined($self->{_stats})) {  
                 $self->{_stats} = $self->figmodel()->database()->GetDBTable("MODEL STATS")->get_row_by_key($self->id(),"Model ID");  
         }  
         return $self->{_stats};  
 }  
   
224  =head3 get_reaction_class  =head3 get_reaction_class
225  Definition:  Definition:
226          string = FIGMODELmodel->get_reaction_class(string::reaction ID);          string = FIGMODELmodel->get_reaction_class(string::reaction ID);
# Line 230  Line 241 
241                  my $ClassRow = $self->{_reaction_classes}->get_row_by_key($reaction,"REACTION");                  my $ClassRow = $self->{_reaction_classes}->get_row_by_key($reaction,"REACTION");
242                  if (defined($ClassRow) && defined($ClassRow->{CLASS})) {                  if (defined($ClassRow) && defined($ClassRow->{CLASS})) {
243                          my $class;                          my $class;
244                            my $min = $ClassRow->{MIN}->[0];
245                            my $max = $ClassRow->{MAX}->[0];
246                          if ($ClassRow->{CLASS}->[0] eq "Positive") {                          if ($ClassRow->{CLASS}->[0] eq "Positive") {
247                                  $class = "Essential =>";                                  $class = "Essential =>";
248                                    $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>";
249                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative") {
250                                  $class = "Essential <=";                                  $class = "Essential <=";
251                                    $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>";
252                          } elsif ($ClassRow->{CLASS}->[0] eq "Positive variable") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Positive variable") {
253                                  $class = "Active =>";                                  $class = "Active =>";
254                                    $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>";
255                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative variable") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Negative variable") {
256                                  $class = "Active <=";                                  $class = "Active <=";
257                                    $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>";
258                          } elsif ($ClassRow->{CLASS}->[0] eq "Variable") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Variable") {
259                                  $class = "Active <=>";                                  $class = "Active <=>";
260                                    $class.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>";
261                          } elsif ($ClassRow->{CLASS}->[0] eq "Blocked") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Blocked") {
262                                  $class = "Inactive";                                  $class = "Inactive";
263                          } elsif ($ClassRow->{CLASS}->[0] eq "Dead") {                          } elsif ($ClassRow->{CLASS}->[0] eq "Dead") {
264                                  $class = "Disconnected";                                  $class = "Disconnected";
265                          }                          }
266    
267                          if (!defined($nohtml) || $nohtml ne "1") {                          if (!defined($nohtml) || $nohtml ne "1") {
268                                  $class = "<span title=\"Flux:".$ClassRow->{MIN}->[0]." to ".$ClassRow->{MAX}->[0]."\">".$class."</span>";                                  $class = "<span title=\"Flux:".$min." to ".$max."\">".$class."</span>";
269                          }                          }
270    
271                          return $class;                          return $class;
272                  }                  }
273                  return undef;                  return undef;
# Line 268  Line 288 
288                                  $classstring .= "<br>";                                  $classstring .= "<br>";
289                          }                          }
290                          my $NewClass;                          my $NewClass;
291                            my $min = $ClassRow->{MIN}->[$i];
292                            my $max = $ClassRow->{MAX}->[$i];
293                          if ($ClassRow->{CLASS}->[$i] eq "Positive") {                          if ($ClassRow->{CLASS}->[$i] eq "Positive") {
294                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential =>";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential =>";
295                                  if (!defined($nohtml) || $nohtml ne "1") {                                  $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>";
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
296                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative") {
297                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential <=";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Essential <=";
298                                  if (!defined($nohtml) || $nohtml ne "1") {                                  $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>";
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
299                          } elsif ($ClassRow->{CLASS}->[$i] eq "Positive variable") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Positive variable") {
300                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active =>";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active =>";
301                                  if (!defined($nohtml) || $nohtml ne "1") {                                  $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>";
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
302                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative variable") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Negative variable") {
303                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=";
304                                  if (!defined($nohtml) || $nohtml ne "1") {                                  $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>";
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
305                          } elsif ($ClassRow->{CLASS}->[$i] eq "Variable") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Variable") {
306                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=>";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Active <=>";
307                                  if (!defined($nohtml) || $nohtml ne "1") {                                  $NewClass.="<br>[Flux: ".sprintf("%.3g",$min)." to ".sprintf("%.3g",$max)."]<br>";
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
308                          } elsif ($ClassRow->{CLASS}->[$i] eq "Blocked") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Blocked") {
309                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Inactive";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Inactive";
                                 if (!defined($nohtml) || $nohtml ne "1") {  
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
                                 }  
310                          } elsif ($ClassRow->{CLASS}->[$i] eq "Dead") {                          } elsif ($ClassRow->{CLASS}->[$i] eq "Dead") {
311                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Disconnected";                                  $NewClass = $ClassRow->{MEDIA}->[$i].":Disconnected";
                                 if (!defined($nohtml) || $nohtml ne "1") {  
                                         $NewClass = "<span title=\"Flux:".$ClassRow->{MIN}->[$i]." to ".$ClassRow->{MAX}->[$i]."\">".$NewClass."</span>";  
312                                  }                                  }
313    
314                            if (!defined($nohtml) || $nohtml ne "1") {
315                                    $NewClass = "<span title=\"Flux:".$min." to ".$max."\">".$NewClass."</span>";
316                          }                          }
317                          $classstring .= $NewClass;                          $classstring .= $NewClass;
318                  }                  }
# Line 366  Line 376 
376          return $Data->{LOAD}->[0];          return $Data->{LOAD}->[0];
377  }  }
378    
379    =head3 load_model_table
380    
381    Definition: FIGMODELTable = FIGMODELmodel->load_model_table(string:table name,0/1:refresh the table));
382    
383    Description: Returns the table specified by the input filename. Table will be stored in a file in the model directory.
384    
385    =cut
386    sub load_model_table {
387            my ($self,$name,$refresh) = @_;
388            if (!defined($refresh)) {
389                    $refresh = 1;
390            }
391            if ($refresh == 1) {
392                    delete $self->{"_".$name};
393            }
394            if (!defined($self->{"_".$name})) {
395                    my $tbldef = $self->figmodel()->config("$name");
396                    if (!defined($tbldef)) {
397                            return undef;
398                    }
399                    my $filename = $self->directory().$name."-".$self->id().$self->selected_version().".tbl";
400                    $self->{"_".$name} = $self->figmodel()->database()->load_table($filename,"\t","|",$tbldef->{headingline}->[0],$tbldef->{hashcolumns});
401                    if (!defined($self->{"_".$name})) {
402                            if (defined($tbldef->{prefix})) {
403                                    $self->{"_".$name} = FIGMODELTable->new($tbldef->{columns},$filename,$tbldef->{hashcolumns},"\t","|",join(@{$tbldef->{prefix}},"\n"));
404                            } else {
405                                    $self->{"_".$name} = FIGMODELTable->new($tbldef->{columns},$filename,$tbldef->{hashcolumns},"\t","|");
406                            }
407                    }
408            }
409            return $self->{"_".$name};
410    }
411    
412    =head3 create_table_prototype
413    
414    Definition:
415            FIGMODELTable::table = FIGMODELmodel->create_table_prototype(string::table);
416    Description:
417            Returns a empty FIGMODELTable with all the metadata associated with the input table name
418    
419    =cut
420    sub create_table_prototype {
421            my ($self,$TableName) = @_;
422    
423            #Checking if the table definition exists in the FIGMODELconfig file
424            if (!defined($self->figmodel()->config($TableName))) {
425                    $self->figmodel()->error_message("FIGMODELdatabase:create_table_prototype:Definition not found for ".$TableName);
426                    return undef;
427            }
428            #Checking that this is a database table
429            if (!defined($self->config($TableName)->{tabletype}) || $self->config($TableName)->{tabletype}->[0] ne "ModelTable") {
430                    $self->figmodel()->error_message("FIGMODELdatabase:create_table_prototype:".$TableName." is not a model table!");
431                    return undef;
432            }
433            if (!defined($self->config($TableName)->{delimiter})) {
434                    $self->config($TableName)->{delimiter}->[0] = ";";
435            }
436            if (!defined($self->config($TableName)->{itemdelimiter})) {
437                    $self->config($TableName)->{itemdelimiter}->[0] = "|";
438            }
439            my $prefix;
440            if (defined($self->config($TableName)->{prefix})) {
441                    $prefix = join("\n",@{$self->config($TableName)->{prefix}});
442            }
443            my $tbl = FIGMODELTable->new($self->config($TableName)->{columns},$self->directory().$self->config($TableName)->{filename_prefix}->[0]."-".$self->id().$self->selected_version().".txt",$self->config($TableName)->{hashcolumns},$self->config($TableName)->{delimiter}->[0],$self->config($TableName)->{itemdelimiter}->[0],$prefix);
444            return $tbl;
445    }
446    
447  =head3 get_reaction_number  =head3 get_reaction_number
448  Definition:  Definition:
449          int = FIGMODELmodel->get_reaction_number();          int = FIGMODELmodel->get_reaction_number();
# Line 374  Line 452 
452  =cut  =cut
453  sub get_reaction_number {  sub get_reaction_number {
454          my ($self) = @_;          my ($self) = @_;
   
455          if (!defined($self->reaction_table())) {          if (!defined($self->reaction_table())) {
456                  return 0;                  return 0;
457          }          }
   
458          return $self->reaction_table()->size();          return $self->reaction_table()->size();
459  }  }
460    
# Line 393  Line 469 
469    
470          if (!defined($self->{_reaction_data})) {          if (!defined($self->{_reaction_data})) {
471                  $self->{_reaction_data} = $self->figmodel()->database()->GetDBModel($self->id());                  $self->{_reaction_data} = $self->figmodel()->database()->GetDBModel($self->id());
472                    my $classTbl = $self->reaction_class_table();
473                    for (my $i=0; $i < $classTbl->size(); $i++) {
474                            my $row = $classTbl->get_row($i);
475                            my $rxnRow = $self->{_reaction_data}->get_row_by_key($row->{"REACTION"}->[0],"LOAD");
476                            for (my $j=0; $j < @{$row->{MEDIA}};$j++) {
477                                    my $class = "Active <=>";
478                                    if ($row->{CLASS}->[$j] eq "Positive") {
479                                            $class = "Essential =>";
480                                    } elsif ($row->{CLASS}->[$j] eq "Negative") {
481                                            $class = "Essential <=";
482                                    } elsif ($row->{CLASS}->[$j] eq "Blocked") {
483                                            $class = "Inactive";
484                                    } elsif ($row->{CLASS}->[$j] eq "Positive variable") {
485                                            $class = "Active =>";
486                                    } elsif ($row->{CLASS}->[$j] eq "Negative variable") {
487                                            $class = "Active <=";
488                                    } elsif ($row->{CLASS}->[$j] eq "Variable") {
489                                            $class = "Active <=>";
490                                    } elsif ($row->{CLASS}->[$j] eq "Dead") {
491                                            $class = "Dead";
492                                    }
493                                    push(@{$rxnRow->{PREDICTIONS}},$row->{MEDIA}->[$j].":".$class);
494                            }
495                    }
496          }          }
497    
498          return $self->{_reaction_data};          return $self->{_reaction_data};
499  }  }
500    
501    =head3 feature_table
502    Definition:
503            FIGMODELTable = FIGMODELmodel->feature_table();
504    Description:
505            Returns FIGMODELTable with the feature list for the model
506    =cut
507    sub feature_table {
508            my ($self) = @_;
509    
510            if (!defined($self->{_feature_data})) {
511                    #Getting the genome feature list
512                    my $FeatureTable = $self->figmodel()->GetGenomeFeatureTable($self->genome());
513                    if (!defined($FeatureTable)) {
514                            print STDERR "FIGMODELmodel:feature_table:Could not get features for genome ".$self->genome()." in database!";
515                            return undef;
516                    }
517                    #Getting the reaction table for the model
518                    my $rxnTable = $self->reaction_table();
519                    if (!defined($rxnTable)) {
520                    print STDERR "FIGMODELmodel:feature_table:Could not get reaction table for model ".$self->id()." in database!";
521                            return undef;
522                }
523                    #Cloning the feature table
524                    $self->{_feature_data} = $FeatureTable->clone_table_def();
525                    $self->{_feature_data}->add_headings(($self->id()."REACTIONS",$self->id()."PREDICTIONS"));
526                for (my $i=0; $i < $rxnTable->size(); $i++) {
527                    my $Row = $rxnTable->get_row($i);
528                    if (defined($Row) && defined($Row->{"ASSOCIATED PEG"})) {
529                            foreach my $GeneSet (@{$Row->{"ASSOCIATED PEG"}}) {
530                                    my $temp = $GeneSet;
531                                    $temp =~ s/\+/|/g;
532                                    $temp =~ s/\sAND\s/|/gi;
533                                    $temp =~ s/\sOR\s/|/gi;
534                                    $temp =~ s/[\(\)\s]//g;
535                                    my @GeneList = split(/\|/,$temp);
536                                    foreach my $Gene (@GeneList) {
537                                    my $FeatureRow = $self->{_feature_data}->get_row_by_key("fig|".$self->genome().".".$Gene,"ID");
538                                                    if (!defined($FeatureRow)) {
539                                                            $FeatureRow = $FeatureTable->get_row_by_key("fig|".$self->genome().".".$Gene,"ID");
540                                                            if (defined($FeatureRow)) {
541                                                                    $self->{_feature_data}->add_row($FeatureRow);
542                                                            }
543                                                    }
544                                                    if (defined($FeatureRow)) {
545                                                            $self->{_feature_data}->add_data($FeatureRow,$self->id()."REACTIONS",$Row->{"LOAD"}->[0],1);
546                                                    }
547                                    }
548                            }
549                    }
550                }
551                #Loading predictions
552                my @files = glob($self->directory()."EssentialGenes-".$self->id()."-*");
553                foreach my $file (@files) {
554                    if ($file =~ m/\-([^\-]+)\.tbl/) {
555                            my $media = $1;
556                            my $list = $self->figmodel()->database()->load_single_column_file($file,"");
557                            my $hash;
558                            foreach my $gene (@{$list}) {
559                                    $hash->{$gene} = 1;
560                            }
561                            for (my $i=0; $i < $self->{_feature_data}->size(); $i++) {
562                                    my $Row = $self->{_feature_data}->get_row($i);
563                                    if ($Row->{ID}->[0] =~ m/(peg\.\d+)/) {
564                                            my $gene = $1;
565                                            if (defined($hash->{$gene})) {
566                                                    push(@{$Row->{$self->id()."PREDICTIONS"}},$media.":essential");
567                                            } else {
568                                                    push(@{$Row->{$self->id()."PREDICTIONS"}},$media.":nonessential");
569                                            }
570                                    }
571                            }
572                    }
573                }
574            }
575            return $self->{_feature_data};
576    }
577    
578  =head3 reaction_class_table  =head3 reaction_class_table
579  Definition:  Definition:
580          FIGMODELTable = FIGMODELmodel->reaction_class_table();          FIGMODELTable = FIGMODELmodel->reaction_class_table();
# Line 438  Line 615 
615          return $self->{_compound_class_table};          return $self->{_compound_class_table};
616  }  }
617    
618    =head3 get_essential_genes
619    Definition:
620            [string::peg ID] = FIGMODELmodel->get_essential_genes(string::media condition);
621    Description:
622            Returns an reference to an array of the predicted essential genes during growth in the input media condition
623    =cut
624    sub get_essential_genes {
625            my ($self,$media) = @_;
626    
627            if (!defined($media)) {
628                    $media = "Complete";
629            }
630            if (!defined($self->{_essential_genes}->{$media})) {
631                    $self->{_essential_genes}->{$media} = undef;
632                    if (-e $self->directory()."EssentialGenes-".$self->id().$self->selected_version()."-".$media.".tbl") {
633                            $self->{_essential_genes}->{$media} = $self->figmodel()->database()->load_single_column_file($self->directory()."EssentialGenes-".$self->id().$self->selected_version()."-".$media.".tbl","");
634                    }
635            }
636    
637            return $self->{_essential_genes}->{$media};
638    }
639    
640  =head3 compound_table  =head3 compound_table
641  Definition:  Definition:
642          FIGMODELTable = FIGMODELmodel->compound_table();          FIGMODELTable = FIGMODELmodel->compound_table();
# Line 456  Line 655 
655    
656  =head3 get_compound_data  =head3 get_compound_data
657  Definition:  Definition:
658          string = FIGMODELmodel->get_compound_data(string::compound ID);          {string:key=>[string]:values} = FIGMODELmodel->get_compound_data(string::compound ID);
659  Description:  Description:
660          Returns model compound data          Returns model compound data
661  =cut  =cut
# Line 467  Line 666 
666                  return undef;                  return undef;
667          }          }
668          if ($compound =~ m/^\d+$/) {          if ($compound =~ m/^\d+$/) {
669                  $self->compound_table()->get_row($compound);                  return $self->compound_table()->get_row($compound);
670          }          }
671          return $self->compound_table()->get_row_by_key($compound,"DATABASE");          return $self->compound_table()->get_row_by_key($compound,"DATABASE");
672  }  }
673    
674    =head3 get_feature_data
675    Definition:
676            {string:key=>[string]:values} = FIGMODELmodel->get_feature_data(string::feature ID);
677    Description:
678            Returns model feature data
679    =cut
680    sub get_feature_data {
681            my ($self,$feature) = @_;
682            if (!defined($self->feature_table())) {
683                    return undef;
684            }
685            if ($feature =~ m/^\d+$/) {
686                    return $self->feature_table()->get_row($feature);
687            }
688            if ($feature =~ m/(peg\.\d+)/) {
689                    $feature = $1;
690            }
691            return $self->feature_table()->get_row_by_key("fig|".$self->genome().".".$feature,"ID");
692    }
693    
694  =head3 genome  =head3 genome
695  Definition:  Definition:
696          string = FIGMODELmodel->genome();          string = FIGMODELmodel->genome();
# Line 480  Line 699 
699  =cut  =cut
700  sub genome {  sub genome {
701          my ($self) = @_;          my ($self) = @_;
702          return $self->{_data}->{genome}->[0];          return $self->{_data}->genome();
703  }  }
704    
705  =head3 source  =head3 source
# Line 491  Line 710 
710  =cut  =cut
711  sub source {  sub source {
712          my ($self) = @_;          my ($self) = @_;
713          return $self->{_data}->{source}->[0];          return $self->{_data}->source();
714  }  }
715    
716  =head3 rights  =head3 rights
# Line 502  Line 721 
721  =cut  =cut
722  sub rights {  sub rights {
723          my ($self,$username) = @_;          my ($self,$username) = @_;
   
724          if ($self->public()) {          if ($self->public()) {
725                  return 1;                  return 1;
726          }          }
# Line 510  Line 728 
728                  return 0;                  return 0;
729          }          }
730          if (!defined($self->{_userrights}->{$username})) {          if (!defined($self->{_userrights}->{$username})) {
731                  if (defined($self->{_data}->{master})) {                  $self->{_userrights}->{$self->{_data}->owner()} = 1;
732                          for (my $i=0; $i < @{$self->{_data}->{master}};$i++) {                  my @users = split(/\|/,$self->{_data}->users());
733                                  $self->{_userrights}->{$self->{_data}->{master}->[$i]} = 1;                  for (my $i=0; $i < @users;$i++) {
734                          }                          $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;  
                         }  
735                  }                  }
736          }          }
737          return $self->{_userrights}->{$username};          return $self->{_userrights}->{$username};
# Line 532  Line 745 
745  =cut  =cut
746  sub public {  sub public {
747          my ($self) = @_;          my ($self) = @_;
748            if ($self->{_data}->users() eq "all") {
749          if (!defined($self->{_public})) {                  return 1;
                 $self->{_public} = 0;  
                 if (defined($self->{_data}->{users}->[0]) && $self->{_data}->{users}->[0] eq "all") {  
                         $self->{_public} = 1;  
                 }  
750          }          }
751          return $self->{_public};          return 0;
752  }  }
753    
754  =head3 directory  =head3 directory
# Line 587  Line 796 
796          return $self->directory().$self->id().$self->selected_version().".txt";          return $self->directory().$self->id().$self->selected_version().".txt";
797  }  }
798    
 =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};  
         }  
 }  
   
799  =head3 version  =head3 version
800  Definition:  Definition:
801          string = FIGMODELmodel->version();          string = FIGMODELmodel->version();
# Line 638  Line 807 
807    
808          if (!defined($self->{_version})) {          if (!defined($self->{_version})) {
809                  if (!defined($self->{_selectedversion})) {                  if (!defined($self->{_selectedversion})) {
810                          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];  
                         }  
811                  } else {                  } else {
812                          $self->{_version} = $self->{_selectedversion};                          $self->{_version} = $self->{_selectedversion};
813                  }                  }
# Line 671  Line 838 
838  =cut  =cut
839  sub modification_time {  sub modification_time {
840          my ($self) = @_;          my ($self) = @_;
841          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};  
842  }  }
843    
844  =head3 gene_reactions  =head3 gene_reactions
# Line 695  Line 849 
849  =cut  =cut
850  sub gene_reactions {  sub gene_reactions {
851          my ($self) = @_;          my ($self) = @_;
852            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};  
853  }  }
854    
855  =head3 total_compounds  =head3 total_compounds
# Line 714  Line 860 
860  =cut  =cut
861  sub total_compounds {  sub total_compounds {
862          my ($self) = @_;          my ($self) = @_;
863            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};  
864  }  }
865    
866  =head3 gapfilling_reactions  =head3 gapfilling_reactions
# Line 733  Line 871 
871  =cut  =cut
872  sub gapfilling_reactions {  sub gapfilling_reactions {
873          my ($self) = @_;          my ($self) = @_;
874            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};  
875  }  }
876    
877  =head3 total_reactions  =head3 total_reactions
# Line 752  Line 882 
882  =cut  =cut
883  sub total_reactions {  sub total_reactions {
884          my ($self) = @_;          my ($self) = @_;
885            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};  
886  }  }
887    
888  =head3 model_genes  =head3 model_genes
# Line 771  Line 893 
893  =cut  =cut
894  sub model_genes {  sub model_genes {
895          my ($self) = @_;          my ($self) = @_;
896            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};  
897  }  }
898    
899  =head3 class  =head3 class
# Line 790  Line 904 
904  =cut  =cut
905  sub class {  sub class {
906          my ($self) = @_;          my ($self) = @_;
907            return $self->{_data}->cellwalltype();
         if (!defined($self->{_class})) {  
                 if ($self->source() =~ /^MGRAST/) {  
                         $self->{_class} = "Other";  
                 } elsif (defined($self->stats())) {  
                         $self->{_class} = $self->stats()->{Class}->[0];  
                 }  
         }  
         return $self->{_class};  
908  }  }
909    
910  =head3 taxonomy  =head3 taxonomy
# Line 866  Line 972 
972                          if (defined($self->mgdata())) {                          if (defined($self->mgdata())) {
973                                  $self->{_genome_genes} = $self->mgdata()->genome_contig_count;                                  $self->{_genome_genes} = $self->mgdata()->genome_contig_count;
974                          }                          }
975                  } elsif (defined($self->stats())) {                  } else {
976                          $self->{_genome_genes} = $self->stats()->{'Total genes'}->[0];                          $self->{_genome_genes} = $self->figmodel()->get_genome_stats($self->genome())->{"TOTAL GENES"}->[0];
977                  }                  }
978          }          }
979    
# Line 892  Line 998 
998          #Checking that the table is defined and the output file exists          #Checking that the table is defined and the output file exists
999          if (defined($result) && defined($result->get_row(0)->{"ESSENTIALGENES"})) {          if (defined($result) && defined($result->get_row(0)->{"ESSENTIALGENES"})) {
1000                  $self->figmodel()->database()->print_array_to_file($self->directory()."EssentialGenes-".$self->id()."-".$Media.".tbl",[join("\n",@{$result->get_row(0)->{"ESSENTIALGENES"}})]);                  $self->figmodel()->database()->print_array_to_file($self->directory()."EssentialGenes-".$self->id()."-".$Media.".tbl",[join("\n",@{$result->get_row(0)->{"ESSENTIALGENES"}})]);
1001            } else {
1002                    $self->figmodel()->error_message("FIGMODELmodel:run_default_model_predictions:could not identify essential reactions for model ".$self->id().$self->selected_version().".");
1003                    return $self->figmodel()->fail();
1004          }          }
1005    
1006          #Classifying reactions and compounds          #Classifying reactions and compounds
1007          my $tbl = $self->classify_model_reactions($Media);          my $tbl = $self->classify_model_reactions($Media);
1008            if (!defined($tbl)) {
1009                    $self->figmodel()->error_message("FIGMODELmodel:run_default_model_predictions:could not classify reactions for model ".$self->id().$self->selected_version().".");
1010                    return $self->figmodel()->fail();
1011            }
1012          $tbl->save();          $tbl->save();
1013    
1014          return $self->figmodel()->success();          return $self->figmodel()->success();
1015  }  }
1016    
 =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();  
         }  
 }  
   
1017  =head3 update_stats_for_gap_filling  =head3 update_stats_for_gap_filling
1018  Definition:  Definition:
1019          {string => [string]} = FIGMODELmodel->update_stats_for_gap_filling(int::gapfill time);          {string => [string]} = FIGMODELmodel->update_stats_for_gap_filling(int::gapfill time);
# Line 925  Line 1021 
1021  =cut  =cut
1022  sub update_stats_for_gap_filling {  sub update_stats_for_gap_filling {
1023          my ($self,$gapfilltime) = @_;          my ($self,$gapfilltime) = @_;
1024            $self->{_data}->autoCompleteTime($gapfilltime);
1025          #preserving the stats for the now obselete model          $self->{_data}->autocompleteDate(time());
1026          $self->save_obsolete_stats();          $self->{_data}->modificationDate(time());
1027          my $stats = $self->update_model_stats(0);          my $version = $self->{_data}->autocompleteVersion();
1028          $stats->{"Gap filling time"}->[0] = $gapfilltime;          $self->{_data}->autocompleteVersion($version+1);
         $stats->{"Gap fill date"}->[0] = time();  
         if (!defined($stats->{"Gap fill version"}->[0])) {  
                 $stats->{"Gap fill version"}->[0] = 0;  
         }  
         $stats->{"Gap fill version"}->[0]++;  
   
         #Updating the stats stored in the table  
         $self->figmodel()->database()->update_row("MODEL STATS",$stats,"Model ID");  
         return $stats;  
1029  }  }
1030    
1031  =head3 update_stats_for_build  =head3 update_stats_for_build
# Line 948  Line 1035 
1035  =cut  =cut
1036  sub update_stats_for_build {  sub update_stats_for_build {
1037          my ($self) = @_;          my ($self) = @_;
1038            $self->{_data}->builtDate(time());
1039          #preserving the stats for the now obselete model          $self->{_data}->modificationDate(time());
1040          $self->save_obsolete_stats();          my $version = $self->{_data}->version();
1041          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;  
1042  }  }
1043    
1044  =head3 update_model_stats  =head3 update_model_stats
# Line 979  Line 1057 
1057          }          }
1058          my $cpdtbl = $self->compound_table();          my $cpdtbl = $self->compound_table();
1059    
1060          #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];  
         }  
   
1061          my %GeneHash;          my %GeneHash;
1062          my %NonpegHash;          my %NonpegHash;
1063          my %CompoundHash;          my %CompoundHash;
1064            my $spontaneousReactions = 0;
1065            my $gapFillReactions = 0;
1066            my $biologReactions = 0;
1067            my $transporters = 0;
1068            my $autoCompleteReactions = 0;
1069            my $associatedSubsystemGenes = 0;
1070          for (my $i=0; $i < $rxntbl->size(); $i++) {          for (my $i=0; $i < $rxntbl->size(); $i++) {
1071                  my $Row = $rxntbl->get_row($i);                  my $Row = $rxntbl->get_row($i);
1072                  if (defined($Row) && defined($Row->{"ASSOCIATED PEG"})) {                  if (defined($Row) && defined($Row->{"ASSOCIATED PEG"})) {
# Line 1037  Line 1074 
1074                          if (defined($ReactionRow->{"EQUATION"}->[0])) {                          if (defined($ReactionRow->{"EQUATION"}->[0])) {
1075                                  #Checking for extracellular metabolites which indicate that this is a transporter                                  #Checking for extracellular metabolites which indicate that this is a transporter
1076                                  if ($ReactionRow->{"EQUATION"}->[0] =~ m/\[e\]/) {                                  if ($ReactionRow->{"EQUATION"}->[0] =~ m/\[e\]/) {
1077                                          $CurrentStats->{"Transport reaction"}->[0]++;                                          $transporters++;
1078                                  }                                  }
1079                          }                          }
1080                          #Identifying spontaneous/biolog/gapfilling/gene associated reactions                          #Identifying spontaneous/biolog/gapfilling/gene associated reactions
1081                          if ($Row->{"ASSOCIATED PEG"}->[0] =~ m/BIOLOG/i) {                          if ($Row->{"ASSOCIATED PEG"}->[0] =~ m/BIOLOG/i) {
1082                                  $CurrentStats->{"Biolog gap filling reactions"}->[0]++;                                  $biologReactions++;
1083                            } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/GROW/i) {
1084                                    $gapFillReactions++;
1085                          } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/SPONTANEOUS/i) {                          } elsif ($Row->{"ASSOCIATED PEG"}->[0] =~ m/SPONTANEOUS/i) {
1086                                  $CurrentStats->{"Spontaneous"}->[0]++;                                  $spontaneousReactions++;
1087                          } 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) {
1088                                  $CurrentStats->{"Gap filling reactions"}->[0]++;                                  $autoCompleteReactions++;
1089                          } else {                          } else {
1090                                  foreach my $GeneSet (@{$Row->{"ASSOCIATED PEG"}}) {                                  foreach my $GeneSet (@{$Row->{"ASSOCIATED PEG"}}) {
1091                                          my @GeneList = split(/\+/,$GeneSet);                                          $_ = $GeneSet;
1092                                            my @GeneList = /(peg\.\d+)/g;
1093                                          foreach my $Gene (@GeneList) {                                          foreach my $Gene (@GeneList) {
1094                                                  if ($Gene =~ m/(peg\.\d+)/) {                                                  if ($Gene =~ m/(peg\.\d+)/) {
1095                                                          $GeneHash{$1} = 1;                                                          $GeneHash{$1} = 1;
# Line 1063  Line 1103 
1103          }          }
1104          my @genes = keys(%GeneHash);          my @genes = keys(%GeneHash);
1105          my @othergenes = keys(%NonpegHash);          my @othergenes = keys(%NonpegHash);
         $CurrentStats->{"Genes with reactions"}->[0] = @genes + @othergenes;  
1106    
1107          #Updating the stats stored in the table          #Setting the reaction count
1108          $self->figmodel()->database()->update_row("MODEL STATS",$CurrentStats,"Model ID");          $self->{_data}->reactions($rxntbl->size());
1109          $self->{_stats} = $CurrentStats;          #Setting the metabolite count
1110          return $CurrentStats;          $self->{_data}->compounds($rxntbl->size());
1111            #Setting the gene count
1112            my $geneCount = @genes + @othergenes;
1113            $self->{_data}->associatedGenes($geneCount);
1114            #Setting remaining stats
1115            $self->{_data}->spontaneousReactions($spontaneousReactions);
1116            $self->{_data}->gapFillReactions($gapFillReactions);
1117            $self->{_data}->biologReactions($biologReactions);
1118            $self->{_data}->transporters($transporters);
1119            $self->{_data}->autoCompleteReactions($autoCompleteReactions);
1120            $self->{_data}->associatedSubsystemGenes($associatedSubsystemGenes);
1121            #Setting the model class
1122            my $class = "";
1123            for (my $i=0; $i < @{$self->figmodel()->config("class list")}; $i++) {
1124                    if (defined($self->figmodel()->config($self->figmodel()->config("class list")->[$i]))) {
1125                            if (defined($self->figmodel()->config($self->figmodel()->config("class list")->[$i])->{$self->id()})) {
1126                                    $class = $self->figmodel()->config("class list")->[$i];
1127                                    last;
1128                            }
1129                            if ($class eq "" && defined($self->figmodel()->config($self->figmodel()->config("class list")->[$i])->{$self->genome()})) {
1130                                    $class = $self->figmodel()->config("class list")->[$i];
1131                            }
1132                    }
1133            }
1134            if ($class eq "") {
1135                    $class = $self->figmodel()->get_genome_stats($self->genome())->{CLASS}->[0];
1136            }
1137            if ($class eq "") {
1138                    $class = "unknown";
1139            }
1140            $self->{_data}->cellwalltype($class);
1141  }  }
1142    
1143  =head3 GapFillModel  =head3 GapFillModel
# Line 1119  Line 1188 
1188                          }                          }
1189                  }                  }
1190                  $MediaTable->save($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");                  $MediaTable->save($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");
1191                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$UniqueFilename."TestMedia",["GapFilling"],{"Default max drain flux" => 0},"GapFill".$self->id().".log",undef));                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),$UniqueFilename."TestMedia",["GapFilling"],{"Default max drain flux" => 0,"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0]},"GapFill".$self->id().".log",undef));
1192                  unlink($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");                  unlink($self->config("Media directory")->[0].$UniqueFilename."TestMedia.txt");
1193          } else {          } else {
1194                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),undef,["GapFilling"],undef,"GapFill".$self->id().".log",undef));                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),undef,["GapFilling"],{"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0]},"GapFill".$self->id().".log",undef));
1195          }          }
1196    
1197          #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
# Line 1140  Line 1209 
1209          for (my $i=($SolutionData->size()-1); $i >=0; $i--) {          for (my $i=($SolutionData->size()-1); $i >=0; $i--) {
1210                  if (defined($SolutionData->get_row($i)->{"Notes"}) && $SolutionData->get_row($i)->{"Notes"}->[0] =~ m/^Recursive/) {                  if (defined($SolutionData->get_row($i)->{"Notes"}) && $SolutionData->get_row($i)->{"Notes"}->[0] =~ m/^Recursive/) {
1211                          my $AllSolutions = substr($SolutionData->get_row($i)->{"Notes"}->[0],15);                          my $AllSolutions = substr($SolutionData->get_row($i)->{"Notes"}->[0],15);
                         print "Solution:".$AllSolutions."\n";  
1212                          my @TempThree = split(/\|/,$AllSolutions);                          my @TempThree = split(/\|/,$AllSolutions);
1213                          if (@TempThree > 0 && $TempThree[0] =~ m/.+:(.+)/) {                          if (@TempThree > 0 && $TempThree[0] =~ m/.+:(.+)/) {
1214                                  my @TempFour = split(/,/,$1);                                  my @TempFour = split(/,/,$1);
# Line 1163  Line 1231 
1231                                                  push(@{$ReactionList},$ID);                                                  push(@{$ReactionList},$ID);
1232                                          }                                          }
1233                                  }                                  }
                                 print "Solution:".$TempThree[0]."\n";  
1234                                  $self->figmodel()->IntegrateGrowMatchSolution($self->id(),undef,$ReactionList,$DirectionList,"GAP FILLING",0,1);                                  $self->figmodel()->IntegrateGrowMatchSolution($self->id(),undef,$ReactionList,$DirectionList,"GAP FILLING",0,1);
1235                          }                          }
1236                          last;                          last;
# Line 1171  Line 1238 
1238          }          }
1239          #Updating model stats with gap filling results          #Updating model stats with gap filling results
1240          my $ElapsedTime = time() - $StartTime;          my $ElapsedTime = time() - $StartTime;
1241          $self->figmodel()->ClearDBModel($self->id(),1);          $self->figmodel()->database()->ClearDBModel($self->id(),1);
1242          #Determining why each gap filling reaction was added          #Determining why each gap filling reaction was added
1243          $self->figmodel()->IdentifyDependancyOfGapFillingReactions($self->id(),$Media);          $self->figmodel()->IdentifyDependancyOfGapFillingReactions($self->id(),$Media);
1244          if (!defined($donotclear) || $donotclear != 1) {          if (!defined($donotclear) || $donotclear != 1) {
# Line 1191  Line 1258 
1258          return $self->success();          return $self->success();
1259  }  }
1260    
1261    =head3 GapGenModel
1262    Definition:
1263            FIGMODELmodel->GapGenModel();
1264    Description:
1265            Runs the gap generation algorithm to correct a single false positive prediction. Results are loaded into a table.
1266    =cut
1267    
1268    sub GapGenModel {
1269            my ($self,$Media,$KOList,$NoKOList,$Experiment,$SolutionLimit) = @_;
1270    
1271            #Enforcing nonoptional arguments
1272            if (!defined($Media)) {
1273                    return undef;
1274            }
1275            if (!defined($KOList)) {
1276                    $KOList->[0] = "none";
1277            }
1278            if (!defined($NoKOList)) {
1279                    $NoKOList->[0] = "none";
1280            }
1281            if (!defined($Experiment)) {
1282                    $Experiment= "ReactionKO";
1283            }
1284            if (!defined($SolutionLimit)) {
1285                    $SolutionLimit = "10";
1286            }
1287    
1288            #Translating the KO lists into arrays
1289            if (ref($KOList) ne "ARRAY") {
1290                    my $temp = $KOList;
1291                    $KOList = ();
1292                    push(@{$KOList},split(/[,;]/,$temp));
1293            }
1294            my $noKOHash;
1295            if (defined($NoKOList) && ref($NoKOList) ne "ARRAY") {
1296                    my $temp = $NoKOList;
1297                    $NoKOList = ();
1298                    push(@{$NoKOList},split(/[,;]/,$temp));
1299                    foreach my $rxn (@{$NoKOList}) {
1300                            $noKOHash->{$rxn} = 1;
1301                    }
1302            }
1303    
1304            #Checking if solutions exist for the input parameters
1305            $self->aquireModelLock();
1306            my $tbl = $self->load_model_table("GapGenSolutions");
1307            my $solutionRow = $tbl->get_table_by_key($Experiment,"Experiment")->get_table_by_key($Media,"Media")->get_row_by_key(join(",",@{$KOList}),"KOlist");
1308            my $solutions;
1309            if (defined($solutionRow)) {
1310                    #Checking if any solutions conform to the no KO list
1311                    foreach my $solution (@{$solutionRow->{Solutions}}) {
1312                            my @reactions = split(/,/,$solution);
1313                            my $include = 1;
1314                            foreach my $rxn (@reactions) {
1315                                    if ($rxn =~ m/(rxn\d\d\d\d\d)/) {
1316                                            if (defined($noKOHash->{$1})) {
1317                                                    $include = 0;
1318                                            }
1319                                    }
1320                            }
1321                            if ($include == 1) {
1322                                    push(@{$solutions},$solution);
1323                            }
1324                    }
1325            } else {
1326                    $solutionRow = {Media => [$Media],Experiment => [$Experiment],KOlist => [join(",",@{$KOList})]};
1327                    $tbl->add_row($solutionRow);
1328                    $self->figmodel()->database()->save_table($tbl);
1329            }
1330            $self->releaseModelLock();
1331    
1332            #Returning solution list of solutions were found
1333            if (defined($solutions) && @{$solutions} > 0) {
1334                    return $solutions;
1335            }
1336    
1337            #Getting unique filename
1338            my $Filename = $self->figmodel()->filename();
1339    
1340            #Running the gap generation
1341            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));
1342            my $ProblemReport = $self->figmodel()->LoadProblemReport($Filename);
1343            if (!defined($ProblemReport)) {
1344                    $self->figmodel()->error_message("FIGMODEL:GapGenerationAlgorithm;No problem report;".$Filename.";".$self->id().$self->selected_version().";".$Media.";".$KOList.";".$NoKOList);
1345                    return undef;
1346            }
1347    
1348            #Clearing the output folder and log file
1349            $self->figmodel()->clearing_output($Filename,"Gapgeneration-".$self->id().$self->selected_version()."-".$Filename.".log");
1350    
1351            #Saving the solution
1352            $self->aquireModelLock();
1353            $tbl = $self->load_model_table("GapGenSolutions");
1354            $solutionRow = $tbl->get_table_by_key($Experiment,"Experiment")->get_table_by_key($Media,"Media")->get_row_by_key(join(",",@{$KOList}),"KOlist");
1355            for (my $j=0; $j < $ProblemReport->size(); $j++) {
1356                    if ($ProblemReport->get_row($j)->{"Notes"}->[0] =~ m/^Recursive\sMILP\s([^)]+)/) {
1357                            my @SolutionList = split(/\|/,$1);
1358                            for (my $k=0; $k < @SolutionList; $k++) {
1359                                    if ($SolutionList[$k] =~ m/(\d+):(.+)/) {
1360                                            push(@{$solutionRow->{Solutions}},$2);
1361                                            push(@{$solutions},$2);
1362                                    }
1363                            }
1364                    }
1365            }
1366            $self->figmodel()->database()->save_table($tbl);
1367            $self->releaseModelLock();
1368    
1369            return $solutions;
1370    }
1371    
1372  =head3 datagapfill  =head3 datagapfill
1373  Definition:  Definition:
1374          success()/fail() = FIGMODELmodel->datagapfill();          success()/fail() = FIGMODELmodel->datagapfill();
# Line 1201  Line 1379 
1379          my ($self,$GapFillingRunSpecs,$TansferFileSuffix) = @_;          my ($self,$GapFillingRunSpecs,$TansferFileSuffix) = @_;
1380          my $UniqueFilename = $self->figmodel()->filename();          my $UniqueFilename = $self->figmodel()->filename();
1381          if (defined($GapFillingRunSpecs) && @{$GapFillingRunSpecs} > 0) {          if (defined($GapFillingRunSpecs) && @{$GapFillingRunSpecs} > 0) {
                 print "Gap filling specs:\n".join("\n",@{$GapFillingRunSpecs})."\n\n";  
1382                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id().$self->selected_version(),"NoBounds",["DataGapFilling"],{"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0],"Gap filling runs" => join(";",@{$GapFillingRunSpecs})},"GapFilling-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,undef));                  system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id().$self->selected_version(),"NoBounds",["DataGapFilling"],{"Reactions to knockout" => $self->config("permanently knocked out reactions")->[0],"Gap filling runs" => join(";",@{$GapFillingRunSpecs})},"GapFilling-".$self->id().$self->selected_version()."-".$UniqueFilename.".log",undef,undef));
   
1383                  #Checking that the solution exists                  #Checking that the solution exists
1384                  if (!-e $self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingSolutionTable.txt") {                  if (!-e $self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingSolutionTable.txt") {
1385                          $self->figmodel()->error_message("FIGMODEL:GapFillingAlgorithm: Could not find MFA output file!");                          $self->figmodel()->error_message("FIGMODEL:GapFillingAlgorithm: Could not find MFA output file!");
# Line 1213  Line 1389 
1389                  my $GapFillResultTable = $self->figmodel()->database()->load_table($self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingSolutionTable.txt",";","",0,undef);                  my $GapFillResultTable = $self->figmodel()->database()->load_table($self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingSolutionTable.txt",";","",0,undef);
1390                  if (defined($TansferFileSuffix)) {                  if (defined($TansferFileSuffix)) {
1391                          system("cp ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingSolutionTable.txt ".$self->directory().$self->id().$self->selected_version()."-".$TansferFileSuffix.".txt");                          system("cp ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingSolutionTable.txt ".$self->directory().$self->id().$self->selected_version()."-".$TansferFileSuffix.".txt");
                         system("cp ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/GapFillingReport.txt ".$self->directory().$self->id().$self->selected_version()."-".$TansferFileSuffix.".txt");  
1392                  }                  }
   
1393                  #If the system is not configured to preserve all logfiles, then the mfatoolkit output folder is deleted                  #If the system is not configured to preserve all logfiles, then the mfatoolkit output folder is deleted
1394                  $self->figmodel()->clearing_output($UniqueFilename,"GapFilling-".$self->id().$self->selected_version()."-".$UniqueFilename.".log");                  $self->figmodel()->clearing_output($UniqueFilename,"GapFilling-".$self->id().$self->selected_version()."-".$UniqueFilename.".log");
1395                  return $GapFillingRunSpecs;                  return $GapFillResultTable;
1396          }          }
1397          if (defined($TansferFileSuffix)) {          if (defined($TansferFileSuffix)) {
1398                  $self->figmodel()->database()->print_array_to_file($self->directory().$self->id().$self->selected_version()."-".$TansferFileSuffix.".txt",["Experiment;Solution index;Solution cost;Solution reactions"]);                  $self->figmodel()->database()->print_array_to_file($self->directory().$self->id().$self->selected_version()."-".$TansferFileSuffix.".txt",["Experiment;Solution index;Solution cost;Solution reactions"]);
# Line 1284  Line 1458 
1458                          push(@{$DirectionArray},$SolutionHash{$ReactionList[$k]});                          push(@{$DirectionArray},$SolutionHash{$ReactionList[$k]});
1459                  }                  }
1460                  print "Integrating solution!\n";                  print "Integrating solution!\n";
1461                  $self->IntegrateGrowMatchSolution($self->id().$self->selected_version(),$self->directory().$self->id().$TempVersion.".txt",$ReactionArray,$DirectionArray,"Gapfilling ".$GapFillResultTable->get_row($i)->{"Experiment"}->[0],1,1);                  $self->figmodel()->IntegrateGrowMatchSolution($self->id().$self->selected_version(),$self->directory().$self->id().$TempVersion.".txt",$ReactionArray,$DirectionArray,"Gapfilling ".$GapFillResultTable->get_row($i)->{"Experiment"}->[0],1,1);
1462                  my $model = $self->get_model($self->id().$TempVersion);                  $self->PrintModelLPFile();
                 $model->PrintModelLPFile();  
1463                  #Running the model against all available experimental data                  #Running the model against all available experimental data
1464                  print "Running test model!\n";                  print "Running test model!\n";
1465                  my ($FalsePostives,$FalseNegatives,$CorrectNegatives,$CorrectPositives,$Errorvector,$HeadingVector) = $self->RunAllStudiesWithDataFast("All");                  my ($FalsePostives,$FalseNegatives,$CorrectNegatives,$CorrectPositives,$Errorvector,$HeadingVector) = $self->RunAllStudiesWithDataFast("All");
# Line 1367  Line 1540 
1540  sub CreateSingleGenomeReactionList {  sub CreateSingleGenomeReactionList {
1541          my ($self,$RunGapFilling) = @_;          my ($self,$RunGapFilling) = @_;
1542    
1543            #Creating directory
1544            if ($self->owner() ne "master" && !-d $self->figmodel()->config("organism directory")->[0].$self->owner()."/") {
1545                    system("mkdir ".$self->figmodel()->config("organism directory")->[0].$self->owner()."/");
1546            } elsif ($self->owner() eq "master" && !-d $self->figmodel()->config("organism directory")->[0].$self->genome()."/") {
1547                    system("mkdir ".$self->figmodel()->config("organism directory")->[0].$self->genome()."/");
1548            }
1549            if ($self->owner() ne "master" && !-d $self->figmodel()->config("organism directory")->[0].$self->owner()."/".$self->genome()."/") {
1550                    system("mkdir ".$self->figmodel()->config("organism directory")->[0].$self->owner()."/".$self->genome()."/");
1551            }
1552    
1553          #Getting genome stats          #Getting genome stats
1554          my $genomestats = $self->figmodel()->get_genome_stats($self->genome());          my $genomestats = $self->figmodel()->get_genome_stats($self->genome());
1555          my $FeatureTable = $self->figmodel()->GetGenomeFeatureTable($self->genome());          my $FeatureTable = $self->figmodel()->GetGenomeFeatureTable($self->genome());
# Line 1601  Line 1784 
1784          }          }
1785    
1786          #Checking if a biomass reaction already exists          #Checking if a biomass reaction already exists
1787          my $BiomassReactionRow = $self->figmodel()->database()->get_row_by_key("BIOMASS TABLE",$self->id(),"MODELS");          my $BiomassReactionRow = $self->BuildSpecificBiomassReaction();
         if (!defined($BiomassReactionRow)) {  
                 $BiomassReactionRow = $self->BuildSpecificBiomassReaction();  
1788                  if (!defined($BiomassReactionRow)) {                  if (!defined($BiomassReactionRow)) {
1789                          $self->set_status(-2,"Preliminary reconstruction failed: could not generate biomass reaction");                          $self->set_status(-2,"Preliminary reconstruction failed: could not generate biomass reaction");
1790                          $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()."!");
1791                          return $self->fail();                          return $self->fail();
1792                  }                  }
         }  
1793          my $ReactionList = $BiomassReactionRow->{"ESSENTIAL REACTIONS"};          my $ReactionList = $BiomassReactionRow->{"ESSENTIAL REACTIONS"};
1794          push(@{$ReactionList},$BiomassReactionRow->{DATABASE}->[0]);          push(@{$ReactionList},$BiomassReactionRow->{DATABASE}->[0]);
1795    
# Line 1702  Line 1882 
1882          $self->figmodel()->database()->save_table($NewModelTable);          $self->figmodel()->database()->save_table($NewModelTable);
1883          $self->{_reaction_data} = $NewModelTable;          $self->{_reaction_data} = $NewModelTable;
1884          #Clearing the previous model from the cache          #Clearing the previous model from the cache
1885          $self->figmodel()->ClearDBModel($self->id(),1);          $self->figmodel()->database()->ClearDBModel($self->id(),1);
1886          #Updating the model stats table          #Updating the model stats table
1887          $self->update_stats_for_build();          $self->update_stats_for_build();
1888          $self->PrintSBMLFile();          $self->PrintSBMLFile();
# Line 1823  Line 2003 
2003          }          }
2004    
2005          #Clearing the previous model from the cache          #Clearing the previous model from the cache
2006          $self->figmodel()->ClearDBModel($self->id(),1);          $self->figmodel()->database()->ClearDBModel($self->id(),1);
2007          $ModelTable->save();          $ModelTable->save();
2008    
2009          return $self->success();          return $self->success();
# Line 1839  Line 2019 
2019  sub ArchiveModel {  sub ArchiveModel {
2020          my ($self) = @_;          my ($self) = @_;
2021    
         #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();  
         }  
   
2022          #Checking that the model file exists          #Checking that the model file exists
2023          if (!(-e $self->filename())) {          if (!(-e $self->filename())) {
2024                  $self->figmodel()->error_message("FIGMODEL:ArchiveModel: Model file ".$self->filename()." not found!");                  $self->figmodel()->error_message("FIGMODEL:ArchiveModel: Model file ".$self->filename()." not found!");
# Line 1895  Line 2069 
2069          Runs microarray analysis attempting to turn off genes that are inactive in the microarray          Runs microarray analysis attempting to turn off genes that are inactive in the microarray
2070  =cut  =cut
2071  sub run_microarray_analysis {  sub run_microarray_analysis {
2072          my ($self,$media,$jobid,$index,$genecall) = @_;          my ($self,$media,$label,$index,$genecall) = @_;
2073          $genecall =~ s/_/:/g;          $genecall =~ s/_/:/g;
2074          $genecall =~ s/\//;/g;          $genecall =~ s/\//;/g;
2075          #print "\n\n".$genecall."\n\n";          my $uniqueFilename = $self->figmodel()->filename();
2076          my $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($jobid,$self->id(),$media,["MFA","MicroarrayAssertions"],{"Microarray assertions" => $self->id().";".$index.";".$genecall,"MFASolver" => "CPLEX","Network output location" => "/scratch/"},"MicroarrayAnalysis-".$jobid.".txt",undef,$self->selected_version());          my $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($uniqueFilename,$self->id(),$media,["ProductionMFA","ShewenellaExperiment"],{"Microarray assertions" => $label.";".$index.";".$genecall,"MFASolver" => "CPLEX","Network output location" => "/scratch/"},"MicroarrayAnalysis-".$uniqueFilename.".txt",undef,$self->selected_version());
2077          #print $command."\n";          system($command);
2078            my $filename = $self->figmodel()->config("MFAToolkit output directory")->[0].$uniqueFilename."/MicroarrayOutput-".$index.".txt";
2079        if (-e $filename) {
2080            my $output = $self->figmodel()->database()->load_single_column_file($filename);
2081            if (defined($output->[0])) {
2082                    my @array = split(/;/,$output->[0]);
2083                    $self->figmodel()->clearing_output($uniqueFilename,"MicroarrayAnalysis-".$uniqueFilename.".txt");
2084                    return ($array[0],$array[1],$array[8].":".$array[2],$array[9].":".$array[3],$array[10].":".$array[4],$array[11].":".$array[5],$array[12].":".$array[6],$array[13].":".$array[7]);
2085            }
2086            print STDERR $filename." is empty!";
2087        }
2088        print STDERR $filename." not found!";
2089        $self->figmodel()->clearing_output($uniqueFilename,"MicroarrayAnalysis-".$uniqueFilename.".txt");
2090    
2091            return undef;
2092    }
2093    
2094    =head3 find_minimal_pathways
2095    Definition:
2096            int::status = FIGMODEL->find_minimal_pathways(string::media,string::objective);
2097    Description:
2098            Runs microarray analysis attempting to turn off genes that are inactive in the microarray
2099    =cut
2100    sub find_minimal_pathways {
2101            my ($self,$media,$objective,$solutionnum,$AllReversible,$additionalexchange) = @_;
2102    
2103            #Setting default media
2104            if (!defined($media)) {
2105                    $media = "Complete";
2106            }
2107    
2108            #Setting default solution number
2109            if (!defined($solutionnum)) {
2110                    $solutionnum = "5";
2111            }
2112    
2113            #Setting additional exchange fluxes
2114            if (!defined($additionalexchange) || length($additionalexchange) == 0) {
2115                    if ($self->id() eq "iAF1260") {
2116                            $additionalexchange = "cpd03422[c]:-100:100;cpd01997[c]:-100:100;cpd11416[c]:-100:0;cpd15378[c]:-100:0;cpd15486[c]:-100:0";
2117                    } else {
2118                            $additionalexchange = $self->figmodel()->config("default exchange fluxes")->[0];
2119                    }
2120            }
2121    
2122            #Translating objective
2123            my $objectivestring;
2124            if ($objective eq "ALL") {
2125                    #Getting the list of universal building blocks
2126                    my $buildingblocks = $self->config("universal building blocks");
2127                    my @objectives = keys(%{$buildingblocks});
2128                    #Getting the nonuniversal building blocks
2129                    my $otherbuildingblocks = $self->config("nonuniversal building blocks");
2130                    my @array = keys(%{$otherbuildingblocks});
2131                    if (defined($self->get_biomass()) && defined($self->figmodel()->get_reaction($self->get_biomass()->{"LOAD"}->[0]))) {
2132                            my $equation = $self->figmodel()->get_reaction($self->get_biomass()->{"LOAD"}->[0])->{"EQUATION"}->[0];
2133                            if (defined($equation)) {
2134                                    for (my $i=0; $i < @array; $i++) {
2135                                            if (CORE::index($equation,$array[$i]) > 0) {
2136                                                    push(@objectives,$array[$i]);
2137                                            }
2138                                    }
2139                            }
2140                    }
2141                    for (my $i=0; $i < @objectives; $i++) {
2142                            $self->find_minimal_pathways($media,$objectives[$i]);
2143                    }
2144                    return;
2145            } elsif ($objective eq "ENERGY") {
2146                    $objectivestring = "MAX;FLUX;rxn00062;c;1";
2147            } elsif ($objective =~ m/cpd\d\d\d\d\d/) {
2148                    if ($objective =~ m/\[(\w)\]/) {
2149                            $objectivestring = "MIN;DRAIN_FLUX;".$objective.";".$1.";1";
2150                            $additionalexchange .= ";".$objective."[".$1."]:-100:0";
2151                    } else {
2152                            $objectivestring = "MIN;DRAIN_FLUX;".$objective.";c;1";
2153                            $additionalexchange .= ";".$objective."[c]:-100:0";
2154                    }
2155            } elsif ($objective =~ m/(rxn\d\d\d\d\d)/) {
2156                    my ($Reactants,$Products) = $self->figmodel()->GetReactionSubstrateData($objective);
2157                    for (my $i=0; $i < @{$Products};$i++) {
2158                            my $temp = $Products->[$i]->{"DATABASE"}->[0];
2159                            if ($additionalexchange !~ m/$temp/) {
2160                                    #$additionalexchange .= ";".$temp."[c]:-100:0";
2161                            }
2162                    }
2163                    for (my $i=0; $i < @{$Reactants};$i++) {
2164                            print $Reactants->[$i]->{"DATABASE"}->[0]." started\n";
2165                            $self->find_minimal_pathways($media,$Reactants->[$i]->{"DATABASE"}->[0],$additionalexchange);
2166                            print $Reactants->[$i]->{"DATABASE"}->[0]." done\n";
2167                    }
2168                    return;
2169            }
2170    
2171            #Adding additional drains
2172            if (($objective eq "cpd15665" || $objective eq "cpd15667" || $objective eq "cpd15668" || $objective eq "cpd15669") && $additionalexchange !~ m/cpd15666/) {
2173                    $additionalexchange .= ";cpd15666[c]:0:100";
2174            } elsif ($objective eq "cpd11493" && $additionalexchange !~ m/cpd12370/) {
2175                    $additionalexchange .= ";cpd12370[c]:0:100";
2176            } elsif ($objective eq "cpd00166" && $additionalexchange !~ m/cpd01997/) {
2177                    $additionalexchange .= ";cpd01997[c]:0:100;cpd03422[c]:0:100";
2178            }
2179    
2180            #Running MFAToolkit
2181            my $filename = $self->figmodel()->filename();
2182            my $command;
2183            if (defined($AllReversible) && $AllReversible == 1) {
2184                    $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($filename,$self->id(),$media,["ProductionMFA"],{"Make all reactions reversible in MFA"=>1, "Recursive MILP solution limit" => $solutionnum,"Generate pathways to objective" => 1,"MFASolver" => "CPLEX","objective" => $objectivestring,"exchange species" => $additionalexchange},"MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",undef,$self->selected_version());
2185            } else {
2186                    $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($filename,$self->id(),$media,["ProductionMFA"],{"Make all reactions reversible in MFA"=>0, "Recursive MILP solution limit" => $solutionnum,"Generate pathways to objective" => 1,"MFASolver" => "CPLEX","objective" => $objectivestring,"exchange species" => $additionalexchange},"MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",undef,$self->selected_version());
2187            }
2188          system($command);          system($command);
2189          #system("/home/chenry/Software/MFAToolkitRepository/Linux/mfatoolkit resetparameter \"user bounds filename\" \"Carbon-D-Glucose.txt\" resetparameter output_folder \"32749.354149.0/\" resetparameter \"Microarray assertions\" \"Seed83333.1;0;peg.3130:-1;peg.4035:-1\" resetparameter \"MFASolver\" \"CPLEX\" resetparameter \"Network output location\" \"/scratch/\" LoadCentralSystem \"/vol/model-dev/MODEL_DEV_DB/Models/83333.1/Seed83333.1.txt\" > \"/vol/model-dev/MODEL_DEV_DB/ReactionDB/log/MicroarrayAnalysis-32749.354149.0.txt\"");  
2190            #Loading problem report
2191            my $results = $self->figmodel()->LoadProblemReport($filename);
2192            #Clearing output
2193            $self->figmodel()->clearing_output($filename,"MinimalPathways-".$media."-".$self->id()."-".$objective.".txt");
2194            if (!defined($results)) {
2195                    print STDERR $objective." pathway results not found!\n";
2196                    return;
2197            }
2198    
2199            #Parsing output
2200            my @Array;
2201            my $row = $results->get_row(1);
2202            if (defined($row->{"Notes"}->[0])) {
2203                    $_ = $row->{"Notes"}->[0];
2204                    @Array = /\d+:([^\|]+)\|/g;
2205            }
2206    
2207            #Writing output to file
2208            $self->figmodel()->database()->print_array_to_file($self->directory()."MinimalPathways-".$media."-".$objective."-".$self->id()."-".$AllReversible."-".$self->selected_version().".txt",[join("|",@Array)]);
2209  }  }
2210    
2211  =head3 find_minimal_pathways  =head3 find_minimal_pathways
# Line 1911  Line 2214 
2214  Description:  Description:
2215          Runs microarray analysis attempting to turn off genes that are inactive in the microarray          Runs microarray analysis attempting to turn off genes that are inactive in the microarray
2216  =cut  =cut
2217  sub find_minimal_pathways {  sub find_minimal_pathways_two {
2218          my ($self,$media,$objective,$solutionnum) = @_;          my ($self,$media,$objective,$solutionnum,$AllReversible,$additionalexchange) = @_;
2219    
2220          #Setting default media          #Setting default media
2221          if (!defined($media)) {          if (!defined($media)) {
# Line 1924  Line 2227 
2227                  $solutionnum = "5";                  $solutionnum = "5";
2228          }          }
2229    
2230            #Setting additional exchange fluxes
2231            if (!defined($additionalexchange) || length($additionalexchange) == 0) {
2232                    if ($self->id() eq "iAF1260") {
2233                            $additionalexchange = "cpd03422[c]:-100:100;cpd01997[c]:-100:100;cpd11416[c]:-100:0;cpd15378[c]:-100:0;cpd15486[c]:-100:0";
2234                    } else {
2235                            $additionalexchange = $self->figmodel()->config("default exchange fluxes")->[0];
2236                    }
2237            }
2238    
2239          #Translating objective          #Translating objective
2240          my $objectivestring;          my $objectivestring;
2241          if ($objective eq "ALL") {          if ($objective eq "ALL") {
# Line 1944  Line 2256 
2256                          }                          }
2257                  }                  }
2258                  for (my $i=0; $i < @objectives; $i++) {                  for (my $i=0; $i < @objectives; $i++) {
2259                          $self->find_minimal_pathways($media,$objectives[$i])                          $self->find_minimal_pathways($media,$objectives[$i]);
2260                  }                  }
2261                    return;
2262          } elsif ($objective eq "ENERGY") {          } elsif ($objective eq "ENERGY") {
2263                  $objectivestring = "MAX;FLUX;rxn00062;c;1";                  $objectivestring = "MAX;FLUX;rxn00062;c;1";
2264          } elsif ($objective =~ m/cpd\d\d\d\d\d/) {          } elsif ($objective =~ m/cpd\d\d\d\d\d/) {
2265                    if ($objective =~ m/\[(\w)\]/) {
2266                            $objectivestring = "MIN;DRAIN_FLUX;".$objective.";".$1.";1";
2267                            $additionalexchange .= ";".$objective."[".$1."]:-100:0";
2268                    } else {
2269                  $objectivestring = "MIN;DRAIN_FLUX;".$objective.";c;1";                  $objectivestring = "MIN;DRAIN_FLUX;".$objective.";c;1";
2270                            $additionalexchange .= ";".$objective."[c]:-100:0";
2271                    }
2272            } elsif ($objective =~ m/(rxn\d\d\d\d\d)/) {
2273                    my ($Reactants,$Products) = $self->figmodel()->GetReactionSubstrateData($objective);
2274                    for (my $i=0; $i < @{$Products};$i++) {
2275                            my $temp = $Products->[$i]->{"DATABASE"}->[0];
2276                            if ($additionalexchange !~ m/$temp/) {
2277                                    #$additionalexchange .= ";".$temp."[c]:-100:0";
2278                            }
2279                    }
2280                    for (my $i=0; $i < @{$Reactants};$i++) {
2281                            print $Reactants->[$i]->{"DATABASE"}->[0]." started\n";
2282                            $self->find_minimal_pathways($media,$Reactants->[$i]->{"DATABASE"}->[0],$additionalexchange);
2283                            print $Reactants->[$i]->{"DATABASE"}->[0]." done\n";
2284                    }
2285                    return;
2286          }          }
2287    
2288          #Setting additional exchange fluxes          #Adding additional drains
2289          my $additionalexchange = $self->config("default exchange fluxes")->[0];          if (($objective eq "cpd15665" || $objective eq "cpd15667" || $objective eq "cpd15668" || $objective eq "cpd15669") && $additionalexchange !~ m/cpd15666/) {
         if ($objective eq "cpd15665" || $objective eq "cpd15667" || $objective eq "cpd15668" || $objective eq "cpd15669") {  
2290                  $additionalexchange .= ";cpd15666[c]:0:100";                  $additionalexchange .= ";cpd15666[c]:0:100";
2291          } elsif ($objective eq "cpd11493") {          } elsif ($objective eq "cpd11493" && $additionalexchange !~ m/cpd12370/) {
2292                  $additionalexchange .= ";cpd12370[c]:0:100";                  $additionalexchange .= ";cpd12370[c]:0:100";
2293          } elsif ($objective eq "cpd00166") {          } elsif ($objective eq "cpd00166" && $additionalexchange !~ m/cpd01997/) {
2294                  $additionalexchange .= ";cpd01997[c]:0:100;cpd03422[c]:0:100";                  $additionalexchange .= ";cpd01997[c]:0:100;cpd03422[c]:0:100";
2295          }          }
2296    
2297          #Running MFAToolkit          #Running MFAToolkit
2298          my $filename = $self->figmodel()->filename();          my $filename = $self->figmodel()->filename();
2299          my $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($filename,$self->id(),$media,["MFA"],{"Recursive MILP solution limit" => $solutionnum,"Generate pathways to objective" => 1,"MFASolver" => "CPLEX","objective" => $objectivestring,"exchange species" => $additionalexchange},"MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",undef,$self->selected_version());          my $command;
2300            if (defined($AllReversible) && $AllReversible == 1) {
2301                    $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($filename,$self->id(),$media,["ProductionMFA"],{"use simple variable and constraint names"=>1,"Make all reactions reversible in MFA"=>1, "Recursive MILP solution limit" => $solutionnum,"Generate pathways to objective" => 1,"MFASolver" => "SCIP","objective" => $objectivestring,"exchange species" => $additionalexchange},"MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",undef,$self->selected_version());
2302            } else {
2303                    $command = $self->figmodel()->GenerateMFAToolkitCommandLineCall($filename,$self->id(),$media,["ProductionMFA"],{"use simple variable and constraint names"=>1,"Make all reactions reversible in MFA"=>0, "Recursive MILP solution limit" => $solutionnum,"Generate pathways to objective" => 1,"MFASolver" => "SCIP","objective" => $objectivestring,"exchange species" => $additionalexchange},"MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",undef,$self->selected_version());
2304            }
2305            print $command."\n";
2306          system($command);          system($command);
2307    
2308          #Loading problem report          #Loading problem report
# Line 1972  Line 2310 
2310          #Clearing output          #Clearing output
2311          $self->figmodel()->clearing_output($filename,"MinimalPathways-".$media."-".$self->id()."-".$objective.".txt");          $self->figmodel()->clearing_output($filename,"MinimalPathways-".$media."-".$self->id()."-".$objective.".txt");
2312          if (!defined($results)) {          if (!defined($results)) {
2313                    print STDERR $objective." pathway results not found!\n";
2314                  return;                  return;
2315          }          }
2316    
# Line 1983  Line 2322 
2322                  @Array = /\d+:([^\|]+)\|/g;                  @Array = /\d+:([^\|]+)\|/g;
2323          }          }
2324    
2325          # Storing data in a figmodel table          #Writing output to file
2326          my $TableObject;          $self->figmodel()->database()->print_array_to_file($self->directory()."MinimalPathways-".$media."-".$objective."-".$self->id()."-".$AllReversible."-".$self->selected_version().".txt",[join("|",@Array)]);
2327          if (-e $self->directory()."MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt") {  }
2328                  $TableObject->load_table($self->directory()."MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",";","|",0,["OBJECTIVE"]);  
2329          } else {  sub combine_minimal_pathways {
2330                  $TableObject = FIGMODELTable->new(["OBJECTIVE","REACTIONS"],$self->directory()."MinimalPathways-".$media."-".$self->id().$self->selected_version().".txt",["OBJECTIVE"],";","|",undef);          my ($self) = @_;
2331          }  
2332          my $tablerow = $TableObject->get_row_by_key($objective,"OBJECTIVE",1);          my $tbl;
2333          push(@{$tablerow->{"REACTIONS"}},@Array);          if (-e $self->directory()."MinimalPathwayTable-".$self->id().$self->selected_version().".tbl") {
2334          $TableObject->save();                  $tbl = FIGMODELTable::load_table($self->directory()."MinimalPathwayTable-".$self->id().$self->selected_version().".tbl",";","|",0,["Objective","Media","Reversible"]);
2335            } else {
2336                    $tbl = FIGMODELTable->new(["Objective","Media","Reactions","Reversible","Shortest path","Number of essentials","Essentials","Length"],$self->directory()."MinimalPathwayTable-".$self->id().$self->selected_version().".tbl",["Objective","Media","Reversible"],";","|");
2337            }
2338            my @files = glob($self->directory()."MinimalPathways-*");
2339            for (my $i=0; $i < @files;$i++) {
2340                    if ($files[$i] =~ m/MinimalPathways\-(\S+)\-(cpd\d\d\d\d\d)\-(\w+)\-(\d)\-/ || $files[$i] =~ m/MinimalPathways\-(\S+)\-(ENERGY)\-(\w+)\-(\d)\-/) {
2341                            my $reactions = $self->figmodel()->database()->load_single_column_file($files[$i],"");
2342                            if (defined($reactions) && @{$reactions} > 0 && length($reactions->[0]) > 0) {
2343                                    my $newrow = {"Objective"=>[$2],"Media"=>[$1],"Reversible"=>[$4]};
2344                                    my $row = $tbl->get_table_by_key($newrow->{"Objective"}->[0],"Objective")->get_table_by_key($newrow->{"Media"}->[0],"Media")->get_row_by_key($newrow->{"Reversible"}->[0],"Reversible");
2345                                    if (!defined($row)) {
2346                                            $row = $tbl->add_row($newrow);
2347                                    }
2348                                    $row->{Reactions} = $self->figmodel()->database()->load_single_column_file($files[$i],"");
2349                                    delete($row->{"Shortest path"});
2350                                    delete($row->{"Number of essentials"});
2351                                    delete($row->{"Essentials"});
2352                                    delete($row->{"Length"});
2353                                    for (my $j=0; $j < @{$row->{Reactions}}; $j++) {
2354                                            my @array = split(/,/,$row->{Reactions}->[$j]);
2355                                            $row->{"Length"}->[$j] = @array;
2356                                            if (!defined($row->{"Shortest path"}->[0]) || $row->{"Length"}->[$j] < $row->{"Shortest path"}->[0]) {
2357                                                    $row->{"Shortest path"}->[0] = $row->{"Length"}->[$j];
2358                                            }
2359                                            $row->{"Number of essentials"}->[0] = 0;
2360                                            for (my $k=0; $k < @array;$k++) {
2361                                                    if ($array[$k] =~ m/(rxn\d\d\d\d\d)/) {
2362                                                            my $class = $self->get_reaction_class($1,1);
2363                                                            my $temp = $row->{Media}->[0].":Essential";
2364                                                            if ($class =~ m/$temp/) {
2365                                                                    $row->{"Number of essentials"}->[$j]++;
2366                                                                    if (!defined($row->{"Essentials"}->[$j]) && length($row->{"Essentials"}->[$j]) > 0) {
2367                                                                            $row->{"Essentials"}->[$j] = $array[$k];
2368                                                                    } else {
2369                                                                            $row->{"Essentials"}->[$j] .= ",".$array[$k];
2370                                                                    }
2371                                                            }
2372                                                    }
2373                                            }
2374                                    }
2375                            }
2376                    }
2377            }
2378            $tbl->save();
2379  }  }
2380    
2381  =head3 calculate_growth  =head3 calculate_growth
# Line 2036  Line 2419 
2419          7.) Dead: these reactions are disconnected from the network.          7.) Dead: these reactions are disconnected from the network.
2420  =cut  =cut
2421  sub classify_model_reactions {  sub classify_model_reactions {
2422          my ($self,$Media) = @_;          my ($self,$Media,$SaveChanges) = @_;
2423    
2424          #Getting unique file for printing model output          #Getting unique file for printing model output
2425          my $UniqueFilename = $self->figmodel()->filename();          my $UniqueFilename = $self->figmodel()->filename();
# Line 2123  Line 2506 
2506                                  $CpdRow->{MEDIA}->[$index] = $Media;                                  $CpdRow->{MEDIA}->[$index] = $Media;
2507                          }                          }
2508                  }                  }
2509                    if (!defined($SaveChanges) || $SaveChanges == 1) {
2510                  $cpdclasstable->save();                  $cpdclasstable->save();
2511          }          }
2512            }
2513          if (defined($ReactionTB)) {          if (defined($ReactionTB)) {
2514                  for (my $i=0; $i < $ReactionTB->size(); $i++) {                  for (my $i=0; $i < $ReactionTB->size(); $i++) {
2515                          my $Row = $ReactionTB->get_row($i);                          my $Row = $ReactionTB->get_row($i);
# Line 2179  Line 2564 
2564                                  $RxnRow->{MEDIA}->[$index] = $Media;                                  $RxnRow->{MEDIA}->[$index] = $Media;
2565                          }                          }
2566                  }                  }
2567                    if (!defined($SaveChanges) || $SaveChanges == 1) {
2568                  $rxnclasstable->save();                  $rxnclasstable->save();
2569          }          }
2570            }
2571          return ($rxnclasstable,$cpdclasstable);          return ($rxnclasstable,$cpdclasstable);
2572  }  }
2573    
# Line 2212  Line 2599 
2599    
2600          #Running simulations          #Running simulations
2601          system($self->config("mfalite executable")->[0]." ".$self->config("Reaction database directory")->[0]."masterfiles/MediaTable.txt ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/Jobfile.txt ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/Output.txt");          system($self->config("mfalite executable")->[0]." ".$self->config("Reaction database directory")->[0]."masterfiles/MediaTable.txt ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/Jobfile.txt ".$self->config("MFAToolkit output directory")->[0].$UniqueFilename."/Output.txt");
         print "simulation complete for ".$self->id().$self->selected_version()."\n";  
2602          #Parsing the results          #Parsing the results
2603          my $Results = $self->figmodel()->database()->load_table($self->config("MFAToolkit output directory")->[0].$UniqueFilename."/Output.txt",";","\\|",0,undef);          my $Results = $self->figmodel()->database()->load_table($self->config("MFAToolkit output directory")->[0].$UniqueFilename."/Output.txt",";","\\|",0,undef);
2604          if (!defined($Results)) {          if (!defined($Results)) {
# Line 2619  Line 3005 
3005                                          if (length($GapFillingRunSpecs) > 0) {                                          if (length($GapFillingRunSpecs) > 0) {
3006                                                  $GapFillingRunSpecs .= ";";                                                  $GapFillingRunSpecs .= ";";
3007                                          }                                          }
3008                                          $GapFillingRunSpecs .= $HeadingDataArray[2].":".$HeadingDataArray[1].".txt:".$HeadingDataArray[3];                                          $GapFillingRunSpecs .= $HeadingDataArray[2].":".$HeadingDataArray[1].":".$HeadingDataArray[3];
3009                                  } else {                                  } else {
3010                                          $SolutionExistedCount++;                                          $SolutionExistedCount++;
3011                                  }                                  }
# Line 2644  Line 3030 
3030          my $SolutionsFound = 0;          my $SolutionsFound = 0;
3031          my $GapFillingArray;          my $GapFillingArray;
3032          push(@{$GapFillingArray},split(/;/,$GapFillingRunSpecs));          push(@{$GapFillingArray},split(/;/,$GapFillingRunSpecs));
3033          $self->datagapfill($GapFillingArray);          my $GapFillingResults = $self->datagapfill($GapFillingArray,"GFS");
3034            if (defined($GapFillingResults)) {
3035                    $SolutionsFound = 1;
3036            }
3037    
3038          if (defined($RescuedPreviousResults) && @{$RescuedPreviousResults} > 0) {          if (defined($RescuedPreviousResults) && @{$RescuedPreviousResults} > 0) {
3039                  #Printing previous solutions to GFS file                  #Printing previous solutions to GFS file
# Line 2667  Line 3056 
3056          return $self->success();          return $self->success();
3057  }  }
3058    
3059    =head3 SolutionReconciliation
3060    Definition:
3061            FIGMODELmodel->SolutionReconciliation();
3062    Description:
3063            This is a wrapper for running the solution reconciliation algorithm on any model in the database.
3064            The algorithm performs a reconciliation of any gap filling solutions to identify the combination of solutions that results in the optimal model.
3065            This function prints out one output file in the Model directory: ReconciliationOutput.txt: this is a summary of the results of the reconciliation analysis
3066    =cut
3067    
3068    sub SolutionReconciliation {
3069            my ($self,$GapFill,$Stage) = @_;
3070    
3071            #Setting the output filenames
3072            my $OutputFilename;
3073            my $OutputFilenameTwo;
3074            if ($GapFill == 1) {
3075                    $OutputFilename = $self->directory().$self->id().$self->selected_version()."-GFReconciliation.txt";
3076                    $OutputFilenameTwo = $self->directory().$self->id().$self->selected_version()."-GFSRS.txt";
3077            } else {
3078                    $OutputFilename = $self->directory().$self->id().$self->selected_version()."-GGReconciliation.txt";
3079                    $OutputFilenameTwo = $self->directory().$self->id().$self->selected_version()."-GGSRS.txt";
3080            }
3081    
3082            #In stage one, we run the reconciliation and create a test file to check combined solution performance
3083            if (!defined($Stage) || $Stage == 1) {
3084                    my $GrowMatchTable = $self->figmodel()->database()->LockDBTable("GROWMATCH TABLE");
3085                    my $Row = $GrowMatchTable->get_row_by_key($self->genome(),"ORGANISM",1);
3086                    $Row->{"GF RECONCILATION TIMING"}->[0] = time()."-";
3087                    $GrowMatchTable->save();
3088                    $self->figmodel()->database()->UnlockDBTable("GROWMATCH TABLE");
3089    
3090                    #Getting a unique filename
3091                    my $UniqueFilename = $self->figmodel()->filename();
3092    
3093                    #Copying over the necessary files
3094                    if ($GapFill == 1) {
3095                            if (!-e $self->directory().$self->id().$self->selected_version()."-GFEM.txt") {
3096                                    print STDERR "FIGMODEL:SolutionReconciliation:".$self->directory().$self->id().$self->selected_version()."-GFEM.txt file not found. Could not reconcile!";
3097                                    return 0;
3098                            }
3099                            if (!-e $self->directory().$self->id().$self->selected_version()."-OPEM.txt") {
3100                                    print STDERR "FIGMODEL:SolutionReconciliation:".$self->directory().$self->id().$self->selected_version()."-OPEM.txt file not found. Could not reconcile!";
3101                                    return 0;
3102                            }
3103                            system("cp ".$self->directory().$self->id().$self->selected_version()."-GFEM.txt ".$self->figmodel()->config("MFAToolkit input files")->[0].$UniqueFilename."-GFEM.txt");
3104                            system("cp ".$self->directory().$self->id().$self->selected_version()."-OPEM.txt ".$self->figmodel()->config("MFAToolkit input files")->[0].$UniqueFilename."-OPEM.txt");
3105                            #Backing up and deleting the existing reconciliation file
3106                            if (-e $OutputFilename) {
3107                                    system("cp ".$OutputFilename." ".$self->directory().$self->id().$self->selected_version()."-OldGFReconciliation.txt");
3108                                    unlink($OutputFilename);
3109                            }
3110                    } else {
3111                            if (!-e $self->directory().$self->id().$self->selected_version()."-GGEM.txt") {
3112                                    print STDERR "FIGMODEL:SolutionReconciliation:".$self->directory().$self->id().$self->selected_version()."-GGEM.txt file not found. Could not reconcile!";
3113                                    return 0;
3114                            }
3115                            if (!-e $self->directory().$self->id().$self->selected_version()."-GGOPEM.txt") {
3116                                    print STDERR "FIGMODEL:SolutionReconciliation:".$self->directory().$self->id().$self->selected_version()."-GGOPEM.txt file not found. Could not reconcile!";
3117                                    return 0;
3118                            }
3119                            system("cp ".$self->directory().$self->id().$self->selected_version()."-GGEM.txt ".$self->figmodel()->config("MFAToolkit input files")->[0].$UniqueFilename."-GGEM.txt");
3120                            system("cp ".$self->directory().$self->id().$self->selected_version()."-GGOPEM.txt ".$self->figmodel()->config("MFAToolkit input files")->[0].$UniqueFilename."-OPEM.txt");
3121                            #Backing up and deleting the existing reconciliation file
3122                            if (-e $OutputFilename) {
3123                                    system("cp ".$OutputFilename." ".$self->directory().$self->id().$self->selected_version()."-OldGGReconciliation.txt");
3124                                    unlink($OutputFilename);
3125                            }
3126                    }
3127    
3128                    #Running the reconciliation
3129                    system($self->figmodel()->GenerateMFAToolkitCommandLineCall($UniqueFilename,$self->id(),"NONE",["SolutionReconciliation"],{"Solution data for model optimization" => $UniqueFilename},"Reconciliation".$UniqueFilename.".log",undef,$self->selected_version()));
3130                    $GrowMatchTable = $self->figmodel()->database()->LockDBTable("GROWMATCH TABLE");
3131                    $Row = $GrowMatchTable->get_row_by_key($self->genome(),"ORGANISM",1);
3132                    $Row->{"GF RECONCILATION TIMING"}->[0] .= time();
3133                    $GrowMatchTable->save();
3134                    $self->figmodel()->database()->UnlockDBTable("GROWMATCH TABLE");
3135    
3136                    #Loading the problem report from the reconciliation run
3137                    my $ReconciliatonOutput = $self->figmodel()->LoadProblemReport($UniqueFilename);
3138                    print $UniqueFilename."\n";
3139                    #Clearing output files
3140                    $self->figmodel()->clearing_output($UniqueFilename,"Reconciliation".$UniqueFilename.".log");
3141                    $ReconciliatonOutput->save("/home/chenry/Test.txt");
3142    
3143                    #Checking the a problem report was found and was loaded
3144                    if (!defined($ReconciliatonOutput) || $ReconciliatonOutput->size() < 1 || !defined($ReconciliatonOutput->get_row(0)->{"Notes"}->[0])) {
3145                            print STDERR "FIGMODEL:SolutionReconciliation: MFAToolkit output from SolutionReconciliation of ".$self->id()." not found!\n\n";
3146                            return 0;
3147                    }
3148    
3149                    #Processing the solutions
3150                    my $SolutionCount = 0;
3151                    my $ReactionSetHash;
3152                    my $SingleReactionHash;
3153                    my $ReactionDataHash;
3154                    for (my $n=0; $n < $ReconciliatonOutput->size(); $n++) {
3155                            if (defined($ReconciliatonOutput->get_row($n)->{"Notes"}->[0]) && $ReconciliatonOutput->get_row($n)->{"Notes"}->[0] =~ m/^Recursive\sMILP\s([^;]+)/) {
3156                                    #Breaking up the solution into reaction sets
3157                                    my @ReactionSets = split(/\|/,$1);
3158                                    #Creating reaction lists for each set
3159                                    my $SolutionHash;
3160                                    for (my $i=0; $i < @ReactionSets; $i++) {
3161                                            if (length($ReactionSets[$i]) > 0) {
3162                                                    my @Alternatives = split(/:/,$ReactionSets[$i]);
3163                                                    for (my $j=1; $j < @Alternatives; $j++) {
3164                                                            if (length($Alternatives[$j]) > 0) {
3165                                                                    push(@{$SolutionHash->{$Alternatives[$j]}},$Alternatives[0]);
3166                                                            }
3167                                                    }
3168                                                    if (@Alternatives == 1) {
3169                                                            $SingleReactionHash->{$Alternatives[0]}->{$SolutionCount} = 1;
3170                                                            if (!defined($SingleReactionHash->{$Alternatives[0]}->{"COUNT"})) {
3171                                                                    $SingleReactionHash->{$Alternatives[0]}->{"COUNT"} = 0;
3172                                                            }
3173                                                            $SingleReactionHash->{$Alternatives[0]}->{"COUNT"}++;
3174                                                    }
3175                                            }
3176                                    }
3177                                    #Identifying reactions sets and storing the sets in the reactions set hash
3178                                    foreach my $Solution (keys(%{$SolutionHash})) {
3179                                            my $SetKey = join(",",sort(@{$SolutionHash->{$Solution}}));
3180                                            if (!defined($ReactionSetHash->{$SetKey}->{$SetKey}->{$SolutionCount})) {
3181                                                    $ReactionSetHash->{$SetKey}->{$SetKey}->{$SolutionCount} = 1;
3182                                                    if (!defined($ReactionSetHash->{$SetKey}->{$SetKey}->{"COUNT"})) {
3183                                                            $ReactionSetHash->{$SetKey}->{$SetKey}->{"COUNT"} = 0;
3184                                                    }
3185                                                    $ReactionSetHash->{$SetKey}->{$SetKey}->{"COUNT"}++;
3186                                            }
3187                                            $ReactionSetHash->{$SetKey}->{$Solution}->{$SolutionCount} = 1;
3188                                            if (!defined($ReactionSetHash->{$SetKey}->{$Solution}->{"COUNT"})) {
3189                                                    $ReactionSetHash->{$SetKey}->{$Solution}->{"COUNT"} = 0;
3190                                            }
3191                                            $ReactionSetHash->{$SetKey}->{$Solution}->{"COUNT"}++;
3192                                    }
3193                                    $SolutionCount++;
3194                            }
3195                    }
3196    
3197                    #Handling the scenario where no solutions were found
3198                    if ($SolutionCount == 0) {
3199                            print STDERR "FIGMODEL:SolutionReconciliation: Reconciliation unsuccessful. No solution found.\n\n";
3200                            return 0;
3201                    }
3202    
3203                    #Printing results without solution performance figures. Also printing solution test file
3204                    open (RECONCILIATION, ">$OutputFilename");
3205                    #Printing the file heading
3206                    print RECONCILIATION "DATABASE;DEFINITION;REVERSIBLITY;DELTAG;DIRECTION;NUMBER OF SOLUTIONS";
3207                    for (my $i=0; $i < $SolutionCount; $i++) {
3208                            print RECONCILIATION ";Solution ".$i;
3209                    }
3210                    print RECONCILIATION "\n";
3211                    #Printing the singlet reactions first
3212                    my $Solutions;
3213                    print RECONCILIATION "SINGLET REACTIONS\n";
3214                    my @SingletReactions = keys(%{$SingleReactionHash});
3215                    for (my $j=0; $j < $SolutionCount; $j++) {
3216                            $Solutions->[$j]->{"BASE"} = $j;
3217                    }
3218                    for (my $i=0; $i < @SingletReactions; $i++) {
3219                            my $ReactionData;
3220                            if (defined($ReactionDataHash->{$SingletReactions[$i]})) {
3221                                    $ReactionData = $ReactionDataHash->{$SingletReactions[$i]};
3222                            } else {
3223                                    my $Direction = substr($SingletReactions[$i],0,1);
3224                                    if ($Direction eq "+") {
3225                                            $Direction = "=>";
3226                                    } else {
3227                                            $Direction = "<=";
3228                                    }
3229                                    my $Reaction = substr($SingletReactions[$i],1);
3230                                    $ReactionData = FIGMODELObject->load($self->figmodel()->config("reaction directory")->[0].$Reaction,"\t");
3231                                    $ReactionData->{"DIRECTIONS"}->[0] = $Direction;
3232                                    $ReactionData->{"REACTIONS"}->[0] = $Reaction;
3233                                    if (!defined($ReactionData->{"DEFINITION"}->[0])) {
3234                                            $ReactionData->{"DEFINITION"}->[0] = "UNKNOWN";
3235                                    }
3236                                    if (!defined($ReactionData->{"THERMODYNAMIC REVERSIBILITY"}->[0])) {
3237                                            $ReactionData->{"THERMODYNAMIC REVERSIBILITY"}->[0] = "UNKNOWN";
3238                                    }
3239                                    if (!defined($ReactionData->{"DELTAG"}->[0])) {
3240                                            $ReactionData->{"DELTAG"}->[0] = "UNKNOWN";
3241                                    }
3242                                    $ReactionDataHash->{$SingletReactions[$i]} = $ReactionData;
3243                            }
3244                            print RECONCILIATION $ReactionData->{"REACTIONS"}->[0].";".$ReactionData->{"DEFINITION"}->[0].";".$ReactionData->{"THERMODYNAMIC REVERSIBILITY"}->[0].";".$ReactionData->{"DELTAG"}->[0].";".$ReactionData->{"DIRECTIONS"}->[0].";".$SingleReactionHash->{$SingletReactions[$i]}->{"COUNT"};
3245                            for (my $j=0; $j < $SolutionCount; $j++) {
3246                                    print RECONCILIATION ";";
3247                                    if (defined($SingleReactionHash->{$SingletReactions[$i]}->{$j})) {
3248                                            $Solutions->[$j]->{$SingletReactions[$i]} = 1;
3249                                            $Solutions->[$j]->{"BASE"} = $j;
3250                                            print RECONCILIATION "|".$j."|";
3251                                    }
3252                            }
3253                            print RECONCILIATION "\n";
3254                    }
3255                    #Printing the reaction sets with alternatives
3256                    print RECONCILIATION "Reaction sets with alternatives\n";
3257                    my @ReactionSets = keys(%{$ReactionSetHash});
3258                    foreach my $ReactionSet (@ReactionSets) {
3259                            my $NewSolutions;
3260                            my $BaseReactions;
3261                            my $AltList = [$ReactionSet];
3262                            push(@{$AltList},keys(%{$ReactionSetHash->{$ReactionSet}}));
3263                            for (my $j=0; $j < @{$AltList}; $j++) {
3264                                    my $CurrentNewSolutions;
3265                                    my $Index;
3266                                    if ($j == 0) {
3267                                            print RECONCILIATION "NEW SET\n";
3268                                    } elsif ($AltList->[$j] ne $ReactionSet) {
3269                                            print RECONCILIATION "ALTERNATIVE SET\n";
3270                                            #For each base solution in which this set is represented, we copy the base solution to the new solution
3271                                            my $NewSolutionCount = 0;
3272                                            for (my $k=0; $k < $SolutionCount; $k++) {
3273                                                    if (defined($ReactionSetHash->{$ReactionSet}->{$AltList->[$j]}->{$k})) {
3274                                                            if (defined($Solutions)) {
3275                                                                    $Index->{$k} = @{$Solutions} + $NewSolutionCount;
3276                                                            } else {
3277                                                                    $Index->{$k} = $NewSolutionCount;
3278                                                            }
3279                                                            if (defined($NewSolutions) && @{$NewSolutions} > 0) {
3280                                                                    $Index->{$k} += @{$NewSolutions};
3281                                                            }
3282                                                            $CurrentNewSolutions->[$NewSolutionCount] = {};
3283                                                            foreach my $Reaction (keys(%{$Solutions->[$k]})) {
3284                                                                    $CurrentNewSolutions->[$NewSolutionCount]->{$Reaction} = $Solutions->[$k]->{$Reaction};
3285                                                            }
3286                                                            $NewSolutionCount++;
3287                                                    }
3288                                            }
3289                                    }
3290                                    if ($j == 0 || $AltList->[$j] ne $ReactionSet) {
3291                                            my @SingletReactions = split(/,/,$AltList->[$j]);
3292                                            for (my $i=0; $i < @SingletReactions; $i++) {
3293                                                    #Adding base reactions to base solutions and set reactions the new solutions
3294                                                    if ($j == 0) {
3295                                                            push(@{$BaseReactions},$SingletReactions[$i]);
3296                                                    } else {
3297                                                            for (my $k=0; $k < @{$CurrentNewSolutions}; $k++) {
3298                                                                    $CurrentNewSolutions->[$k]->{$SingletReactions[$i]} = 1;
3299                                                            }
3300                                                    }
3301                                                    #Getting reaction data and printing reaction in output file
3302                                                    my $ReactionData;
3303                                                    if (defined($ReactionDataHash->{$SingletReactions[$i]})) {
3304                                                            $ReactionData = $ReactionDataHash->{$SingletReactions[$i]};
3305                                                    } else {
3306                                                            my $Direction = substr($SingletReactions[$i],0,1);
3307                                                            if ($Direction eq "+") {
3308                                                                    $Direction = "=>";
3309                                                            } else {
3310                                                                    $Direction = "<=";
3311                                                            }
3312                                                            my $Reaction = substr($SingletReactions[$i],1);
3313                                                            $ReactionData = FIGMODELObject->load($self->figmodel()->config("reaction directory")->[0].$Reaction,"\t");
3314                                                            $ReactionData->{"DIRECTIONS"}->[0] = $Direction;
3315                                                            $ReactionData->{"REACTIONS"}->[0] = $Reaction;
3316                                                            if (!defined($ReactionData->{"DEFINITION"}->[0])) {
3317                                                                    $ReactionData->{"DEFINITION"}->[0] = "UNKNOWN";
3318                                                            }
3319                                                            if (!defined($ReactionData->{"THERMODYNAMIC REVERSIBILITY"}->[0])) {
3320                                                                    $ReactionData->{"THERMODYNAMIC REVERSIBILITY"}->[0] = "UNKNOWN";
3321                                                            }
3322                                                            if (!defined($ReactionData->{"DELTAG"}->[0])) {
3323                                                                    $ReactionData->{"DELTAG"}->[0] = "UNKNOWN";
3324                                                            }
3325                                                            $ReactionDataHash->{$SingletReactions[$i]} = $ReactionData;
3326                                                    }
3327                                                    print RECONCILIATION $ReactionData->{"REACTIONS"}->[0].";".$ReactionData->{"DEFINITION"}->[0].";".$ReactionData->{"THERMODYNAMIC REVERSIBILITY"}->[0].";".$ReactionData->{"DELTAG"}->[0].";".$ReactionData->{"DIRECTIONS"}->[0].";".$ReactionSetHash->{$ReactionSet}->{$AltList->[$j]}->{"COUNT"};
3328                                                    for (my $k=0; $k < $SolutionCount; $k++) {
3329                                                            print RECONCILIATION ";";
3330                                                            if (defined($ReactionSetHash->{$ReactionSet}->{$AltList->[$j]}->{$k})) {
3331                                                                    if ($j == 0) {
3332                                                                            print RECONCILIATION "|".$k."|";
3333                                                                    } else {
3334                                                                            print RECONCILIATION "|".$Index->{$k}."|";
3335                                                                    }
3336                                                            }
3337                                                    }
3338                                                    print RECONCILIATION "\n";
3339                                            }
3340                                            #Adding the current new solutions to the new solutions array
3341                                            if (defined($CurrentNewSolutions) && @{$CurrentNewSolutions} > 0) {
3342                                                    push(@{$NewSolutions},@{$CurrentNewSolutions});
3343                                            }
3344                                    }
3345                            }
3346                            #Adding the base reactions to all existing solutions
3347                            for (my $j=0; $j < @{$Solutions}; $j++) {
3348                                    if (defined($ReactionSetHash->{$ReactionSet}->{$ReactionSet}->{$Solutions->[$j]->{"BASE"}})) {
3349                                            foreach my $SingleReaction (@{$BaseReactions}) {
3350                                                    $Solutions->[$j]->{$SingleReaction} = 1;
3351                                            }
3352                                    }
3353                            }
3354                            #Adding the new solutions to the set of existing solutions
3355                            push(@{$Solutions},@{$NewSolutions});
3356                    }
3357                    close(RECONCILIATION);
3358                    #Now printing a file that defines all of the solutions in a format the testsolutions function understands
3359                    open (RECONCILIATION, ">$OutputFilenameTwo");
3360                    print RECONCILIATION "Experiment;Solution index;Solution cost;Solution reactions\n";
3361                    for (my $i=0; $i < @{$Solutions}; $i++) {
3362                            delete($Solutions->[$i]->{"BASE"});
3363                            print RECONCILIATION "SR".$i.";".$i.";10;".join(",",keys(%{$Solutions->[$i]}))."\n";
3364                    }
3365                    close(RECONCILIATION);
3366    
3367                    $GrowMatchTable = $self->figmodel()->database()->LockDBTable("GROWMATCH TABLE");
3368                    $Row = $GrowMatchTable->get_row_by_key($self->genome(),"ORGANISM",1);
3369                    $Row->{"GF RECON TESTING TIMING"}->[0] = time()."-";
3370                    $Row->{"GF RECON SOLUTIONS"}->[0] = @{$Solutions};
3371                    $GrowMatchTable->save();
3372                    $self->figmodel()->database()->UnlockDBTable("GROWMATCH TABLE");
3373    
3374                    #Scheduling the solution testing
3375                    if ($GapFill == 1) {
3376                            system($self->figmodel()->config("scheduler executable")->[0]." \"add:testsolutions?".$self->id().$self->selected_version()."?-1?GFSR:BACK:fast:QSUB\"");
3377                    } else {
3378                            system($self->figmodel()->config("scheduler executable")->[0]." \"add:testsolutions?".$self->id().$self->selected_version()."?-1?GGSR:BACK:fast:QSUB\"");
3379                    }
3380            } else {
3381                    #Reading in the solution testing results
3382                    my $Data;
3383                    if ($GapFill == 1) {
3384                            $Data = $self->figmodel()->database()->load_single_column_file($self->directory().$self->id().$self->selected_version()."-GFSREM.txt","");
3385                    } else {
3386                            $Data = $self->figmodel()->database()->load_single_column_file($self->directory().$self->id().$self->selected_version()."-GGSREM.txt","");
3387                    }
3388    
3389                    #Reading in the preliminate reconciliation report
3390                    my $OutputData = $self->figmodel()->database()->load_single_column_file($OutputFilename,"");
3391                    #Replacing the file tags with actual performance data
3392                    my $Count = 0;
3393                    for (my $i=0; $i < @{$Data}; $i++) {
3394                            if ($Data->[$i] =~ m/^SR(\d+);.+;(\d+\/\d+);/) {
3395                                    my $Index = $1;
3396                                    my $Performance = $Index."/".$2;
3397                                    for (my $j=0; $j < @{$OutputData}; $j++) {
3398                                            $OutputData->[$j] =~ s/\|$Index\|/$Performance/g;
3399                                    }
3400                            }
3401                    }
3402                    $self->figmodel()->database()->print_array_to_file($OutputFilename,$OutputData);
3403    
3404                    my $GrowMatchTable = $self->figmodel()->database()->LockDBTable("GROWMATCH TABLE");
3405                    my $Row = $GrowMatchTable->get_row_by_key($self->genome(),"ORGANISM",1);
3406                    $Row->{"GF RECON TESTING TIMING"}->[0] .= time();
3407                    $GrowMatchTable->save();
3408                    $self->figmodel()->database()->UnlockDBTable("GROWMATCH TABLE");
3409            }
3410    
3411            return 1;
3412    }
3413    
3414  =head3 BuildSpecificBiomassReaction  =head3 BuildSpecificBiomassReaction
3415  Definition:  Definition:
3416          FIGMODELmodel->BuildSpecificBiomassReaction();          FIGMODELmodel->BuildSpecificBiomassReaction();
# Line 2679  Line 3423 
3423          my $OrganismID = $self->genome();          my $OrganismID = $self->genome();
3424          #Checking for a biomass override          #Checking for a biomass override
3425          if (defined($self->config("biomass reaction override")->{$OrganismID})) {          if (defined($self->config("biomass reaction override")->{$OrganismID})) {
3426                  $biomassrxn = $self->config("biomass reaction override")->{$OrganismID};                  my $biomassID = $self->config("biomass reaction override")->{$OrganismID};
3427                  print "Overriding biomass template and selecting ".$biomassrxn." for ".$OrganismID.".\n";                  my $tbl = $self->database()->get_table("BIOMASS",1);
3428                    $biomassrxn = $tbl->get_row_by_key($biomassID,"DATABASE");
3429                    print "Overriding biomass template and selecting ".$biomassID." for ".$OrganismID.".\n";
3430          } else {#Creating biomass reaction from the template          } else {#Creating biomass reaction from the template
3431                  #Getting the genome stats                  #Getting the genome stats
3432                  my $genomestats = $self->figmodel()->get_genome_stats($self->genome());                  my $genomestats = $self->figmodel()->get_genome_stats($self->genome());
# Line 2971  Line 3717 
3717    
3718                  #Adding the biomass equation to the biomass table                  #Adding the biomass equation to the biomass table
3719                  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());
3720                  $biomassrxn = $NewRow->{DATABASE}->[0];                  $biomassrxn = $NewRow;
                 print $biomassrxn."\n";  
3721          }          }
3722          print $biomassrxn."\n";          return $biomassrxn;
         my $BiomassRow = $self->figmodel()->add_model_to_biomass_reaction($biomassrxn,$self->id());  
         return $BiomassRow;  
3723  }  }
3724    
3725  =head3 PrintSBMLFile  =head3 PrintSBMLFile
# Line 3263  Line 4006 
4006          close(SBMLOUTPUT);          close(SBMLOUTPUT);
4007  }  }
4008    
4009    =head3 PrintModelSimpleReactionTable
4010    Definition:
4011            success()/fail() FIGMODELmodel->PrintModelSimpleReactionTable();
4012    Description:
4013            Prints the table of model data
4014    =cut
4015    sub PrintModelSimpleReactionTable {
4016            my ($self) = @_;
4017    
4018            my $rxntbl = $self->reaction_table();
4019            my $tbl = $self->create_table_prototype("ModelSimpleReactionTable");
4020            for (my $i=0; $i < $rxntbl->size(); $i++) {
4021                    my $row = $rxntbl->get_row($i);
4022                    $row->{DATABASE} = $row->{LOAD};
4023                    $tbl->add_row($row);
4024            }
4025            $tbl->save();
4026            system("cp ".$tbl->filename()." ".$self->figmodel()->config("Model table download directory")->[0].$self->figmodel()->config("ModelSimpleReactionTable")->{filename_prefix}->[0]."-".$self->id().".txt");
4027    }
4028    
4029  =head3 PrintModelLPFile  =head3 PrintModelLPFile
4030  Definition:  Definition:
4031          success()/fail() FIGMODELmodel->PrintModelLPFile();          success()/fail() FIGMODELmodel->PrintModelLPFile();
# Line 3287  Line 4050 
4050          $self->figmodel()->clearing_output($UniqueFilename,"FBA-".$self->id().$self->selected_version().".lp");          $self->figmodel()->clearing_output($UniqueFilename,"FBA-".$self->id().$self->selected_version().".lp");
4051  }  }
4052    
4053    =head3 patch_model
4054    Definition:
4055            FIGMODELTable:patch results = FIGMODELmodel->patch_model(FIGMODELTable:patch table);
4056    Description:
4057    =cut
4058    sub patch_model {
4059            my ($self,$tbl) = @_;
4060    
4061            #Instantiating table
4062            my $results = FIGMODELTable->new(["Reactions","New genes","Old genes","Genes","Roles","Status"],$self->directory()."PatchResults-".$self->id().$self->selected_version().".tbl",["Reaction"],"\t",";",undef);
4063            #Getting genome annotations
4064            my $features = $self->figmodel()->database()->get_genome_feature_table($self->genome());
4065            #Gettubg reaction table
4066            my $reactions = $self->reaction_table();
4067            #Checking for patched roles
4068            for (my $i=0; $i < $tbl->size(); $i++) {
4069                    my $row = $tbl->get_row($i);
4070                    my @genes = $features->get_rows_by_key($row->{ROLE}->[0],"ROLES");
4071                    if (@genes > 0) {
4072                            for (my $j=0; $j < @{$row->{REACTIONS}};$j++) {
4073                                    my $resultrxn = $results->get_row_by_key($row->{REACTIONS}->[$j],"Reactions");
4074                                    if (!defined($resultrxn)) {
4075                                            $resultrxn = $results->add_row({"Reactions"=>[$row->{REACTIONS}->[$j]],"Roles"=>[$row->{ROLE}->[0]]});
4076                                    }
4077                                    my $rxnrow = $reactions->get_row_by_key($row->{REACTIONS}->[$j],"LOAD");
4078                                    if (defined($rxnrow) && !defined($resultrxn->{"Old genes"})) {
4079                                            $resultrxn->{"Old genes"} = $rxnrow->{"ASSOCIATED PEG"};
4080                                            if ($resultrxn->{"Old genes"}->[0] !~ m/GAP|BOF|UNIVERSAL|SPONTANEOUS/) {
4081                                                    push(@{$resultrxn->{"Genes"}},@{$resultrxn->{"Old genes"}});
4082                                            }
4083                                    }
4084                                    delete $resultrxn->{"Current gene set"};
4085                                    if (defined($resultrxn->{"Genes"})) {
4086                                            push(@{$resultrxn->{"Current gene set"}},@{$resultrxn->{"Genes"}});
4087                                    }
4088                                    for (my $k=0; $k < @genes; $k++) {
4089                                            if ($genes[$k]->{ID}->[0] =~ m/(peg\.\d+)/) {
4090                                                    my $gene = $1;
4091                                                    my $addgene = 1;
4092                                                    if (defined($resultrxn->{"Old genes"})) {
4093                                                            for (my $m=0; $m < @{$resultrxn->{"Old genes"}}; $m++) {
4094                                                                    if ($resultrxn->{"Old genes"}->[$m] =~ m/$gene/) {
4095                                                                            $addgene = 0;
4096                                                                    }
4097                                                            }
4098                                                    }
4099                                                    if ($addgene == 1) {
4100                                                            push(@{$resultrxn->{"New genes"}},$gene);
4101                                                            if ($row->{COMPLEX}->[0] ne "0" && defined($resultrxn->{"Current gene set"})) {
4102                                                                    my $added = 0;
4103                                                                    for (my $m=0; $m < @{$resultrxn->{"Current gene set"}}; $m++) {
4104                                                                            if ($row->{COMPLEX}->[0] eq "1") {
4105                                                                                    $resultrxn->{"Current gene set"}->[$m] = $resultrxn->{"Current gene set"}->[$m]."+".$gene;
4106                                                                                    $added = 1;
4107                                                                            } else {
4108                                                                                    my @geneset = split(/\+/,$resultrxn->{"Current gene set"}->[$m]);
4109                                                                                    for (my $n=0; $n < @geneset;$n++) {
4110                                                                                            if ($self->figmodel()->colocalized_genes($geneset[$n],$gene,$self->genome()) == 1) {
4111                                                                                                    $resultrxn->{"Current gene set"}->[$m] = $resultrxn->{"Current gene set"}->[$m]."+".$gene;
4112                                                                                                    $added = 1;
4113                                                                                                    last;
4114                                                                                            }
4115                                                                                    }
4116                                                                            }
4117                                                                    }
4118                                                                    if ($added == 0) {
4119                                                                            push(@{$resultrxn->{"Current gene set"}},$gene);
4120                                                                    }
4121                                                            } else {
4122                                                                    push(@{$resultrxn->{"Current gene set"}},$gene);
4123                                                            }
4124                                                    }
4125                                            }
4126                                    }
4127                                    delete $resultrxn->{"Genes"};
4128                                    push(@{$resultrxn->{"Genes"}},@{$resultrxn->{"Current gene set"}});
4129                            }
4130                    }
4131            }
4132    
4133            #Ensuring that the old model is preserved
4134            $self->ArchiveModel();
4135            #Modifing the reaction list
4136            for (my $i=0; $i < $results->size();$i++) {
4137                    my $row = $results->get_row($i);
4138                    my $rxnrow = $reactions->get_row_by_key($row->{"Reactions"}->[0],"LOAD");
4139                    if (defined($rxnrow)) {
4140                            $rxnrow->{"ASSOCIATED PEG"} = $row->{"Genes"};
4141                    } else {
4142                            $reactions->add_row({LOAD=>[$row->{"Reactions"}->[0]],DIRECTIONALITY=>[$self->figmodel()->reversibility_of_reaction($row->{"Reactions"}->[0])],COMPARTMENT=>["c"],"ASSOCIATED PEG"=>$row->{"Genes"},SUBSYSTEM=>["NONE"],CONFIDENCE=>[2],REFERENCE=>["NONE"],NOTES=>["PATCH"]});
4143                    }
4144            }
4145            $reactions->save();
4146            $results->save();
4147            $self->update_model_stats();
4148            $self->PrintModelLPFile();
4149            $self->run_default_model_predictions();
4150            #Returning results
4151            return $results;
4152    }
4153    
4154    =head3 translate_genes
4155    Definition:
4156            FIGMODELmodel->translate_genes();
4157    Description:
4158    =cut
4159    sub translate_genes {
4160            my ($self) = @_;
4161    
4162            #Loading gene translations
4163            if (!defined($self->{_gene_aliases})) {
4164                    #Loading gene aliases from feature table
4165                    my $tbl = $self->figmodel()->GetGenomeFeatureTable($self->genome());
4166                    if (defined($tbl)) {
4167                            for (my $i=0; $i < $tbl->size(); $i++) {
4168                                    my $row = $tbl->get_row($i);
4169                                    if ($row->{ID}->[0] =~ m/(peg\.\d+)/) {
4170                                            my $geneID = $1;
4171                                            for (my $j=0; $j < @{$row->{ALIASES}}; $j++) {
4172                                                    $self->{_gene_aliases}->{$row->{ALIASES}->[$j]} = $geneID;
4173                                            }
4174                                    }
4175                            }
4176                    }
4177                    #Loading additional gene aliases from the database
4178                    if (-e $self->figmodel()->config("Translation directory")->[0]."AdditionalAliases/".$self->genome().".txt") {
4179                            my $AdditionalAliases = $self->figmodel()->database()->load_multiple_column_file($self->figmodel()->config("Translation directory")->[0]."AdditionalAliases/".$self->genome().".txt","\t");
4180                            for (my $i=0; $i < @{$AdditionalAliases}; $i++) {
4181                                    $self->{_gene_aliases}->{$AdditionalAliases->[$i]->[1]} = $AdditionalAliases->[$i]->[0];
4182                            }
4183                    }
4184            }
4185    
4186            #Cycling through reactions and translating genes
4187            for (my $i=0; $i < $self->reaction_table()->size(); $i++) {
4188                    my $row = $self->reaction_table()->get_row($i);
4189                    if (defined($row->{"ASSOCIATED PEG"})) {
4190                            for (my $j=0; $j < @{$row->{"ASSOCIATED PEG"}}; $j++) {
4191                                    my $Original = $row->{"ASSOCIATED PEG"}->[$j];
4192                                    $Original =~ s/\sand\s/:/g;
4193                                    $Original =~ s/\sor\s/;/g;
4194                                    my @GeneNames = split(/[,\+\s\(\):;]/,$Original);
4195                                    foreach my $Gene (@GeneNames) {
4196                                            if (length($Gene) > 0 && defined($self->{_gene_aliases}->{$Gene})) {
4197                                                    my $Replace = $self->{_gene_aliases}->{$Gene};
4198                                                    $Original =~ s/([^\w])$Gene([^\w])/$1$Replace$2/g;
4199                                                    $Original =~ s/^$Gene([^\w])/$Replace$1/g;
4200                                                    $Original =~ s/([^\w])$Gene$/$1$Replace/g;
4201                                                    $Original =~ s/^$Gene$/$Replace/g;
4202                                            }
4203                                    }
4204                                    $Original =~ s/:/ and /g;
4205                                    $Original =~ s/;/ or /g;
4206                                    $row->{"ASSOCIATED PEG"}->[$j] = $Original;
4207                            }
4208                    }
4209            }
4210    
4211            #Archiving model and saving reaction table
4212            $self->ArchiveModel();
4213            $self->reaction_table()->save();
4214    }
4215    
4216    =head3 feature_web_data
4217    Definition:
4218            string:web output for feature/model connection = FIGMODELmodel->feature_web_data(FIGMODELfeature:feature);
4219    Description:
4220    =cut
4221    sub feature_web_data {
4222            my ($self,$feature) = @_;
4223    
4224            #First checking if the feature is in the model
4225            my $featureGenome = $feature->{GENOME}->[0];
4226            if ($feature->{GENOME}->[0] =~ m/\>(\d+\.\d+)\</) {
4227                    $featureGenome = $1;
4228            }
4229            if ($featureGenome ne $self->genome()) {
4230                    return "Not in model";
4231            }
4232            my $data = $self->get_feature_data($feature->{ID}->[0]);
4233            if (!defined($data)) {
4234                    return "Not in model";
4235            }
4236    
4237            my $output;
4238            #Printing predictions
4239            if (defined($data->{$self->id()."PREDICTIONS"})) {
4240                    #Parsing essentiality data
4241                    my $essentialityData;
4242                    if (defined($feature->{ESSENTIALITY})) {
4243                            for (my $i=0; $i < @{$feature->{ESSENTIALITY}};$i++) {
4244                                    my @temp = split(/:/,$feature->{ESSENTIALITY}->[$i]);
4245                                    $essentialityData->{$temp[0]} = $temp[1];
4246                            }
4247                    }
4248                    my $predictionHash;
4249                    for (my $i=0; $i < @{$data->{$self->id()."PREDICTIONS"}};$i++) {
4250                            my @temp = split(/:/,$data->{$self->id()."PREDICTIONS"}->[$i]);
4251                            if (defined($essentialityData->{$temp[0]})) {
4252                                    if ($temp[1] eq "essential" && $essentialityData->{$temp[0]} eq "essential") {
4253                                            push(@{$predictionHash->{"Correct negative"}},$temp[0]);
4254                                    } elsif ($temp[1] eq "nonessential" && $essentialityData->{$temp[0]} eq "essential") {
4255                                            push(@{$predictionHash->{"False positive"}},$temp[0]);
4256                                    } elsif ($temp[1] eq "essential" && $essentialityData->{$temp[0]} eq "nonessential") {
4257                                            push(@{$predictionHash->{"False negative"}},$temp[0]);
4258                                    } elsif ($temp[1] eq "nonessential" && $essentialityData->{$temp[0]} eq "nonessential") {
4259                                            push(@{$predictionHash->{"Correct positive"}},$temp[0]);
4260                                    }
4261                            } else {
4262                                    push(@{$predictionHash->{$temp[1]}},$temp[0]);
4263                            }
4264                    }
4265                    foreach my $key (keys(%{$predictionHash})) {
4266                            my $string = $key;
4267                            $string = ucfirst($string);
4268                            push(@{$output},'<span title="'.join(", ",@{$predictionHash->{$key}}).'">'.$string.'</span>');
4269                    }
4270            }
4271    
4272            #Printing reactions
4273            if (defined($data->{$self->id()."REACTIONS"})) {
4274                    for (my $i=0; $i < @{$data->{$self->id()."REACTIONS"}};$i++) {
4275                            my $rxnData = $self->get_reaction_data($data->{$self->id()."REACTIONS"}->[$i]);
4276                            my $reactionString = $self->figmodel()->web()->create_reaction_link($data->{$self->id()."REACTIONS"}->[$i],join(" or ",@{$rxnData->{"ASSOCIATED PEG"}}),$self->id());
4277                            if (defined($rxnData->{PREDICTIONS})) {
4278                                    my $predictionHash;
4279                                    for (my $i=0; $i < @{$rxnData->{PREDICTIONS}};$i++) {
4280                                            my @temp = split(/:/,$rxnData->{PREDICTIONS}->[$i]);
4281                                            push(@{$predictionHash->{$temp[1]}},$temp[0]);
4282                                    }
4283                                    $reactionString .= "(";
4284                                    foreach my $key (keys(%{$predictionHash})) {
4285                                            if ($key eq "Essential =>") {
4286                                                    $reactionString .= '<span title="Essential in '.join(",",@{$predictionHash->{$key}}).'">E=></span>,';
4287                                            } elsif ($key eq "Essential <=") {
4288                                                    $reactionString .= '<span title="Essential in '.join(",",@{$predictionHash->{$key}}).'">E<=</span>,';
4289                                            } elsif ($key eq "Active =>") {
4290                                                    $reactionString .= '<span title="Active in '.join(",",@{$predictionHash->{$key}}).'">A=></span>,';
4291                                            } elsif ($key eq "Active <=") {
4292                                                    $reactionString .= '<span title="Active in '.join(",",@{$predictionHash->{$key}}).'">A<=</span>,';
4293                                            } elsif ($key eq "Active <=>") {
4294                                                    $reactionString .= '<span title="Active in '.join(",",@{$predictionHash->{$key}}).'">A</span>,';
4295                                            } elsif ($key eq "Inactive") {
4296                                                    $reactionString .= '<span title="Inactive in '.join(",",@{$predictionHash->{$key}}).'">I</span>,';
4297                                            } elsif ($key eq "Dead") {
4298                                                    $reactionString .= '<span title="Dead">D</span>,';
4299                                            }
4300                                    }
4301                                    $reactionString =~ s/,$/)/;
4302                            }
4303                            push(@{$output},$reactionString);
4304                    }
4305            }
4306    
4307            #Returning output
4308            return join("<br>",@{$output});
4309    }
4310    
4311    =head3 remove_obsolete_reactions
4312    Definition:
4313            void FIGMODELmodel->remove_obsolete_reactions();
4314    Description:
4315    =cut
4316    sub remove_obsolete_reactions {
4317            my ($self) = @_;
4318    
4319            (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"));
4320            my $rxnTbl = $self->reaction_table();
4321            if (defined($rxnTbl)) {
4322                    for (my $i=0; $i < $rxnTbl->size(); $i++) {
4323                            my $row = $rxnTbl->get_row($i);
4324                            if (defined($translation->{$row->{LOAD}->[0]}) || defined($translation->{$row->{LOAD}->[0]."r"})) {
4325                                    my $direction = $row->{DIRECTION}->[0];
4326                                    my $newRxn;
4327                                    if (defined($translation->{$row->{LOAD}->[0]."r"})) {
4328                                            $newRxn = $translation->{$row->{LOAD}->[0]."r"};
4329                                            if ($direction eq "<=") {
4330                                                    $direction = "=>";
4331                                            } elsif ($direction eq "=>") {
4332                                                    $direction = "<=";
4333                                            }
4334                                    } else {
4335                                            $newRxn = $translation->{$row->{LOAD}->[0]};
4336                                    }
4337                                    #Checking if the new reaction is already in the model
4338                                    my $newRow = $rxnTbl->get_row_by_key($newRxn,"LOAD");
4339                                    if (defined($newRow)) {
4340                                            #Handling direction
4341                                            if ($newRow->{DIRECTION}->[0] ne $direction) {
4342                                                    $newRow->{DIRECTION}->[0] = "<=>";
4343                                            }
4344                                            push(@{$row->{"ASSOCIATED PEG"}},@{$rxnTbl->get_row($i)->{"ASSOCIATED PEG"}});
4345                                    } else {
4346                                            $rxnTbl->get_row($i)->{LOAD}->[0] = $newRxn;
4347                                            $rxnTbl->get_row($i)->{DIRECTION}->[0] = $direction;
4348                                    }
4349                            }
4350                    }
4351                    $rxnTbl->save();
4352            }
4353    }
4354    
4355  1;  1;

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

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3