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

View of /FigKernelPackages/FBAMODEL.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.14 - (download) (as text) (annotate)
Fri Nov 5 21:50:06 2010 UTC (9 years, 1 month ago) by dejongh
Branch: MAIN
CVS Tags: rast_rel_2010_1206
Changes since 1.13: +7 -2 lines
fix return

#!/usr/bin/perl -w
use strict;

#
# Copyright (c) 2003-2006 University of Chicago and Fellowship
# for Interpretations of Genomes. All Rights Reserved.
#
# This file is part of the SEED Toolkit.
#
# The SEED Toolkit is free software. You can redistribute
# it and/or modify it under the terms of the SEED Toolkit
# Public License.
#
# You should have received a copy of the SEED Toolkit Public License
# along with this program; if not write to the University of Chicago
# at info@ci.uchicago.edu or the Fellowship for Interpretation of
# Genomes at veronika@thefig.info or download a copy from
# http://www.theseed.org/LICENSE.TXT.
#
package FBAMODEL;

    use strict;
    use FIGMODEL;
	use Tracer;
    use SeedUtils;


=head1 FBA Model Function Object

This file contains the functions and utilities used by the FBAMODEL Server
(B<MODEL_server.cgi>). The L</Primary Methods> represent function
calls direct to the server. These all have a signature similar to the following.

    my $document = FBAMODEL->function_name($args);

where C<$MODELservObject> is an object created by this module, C<$args> is a parameter
structure, and C<function_name> is the FBAMODEL Server function name. The
output is a structure.

=head2 Special Methods

=head3 new

Definition:
	FBAMODEL::FBAMODEL object = FBAMODEL->new();

Description:
    Creates a new FBAMODEL function object. The function object is used to invoke the server functions.

=cut
sub new {
    my ($class) = @_;
    my $FBAMODELObject;
	$FBAMODELObject->{_figmodel} = FIGMODEL->new();
	bless $FBAMODELObject, $class;
    return $FBAMODELObject;
}

=head3 figmodel

Definition:

	FIGMODEL::figmodel object = FBAMODEL->figmodel();

Description:

    Returns the FIGMODEL object required to get model data from the server

=cut
sub figmodel {
    my ($self) = @_;
	return $self->{_figmodel};
}

=head3 methods

Definition:

	FIGMODEL::figmodel object = FBAMODEL->methods();

Description:

    Returns a list of the methods for the class

=cut
sub methods {
    my ($self) = @_;
	if (!defined($self->{_methods})) {
		$self->{_methods} = ["get_reaction_id_list",
			"get_reaction_data",
			"get_biomass_reaction_data",
			"get_compound_id_list",
			"get_compound_data",
			"get_media_id_list",
			"get_media_data",
			"get_model_id_list",
			"get_model_data",
			"classify_model_entities",
			"simulate_all_single_gene_knockout",
			"simulate_model_growth",
			"get_model_reaction_classification_table",
            "get_role_to_complex",
            "get_complex_to_reaction"];
	}
	return $self->{_methods};
}

=head3 authenticate_user

Definition:

	FIGMODEL::figmodel object = FBAMODEL->authenticate_user( { user => string::username,
                                                  password => string::password
                                              } );

Description:

    Determines if user data was input and points to a valid account

=cut
sub authenticate_user {
    my ($self,$args) = @_;
	if (defined($args->{user}) && defined($args->{password})) {
		$self->figmodel()->authenticate_user($args->{user},$args->{password});
	}
	return $args;
}

=head3 process_arguments

Definition:

	{key=>value} = FBAMODEL->process_arguments( {key=>value} );

Description:

    Processes arguments to authenticate users and perform other needed tasks

=cut
sub process_arguments {
    my ($self,$args) = @_;
	return $self->authenticate_user($args);
}

=head2 Primary Methods

=head3 get_reaction_id_list

Definition:

	{ string::model ids => [string::reaction ids] } = FBAMODEL->get_reaction_id_list( {"id" => [string::model id] } );

Description:

Takes as input a hash with key "id" pointing to a list of model IDs. If no
ids are input or if the id "ALL" is submitted, this function will return
a list of all reaction IDs in the database.  Returns a hash with the
model IDs as keys pointing to arrays of the reaction IDs in the models.

Example:

    my $ConfigHashRef = { "id" => ["Seed83333.1", "iJR904"] };
    my $resultsHashRef = $FBAModel->get_reaction_id_list($ConfigHashRef);
    $resultsHashRef == { "iJR904" => [ "rxn00001", "rxn00002", ...],
                         "Seed83333.1" => [ "rxn00003", "rxn00007", ...],
                       }

=cut
sub get_reaction_id_list {
	my ($self, $args) = @_;
	$args = $self->process_arguments($args);
	#List of IDs to be returned will be stored here
	my $ids;
	#First checking that the "id" key exists
	if (!defined($args->{id})) {
		$ids = ["ALL"];
	} else {
		#Checking if the hash contains a single ID instead of a reference to an array of IDs
		if (ref($args->{id}) ne "ARRAY") {
			push(@{$ids},$args->{id});
		} else {
			push(@{$ids},@{$args->{id}});
		}
	}
	#If IDs is ["ALL"], we return an array of all reaction objects
	my $output;
	for (my $i=0; $i < @{$ids}; $i++) {
		if ($ids->[$i] eq "ALL") {
			#Getting the FIGMODELTable with all reactions
			my $tbl = $self->figmodel()->database()->GetDBTable("REACTIONS");
			if (defined($tbl)) {
				for (my $j=0; $j < $tbl->size(); $j++) {
					push(@{$output->{$ids->[$i]}},$tbl->get_row($j)->{DATABASE}->[0]);
				}
			}
		} elsif (defined($self->figmodel()->get_model($ids->[$i]))) {
			my $tbl = $self->figmodel()->get_model($ids->[$i])->reaction_table();
			if (defined($tbl)) {
				for (my $j=0; $j < $tbl->size(); $j++) {
					push(@{$output->{$ids->[$i]}},$tbl->get_row($j)->{LOAD}->[0]);
				}
			}
		}
	}
	#Returning the output
	return $output;
}

=head3 get_reaction_data

Definition:

    { string::reaction ids => { string::keys => [ string::data ]
                                }
      } = FBAMODEL->get_reaction_data( { "id" => [string::reaction ids],
                                         "model" => [string::model ids],
					 "fields" => [string::fields],
					 "model_fields" => [string::fields]
                                     } );

Description:

Takes as input a a hash with key "id" pointing to a list of
reaction IDs and (optionally) the key "model" pointing to a list
of model ids.

Returns a hash with the input IDs as keys pointing to hashes with the
reaction data.  The keys in the reaction data hash are "DATABASE" pointing
to the reaction ID, "NAME" pointing to an array of reaction names,
"EQUATION" pointing to the reaction stoichiometry, "ENZYME" pointing
to an array of reaction EC numbers, "PATHWAY" pointing to an array of
the metabolic pathways the reaction is involved in, "REVERSIBILITY"
pointing to the predicted reversibility for the reaction, "DELTAG"
pointing to the predicted gibbs free energy change of the reaction,
"DELTAGERR" point to the uncertainty in the predicted free energy change,
and "KEGGID" pointing to the ID of the reaction in the KEGG database.

In addition users can specify a subset of fields they want returned, 
as well as a subset of fields from the model data, using a hash with key 
"fields" and a hash with key "model_fields".  If no fields are specified,
all fields are returned.

Example:

    my $configHashRef = { "id" => ["rxn00001","rxn00002"...],
                          "model" => ["iJR904","Seed83333.1"]
                        };
    my $resultHashRef = $FBAmodel->get_reaction_data($configHashRef);
    $resultHashRef == { "rxn00001" => { "DATABASE" => ["rxn00001"],
                                        "EQUATION" => ["A + B => C + D"],
                                        "Seed83333.1" => {"DIRECTIONALITY" => ["<="],
                                        "COMPARTMENT" => ["c"],
                                        "ASSOCIATED PEG" => ["peg.1+peg.2","peg.30"],
                                      },
                        "rxn00002" => ...,
                       }
 

=cut
sub get_reaction_data {
	my ($self, $args) = @_;
	$args = $self->process_arguments($args);
	#Getting the FIGMODELTable with all reactions
    my $FullTable = $self->figmodel()->database()->get_table("REACTIONS");
	#Checking that the reaction table is defined
	if (!defined($FullTable)) {
		return undef;
	}
	#List of IDs to be returned will be stored here
	my $ids;
	#First checking that the "id" key exists
	if (!defined($args->{id}) || $args->{id}->[0] eq "ALL") {
		for (my $i=0; $i < $FullTable->size(); $i++) {
			push(@{$ids},$FullTable->get_row($i)->{DATABASE}->[0]);
		}
	} else {
		#Checking if the hash contains a single ID instead of a reference to an array of IDs
		if (ref($args->{id}) ne "ARRAY") {
			push(@{$ids},$args->{id});
		} else {
			push(@{$ids},@{$args->{id}});
		}
	}
	#Collecting reaction data for ID list
	my $output;
	for (my $i=0; $i < @{$ids}; $i++) {
		my $row;
		if ($ids->[$i] =~ m/rxn\d\d\d\d\d/) {
			$row = $FullTable->get_row_by_key($ids->[$i],"DATABASE");
		} elsif ($ids->[$i] =~ m/bio\d\d\d\d\d/) {
			my $obj = $self->figmodel()->database()->get_object("bof",{id=>$ids->[$i]});
			if (defined($obj)) {
				$row = {DATABASE=>[$ids->[$i]],NAME=>[$obj->name()],EQUATION=>[$obj->equation()],CODE=>[$obj->equation()],"MAIN EQUATION"=>[$obj->equation()],REVERSIBILITY=>["=>"]};
			}
		}
		if (defined($row)) {
			# kegg map ids look like octal numbers in Java because they start with
		    # a zero; fix this by telling YAML they are Strings.
		    if (exists $row->{"KEGG MAPS"}) {
				my @yaml_kegg_maps = map {"map$_"} @{$row->{"KEGG MAPS"}};
				$row->{"KEGG MAPS"} = \@yaml_kegg_maps;
		    }
		    my $return_row = {};
		    # allow the user to request specific fields
		    if (exists $args->{fields}) {
				map { $return_row->{$_} = $row->{$_} } @{$args->{fields}};
		    }
		    else {
				$return_row = $row;
		    }
		    $output->{$ids->[$i]} = $return_row;
			if (defined($args->{model})) {
				for (my $j=0; $j < @{$args->{model}}; $j++) {
					my $model = $self->figmodel()->get_model($args->{model}->[$j]);
					if (defined($model)) {
						my $data = $model->get_reaction_data($ids->[$i]);
						if (defined($data)) {
						    my $return_data = {};
						    if (exists $args->{model_fields}) {
								map { $return_data->{$_} = $data->{$_} } @{$args->{model_fields}};
						    }
						    else {
								$return_data = $data;
						    }
						    $output->{$ids->[$i]}->{$model->id} = $return_data;
						}
					}
				}
			}
		}
	}
	return $output;
}

sub get_biomass_reaction_data {
    my ($self, $args) = @_;
    print STDERR "In get_biomass_reaction_data\n";
	$args = $self->process_arguments($args);
	my $output;
	if (defined($args->{model})) {
		for (my $j=0; $j < @{$args->{model}}; $j++) {
			my $model = $self->figmodel()->get_model($args->{model}->[$j]);
			print STDERR "Checking $model\n";
			if (defined($model)) {
				my $bm1 = $model->biomassReaction();
				print STDERR "Found $bm1\n";
				my $obj = $self->figmodel()->database()->get_object("bof",{id=>$bm1});
				if (defined($obj)) {
					$output->{$model->id} = {DATABASE=>[$bm1],NAME=>[$obj->name()],EQUATION=>[$obj->equation()],CODE=>[$obj->equation()],"MAIN EQUATION"=>[$obj->equation()],REVERSIBILITY=>["=>"]};
				}
			}
		}
	}
    return $output;
}

=head3 get_compound_id_list

Definition:

	{ string::model id => [string::compound ids] } = FBAMODEL->get_compound_id_list({"id" => [string::model id]});

Description:

Takes as input a hash with the key "id" pointing to a list of model IDs.
If no ids are input or if the id "ALL" is submitted, this function will
return a list of all compound IDs in the database.

Returns a hash with the input IDs as keys pointing to
arrays of the compound IDs in the models.

Example:
    
    my $configHashRef = { "id" => ["Seed83333.1", "iJR904"] };
    my $retValHashRef = $FBAModel->get_compound_id_list($configHashRef);
    
    $retValHashRef == { "iJR904" => ["cpd00001", "cpd00002", ...],
                        "Seed83333.1" => ["cpd00003", "cpd00007"],
                      }

=cut
sub get_compound_id_list {
	my ($self, $args) = @_;
	$args = $self->process_arguments($args);
	#List of IDs to be returned will be stored here
	my $ids;
	#First checking that the "id" key exists
	if (!defined($args->{id})) {
		$ids = ["ALL"];
	} else {
		#Checking if the hash contains a single ID instead of a reference to an array of IDs
		if (ref($args->{id}) ne "ARRAY") {
			push(@{$ids},$args->{id});
		} else {
			push(@{$ids},@{$args->{id}});
		}
	}
	#If IDs is ["ALL"], we return an array of all reaction objects
	my $output;
	for (my $i=0; $i < @{$ids}; $i++) {
		if ($ids->[$i] eq "ALL") {
			#Getting the FIGMODELTable with all reactions
			my $tbl = $self->figmodel()->database()->GetDBTable("COMPOUNDS");
			if (defined($tbl)) {
				for (my $j=0; $j < $tbl->size(); $j++) {
					push(@{$output->{$ids->[$i]}},$tbl->get_row($j)->{DATABASE}->[0]);
				}
			}
		} elsif (defined($self->figmodel()->get_model($ids->[$i]))) {
			my $tbl = $self->figmodel()->get_model($ids->[$i])->compound_table();
			if (defined($tbl)) {
				for (my $j=0; $j < $tbl->size(); $j++) {
					push(@{$output->{$ids->[$i]}},$tbl->get_row($j)->{DATABASE}->[0]);
				}
			}
		}
	}
	#Returning the output
	return $output;
}

=head3 get_compound_data

Definition:

	{ string::compound ids => { string::keys => [ string::data ],
                              }
    } = FBAMODEL->get_compound_data( { "id" => [string::compound ids],
                                       "model" => [string::model ids],
				       "fields" => [string::fields]
                                   } );

Description:

Takes as input a hash with the key "id" pointing to a list of
compound IDs and (optionally) the key "model" pointing to a
list of model ids.

Returns a hash with the input IDs as keys pointing a hash with the
compound data. The keys in the compound data hash are "DATABASE" pointing
to the ID of the compound in the database, "NAME" pointing to an array of
names for the compound, "FORMULA" pointing to the molecular formula of
the compound at pH7, "CHARGE" pointing to the charge of the compound at
pH7, "STRINGCODE" pointing to a unique string that encodes the compound
structure, and "KEGGID" pointing to an array of KEGG ID for the compound.

In addition users can specify a subset of fields they want returned,
using a hash with key "fields".  If no fields are specified, all fields 
are returned.

Example:

    my $configHashRef = { "id" => ["rxn00001", "rxn00002", ...],
                          "model" => ["iJR904", "Seeed83333.1", ...]
                        };
    my $retValHashRef = $FBAModel->get_compound_data($configHashRef);
    
    $retValHashRef == { "rxn00001" => { "DATABASE" => ["rxn00001"],
                                        "EQUATION" => ["A + B => C + D"],
                                        "Seed83333.1" => {
                                            "DIRECTIONALITY" => ["<="],
                                            "COMPARTMENT" => ["c"],
                                            "ASSOCIATED PEG" => ["peg.1+peg.2","peg.30"],
                                        }
                                      }
                      }

=cut
sub get_compound_data {
	my ($self, $args) = @_;
	$args = $self->process_arguments($args);
	#Getting the FIGMODELTable with all compounds
    my $FullTable = $self->figmodel()->database()->GetDBTable("COMPOUNDS");
	#Checking that the compound table is defined
	if (!defined($FullTable)) {
		return undef;
	}
	#List of IDs to be returned will be stored here
	my $ids;
	#First checking that the "id" key exists
	if (!defined($args->{id}) || $args->{id}->[0] eq "ALL") {
		for (my $i=0; $i < $FullTable->size(); $i++) {
			push(@{$ids},$FullTable->get_row($i)->{DATABASE}->[0]);
		}
	} else {
		#Checking if the hash contains a single ID instead of a reference to an array of IDs
		if (ref($args->{id}) ne "ARRAY") {
			push(@{$ids},$args->{id});
		} else {
			push(@{$ids},@{$args->{id}});
		}
	}
	#Collecting compound data for ID list
	my $output;
	for (my $i=0; $i < @{$ids}; $i++) {
		my $row = $FullTable->get_row_by_key($ids->[$i],"DATABASE");
		if (defined($row)) {
			my $tempData;
			if (exists $args->{fields}) {
				map { $tempData->{$_} = $row->{$_} } @{$args->{fields}};
			} else {
				$tempData = $row;
			}
			$output->{$ids->[$i]} = $tempData;
			if (defined($args->{model})) {
				for (my $j=0; $j < @{$args->{model}}; $j++) {
					my $model = $self->figmodel()->get_model($args->{model}->[$j]);
					if (defined($model)) {
						my $data = $model->get_compound_data($ids->[$i]);
						if (defined($data)) {
							$output->{$ids->[$i]}->{$args->{model}->[$j]} = $data;
						}
						my $return_data = {};
						if (exists $args->{fields}) {
							map { $return_data->{$_} = $data->{$_} } @{$args->{fields}};
						} else {
							$return_data = $data;
						}
						$output->{$ids->[$i]}->{$model->id} = $return_data;
					}
				}
			}
		}
	}
	return $output;
}

=head3 get_media_id_list

Definition:
	[string::media ids] = FBAMODEL->get_media_id_list();

Description:

	Takes no input. Returns an array reference of the IDs for all media
	formulations stored in the SEED biochemistry database.	These are
	the only media formulations on which flux balance analysis may
	be performed.

Example:

    my $media = $FBAModel->get_media_id_list();
    @$media == [ "ArgonneLBMedia", "Carbon-D-Glucose", ...];

=cut
sub get_media_id_list {
	my ($self, $args) = @_;
	$args = $self->process_arguments($args);
	my $output;
	my $FullTable = $self->figmodel()->database()->GetDBTable("MEDIA");
	if (!defined($FullTable)) {
		return undef;
	}
	for (my $i=0; $i < $FullTable->size(); $i++) {
		push(@{$output},$FullTable->get_row($i)->{NAME}->[0]);
	}
	return $output;
}

=head3 get_media_data

Definition:

	{ string::media ids => { string::key => [string::data] } } = FBAMODEL->get_media_data({"id" => [string::media ids] });

Description:

	Takes as input a hash with the key "id" pointing to an array of
	media ids. Returns a hash with the media ids pointing to a hash
	containing the media data.

Example:

    my $media = ["Carbon-D-Glucose", "ArgonneLBMedia"];
    my $retValHashRef = $FBAModel->get_media_data($media);
    $retValHashRef == { "Carbon-D-Glucose" => { "Compounds" => [ "cpd00001", "cpd00002", ...],
                                                "Compartments" => ["e", "e", ...],
                                                "Max"       => [ 100, 100, ...],
                                                "Min"       => [ -100, -100, ...],
                                              },
                         "ArgonneLBMedia" => { ... },
                       }  

=cut
sub get_media_data {
	my ($self, $args) = @_;
	$args = $self->process_arguments($args);
	#TODO
	#Getting the FIGMODELTable with all compounds
    my $FullTable = $self->figmodel()->database()->GetDBTable("MEDIA");
	#Checking that the compound table is defined
	if (!defined($FullTable)) {
		return undef;
	}
	#List of IDs to be returned will be stored here
	my $ids;
	#First checking that the "id" key exists
	if (!defined($args->{id}) || $args->{id}->[0] eq "ALL") {
		for (my $i=0; $i < $FullTable->size(); $i++) {
			push(@{$ids},$FullTable->get_row($i)->{NAME}->[0]);
		}
	} else {
		#Checking if the hash contains a single ID instead of a reference to an array of IDs
		if (ref($args->{id}) ne "ARRAY") {
			push(@{$ids},$args->{id});
		} else {
			push(@{$ids},@{$args->{id}});
		}
	}
	#Collecting reaction data for ID list
	my $output;
	for (my $i=0; $i < @{$ids}; $i++) {
		my $row = $FullTable->get_row_by_key($ids->[$i],"NAME");
		if (defined($row)) {
			$output->{$ids->[$i]} = $row;
		}
	}
	return $output;
}

=head3 get_model_id_list

Definition:

	[string::model ids] = FBAMODEL->get_model_id_list( {"user" => string, "password" => string} );

Description:
	Takes as input a hash with the key "user" pointing to the
	username of a RAST account and the key "password" pointing
	to the password from the same RAST account. 

    Returns an array containing the names of all models owned by the user.
    If no input is provided, the function returns an array containing
    the names of all public models.

=cut
sub get_model_id_list {
	my ($self, $args) = @_;
	$args = $self->process_arguments($args);
	my $output;
	my $models = $self->figmodel()->get_models({users => "all"});
	if (defined($models)) {
		for (my $i=0; $i < @{$models}; $i++) {
			push(@{$output},$models->[$i]->id());
		}
	}
	$models = $self->figmodel()->get_models();
	if (defined($models)) {
		for (my $i=0; $i < @{$models}; $i++) {
			push(@{$output},$models->[$i]->id());
		}
	}
	return $output;
}

=head3 get_model_data

Definition:

	{ string::model ids => { string::key => [string::data] } } 
        = FBAMODEL->get_model_data( { "id"   => [string::model ids],
                                      "user" => string,
                                      "password" => string,
                                  } );

Description:

Takes as input a hash with the key "id" pointing to an array of model
ids and the optional key "user" pointing to a RAST account along with
the key "password" pointing to the password for the RAST account,

Returns a hash with the model ids as keys pointing to a hash containing
the model data. User ID and password must be provided to access data
for private models.

Example:

    my $inputHashRef = { "id" => ["Seed83333.1", "iJR904"],
                         "user" => "Alice",
                         "password" => "eval",
                       };
    my $retValHashRef = $FBAModel->get_model_data($inputHashRef);
    
    $retValHashRef == { "Seed83333.1" => { "Genome" => "83333.1",
                                           "Name" => "E. coli",
                                           "Source" => "SEED"...},
                        ...}

=cut

sub get_model_data {
	my ($self, $args) = @_;
	$args = $self->process_arguments($args);
	#Checking that at least one id was input
	if (!defined($args->{id})) {
		return undef;
	}
	#Getting the id list
	my $ids;
	if (ref($args->{id}) ne "ARRAY") {
		$ids = [$args->{id}];
	} else {
		$ids = $args->{id};
	}
	#Cycling through IDs and storing model data
	my $output;
	for (my $i=0; $i < @{$ids}; $i++) {
		#Getting the model object
		my $modelobj = $self->figmodel()->get_model($ids->[$i]);
		if (defined($modelobj)) {
			$output->{$ids->[$i]} = { "Genome" => "id:".$modelobj->genome(), "Source" => $modelobj->source(), "Name" => $modelobj->name() };
		}
	}
	return $output;
}

=head3 classify_model_entities

Definition:

    [ { id      => string,
        media   => string,
        reactionKO  => string,
        geneKO      => string,
        entities    => [ string::reaction and transportable compounds ids],
        classes => [string::classes],
        "min flux" => [float::minimum flux],
        "max flux" => [float::maximum flux]
    } ] = FBAMODEL->classify_model_entities(
        { "parameters" => [ { id         => string,
                              media      => string,
                              reactionKO => [string::reaction ids],
                              geneKO     => [string::gene ids],
                              archiveResults => [0|1],
                          } ],
           "user" => string,
           "password" => string
    });

Description:

Takes as input a hash with the key "parameters" pointing to
an array of hashes with analysis parameters, the key "user"
pointing to the username associated with a RAST account, and
the key "password" pointing to the password associated with the
RAST account.

The analysis parameters are stored in hashes where the keys are the
parameter names pointing to the parameter values.  Only one parameter
is required: "id" pointing to the name of the model to be analyzed.
Optional parameters include "media" pointing to the name of the media
for the simulation (default is complete media), "reactionKO" pointing
to a ";" delimited list of reactions to be knocked out (default is no
reactions knocked out), and "geneKO" pointing to a ";" delimited list
of the genes to be knocked (default is no genes knocked out).

Returns an array of the input analysis parameters with the additional
key values "entities" (which points to an array of the reactions and
transportable compounds in the model), "classes" (which points to an
array of the class each reaction/compound was assigned to), "max flux"
(which points to an array of the maximum possible flux through each
reaction/compound), and "min flux" (which points to an array of the
minimum possible flux through each reaction/compound) 

If the	"entities" key is undefined in the output, this means
the specified model did not grow in the specified conditions.

Example:

    my $ConfigHashRef = {"model" => [{"id" => "Seed83333.1",
                                      "media" => "Carbon-D-Glucose",
                                      "reactionKO" => "rxn00001;rxn00002",
                                      "geneKO" => "peg.1,peg.2"}],
                         "user" => "reviewer",
                         "password" => "eval"};
    my $retValArrayRef = $FBAModel->classify_model_entities($ConfigHashRef);
    $retValArrayRef == [{ "id" => "Seed83333.1",
                          "media" => "Carbon-D-Glucose",
                          "reactionKO" => "rxn00001;rxn00002",
                          "geneKO" => "peg.1,peg.2",
                          "reactions" => ["rxn00001","rxn00002"....],
                          "classes" => ["essential =>","essential<=",...],
                          "max flux" => [100,-10...],
                          "min flux" => [10,-100...],
                       }]

=cut
sub classify_model_entities {
	my ($self, $args) = @_;
	$args = $self->process_arguments($args);
	#Checking that at least one parameter was input
	if (!defined($args->{parameters})) {
		return undef;
	}
	#Getting parameter array
	my $parameters;
	if (ref($args->{parameters}) ne "ARRAY") {
		$parameters = [$args->{parameters}];
	} else {
		$parameters = $args->{parameters};
	}
	#Cycling through parameters and running fba studies
	my $output;
	for (my $i=0; $i < @{$parameters}; $i++) {
		if (defined($parameters->[$i]->{id})) {
			if (!defined($parameters->[$i]->{media})) {
				$parameters->[$i]->{media} = "Complete";
			}
			my $modelobj = $self->figmodel()->get_model($parameters->[$i]->{id});
			if (defined($modelobj)) {
				$ENV{'ILOG_LICENSE_FILE'} = '/home/chenry/Software/ilm/access.ilm';
				$ENV{'ARGONNEDB'} = '/vol/model-dev/MODEL_DEV_DB/ReactionDB/';
				my $archiveResults = 0;
				if (defined($parameters->[$i]->{archiveResults}) && !defined($parameters->[$i]->{reactionKO}) && !defined($parameters->[$i]->{geneKO})) {
					$archiveResults = 1;
				}
				my ($rxnclasstable,$cpdclasstable) = $modelobj->classify_model_reactions($parameters->[$i]->{media},$archiveResults,$parameters->[$i]->{reactionKO},$parameters->[$i]->{geneKO});
				if (defined($rxnclasstable)) {
					for (my $j=0; $j < $rxnclasstable->size();$j++) {
						my $row = $rxnclasstable->get_row($j);
						push(@{$parameters->[$i]->{entities}},$row->{REACTION}->[0]);
						push(@{$parameters->[$i]->{classes}},$row->{CLASS}->[0]);
						push(@{$parameters->[$i]->{"min flux"}},$row->{MIN}->[0]);
						push(@{$parameters->[$i]->{"max flux"}},$row->{MAX}->[0]);
					}
				}
				if (defined($cpdclasstable)) {
					for (my $j=0; $j < $cpdclasstable->size();$j++) {
						my $row = $cpdclasstable->get_row($j);
						if ($row->{CLASS}->[0] ne "Unknown") {
							push(@{$parameters->[$i]->{entities}},$row->{COMPOUND}->[0]);
							push(@{$parameters->[$i]->{classes}},$row->{CLASS}->[0]);
							push(@{$parameters->[$i]->{"min flux"}},$row->{MIN}->[0]);
							push(@{$parameters->[$i]->{"max flux"}},$row->{MAX}->[0]);
						}
					}
				}
				push(@{$output},$parameters->[$i]);
			}
		}
	}
	return $output;
}

=head3 simulate_all_single_gene_knockout

=item Definition:

	[ { id          => string,
        media       => string,
        reactionKO  => string,
        geneKO      => string,
        "essential genes"   => [string::peg ids],
        "nonessential genes"=> [string::peg ids],
      } ] 
    = MODELserv->simulate_all_single_gene_knockout( { 
        "parameters" => [ { id     => string,
                            media  => string, 
                            reactionKO => string,
                            geneKO => string,
                        } ],
        "user" => string,
        "password" => string
    });

=item Description:

Takes as input a hash with the key "parameters" pointing to
an array of hashes with analysis parameters, the key "user"
pointing to the username associated with a RAST account, and
the key "password" pointing to the password associated with the
RAST account. 

The analysis parameters is a hash reference containing the following required and optional key/value pairs:

"id" pointing to the string ID of the model to be analyzed. (Required)

"media" pointing to the name of the media for the simulation (default is complete media).

"reactionKO" pointing to a ";" delimited list of reactions to be knocked out (default is no reactions knocked out).

"geneKO" pointing to a ";" delimited list of the genes to be knocked (default is no genes knocked out).

Returns an array of the input analysis parameters with the additional key
values are "essential genes" and "non essential genes" If the  "essential
genes" and "nonessential genes" keys are undefined in the output, this
means the specified model did not grow in the specified conditions.

=item Example:

    my $configHashRef = { "parameters" => [{ "id" => "Seed83333.1",
                                             "media" => "Carbon-D-Glucose",
                                             "reactionKO" => "rxn00001;rxn00002",
                                             "geneKO" => "peg.1,pge.2"}],
                          "user"       => "bob",
                          "password"   => "password123",
                        };
    my $retValArrayRef = $FBAModel->simulate_all_single_gene_knockout($configHashRef);

    $retValArrayRef == [ {"id" => "Seed83333.1",
                          "media" => "Carbon-D-Glucose",
                          "reactionKO" => "rxn00001;rxn00002",
                          "geneKO" => "peg.1,peg.2",
                          "essential genes" => ["peg.10","peg.45"...],
                          "nonessential genes" => ["peg.1", "peg.2"...],
                       }]

=cut
sub simulate_all_single_gene_knockout {
	my ($self, $args) = @_;
	$args = $self->process_arguments($args);
	#Checking that at least one parameter was input
	if (!defined($args->{parameters})) {
		return undef;
	}
	#Getting parameter array
	my $parameters;
	if (ref($args->{parameters}) ne "ARRAY") {
		$parameters = [$args->{parameters}];
	} else {
		$parameters = $args->{parameters};
	}
	#Cycling through parameters and running fba studies
	my $output;
	for (my $i=0; $i < @{$parameters}; $i++) {
		if (defined($parameters->[$i]->{id})) {
			if (!defined($parameters->[$i]->{media})) {
				$parameters->[$i]->{media} = "Complete";
			}
			my $modelobj = $self->figmodel()->get_model($parameters->[$i]->{id});
			if (defined($modelobj)) {
				my $reactionKO;
				my $geneKO;
				if (defined($parameters->[$i]->{reactionKO})) {
					$reactionKO = [$parameters->[$i]->{reactionKO}];
				}
				if (defined($parameters->[$i]->{geneKO})) {
					$geneKO = [$parameters->[$i]->{geneKO}];
				}
				my $result = $self->figmodel()->RunFBASimulation("FBAMODEL:simulate_all_single_gene_knockout:".$modelobj->id(),"SINGLEKO",$reactionKO,$geneKO,[$modelobj->id()],[$parameters->[$i]->{media}]);
				if (defined($result) && defined($result->get_row(0)->{"ESSENTIALGENES"})) {
					$parameters->[$i]->{"essential genes"} = $result->get_row(0)->{"ESSENTIALGENES"};
					$parameters->[$i]->{"nonessential genes"} = $result->get_row(0)->{"NONESSENTIALGENES"};
				}
				push(@{$output},$parameters->[$i]);
			}
		}
	}
	return $output;
}

=head3 simulate_model_growth
    
=item Definition:

    [ { id          =>  string,
        media       =>  string,
        reactionKO  =>  string,
        geneKO      =>  string,
        growth      =>  double,
        entities    =>  [ string::reaction or transportable compounds ids],
        fluxes      =>  [double]
    } ] 
    = FBAMODEL->simulate_model_growth( {"parameters" => [ { id      => string,
                                                            media   => string,
                                                            reactionKO => string,
                                                            geneKO  => string,
                                                        } ],
                                        "user"       => string,
                                        "password"   => string,
                                     } );

=item Description:

Takes as input a hash with: the key "parameters" pointing to an array of
hashes with L<analysis parameters|/"analysis parameters">, the key "user" pointing to the username
associated with a RAST account, and the key "password" pointing to the
password associated with the RAST account.

=over 

=item analysis parameters 

This is a hash reference with the following keys:

id : The string ID of the model to be analyzed. Required.

media : The name of the media for the simulation (default is complete media).

reactionKO : A ";" delimited list of reactions to be knocked out (default is no reactions knocked out).

geneKO : A ";" delimited list of the genes to be knocked (default is no genes knocked out).

=back

Returns an array of the input analysis parameters with the additional
key values "growth" (which points to a float with the optimal growth
of the model in the specified conditions), "entities" (which points to
the reactions and transportable compounds in the model), and "fluxes"
(which points to the flux through each reaction).

=item Example
    
    my $configHash = {"parameters" => [ { "id"      => "Seed83333.1",  
                                          "media"   => "Carbon-D-Glucose",
                                          "reactionKO" => "rxn00001;rxn00002",
                                          "geneKO"  => "peg.1,peg.2",
                                      } ],
                      "user"       => "alice",
                      "password"   => "password123"};
    my $arrayRefRetVal = $FBAModel->simulate_model_growth($configHash);

=cut

sub simulate_model_growth {
	my ($self, $args) = @_;
	$args = $self->process_arguments($args);
	#Checking that at least one parameter was input
	if (!defined($args->{parameters})) {
		return undef;
	}
	#Getting parameter array
	my $parameters;
	if (ref($args->{parameters}) ne "ARRAY") {
		$parameters = [$args->{parameters}];
	} else {
		$parameters = $args->{parameters};
	}
	#Cycling through parameters and running fba studies
	my $output;
	for (my $i=0; $i < @{$parameters}; $i++) {
		if (defined($parameters->[$i]->{id})) {
			if (!defined($parameters->[$i]->{media})) {
				$parameters->[$i]->{media} = "Complete";
			}
			my $modelobj = $self->figmodel()->get_model($parameters->[$i]->{id});
			if (defined($modelobj)) {
				my $reactionKO;
				my $geneKO;
				if (defined($parameters->[$i]->{reactionKO})) {
					$reactionKO = [$parameters->[$i]->{reactionKO}];
				}
				if (defined($parameters->[$i]->{geneKO})) {
					$geneKO = [$parameters->[$i]->{geneKO}];
				}
				my $result = $self->figmodel()->RunFBASimulation("FBAMODEL:simulate_model_growth:".$modelobj->id(),"GROWTH",$reactionKO,$geneKO,[$modelobj->id()],[$parameters->[$i]->{media}]);
				if (defined($result) && defined($result->get_row(0)->{"FLUXES"})) {
					$parameters->[$i]->{"growth"} = $result->get_row(0)->{"OBJECTIVE"}->[0];
					if (defined($result->get_row(0)->{"TYPES"}) && defined($result->get_row(0)->{"ENTITIES"}) && defined($result->get_row(0)->{"FLUXES"})) {
						my ($types,$entities,$fluxes);
						push(@{$types},split(/,/,$result->get_row(0)->{"TYPES"}->[0]));
						push(@{$entities},split(/,/,$result->get_row(0)->{"ENTITIES"}->[0]));
						push(@{$fluxes},split(/,/,$result->get_row(0)->{"FLUXES"}->[0]));
						for (my $j=0; $j < @{$types}; $j++) {
							if ($types->[$j] eq "FLUX" || $types->[$j] eq "DRAIN_FLUX") {
								push(@{$parameters->[$i]->{"entities"}},$entities->[$j]);
								push(@{$parameters->[$i]->{"fluxes"}},$fluxes->[$j]);
							}
						}
					}
				}
				push(@{$output},$parameters->[$i]);
			}
		}
	}
	return $output;
}

=head3 get_model_reaction_classification_table

=item Definition: 

    { string::model IDs => [ reaction => [string::reaction ID],
                             media => [string::media IDs],
                             class => [string::essential|active|inactive|dead],
                             class_directionality => [string::=>|<=|<=>],
                             min_flux => [double],
                             max_flux => [double]
                           ]
    } = FBAMODEL->get_model_reaction_classification_table( { model    => [string::model ids],
                                                           user     => string::username,
                                                           password => string::password 
                                                       } );


=item Description:

    my $returnArrayRef = $FBAModel->get_model_reaction_classification_table($configHash);

Where C<$configHash> is a hash reference with the following syntax:

    my $configHash = {    "model"    => [ "Seed83333.1", "iJR904.1" ],
                          "user"     => "bob",
                          "password" => "password123",
                    });

C<$returnArrayRef> is a hash reference with model ID strings as keys. The
value of each model ID is an array reference with the following syntax:

    "reaction" => an array reference with one element, the string of the reaction id.
    "media"    => an array reference containing media ID strings.
    "class"    => an array reference of the class of the reaction, ordered by the media condition column.
    "class_directionality" => an array reference of the class of the reaction, ordered by the media condition column.
    "min_flux" => minimum flux through each reaction in each media condition in the media colum.
    "max_flux" => maximum flux through each reaction in each media condition in the media column. 

This function naturally pairs with the L<C<classify_model_entities()>|/"classify_model_entities"> 
function which runs new classification analysis on additional media
conditions and adds the output to the archived table of classifications
if the C<$archiveResults> tag is set to. The function accepts as input
a hash with the key "model" pointing to an array of model IDs for
which classification tables should be returned.  The function returns
a hash with the model IDs acting as the keys pointing to a table of
classification data.

=cut

sub get_model_reaction_classification_table {
	my ($self, $args) = @_;
	$args = $self->process_arguments($args);
	#Checking that some model ID has been submitted
	if (!defined($args->{model})) {
		return undef;
	}
	
	#First logging in the user if a username is provided
	$self->figmodel()->authenticate_user($args->{username},$args->{password});
	
	#Now retreiving the specified models from the database
	my $output;
	for (my $i=0; $i < @{$args->{model}}; $i++) {
		my $model = $self->figmodel()->get_model($args->{model}->[$i]);
		if (defined($model)) {
			my $tbl = $model->reaction_class_table();
			for (my $j=0; $j < $tbl->size(); $j++) {
				my $row = $tbl->get_row($j);
				my $class;
				my $classdir;
				for (my $k=0; $k < @{$row->{CLASS}}; $k++) {
					if ($row->{CLASS}->[$k] eq "Positive") {
						push(@{$class},"Essential");
						push(@{$classdir},"=>");
					} elsif ($row->{CLASS}->[$k] eq "Dead") {
						push(@{$class},"Disconnected");
						push(@{$classdir},"NA");
					} elsif ($row->{CLASS}->[$k] eq "Negative") {
						push(@{$class},"Essential");
						push(@{$classdir},"<=");
					} elsif ($row->{CLASS}->[$k] eq "Positive variable") {
						push(@{$class},"Active");
						push(@{$classdir},"=>");
					} elsif ($row->{CLASS}->[$k] eq "Negative variable") {
						push(@{$class},"Active");
						push(@{$classdir},"<=");
					} elsif ($row->{CLASS}->[$k] eq "Variable") {
						push(@{$class},"Active");
						push(@{$classdir},"<=>");
					} elsif ($row->{CLASS}->[$k] eq "Blocked") {
						push(@{$class},"Inactive");
						push(@{$classdir},"NA");
					}
				}
				push(@{$output->{$args->{model}->[$i]}},{reaction => [$row->{REACTION}->[0]],media => $row->{MEDIA}, class => $class, class_directionality => $classdir, min_flux => $row->{MIN}, max_flux => $row->{MAX}});
			}
		}
	}
	
	#Returning the output
	return $output;
}

sub get_role_to_complex {
    my ($self,$args) = @_;
    $args = $self->process_arguments($args);
    my $roles = $self->figmodel()->database()->get_objects("ROLE");
    my $roleHash = {};
    for(my $i=0; $i<@$roles; $i++) {
        next unless(defined($roles->[$i]->id()) && defined($roles->[$i]->name())); 
        $roleHash->{$roles->[$i]->id()} = $roles->[$i]->name();
    }
    my $complexTable = [];    
    my $cpxs = $self->figmodel()->database()->get_objects("cpxrole");
    for(my $i=0; $i<@$cpxs; $i++) {
        next unless(defined($cpxs->[$i]->COMPLEX()) && defined($cpxs->[$i]->ROLE()) &&
                    defined($cpxs->[$i]->type()) && defined($roleHash->{$cpxs->[$i]->ROLE()}));
        push(@$complexTable, { "Complex Id" => $cpxs->[$i]->COMPLEX(),
                               "Functional Role" => $roleHash->{$cpxs->[$i]->ROLE()},
                               "Complex Type"    => $cpxs->[$i]->type(),
                            }); 
    }
    return $complexTable; 
}

sub get_complex_to_reaction {
    my ($self,$args) = @_;
    $args = $self->process_arguments($args);
    my $objs = $self->figmodel()->database()->get_objects("rxncpx",{ 'master' => 1});
    my $complexToReactionTable = [];
    for(my $i=0; $i<@$objs; $i++) {
        next unless(defined($objs->[$i]->REACTION()) && defined($objs->[$i]->COMPLEX()));
        push(@$complexToReactionTable, { 'Complex Id' => $objs->[$i]->COMPLEX(),
                                         'Reaction Id'=> $objs->[$i]->REACTION() });
    }
    return $complexToReactionTable;
}

=head2 Methods that access data from the database

=head3 get_model_essentaility_data

=item Definition:

	$results = FBAMODEL->get_model_essentaility_data($arguments);
	
	$arguments = {"model" => [string]:model ids,
				  "user" => string:user login,
				  "password" => string:password}
	
	$results = {string:model ids => 
			    	{string:media ids => 
			    		{"essential" => [string]:gene ids}
			    	}
    			}
    
=item Description:
	
	Returns available gene essentiality predictions for the input set of models.

=cut

sub get_model_essentaility_data {
	my ($self,$args) = @_;
    $args = $self->process_arguments($args);
	my $results;
    if (!defined($args->{model})) {
    	for (my $i=0; $i < @{$args->{model}}; $i++) {
    		my $modelObj = $self->figmodel()->get_model($args->{model}->[$i]);
    		if (defined($modelObj)) {
    			my $dataTable = $modelObj->essentials_table();
    			if (defined($dataTable)) {
					for (my $j=0; $j < $dataTable->size(); $j++) { 
						my $row = $dataTable->get_row($j);
						if (defined($row->{"ESSENTIAL GENES"}->[0]) && defined($row->{MEDIA}->[0])) {
							push(@{$results->{$args->{model}->[$i]}->{$row->{MEDIA}->[0]}->{essential}},@{$row->{"ESSENTIAL GENES"}});
						}
					}
				}
    		}
    	}
    }
}

=head3 get_experimental_essentaility_data

=item Definition:

	$results = FBAMODEL->get_experimental_essentaility_data($arguments);
	
	$arguments = {"genome" => [string]:genome ids,
				  "user" => string:user login,
				  "password" => string:password}
	
	$results = {string:genome ids => 
			    	{string:media ids => 
			    		{"essential" => [string]:gene ids,
			    		 "nonessential" => [string]:gene ids}
			    	}
    			}
    
=item Description:
	
	Returns available gene essentiality data for the input set of genomes.

=cut

sub get_experimental_essentaility_data {
	my ($self,$args) = @_;
    $args = $self->process_arguments($args);
	my $results;
    if (!defined($args->{genome})) {
    	for (my $i=0; $i < @{$args->{genome}}; $i++) {
    		my $dataTable = $self->figmodel()->GetEssentialityData($args->{genome}->[$i]);
			if (defined($dataTable)) {
				for (my $j=0; $j < $dataTable->size(); $j++) { 
					my $row = $dataTable->get_row($j);
					if (defined($row->{Essentiality}->[0]) && defined($row->{Media}->[0])) {
						if ($row->{Essentiality}->[0] eq "essential" || $row->{Essentiality}->[0] eq "potential essential") {
							push(@{$results->{$args->{genome}->[$i]}->{$row->{Media}->[0]}->{essential}},$row->{Gene}->[0]);
						} elsif ($row->{Essentiality}->[0] eq "nonessential" || $row->{Essentiality}->[0] eq "potential nonessential") {
							push(@{$results->{$args->{genome}->[$i]}->{$row->{Media}->[0]}->{nonessential}},$row->{Gene}->[0]);
						}
					}
				}
			}
    	}
    }
    return $results;
}

=head2 Admin Control Methods

=head3 rename_functional_role

=item Definition:

    string:error message = FBAMODEL->rename_functional_role({originalRoleName => string, newRoleNames => [string], keepOriginal => 0/1, user => string, password => string});

=item Description:
	
	Changes the name of the input "originalRoleName" to one or more new names input as an array in "newRoleNames". If multiple names are input, all mappings involving the original functional role are replicated.
	If the input flage "keepOriginal" exists and is set to "1", then new roles are created with the new names while the orignal role is retained. 
	All mappings with the original role are retained but also copied with the new names.
	This is an administrative function with access limited to Model SEED administrators.

=cut

sub rename_functional_role {
    my ($self,$args) = @_;
    $args = $self->process_arguments($args);
    if ($self->figmodel()->admin() != 1) {
    	return "Cannot use this function without Model SEED administrator privelages";	
    }
    if (!defined($args->{originalRoleName})) {
    	return "No original role name provided";	
    }
    my $roleObj = $self->figmodel()->database()->get_object("role",{name => $args->{originalRoleName}});
    if (!defined($roleObj)) {
    	my $searchName = $self->figmodel()->convert_to_search_role($args->{originalRoleName});
    	$roleObj = $self->figmodel()->database()->get_object("role",{searchname => $searchName});
    }
    if (!defined($roleObj)) {
    	return "Specified original role was not found";	
    }
    my $additionalNames;
    
    if (defined($args->{newRoleNames}) && @{$args->{newRoleNames}} > 0) {
    	for (my $i=0; $i < @{$additionalNames}; $i++) {
    		#Checking that the new role doesn't already exist
    		my $newSearchName = $self->figmodel()->convert_to_search_role($additionalNames->[$i]);
    		if (!defined($self->figmodel()->database()->get_object("role",{searchname => $newSearchName}))) {
    			#Creating the new roles
    			my $newRoleID = $self->figmodel()->database()->check_out_new_id("role");
    			my $newRole = $self->figmodel()->database()->create_object("role",{id => $newRoleID,name => $additionalNames->[$i],searchname => $newSearchName});
    			#Replicating the mappings with the new role
    			$self->figmodel()->replicate_role_mappings($roleObj->id(),$newRoleID);
    		}
    	}
    }
    if (!defined($args->{keepOriginal}) || $args->{keepOriginal} == 0) {
    	$self->figmodel()->delete_role_and_mappings($roleObj->id());
    }
    return undef;
}

1;


MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3