1+
2+ #*******************************************************************
3+ # * File: merge.py
4+ # * Description:
5+ # * Author: HarshaRani
6+ 7+ # ********************************************************************/
8+ # **********************************************************************
9+ #** This program is part of 'MOOSE', the
10+ #** Messaging Object Oriented Simulation Environment,
11+ #** also known as GENESIS 3 base code.
12+ #** copyright (C) 2003-2016 Upinder S. Bhalla. and NCBS
13+ #Created : Friday June 13 12:19:00 2016(+0530)
14+ #Version
15+ #Last-Updated:Tuesday June 21 12.22.37
16+ # By:
17+ #**********************************************************************/
18+
19+ # This program is used to merge models
20+ # -- Model B is merged to A
21+ # -- Rules are
22+ # ## check for compartment in B exist in A
23+ # *** If compartment from model B doesn't exist in model A, then copy entire compartment from B to A
24+ # *** If compartment from model B exist in model A
25+ # ^^^^ check the volume of compartment of B as compared to A
26+ # !!!!! If same, then copy all the moose object which doesn't exist in A and reference to both mooseId
27+ # which is used for connecting objects.
28+ #
29+ # ^^^^ If volume of compartment of model B is different then change the volume of compartment of model B same as A
30+ # !!!! If same, then copy all the moose object which doesn't exist in A and reference to both mooseId
31+ # which is used for connecting objects
32+
33+ # &&&&&& copying pools from compartment from B to A is easy
34+ # &&&&& but while copying reaction and enzyme check if the same reaction exist
35+ # -- if same reaction name exists
36+ # -- Yes
37+ # 1) check if substrate and product are same as compartment from model B to compartment modelA
38+ # --yes do nothing
39+ # --No then duplicate the reaction in model A and connect the message of approraite sub/prd
40+ # and warn the user the same reaction name with different sub or product
41+ # -- No
42+ # copy the reaction
43+ import sys
44+ from . import _moose as moose
45+
46+ def merge (A ,B ):
47+ #load models into moose and solver's are deleted
48+ apath = loadModels (A )
49+ bpath = loadModels (B )
50+
51+ comptAdict = comptList (apath )
52+ comptBdict = comptList (bpath )
53+
54+
55+ for key in comptBdict .keys ():
56+
57+ if not comptAdict .has_key (key ):
58+ # comptBdict[key] - compartment from model B which does not exist in model A
59+ moose .copy (comptBdict [key ],moose .element (apath ))
60+ else :
61+ war_msg = ""
62+ copied , duplicated = [],[]
63+
64+ if not (comptAdict [key ].volume == comptBdict [key ].volume ):
65+ #change volume of ModelB same as ModelA
66+ volumeA = comptAdict [key ].volume
67+ comptBdict [key ].volume = volumeA
68+
69+ #Merging Pool
70+ poolName_a = []
71+ poolListina = moose .wildcardFind (comptAdict [key ].path + '/##[ISA=PoolBase]' )
72+
73+ neutral_compartment = findgroup_compartment (poolListina [0 ])
74+ for pl in poolListina :
75+ poolName_a .append (pl .name )
76+
77+ for pool in moose .wildcardFind (comptBdict [key ].path + '/##[ISA=PoolBase]' ):
78+ if not pool .name in poolName_a :
79+ #pool has compartment(assume its direct pool ),so copy under kinetics
80+ if ((pool .parent ).className == "CubeMesh" or (pool .parent ).className == "Neutral" ):
81+ c = moose .copy (pool ,neutral_compartment )
82+ copied .append (c )
83+ elif (pool .parent ).className == "ZombieEnz" or (pool .parent ).className == "Enz" :
84+ print " Pool not in modelA but enz parent" ,pool .name
85+ pass
86+ else :
87+ print " Check this pool, parent which doesn't have ChemCompt or Enz" ,
88+
89+ #Mergering Reaction
90+ reacName_a = []
91+ reacListina = moose .wildcardFind (comptAdict [key ].path + '/##[ISA=ReacBase]' )
92+ neutral_compartment = findgroup_compartment (poolListina [0 ])
93+
94+ for re in reacListina :
95+ reacName_a .append (re .name )
96+ for reac in moose .wildcardFind (comptBdict [key ].path + '/##[ISA=ReacBase]' ):
97+ if reac .name in reacName_a :
98+
99+ rA = comptAdict [key ].path + '/' + reac .name
100+ rB = comptBdict [key ].path + '/' + reac .name
101+
102+ rAsubname ,rBsubname ,rAprdname ,rBprdname = [], [], [], []
103+ rAsubname = subprdList (rA ,"sub" )
104+ rBsubname = subprdList (rB ,"sub" )
105+ rAprdname = subprdList (rA ,"prd" )
106+ rBprdname = subprdList (rB ,"prd" )
107+
108+ aS = set (rAsubname )
109+ bS = set (rBsubname )
110+ aP = set (rAprdname )
111+ bP = set (rBprdname )
112+ hasSameSub = True
113+ hasSamePrd = True
114+ if len (aS .union (bS ) - aS .intersection (bS )):
115+ hasSameSub = False
116+
117+ if len (aP .union (bP ) - aP .intersection (bP )):
118+ hasSamePrd = False
119+
120+ if not all ((hasSameSub ,hasSamePrd )):
121+ war_msg = war_msg + "Reaction \" " + reac .name + "\" also contains in modelA but with different"
122+ if not hasSameSub :
123+ war_msg = war_msg + " substrate "
124+
125+ if not hasSamePrd :
126+ war_msg = war_msg + " product"
127+ war_msg = war_msg + ", reaction is duplicated in modelA. \n Modeler should decide to keep or remove this reaction"
128+
129+ reac = moose .Reac (comptAdict [key ].path + '/' + reac .name + "_duplicated" )
130+ mooseConnect (comptAdict [key ].path ,reac ,rBsubname ,"sub" )
131+ mooseConnect (comptAdict [key ].path ,reac ,rBprdname ,"prd" )
132+
133+ duplicated .append (reac )
134+
135+ elif not reac .name in reacName_a :
136+ #reac has compartment(assume its direct reac ),so copy under kinetics
137+ if ((reac .parent ).className == "CubeMesh" or (reac .parent ).className == "Neutral" ):
138+ c = moose .copy (reac ,neutral_compartment )
139+ copied .append (c )
140+
141+ rBsubname , rBprdname = [],[]
142+ rBsubname = subprdList (reac ,"sub" )
143+ rBprdname = subprdList (reac ,"prd" )
144+ mooseConnect (comptAdict [key ].path ,reac ,rBsubname ,"sub" )
145+ mooseConnect (comptAdict [key ].path ,reac ,rBprdname ,"prd" )
146+ print "c " , copied , "\n warning " ,war_msg , "\n Duplicated " ,duplicated
147+ return copied ,duplicated ,war_msg
148+ def loadModels (filename ):
149+ apath = '/'
150+
151+ apath = filename [filename .rfind ('/' ): filename .rfind ('.' )]
152+
153+ moose .loadModel (filename ,apath )
154+
155+ #Solvers are removed
156+ deleteSolver (apath )
157+ return apath
158+
159+ def comptList (modelpath ):
160+ comptdict = {}
161+ for ca in moose .wildcardFind (modelpath + '/##[ISA=ChemCompt]' ):
162+ comptdict [ca .name ] = ca
163+ return comptdict
164+
165+ def mooseConnect (modelpath ,reac ,spList ,sptype ):
166+ for spl in spList :
167+ spl_id = moose .element (modelpath + '/' + spl )
168+ reac_id = moose .element (modelpath + '/' + reac .name )
169+ if sptype == "sub" :
170+ m = moose .connect ( reac_id , "sub" , spl_id , 'reac' )
171+ else :
172+ moose .connect ( reac_id , "prd" , spl_id , 'reac' )
173+
174+ def deleteSolver (modelRoot ):
175+ compts = moose .wildcardFind (modelRoot + '/##[ISA=ChemCompt]' )
176+ for compt in compts :
177+ if moose .exists (compt .path + '/stoich' ):
178+ st = moose .element (compt .path + '/stoich' )
179+ st_ksolve = st .ksolve
180+ moose .delete (st )
181+ if moose .exists ((st_ksolve ).path ):
182+ moose .delete (st_ksolve )
183+
184+ def subprdList (reac ,subprd ):
185+ rtype = moose .element (reac ).neighbors [subprd ]
186+ rname = []
187+ for rs in rtype :
188+ rname .append (rs .name )
189+ return rname
190+ def mergeAtoB (a ,b ):
191+
192+ ca = moose .wildcardFind (m1path + '/##[ISA=PoolBase]' )
193+ cb = moose .wildcardFind (m2path + '/##[ISA=PoolBase]' )
194+
195+ cca = {}
196+ ccb = {}
197+ for c in ca :
198+ cca [c .name ] = c
199+ for c in cb :
200+ ccb [c .name ] = c
201+ avalue = cca .keys ()
202+ bvalue = ccb .keys ()
203+ #print cca,ccb
204+ print " bvalue " ,len (bvalue ), " avalue " ,len (avalue )
205+ myset = list (set (cca .keys ()).union (set (ccb .keys ())))
206+ print " insder " ,myset , len (myset )
207+ return model1
208+
209+ def findCompartment (element ):
210+ while not mooseIsInstance (element ,["CubeMesh" ,"CyclMesh" ]):
211+ element = element .parent
212+ return element
213+ def mooseIsInstance (element , classNames ):
214+ #print classNames
215+ #print moose.element(element).__class__.__name__ in classNames
216+ return moose .element (element ).__class__ .__name__ in classNames
217+
218+ def findgroup_compartment (element ):
219+ #Try finding Group which is Neutral but it should exist before Compartment, if Compartment exist then stop at Comparment
220+ while not mooseIsInstance (element ,"Neutral" ):
221+ if mooseIsInstance (element ,["CubeMesh" ,"CyclMesh" ]):
222+ return element
223+ element = element .parent
224+ return element
225+ if __name__ == "__main__" :
226+
227+ model1 = '/home/harsha/genesis_files/gfile/acc12.g'
228+ model2 = '/home/harsha/Trash/acc12_withadditionPool.g'
229+ #model1 = '/home/harsha/Trash/modelA.g'
230+ #model2 = '/home/harsha/Trash/modelB.g'
231+ model1 = '/home/harsha/genesis_files/gfile/acc44.g'
232+ model2 = '/home/harsha/genesis_files/gfile/acc45.g'
233+ mergered = merge (model1 ,model2 )
0 commit comments