197def modify_param_card(param_card_input=None,param_card_backup=None,process_dir=MADGRAPH_GRIDPACK_LOCATION,params={},output_location=None):
198 """Build a new param_card.dat from an existing one.
199 Params should be a dictionary of dictionaries. The first key is the block name, and the second in the param name.
200 Keys can include MASS (for masses) and DECAY X (for decays of particle X)"""
204 if param_card_input
is None:
205 param_card_input=process_dir+
'/Cards/param_card.dat'
206 elif param_card_input
is not None and not os.access(param_card_input,os.R_OK):
207 paramcard = subprocess.Popen([
'get_files',
'-data',param_card_input])
209 if not os.access(param_card_input,os.R_OK):
210 raise RuntimeError(
'Could not get param card '+param_card_input)
211 mglog.info(
'Using input param card at '+param_card_input)
215 for blockName
in list(params.keys()):
216 paramsUpper[blockName.upper()] = {}
217 for paramName
in list(params[blockName].keys()):
218 paramsUpper[blockName.upper()][paramName.upper()] = params[blockName][paramName]
220 if param_card_backup
is not None:
221 mglog.info(
'Keeping backup of original param card at '+param_card_backup)
222 param_card_old = param_card_backup
224 param_card_old = param_card_input+
'.old_to_be_deleted'
225 if os.path.isfile(param_card_old):
226 os.unlink(param_card_old)
227 os.rename(param_card_input, param_card_old)
229 oldcard = open(param_card_old,
'r')
230 param_card_location= process_dir+
'/Cards/param_card.dat' if output_location
is None else output_location
231 newcard = open(param_card_location,
'w')
235 for linewithcomment
in oldcard:
236 line=linewithcomment.split(
'#')[0]
237 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
238 and len(line.strip().
split()) > 1:
239 if decayEdit
and blockName ==
'DECAY':
241 pos = 0
if line.strip().startswith(
'DECAY')
else 1
242 if blockName==
'MASS' and 'MASS' in paramsUpper:
244 if "MASS" in doneParams:
245 leftOvers = [ x
for x
in paramsUpper[
'MASS']
if x
not in doneParams[
'MASS'] ]
247 leftOvers = [ x
for x
in paramsUpper[
'MASS'] ]
249 for pdg_id
in leftOvers:
250 mglog.warning(
'Adding mass line for '+str(pdg_id)+
' = '+str(paramsUpper[
'MASS'][pdg_id])+
' which was not in original param card')
251 newcard.write(
' '+str(pdg_id)+
' '+str(paramsUpper[
'MASS'][pdg_id])+
'\n')
252 doneParams[
'MASS'][pdg_id]=
True
253 if blockName==
'DECAY' and 'DECAY' not in line.strip().
upper()
and 'DECAY' in paramsUpper:
255 leftOvers = [ x
for x
in paramsUpper[
'DECAY']
if x
not in doneParams[
'DECAY'] ]
256 for pdg_id
in leftOvers:
257 mglog.warning(
'Adding decay for pdg id '+str(pdg_id)+
' which was not in the original param card')
258 newcard.write( paramsUpper[
'DECAY'][pdg_id].
strip()+
'\n' )
259 doneParams[
'DECAY'][pdg_id]=
True
265 if blockName !=
'DECAY' and len(line.strip().
split()) > 0:
268 if len(line.split())==2:
272 akey = line.upper().
strip()[:line.strip().rfind(
' ')].
strip()
273 elif blockName ==
'DECAY' and len(line.strip().
split()) > 1:
274 akey = line.strip().
split()[1]
276 newcard.write(linewithcomment)
280 if blockName
not in paramsUpper:
281 newcard.write(linewithcomment)
283 blockParams = paramsUpper[blockName]
289 if '#' in linewithcomment:
290 stringkey = linewithcomment[linewithcomment.find(
'#')+1:].
strip()
291 if len(stringkey.split()) > 0:
292 stringkey = stringkey.split()[0].
upper()
294 if akey
not in blockParams
and not (stringkey
is not None and stringkey
in blockParams):
295 newcard.write(linewithcomment)
298 if akey
in blockParams
and (stringkey
is not None and stringkey
in blockParams):
299 raise RuntimeError(
'Conflicting use of numeric and string keys '+akey+
' and '+stringkey)
301 theParam = blockParams.get(akey,blockParams[stringkey]
if stringkey
in blockParams
else None)
302 if blockName
not in doneParams:
303 doneParams[blockName] = {}
304 if akey
in blockParams:
305 doneParams[blockName][akey]=
True
306 elif stringkey
is not None and stringkey
in blockParams:
307 doneParams[blockName][stringkey]=
True
310 if blockName==
"DECAY":
311 if theParam.splitlines()[0].
split()[0].
upper()==
"DECAY":
313 for newline
in theParam.splitlines():
314 newcard.write(newline+
'\n')
318 newcard.write(
'DECAY '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
319 mglog.info(
'DECAY '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
321 elif blockName==
'QNUMBERS':
323 for newline
in theParam.splitlines():
324 newcard.write(newline+
'\n')
328 newcard.write(
' '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
329 mglog.info(
' '+akey+
' '+str(theParam)+
' # '+(linewithcomment[linewithcomment.find(
'#')+1:].
strip()
if linewithcomment.find(
'#')>0
else "")+
'\n')
333 for blockName
in paramsUpper:
334 if blockName
not in doneParams
and len(paramsUpper[blockName].keys())>0:
335 raise RuntimeError(
'Did not find any of the parameters for block '+blockName+
' in param_card')
336 for paramName
in paramsUpper[blockName]:
337 if paramName
not in doneParams[blockName]:
338 raise RuntimeError(
'Was not able to replace parameter '+paramName+
' in param_card')