Package models :: Module check_param_card
[hide private]
[frames] | no frames]

Source Code for Module models.check_param_card

   1  from __future__ import division 
   2   
   3  from __future__ import absolute_import 
   4  from __future__ import print_function 
   5  import itertools 
   6  import xml.etree.ElementTree as ET 
   7  import math 
   8   
   9  import os 
  10  import re 
  11  import shutil 
  12  import logging 
  13  import random 
  14  import six 
  15  StringIO = six 
  16  from six.moves import range 
  17   
  18  logger = logging.getLogger('madgraph.models') # -> stdout 
  19   
  20  try: 
  21      import madgraph.iolibs.file_writers as file_writers 
  22      import madgraph.various.misc as misc     
  23  except: 
  24      import internal.file_writers as file_writers 
  25      import internal.misc as misc 
  26   
  27  pjoin = os.path.join  
28 29 -class InvalidParamCard(Exception):
30 """ a class for invalid param_card """ 31 pass
32
33 -class Parameter (object):
34 """A class for a param_card parameter""" 35
36 - def __init__(self, param=None, block=None, lhacode=None, value=None, comment=None):
37 """Init the parameter""" 38 39 self.format = 'float' 40 if param: 41 block = param.lhablock 42 lhacode = param.lhacode 43 value = param.value 44 comment = param.comment 45 format = param.format 46 47 self.lhablock = block 48 if lhacode: 49 self.lhacode = lhacode 50 else: 51 self.lhacode = [] 52 self.value = value 53 self.comment = comment
54
55 - def set_block(self, block):
56 """ set the block name """ 57 58 self.lhablock = block
59
60 - def load_str(self, text):
61 """ initialize the information from a str""" 62 63 if '#' in text: 64 data, self.comment = text.split('#',1) 65 else: 66 data, self.comment = text, "" 67 68 69 data = data.split() 70 if any(d.startswith('scan') for d in data): 71 position = [i for i,d in enumerate(data) if d.startswith('scan')][0] 72 data = data[:position] + [' '.join(data[position:])] 73 if not len(data): 74 return 75 try: 76 self.lhacode = tuple([int(d) for d in data[:-1]]) 77 except Exception: 78 self.lhacode = tuple([int(d) for d in data[:-1] if d.isdigit()]) 79 self.value= ' '.join(data[len(self.lhacode):]) 80 else: 81 self.value = data[-1] 82 83 # convert to number when possible 84 try: 85 self.value = float(self.value) 86 except: 87 self.format = 'str' 88 pass 89 else: 90 if self.lhablock == 'modsel': 91 self.format = 'int' 92 self.value = int(self.value)
93
94 - def load_decay(self, text):
95 """ initialize the decay information from a str""" 96 97 if '#' in text: 98 data, self.comment = text.split('#',1) 99 else: 100 data, self.comment = text, "" 101 102 if ']]>' in data: 103 data = data.split(']]>',1)[0] 104 105 106 data = data.split() 107 if not len(data): 108 return 109 self.lhacode = [int(d) for d in data[2:]] 110 self.lhacode.sort() 111 self.lhacode = tuple([len(self.lhacode)] + self.lhacode) 112 113 self.value = float(data[0]) 114 self.format = 'decay_table'
115
116 - def __str__(self, precision=''):
117 """ return a SLAH string """ 118 119 120 format = self.format 121 if self.format == 'float': 122 try: 123 value = float(self.value) 124 except: 125 format = 'str' 126 self.comment = self.comment.strip() 127 if not precision: 128 precision = 6 129 130 if format == 'float': 131 if self.lhablock == 'decay' and not isinstance(self.value,six.string_types): 132 return 'DECAY %s %.{0}e # %s'.format(precision) % (' '.join([str(d) for d in self.lhacode]), self.value, self.comment) 133 elif self.lhablock == 'decay': 134 return 'DECAY %s Auto # %s' % (' '.join([str(d) for d in self.lhacode]), self.comment) 135 elif self.lhablock and self.lhablock.startswith('qnumbers'): 136 return ' %s %i # %s' % (' '.join([str(d) for d in self.lhacode]), int(self.value), self.comment) 137 else: 138 return ' %s %.{0}e # %s'.format(precision) % (' '.join([str(d) for d in self.lhacode]), self.value, self.comment) 139 elif format == 'int': 140 return ' %s %i # %s' % (' '.join([str(d) for d in self.lhacode]), int(self.value), self.comment) 141 elif format == 'str': 142 if self.lhablock == 'decay': 143 return 'DECAY %s %s # %s' % (' '.join([str(d) for d in self.lhacode]),self.value, self.comment) 144 return ' %s %s # %s' % (' '.join([str(d) for d in self.lhacode]), self.value, self.comment) 145 elif self.format == 'decay_table': 146 return ' %e %s # %s' % ( self.value,' '.join([str(d) for d in self.lhacode]), self.comment) 147 elif self.format == 'int': 148 return ' %s %i # %s' % (' '.join([str(d) for d in self.lhacode]), int(self.value), self.comment) 149 else: 150 if self.lhablock == 'decay': 151 return 'DECAY %s %d # %s' % (' '.join([str(d) for d in self.lhacode]), self.value, self.comment) 152 else: 153 return ' %s %d # %s' % (' '.join([str(d) for d in self.lhacode]), self.value, self.comment)
154
155 156 -class Block(list):
157 """ list of parameter """ 158
159 - def __init__(self, name=None):
160 if name: 161 self.name = name.lower() 162 else: 163 self.name = name 164 self.scale = None 165 self.comment = '' 166 self.decay_table = {} 167 self.param_dict={} 168 list.__init__(self)
169
170 - def get(self, lhacode, default=None):
171 """return the parameter associate to the lhacode""" 172 if not self.param_dict: 173 self.create_param_dict() 174 175 if isinstance(lhacode, int): 176 lhacode = (lhacode,) 177 178 try: 179 return self.param_dict[tuple(lhacode)] 180 except KeyError: 181 if default is None: 182 raise KeyError('id %s is not in %s' % (tuple(lhacode), self.name)) 183 else: 184 return Parameter(block=self, lhacode=lhacode, value=default, 185 comment='not define')
186
187 - def rename_keys(self, change_keys):
188 189 190 for old_key, new_key in change_keys.items(): 191 192 assert old_key in self.param_dict 193 param = self.param_dict[old_key] 194 del self.param_dict[old_key] 195 self.param_dict[new_key] = param 196 param.lhacode = new_key
197 198
199 - def remove(self, lhacode):
200 """ remove a parameter """ 201 list.remove(self, self.get(lhacode)) 202 # update the dictionary of key 203 return self.param_dict.pop(tuple(lhacode))
204
205 - def __eq__(self, other, prec=1e-4):
206 """ """ 207 208 if isinstance(other, str) and ' ' not in other: 209 return self.name.lower() == other.lower() 210 211 212 if len(self) != len(other): 213 return False 214 215 return not any(abs(param.value-other.param_dict[key].value)> prec * abs(param.value) 216 for key, param in self.param_dict.items())
217
218 - def __ne__(self, other, prec=1e-4):
219 return not self.__eq__(other, prec)
220
221 - def append(self, obj):
222 223 assert isinstance(obj, Parameter) 224 if not hasattr(self, 'name'): #can happen if loeaded from pickle 225 self.__init__(obj.lhablock) 226 assert not obj.lhablock or obj.lhablock == self.name 227 228 #The following line seems/is stupid but allow to pickle/unpickle this object 229 #this is important for madspin (in gridpack mode) 230 if not hasattr(self, 'param_dict'): 231 self.param_dict = {} 232 233 if tuple(obj.lhacode) in self.param_dict: 234 if self.param_dict[tuple(obj.lhacode)].value != obj.value: 235 raise InvalidParamCard('%s %s is already define to %s impossible to assign %s' % \ 236 (self.name, obj.lhacode, self.param_dict[tuple(obj.lhacode)].value, obj.value)) 237 return 238 list.append(self, obj) 239 # update the dictionary of key 240 self.param_dict[tuple(obj.lhacode)] = obj
241
242 - def create_param_dict(self):
243 """create a link between the lhacode and the Parameter""" 244 for param in self: 245 self.param_dict[tuple(param.lhacode)] = param 246 247 return self.param_dict
248
249 - def def_scale(self, scale):
250 """ """ 251 self.scale = scale
252
253 - def load_str(self, text):
254 "set inforamtion from the line" 255 256 if '#' in text: 257 data, self.comment = text.split('#',1) 258 else: 259 data, self.comment = text, "" 260 261 data = data.lower() 262 data = data.split() 263 self.name = data[1] # the first part of data is model 264 if len(data) == 3: 265 if data[2].startswith('q='): 266 #the last part should be of the form Q= 267 self.scale = float(data[2][2:]) 268 elif self.name == 'qnumbers': 269 self.name += ' %s' % data[2] 270 elif len(data) == 4 and data[2] == 'q=': 271 #the last part should be of the form Q= 272 self.scale = float(data[3]) 273 274 return self
275
276 - def keys(self):
277 """returns the list of id define in this blocks""" 278 279 return [p.lhacode for p in self]
280
281 - def __str__(self, precision=''):
282 """ return a str in the SLAH format """ 283 284 text = """###################################""" + \ 285 """\n## INFORMATION FOR %s""" % self.name.upper() +\ 286 """\n###################################\n""" 287 #special case for decay chain 288 if self.name == 'decay': 289 for param in self: 290 pid = param.lhacode[0] 291 param.set_block('decay') 292 text += str(param)+ '\n' 293 if pid in self.decay_table: 294 text += str(self.decay_table[pid])+'\n' 295 return text 296 elif self.name.startswith('decay'): 297 text = '' # avoid block definition 298 #general case 299 elif not self.scale: 300 text += 'BLOCK %s # %s\n' % (self.name.upper(), self.comment) 301 else: 302 text += 'BLOCK %s Q= %e # %s\n' % (self.name.upper(), self.scale, self.comment) 303 304 text += '\n'.join([param.__str__(precision) for param in self]) 305 return text + '\n'
306
307 308 -class ParamCard(dict):
309 """ a param Card: list of Block """ 310 mp_prefix = 'MP__' 311 312 header = \ 313 """######################################################################\n""" + \ 314 """## PARAM_CARD AUTOMATICALY GENERATED BY MG5 ####\n""" + \ 315 """######################################################################\n""" 316 317
318 - def __init__(self, input_path=None):
319 dict.__init__(self,{}) 320 self.order = [] 321 self.not_parsed_entry = [] 322 323 if isinstance(input_path, ParamCard): 324 self.read(input_path.write()) 325 self.input_path = input_path.input_path 326 else: 327 self.input_path = input_path 328 if input_path: 329 self.read(input_path)
330
331 - def read(self, input_path):
332 """ read a card and full this object with the content of the card """ 333 334 if isinstance(input_path, str): 335 if '\n' in input_path: 336 input = StringIO.StringIO(input_path) 337 else: 338 input = open(input_path) 339 else: 340 input = input_path #Use for banner loading and test 341 342 343 cur_block = None 344 for line in input: 345 line = line.strip() 346 if not line or line[0] == '#': 347 continue 348 line = line.lower() 349 if line.startswith('block'): 350 cur_block = Block() 351 cur_block.load_str(line) 352 self.append(cur_block) 353 continue 354 355 if line.startswith('decay'): 356 if not self.has_block('decay'): 357 cur_block = Block('decay') 358 self.append(cur_block) 359 else: 360 cur_block = self['decay'] 361 param = Parameter() 362 param.set_block(cur_block.name) 363 param.load_str(line[6:]) 364 cur_block.append(param) 365 continue 366 367 if line.startswith('xsection') or cur_block == 'notparsed': 368 cur_block = 'notparsed' 369 self.not_parsed_entry.append(line) 370 continue 371 372 373 if cur_block is None: 374 continue 375 376 if cur_block.name == 'decay': 377 # This is a decay table 378 id = cur_block[-1].lhacode[0] 379 cur_block = Block('decay_table_%s' % id) 380 self['decay'].decay_table[id] = cur_block 381 382 if cur_block.name.startswith('decay_table'): 383 param = Parameter() 384 param.load_decay(line) 385 try: 386 cur_block.append(param) 387 except InvalidParamCard: 388 pass 389 else: 390 param = Parameter() 391 param.set_block(cur_block.name) 392 param.load_str(line) 393 cur_block.append(param) 394 395 return self
396
397 - def __setitem__(self, name, value):
398 399 return dict.__setitem__(self, name.lower(), value)
400
401 - def __getitem__(self, name):
402 return dict.__getitem__(self,name.lower())
403
404 - def analyze_param_card(self):
405 """ Analyzes the comment of the parameter in the param_card and returns 406 a dictionary with parameter names in values and the tuple (lhablock, id) 407 in value as well as a dictionary for restricted values. 408 WARNING: THIS FUNCTION RELIES ON THE FORMATTING OF THE COMMENT IN THE 409 CARD TO FETCH THE PARAMETER NAME. This is mostly ok on the *_default.dat 410 but typically dangerous on the user-defined card.""" 411 412 pname2block = {} 413 restricted_value = {} 414 415 for bname, block in self.items(): 416 for lha_id, param in block.param_dict.items(): 417 all_var = [] 418 comment = param.comment 419 # treat merge parameter 420 if comment.strip().startswith('set of param :'): 421 all_var = list(re.findall(r'''[^-]1\*(\w*)\b''', comment)) 422 # just the variable name as comment 423 elif len(comment.split()) == 1: 424 all_var = [comment.strip().lower()] 425 # either contraction or not formatted 426 else: 427 split = comment.split() 428 if len(split) >2 and split[1] == ':': 429 # NO VAR associated 430 restricted_value[(bname, lha_id)] = ' '.join(split[1:]) 431 elif len(split) == 2: 432 if re.search(r'''\[[A-Z]\]eV\^''', split[1]): 433 all_var = [comment.strip().lower()] 434 elif len(split) >=2 and split[1].startswith('('): 435 all_var = [split[0].strip().lower()] 436 else: 437 if not bname.startswith('qnumbers'): 438 logger.debug("not recognize information for %s %s : %s", 439 bname, lha_id, comment) 440 # not recognized format 441 continue 442 443 for var in all_var: 444 var = var.lower() 445 if var in pname2block: 446 pname2block[var].append((bname, lha_id)) 447 else: 448 pname2block[var] = [(bname, lha_id)] 449 450 return pname2block, restricted_value
451
452 - def update_dependent(self, model, restrict_rule, loglevel):
453 """update the parameter of the card which are not free parameter 454 (i.e mass and width) 455 loglevel can be: None 456 info 457 warning 458 crash # raise an error 459 return if the param_card was modified or not 460 """ 461 modify = False 462 if isinstance(restrict_rule, str): 463 restrict_rule = ParamCardRule(restrict_rule) 464 465 # apply all the basic restriction rule 466 if restrict_rule: 467 _, modify = restrict_rule.check_param_card(self, modify=True, log=loglevel) 468 469 import models.model_reader as model_reader 470 import madgraph.core.base_objects as base_objects 471 if not isinstance(model, model_reader.ModelReader): 472 model = model_reader.ModelReader(model) 473 parameters = model.set_parameters_and_couplings(self) 474 else: 475 parameters = model.set_parameters_and_couplings(self) 476 477 478 for particle in model.get('particles'): 479 if particle.get('goldstone') or particle.get('ghost'): 480 continue 481 mass = model.get_parameter(particle.get('mass')) 482 lhacode = abs(particle.get_pdg_code()) 483 484 if isinstance(mass, base_objects.ModelVariable) and not isinstance(mass, base_objects.ParamCardVariable): 485 try: 486 param_value = self.get('mass').get(lhacode).value 487 except Exception: 488 param = Parameter(block='mass', lhacode=(lhacode,),value=0,comment='added') 489 param_value = -999.999 490 self.get('mass').append(param) 491 model_value = parameters[particle.get('mass')] 492 if isinstance(model_value, complex): 493 if model_value.imag > 1e-5 * model_value.real: 494 raise Exception("Mass should be real number: particle %s (%s) has mass: %s" % (lhacode, particle.get('name'), model_value)) 495 model_value = model_value.real 496 497 if not misc.equal(model_value, param_value, 4): 498 modify = True 499 if loglevel == 20: 500 logger.info('For consistency, the mass of particle %s (%s) is changed to %s.' % (lhacode, particle.get('name'), model_value), '$MG:BOLD') 501 else: 502 logger.log(loglevel, 'For consistency, the mass of particle %s (%s) is changed to %s.' % (lhacode, particle.get('name'), model_value)) 503 #logger.debug('was %s', param_value) 504 if model_value != param_value: 505 self.get('mass').get(abs(particle.get_pdg_code())).value = model_value 506 507 width = model.get_parameter(particle.get('width')) 508 if isinstance(width, base_objects.ModelVariable): 509 try: 510 param_value = self.get('decay').get(lhacode).value 511 except Exception: 512 param = Parameter(block='decay', lhacode=(lhacode,),value=0,comment='added') 513 param_value = -999.999 514 self.get('decay').append(param) 515 model_value = parameters[particle.get('width')] 516 if isinstance(model_value, complex): 517 if model_value.imag > 1e-5 * model_value.real: 518 raise Exception("Width should be real number: particle %s (%s) has mass: %s") 519 model_value = model_value.real 520 if not misc.equal(abs(model_value), param_value, 4): 521 modify = True 522 if loglevel == 20: 523 logger.info('For consistency, the width of particle %s (%s) is changed to %s.' % (lhacode, particle.get('name'), model_value), '$MG:BOLD') 524 else: 525 logger.log(loglevel,'For consistency, the width of particle %s (%s) is changed to %s.' % (lhacode, particle.get('name'), model_value)) 526 #logger.debug('was %s', param_value) 527 if abs(model_value) != param_value: 528 self.get('decay').get(abs(particle.get_pdg_code())).value = abs(model_value) 529 530 return modify
531 532
533 - def write(self, outpath=None, precision=''):
534 """schedular for writing a card""" 535 536 # order the block in a smart way 537 blocks = self.order_block() 538 text = self.header 539 text += ''.join([block.__str__(precision) for block in blocks]) 540 text += '\n' 541 text += '\n'.join(self.not_parsed_entry) 542 if not outpath: 543 return text 544 elif isinstance(outpath, str): 545 open(outpath,'w').write(text) 546 else: 547 outpath.write(text) # for test purpose
548
549 - def create_diff(self, new_card):
550 """return a text file allowing to pass from this card to the new one 551 via the set command""" 552 553 diff = '' 554 for blockname, block in self.items(): 555 for param in block: 556 lhacode = param.lhacode 557 value = param.value 558 new_value = new_card[blockname].get(lhacode).value 559 if not misc.equal(value, new_value, 6, zero_limit=False): 560 lhacode = ' '.join([str(i) for i in lhacode]) 561 diff += 'set param_card %s %s %s # orig: %s\n' % \ 562 (blockname, lhacode , new_value, value) 563 return diff
564 565
566 - def get_value(self, blockname, lhecode, default=None):
567 try: 568 return self[blockname].get(lhecode).value 569 except KeyError: 570 if blockname == 'width': 571 blockname = 'decay' 572 return self.get_value(blockname, lhecode,default=default) 573 elif default is not None: 574 return default 575 raise
576
577 - def get_missing_block(self, identpath):
578 """ """ 579 missing = set() 580 all_blocks = set(self.keys()) 581 for line in open(identpath): 582 if line.startswith('c ') or line.startswith('ccccc'): 583 continue 584 split = line.split() 585 if len(split) < 3: 586 continue 587 block = split[0] 588 if block not in self: 589 missing.add(block) 590 elif block in all_blocks: 591 all_blocks.remove(block) 592 593 unknow = all_blocks 594 return missing, unknow
595
596 - def secure_slha2(self,identpath):
597 598 missing_set, unknow_set = self.get_missing_block(identpath) 599 600 apply_conversion = [] 601 if missing_set == set(['fralpha']) and 'alpha' in unknow_set: 602 apply_conversion.append('alpha') 603 elif all([b in missing_set for b in ['te','msl2','dsqmix','tu','selmix','msu2','msq2','usqmix','td', 'mse2','msd2']]) and\ 604 all(b in unknow_set for b in ['ae','ad','sbotmix','au','modsel','staumix','stopmix']): 605 apply_conversion.append('to_slha2') 606 607 if 'to_slha2' in apply_conversion: 608 logger.error('Convention for the param_card seems to be wrong. Trying to automatically convert your file to SLHA2 format. \n'+\ 609 "Please check that the conversion occurs as expected (The converter is not fully general)") 610 611 param_card =self.input_path 612 convert_to_mg5card(param_card, writting=True) 613 self.clear() 614 self.__init__(param_card) 615 616 if 'alpha' in apply_conversion: 617 logger.info("Missing block fralpha but found a block alpha, apply automatic conversion") 618 self.rename_blocks({'alpha':'fralpha'}) 619 self['fralpha'].rename_keys({(): (1,)}) 620 self.write(param_card.input_path)
621
622 - def write_inc_file(self, outpath, identpath, default, need_mp=False):
623 """ write a fortran file which hardcode the param value""" 624 625 self.secure_slha2(identpath) 626 627 628 fout = file_writers.FortranWriter(outpath) 629 defaultcard = ParamCard(default) 630 for line in open(identpath): 631 if line.startswith('c ') or line.startswith('ccccc'): 632 continue 633 split = line.split() 634 if len(split) < 3: 635 continue 636 block = split[0] 637 lhaid = [int(i) for i in split[1:-1]] 638 variable = split[-1] 639 if block in self: 640 try: 641 value = self[block].get(tuple(lhaid)).value 642 except KeyError: 643 value =defaultcard[block].get(tuple(lhaid)).value 644 logger.warning('information about \"%s %s" is missing using default value: %s.' %\ 645 (block, lhaid, value)) 646 else: 647 value =defaultcard[block].get(tuple(lhaid)).value 648 if block != 'loop': 649 logger.warning('information about \"%s %s" is missing (full block missing) using default value: %s.' %\ 650 (block, lhaid, value)) 651 value = str(value).lower() 652 #special handling for negative mass -> set width negative 653 if block == 'decay': 654 if self['mass'].get(tuple(lhaid)).value < 0: 655 value = '-%s' % value 656 657 fout.writelines(' %s = %s' % (variable, ('%e'%float(value)).replace('e','d'))) 658 if need_mp: 659 fout.writelines(' mp__%s = %s_16' % (variable, value))
660
662 """ Convert this param_card to the convention used for the complex mass scheme: 663 This includes, removing the Yukawa block if present and making sure the EW input 664 scheme is (MZ, MW, aewm1). """ 665 666 # The yukawa block is irrelevant for the CMS models, we must remove them 667 if self.has_block('yukawa'): 668 # Notice that the last parameter removed will also remove the block. 669 for lhacode in [param.lhacode for param in self['yukawa']]: 670 self.remove_param('yukawa', lhacode) 671 672 # Now fix the EW input scheme 673 EW_input = {('sminputs',(1,)):None, 674 ('sminputs',(2,)):None, 675 ('mass',(23,)):None, 676 ('mass',(24,)):None} 677 for block, lhaid in EW_input.keys(): 678 try: 679 EW_input[(block,lhaid)] = self[block].get(lhaid).value 680 except: 681 pass 682 683 # Now specify the missing values. We only support the following EW 684 # input scheme: 685 # (alpha, GF, MZ) input 686 internal_param = [key for key,value in EW_input.items() if value is None] 687 if len(internal_param)==0: 688 # All parameters are already set, no need for modifications 689 return 690 691 if len(internal_param)!=1: 692 raise InvalidParamCard(' The specified EW inputs has more than one'+\ 693 ' unknown: [%s]'%(','.join([str(elem) for elem in internal_param]))) 694 695 696 if not internal_param[0] in [('mass',(24,)), ('sminputs',(2,)), 697 ('sminputs',(1,))]: 698 raise InvalidParamCard(' The only EW input scheme currently supported'+\ 699 ' are those with either the W mass or GF left internal.') 700 701 # Now if the Wmass is internal, then we must change the scheme 702 if internal_param[0] == ('mass',(24,)): 703 aewm1 = EW_input[('sminputs',(1,))] 704 Gf = EW_input[('sminputs',(2,))] 705 Mz = EW_input[('mass',(23,))] 706 try: 707 Mw = math.sqrt((Mz**2/2.0)+math.sqrt((Mz**4/4.0)-(( 708 (1.0/aewm1)*math.pi*Mz**2)/(Gf*math.sqrt(2.0))))) 709 except: 710 InvalidParamCard, 'The EW inputs 1/a_ew=%f, Gf=%f, Mz=%f are inconsistent'%\ 711 (aewm1,Gf,Mz) 712 self.remove_param('sminputs', (2,)) 713 self.add_param('mass', (24,), Mw, 'MW')
714
715 - def append(self, obj):
716 """add an object to this""" 717 718 assert isinstance(obj, Block) 719 self[obj.name] = obj 720 if not obj.name.startswith('decay_table'): 721 self.order.append(obj)
722 723 724
725 - def has_block(self, name):
726 return name in self
727
728 - def order_block(self):
729 """ reorganize the block """ 730 return self.order
731
732 - def rename_blocks(self, name_dict):
733 """ rename the blocks """ 734 735 for old_name, new_name in name_dict.items(): 736 self[new_name] = self.pop(old_name) 737 self[new_name].name = new_name 738 for param in self[new_name]: 739 param.lhablock = new_name
740
741 - def remove_block(self, name):
742 """ remove a blocks """ 743 assert len(self[name])==0 744 [self.order.pop(i) for i,b in enumerate(self.order) if b.name == name] 745 self.pop(name)
746
747 - def remove_param(self, block, lhacode):
748 """ remove a parameter """ 749 if self.has_param(block, lhacode): 750 self[block].remove(lhacode) 751 if len(self[block]) == 0: 752 self.remove_block(block)
753
754 - def has_param(self, block, lhacode):
755 """check if param exists""" 756 757 try: 758 self[block].get(lhacode) 759 except: 760 return False 761 else: 762 return True
763
764 - def copy_param(self,old_block, old_lha, block=None, lhacode=None):
765 """ make a parameter, a symbolic link on another one """ 766 767 # Find the current block/parameter 768 old_block_obj = self[old_block] 769 parameter = old_block_obj.get(old_lha) 770 if not block: 771 block = old_block 772 if not lhacode: 773 lhacode = old_lha 774 775 self.add_param(block, lhacode, parameter.value, parameter.comment)
776
777 - def add_param(self,block, lha, value, comment=''):
778 779 parameter = Parameter(block=block, lhacode=lha, value=value, 780 comment=comment) 781 try: 782 new_block = self[block] 783 except KeyError: 784 # If the new block didn't exist yet 785 new_block = Block(block) 786 self.append(new_block) 787 new_block.append(parameter)
788
789 - def do_help(self, block, lhacode, default=None):
790 791 if not lhacode: 792 logger.info("Information on block parameter %s:" % block, '$MG:color:BLUE') 793 print(str(self[block])) 794 elif default: 795 pname2block, restricted = default.analyze_param_card() 796 if (block, lhacode) in restricted: 797 logger.warning("This parameter will not be consider by MG5_aMC") 798 print( " MadGraph will use the following formula:") 799 print(restricted[(block, lhacode)]) 800 print( " Note that some code (MadSpin/Pythia/...) will read directly the value") 801 else: 802 for name, values in pname2block.items(): 803 if (block, lhacode) in values: 804 valid_name = name 805 break 806 logger.info("Information for parameter %s of the param_card" % valid_name, '$MG:color:BLUE') 807 print(("Part of Block \"%s\" with identification number %s" % (block, lhacode))) 808 print(("Current value: %s" % self[block].get(lhacode).value)) 809 print(("Default value: %s" % default[block].get(lhacode).value)) 810 print(("comment present in the cards: %s " % default[block].get(lhacode).comment))
811 812 813 814
815 - def mod_param(self, old_block, old_lha, block=None, lhacode=None, 816 value=None, comment=None):
817 """ change a parameter to a new one. This is not a duplication.""" 818 819 # Find the current block/parameter 820 old_block = self[old_block] 821 try: 822 parameter = old_block.get(old_lha) 823 except: 824 if lhacode is not None: 825 lhacode=old_lha 826 self.add_param(block, lhacode, value, comment) 827 return 828 829 830 # Update the parameter 831 if block: 832 parameter.lhablock = block 833 if lhacode: 834 parameter.lhacode = lhacode 835 if value: 836 parameter.value = value 837 if comment: 838 parameter.comment = comment 839 840 # Change the block of the parameter 841 if block: 842 old_block.remove(old_lha) 843 if not len(old_block): 844 self.remove_block(old_block.name) 845 try: 846 new_block = self[block] 847 except KeyError: 848 # If the new block didn't exist yet 849 new_block = Block(block) 850 self.append(new_block) 851 new_block.append(parameter) 852 elif lhacode: 853 old_block.param_dict[tuple(lhacode)] = \ 854 old_block.param_dict.pop(tuple(old_lha))
855 856
857 - def check_and_remove(self, block, lhacode, value):
858 """ check that the value is coherent and remove it""" 859 860 if self.has_param(block, lhacode): 861 param = self[block].get(lhacode) 862 if param.value != value: 863 error_msg = 'This card is not suitable to be convert to SLAH1\n' 864 error_msg += 'Parameter %s %s should be %s' % (block, lhacode, value) 865 raise InvalidParamCard(error_msg) 866 self.remove_param(block, lhacode)
867
868 869 -class ParamCardMP(ParamCard):
870 """ a param Card: list of Block with also MP definition of variables""" 871
872 - def write_inc_file(self, outpath, identpath, default):
873 """ write a fortran file which hardcode the param value""" 874 875 fout = file_writers.FortranWriter(outpath) 876 defaultcard = ParamCard(default) 877 for line in open(identpath): 878 if line.startswith('c ') or line.startswith('ccccc'): 879 continue 880 split = line.split() 881 if len(split) < 3: 882 continue 883 block = split[0] 884 lhaid = [int(i) for i in split[1:-1]] 885 variable = split[-1] 886 if block in self: 887 try: 888 value = self[block].get(tuple(lhaid)).value 889 except KeyError: 890 value =defaultcard[block].get(tuple(lhaid)).value 891 elif block == 'loop' and lhaid == [1]: 892 try: 893 value =defaultcard[block].get(tuple(lhaid)).value 894 except: 895 value = 9.1188 896 else: 897 value =defaultcard[block].get(tuple(lhaid)).value 898 #value = str(value).lower() 899 fout.writelines(' %s = %s' % (variable, ('%e' % value).replace('e','d'))) 900 fout.writelines(' %s%s = %s_16' % (self.mp_prefix, 901 variable, ('%e' % value)))
902
903 904 905 906 -class ParamCardIterator(ParamCard):
907 """A class keeping track of the scan: flag in the param_card and 908 having an __iter__() function to scan over all the points of the scan. 909 """ 910 911 logging = True
912 - def __init__(self, input_path=None):
913 super(ParamCardIterator, self).__init__(input_path=input_path) 914 self.itertag = [] #all the current value use 915 self.cross = [] # keep track of all the cross-section computed 916 self.param_order = []
917
918 - def __iter__(self):
919 """generate the next param_card (in a abstract way) related to the scan. 920 Technically this generates only the generator.""" 921 922 if hasattr(self, 'iterator'): 923 return self.iterator 924 self.iterator = self.iterate() 925 return self.iterator
926
927 - def next(self, autostart=False):
928 """call the next iteration value""" 929 try: 930 iterator = self.iterator 931 except: 932 if autostart: 933 iterator = self.__iter__() 934 else: 935 raise 936 try: 937 out = next(iterator) 938 except StopIteration: 939 del self.iterator 940 raise 941 return out
942
943 - def iterate(self):
944 """create the actual generator""" 945 all_iterators = {} # dictionary of key -> block of object to scan [([param, [values]), ...] 946 pattern = re.compile(r'''scan\s*(?P<id>\d*)\s*:\s*(?P<value>[^#]*)''', re.I) 947 self.autowidth = [] 948 # First determine which parameter to change and in which group 949 # so far only explicit value of the scan (no lambda function are allowed) 950 for block in self.order: 951 for param in block: 952 if isinstance(param.value, str) and param.value.strip().lower().startswith('scan'): 953 try: 954 key, def_list = pattern.findall(param.value)[0] 955 except: 956 raise Exception("Fail to handle scanning tag: Please check that the syntax is valid") 957 if key == '': 958 key = -1 * len(all_iterators) 959 if key not in all_iterators: 960 all_iterators[key] = [] 961 try: 962 all_iterators[key].append( (param, eval(def_list))) 963 except SyntaxError as error: 964 raise Exception("Fail to handle your scan definition. Please check your syntax:\n entry: %s \n Error reported: %s" %(def_list, error)) 965 elif isinstance(param.value, str) and param.value.strip().lower().startswith('auto'): 966 self.autowidth.append(param) 967 keys = list(all_iterators.keys()) # need to fix an order for the scan 968 param_card = ParamCard(self) 969 #store the type of parameter 970 for key in keys: 971 for param, values in all_iterators[key]: 972 self.param_order.append("%s#%s" % (param.lhablock, '_'.join(repr(i) for i in param.lhacode))) 973 974 # do the loop 975 lengths = [list(range(len(all_iterators[key][0][1]))) for key in keys] 976 for positions in itertools.product(*lengths): 977 self.itertag = [] 978 if self.logging: 979 logger.info("Create the next param_card in the scan definition", '$MG:BOLD') 980 for i, pos in enumerate(positions): 981 key = keys[i] 982 for param, values in all_iterators[key]: 983 # assign the value in the card. 984 param_card[param.lhablock].get(param.lhacode).value = values[pos] 985 self.itertag.append(values[pos]) 986 if self.logging: 987 logger.info("change parameter %s with code %s to %s", \ 988 param.lhablock, param.lhacode, values[pos]) 989 990 991 # retrun the current param_card up to next iteration 992 yield param_card
993 994
995 - def store_entry(self, run_name, cross, error=None, param_card_path=None):
996 """store the value of the cross-section""" 997 998 if isinstance(cross, dict): 999 info = dict(cross) 1000 info.update({'bench' : self.itertag, 'run_name': run_name}) 1001 self.cross.append(info) 1002 else: 1003 if error is None: 1004 self.cross.append({'bench' : self.itertag, 'run_name': run_name, 'cross(pb)':cross}) 1005 else: 1006 self.cross.append({'bench' : self.itertag, 'run_name': run_name, 'cross(pb)':cross, 'error(pb)':error}) 1007 1008 if self.autowidth and param_card_path: 1009 paramcard = ParamCard(param_card_path) 1010 for param in self.autowidth: 1011 self.cross[-1]['width#%s' % param.lhacode[0]] = paramcard.get_value(param.lhablock, param.lhacode)
1012 1013
1014 - def write_summary(self, path, order=None, lastline=False, nbcol=20):
1015 """ """ 1016 1017 if path: 1018 ff = open(path, 'w') 1019 else: 1020 ff = StringIO.StringIO() 1021 if order: 1022 keys = order 1023 else: 1024 keys = list(self.cross[0].keys()) 1025 if 'bench' in keys: keys.remove('bench') 1026 if 'run_name' in keys: keys.remove('run_name') 1027 keys.sort() 1028 if 'cross(pb)' in keys: 1029 keys.remove('cross(pb)') 1030 keys.append('cross(pb)') 1031 if 'error(pb)' in keys: 1032 keys.remove('error(pb)') 1033 keys.append('error(pb)') 1034 1035 formatting = "#%s%s%s\n" %('%%-%is ' % (nbcol-1), ('%%-%is ' % (nbcol))* len(self.param_order), 1036 ('%%-%is ' % (nbcol))* len(keys)) 1037 # header 1038 if not lastline: 1039 ff.write(formatting % tuple(['run_name'] + self.param_order + keys)) 1040 formatting = "%s%s%s\n" %('%%-%is ' % (nbcol), ('%%-%ie ' % (nbcol))* len(self.param_order), 1041 ('%%-%ie ' % (nbcol))* len(keys)) 1042 1043 1044 if not lastline: 1045 to_print = self.cross 1046 else: 1047 to_print = self.cross[-1:] 1048 1049 for info in to_print: 1050 name = info['run_name'] 1051 bench = info['bench'] 1052 data = [] 1053 for k in keys: 1054 if k in info: 1055 data.append(info[k]) 1056 else: 1057 data.append(0.) 1058 ff.write(formatting % tuple([name] + bench + data)) 1059 1060 if not path: 1061 return ff.getvalue()
1062 1063
1064 - def get_next_name(self, run_name):
1065 """returns a smart name for the next run""" 1066 1067 if '_' in run_name: 1068 name, value = run_name.rsplit('_',1) 1069 if value.isdigit(): 1070 return '%s_%02i' % (name, float(value)+1) 1071 # no valid '_' in the name 1072 return '%s_scan_02' % run_name
1073
1074 1075 1076 -class ParamCardRule(object):
1077 """ A class for storing the linked between the different parameter of 1078 the param_card. 1079 Able to write a file 'param_card_rule.dat' 1080 Able to read a file 'param_card_rule.dat' 1081 Able to check the validity of a param_card.dat 1082 """ 1083 1084
1085 - def __init__(self, inputpath=None):
1086 """initialize an object """ 1087 1088 # constraint due to model restriction 1089 self.zero = [] 1090 self.one = [] 1091 self.identical = [] 1092 self.opposite = [] 1093 1094 # constraint due to the model 1095 self.rule = [] 1096 1097 if inputpath: 1098 self.load_rule(inputpath)
1099
1100 - def add_zero(self, lhablock, lhacode, comment=''):
1101 """add a zero rule""" 1102 self.zero.append( (lhablock, lhacode, comment) )
1103
1104 - def add_one(self, lhablock, lhacode, comment=''):
1105 """add a one rule""" 1106 self.one.append( (lhablock, lhacode, comment) )
1107
1108 - def add_identical(self, lhablock, lhacode, lhacode2, comment=''):
1109 """add a rule for identical value""" 1110 self.identical.append( (lhablock, lhacode, lhacode2, comment) )
1111
1112 - def add_opposite(self, lhablock, lhacode, lhacode2, comment=''):
1113 """add a rule for identical value""" 1114 self.opposite.append( (lhablock, lhacode, lhacode2, comment) )
1115 1116
1117 - def add_rule(self, lhablock, lhacode, rule, comment=''):
1118 """add a rule for constraint value""" 1119 self.rule.append( (lhablock, lhacode, rule) )
1120
1121 - def write_file(self, output=None):
1122 1123 text = """<file>###################################################################### 1124 ## VALIDITY RULE FOR THE PARAM_CARD #### 1125 ######################################################################\n""" 1126 1127 # ZERO 1128 text +='<zero>\n' 1129 for name, id, comment in self.zero: 1130 text+=' %s %s # %s\n' % (name, ' '.join([str(i) for i in id]), 1131 comment) 1132 # ONE 1133 text +='</zero>\n<one>\n' 1134 for name, id, comment in self.one: 1135 text+=' %s %s # %s\n' % (name, ' '.join([str(i) for i in id]), 1136 comment) 1137 # IDENTICAL 1138 text +='</one>\n<identical>\n' 1139 for name, id,id2, comment in self.identical: 1140 text+=' %s %s : %s # %s\n' % (name, ' '.join([str(i) for i in id]), 1141 ' '.join([str(i) for i in id2]), comment) 1142 1143 # OPPOSITE 1144 text +='</identical>\n<opposite>\n' 1145 for name, id,id2, comment in self.opposite: 1146 text+=' %s %s : %s # %s\n' % (name, ' '.join([str(i) for i in id]), 1147 ' '.join([str(i) for i in id2]), comment) 1148 1149 # CONSTRAINT 1150 text += '</opposite>\n<constraint>\n' 1151 for name, id, rule, comment in self.rule: 1152 text += ' %s %s : %s # %s\n' % (name, ' '.join([str(i) for i in id]), 1153 rule, comment) 1154 text += '</constraint>\n</file>' 1155 1156 if isinstance(output, str): 1157 output = open(output,'w') 1158 if hasattr(output, 'write'): 1159 output.write(text) 1160 return text
1161
1162 - def load_rule(self, inputpath):
1163 """ import a validity rule file """ 1164 1165 1166 try: 1167 tree = ET.parse(inputpath) 1168 except IOError: 1169 if '\n' in inputpath: 1170 # this is convinient for the tests 1171 tree = ET.fromstring(inputpath) 1172 else: 1173 raise 1174 1175 #Add zero element 1176 element = tree.find('zero') 1177 if element is not None: 1178 for line in element.text.split('\n'): 1179 line = line.split('#',1)[0] 1180 if not line: 1181 continue 1182 lhacode = line.split() 1183 blockname = lhacode.pop(0) 1184 lhacode = [int(code) for code in lhacode ] 1185 self.add_zero(blockname, lhacode, '') 1186 1187 #Add one element 1188 element = tree.find('one') 1189 if element is not None: 1190 for line in element.text.split('\n'): 1191 line = line.split('#',1)[0] 1192 if not line: 1193 continue 1194 lhacode = line.split() 1195 blockname = lhacode.pop(0) 1196 lhacode = [int(code) for code in lhacode ] 1197 self.add_one(blockname, lhacode, '') 1198 1199 #Add Identical element 1200 element = tree.find('identical') 1201 if element is not None: 1202 for line in element.text.split('\n'): 1203 line = line.split('#',1)[0] 1204 if not line: 1205 continue 1206 line, lhacode2 = line.split(':') 1207 lhacode = line.split() 1208 blockname = lhacode.pop(0) 1209 lhacode = [int(code) for code in lhacode ] 1210 lhacode2 = [int(code) for code in lhacode2.split() ] 1211 self.add_identical(blockname, lhacode, lhacode2, '') 1212 1213 #Add Opposite element 1214 element = tree.find('opposite') 1215 if element is not None: 1216 for line in element.text.split('\n'): 1217 line = line.split('#',1)[0] 1218 if not line: 1219 continue 1220 line, lhacode2 = line.split(':') 1221 lhacode = line.split() 1222 blockname = lhacode.pop(0) 1223 lhacode = [int(code) for code in lhacode ] 1224 lhacode2 = [int(code) for code in lhacode2.split() ] 1225 self.add_opposite(blockname, lhacode, lhacode2, '') 1226 1227 #Add Rule element 1228 element = tree.find('rule') 1229 if element is not None: 1230 for line in element.text.split('\n'): 1231 line = line.split('#',1)[0] 1232 if not line: 1233 continue 1234 line, rule = line.split(':') 1235 lhacode = line.split() 1236 blockname = lhacode.pop(0) 1237 self.add_rule(blockname, lhacode, rule, '')
1238 1239 @staticmethod
1240 - def read_param_card(path):
1241 """ read a param_card and return a dictionary with the associated value.""" 1242 1243 output = ParamCard(path) 1244 1245 1246 1247 return output
1248 1249 @staticmethod
1250 - def write_param_card(path, data):
1251 """ read a param_card and return a dictionary with the associated value.""" 1252 1253 output = {} 1254 1255 if isinstance(path, str): 1256 output = open(path, 'w') 1257 else: 1258 output = path # helpfull for the test 1259 1260 data.write(path)
1261 1262
1263 - def check_param_card(self, path, modify=False, write_missing=False, log=False):
1264 """Check that the restriction card are applied""" 1265 1266 is_modified = False 1267 1268 if isinstance(path,str): 1269 card = self.read_param_card(path) 1270 else: 1271 card = path 1272 1273 # check zero 1274 for block, id, comment in self.zero: 1275 try: 1276 value = float(card[block].get(id).value) 1277 except KeyError: 1278 if modify and write_missing: 1279 new_param = Parameter(block=block,lhacode=id, value=0, 1280 comment='fixed by the model') 1281 if block in card: 1282 card[block].append(new_param) 1283 else: 1284 new_block = Block(block) 1285 card.append(new_block) 1286 new_block.append(new_param) 1287 else: 1288 if value != 0: 1289 if not modify: 1290 raise InvalidParamCard('parameter %s: %s is not at zero' % \ 1291 (block, ' '.join([str(i) for i in id]))) 1292 else: 1293 param = card[block].get(id) 1294 param.value = 0.0 1295 param.comment += ' fixed by the model' 1296 is_modified = True 1297 if log ==20: 1298 logger.log(log,'For model consistency, update %s with id %s to value %s', 1299 block, id, 0.0, '$MG:BOLD') 1300 elif log: 1301 logger.log(log,'For model consistency, update %s with id %s to value %s', 1302 block, id, 0.0) 1303 1304 # check one 1305 for block, id, comment in self.one: 1306 try: 1307 value = card[block].get(id).value 1308 except KeyError: 1309 if modify and write_missing: 1310 new_param = Parameter(block=block,lhacode=id, value=1, 1311 comment='fixed by the model') 1312 if block in card: 1313 card[block].append(new_param) 1314 else: 1315 new_block = Block(block) 1316 card.append(new_block) 1317 new_block.append(new_param) 1318 else: 1319 if value != 1: 1320 if not modify: 1321 raise InvalidParamCard('parameter %s: %s is not at one but at %s' % \ 1322 (block, ' '.join([str(i) for i in id]), value)) 1323 else: 1324 param = card[block].get(id) 1325 param.value = 1.0 1326 param.comment += ' fixed by the model' 1327 is_modified = True 1328 if log ==20: 1329 logger.log(log,'For model consistency, update %s with id %s to value %s', 1330 (block, id, 1.0), '$MG:BOLD') 1331 elif log: 1332 logger.log(log,'For model consistency, update %s with id %s to value %s' % 1333 (block, id, 1.0)) 1334 1335 1336 # check identical 1337 for block, id1, id2, comment in self.identical: 1338 if block not in card: 1339 is_modified = True 1340 logger.warning('''Param card is not complete: Block %s is simply missing. 1341 We will use model default for all missing value! Please cross-check that 1342 this correspond to your expectation.''' % block) 1343 continue 1344 value2 = float(card[block].get(id2).value) 1345 try: 1346 param = card[block].get(id1) 1347 except KeyError: 1348 if modify and write_missing: 1349 new_param = Parameter(block=block,lhacode=id1, value=value2, 1350 comment='must be identical to %s' %id2) 1351 card[block].append(new_param) 1352 else: 1353 value1 = float(param.value) 1354 1355 if value1 != value2: 1356 if not modify: 1357 raise InvalidParamCard('parameter %s: %s is not to identical to parameter %s' % \ 1358 (block, ' '.join([str(i) for i in id1]), 1359 ' '.join([str(i) for i in id2]))) 1360 else: 1361 param = card[block].get(id1) 1362 param.value = value2 1363 param.comment += ' must be identical to %s' % id2 1364 is_modified = True 1365 if log ==20: 1366 logger.log(log,'For model consistency, update %s with id %s to value %s since it should be equal to parameter with id %s', 1367 block, id1, value2, id2, '$MG:BOLD') 1368 elif log: 1369 logger.log(log,'For model consistency, update %s with id %s to value %s since it should be equal to parameter with id %s', 1370 block, id1, value2, id2) 1371 # check opposite 1372 for block, id1, id2, comment in self.opposite: 1373 value2 = float(card[block].get(id2).value) 1374 try: 1375 param = card[block].get(id1) 1376 except KeyError: 1377 if modify and write_missing: 1378 new_param = Parameter(block=block,lhacode=id1, value=-value2, 1379 comment='must be opposite to to %s' %id2) 1380 card[block].append(new_param) 1381 else: 1382 value1 = float(param.value) 1383 1384 if value1 != -value2: 1385 if not modify: 1386 raise InvalidParamCard('parameter %s: %s is not to opposite to parameter %s' % \ 1387 (block, ' '.join([str(i) for i in id1]), 1388 ' '.join([str(i) for i in id2]))) 1389 else: 1390 param = card[block].get(id1) 1391 param.value = -value2 1392 param.comment += ' must be opposite to %s' % id2 1393 is_modified = True 1394 if log ==20: 1395 logger.log(log,'For model consistency, update %s with id %s to value %s since it should be equal to the opposite of the parameter with id %s', 1396 block, id1, -value2, id2, '$MG:BOLD') 1397 elif log: 1398 logger.log(log,'For model consistency, update %s with id %s to value %s since it should be equal to the opposite of the parameter with id %s', 1399 block, id1, -value2, id2) 1400 1401 return card, is_modified
1402
1403 1404 -def convert_to_slha1(path, outputpath=None ):
1405 """ """ 1406 1407 if not outputpath: 1408 outputpath = path 1409 card = ParamCard(path) 1410 if not 'usqmix' in card: 1411 #already slha1 1412 card.write(outputpath) 1413 return 1414 1415 # Mass 1416 #card.reorder_mass() # needed? 1417 card.copy_param('mass', [6], 'sminputs', [6]) 1418 card.copy_param('mass', [15], 'sminputs', [7]) 1419 card.copy_param('mass', [23], 'sminputs', [4]) 1420 # Decay: Nothing to do. 1421 1422 # MODSEL 1423 card.add_param('modsel',[1], value=1) 1424 card['modsel'].get([1]).format = 'int' 1425 1426 # find scale 1427 scale = card['hmix'].scale 1428 if not scale: 1429 scale = 1 # Need to be define (this is dummy value) 1430 1431 # SMINPUTS 1432 if not card.has_param('sminputs', [2]): 1433 aem1 = card['sminputs'].get([1]).value 1434 mz = card['mass'].get([23]).value 1435 mw = card['mass'].get([24]).value 1436 gf = math.pi / math.sqrt(2) / aem1 * mz**2/ mw**2 /(mz**2-mw**2) 1437 card.add_param('sminputs', [2], gf, 'G_F [GeV^-2]') 1438 1439 # USQMIX 1440 card.check_and_remove('usqmix', [1,1], 1.0) 1441 card.check_and_remove('usqmix', [2,2], 1.0) 1442 card.check_and_remove('usqmix', [4,4], 1.0) 1443 card.check_and_remove('usqmix', [5,5], 1.0) 1444 card.mod_param('usqmix', [3,3], 'stopmix', [1,1]) 1445 card.mod_param('usqmix', [3,6], 'stopmix', [1,2]) 1446 card.mod_param('usqmix', [6,3], 'stopmix', [2,1]) 1447 card.mod_param('usqmix', [6,6], 'stopmix', [2,2]) 1448 1449 # DSQMIX 1450 card.check_and_remove('dsqmix', [1,1], 1.0) 1451 card.check_and_remove('dsqmix', [2,2], 1.0) 1452 card.check_and_remove('dsqmix', [4,4], 1.0) 1453 card.check_and_remove('dsqmix', [5,5], 1.0) 1454 card.mod_param('dsqmix', [3,3], 'sbotmix', [1,1]) 1455 card.mod_param('dsqmix', [3,6], 'sbotmix', [1,2]) 1456 card.mod_param('dsqmix', [6,3], 'sbotmix', [2,1]) 1457 card.mod_param('dsqmix', [6,6], 'sbotmix', [2,2]) 1458 1459 1460 # SELMIX 1461 card.check_and_remove('selmix', [1,1], 1.0) 1462 card.check_and_remove('selmix', [2,2], 1.0) 1463 card.check_and_remove('selmix', [4,4], 1.0) 1464 card.check_and_remove('selmix', [5,5], 1.0) 1465 card.mod_param('selmix', [3,3], 'staumix', [1,1]) 1466 card.mod_param('selmix', [3,6], 'staumix', [1,2]) 1467 card.mod_param('selmix', [6,3], 'staumix', [2,1]) 1468 card.mod_param('selmix', [6,6], 'staumix', [2,2]) 1469 1470 # FRALPHA 1471 card.mod_param('fralpha', [1], 'alpha', [' ']) 1472 1473 #HMIX 1474 if not card.has_param('hmix', [3]): 1475 aem1 = card['sminputs'].get([1]).value 1476 tanb = card['hmix'].get([2]).value 1477 mz = card['mass'].get([23]).value 1478 mw = card['mass'].get([24]).value 1479 sw = math.sqrt(mz**2 - mw**2)/mz 1480 ee = 2 * math.sqrt(1/aem1) * math.sqrt(math.pi) 1481 vu = 2 * mw *sw /ee * math.sin(math.atan(tanb)) 1482 card.add_param('hmix', [3], vu, 'higgs vev(Q) MSSM DRb') 1483 card['hmix'].scale= scale 1484 1485 # VCKM 1486 card.check_and_remove('vckm', [1,1], 1.0) 1487 card.check_and_remove('vckm', [2,2], 1.0) 1488 card.check_and_remove('vckm', [3,3], 1.0) 1489 1490 #SNUMIX 1491 card.check_and_remove('snumix', [1,1], 1.0) 1492 card.check_and_remove('snumix', [2,2], 1.0) 1493 card.check_and_remove('snumix', [3,3], 1.0) 1494 1495 #UPMNS 1496 card.check_and_remove('upmns', [1,1], 1.0) 1497 card.check_and_remove('upmns', [2,2], 1.0) 1498 card.check_and_remove('upmns', [3,3], 1.0) 1499 1500 # Te 1501 ye = card['ye'].get([3, 3]).value 1502 te = card['te'].get([3, 3]).value 1503 card.mod_param('te', [3,3], 'ae', [3,3], value= te/ye, comment='A_tau(Q) DRbar') 1504 card.add_param('ae', [1,1], 0, 'A_e(Q) DRbar') 1505 card.add_param('ae', [2,2], 0, 'A_mu(Q) DRbar') 1506 card['ae'].scale = scale 1507 card['ye'].scale = scale 1508 1509 # Tu 1510 yu = card['yu'].get([3, 3]).value 1511 tu = card['tu'].get([3, 3]).value 1512 card.mod_param('tu', [3,3], 'au', [3,3], value= tu/yu, comment='A_t(Q) DRbar') 1513 card.add_param('au', [1,1], 0, 'A_u(Q) DRbar') 1514 card.add_param('au', [2,2], 0, 'A_c(Q) DRbar') 1515 card['au'].scale = scale 1516 card['yu'].scale = scale 1517 1518 # Td 1519 yd = card['yd'].get([3, 3]).value 1520 td = card['td'].get([3, 3]).value 1521 if td: 1522 card.mod_param('td', [3,3], 'ad', [3,3], value= td/yd, comment='A_b(Q) DRbar') 1523 else: 1524 card.mod_param('td', [3,3], 'ad', [3,3], value= 0., comment='A_b(Q) DRbar') 1525 card.add_param('ad', [1,1], 0, 'A_d(Q) DRbar') 1526 card.add_param('ad', [2,2], 0, 'A_s(Q) DRbar') 1527 card['ad'].scale = scale 1528 card['yd'].scale = scale 1529 1530 # MSL2 1531 value = card['msl2'].get([1, 1]).value 1532 card.mod_param('msl2', [1,1], 'msoft', [31], math.sqrt(value)) 1533 value = card['msl2'].get([2, 2]).value 1534 card.mod_param('msl2', [2,2], 'msoft', [32], math.sqrt(value)) 1535 value = card['msl2'].get([3, 3]).value 1536 card.mod_param('msl2', [3,3], 'msoft', [33], math.sqrt(value)) 1537 card['msoft'].scale = scale 1538 1539 # MSE2 1540 value = card['mse2'].get([1, 1]).value 1541 card.mod_param('mse2', [1,1], 'msoft', [34], math.sqrt(value)) 1542 value = card['mse2'].get([2, 2]).value 1543 card.mod_param('mse2', [2,2], 'msoft', [35], math.sqrt(value)) 1544 value = card['mse2'].get([3, 3]).value 1545 card.mod_param('mse2', [3,3], 'msoft', [36], math.sqrt(value)) 1546 1547 # MSQ2 1548 value = card['msq2'].get([1, 1]).value 1549 card.mod_param('msq2', [1,1], 'msoft', [41], math.sqrt(value)) 1550 value = card['msq2'].get([2, 2]).value 1551 card.mod_param('msq2', [2,2], 'msoft', [42], math.sqrt(value)) 1552 value = card['msq2'].get([3, 3]).value 1553 card.mod_param('msq2', [3,3], 'msoft', [43], math.sqrt(value)) 1554 1555 # MSU2 1556 value = card['msu2'].get([1, 1]).value 1557 card.mod_param('msu2', [1,1], 'msoft', [44], math.sqrt(value)) 1558 value = card['msu2'].get([2, 2]).value 1559 card.mod_param('msu2', [2,2], 'msoft', [45], math.sqrt(value)) 1560 value = card['msu2'].get([3, 3]).value 1561 card.mod_param('msu2', [3,3], 'msoft', [46], math.sqrt(value)) 1562 1563 # MSD2 1564 value = card['msd2'].get([1, 1]).value 1565 card.mod_param('msd2', [1,1], 'msoft', [47], math.sqrt(value)) 1566 value = card['msd2'].get([2, 2]).value 1567 card.mod_param('msd2', [2,2], 'msoft', [48], math.sqrt(value)) 1568 value = card['msd2'].get([3, 3]).value 1569 card.mod_param('msd2', [3,3], 'msoft', [49], math.sqrt(value)) 1570 1571 1572 1573 ################# 1574 # WRITE OUTPUT 1575 ################# 1576 card.write(outputpath)
1577
1578 1579 1580 -def convert_to_mg5card(path, outputpath=None, writting=True):
1581 """ 1582 """ 1583 1584 if not outputpath: 1585 outputpath = path 1586 card = ParamCard(path) 1587 if 'usqmix' in card: 1588 #already mg5(slha2) format 1589 if outputpath != path and writting: 1590 card.write(outputpath) 1591 return card 1592 1593 1594 # SMINPUTS 1595 card.remove_param('sminputs', [2]) 1596 card.remove_param('sminputs', [4]) 1597 card.remove_param('sminputs', [6]) 1598 card.remove_param('sminputs', [7]) 1599 # Decay: Nothing to do. 1600 1601 # MODSEL 1602 card.remove_param('modsel',[1]) 1603 1604 1605 # USQMIX 1606 card.add_param('usqmix', [1,1], 1.0) 1607 card.add_param('usqmix', [2,2], 1.0) 1608 card.add_param('usqmix', [4,4], 1.0) 1609 card.add_param('usqmix', [5,5], 1.0) 1610 card.mod_param('stopmix', [1,1], 'usqmix', [3,3]) 1611 card.mod_param('stopmix', [1,2], 'usqmix', [3,6]) 1612 card.mod_param('stopmix', [2,1], 'usqmix', [6,3]) 1613 card.mod_param('stopmix', [2,2], 'usqmix', [6,6]) 1614 1615 # DSQMIX 1616 card.add_param('dsqmix', [1,1], 1.0) 1617 card.add_param('dsqmix', [2,2], 1.0) 1618 card.add_param('dsqmix', [4,4], 1.0) 1619 card.add_param('dsqmix', [5,5], 1.0) 1620 card.mod_param('sbotmix', [1,1], 'dsqmix', [3,3]) 1621 card.mod_param('sbotmix', [1,2], 'dsqmix', [3,6]) 1622 card.mod_param('sbotmix', [2,1], 'dsqmix', [6,3]) 1623 card.mod_param('sbotmix', [2,2], 'dsqmix', [6,6]) 1624 1625 1626 # SELMIX 1627 card.add_param('selmix', [1,1], 1.0) 1628 card.add_param('selmix', [2,2], 1.0) 1629 card.add_param('selmix', [4,4], 1.0) 1630 card.add_param('selmix', [5,5], 1.0) 1631 card.mod_param('staumix', [1,1], 'selmix', [3,3]) 1632 card.mod_param('staumix', [1,2], 'selmix', [3,6]) 1633 card.mod_param('staumix', [2,1], 'selmix', [6,3]) 1634 card.mod_param('staumix', [2,2], 'selmix', [6,6]) 1635 1636 # FRALPHA 1637 card.mod_param('alpha', [], 'fralpha', [1]) 1638 1639 #HMIX 1640 card.remove_param('hmix', [3]) 1641 1642 # VCKM 1643 card.add_param('vckm', [1,1], 1.0) 1644 card.add_param('vckm', [2,2], 1.0) 1645 card.add_param('vckm', [3,3], 1.0) 1646 1647 #SNUMIX 1648 card.add_param('snumix', [1,1], 1.0) 1649 card.add_param('snumix', [2,2], 1.0) 1650 card.add_param('snumix', [3,3], 1.0) 1651 1652 #UPMNS 1653 card.add_param('upmns', [1,1], 1.0) 1654 card.add_param('upmns', [2,2], 1.0) 1655 card.add_param('upmns', [3,3], 1.0) 1656 1657 # Te 1658 ye = card['ye'].get([1, 1], default=0).value 1659 ae = card['ae'].get([1, 1], default=0).value 1660 card.mod_param('ae', [1,1], 'te', [1,1], value= ae * ye, comment='T_e(Q) DRbar') 1661 if ae * ye: 1662 raise InvalidParamCard('''This card is not suitable to be converted to MSSM UFO model 1663 Parameter ae [1, 1] times ye [1,1] should be 0''') 1664 card.remove_param('ae', [1,1]) 1665 #2 1666 ye = card['ye'].get([2, 2], default=0).value 1667 1668 ae = card['ae'].get([2, 2], default=0).value 1669 card.mod_param('ae', [2,2], 'te', [2,2], value= ae * ye, comment='T_mu(Q) DRbar') 1670 if ae * ye: 1671 raise InvalidParamCard('''This card is not suitable to be converted to MSSM UFO model 1672 Parameter ae [2, 2] times ye [2,2] should be 0''') 1673 card.remove_param('ae', [2,2]) 1674 #3 1675 ye = card['ye'].get([3, 3], default=0).value 1676 ae = card['ae'].get([3, 3], default=0).value 1677 card.mod_param('ae', [3,3], 'te', [3,3], value= ae * ye, comment='T_tau(Q) DRbar') 1678 1679 # Tu 1680 yu = card['yu'].get([1, 1], default=0).value 1681 au = card['au'].get([1, 1], default=0).value 1682 card.mod_param('au', [1,1], 'tu', [1,1], value= au * yu, comment='T_u(Q) DRbar') 1683 if au * yu: 1684 raise InvalidParamCard('''This card is not suitable to be converted to MSSM UFO model 1685 Parameter au [1, 1] times yu [1,1] should be 0''') 1686 card.remove_param('au', [1,1]) 1687 #2 1688 ye = card['yu'].get([2, 2], default=0).value 1689 1690 ae = card['au'].get([2, 2], default=0).value 1691 card.mod_param('au', [2,2], 'tu', [2,2], value= au * yu, comment='T_c(Q) DRbar') 1692 if au * yu: 1693 raise InvalidParamCard('''This card is not suitable to be converted to MSSM UFO model 1694 Parameter au [2, 2] times yu [2,2] should be 0''') 1695 card.remove_param('au', [2,2]) 1696 #3 1697 yu = card['yu'].get([3, 3]).value 1698 au = card['au'].get([3, 3]).value 1699 card.mod_param('au', [3,3], 'tu', [3,3], value= au * yu, comment='T_t(Q) DRbar') 1700 1701 # Td 1702 yd = card['yd'].get([1, 1], default=0).value 1703 ad = card['ad'].get([1, 1], default=0).value 1704 card.mod_param('ad', [1,1], 'td', [1,1], value= ad * yd, comment='T_d(Q) DRbar') 1705 if ad * yd: 1706 raise InvalidParamCard('''This card is not suitable to be converted to MSSM UFO model 1707 Parameter ad [1, 1] times yd [1,1] should be 0''') 1708 card.remove_param('ad', [1,1]) 1709 #2 1710 ye = card['yd'].get([2, 2], default=0).value 1711 1712 ae = card['ad'].get([2, 2], default=0).value 1713 card.mod_param('ad', [2,2], 'td', [2,2], value= ad * yd, comment='T_s(Q) DRbar') 1714 if ad * yd: 1715 raise InvalidParamCard('''This card is not suitable to be converted to MSSM UFO model 1716 Parameter ad [2, 2] times yd [2,2] should be 0''') 1717 card.remove_param('ad', [2,2]) 1718 #3 1719 yd = card['yd'].get([3, 3]).value 1720 ad = card['ad'].get([3, 3]).value 1721 card.mod_param('ad', [3,3], 'td', [3,3], value= ad * yd, comment='T_b(Q) DRbar') 1722 1723 1724 # MSL2 1725 value = card['msoft'].get([31]).value 1726 card.mod_param('msoft', [31], 'msl2', [1,1], value**2) 1727 value = card['msoft'].get([32]).value 1728 card.mod_param('msoft', [32], 'msl2', [2,2], value**2) 1729 value = card['msoft'].get([33]).value 1730 card.mod_param('msoft', [33], 'msl2', [3,3], value**2) 1731 1732 # MSE2 1733 value = card['msoft'].get([34]).value 1734 card.mod_param('msoft', [34], 'mse2', [1,1], value**2) 1735 value = card['msoft'].get([35]).value 1736 card.mod_param('msoft', [35], 'mse2', [2,2], value**2) 1737 value = card['msoft'].get([36]).value 1738 card.mod_param('msoft', [36], 'mse2', [3,3], value**2) 1739 1740 # MSQ2 1741 value = card['msoft'].get([41]).value 1742 card.mod_param('msoft', [41], 'msq2', [1,1], value**2) 1743 value = card['msoft'].get([42]).value 1744 card.mod_param('msoft', [42], 'msq2', [2,2], value**2) 1745 value = card['msoft'].get([43]).value 1746 card.mod_param('msoft', [43], 'msq2', [3,3], value**2) 1747 1748 # MSU2 1749 value = card['msoft'].get([44]).value 1750 card.mod_param('msoft', [44], 'msu2', [1,1], value**2) 1751 value = card['msoft'].get([45]).value 1752 card.mod_param('msoft', [45], 'msu2', [2,2], value**2) 1753 value = card['msoft'].get([46]).value 1754 card.mod_param('msoft', [46], 'msu2', [3,3], value**2) 1755 1756 # MSD2 1757 value = card['msoft'].get([47]).value 1758 card.mod_param('msoft', [47], 'msd2', [1,1], value**2) 1759 value = card['msoft'].get([48]).value 1760 card.mod_param('msoft', [48], 'msd2', [2,2], value**2) 1761 value = card['msoft'].get([49]).value 1762 card.mod_param('msoft', [49], 'msd2', [3,3], value**2) 1763 1764 ################# 1765 # WRITE OUTPUT 1766 ################# 1767 if writting: 1768 card.write(outputpath) 1769 return card
1770
1771 1772 -def make_valid_param_card(path, restrictpath, outputpath=None):
1773 """ modify the current param_card such that it agrees with the restriction""" 1774 1775 if not outputpath: 1776 outputpath = path 1777 1778 cardrule = ParamCardRule() 1779 cardrule.load_rule(restrictpath) 1780 try : 1781 cardrule.check_param_card(path, modify=False) 1782 except InvalidParamCard: 1783 new_data, was_modified = cardrule.check_param_card(path, modify=True, write_missing=True) 1784 if was_modified: 1785 cardrule.write_param_card(outputpath, new_data) 1786 else: 1787 if path != outputpath: 1788 shutil.copy(path, outputpath) 1789 return cardrule
1790
1791 -def check_valid_param_card(path, restrictpath=None):
1792 """ check if the current param_card agrees with the restriction""" 1793 1794 if restrictpath is None: 1795 restrictpath = os.path.dirname(path) 1796 restrictpath = os.path.join(restrictpath, os.pardir, os.pardir, 'Source', 1797 'MODEL', 'param_card_rule.dat') 1798 if not os.path.exists(restrictpath): 1799 restrictpath = os.path.dirname(path) 1800 restrictpath = os.path.join(restrictpath, os.pardir, 'Source', 1801 'MODEL', 'param_card_rule.dat') 1802 if not os.path.exists(restrictpath): 1803 return True 1804 1805 cardrule = ParamCardRule() 1806 cardrule.load_rule(restrictpath) 1807 cardrule.check_param_card(path, modify=False)
1808 1809 1810 1811 if '__main__' == __name__: 1812 1813 1814 #make_valid_param_card('./Cards/param_card.dat', './Source/MODEL/param_card_rule.dat', 1815 # outputpath='tmp1.dat') 1816 import sys 1817 args = sys.argv 1818 sys.path.append(os.path.dirname(__file__)) 1819 convert_to_slha1(args[1] , args[2]) 1820