def biomass(self, biomass_file, readquiet):
		#read and define biomass equation...
		if not readquiet:
			print 'biomass from', biomass_file
		biomass_equation = [[], []]
		file = open(biomass_file)
		while True:
			line = file.readline()
			if line == '': break
			line = line.rstrip()
			if line == '': continue
			if line[0] == '#': continue
			col = line.split('\t')
			[rawmet, coef, side] = col[0:3]
			
			#convert metabolites from forms like 'leu-L[c]' to 'M_leu_DASH_L_c'...
			met = eq_current.convert_metabolite_ext2int(rawmet)
			
			if 'reactant' in side:
				biomass_equation[0].append((met, coef))
				self.NOTSOURCES.append(met)
			elif 'product' in side:
				biomass_equation[1].append((met, coef))
				self.NOTSOURCES.append(met)
			else:
				print 'Warning: biomass component skipped because cannot be idenified as reactant or product-->', line
		#add biomass equation to model, and set this as the objective...
		cb.add_reaction(self, 'R_biomass_target', 'BiomassRxn', False, {'SUBSYSTEM: BiomassObjective':1, 'EC: .':1}, biomass_equation)
		cb.set_objective(self, 'Maximize', 'R_biomass_target')
		#cb.set_constraint(self, 'R_biomass_target', '0.0', str(float(self.VMAX)) )
		if not readquiet:
			print eq_current.makestring(biomass_equation, False)
			print
	def deletions (self, level):
		"Delete all genes, proteins, or reactions, one at a time."
		cb.solve(self, verbose=False)
		fullstatus, fullobjectivevalue = self.STATUS, self.OBJECTIVE_VALUE
		#item is a gene, protein, or reaction; level is self.GENES, self.PROTS, or self.REACTS
		lethals = {}
		for item in level:
			#delete item
			level[item] = 0
			#calculate consequences of deleted item according to boolean rules (i.e., which reactions are eliminated?)
			deletedrxns = cb.calc(self)
			#now constrain each reaction that is deleted by the change to have zero flux, attempt fba
			for r in deletedrxns:
				name, rev, notes, equation = self.REACTIONS[r]
				if rev:
					lbound = '-' + self.VMAX
				else:
					lbound = '0'
				default_lbound, default_ubound = self.CONSTRAINTS.get(r, (lbound, self.VMAX))
				cb.set_constraint(self, r, 0, 0)
				cb.solve(self, verbose=False)
				#if status != OPTIMAL or objective value is < 25% of 'wild type', print item, reaction, and results
				if (not self.STATUS == 'OPTIMAL') or (float(self.OBJECTIVE_VALUE) < 0.25 * float(fullobjectivevalue)):
					reactionequation = eq_current.makestring(equation, rev)
					print item + '\t' + r + '\t' + reactionequation + '\t' + self.STATUS + '\t' + str(self.OBJECTIVE_VALUE)
					lethals[item] = 1
				#reset reaction constraints to default	
				cb.set_constraint(self, r, default_lbound, default_ubound)
			#make item (gene, protein, ...) available again
			level[item] = 1
		return lethals
	def ddeletions (self):
		"Double deletions at the reaction level."
		cb.solve(self, verbose=False)
		essential_reactions = cb.deletion_testing(self)

		fullstatus, fullobjectivevalue = self.STATUS, self.OBJECTIVE_VALUE
		for i, r in enumerate(self.REACTIONS.keys()):
			if not r == self.OBJECTIVE[1] and not r in essential_reactions and not 'R_ESC' in r and not 'R_SRC' in r:
				name, rev, notes, equation = self.REACTIONS[r]
				if rev:
					lbound = '-' + self.VMAX
				else:
					lbound = '0'
				default_lbound, default_ubound = self.CONSTRAINTS.get(r, (lbound, self.VMAX))
				cb.set_constraint(self, r, 0, 0)
				
				for j, r2 in enumerate(self.REACTIONS.keys()[i+1:]):
					if not r2 == self.OBJECTIVE[1] and not r2 in essential_reactions and not 'R_ESC' in r2 and not 'R_SRC' in r2:
						name2, rev2, notes2, equation2 = self.REACTIONS[r2]
						if rev2:
							lbound2 = '-' + self.VMAX
						else:
							lbound2 = '0'
						default_lbound2, default_ubound2 = self.CONSTRAINTS.get(r2, (lbound2, self.VMAX))
						cb.set_constraint(self, r2, 0, 0)
				
						cb.solve(self, verbose=False)
						
						if (not self.STATUS == 'OPTIMAL') or (float(self.OBJECTIVE_VALUE) < 0.25 * float(fullobjectivevalue)):
							reactionequation1 = eq_current.makestring(equation, rev)
							reactionequation2 = eq_current.makestring(equation2, rev2)
							print self.STATUS + '\t' + str(self.OBJECTIVE_VALUE)
							print r + '\t' + reactionequation1
							print r2 + '\t' + reactionequation2
							print
						cb.set_constraint(self, r2, default_lbound2, default_ubound2)
						
				cb.set_constraint(self, r, default_lbound, default_ubound)	
	def add_reaction (self, ID, name, rev, notes, equation):
		"Add a new reaction into the model. Example: m.make_reaction('R_ss_biomass', 'ssa biomass', 'false', {'CONFIDENCE: 1':1, 'SUBSYSTEM: biomass':1, 'GPR: ':1, 'EC Number: ':1}, [[('M_atp_c', '1')],[('M_adp_c', '1'), ('M_pi_c', '1')]])"
		if ID in self.REACTIONS:
			print ID, 'already in REACTIONS'
		else:
			self.REACTIONS[ID] = (name, rev, notes, equation)
			if ID in DISCREPANCIES:
				warning_equation = eq_current.makestring(equation, rev)
				#print ID, 'discrepant across models. Using:', warning_equation
			for species, coef in (equation[0] + equation[1]):
				#add compartment if necessary
				compartment, outside = abbrev2compartment[species[-1:]]
				if not compartment in self.COMPARTMENTS:
					cb.add_compartment(self, compartment, outside)
				#add species if necessary
				if not species in self.SPECIES:
					name, db_compartment, charge, boundaryCondition = '.', '.', '.', 'false'
					cb.add_species(self, species, name, compartment, charge, boundaryCondition)
    model.scoringExpData(exprfile)
    model.webScraping(organism)
    calls[x] = makeCallsDict(model.REACTIONS, model.hirxnset, model.lowrxnset)
    fluxes[x] = deepcopy(model.REACTION2FLUXVALUE)

    # reset default constraints:
    # for c in constraints:
    #       (lb, ub) = defaultConstraints[c[0]]
    #       model.set_constraint(c[0], lb, ub)

    # model.print_flux_xls( fluxes, 'Ruppins_SpaceFlight_05_09_2012.xls', calls )
    cache = {}
    # for reaction in model.varkeys():
    for reaction in model.REACTIONS:
        name, reversible, notes, equation = model.REACTIONS[reaction]
        reactionequation = eq_current.makestring(equation, reversible)
        # search for any ec numbers and pathways in reaction notes; it IS possible for there to be > 1 ec or pathway for a given reaction
        confidence, gpr = "?", "?"
        holder = {"pathways": {}, "ecs": {}}
        ref, prr = ".", "."
        for note in notes:
            if "SUBSYSTEM: " in note:
                holder["pathways"][note[11:]] = 1
            if "EC: " in note:
                holder["ecs"][note[4:]] = 1
            #                    print note
            if "SCORES: " in note:
                print "THIS IS THE SCORE", notes["SCORES: "]
                Avg = notes["SCORES: "] + Avg
                count += 1
            if "CONFIDENCE: " in note:
	def list_reactions (self, out=False, showfluxvalues=True):
		"Prints a list of reactions from current model, organized by path, then ecnumber. Arguments are out=<fn>, showfluxvalues=<True/False>. Defaults are False, True."
		cache = {}
		for reaction in self.REACTIONS:
			name, reversible, notes, equation = self.REACTIONS[reaction]
			reactionequation = eq_current.makestring(equation, reversible)
			#search for any ec numbers and pathways in reaction notes; it IS possible for there to be > 1 ec or pathway for a given reaction
			confidence, gpr = '?', '?'
			holder = {'pathways':{}, 'ecs':{}}
			ref, prr = '.', '.'
			for note in notes:
				if 'SUBSYSTEM: ' in note:
					holder['pathways'][note[11:]] = 1
				if 'EC: ' in note:
					holder['ecs'][note[4:]] = 1
				if 'CONFIDENCE: ' in note:
					confidence = note[12:]
				if 'GPR: ' in note:
					gpr = note[5:]
				if 'Protein_reaction_relation: ' in note:
					prr = note[note.find(' == ') + 4:]
				if 'PMID: ' in note: # and not 'review' in note and not 'related_organism' in note 
					ref = ref + note.split(',')[0][6:] + ' '
			if not ref == '.':
				ref = 'PMIDs: ' + ref[1:-1]
			
			#construct grr
			grr = prr
			for i in prr.split():
				if '(' in i:
					i = i[1:]
				if ')' in i:
					i = i[:-1]
				if i in self.PROTEIN2GENE:
					grr = grr.replace(i, self.PROTEIN2GENE[i])
					
			#add to cache for printing...																		
			for pathwayname in holder['pathways']:
				for ec in holder['ecs']:
					if not pathwayname in cache:
						cache[pathwayname] = {}
					if not ec in cache[pathwayname]:
						cache[pathwayname][ec] = {}
						
					#if this is printing the results of 'solve', then get flux activities...
					#reactionID	name	rev	pathway	ec	equation	confidence	gpr
					if showfluxvalues and self.REACTION2FLUXVALUE.get(reaction, '.') != '0':
						cache[pathwayname][ec][ ('\t').join((reaction, name, str(reversible), pathwayname, ec, self.REACTION2FLUXVALUE.get(reaction, '.'), reactionequation)) ] = 1
					if not showfluxvalues:
						cache[pathwayname][ec][ ('\t').join((reaction, name, str(reversible), pathwayname, ec, reactionequation, prr, grr, ref)) ] = 1
		
		paths = cache.keys()
		paths.sort()		
		
		if out:
			outfi = open(out, 'w')
				
			for path in paths:
				ecs = cache[path].keys()
				ecs.sort()
				for ec in ecs:
					for r in cache[path][ec]:
						print >>outfi, r
				#print >>outfi, '\n'
				
		else:
			for path in paths:
				ecs = cache[path].keys()
				ecs.sort()
				for ec in ecs:
					for r in cache[path][ec]:
						print r
	def get_equation (self, id):
		"Given a reactionID, prettyprint the reaction equation."
		name, reversible, notes, equation = self.REACTIONS[id]
		reactionequation = eq_current.makestring(equation, reversible)
		return reactionequation
    def data_integration(self,gammas = (-0.1,0.1),exprfile = args.exp,forceBiomass = True, verbose = False):
        """
        Ruppin  analysis of syw using the datasets from Tetu et al., 2009 about phosphate stress.
        """
        gprfname = self.infile + '.gpr'
        #gap_Exchanges = "gapSRC_ESC.txt"
        def makeCallsDict( allRxns, hirxns, lorxns ):
            calls = {}
            for r in hirxns:
                assert r in allRxns and r not in lorxns
            for r in lorxns:
                assert r in allRxns and r not in hirxns
            for r in allRxns:
                if r in hirxns:
                    calls[r] = "On"
                elif r in lorxns:
                    calls[r] = "Off"
                else: 
                    calls[r] = "No call"
            for r in allRxns:
                assert not calls[r] == None
            return calls
        
        organism = raw_input("What is the organism's name in PubMed? ")
        self.model = mg.gurobicb()
        w2m.wil2metmodel(self.wilfname)
        #self.model.build_from_textfiles(modelfile=self.modelname + ".reactions", biomassfile=self.modelname + ".biomass", sourcesfile=self.modelname+".sources", escapesfile=self.modelname +".escapes", exchangesfile="", gapexfile=gap_Exchanges)
        self.model.build_from_textfiles(modelfile=self.modelname + ".reactions", biomassfile=self.modelname + ".biomass", sourcesfile=self.modelname+".sources", escapesfile=self.modelname +".escapes", exchangesfile="")
        if verbose:
            rq = False
        else:
            rq = True
        self.model.gpr2(gprfname,readquiet=rq)

        fluxes = {}
        calls = {}

        self.model.solve(verbose=verbose)
        fluxes['fba'] = deepcopy(self.model.REACTION2FLUXVALUE)

        self.model.ruppin(exprfile,gammas,forceBiomass=forceBiomass)
        #self.model.scoringExpData(exprfile)
        #self.model.webScrapping(organism)

        calls[self.outprefix] = makeCallsDict(self.model.REACTIONS,self.model.hirxnset,self.model.lowrxnset)
        fluxes[self.outprefix] = deepcopy(self.model.REACTION2FLUXVALUE)
        cache = {}
        for reaction in self.model.REACTIONS:
            name, reversible, notes, equation = self.model.REACTIONS[reaction]
            reactionequation = eq_current.makestring(equation, reversible)
            confidence,gpr = '?','?'
            holder = {'pathways':{}, 'ecs':{}}
            ref, prr = '.', '.'
            for note in notes:
                if 'SUBSYSTEM: ' in note:
                    holder['pathways'][note[11:]] = 1
                if 'EC: ' in note:
                    holder['ecs'][note[4:]] = 1
                if 'SCORES: ' in note:
                    print ("THIS IS THE SCORE", notes['SCORES: '])
                    Avg = notes['SCORES: '] + Avg
                    count += 1
                if 'CONFIDENCE: ' in note:
                    confidence = note[12:]
                if 'GPR: ' in note:
                    gpr = note[5:]
                if 'Protein_reaction_relation: ' in note:
                    prr = note[note.find(' == ') + 4:]
                if 'PMID: ' in note: # and not 'review' in note and not 'related_organism' in note 
                    ref = ref + note.split(',')[0][6:] + ' '
            if not ref == '.':
                ref = 'PMIDs: ' + ref[1:-1]

            grr = prr
            for i in prr.split():
                if '(' in i:
                    i = i[1:]
                if ')' in i:
                    i = i[:-1]
                if i in self.model.PROTEIN2GENE:
                    grr = grr.replace(i, model.PROTEIN2GENE[i])
                    
            #add to cache for printing...                                                                       
            for pathwayname in holder['pathways']:
                for ec in holder['ecs']:
                    if not pathwayname in cache:
                        cache[pathwayname] = {}
                    if not ec in cache[pathwayname]:
                        cache[pathwayname][ec] = {}

                    cache[pathwayname][ec][ ('\t').join((reaction, name, str(reversible), pathwayname, ec, fluxes['fba'][reaction], fluxes[self.outprefix][reaction], reactionequation)) ] = 1
        paths = cache.keys()
        paths.sort()
        outfile = open(self.outprefix+"integrated.xls","w")

        for path in paths:
            ecs = cache[path].keys()
            ecs.sort()
            for ec in ecs:
                for r in cache[path][ec]:
                    outfile.write("%s\n" % r)
                    
        #Average = float(Avg)/float(count)
        #print ('\n\n', "Average Score of Model: ", Avg, '\n')
        #print ("Average Score of Model per Gene: ", Average, '\n')
        self.model.writeECfile(self.outprefix + "ec3.txt")
        metfile = open(self.outprefix + "metabolites3.txt","w")
        numspecies = 0
        for species in self.model.SPECIES.keys():
            if not species.endswith("_b"):
                metfile.write("%s\n" % (species))
                numspecies += 1
        numreactions = 0
        for reactions in self.model.REACTIONS.keys():
            if (not reactions.startswith("R_SRC")) and (not reactions.startswith("R_ESC")) and (not reactions.startswith("R_EXCH")):
                numreactions += 1
        
        del self.model
        return numspecies,numreactions
        
        del self.model