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