189def modify_param_card(param_card_input=None,param_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,params={},output_location=None):
190 """Build a new param_card.dat from an existing one.
191 Params should be a dictionary of dictionaries. The first key is the block name, and the second in the param name.
192 Keys can include MASS (for masses) and DECAY X (for decays of particle X)"""
196 if param_card_input
is None:
197 param_card_input=process_dir+
'/Cards/param_card.dat'
198 elif param_card_input
is not None and not os.access(param_card_input,os.R_OK):
199 paramcard = subprocess.Popen([
'get_files',
'-data',param_card_input])
201 if not os.access(param_card_input,os.R_OK):
202 raise RuntimeError(
'Could not get param card '+param_card_input)
203 mglog.info(
'Using input param card at '+param_card_input)
207 for blockName
in list(params.keys()):
208 paramsUpper[blockName.upper()] = {}
209 for paramName
in list(params[blockName].keys()):
210 paramsUpper[blockName.upper()][paramName.upper()] = params[blockName][paramName]
212 if param_card_backup
is not None:
213 mglog.info(
'Keeping backup of original param card at '+param_card_backup)
214 param_card_old = param_card_backup
216 param_card_old = param_card_input+
'.old_to_be_deleted'
217 if os.path.isfile(param_card_old):
218 os.unlink(param_card_old)
219 os.rename(param_card_input, param_card_old)
221 oldcard = open(param_card_old,
'r')
222 param_card_location= process_dir+
'/Cards/param_card.dat' if output_location
is None else output_location
223 newcard = open(param_card_location,
'w')
227 for linewithcomment
in oldcard:
228 line=linewithcomment.split(
'#')[0]
229 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
230 and len(line.strip().
split()) > 1:
231 if decayEdit
and blockName ==
'DECAY':
233 pos = 0
if line.strip().startswith(
'DECAY')
else 1
234 if blockName==
'MASS' and 'MASS' in paramsUpper:
236 if "MASS" in doneParams:
237 leftOvers = [ x
for x
in paramsUpper[
'MASS']
if x
not in doneParams[
'MASS'] ]
239 leftOvers = [ x
for x
in paramsUpper[
'MASS'] ]
241 for pdg_id
in leftOvers:
242 mglog.warning(
'Adding mass line for '+str(pdg_id)+
' = '+str(paramsUpper[
'MASS'][pdg_id])+
' which was not in original param card')
243 newcard.write(
' '+str(pdg_id)+
' '+str(paramsUpper[
'MASS'][pdg_id])+
'\n')
244 doneParams[
'MASS'][pdg_id]=
True
245 if blockName==
'DECAY' and 'DECAY' not in line.strip().
upper()
and 'DECAY' in paramsUpper:
247 leftOvers = [ x
for x
in paramsUpper[
'DECAY']
if x
not in doneParams[
'DECAY'] ]
248 for pdg_id
in leftOvers:
249 mglog.warning(
'Adding decay for pdg id '+str(pdg_id)+
' which was not in the original param card')
250 newcard.write( paramsUpper[
'DECAY'][pdg_id].
strip()+
'\n' )
251 doneParams[
'DECAY'][pdg_id]=
True
257 if blockName !=
'DECAY' and len(line.strip().
split()) > 0:
260 if len(line.split())==2:
264 akey = line.upper().
strip()[:line.strip().rfind(
' ')].
strip()
265 elif blockName ==
'DECAY' and len(line.strip().
split()) > 1:
266 akey = line.strip().
split()[1]
268 newcard.write(linewithcomment)
272 if blockName
not in paramsUpper:
273 newcard.write(linewithcomment)
275 blockParams = paramsUpper[blockName]
281 if '#' in linewithcomment:
282 stringkey = linewithcomment[linewithcomment.find(
'#')+1:].
strip()
283 if len(stringkey.split()) > 0:
284 stringkey = stringkey.split()[0].
upper()
286 if akey
not in blockParams
and not (stringkey
is not None and stringkey
in blockParams):
287 newcard.write(linewithcomment)
290 if akey
in blockParams
and (stringkey
is not None and stringkey
in blockParams):
291 raise RuntimeError(
'Conflicting use of numeric and string keys '+akey+
' and '+stringkey)
293 theParam = blockParams.get(akey,blockParams[stringkey]
if stringkey
in blockParams
else None)
294 if blockName
not in doneParams:
295 doneParams[blockName] = {}
296 if akey
in blockParams:
297 doneParams[blockName][akey]=
True
298 elif stringkey
is not None and stringkey
in blockParams:
299 doneParams[blockName][stringkey]=
True
302 if blockName==
"DECAY":
303 if theParam.splitlines()[0].
split()[0].
upper()==
"DECAY":
305 for newline
in theParam.splitlines():
306 newcard.write(newline+
'\n')
310 newcard.write(
'DECAY '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
311 mglog.info(
'DECAY '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
313 elif blockName==
'QNUMBERS':
315 for newline
in theParam.splitlines():
316 newcard.write(newline+
'\n')
320 newcard.write(
' '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
321 mglog.info(
' '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
325 for blockName
in paramsUpper:
326 if blockName
not in doneParams
and len(paramsUpper[blockName].keys())>0:
327 raise RuntimeError(
'Did not find any of the parameters for block '+blockName+
' in param_card')
328 for paramName
in paramsUpper[blockName]:
329 if paramName
not in doneParams[blockName]:
330 raise RuntimeError(
'Was not able to replace parameter '+paramName+
' in param_card')