#!/usr/bin/env python #Extension import os import re import string import sys import xml.sax.handler try: import madgraph.madweight.Cards as Cards import madgraph.madweight.mod_file as mod_file import madgraph.madweight.particle_class as particle_class import madgraph.madweight.MW_fct as MW_fct except ImportError: import internal.madweight.Cards as Cards import internal.madweight.mod_file as mod_file import internal.madweight.particle_class as particle_class import internal.madweight.MW_fct as MW_fct ###f77 forbiden term #forbiden=["goto","return","stop","call","write","read","do","while","end ","continue","asign","pause","print","rewind","backspace","endfile","open","close","inquire","entry","optional","save","equivalence","intent","target","rule","compute","system","enddo"] def create_TF_main(name,make, MW_dir): print "start main program" TF_file=Full_TF(name) TF_file.read_file("./data/TF_"+name+".dat") print "deleting the current TFlib: " os.system("rm ../../../lib/libTF.a >& /dev/null") TF_file.create_ordering_file() print "ordering_file.inc created" list_var=TF_file.create_transfer_functions() print "transfer_function.f created" TF_file.create_transfer_card(list_var) print "transfer_card.dat created" create_param_inc(list_var) print "TF_param created" create_ident_card(list_var) print "ident_card created" create_version(name) print 'TransferFunctionVersion created' fsock = open('nb_tf.inc','w').write(' integer nb_tf\n parameter (nb_tf=1)\n') os.chdir('../../../') #go to main # P_dir,MW_dir=MW_param.detect_SubProcess(P_mode=1) for directory in MW_dir: obj=TF_in_SubProcesses(TF_file,directory) obj.write_transfer_function_file() print 'call_TF.f created in for all Subprocesses' os.chdir('./Source/MadWeight/transfer_function') update_dir(name,make,MW_dir) print 'generation completed' #1 ################################################################################# class XML_input(xml.sax.handler.ContentHandler): """ This class will organize in python obect the TF_param.dat file (written in xml) """ #2 ############################################################################# def __init__(self): self.block = {} self.inblock='' self.in_variable='' self.buffer='' #2 ############################################################################# def startElement(self, name, attributes): self.buffer='' if name == "block": block_name=attributes["name"] self.block[block_name]=TF_block(block_name) self.inblock=block_name elif name == "variable": self.in_variable=attributes["name"] #2 ############################################################################# def characters(self, data): self.buffer += data #2 ############################################################################# def endElement(self, name): if name == 'particles': self.block[self.inblock].def_particles(self.buffer) elif name == 'width_type': self.block[self.inblock].def_width_type(self.buffer) elif name == "tf": self.block[self.inblock][self.in_variable].change_tf(self.buffer) elif name == "width": self.block[self.inblock][self.in_variable].change_width(self.buffer) elif name == "info": self.block[self.inblock].def_info(self.buffer) elif name == "include": self.block[self.inblock][self.in_variable].def_include(self.buffer) #2 ############################################################################# def read_file(self,filepos): """ parse the file and fulfill the object """ parser = xml.sax.make_parser( ) parser.setContentHandler(self) parser.parse(filepos) #2 ############################################################################# def find_label_to_block(self): """ return a dict {label:block_name} store it for efficiency reason""" if hasattr(self,'label_to_block'): return self.label_to_block self.label_to_block={} for name,block in self.block.items(): for label in block.particles: self.label_to_block[label]=name return self.label_to_block #1 ################################################################################# class TF_with_particles(XML_input): """ this class extend the XML with routine associating the particles.dat file """ def __init__(self,only_add=0): """ standard input but add a tag if the particles.dat is loaded or not """ if not only_add: XML_input.__init__(self) self.particles_file=0 def load_particles_file(self,filepos='./Source/MODEL/particles.dat'): """ load the particles file if not already loaded """ if not self.particles_file: self.particles_file = Cards.Particles_file(filepos) def find_pid_to_label(self): if hasattr(self, 'pid_to_label'): return self.pid_to_label self.pid_to_label=self.particles_file.give_pid_to_label() return self.pid_to_label #1 ################################################################################# class TF_input(XML_input): """ This class extend the XML input containing routines containing writing output """ #2 ############################################################################# def __init__(self,name): XML_input.__init__(self) self.tf_name=name #2 ############################################################################# def create_ordering_file(self): """ take input form TF_input.dat and insert in ordering_file.inc""" #collect particle information thin=[] large=[] with_x=0 theta = [] phi = [] for block in self.block.values(): if block.order==1: thin+=block.particles elif block.order==2: large+=block.particles if "x1" in block.particles or "x2" in block.particles: with_x=1 if block['THETA'].tf_code.strip() != 'tf=1d0' or \ block['THETA'].width_code.strip() != 'width=0d0': theta += block.particles if block['PHI'].tf_code.strip() != 'tf=1d0' or \ block['PHI'].width_code.strip() != 'width=0d0': phi += block.particles #define the rule of how modif file transfer_function/input/ordering_file.inc modif_rule={} modif_rule['THIN']=','.join(thin) modif_rule['LARGE']=','.join(large) modif_rule['X']=str(with_x) modif_rule['NAME_TF']=self.tf_name modif_rule['THETA'] = ','.join(theta) modif_rule['PHI'] = ','.join(phi) #modify file mod_file.mod_file('./input/ordering_file.inc',modif_rule,write='./ordering_file.inc') #2 ############################################################################# def create_transfer_functions(self): """ define for each block the 3 functions TF and the three TF width """ def create_optional_variable(text,blockname,variable,list_var=[]): """ replace all #1,#2 by fortran name """ output='' Pattern=re.compile(r'''#(\d*)''') prov=Pattern.split(text) i=0 while i2: #invisible particlule but not the initial part text+=' do i=0,3\n p_met_rec(i)=p_met_rec(i)+p(i,%s)\n enddo\n' %(i+1) continue text+=' n_lhco=tag_lhco(%s)\n' % (i+1) for var in ['E','THETA','PHI']: text+=' call tf_%s_%s(pexp(0,%s),p(0,%s),n_lhco,weight)\n' %(var,blockname,i+1,i+1) text+='\n'#space between particles definition if met: text+=' k=met_lhco\n' text+=' call four_momentum_set2(eta_init(k),phi_init(k),pt_init(k),j_mass(k),p_met_exp)\n' text+=' call tf_E_%s(p_met_exp,p_met_rec,met_lhco,weight)\n' %(met) text+="\n call check_nan(weight)\n return \n end\n" return text #2 ############################################################################# def text_tf_E_for_part(self): """ return the different tf_E_for_XX function in a unformated text (need to pass in mod_file for comment, and to f77_format """ text2='' #text containing all the single call #Comment-subroutine-definition-init weight text='$B$ START_TF_E_FOR_PART $E$\n' for i in range(0,len(self.blockname_list)): text2+='\n'+self.text_tf_E_for_one_part(i)+'\n' blockname=self.blockname_list[i] if not isinstance(blockname, basestring): text+=' if(MG_num.eq.%s) then\n tf_E_for_part=1d0\n return\n endif\n' % (i+1) else: text+=' if(MG_num.eq.%s) then\n' %(i+1) text+=' tf_E_for_part=1d0\n' text+=' n_lhco=tag_lhco(%s)\n'% (i+1) text+=' call tf_E_%s(pexp(0,%s),momenta(0,%s),n_lhco,tf_E_for_part)\n' % (blockname,i+1,i+1) text+='\n return\n endif\n' text+="\n return \n end\n" return text+text2 #2 ############################################################################# def text_tf_E_for_one_part(self,i): """ return the different tf_E_for_XX function in a unformated text (need to pass in mod_file for comment, and to f77_format """ text='$B$ S-COMMENT_C $B$ Subroutine: tf_E_for_XX()\n' text+='\n purpose: returns the value of the transfer function (in energy)\n' text+='$E$ S-COMMENT_C $E$\n' text+=' double precision function tf_E_for_%s()\n\n' % (i+1) #Comment-subroutine-definition-init weight text+='$B$ DEF_TF_E_FOR_ONE_PART $E$\n' blockname=self.blockname_list[i] if not isinstance(blockname, basestring): text+=' tf_E_for_%s=1d0\n' %(i+1) else: text+=' tf_E_for_%s=1d0\n' %(i+1) text+=' n_lhco=tag_lhco(%s)\n'% (i+1) text+=' call tf_E_%s(pexp(0,%s),momenta(0,%s),n_lhco,tf_E_for_%s)\n' % (blockname,i+1,i+1,i+1) text+="\n return \n end\n" return text #1 ################################################################################# def create_param_inc(list_var): out=open("TF_param.inc",'w') file_in=open("./input/TF_param_generic.inc",'r') out.writelines(file_in.read()) file_in.close() if list_var==[]: print "TF_param created (no input)" return common_text='' for name in list_var: name = name.replace('(curr_tf)','') line=" double precision "+name+"(nb_tf)\n" out.writelines(line) common_text+=name+',' common_text=common_text[:-1] #suppress last coma line=" Common/to_TF_param/"+common_text line=MW_fct.put_in_fortran_format(line) out.writelines(line) out.close() return def create_ident_card(list_var): ff=open("./input/ident_mw_card_generic.dat",'r') out=open("ident_mw_card.dat",'w') #copy generic file out.writelines(ff.read()) for name in list_var: data=name.split('_') line="TF_"+data[1].upper()+'_'+data[2].upper() line+=' '+data[3]+" "+name+" real \n" out.writelines(line) return def create_rw(list_var): file_in=open("./input/rw_tf_generic.f","r") file_out=open("./rw_tf.f","w") Pattern=re.compile(r'''\$\$ADD_HERE\$\$''') while 1: line=file_in.readline() if line=="": break if not(Pattern.search(line)): file_out.writelines(line) else: #We are in position to put data info for name in list_var: file_out.writelines(" call get_real_t(npara,param,value,\""+name+"\" ,"+name+", 1d0)\n") file_out.writelines(file_in.read()) break file_in.close() file_out.close() return def create_version(name): """ standard version number DIRNAME_X.Y written in Transfer_FctVersion.txt DIRNAME: name of the directory X and Y: version number coming from the new_transfer function """ #load version number: ff=open('./Transfer_FctVersion.txt','r') line=ff.readline().split(':',1) ff.close() #dirname: # dirname=os.path.basename(os.getcwd()) #writefile: ff=open('./Transfer_FctVersion.txt','w') ff.writelines(name+':'+line[1]) ff.close() return def update_dir(name,make,MW_dir): main='../../../' os.system("cp ./ident_mw_card.dat "+main+"/Cards/") os.system("cp transfer_card.dat "+main+"/Cards/") os.system("cp data/transfer_card_"+name+".dat "+main+"/Cards/transfer_card.dat &>/dev/null") os.system("cp data/transfer_card_"+name+".dat "+main+"/Cards/transfer_card_default.dat &>/dev/null") if make: os.chdir(main+"/Source/") os.system("make") for directory in MW_dir: os.chdir(main+"/SubProcesses/"+directory) os.system("ln -s ../../Source/MadWeight/transfer_function/TF_param.inc TF_param.inc") os.system("ln -s ../../Source/MadWeight/transfer_function/nb_tf.inc nb_tf.inc") os.system("make") os.chdir('../../') else: os.system("make ") # always compile libTF ... os.chdir(main) for directory in MW_dir: os.chdir("SubProcesses/"+directory) os.system("ln -s ../../Source/MadWeight/transfer_function/TF_param.inc TF_param.inc") os.system("ln -s ../../Source/MadWeight/transfer_function/nb_tf.inc nb_tf.inc") os.chdir('../../') #charge card ident=Cards.Card('./Cards/ident_mw_card.dat') madweight=Cards.Card('./Cards/MadWeight_card.dat') transfer=Cards.Card('./Cards/transfer_card.dat') #create output madweight.create_include_file(ident,'./Source/madweight_card.inc') transfer.create_include_file_tf(ident,'./Source/MadWeight/transfer_function') os.chdir('./Source/MadWeight/transfer_function') #def check_valid(text): # for name in forbiden: # Pattern=re.compile(name,re.I) # if Pattern.search(text): # print "ERROR: invalid usage of statement: ",name # print "for security reason transfer functions can't use this statement" # sys.exit() # return def extract_tf_name(filepos='./Cards/proc_card.dat'): """ read the file to find the requested change of variable""" found=0 for line in file(filepos): if found: name=line.split()[0] #remove blank spae,end of line,... return name if line.startswith('# Begin transfer_function'): found=1 ########################### TEST ################################# if(__name__=="__main__"): import MW_param MW_param.go_to_main_dir() P_dir,MW_dir=MW_param.detect_SubProcess(P_mode=1) opt=sys.argv if len(opt)<2: listdir=os.listdir('./Source/MadWeight/transfer_function/data') print 'Available TF function:\n ', print '\n '.join([content[3:-4] for content in listdir if (content.startswith('TF') and content.endswith('dat'))]) name=raw_input('Choose your Transfer Function\n') else: name=opt[1] if name in ['proc_card.dat','auto']: name=extract_tf_name('./Cards/proc_card.dat') if len(opt)==3: made_make=int(opt[2]) else: made_make=0 os.chdir('./Source/MadWeight/transfer_function') create_TF_main(name,made_make,MW_dir) ## file=raw_input("file: ") ## ff=open(file,'r') ## gg=open(file+'_70.f','w') ## text=ff.read() ## text=MW_fct.put_in_fortran_format(text) ## gg.writelines(text)