Package madgraph :: Package interface :: Module launch_ext_program
[hide private]
[frames] | no frames]

Source Code for Module madgraph.interface.launch_ext_program

  1  ################################################################################ 
  2  # 
  3  # Copyright (c) 2009 The MadGraph Development team and Contributors 
  4  # 
  5  # This file is a part of the MadGraph 5 project, an application which  
  6  # automatically generates Feynman diagrams and matrix elements for arbitrary 
  7  # high-energy processes in the Standard Model and beyond. 
  8  # 
  9  # It is subject to the MadGraph license which should accompany this  
 10  # distribution. 
 11  # 
 12  # For more information, please visit: http://madgraph.phys.ucl.ac.be 
 13  # 
 14  ################################################################################ 
 15   
 16  import glob 
 17  import logging 
 18  import os 
 19  import pydoc 
 20  import re 
 21  import sys 
 22  import subprocess 
 23  import thread 
 24  import time 
 25   
 26  import madgraph.iolibs.files as files 
 27  import madgraph.interface.extended_cmd as cmd 
 28  import madgraph.interface.madevent_interface as me_cmd 
 29  import madgraph.various.misc as misc 
 30   
 31  from madgraph import MG4DIR, MG5DIR, MadGraph5Error 
 32  from madgraph.iolibs.files import cp 
 33   
 34   
 35   
 36  logger = logging.getLogger('cmdprint.ext_program') 
 37   
38 -class ExtLauncher(object):
39 """ Generic Class for executing external program """ 40 41 program_dir = '' 42 executable = '' # path from program_dir 43 44 force = False 45
46 - def __init__(self, cmd, running_dir, card_dir='', 47 **options):
48 """ initialize an object """ 49 50 self.running_dir = running_dir 51 self.card_dir = os.path.join(self.running_dir, card_dir) 52 self.cmd_int = cmd 53 #include/overwrite options 54 for key,value in options.items(): 55 setattr(self, key, value) 56 57 self.cards = [] # files can be modified (path from self.card_dir)
58
59 - def run(self):
60 """ execute the main code """ 61 62 self.prepare_run() 63 for card in self.cards: 64 self.treat_input_file(card, default = 'n') 65 66 self.launch_program()
67 68
69 - def prepare_run(self):
70 """ aditional way to prepare the run""" 71 pass
72
73 - def launch_program(self):
74 """launch the main program""" 75 subprocess.call([self.executable], cwd=self.running_dir)
76
77 - def edit_file(self, path):
78 """edit a file""" 79 80 path = os.path.realpath(path) 81 open_file(path)
82 83 84 # Treat Nicely the timeout
85 - def timeout_fct(self,timeout):
86 if timeout: 87 # avoid to always wait a given time for the next answer 88 self.force = True
89
90 - def ask(self, question, default, choices=[], path_msg=None):
91 """nice handling of question""" 92 93 if not self.force: 94 return self.cmd_int.ask(question, default, choices=choices, 95 path_msg=path_msg, fct_timeout=self.timeout_fct) 96 else: 97 return str(default)
98 99
100 - def treat_input_file(self, filename, default=None, msg=''):
101 """ask to edit a file""" 102 103 if msg == '' and filename == 'param_card.dat': 104 msg = \ 105 """WARNING: If you edit this file don\'t forget to modify 106 consistently the different parameters, especially 107 the width of all particles.""" 108 109 fct = lambda q: cmd.raw_path_input(q, allow_arg=['y','n']) 110 111 if not self.force: 112 if msg: print msg 113 question = 'Do you want to edit file: %(card)s?' % {'card':filename} 114 choices = ['y', 'n'] 115 path_info = 'path of the new %(card)s' % {'card':os.path.basename(filename)} 116 ans = self.ask(question, default, choices, path_info) 117 else: 118 ans = default 119 120 if ans == 'y': 121 path = os.path.join(self.card_dir, filename) 122 self.edit_file(path) 123 elif ans == 'n': 124 return 125 else: 126 path = os.path.join(self.card_dir, filename) 127 files.cp(ans, path)
128 129 130 131
132 -class SALauncher(ExtLauncher):
133 """ A class to launch a simple Standalone test """ 134
135 - def __init__(self, cmd_int, running_dir, **options):
136 """ initialize the StandAlone Version""" 137 138 ExtLauncher.__init__(self, cmd_int, running_dir, './Cards', **options) 139 self.cards = ['param_card.dat']
140 141
142 - def launch_program(self):
143 """launch the main program""" 144 sub_path = os.path.join(self.running_dir, 'SubProcesses') 145 for path in os.listdir(sub_path): 146 if path.startswith('P') and \ 147 os.path.isdir(os.path.join(sub_path, path)): 148 cur_path = os.path.join(sub_path, path) 149 # make 150 misc.compile(cwd=cur_path, mode='unknown') 151 # check 152 subprocess.call(['./check'], cwd=cur_path)
153 154
155 -class MELauncher(ExtLauncher):
156 """A class to launch MadEvent run""" 157
158 - def __init__(self, running_dir, cmd_int , unit='pb', **option):
159 """ initialize the StandAlone Version""" 160 161 ExtLauncher.__init__(self, cmd_int, running_dir, './Cards', **option) 162 #self.executable = os.path.join('.', 'bin','generate_events') 163 self.pythia = cmd_int.options['pythia-pgs_path'] 164 self.delphes = cmd_int.options['delphes_path'], 165 166 assert hasattr(self, 'cluster') 167 assert hasattr(self, 'multicore') 168 assert hasattr(self, 'name') 169 assert hasattr(self, 'shell') 170 171 self.unit = unit 172 173 if self.cluster: 174 self.cluster = 1 175 if self.multicore: 176 self.cluster = 2 177 178 self.cards = [] 179 180 # Assign a valid run name if not put in options 181 if self.name == '': 182 self.name = me_cmd.MadEventCmd.find_available_run_name(self.running_dir)
183
184 - def launch_program(self):
185 """launch the main program""" 186 187 # Check for number of cores if multicore mode 188 mode = str(self.cluster) 189 nb_node = 1 190 if mode == "2": 191 import multiprocessing 192 max_node = multiprocessing.cpu_count() 193 if max_node == 1: 194 logger.warning('Only one core is detected on your computer! Pass in single machine') 195 self.cluster = 0 196 self.launch_program() 197 return 198 elif max_node == 2: 199 nb_node = 2 200 elif not self.force: 201 nb_node = self.ask('How many core do you want to use?', max_node, range(2,max_node+1)) 202 else: 203 nb_node=max_node 204 205 import madgraph.interface.madevent_interface as ME 206 207 if self.shell: 208 usecmd = ME.MadEventCmdShell(me_dir=self.running_dir) 209 else: 210 usecmd = ME.MadEventCmd(me_dir=self.running_dir) 211 212 #Check if some configuration were overwritten by a command. If so use it 213 set_cmd = [l for l in self.cmd_int.history if l.strip().startswith('set')] 214 for line in set_cmd: 215 try: 216 usecmd.exec_cmd(line) 217 except: 218 pass 219 launch = self.cmd_int.define_child_cmd_interface( 220 usecmd, interface=False) 221 #launch.me_dir = self.running_dir 222 if self.unit == 'pb': 223 command = 'generate_events %s' % self.name 224 else: 225 warning_text = '''\ 226 This command will create a new param_card with the computed width. 227 This param_card makes sense only if you include all processes for 228 the computation of the width.''' 229 logger.warning(warning_text) 230 231 command = 'calculate_decay_widths %s' % self.name 232 if mode == "1": 233 command += " --cluster" 234 elif mode == "2": 235 command += " --nb_core=%s" % nb_node 236 237 if self.force: 238 command+= " -f" 239 240 if self.laststep: 241 command += ' --laststep=%s' % self.laststep 242 243 try: 244 os.remove('ME5_debug') 245 except: 246 pass 247 launch.run_cmd(command) 248 launch.run_cmd('quit') 249 250 if os.path.exists('ME5_debug'): 251 return True 252 253 # Display the cross-section to the screen 254 path = os.path.join(self.running_dir, 'SubProcesses', 'results.dat') 255 if not os.path.exists(path): 256 logger.error('Generation failed (no results.dat file found)') 257 return 258 fsock = open(path) 259 line = fsock.readline() 260 cross, error = line.split()[0:2] 261 262 logger.info('more information in %s' 263 % os.path.join(self.running_dir, 'index.html'))
264 265
266 -class Pythia8Launcher(ExtLauncher):
267 """A class to launch Pythia8 run""" 268
269 - def __init__(self, running_dir, cmd_int, **option):
270 """ initialize launching Pythia 8""" 271 272 running_dir = os.path.join(running_dir, 'examples') 273 ExtLauncher.__init__(self, cmd_int, running_dir, '.', **option) 274 self.cards = []
275
276 - def prepare_run(self):
277 """ ask for pythia-pgs/delphes run """ 278 279 # Find all main_model_process.cc files 280 date_file_list = [] 281 for file in glob.glob(os.path.join(self.running_dir,'main_*_*.cc')): 282 # retrieves the stats for the current file as a tuple 283 # (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) 284 # the tuple element mtime at index 8 is the last-modified-date 285 stats = os.stat(file) 286 # create tuple (year yyyy, month(1-12), day(1-31), hour(0-23), minute(0-59), second(0-59), 287 # weekday(0-6, 0 is monday), Julian day(1-366), daylight flag(-1,0 or 1)) from seconds since epoch 288 # note: this tuple can be sorted properly by date and time 289 lastmod_date = time.localtime(stats[8]) 290 date_file_list.append((lastmod_date, os.path.split(file)[-1])) 291 292 if not date_file_list: 293 raise MadGraph5Error, 'No Pythia output found' 294 # Sort files according to date with newest first 295 date_file_list.sort() 296 date_file_list.reverse() 297 files = [d[1] for d in date_file_list] 298 299 answer = '' 300 answer = self.ask('Select a main file to run:', files[0], files) 301 302 self.cards.append(answer) 303 304 self.executable = self.cards[-1].replace(".cc","") 305 306 # Assign a valid run name if not put in options 307 if self.name == '': 308 for i in range(1000): 309 path = os.path.join(self.running_dir, '', 310 '%s_%02i.log' % (self.executable, i)) 311 if not os.path.exists(path): 312 self.name = '%s_%02i.log' % (self.executable, i) 313 break 314 315 if self.name == '': 316 raise MadGraph5Error, 'too many runs in this directory' 317 318 # Find all exported models 319 models = glob.glob(os.path.join(self.running_dir,os.path.pardir, 320 "Processes_*")) 321 models = [os.path.split(m)[-1].replace("Processes_","") for m in models] 322 # Extract model name from executable 323 models.sort(key=len) 324 models.reverse() 325 model_dir = "" 326 for model in models: 327 if self.executable.replace("main_", "").startswith(model): 328 model_dir = "Processes_%s" % model 329 break 330 if model_dir: 331 self.model = model 332 self.model_dir = os.path.realpath(os.path.join(self.running_dir, 333 os.path.pardir, 334 model_dir)) 335 self.cards.append(os.path.join(self.model_dir, 336 "param_card_%s.dat" % model))
337
338 - def launch_program(self):
339 """launch the main program""" 340 341 # Make pythia8 342 print "Running make for pythia8 directory" 343 misc.compile(cwd=os.path.join(self.running_dir, os.path.pardir), mode='cpp') 344 if self.model_dir: 345 print "Running make in %s" % self.model_dir 346 misc.compile(cwd=self.model_dir, mode='cpp') 347 # Finally run make for executable 348 makefile = self.executable.replace("main_","Makefile_") 349 print "Running make with %s" % makefile 350 misc.compile(arg=['-f', makefile], cwd=self.running_dir, mode='cpp') 351 352 print "Running " + self.executable 353 354 output = open(os.path.join(self.running_dir, self.name), 'w') 355 if not self.executable.startswith('./'): 356 self.executable = os.path.join(".", self.executable) 357 subprocess.call([self.executable], stdout = output, stderr = output, 358 cwd=self.running_dir) 359 360 # Display the cross-section to the screen 361 path = os.path.join(self.running_dir, self.name) 362 pydoc.pager(open(path).read()) 363 364 print "Output of the run is found at " + \ 365 os.path.realpath(os.path.join(self.running_dir, self.name))
366 367 # old compatibility shortcut 368 open_file = misc.open_file 369