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
12 logger = logging.getLogger('madgraph.models')
13
14 try:
15 import madgraph.iolibs.file_writers as file_writers
16 import madgraph.various.misc as misc
17 except:
18 import internal.file_writers as file_writers
19 import internal.misc as misc
20
21 import StringIO
24 """ a class for invalid param_card """
25 pass
26
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
50 """ set the block name """
51
52 self.lhablock = block
53
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
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
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
108 """ return a SLAH string """
109
110 format = self.format
111 if self.format == 'float':
112 try:
113 value = float(self.value)
114 except:
115 format = 'str'
116
117 if format == 'float':
118 if self.lhablock == 'decay' and not isinstance(self.value,basestring):
119 return 'DECAY %s %e # %s' % (' '.join([str(d) for d in self.lhacode]), self.value, self.comment)
120 elif self.lhablock == 'decay':
121 return 'DECAY %s Auto # %s' % (' '.join([str(d) for d in self.lhacode]), self.comment)
122 elif self.lhablock and self.lhablock.startswith('qnumbers'):
123 return ' %s %i # %s' % (' '.join([str(d) for d in self.lhacode]), int(self.value), self.comment)
124 else:
125 return ' %s %e # %s' % (' '.join([str(d) for d in self.lhacode]), self.value, self.comment)
126 elif format == 'int':
127 return ' %s %i # %s' % (' '.join([str(d) for d in self.lhacode]), int(self.value), self.comment)
128 elif format == 'str':
129 if self.lhablock == 'decay':
130 return 'DECAY %s %s # %s' % (' '.join([str(d) for d in self.lhacode]),self.value, self.comment)
131 return ' %s %s # %s' % (' '.join([str(d) for d in self.lhacode]), self.value, self.comment)
132 elif self.format == 'decay_table':
133 return ' %e %s # %s' % ( self.value,' '.join([str(d) for d in self.lhacode]), self.comment)
134 elif self.format == 'int':
135 return ' %s %i # %s' % (' '.join([str(d) for d in self.lhacode]), int(self.value), self.comment)
136 else:
137 if self.lhablock == 'decay':
138 return 'DECAY %s %d # %s' % (' '.join([str(d) for d in self.lhacode]), self.value, self.comment)
139 else:
140 return ' %s %d # %s' % (' '.join([str(d) for d in self.lhacode]), self.value, self.comment)
141
144 """ list of parameter """
145
147 if name:
148 self.name = name.lower()
149 else:
150 self.name = name
151 self.scale = None
152 self.comment = ''
153 self.decay_table = {}
154 self.param_dict={}
155 list.__init__(self)
156
157 - def get(self, lhacode, default=None):
158 """return the parameter associate to the lhacode"""
159 if not self.param_dict:
160 self.create_param_dict()
161
162 if isinstance(lhacode, int):
163 lhacode = (lhacode,)
164
165 try:
166 return self.param_dict[tuple(lhacode)]
167 except KeyError:
168 if default is None:
169 raise KeyError, 'id %s is not in %s' % (tuple(lhacode), self.name)
170 else:
171 return Parameter(block=self, lhacode=lhacode, value=default,
172 comment='not define')
173
175 """ remove a parameter """
176 list.remove(self, self.get(lhacode))
177
178 return self.param_dict.pop(tuple(lhacode))
179
180 - def __eq__(self, other, prec=1e-4):
181 """ """
182 if len(self) != len(other):
183 return False
184
185 return not any(abs(param.value-other.param_dict[key].value)> prec * abs(param.value)
186 for key, param in self.param_dict.items())
187
188 - def __ne__(self, other, prec=1e-4):
189 return not self.__eq__(other, prec)
190
192
193 assert isinstance(obj, Parameter)
194 if not hasattr(self, 'name'):
195 self.__init__(obj.lhablock)
196 assert not obj.lhablock or obj.lhablock == self.name
197
198
199
200 if not hasattr(self, 'param_dict'):
201 self.param_dict = {}
202
203 if tuple(obj.lhacode) in self.param_dict:
204 if self.param_dict[tuple(obj.lhacode)].value != obj.value:
205 raise InvalidParamCard, '%s %s is already define to %s impossible to assign %s' % \
206 (self.name, obj.lhacode, self.param_dict[tuple(obj.lhacode)].value, obj.value)
207 return
208 list.append(self, obj)
209
210 self.param_dict[tuple(obj.lhacode)] = obj
211
213 """create a link between the lhacode and the Parameter"""
214 for param in self:
215 self.param_dict[tuple(param.lhacode)] = param
216
217 return self.param_dict
218
220 """ """
221 self.scale = scale
222
224 "set inforamtion from the line"
225
226 if '#' in text:
227 data, self.comment = text.split('#',1)
228 else:
229 data, self.commant = text, ""
230
231 data = data.lower()
232 data = data.split()
233 self.name = data[1]
234 if len(data) == 3:
235 if data[2].startswith('q='):
236
237 self.scale = float(data[2][2:])
238 elif self.name == 'qnumbers':
239 self.name += ' %s' % data[2]
240 elif len(data) == 4 and data[2] == 'q=':
241
242 self.scale = float(data[3])
243
244 return self
245
247 """returns the list of id define in this blocks"""
248
249 return [p.lhacode for p in self]
250
252 """ return a str in the SLAH format """
253
254 text = """###################################""" + \
255 """\n## INFORMATION FOR %s""" % self.name.upper() +\
256 """\n###################################\n"""
257
258
259 if self.name == 'decay':
260 for param in self:
261 pid = param.lhacode[0]
262 param.set_block('decay')
263 text += str(param)+ '\n'
264 if self.decay_table.has_key(pid):
265 text += str(self.decay_table[pid])+'\n'
266 return text
267 elif self.name.startswith('decay'):
268 text = ''
269
270 elif not self.scale:
271 text += 'BLOCK %s # %s\n' % (self.name.upper(), self.comment)
272 else:
273 text += 'BLOCK %s Q= %e # %s\n' % (self.name.upper(), self.scale, self.comment)
274
275 text += '\n'.join([str(param) for param in self])
276 return text + '\n'
277
280 """ a param Card: list of Block """
281 mp_prefix = 'MP__'
282
283 header = \
284 """######################################################################\n""" + \
285 """## PARAM_CARD AUTOMATICALY GENERATED BY MG5 ####\n""" + \
286 """######################################################################\n"""
287
288
290 self.order = []
291
292 if isinstance(input_path, ParamCard):
293 self.read(input_path.write())
294 self.input_path = input_path.input_path
295 else:
296 self.input_path = input_path
297 if input_path:
298 self.read(input_path)
299
300 - def read(self, input_path):
301 """ read a card and full this object with the content of the card """
302
303 if isinstance(input_path, str):
304 if '\n' in input_path:
305 input = StringIO.StringIO(input_path)
306 else:
307 input = open(input_path)
308 else:
309 input = input_path
310
311
312 cur_block = None
313 for line in input:
314 line = line.strip()
315 if not line or line[0] == '#':
316 continue
317 line = line.lower()
318 if line.startswith('block'):
319 cur_block = Block()
320 cur_block.load_str(line)
321 self.append(cur_block)
322 continue
323
324 if line.startswith('decay'):
325 if not self.has_block('decay'):
326 cur_block = Block('decay')
327 self.append(cur_block)
328 else:
329 cur_block = self['decay']
330 param = Parameter()
331 param.set_block(cur_block.name)
332 param.load_str(line[6:])
333 cur_block.append(param)
334 continue
335
336 if cur_block is None:
337 continue
338
339 if cur_block.name == 'decay':
340
341 id = cur_block[-1].lhacode[0]
342 cur_block = Block('decay_table_%s' % id)
343 self['decay'].decay_table[id] = cur_block
344
345
346
347
348 if cur_block.name.startswith('decay_table'):
349 param = Parameter()
350 param.load_decay(line)
351 try:
352 cur_block.append(param)
353 except InvalidParamCard:
354 pass
355 else:
356 param = Parameter()
357 param.set_block(cur_block.name)
358 param.load_str(line)
359 cur_block.append(param)
360
361 return self
362
364 """ Analyzes the comment of the parameter in the param_card and returns
365 a dictionary with parameter names in values and the tuple (lhablock, id)
366 in value as well as a dictionary for restricted values.
367 WARNING: THIS FUNCTION RELIES ON THE FORMATTING OF THE COMMENT IN THE
368 CARD TO FETCH THE PARAMETER NAME. This is mostly ok on the *_default.dat
369 but typically dangerous on the user-defined card."""
370
371 pname2block = {}
372 restricted_value = {}
373
374 for bname, block in self.items():
375 for lha_id, param in block.param_dict.items():
376 all_var = []
377 comment = param.comment
378
379 if comment.strip().startswith('set of param :'):
380 all_var = list(re.findall(r'''[^-]1\*(\w*)\b''', comment))
381
382 elif len(comment.split()) == 1:
383 all_var = [comment.strip().lower()]
384
385 else:
386 split = comment.split()
387 if len(split) >2 and split[1] == ':':
388
389 restricted_value[(bname, lha_id)] = ' '.join(split[1:])
390 elif len(split) == 2:
391 if re.search(r'''\[[A-Z]\]eV\^''', split[1]):
392 all_var = [comment.strip().lower()]
393 elif len(split) >=2 and split[1].startswith('('):
394 all_var = [split[0].strip().lower()]
395 else:
396 if not bname.startswith('qnumbers'):
397 logger.debug("not recognize information for %s %s : %s",
398 bname, lha_id, comment)
399
400 continue
401
402 for var in all_var:
403 var = var.lower()
404 if var in pname2block:
405 pname2block[var].append((bname, lha_id))
406 else:
407 pname2block[var] = [(bname, lha_id)]
408
409 return pname2block, restricted_value
410
411 - def write(self, outpath=None):
412 """schedular for writing a card"""
413
414
415 blocks = self.order_block()
416 text = self.header
417 text += ''.join([str(block) for block in blocks])
418
419 if not outpath:
420 return text
421 elif isinstance(outpath, str):
422 file(outpath,'w').write(text)
423 else:
424 outpath.write(text)
425
427 """return a text file allowing to pass from this card to the new one
428 via the set command"""
429
430 diff = ''
431 for blockname, block in self.items():
432 for param in block:
433 lhacode = param.lhacode
434 value = param.value
435 new_value = new_card[blockname].get(lhacode).value
436 if not misc.equal(value, new_value, 6, zero_limit=False):
437 lhacode = ' '.join([str(i) for i in lhacode])
438 diff += 'set param_card %s %s %s # orig: %s\n' % \
439 (blockname, lhacode , new_value, value)
440 return diff
441
442
443 - def write_inc_file(self, outpath, identpath, default, need_mp=False):
444 """ write a fortran file which hardcode the param value"""
445
446 fout = file_writers.FortranWriter(outpath)
447 defaultcard = ParamCard(default)
448 for line in open(identpath):
449 if line.startswith('c ') or line.startswith('ccccc'):
450 continue
451 split = line.split()
452 if len(split) < 3:
453 continue
454 block = split[0]
455 lhaid = [int(i) for i in split[1:-1]]
456 variable = split[-1]
457 if block in self:
458 try:
459 value = self[block].get(tuple(lhaid)).value
460 except KeyError:
461 value =defaultcard[block].get(tuple(lhaid)).value
462 logger.warning('information about \"%s %s" is missing using default value: %s.' %\
463 (block, lhaid, value))
464 else:
465 value =defaultcard[block].get(tuple(lhaid)).value
466 logger.warning('information about \"%s %s" is missing (full block missing) using default value: %s.' %\
467 (block, lhaid, value))
468 value = str(value).lower()
469 fout.writelines(' %s = %s' % (variable, ('%e'%float(value)).replace('e','d')))
470 if need_mp:
471 fout.writelines(' mp__%s = %s_16' % (variable, value))
472
474 """ Convert this param_card to the convention used for the complex mass scheme:
475 This includes, removing the Yukawa block if present and making sure the EW input
476 scheme is (MZ, MW, aewm1). """
477
478
479 if self.has_block('yukawa'):
480
481 for lhacode in [param.lhacode for param in self['yukawa']]:
482 self.remove_param('yukawa', lhacode)
483
484
485 EW_input = {('sminputs',(1,)):None,
486 ('sminputs',(2,)):None,
487 ('mass',(23,)):None,
488 ('mass',(24,)):None}
489 for block, lhaid in EW_input.keys():
490 try:
491 EW_input[(block,lhaid)] = self[block].get(lhaid).value
492 except:
493 pass
494
495
496
497
498 internal_param = [key for key,value in EW_input.items() if value is None]
499 if len(internal_param)==0:
500
501 return
502
503 if len(internal_param)!=1:
504 raise InvalidParamCard,' The specified EW inputs has more than one'+\
505 ' unknown: [%s]'%(','.join([str(elem) for elem in internal_param]))
506
507
508 if not internal_param[0] in [('mass',(24,)), ('sminputs',(2,)),
509 ('sminputs',(1,))]:
510 raise InvalidParamCard, ' The only EW input scheme currently supported'+\
511 ' are those with either the W mass or GF left internal.'
512
513
514 if internal_param[0] == ('mass',(24,)):
515 aewm1 = EW_input[('sminputs',(1,))]
516 Gf = EW_input[('sminputs',(2,))]
517 Mz = EW_input[('mass',(23,))]
518 try:
519 Mw = math.sqrt((Mz**2/2.0)+math.sqrt((Mz**4/4.0)-((
520 (1.0/aewm1)*math.pi*Mz**2)/(Gf*math.sqrt(2.0)))))
521 except:
522 InvalidParamCard, 'The EW inputs 1/a_ew=%f, Gf=%f, Mz=%f are inconsistent'%\
523 (aewm1,Gf,Mz)
524 self.remove_param('sminputs', (2,))
525 self.add_param('mass', (24,), Mw, 'MW')
526
528 """add an object to this"""
529
530 assert isinstance(obj, Block)
531 self[obj.name] = obj
532 if not obj.name.startswith('decay_table'):
533 self.order.append(obj)
534
535
536
538 return self.has_key(name)
539
541 """ reorganize the block """
542 return self.order
543
545 """ rename the blocks """
546
547 for old_name, new_name in name_dict.items():
548 self[new_name] = self.pop(old_name)
549 self[new_name].name = new_name
550 for param in self[new_name]:
551 param.lhablock = new_name
552
554 """ remove a blocks """
555 assert len(self[name])==0
556 [self.order.pop(i) for i,b in enumerate(self.order) if b.name == name]
557 self.pop(name)
558
560 """ remove a parameter """
561 if self.has_param(block, lhacode):
562 self[block].remove(lhacode)
563 if len(self[block]) == 0:
564 self.remove_block(block)
565
567 """check if param exists"""
568
569 try:
570 self[block].get(lhacode)
571 except:
572 return False
573 else:
574 return True
575
576 - def copy_param(self,old_block, old_lha, block=None, lhacode=None):
577 """ make a parameter, a symbolic link on another one """
578
579
580 old_block_obj = self[old_block]
581 parameter = old_block_obj.get(old_lha)
582 if not block:
583 block = old_block
584 if not lhacode:
585 lhacode = old_lha
586
587 self.add_param(block, lhacode, parameter.value, parameter.comment)
588
589 - def add_param(self,block, lha, value, comment=''):
590
591 parameter = Parameter(block=block, lhacode=lha, value=value,
592 comment=comment)
593 try:
594 new_block = self[block]
595 except KeyError:
596
597 new_block = Block(block)
598 self.append(new_block)
599 new_block.append(parameter)
600
601
602 - def mod_param(self, old_block, old_lha, block=None, lhacode=None,
603 value=None, comment=None):
604 """ change a parameter to a new one. This is not a duplication."""
605
606
607 old_block = self[old_block]
608 try:
609 parameter = old_block.get(old_lha)
610 except:
611 if lhacode is not None:
612 lhacode=old_lha
613 self.add_param(block, lhacode, value, comment)
614 return
615
616
617
618 if block:
619 parameter.lhablock = block
620 if lhacode:
621 parameter.lhacode = lhacode
622 if value:
623 parameter.value = value
624 if comment:
625 parameter.comment = comment
626
627
628 if block:
629 old_block.remove(old_lha)
630 if not len(old_block):
631 self.remove_block(old_block.name)
632 try:
633 new_block = self[block]
634 except KeyError:
635
636 new_block = Block(block)
637 self.append(new_block)
638 new_block.append(parameter)
639 elif lhacode:
640 old_block.param_dict[tuple(lhacode)] = \
641 old_block.param_dict.pop(tuple(old_lha))
642
643
645 """ check that the value is coherent and remove it"""
646
647 if self.has_param(block, lhacode):
648 param = self[block].get(lhacode)
649 if param.value != value:
650 error_msg = 'This card is not suitable to be convert to SLAH1\n'
651 error_msg += 'Parameter %s %s should be %s' % (block, lhacode, value)
652 raise InvalidParamCard, error_msg
653 self.remove_param(block, lhacode)
654
657 """ a param Card: list of Block with also MP definition of variables"""
658
660 """ write a fortran file which hardcode the param value"""
661
662 fout = file_writers.FortranWriter(outpath)
663 defaultcard = ParamCard(default)
664 for line in open(identpath):
665 if line.startswith('c ') or line.startswith('ccccc'):
666 continue
667 split = line.split()
668 if len(split) < 3:
669 continue
670 block = split[0]
671 lhaid = [int(i) for i in split[1:-1]]
672 variable = split[-1]
673 if block in self:
674 try:
675 value = self[block].get(tuple(lhaid)).value
676 except KeyError:
677 value =defaultcard[block].get(tuple(lhaid)).value
678 else:
679 value =defaultcard[block].get(tuple(lhaid)).value
680
681 fout.writelines(' %s = %s' % (variable, ('%e' % value).replace('e','d')))
682 fout.writelines(' %s%s = %s_16' % (self.mp_prefix,
683 variable, ('%e' % value)))
684
688 """A class keeping track of the scan: flag in the param_card and
689 having an __iter__() function to scan over all the points of the scan.
690 """
691
692 logging = True
698
700 """generate the next param_card (in a abstract way) related to the scan.
701 Technically this generates only the generator."""
702
703 if hasattr(self, 'iterator'):
704 return self.iterator
705 self.iterator = self.iterate()
706 return self.iterator
707
708 - def next(self, autostart=False):
709 """call the next iteration value"""
710 try:
711 iterator = self.iterator
712 except:
713 if autostart:
714 iterator = self.__iter__()
715 else:
716 raise
717 try:
718 out = iterator.next()
719 except StopIteration:
720 del self.iterator
721 raise
722 return out
723
725 """create the actual generator"""
726 all_iterators = {}
727 auto = 'Auto'
728 pattern = re.compile(r'''scan\s*(?P<id>\d*)\s*:\s*(?P<value>[^#]*)''', re.I)
729
730
731 for block in self.order:
732 for param in block:
733 if isinstance(param.value, str) and param.value.strip().lower().startswith('scan'):
734 try:
735 key, def_list = pattern.findall(param.value)[0]
736 except:
737 raise Exception, "Fail to handle scanning tag: Please check that the syntax is valid"
738 if key == '':
739 key = -1 * len(all_iterators)
740 if key not in all_iterators:
741 all_iterators[key] = []
742 try:
743 all_iterators[key].append( (param, eval(def_list)))
744 except SyntaxError:
745 raise Exception, "Fail to handle your scan definition. Please check your syntax."
746
747 keys = all_iterators.keys()
748 param_card = ParamCard(self)
749
750 for key in keys:
751 for param, values in all_iterators[key]:
752 self.param_order.append("%s#%s" % (param.lhablock, '_'.join(`i` for i in param.lhacode)))
753
754
755 lengths = [range(len(all_iterators[key][0][1])) for key in keys]
756 for positions in itertools.product(*lengths):
757 self.itertag = []
758 if self.logging:
759 logger.info("Create the next param_card in the scan definition", '$MG:color:BLACK')
760 for i, pos in enumerate(positions):
761 key = keys[i]
762 for param, values in all_iterators[key]:
763
764 param_card[param.lhablock].get(param.lhacode).value = values[pos]
765 self.itertag.append(values[pos])
766 if self.logging:
767 logger.info("change parameter %s with code %s to %s", \
768 param.lhablock, param.lhacode, values[pos])
769
770 yield param_card
771
772
773 - def store_entry(self, run_name, cross):
774 """store the value of the cross-section"""
775 self.cross.append({'bench' : self.itertag, 'run_name': run_name, 'cross':cross})
776
777
779 """ """
780
781 ff = open(path, 'w')
782 ff.write("#%-19s %-20s %-20s\n" % ('run_name',' '.join(self.param_order), 'cross(pb)'))
783 for info in self.cross:
784 bench = [str(p) for p in info['bench']]
785 cross = info['cross']
786 name = info['run_name']
787 ff.write("%-20s %-20s %-20s \n" % (name,' '.join(bench) ,cross))
788
792 """ A class for storing the linked between the different parameter of
793 the param_card.
794 Able to write a file 'param_card_rule.dat'
795 Able to read a file 'param_card_rule.dat'
796 Able to check the validity of a param_card.dat
797 """
798
799
801 """initialize an object """
802
803
804 self.zero = []
805 self.one = []
806 self.identical = []
807 self.opposite = []
808
809
810 self.rule = []
811
812 if inputpath:
813 self.load_rule(inputpath)
814
815 - def add_zero(self, lhablock, lhacode, comment=''):
816 """add a zero rule"""
817 self.zero.append( (lhablock, lhacode, comment) )
818
819 - def add_one(self, lhablock, lhacode, comment=''):
820 """add a one rule"""
821 self.one.append( (lhablock, lhacode, comment) )
822
823 - def add_identical(self, lhablock, lhacode, lhacode2, comment=''):
824 """add a rule for identical value"""
825 self.identical.append( (lhablock, lhacode, lhacode2, comment) )
826
827 - def add_opposite(self, lhablock, lhacode, lhacode2, comment=''):
828 """add a rule for identical value"""
829 self.opposite.append( (lhablock, lhacode, lhacode2, comment) )
830
831
832 - def add_rule(self, lhablock, lhacode, rule, comment=''):
833 """add a rule for constraint value"""
834 self.rule.append( (lhablock, lhacode, rule) )
835
837
838 text = """<file>######################################################################
839 ## VALIDITY RULE FOR THE PARAM_CARD ####
840 ######################################################################\n"""
841
842
843 text +='<zero>\n'
844 for name, id, comment in self.zero:
845 text+=' %s %s # %s\n' % (name, ' '.join([str(i) for i in id]),
846 comment)
847
848 text +='</zero>\n<one>\n'
849 for name, id, comment in self.one:
850 text+=' %s %s # %s\n' % (name, ' '.join([str(i) for i in id]),
851 comment)
852
853 text +='</one>\n<identical>\n'
854 for name, id,id2, comment in self.identical:
855 text+=' %s %s : %s # %s\n' % (name, ' '.join([str(i) for i in id]),
856 ' '.join([str(i) for i in id2]), comment)
857
858
859 text +='</identical>\n<opposite>\n'
860 for name, id,id2, comment in self.opposite:
861 text+=' %s %s : %s # %s\n' % (name, ' '.join([str(i) for i in id]),
862 ' '.join([str(i) for i in id2]), comment)
863
864
865 text += '</opposite>\n<constraint>\n'
866 for name, id, rule, comment in self.rule:
867 text += ' %s %s : %s # %s\n' % (name, ' '.join([str(i) for i in id]),
868 rule, comment)
869 text += '</constraint>\n</file>'
870
871 if isinstance(output, str):
872 output = open(output,'w')
873 if hasattr(output, 'write'):
874 output.write(text)
875 return text
876
878 """ import a validity rule file """
879
880
881 try:
882 tree = ET.parse(inputpath)
883 except IOError:
884 if '\n' in inputpath:
885
886 tree = ET.fromstring(inputpath)
887 else:
888 raise
889
890
891 element = tree.find('zero')
892 if element is not None:
893 for line in element.text.split('\n'):
894 line = line.split('#',1)[0]
895 if not line:
896 continue
897 lhacode = line.split()
898 blockname = lhacode.pop(0)
899 lhacode = [int(code) for code in lhacode ]
900 self.add_zero(blockname, lhacode, '')
901
902
903 element = tree.find('one')
904 if element is not None:
905 for line in element.text.split('\n'):
906 line = line.split('#',1)[0]
907 if not line:
908 continue
909 lhacode = line.split()
910 blockname = lhacode.pop(0)
911 lhacode = [int(code) for code in lhacode ]
912 self.add_one(blockname, lhacode, '')
913
914
915 element = tree.find('identical')
916 if element is not None:
917 for line in element.text.split('\n'):
918 line = line.split('#',1)[0]
919 if not line:
920 continue
921 line, lhacode2 = line.split(':')
922 lhacode = line.split()
923 blockname = lhacode.pop(0)
924 lhacode = [int(code) for code in lhacode ]
925 lhacode2 = [int(code) for code in lhacode2.split() ]
926 self.add_identical(blockname, lhacode, lhacode2, '')
927
928
929 element = tree.find('opposite')
930 if element is not None:
931 for line in element.text.split('\n'):
932 line = line.split('#',1)[0]
933 if not line:
934 continue
935 line, lhacode2 = line.split(':')
936 lhacode = line.split()
937 blockname = lhacode.pop(0)
938 lhacode = [int(code) for code in lhacode ]
939 lhacode2 = [int(code) for code in lhacode2.split() ]
940 self.add_opposite(blockname, lhacode, lhacode2, '')
941
942
943 element = tree.find('rule')
944 if element is not None:
945 for line in element.text.split('\n'):
946 line = line.split('#',1)[0]
947 if not line:
948 continue
949 line, rule = line.split(':')
950 lhacode = line.split()
951 blockname = lhacode.pop(0)
952 self.add_rule(blockname, lhacode, rule, '')
953
954 @staticmethod
956 """ read a param_card and return a dictionary with the associated value."""
957
958 output = ParamCard(path)
959
960
961
962 return output
963
964 @staticmethod
966 """ read a param_card and return a dictionary with the associated value."""
967
968 output = {}
969
970 if isinstance(path, str):
971 output = open(path, 'w')
972 else:
973 output = path
974
975 data.write(path)
976
977
979 """Check that the restriction card are applied"""
980
981 card = self.read_param_card(path)
982
983
984 for block, id, comment in self.zero:
985 try:
986 value = float(card[block].get(id).value)
987 except KeyError:
988 if modify:
989 new_param = Parameter(block=block,lhacode=id, value=0,
990 comment='fixed by the model')
991 if block in card:
992 card[block].append(new_param)
993 else:
994 new_block = Block(block)
995 card.append(new_block)
996 new_block.append(new_param)
997 else:
998 if value != 0:
999 if not modify:
1000 raise InvalidParamCard, 'parameter %s: %s is not at zero' % \
1001 (block, ' '.join([str(i) for i in id]))
1002 else:
1003 param = card[block].get(id)
1004 param.value = 0.0
1005 param.comment += ' fixed by the model'
1006
1007
1008 for block, id, comment in self.one:
1009 try:
1010 value = card[block].get(id).value
1011 except KeyError:
1012 if modify:
1013 new_param = Parameter(block=block,lhacode=id, value=1,
1014 comment='fixed by the model')
1015 if block in card:
1016 card[block].append(new_param)
1017 else:
1018 new_block = Block(block)
1019 card.append(new_block)
1020 new_block.append(new_param)
1021 else:
1022 if value != 1:
1023 if not modify:
1024 raise InvalidParamCard, 'parameter %s: %s is not at one but at %s' % \
1025 (block, ' '.join([str(i) for i in id]), value)
1026 else:
1027 param = card[block].get(id)
1028 param.value = 1.0
1029 param.comment += ' fixed by the model'
1030
1031
1032
1033 for block, id1, id2, comment in self.identical:
1034 if block not in card:
1035 logger.warning('''Param card is not complete: Block %s is simply missing.
1036 We will use model default for all missing value! Please cross-check that
1037 this correspond to your expectation.''' % block)
1038 continue
1039 value2 = float(card[block].get(id2).value)
1040 try:
1041 param = card[block].get(id1)
1042 except KeyError:
1043 if modify:
1044 new_param = Parameter(block=block,lhacode=id1, value=value2,
1045 comment='must be identical to %s' %id2)
1046 card[block].append(new_param)
1047 else:
1048 value1 = float(param.value)
1049
1050 if value1 != value2:
1051 if not modify:
1052 raise InvalidParamCard, 'parameter %s: %s is not to identical to parameter %s' % \
1053 (block, ' '.join([str(i) for i in id1]),
1054 ' '.join([str(i) for i in id2]))
1055 else:
1056 param = card[block].get(id1)
1057 param.value = value2
1058 param.comment += ' must be identical to %s' % id2
1059
1060
1061 for block, id1, id2, comment in self.opposite:
1062 value2 = float(card[block].get(id2).value)
1063 try:
1064 param = card[block].get(id1)
1065 except KeyError:
1066 if modify:
1067 new_param = Parameter(block=block,lhacode=id1, value=-value2,
1068 comment='must be opposite to to %s' %id2)
1069 card[block].append(new_param)
1070 else:
1071 value1 = float(param.value)
1072
1073 if value1 != -value2:
1074 if not modify:
1075 raise InvalidParamCard, 'parameter %s: %s is not to opposite to parameter %s' % \
1076 (block, ' '.join([str(i) for i in id1]),
1077 ' '.join([str(i) for i in id2]))
1078 else:
1079 param = card[block].get(id1)
1080 param.value = -value2
1081 param.comment += ' must be opposite to %s' % id2
1082
1083 return card
1084
1087 """ """
1088
1089 if not outputpath:
1090 outputpath = path
1091 card = ParamCard(path)
1092 if not 'usqmix' in card:
1093
1094 card.write(outputpath)
1095 return
1096
1097
1098
1099 card.copy_param('mass', [6], 'sminputs', [6])
1100 card.copy_param('mass', [15], 'sminputs', [7])
1101 card.copy_param('mass', [23], 'sminputs', [4])
1102
1103
1104
1105 card.add_param('modsel',[1], value=1)
1106 card['modsel'].get([1]).format = 'int'
1107
1108
1109 scale = card['hmix'].scale
1110 if not scale:
1111 scale = 1
1112
1113
1114 if not card.has_param('sminputs', [2]):
1115 aem1 = card['sminputs'].get([1]).value
1116 mz = card['mass'].get([23]).value
1117 mw = card['mass'].get([24]).value
1118 gf = math.pi / math.sqrt(2) / aem1 * mz**2/ mw**2 /(mz**2-mw**2)
1119 card.add_param('sminputs', [2], gf, 'G_F [GeV^-2]')
1120
1121
1122 card.check_and_remove('usqmix', [1,1], 1.0)
1123 card.check_and_remove('usqmix', [2,2], 1.0)
1124 card.check_and_remove('usqmix', [4,4], 1.0)
1125 card.check_and_remove('usqmix', [5,5], 1.0)
1126 card.mod_param('usqmix', [3,3], 'stopmix', [1,1])
1127 card.mod_param('usqmix', [3,6], 'stopmix', [1,2])
1128 card.mod_param('usqmix', [6,3], 'stopmix', [2,1])
1129 card.mod_param('usqmix', [6,6], 'stopmix', [2,2])
1130
1131
1132 card.check_and_remove('dsqmix', [1,1], 1.0)
1133 card.check_and_remove('dsqmix', [2,2], 1.0)
1134 card.check_and_remove('dsqmix', [4,4], 1.0)
1135 card.check_and_remove('dsqmix', [5,5], 1.0)
1136 card.mod_param('dsqmix', [3,3], 'sbotmix', [1,1])
1137 card.mod_param('dsqmix', [3,6], 'sbotmix', [1,2])
1138 card.mod_param('dsqmix', [6,3], 'sbotmix', [2,1])
1139 card.mod_param('dsqmix', [6,6], 'sbotmix', [2,2])
1140
1141
1142
1143 card.check_and_remove('selmix', [1,1], 1.0)
1144 card.check_and_remove('selmix', [2,2], 1.0)
1145 card.check_and_remove('selmix', [4,4], 1.0)
1146 card.check_and_remove('selmix', [5,5], 1.0)
1147 card.mod_param('selmix', [3,3], 'staumix', [1,1])
1148 card.mod_param('selmix', [3,6], 'staumix', [1,2])
1149 card.mod_param('selmix', [6,3], 'staumix', [2,1])
1150 card.mod_param('selmix', [6,6], 'staumix', [2,2])
1151
1152
1153 card.mod_param('fralpha', [1], 'alpha', [' '])
1154
1155
1156 if not card.has_param('hmix', [3]):
1157 aem1 = card['sminputs'].get([1]).value
1158 tanb = card['hmix'].get([2]).value
1159 mz = card['mass'].get([23]).value
1160 mw = card['mass'].get([24]).value
1161 sw = math.sqrt(mz**2 - mw**2)/mz
1162 ee = 2 * math.sqrt(1/aem1) * math.sqrt(math.pi)
1163 vu = 2 * mw *sw /ee * math.sin(math.atan(tanb))
1164 card.add_param('hmix', [3], vu, 'higgs vev(Q) MSSM DRb')
1165 card['hmix'].scale= scale
1166
1167
1168 card.check_and_remove('vckm', [1,1], 1.0)
1169 card.check_and_remove('vckm', [2,2], 1.0)
1170 card.check_and_remove('vckm', [3,3], 1.0)
1171
1172
1173 card.check_and_remove('snumix', [1,1], 1.0)
1174 card.check_and_remove('snumix', [2,2], 1.0)
1175 card.check_and_remove('snumix', [3,3], 1.0)
1176
1177
1178 card.check_and_remove('upmns', [1,1], 1.0)
1179 card.check_and_remove('upmns', [2,2], 1.0)
1180 card.check_and_remove('upmns', [3,3], 1.0)
1181
1182
1183 ye = card['ye'].get([3, 3]).value
1184 te = card['te'].get([3, 3]).value
1185 card.mod_param('te', [3,3], 'ae', [3,3], value= te/ye, comment='A_tau(Q) DRbar')
1186 card.add_param('ae', [1,1], 0, 'A_e(Q) DRbar')
1187 card.add_param('ae', [2,2], 0, 'A_mu(Q) DRbar')
1188 card['ae'].scale = scale
1189 card['ye'].scale = scale
1190
1191
1192 yu = card['yu'].get([3, 3]).value
1193 tu = card['tu'].get([3, 3]).value
1194 card.mod_param('tu', [3,3], 'au', [3,3], value= tu/yu, comment='A_t(Q) DRbar')
1195 card.add_param('au', [1,1], 0, 'A_u(Q) DRbar')
1196 card.add_param('au', [2,2], 0, 'A_c(Q) DRbar')
1197 card['au'].scale = scale
1198 card['yu'].scale = scale
1199
1200
1201 yd = card['yd'].get([3, 3]).value
1202 td = card['td'].get([3, 3]).value
1203 if td:
1204 card.mod_param('td', [3,3], 'ad', [3,3], value= td/yd, comment='A_b(Q) DRbar')
1205 else:
1206 card.mod_param('td', [3,3], 'ad', [3,3], value= 0., comment='A_b(Q) DRbar')
1207 card.add_param('ad', [1,1], 0, 'A_d(Q) DRbar')
1208 card.add_param('ad', [2,2], 0, 'A_s(Q) DRbar')
1209 card['ad'].scale = scale
1210 card['yd'].scale = scale
1211
1212
1213 value = card['msl2'].get([1, 1]).value
1214 card.mod_param('msl2', [1,1], 'msoft', [31], math.sqrt(value))
1215 value = card['msl2'].get([2, 2]).value
1216 card.mod_param('msl2', [2,2], 'msoft', [32], math.sqrt(value))
1217 value = card['msl2'].get([3, 3]).value
1218 card.mod_param('msl2', [3,3], 'msoft', [33], math.sqrt(value))
1219 card['msoft'].scale = scale
1220
1221
1222 value = card['mse2'].get([1, 1]).value
1223 card.mod_param('mse2', [1,1], 'msoft', [34], math.sqrt(value))
1224 value = card['mse2'].get([2, 2]).value
1225 card.mod_param('mse2', [2,2], 'msoft', [35], math.sqrt(value))
1226 value = card['mse2'].get([3, 3]).value
1227 card.mod_param('mse2', [3,3], 'msoft', [36], math.sqrt(value))
1228
1229
1230 value = card['msq2'].get([1, 1]).value
1231 card.mod_param('msq2', [1,1], 'msoft', [41], math.sqrt(value))
1232 value = card['msq2'].get([2, 2]).value
1233 card.mod_param('msq2', [2,2], 'msoft', [42], math.sqrt(value))
1234 value = card['msq2'].get([3, 3]).value
1235 card.mod_param('msq2', [3,3], 'msoft', [43], math.sqrt(value))
1236
1237
1238 value = card['msu2'].get([1, 1]).value
1239 card.mod_param('msu2', [1,1], 'msoft', [44], math.sqrt(value))
1240 value = card['msu2'].get([2, 2]).value
1241 card.mod_param('msu2', [2,2], 'msoft', [45], math.sqrt(value))
1242 value = card['msu2'].get([3, 3]).value
1243 card.mod_param('msu2', [3,3], 'msoft', [46], math.sqrt(value))
1244
1245
1246 value = card['msd2'].get([1, 1]).value
1247 card.mod_param('msd2', [1,1], 'msoft', [47], math.sqrt(value))
1248 value = card['msd2'].get([2, 2]).value
1249 card.mod_param('msd2', [2,2], 'msoft', [48], math.sqrt(value))
1250 value = card['msd2'].get([3, 3]).value
1251 card.mod_param('msd2', [3,3], 'msoft', [49], math.sqrt(value))
1252
1253
1254
1255
1256
1257
1258 card.write(outputpath)
1259
1263 """
1264 """
1265
1266 if not outputpath:
1267 outputpath = path
1268 card = ParamCard(path)
1269 if 'usqmix' in card:
1270
1271 if outputpath != path and writting:
1272 card.write(outputpath)
1273 return card
1274
1275
1276
1277 card.remove_param('sminputs', [2])
1278 card.remove_param('sminputs', [4])
1279 card.remove_param('sminputs', [6])
1280 card.remove_param('sminputs', [7])
1281
1282
1283
1284 card.remove_param('modsel',[1])
1285
1286
1287
1288 card.add_param('usqmix', [1,1], 1.0)
1289 card.add_param('usqmix', [2,2], 1.0)
1290 card.add_param('usqmix', [4,4], 1.0)
1291 card.add_param('usqmix', [5,5], 1.0)
1292 card.mod_param('stopmix', [1,1], 'usqmix', [3,3])
1293 card.mod_param('stopmix', [1,2], 'usqmix', [3,6])
1294 card.mod_param('stopmix', [2,1], 'usqmix', [6,3])
1295 card.mod_param('stopmix', [2,2], 'usqmix', [6,6])
1296
1297
1298 card.add_param('dsqmix', [1,1], 1.0)
1299 card.add_param('dsqmix', [2,2], 1.0)
1300 card.add_param('dsqmix', [4,4], 1.0)
1301 card.add_param('dsqmix', [5,5], 1.0)
1302 card.mod_param('sbotmix', [1,1], 'dsqmix', [3,3])
1303 card.mod_param('sbotmix', [1,2], 'dsqmix', [3,6])
1304 card.mod_param('sbotmix', [2,1], 'dsqmix', [6,3])
1305 card.mod_param('sbotmix', [2,2], 'dsqmix', [6,6])
1306
1307
1308
1309 card.add_param('selmix', [1,1], 1.0)
1310 card.add_param('selmix', [2,2], 1.0)
1311 card.add_param('selmix', [4,4], 1.0)
1312 card.add_param('selmix', [5,5], 1.0)
1313 card.mod_param('staumix', [1,1], 'selmix', [3,3])
1314 card.mod_param('staumix', [1,2], 'selmix', [3,6])
1315 card.mod_param('staumix', [2,1], 'selmix', [6,3])
1316 card.mod_param('staumix', [2,2], 'selmix', [6,6])
1317
1318
1319 card.mod_param('alpha', [], 'fralpha', [1])
1320
1321
1322 card.remove_param('hmix', [3])
1323
1324
1325 card.add_param('vckm', [1,1], 1.0)
1326 card.add_param('vckm', [2,2], 1.0)
1327 card.add_param('vckm', [3,3], 1.0)
1328
1329
1330 card.add_param('snumix', [1,1], 1.0)
1331 card.add_param('snumix', [2,2], 1.0)
1332 card.add_param('snumix', [3,3], 1.0)
1333
1334
1335 card.add_param('upmns', [1,1], 1.0)
1336 card.add_param('upmns', [2,2], 1.0)
1337 card.add_param('upmns', [3,3], 1.0)
1338
1339
1340 ye = card['ye'].get([1, 1], default=0).value
1341 ae = card['ae'].get([1, 1], default=0).value
1342 card.mod_param('ae', [1,1], 'te', [1,1], value= ae * ye, comment='T_e(Q) DRbar')
1343 if ae * ye:
1344 raise InvalidParamCard, '''This card is not suitable to be converted to MSSM UFO model
1345 Parameter ae [1, 1] times ye [1,1] should be 0'''
1346 card.remove_param('ae', [1,1])
1347
1348 ye = card['ye'].get([2, 2], default=0).value
1349
1350 ae = card['ae'].get([2, 2], default=0).value
1351 card.mod_param('ae', [2,2], 'te', [2,2], value= ae * ye, comment='T_mu(Q) DRbar')
1352 if ae * ye:
1353 raise InvalidParamCard, '''This card is not suitable to be converted to MSSM UFO model
1354 Parameter ae [2, 2] times ye [2,2] should be 0'''
1355 card.remove_param('ae', [2,2])
1356
1357 ye = card['ye'].get([3, 3], default=0).value
1358 ae = card['ae'].get([3, 3], default=0).value
1359 card.mod_param('ae', [3,3], 'te', [3,3], value= ae * ye, comment='T_tau(Q) DRbar')
1360
1361
1362 yu = card['yu'].get([1, 1], default=0).value
1363 au = card['au'].get([1, 1], default=0).value
1364 card.mod_param('au', [1,1], 'tu', [1,1], value= au * yu, comment='T_u(Q) DRbar')
1365 if au * yu:
1366 raise InvalidParamCard, '''This card is not suitable to be converted to MSSM UFO model
1367 Parameter au [1, 1] times yu [1,1] should be 0'''
1368 card.remove_param('au', [1,1])
1369
1370 ye = card['yu'].get([2, 2], default=0).value
1371
1372 ae = card['au'].get([2, 2], default=0).value
1373 card.mod_param('au', [2,2], 'tu', [2,2], value= au * yu, comment='T_c(Q) DRbar')
1374 if au * yu:
1375 raise InvalidParamCard, '''This card is not suitable to be converted to MSSM UFO model
1376 Parameter au [2, 2] times yu [2,2] should be 0'''
1377 card.remove_param('au', [2,2])
1378
1379 yu = card['yu'].get([3, 3]).value
1380 au = card['au'].get([3, 3]).value
1381 card.mod_param('au', [3,3], 'tu', [3,3], value= au * yu, comment='T_t(Q) DRbar')
1382
1383
1384 yd = card['yd'].get([1, 1], default=0).value
1385 ad = card['ad'].get([1, 1], default=0).value
1386 card.mod_param('ad', [1,1], 'td', [1,1], value= ad * yd, comment='T_d(Q) DRbar')
1387 if ad * yd:
1388 raise InvalidParamCard, '''This card is not suitable to be converted to MSSM UFO model
1389 Parameter ad [1, 1] times yd [1,1] should be 0'''
1390 card.remove_param('ad', [1,1])
1391
1392 ye = card['yd'].get([2, 2], default=0).value
1393
1394 ae = card['ad'].get([2, 2], default=0).value
1395 card.mod_param('ad', [2,2], 'td', [2,2], value= ad * yd, comment='T_s(Q) DRbar')
1396 if ad * yd:
1397 raise InvalidParamCard, '''This card is not suitable to be converted to MSSM UFO model
1398 Parameter ad [2, 2] times yd [2,2] should be 0'''
1399 card.remove_param('ad', [2,2])
1400
1401 yd = card['yd'].get([3, 3]).value
1402 ad = card['ad'].get([3, 3]).value
1403 card.mod_param('ad', [3,3], 'td', [3,3], value= ad * yd, comment='T_b(Q) DRbar')
1404
1405
1406
1407 value = card['msoft'].get([31]).value
1408 card.mod_param('msoft', [31], 'msl2', [1,1], value**2)
1409 value = card['msoft'].get([32]).value
1410 card.mod_param('msoft', [32], 'msl2', [2,2], value**2)
1411 value = card['msoft'].get([33]).value
1412 card.mod_param('msoft', [33], 'msl2', [3,3], value**2)
1413
1414
1415 value = card['msoft'].get([34]).value
1416 card.mod_param('msoft', [34], 'mse2', [1,1], value**2)
1417 value = card['msoft'].get([35]).value
1418 card.mod_param('msoft', [35], 'mse2', [2,2], value**2)
1419 value = card['msoft'].get([36]).value
1420 card.mod_param('msoft', [36], 'mse2', [3,3], value**2)
1421
1422
1423 value = card['msoft'].get([41]).value
1424 card.mod_param('msoft', [41], 'msq2', [1,1], value**2)
1425 value = card['msoft'].get([42]).value
1426 card.mod_param('msoft', [42], 'msq2', [2,2], value**2)
1427 value = card['msoft'].get([43]).value
1428 card.mod_param('msoft', [43], 'msq2', [3,3], value**2)
1429
1430
1431 value = card['msoft'].get([44]).value
1432 card.mod_param('msoft', [44], 'msu2', [1,1], value**2)
1433 value = card['msoft'].get([45]).value
1434 card.mod_param('msoft', [45], 'msu2', [2,2], value**2)
1435 value = card['msoft'].get([46]).value
1436 card.mod_param('msoft', [46], 'msu2', [3,3], value**2)
1437
1438
1439 value = card['msoft'].get([47]).value
1440 card.mod_param('msoft', [47], 'msd2', [1,1], value**2)
1441 value = card['msoft'].get([48]).value
1442 card.mod_param('msoft', [48], 'msd2', [2,2], value**2)
1443 value = card['msoft'].get([49]).value
1444 card.mod_param('msoft', [49], 'msd2', [3,3], value**2)
1445
1446
1447
1448
1449 if writting:
1450 card.write(outputpath)
1451 return card
1452
1455 """ modify the current param_card such that it agrees with the restriction"""
1456
1457 if not outputpath:
1458 outputpath = path
1459
1460 cardrule = ParamCardRule()
1461 cardrule.load_rule(restrictpath)
1462 try :
1463 cardrule.check_param_card(path, modify=False)
1464 except InvalidParamCard:
1465 new_data = cardrule.check_param_card(path, modify=True)
1466 cardrule.write_param_card(outputpath, new_data)
1467 else:
1468 if path != outputpath:
1469 shutil.copy(path, outputpath)
1470 return cardrule
1471
1473 """ check if the current param_card agrees with the restriction"""
1474
1475 if restrictpath is None:
1476 restrictpath = os.path.dirname(path)
1477 restrictpath = os.path.join(restrictpath, os.pardir, os.pardir, 'Source',
1478 'MODEL', 'param_card_rule.dat')
1479 if not os.path.exists(restrictpath):
1480 restrictpath = os.path.dirname(path)
1481 restrictpath = os.path.join(restrictpath, os.pardir, 'Source',
1482 'MODEL', 'param_card_rule.dat')
1483 if not os.path.exists(restrictpath):
1484 return True
1485
1486 cardrule = ParamCardRule()
1487 cardrule.load_rule(restrictpath)
1488 cardrule.check_param_card(path, modify=False)
1489
1490 if '__main__' == __name__:
1491
1492
1493
1494
1495 import sys
1496 args = sys.argv
1497 sys.path.append(os.path.dirname(__file__))
1498 convert_to_slha1(args[1] , args[2])
1499