= Practical 4 = In this practical you will familiarise yourselves with the constraint scanning method covered in the lectures this morning. Specifically, you will investigate the response of a rice GSM to changes in photon input. For reference, have a look at the [[http://www.plantphysiol.org/content/162/2/1060 | paper]]. Download and extract [[http://mudsharkstatic.brookes.ac.uk/Download/Models/RicePr4.zip | this file]]. After extraction you should have a directory containing a number of {{{ScrumPy}}} files ({{{.spy}}}) and a {{{Python}}} file ({{{.py}}}). The model files are ''modules'' of the rice GSM, and the {{{Python}}} file contains two dictionaries that you will need as constrains for the LP. 1. Load the model with the {{{ScrumPy.Model()}}} method as previously, using {{{Rice.spy}}} as the argument. 2. Import the file with the constraints dictionaries ({{{RiceConstr}}}). The dictionaries can be accessed using dot notation: {{{#!python >>> import RiceConstr >>> fixed = RiceConstr.fixed >>> bounds = RiceConstr.bounds }}} 3. Create an LP object with the rice GSM as argument (see previous LP exercise for details on how to do this). 4. Set the objective to minimisation of all fluxes. Since minimisation is the default direction, all you need to do is to use the {{{lp.SetObjective()}}} method with all reactions in the LP object as argument, which can be obtained as {{{lp.cnames.values()}}}. 5. Use the dictionary of bounds on transporter reactions as flux bounds ({{{lp.SetFluxBounds(...)}}}) and the dictionary of biomass fluxes as fixed constraints ({{{lp.SetFixedFlux(...)}}}). '''Note: You must set the constraints in this order otherwise the biomass constraint is overwritten by the flux bounds!''' 6. Try to solve the LP and make sure the number of reactions in the solution is non-zero. 7. You will scan the photon uptake reaction by fixing its flux to a set of value in a linear range, specifically 50 points evenly distributed from 0 to 10. To do this, first generate a list of these values (have a look at your solution to exercise '''(f)''' of the [[AccliPhot/WorkshopOne/prac1 | python practical]]). 8. Define a dictionary (this will be referred to as {{{collection}}} henceforth) where you will collect the LP solutions. 9. Write a {{{for}}} loop over the list of values generated above. Inside the loop, set the constrain on the photon uptake reaction ({{{chl_Photon_tx}}}) equal to the loop variable, solve the LP, and collect the solution in {{{collection}}} created above (you can use the loop variable as key). 10. You will now analyse the LP data. In order to collect the names of all reactions that appear in any of the solutions, create an empty dictionary and run a {{{for}}} loop to update it with the reaction names from the solutions generated previously, e.g.: {{{#!python >>> reacs = {} >>> for sol in collection: reacs.update(sol_collection[sol]) }}} 11. Import the module {{{DataSets}}} from {{{Data}}}. Create an instance of the {{{DataSet}}} class, give the keys of the reaction name dictionary just created to the argument with keyword {{{ItemNames}}}, as such: {{{#!python >>> ds = DataSets.DataSet(ItemNames=reacs.keys()) }}} The names provided will be column names in data set created. The {{{DataSet}}} class is a subclass of the {{{ScrumPy}}} {{{matrix}}} class, as are the stoichiometry matrices that you have looked at before, so much of the structure and properties of data sets will be familiar. 12. Update the data set with the LP solutions so that each row corresponds to a fixed photon flux. Conveniently, there is a {{{DataSet}}} method, called {{{UpdateFromDic(...)}}}, that updates the data set with a dictionary if the keys can be found in the column names of the data set and the values are numbers. Write a {{{for}}} loop over the {{{collection}}} dictionary and update the data set with each solution. 13. Since we are interested in reactions that change flux as a response to changes in photon flux, we need to identify these reaction in the data set. We will do this by looking at the aboslute difference between the smallest and largest flux through each reaction in the set. Use a {{{for}}} loop over the column names of the data set (if the data set is names{{{ds}}} this is {{{ds.cnames}}}). For each column name get the associated list of values (use the method {{{ds.GetCol(c)}}} with {{{c}}} being the name of column, i.e. if you are in a loop, the loop variable); calculate absolute of the difference between the maximum and minimum flux value in the list (we can use the built-in functions {{{abs()}}}, {{{max()}}}, and {{{min()}}} for this), if this difference is above a fixed threshold the reaction (i.e. the loop variable) will be stored. Here is the code: {{{#!python >>> changing = [] # list to store reactions with changing flux >>> lim = 1e-7 # flux threshold >>> for c in ds.cnames: col = ds.GetCol(c) if abs(max(col) - min(col)) > lim: changing.append(c) }}} 14. Use the plotting methods of {{{DataSet}}} to look at the flux responses of the changing reactions. Set the x-axis as the photon flux with the method {{{.SetPlotX(...)}}}, where the argument is a column name in the data set, here the photon transporter ({{{chl_Photon_tx}}}) (note that {{{.SetPlotX(...)}}} only initialises the plot internally, you will not see the plot until data is added). Add columns to the plot using the method {{{.AddToPlot(...)}}}, where the argument is either a string (name of a column), or a list (of column names). Similarly, you can remove column from the plot using the methods {{{.RemoveFromPlot(...)}}} and {{{.RemoveAllFromPlot()}}}.