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