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