"""A class for tracking results for growth simulations."""from__future__importannotationsfromfunctoolsimportreducefromdataclassesimportdataclassimportpandasaspdimporttypingfromzipfileimportZipFilefrom..annotationimportannotate_metabolites_from_exchangesiftyping.TYPE_CHECKING:from..communityimportCommunityfrom..solutionimportCommunitySolution
[docs]defsave(self,path:str):"""Save growth results to a file. This will write all tables as CSV into a single ZIP file. Arguments --------- path : str A filepath for the generated file. Should end in `.zip`. """withZipFile(path,"w")aszippy:forattrin["growth_rates","exchanges","annotations"]:getattr(self,attr).to_csv(zippy.open(f"{attr}.csv","w"),index=False)
@staticmethod
[docs]defload(path:str)->GrowthResults:"""Load growth results from a file. Arguments --------- path : str Path to saved `GrowthResults`. Returns ------- GrowthResults The loaded growth results. """tables=[]withZipFile(path,"r")aszippy:forattrin["growth_rates","exchanges","annotations"]:tab=pd.read_csv(zippy.open(f"{attr}.csv","r"))tables.append(tab)returnGrowthResults(*tables)
[docs]def__add__(self,other:GrowthResults)->GrowthResults:"""Combine two GrowthResults objects. Arguments --------- other : GrowthResults The other result to merge with the current one. Returns ------- GrowthResult A merged growth result containing data from both. """rates=pd.concat([self.growth_rates,other.growth_rates])exs=pd.concat([self.exchanges,other.exchanges])anns=pd.concat([self.annotations,other.annotations]).drop_duplicates(subset=["reaction"])anns.index=anns.reactionreturnGrowthResults(rates,exs,anns)
@staticmethod
[docs]deffrom_solution(sol:CommunitySolution,com:Community)->GrowthResults:"""Convert a solution to growth results."""ifsol.fluxesisNone:raiseValueError("Solution needs to contain fluxes to be converted.")tol=com.solver.configuration.tolerances.feasibility# Get the main objectsrates=sol.members.drop("medium")rates["taxon"]=rates.indexrates["sample_id"]=com.idexs=list({r.global_idforrincom.internal_exchanges+com.exchanges})fluxes=sol.fluxes.loc[:,exs].copy()fluxes["sample_id"]=com.idfluxes["tolerance"]=tolfluxes["taxon"]=fluxes.index.valuesanns=annotate_metabolites_from_exchanges(com)anns.drop_duplicates(subset=["reaction"],inplace=True)# Cast data into the expected formatfluxes=fluxes.melt(id_vars=["taxon","sample_id","tolerance"],var_name="reaction",value_name="flux",).dropna(subset=["flux"])abundance=rates[["taxon","sample_id","abundance"]]exchanges=pd.merge(fluxes,abundance,on=["taxon","sample_id"],how="outer")anns.index=anns.reactionexchanges=pd.merge(exchanges,anns[["metabolite"]],on="reaction",how="left")exchanges["direction"]=DIRECTION[(exchanges.flux>0.0).astype(int)].valuesexchanges=exchanges[exchanges.flux.abs()>exchanges.tolerance]returnGrowthResults(rates,exchanges,anns)
[docs]defsave_results(results:GrowthResults,path:str):"""Save growth results to a file. This will write all tables as CSV into a single ZIP file. Arguments --------- results : GrowthResults The results as returned from `grow`. path : str A filepath for the generated file. Should end in `.zip`. """results.save(path)
[docs]defload_results(path):"""Load growth results from a file. Arguments --------- path : str Path to saved `GrowthResults`. Returns ------- GrowthResults The saved GrowthResults. """returnGrowthResults.load(path)
[docs]defcombine_results(it:typing.Iterable[GrowthResults])->GrowthResults:"""Combine several GrowthResults. Arguments --------- it : Iterable of GrowthResults The growth results to combine. Returns ------- GrowthResults The merged results. """returnreduce(lambdax,y:x+y,it)