1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """ A python file to replace the fortran script gen_ximprove.
16 This script analyses the result of the survey/ previous refine and
17 creates the jobs for the following script.
18 """
19 from __future__ import division
20
21 import collections
22 import os
23 import glob
24 import logging
25 import math
26 import re
27 import subprocess
28 import shutil
29
30 try:
31 import madgraph
32 except ImportError:
33 MADEVENT = True
34 import internal.sum_html as sum_html
35 import internal.banner as bannermod
36 import internal.misc as misc
37 import internal.files as files
38 import internal.cluster as cluster
39 import internal.combine_grid as combine_grid
40 import internal.combine_runs as combine_runs
41 import internal.lhe_parser as lhe_parser
42 else:
43 MADEVENT= False
44 import madgraph.madevent.sum_html as sum_html
45 import madgraph.various.banner as bannermod
46 import madgraph.various.misc as misc
47 import madgraph.iolibs.files as files
48 import madgraph.various.cluster as cluster
49 import madgraph.madevent.combine_grid as combine_grid
50 import madgraph.madevent.combine_runs as combine_runs
51 import madgraph.various.lhe_parser as lhe_parser
52
53 logger = logging.getLogger('madgraph.madevent.gen_ximprove')
54 pjoin = os.path.join
57 """a class to call the fortran gensym executable and handle it's output
58 in order to create the various job that are needed for the survey"""
59
60
61 @ staticmethod
64
65 combining_job = 2
66 splitted_grid = False
67 min_iterations = 3
68 mode= "survey"
69
70
72
73 try:
74 super(gensym, self).__init__(cmd, opt)
75 except TypeError:
76 pass
77
78
79 self.run_statistics = {}
80
81 self.cmd = cmd
82 self.run_card = cmd.run_card
83 self.me_dir = cmd.me_dir
84
85
86
87 self.cross = collections.defaultdict(int)
88 self.abscross = collections.defaultdict(int)
89 self.sigma = collections.defaultdict(int)
90 self.chi2 = collections.defaultdict(int)
91
92 self.splitted_grid = False
93 if self.cmd.proc_characteristics['loop_induced']:
94 nexternal = self.cmd.proc_characteristics['nexternal']
95 self.splitted_grid = max(2, (nexternal-2)**2)
96 if hasattr(self.cmd, "opts") and self.cmd.opts['accuracy'] == 0.1:
97 self.cmd.opts['accuracy'] = 0.02
98
99 if isinstance(cmd.cluster, cluster.MultiCore) and self.splitted_grid > 1:
100 self.splitted_grid = int(cmd.cluster.nb_core**0.5)
101 if self.splitted_grid == 1 and cmd.cluster.nb_core >1:
102 self.splitted_grid = 2
103
104
105 if self.run_card['survey_splitting'] != -1:
106 self.splitted_grid = self.run_card['survey_splitting']
107
108 self.splitted_Pdir = {}
109 self.splitted_for_dir = lambda x,y: self.splitted_grid
110 self.combining_job_for_Pdir = lambda x: self.combining_job
111 self.lastoffset = {}
112
114 """ """
115
116 self.subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses',
117 'subproc.mg'))]
118 subproc = self.subproc
119
120 P_zero_result = []
121
122 nb_tot_proc = len(subproc)
123 for nb_proc,subdir in enumerate(subproc):
124 job_list = {}
125 self.cmd.update_status('Compiling for process %s/%s. <br> (previous processes already running)' % \
126 (nb_proc+1,nb_tot_proc), level=None)
127
128 subdir = subdir.strip()
129 Pdir = pjoin(self.me_dir, 'SubProcesses',subdir)
130 logger.info(' %s ' % subdir)
131
132
133 for match in misc.glob('*ajob*', Pdir):
134 if os.path.basename(match)[:4] in ['ajob', 'wait', 'run.', 'done']:
135 os.remove(match)
136 for match in misc.glob('G*', Pdir):
137 if os.path.exists(pjoin(match,'results.dat')):
138 os.remove(pjoin(match, 'results.dat'))
139 if os.path.exists(pjoin(match, 'ftn25')):
140 os.remove(pjoin(match, 'ftn25'))
141
142
143 self.cmd.compile(['gensym'], cwd=Pdir)
144 if not os.path.exists(pjoin(Pdir, 'gensym')):
145 raise Exception, 'Error make gensym not successful'
146
147
148 p = misc.Popen(['./gensym'], stdout=subprocess.PIPE,
149 stderr=subprocess.STDOUT, cwd=Pdir)
150
151 (stdout, _) = p.communicate('')
152
153 if os.path.exists(pjoin(self.me_dir,'error')):
154 files.mv(pjoin(self.me_dir,'error'), pjoin(Pdir,'ajob.no_ps.log'))
155 P_zero_result.append(subdir)
156 continue
157
158 jobs = stdout.split()
159 job_list[Pdir] = jobs
160 try:
161
162 [float(s) for s in jobs]
163 except Exception:
164 logger.debug("unformated string found in gensym. Please check:\n %s" % stdout)
165 job_list[Pdir] = []
166 for s in jobs:
167 try:
168 float(s)
169 except:
170 continue
171 else:
172 job_list[Pdir].append(s)
173
174 self.cmd.compile(['madevent'], cwd=Pdir)
175 self.submit_to_cluster(job_list)
176 return job_list, P_zero_result
177
178
180 """ """
181
182 if self.run_card['job_strategy'] > 0:
183 if len(job_list) >1:
184 for path, dirs in job_list.items():
185 self.submit_to_cluster({path:dirs})
186 return
187 path, value = job_list.items()[0]
188 nexternal = self.cmd.proc_characteristics['nexternal']
189 current = open(pjoin(path, "nexternal.inc")).read()
190 ext = re.search(r"PARAMETER \(NEXTERNAL=(\d+)\)", current).group(1)
191
192 if self.run_card['job_strategy'] == 2:
193 self.splitted_grid = 2
194 if nexternal == int(ext):
195 to_split = 2
196 else:
197 to_split = 0
198 if hasattr(self, 'splitted_Pdir'):
199 self.splitted_Pdir[path] = to_split
200 else:
201 self.splitted_Pdir = {path: to_split}
202 self.splitted_for_dir = lambda x,y : self.splitted_Pdir[x]
203 elif self.run_card['job_strategy'] == 1:
204 if nexternal == int(ext):
205 combine = 1
206 else:
207 combine = self.combining_job
208 if hasattr(self, 'splitted_Pdir'):
209 self.splitted_Pdir[path] = combine
210 else:
211 self.splitted_Pdir = {path: combine}
212 self.combining_job_for_Pdir = lambda x : self.splitted_Pdir[x]
213
214 if not self.splitted_grid:
215 return self.submit_to_cluster_no_splitting(job_list)
216 elif self.cmd.cluster_mode == 0:
217 return self.submit_to_cluster_no_splitting(job_list)
218 elif self.cmd.cluster_mode == 2 and self.cmd.options['nb_core'] == 1:
219 return self.submit_to_cluster_no_splitting(job_list)
220 else:
221 return self.submit_to_cluster_splitted(job_list)
222
223
225 """submit the survey without the parralelization.
226 This is the old mode which is still usefull in single core"""
227
228
229 self.write_parameter(parralelization=False, Pdirs=job_list.keys())
230
231
232
233 for Pdir, jobs in job_list.items():
234 jobs = list(jobs)
235 i=0
236 while jobs:
237 i+=1
238 to_submit = ['0']
239 for _ in range(self.combining_job_for_Pdir(Pdir)):
240 if jobs:
241 to_submit.append(jobs.pop(0))
242
243 self.cmd.launch_job(pjoin(self.me_dir, 'SubProcesses', 'survey.sh'),
244 argument=to_submit,
245 cwd=pjoin(self.me_dir,'SubProcesses' , Pdir))
246
247
249 """prepare the input_file for submitting the channel"""
250
251
252 if 'SubProcesses' not in Pdir:
253 Pdir = pjoin(self.me_dir, 'SubProcesses', Pdir)
254
255
256 self.splitted_Pdir[(Pdir, G)] = int(nb_job)
257
258
259
260 run_card = self.cmd.run_card
261 options = {'event' : submit_ps,
262 'maxiter': 1,
263 'miniter': 1,
264 'accuracy': self.cmd.opts['accuracy'],
265 'helicity': run_card['nhel_survey'] if 'nhel_survey' in run_card \
266 else run_card['nhel'],
267 'gridmode': -2,
268 'channel' : G
269 }
270
271 Gdir = pjoin(Pdir, 'G%s' % G)
272 self.write_parameter_file(pjoin(Gdir, 'input_app.txt'), options)
273
274
275 assert os.path.exists(pjoin(Gdir, "ftn25"))
276
277
278
279
280 packet = cluster.Packet((Pdir, G, step+1),
281 self.combine_iteration,
282 (Pdir, G, step+1))
283
284 if step ==0:
285 self.lastoffset[(Pdir, G)] = 0
286
287
288 for i in xrange(int(nb_job)):
289 name = "G%s_%s" % (G,i+1)
290 self.lastoffset[(Pdir, G)] += 1
291 offset = self.lastoffset[(Pdir, G)]
292 self.cmd.launch_job(pjoin(self.me_dir, 'SubProcesses', 'refine_splitted.sh'),
293 argument=[name, 'G%s'%G, offset],
294 cwd= Pdir,
295 packet_member=packet)
296
297
299 """ submit the version of the survey with splitted grid creation
300 """
301
302
303
304
305 for Pdir, jobs in job_list.items():
306 if self.splitted_for_dir(Pdir, jobs[0]) <= 1:
307 return self.submit_to_cluster_no_splitting({Pdir:jobs})
308
309 self.write_parameter(parralelization=True, Pdirs=[Pdir])
310
311
312 for job in jobs:
313 packet = cluster.Packet((Pdir, job, 1), self.combine_iteration, (Pdir, job, 1))
314 for i in range(self.splitted_for_dir(Pdir, job)):
315 self.cmd.launch_job(pjoin(self.me_dir, 'SubProcesses', 'survey.sh'),
316 argument=[i+1, job],
317 cwd=pjoin(self.me_dir,'SubProcesses' , Pdir),
318 packet_member=packet)
319
321
322 grid_calculator, cross, error = self.combine_grid(Pdir, G, step)
323
324
325 nb_events = grid_calculator.target_evt
326
327 Gdirs = []
328 for i in range(self.splitted_for_dir(Pdir, G)):
329 path = pjoin(Pdir, "G%s_%s" % (G, i+1))
330 Gdirs.append(path)
331
332
333
334
335
336 need_submit = False
337 if step < self.min_iterations and cross != 0:
338 if step == 1:
339 need_submit = True
340 else:
341 across = self.abscross[(Pdir,G)]/(self.sigma[(Pdir,G)]+1e-99)
342 tot_across = self.get_current_axsec()
343 if across / tot_across < 1e-6:
344 need_submit = False
345 elif error < self.cmd.opts['accuracy'] / 100:
346 need_submit = False
347 else:
348 need_submit = True
349
350 elif step >= self.cmd.opts['iterations']:
351 need_submit = False
352 elif self.cmd.opts['accuracy'] < 0:
353
354 raise Exception, "Not Implemented"
355 elif self.abscross[(Pdir,G)] == 0:
356 need_submit = False
357 else:
358 across = self.abscross[(Pdir,G)]/(self.sigma[(Pdir,G)]+1e-99)
359 tot_across = self.get_current_axsec()
360 if across == 0:
361 need_submit = False
362 elif across / tot_across < 1e-5:
363 need_submit = False
364 elif error > self.cmd.opts['accuracy']:
365 need_submit = True
366 else:
367 need_submit = False
368
369
370 if cross:
371 grid_calculator.write_grid_for_submission(Pdir,G,
372 self.splitted_for_dir(Pdir, G),
373 nb_events,mode=self.mode,
374 conservative_factor=5.0)
375
376 xsec_format = '.%ig'%(max(3,int(math.log10(1.0/float(error)))+2)
377 if float(cross)!=0.0 and float(error)!=0.0 else 8)
378 if need_submit:
379 message = "%%s/G%%s is at %%%s +- %%.3g pb. Now submitting iteration #%s."%(xsec_format, step+1)
380 logger.info(message%\
381 (os.path.basename(Pdir), G, float(cross),
382 float(error)*float(cross)))
383 self.resubmit_survey(Pdir,G, Gdirs, step)
384 elif cross:
385 logger.info("Survey finished for %s/G%s at %s"%(
386 os.path.basename(Pdir),G,('%%%s +- %%.3g pb'%xsec_format))%
387 (float(cross), float(error)*float(cross)))
388
389 newGpath = pjoin(self.me_dir,'SubProcesses' , Pdir, 'G%s' % G)
390 if not os.path.exists(newGpath):
391 os.mkdir(newGpath)
392
393
394 files.cp(pjoin(Gdirs[0], 'ftn25'),
395 pjoin(self.me_dir,'SubProcesses' , Pdir, 'G%s' % G, 'ftn26'))
396
397
398 fsock = open(pjoin(newGpath, 'events.lhe'), 'w')
399 for Gdir in Gdirs:
400 fsock.write(open(pjoin(Gdir, 'events.lhe')).read())
401
402
403 files.cp(pjoin(Gdirs[0], 'log.txt'),
404 pjoin(self.me_dir,'SubProcesses' , Pdir, 'G%s' % G))
405
406
407
408 self.write_results(grid_calculator, cross, error, Pdir, G, step)
409 else:
410 logger.info("Survey finished for %s/G%s [0 cross]", os.path.basename(Pdir),G)
411
412 Gdir = pjoin(self.me_dir,'SubProcesses' , Pdir, 'G%s' % G)
413 if not os.path.exists(Gdir):
414 os.mkdir(Gdir)
415
416 files.cp(pjoin(Gdirs[0], 'log.txt'), Gdir)
417
418 self.write_results(grid_calculator, cross, error, Pdir, G, step)
419
420 return 0
421
422 - def combine_grid(self, Pdir, G, step, exclude_sub_jobs=[]):
423 """ exclude_sub_jobs is to remove some of the subjobs if a numerical
424 issue is detected in one of them. Warning is issue when this occurs.
425 """
426
427
428 grid_calculator = combine_grid.grid_information(self.run_card['nhel'])
429
430 for i in range(self.splitted_for_dir(Pdir, G)):
431 if i in exclude_sub_jobs:
432 continue
433 path = pjoin(Pdir, "G%s_%s" % (G, i+1))
434 fsock = misc.mult_try_open(pjoin(path, 'results.dat'))
435 one_result = grid_calculator.add_results_information(fsock)
436 fsock.close()
437 if one_result.axsec == 0:
438 grid_calculator.onefail = True
439 continue
440 fsock = misc.mult_try_open(pjoin(path, 'grid_information'))
441 grid_calculator.add_one_grid_information(fsock)
442 fsock.close()
443 os.remove(pjoin(path, 'results.dat'))
444
445
446
447
448
449
450 cross, across, sigma = grid_calculator.get_cross_section()
451
452
453
454 maxwgt = grid_calculator.get_max_wgt(0.01)
455 if maxwgt:
456 nunwgt = grid_calculator.get_nunwgt(maxwgt)
457
458
459
460
461 apply_instability_security = False
462 rel_contrib = 0.0
463 if (self.__class__ != gensym or step > 1):
464 Pdir_across = 0.0
465 Gdir_across = 0.0
466 for (mPdir,mG) in self.abscross.keys():
467 if mPdir == Pdir:
468 Pdir_across += (self.abscross[(mPdir,mG)]/
469 (self.sigma[(mPdir,mG)]+1e-99))
470 if mG == G:
471 Gdir_across += (self.abscross[(mPdir,mG)]/
472 (self.sigma[(mPdir,mG)]+1e-99))
473 rel_contrib = abs(Gdir_across/(Pdir_across+1e-99))
474 if rel_contrib > (1.0e-8) and \
475 nunwgt < 2 and len(grid_calculator.results) > 1:
476 apply_instability_security = True
477
478 if apply_instability_security:
479
480 th_maxwgt = [(r.th_maxwgt,i) for i,r in enumerate(grid_calculator.results)]
481 th_maxwgt.sort()
482 ratio = th_maxwgt[-1][0]/th_maxwgt[-2][0]
483 if ratio > 1e4:
484 logger.warning(
485 """"One Event with large weight have been found (ratio = %.3g) in channel G%s (with rel.contrib=%.3g).
486 This is likely due to numerical instabilities. The associated job is discarded to recover.
487 For offline investigation, the problematic discarded events are stored in:
488 %s"""%(ratio,G,rel_contrib,pjoin(Pdir,'DiscardedUnstableEvents')))
489 exclude_sub_jobs = list(exclude_sub_jobs)
490 exclude_sub_jobs.append(th_maxwgt[-1][1])
491 grid_calculator.results.run_statistics['skipped_subchannel'] += 1
492
493
494 gPath = pjoin(Pdir, "G%s_%s" % (G, th_maxwgt[-1][1]+1))
495 if os.path.isfile(pjoin(gPath,'events.lhe')):
496 lhe_file = lhe_parser.EventFile(pjoin(gPath,'events.lhe'))
497 discardedPath = pjoin(Pdir,'DiscardedUnstableEvents')
498 if not os.path.exists(discardedPath):
499 os.mkdir(discardedPath)
500 if os.path.isdir(discardedPath):
501
502
503 evtRecord = open(pjoin(discardedPath,'discarded_G%s.dat'%G),'a')
504 lhe_file.seek(0)
505 try:
506 evtRecord.write('\n'+str(max(lhe_file,key=lambda evt:abs(evt.wgt))))
507 except Exception:
508
509 lhe_file.close()
510 evtRecord.write(pjoin(gPath,'events.lhe').read())
511 evtRecord.close()
512
513 return self.combine_grid(Pdir, G, step, exclude_sub_jobs)
514
515
516 if across !=0:
517 if sigma != 0:
518 self.cross[(Pdir,G)] += cross**3/sigma**2
519 self.abscross[(Pdir,G)] += across * cross**2/sigma**2
520 self.sigma[(Pdir,G)] += cross**2/ sigma**2
521 self.chi2[(Pdir,G)] += cross**4/sigma**2
522
523 cross = self.cross[(Pdir,G)]/self.sigma[(Pdir,G)]
524 if step > 1:
525 error = math.sqrt(abs((self.chi2[(Pdir,G)]/cross**2 - \
526 self.sigma[(Pdir,G)])/(step-1))/self.sigma[(Pdir,G)])
527 else:
528 error = sigma/cross
529 else:
530 self.cross[(Pdir,G)] = cross
531 self.abscross[(Pdir,G)] = across
532 self.sigma[(Pdir,G)] = 0
533 self.chi2[(Pdir,G)] = 0
534 cross = self.cross[(Pdir,G)]
535 error = 0
536
537 else:
538 error = 0
539
540 grid_calculator.results.compute_values(update_statistics=True)
541 if (str(os.path.basename(Pdir)), G) in self.run_statistics:
542 self.run_statistics[(str(os.path.basename(Pdir)), G)]\
543 .aggregate_statistics(grid_calculator.results.run_statistics)
544 else:
545 self.run_statistics[(str(os.path.basename(Pdir)), G)] = \
546 grid_calculator.results.run_statistics
547
548 self.warnings_from_statistics(G, grid_calculator.results.run_statistics)
549 stats_msg = grid_calculator.results.run_statistics.nice_output(
550 '/'.join([os.path.basename(Pdir),'G%s'%G]))
551
552 if stats_msg:
553 logger.log(5, stats_msg)
554
555
556 for i in range(self.splitted_for_dir(Pdir, G)):
557 path = pjoin(Pdir, "G%s_%s" % (G, i+1))
558 try:
559 os.remove(pjoin(path, 'grid_information'))
560 except OSError, oneerror:
561 if oneerror.errno != 2:
562 raise
563 return grid_calculator, cross, error
564
566 """Possible warn user for worrying MadLoop stats for this channel."""
567
568 if stats['n_madloop_calls']==0:
569 return
570
571 EPS_fraction = float(stats['exceptional_points'])/stats['n_madloop_calls']
572
573 msg = "Channel %s has encountered a fraction of %.3g\n"+ \
574 "of numerically unstable loop matrix element computations\n"+\
575 "(which could not be rescued using quadruple precision).\n"+\
576 "The results might not be trusted."
577
578 if 0.01 > EPS_fraction > 0.001:
579 logger.warning(msg%(G,EPS_fraction))
580 elif EPS_fraction > 0.01:
581 logger.critical((msg%(G,EPS_fraction)).replace('might', 'can'))
582 raise Exception, (msg%(G,EPS_fraction)).replace('might', 'can')
583
585
586 across = 0
587 for (Pdir,G) in self.abscross:
588 across += self.abscross[(Pdir,G)]/(self.sigma[(Pdir,G)]+1e-99)
589 return across
590
591 - def write_results(self, grid_calculator, cross, error, Pdir, G, step):
592
593
594 if cross == 0:
595 abscross,nw, luminosity = 0, 0, 0
596 wgt, maxit,nunwgt, wgt, nevents = 0,0,0,0,0
597 maxwgt = 0
598 error = 0
599 else:
600 grid_calculator.results.compute_values()
601 abscross = self.abscross[(Pdir,G)]/self.sigma[(Pdir,G)]
602 nw = grid_calculator.results.nw
603 wgt = grid_calculator.results.wgt
604 maxit = step
605 wgt = 0
606 nevents = grid_calculator.results.nevents
607 maxwgt = grid_calculator.get_max_wgt()
608 nunwgt = grid_calculator.get_nunwgt()
609 luminosity = nunwgt/cross
610
611
612 def fstr(nb):
613 data = '%E' % nb
614 nb, power = data.split('E')
615 nb = float(nb) /10
616 power = int(power) + 1
617 return '%.5fE%+03i' %(nb,power)
618 line = '%s %s %s %i %i %i %i %s %s %s %s 0.0 0\n' % \
619 (fstr(cross), fstr(error*cross), fstr(error*cross),
620 nevents, nw, maxit,nunwgt,
621 fstr(luminosity), fstr(wgt), fstr(abscross), fstr(maxwgt))
622
623 fsock = open(pjoin(self.me_dir,'SubProcesses' , Pdir, 'G%s' % G,
624 'results.dat'),'w')
625 fsock.writelines(line)
626 fsock.close()
627
629 """submit the next iteration of the survey"""
630
631
632 run_card = self.cmd.run_card
633 options = {'event' : 2**(step) * self.cmd.opts['points'] / self.splitted_grid,
634 'maxiter': 1,
635 'miniter': 1,
636 'accuracy': self.cmd.opts['accuracy'],
637 'helicity': run_card['nhel_survey'] if 'nhel_survey' in run_card \
638 else run_card['nhel'],
639 'gridmode': -2,
640 'channel' : ''
641 }
642
643 if int(options['helicity']) == 1:
644 options['event'] = options['event'] * 2**(self.cmd.proc_characteristics['nexternal']//3)
645
646 for Gdir in Gdirs:
647 self.write_parameter_file(pjoin(Gdir, 'input_app.txt'), options)
648
649
650
651 packet = cluster.Packet((Pdir, G, step+1), self.combine_iteration, \
652 (Pdir, G, step+1))
653 nb_step = len(Gdirs) * (step+1)
654 for i,subdir in enumerate(Gdirs):
655 subdir = subdir.rsplit('_',1)[1]
656 subdir = int(subdir)
657 offset = nb_step+i+1
658 offset=str(offset)
659 tag = "%s.%s" % (subdir, offset)
660
661 self.cmd.launch_job(pjoin(self.me_dir, 'SubProcesses', 'survey.sh'),
662 argument=[tag, G],
663 cwd=pjoin(self.me_dir,'SubProcesses' , Pdir),
664 packet_member=packet)
665
666
667
668
670 """ """
671
672 template =""" %(event)s %(maxiter)s %(miniter)s !Number of events and max and min iterations
673 %(accuracy)s !Accuracy
674 %(gridmode)s !Grid Adjustment 0=none, 2=adjust
675 1 !Suppress Amplitude 1=yes
676 %(helicity)s !Helicity Sum/event 0=exact
677 %(channel)s """
678 options['event'] = int(options['event'])
679 open(path, 'w').write(template % options)
680
681
682
684 """Write the parameter of the survey run"""
685
686 run_card = self.cmd.run_card
687
688 options = {'event' : self.cmd.opts['points'],
689 'maxiter': self.cmd.opts['iterations'],
690 'miniter': self.min_iterations,
691 'accuracy': self.cmd.opts['accuracy'],
692 'helicity': run_card['nhel_survey'] if 'nhel_survey' in run_card \
693 else run_card['nhel'],
694 'gridmode': 2,
695 'channel': ''
696 }
697
698 if int(options['helicity'])== 1:
699 options['event'] = options['event'] * 2**(self.cmd.proc_characteristics['nexternal']//3)
700
701 if parralelization:
702 options['gridmode'] = -2
703 options['maxiter'] = 1
704 options['miniter'] = 1
705 options['event'] /= self.splitted_grid
706
707 if not Pdirs:
708 Pdirs = self.subproc
709
710 for Pdir in Pdirs:
711 path =pjoin(Pdir, 'input_app.txt')
712 self.write_parameter_file(path, options)
713
717
718
719
720 gen_events_security = 1.2
721 combining_job = 0
722 max_request_event = 1000
723 max_event_in_iter = 5000
724 min_event_in_iter = 1000
725 max_splitting = 130
726 min_iter = 3
727 max_iter = 9
728 keep_grid_for_refine = False
729
730
731 @ staticmethod
734
735
737 """Choose in which type of refine we want to be"""
738
739 if cmd.proc_characteristics['loop_induced']:
740 return super(gen_ximprove, cls).__new__(gen_ximprove_share, cmd, opt)
741 elif gen_ximprove.format_variable(cmd.run_card['gridpack'], bool):
742 raise Exception, "Not implemented"
743 elif cmd.run_card["job_strategy"] == 2:
744 return super(gen_ximprove, cls).__new__(gen_ximprove_share, cmd, opt)
745 else:
746 return super(gen_ximprove, cls).__new__(gen_ximprove_v4, cmd, opt)
747
748
750
751 try:
752 super(gen_ximprove, self).__init__(cmd, opt)
753 except TypeError:
754 pass
755
756 self.run_statistics = {}
757 self.cmd = cmd
758 self.run_card = cmd.run_card
759 run_card = self.run_card
760 self.me_dir = cmd.me_dir
761
762
763 self.gridpack = run_card['gridpack']
764 self.nhel = run_card['nhel']
765 if "nhel_refine" in run_card:
766 self.nhel = run_card["nhel_refine"]
767
768 if self.run_card['refine_evt_by_job'] != -1:
769 self.max_request_event = run_card['refine_evt_by_job']
770
771
772
773 self.gen_events = True
774 self.min_iter = 3
775 self.parralel = False
776
777 self.err_goal = 0.01
778 self.max_np = 9
779 self.split_channels = False
780
781 self.nreq = 2000
782 self.iseed = 4321
783 self.ngran = 1
784
785
786 self.results = 0
787
788 if isinstance(opt, dict):
789 self.configure(opt)
790 elif isinstance(opt, bannermod.GridpackCard):
791 self.configure_gridpack(opt)
792
795
810
811
832
834 """not needed but for gridpack --which is not handle here for the moment"""
835 return
836
837
839 """return the list of channel that need to be improved"""
840
841 assert self.err_goal >=1
842 self.err_goal = int(self.err_goal)
843
844 goal_lum = self.err_goal/(self.results.axsec+1e-99)
845 logger.info('Effective Luminosity %s pb^-1', goal_lum)
846
847 all_channels = sum([list(P) for P in self.results],[])
848 all_channels.sort(cmp= lambda x,y: 1 if y.get('luminosity') - \
849 x.get('luminosity') > 0 else -1)
850
851 to_refine = []
852 for C in all_channels:
853 if C.get('axsec') == 0:
854 continue
855 if goal_lum/(C.get('luminosity')+1e-99) >= 1 + (self.gen_events_security-1)/2:
856 logger.debug("channel %s is at %s (%s) (%s pb)", C.name, C.get('luminosity'), goal_lum/(C.get('luminosity')+1e-99), C.get('xsec'))
857 to_refine.append(C)
858 elif C.get('xerr') > max(C.get('axsec'),
859 (1/(100*math.sqrt(self.err_goal)))*all_channels[-1].get('axsec')):
860 to_refine.append(C)
861
862 logger.info('need to improve %s channels' % len(to_refine))
863 return goal_lum, to_refine
864
866 """update the html from this object since it contains all the information"""
867
868
869 run = self.cmd.results.current['run_name']
870 if not os.path.exists(pjoin(self.cmd.me_dir, 'HTML', run)):
871 os.mkdir(pjoin(self.cmd.me_dir, 'HTML', run))
872
873 unit = self.cmd.results.unit
874 P_text = ""
875 if self.results:
876 Presults = self.results
877 else:
878 self.results = sum_html.collect_result(self.cmd, None)
879 Presults = self.results
880
881 for P_comb in Presults:
882 P_text += P_comb.get_html(run, unit, self.cmd.me_dir)
883
884 Presults.write_results_dat(pjoin(self.cmd.me_dir,'SubProcesses', 'results.dat'))
885
886 fsock = open(pjoin(self.cmd.me_dir, 'HTML', run, 'results.html'),'w')
887 fsock.write(sum_html.results_header)
888 fsock.write('%s <dl>' % Presults.get_html(run, unit, self.cmd.me_dir))
889 fsock.write('%s </dl></body>' % P_text)
890
891 self.cmd.results.add_detail('cross', Presults.xsec)
892 self.cmd.results.add_detail('error', Presults.xerru)
893
894 return Presults.xsec, Presults.xerru
895
918
920
921 for path in misc.glob(pjoin('*', '*','multijob.dat'), pjoin(self.me_dir, 'SubProcesses')):
922 open(path,'w').write('0\n')
923
925 """ """
926 if nb_split <=1:
927 return
928 f = open(pjoin(self.me_dir, 'SubProcesses', Channel.get('name'), 'multijob.dat'), 'w')
929 f.write('%i\n' % nb_split)
930 f.close()
931
941
942 alphabet = "abcdefghijklmnopqrstuvwxyz"
944 """generate the script in order to generate a given number of event"""
945
946
947
948 goal_lum, to_refine = self.find_job_for_event()
949
950
951 self.reset_multijob()
952
953 jobs = []
954
955
956
957 if self.combining_job >1:
958
959 new_order = []
960 if self.combining_job % 2 == 0:
961 for i in range(len(to_refine) //2):
962 new_order.append(to_refine[i])
963 new_order.append(to_refine[-i-1])
964 if len(to_refine) % 2:
965 new_order.append(to_refine[i+1])
966 else:
967 for i in range(len(to_refine) //3):
968 new_order.append(to_refine[i])
969 new_order.append(to_refine[-2*i-1])
970 new_order.append(to_refine[-2*i-2])
971 if len(to_refine) % 3 == 1:
972 new_order.append(to_refine[i+1])
973 elif len(to_refine) % 3 == 2:
974 new_order.append(to_refine[i+2])
975
976 assert set([id(C) for C in to_refine]) == set([id(C) for C in new_order])
977 to_refine = new_order
978
979
980
981 for C in to_refine:
982
983 needed_event = goal_lum*C.get('axsec')
984 nb_split = int(max(1,((needed_event-1)// self.max_request_event) +1))
985 if not self.split_channels:
986 nb_split = 1
987 if nb_split > self.max_splitting:
988 nb_split = self.max_splitting
989 nb_split=max(1, nb_split)
990
991
992
993 if C.get('nunwgt') > 0:
994 nevents = needed_event / nb_split * (C.get('nevents') / C.get('nunwgt'))
995
996 nevents = int(nevents / (2**self.min_iter-1))
997 else:
998 nevents = self.max_event_in_iter
999
1000 if nevents < self.min_event_in_iter:
1001 nb_split = int(nb_split * nevents / self.min_event_in_iter) + 1
1002 nevents = self.min_event_in_iter
1003
1004
1005 nevents = max(self.min_event_in_iter, min(self.max_event_in_iter, nevents))
1006 logger.debug("%s : need %s event. Need %s split job of %s points", C.name, needed_event, nb_split, nevents)
1007
1008
1009
1010 self.write_multijob(C, nb_split)
1011
1012 packet = cluster.Packet((C.parent_name, C.name),
1013 combine_runs.CombineRuns,
1014 (pjoin(self.me_dir, 'SubProcesses', C.parent_name)),
1015 {"subproc": C.name, "nb_split":nb_split})
1016
1017
1018
1019 info = {'name': self.cmd.results.current['run_name'],
1020 'script_name': 'unknown',
1021 'directory': C.name,
1022 'P_dir': C.parent_name,
1023 'offset': 1,
1024 'nevents': nevents,
1025 'maxiter': self.max_iter,
1026 'miniter': self.min_iter,
1027 'precision': -goal_lum/nb_split,
1028 'nhel': self.run_card['nhel'],
1029 'channel': C.name.replace('G',''),
1030 'grid_refinment' : 0,
1031 'base_directory': '',
1032 'packet': packet,
1033 }
1034
1035 if nb_split == 1:
1036 jobs.append(info)
1037 else:
1038 for i in range(nb_split):
1039 new_info = dict(info)
1040 new_info['offset'] = i+1
1041 new_info['directory'] += self.alphabet[i % 26] + str((i+1)//26)
1042 if self.keep_grid_for_refine:
1043 new_info['base_directory'] = info['directory']
1044 jobs.append(new_info)
1045
1046 self.create_ajob(pjoin(self.me_dir, 'SubProcesses', 'refine.sh'), jobs)
1047
1048
1050 """create the ajob"""
1051
1052 if not jobs:
1053 return
1054
1055
1056 P2job= collections.defaultdict(list)
1057 for j in jobs:
1058 P2job[j['P_dir']].append(j)
1059 if len(P2job) >1:
1060 for P in P2job.values():
1061 self.create_ajob(template, P)
1062 return
1063
1064
1065 path = pjoin(self.me_dir, 'SubProcesses' ,jobs[0]['P_dir'])
1066
1067 template_text = open(template, 'r').read()
1068
1069
1070 if self.combining_job > 1:
1071 skip1=0
1072 n_channels = len(jobs)
1073 nb_sub = n_channels // self.combining_job
1074 nb_job_in_last = n_channels % self.combining_job
1075 if nb_job_in_last:
1076 nb_sub +=1
1077 skip1 = self.combining_job - nb_job_in_last
1078 if skip1 > nb_sub:
1079 self.combining_job -=1
1080 return self.create_ajob(template, jobs)
1081 combining_job = self.combining_job
1082 else:
1083
1084
1085 skip1=0
1086 combining_job =1
1087 nb_sub = len(jobs)
1088
1089
1090 nb_use = 0
1091 for i in range(nb_sub):
1092 script_number = i+1
1093 if i < skip1:
1094 nb_job = combining_job -1
1095 else:
1096 nb_job = combining_job
1097 fsock = open(pjoin(path, 'ajob%i' % script_number), 'w')
1098 for j in range(nb_use, nb_use + nb_job):
1099 if j> len(jobs):
1100 break
1101 info = jobs[j]
1102 info['script_name'] = 'ajob%i' % script_number
1103 if "base_directory" not in info:
1104 info["base_directory"] = "./"
1105 fsock.write(template_text % info)
1106 nb_use += nb_job
1107
1109 """create the ajob to achieve a give precision on the total cross-section"""
1110
1111
1112 assert self.err_goal <=1
1113 xtot = abs(self.results.xsec)
1114 logger.info("Working on precision: %s %%" %(100*self.err_goal))
1115 all_channels = sum([list(P) for P in self.results if P.mfactor],[])
1116 limit = self.err_goal * xtot / len(all_channels)
1117 to_refine = []
1118 rerr = 0
1119 for C in all_channels:
1120 cerr = C.mfactor*(C.xerru + len(all_channels)*C.xerrc)
1121 if cerr > abs(limit):
1122 to_refine.append(C)
1123 else:
1124 rerr += cerr
1125 rerr *=rerr
1126 if not len(to_refine):
1127 return
1128
1129
1130 limit = math.sqrt((self.err_goal * xtot)**2 - rerr/math.sqrt(len(to_refine)))
1131 for C in to_refine[:]:
1132 cerr = C.mfactor*(C.xerru + len(to_refine)*C.xerrc)
1133 if cerr < limit:
1134 to_refine.remove(C)
1135
1136
1137 logger.info('need to improve %s channels' % len(to_refine))
1138
1139
1140 jobs = []
1141
1142
1143
1144 for C in to_refine:
1145
1146
1147 yerr = C.mfactor*(C.xerru+len(to_refine)*C.xerrc)
1148 nevents = 0.2*C.nevents*(yerr/limit)**2
1149
1150 nb_split = int((nevents*(C.nunwgt/C.nevents)/self.max_request_event/ (2**self.min_iter-1))**(2/3))
1151 nb_split = max(nb_split, 1)
1152
1153 if nb_split > self.max_splitting:
1154 nb_split = self.max_splitting
1155
1156 if nb_split >1:
1157 nevents = nevents / nb_split
1158 self.write_multijob(C, nb_split)
1159
1160 nevents = min(self.min_event_in_iter, max(self.max_event_in_iter, nevents))
1161
1162
1163
1164 info = {'name': self.cmd.results.current['run_name'],
1165 'script_name': 'unknown',
1166 'directory': C.name,
1167 'P_dir': C.parent_name,
1168 'offset': 1,
1169 'nevents': nevents,
1170 'maxiter': self.max_iter,
1171 'miniter': self.min_iter,
1172 'precision': yerr/math.sqrt(nb_split)/(C.get('xsec')+ yerr),
1173 'nhel': self.run_card['nhel'],
1174 'channel': C.name.replace('G',''),
1175 'grid_refinment' : 1
1176 }
1177
1178 if nb_split == 1:
1179 jobs.append(info)
1180 else:
1181 for i in range(nb_split):
1182 new_info = dict(info)
1183 new_info['offset'] = i+1
1184 new_info['directory'] += self.alphabet[i % 26] + str((i+1)//26)
1185 jobs.append(new_info)
1186 self.create_ajob(pjoin(self.me_dir, 'SubProcesses', 'refine.sh'), jobs)
1187
1189 """update the html from this object since it contains all the information"""
1190
1191
1192 run = self.cmd.results.current['run_name']
1193 if not os.path.exists(pjoin(self.cmd.me_dir, 'HTML', run)):
1194 os.mkdir(pjoin(self.cmd.me_dir, 'HTML', run))
1195
1196 unit = self.cmd.results.unit
1197 P_text = ""
1198 if self.results:
1199 Presults = self.results
1200 else:
1201 self.results = sum_html.collect_result(self.cmd, None)
1202 Presults = self.results
1203
1204 for P_comb in Presults:
1205 P_text += P_comb.get_html(run, unit, self.cmd.me_dir)
1206
1207 Presults.write_results_dat(pjoin(self.cmd.me_dir,'SubProcesses', 'results.dat'))
1208
1209 fsock = open(pjoin(self.cmd.me_dir, 'HTML', run, 'results.html'),'w')
1210 fsock.write(sum_html.results_header)
1211 fsock.write('%s <dl>' % Presults.get_html(run, unit, self.cmd.me_dir))
1212 fsock.write('%s </dl></body>' % P_text)
1213
1214 self.cmd.results.add_detail('cross', Presults.xsec)
1215 self.cmd.results.add_detail('error', Presults.xerru)
1216
1217 return Presults.xsec, Presults.xerru
1218
1243
1258
1260 """Doing the refine in multicore. Each core handle a couple of PS point."""
1261
1262 nb_ps_by_job = 2000
1263 mode = "refine"
1264 gen_events_security = 1.15
1265
1266
1267
1269
1270 super(gen_ximprove_share, self).__init__(*args, **opts)
1271 self.generated_events = {}
1272 self.splitted_for_dir = lambda x,y : self.splitted_Pdir[(x,y)]
1273
1274
1276 """generate the script in order to generate a given number of event"""
1277
1278
1279
1280 goal_lum, to_refine = self.find_job_for_event()
1281 self.goal_lum = goal_lum
1282
1283
1284 total_ps_points = 0
1285 channel_to_ps_point = []
1286 for C in to_refine:
1287
1288 try:
1289 os.remove(pjoin(self.me_dir, "SubProcesses",C.parent_name, C.name, "events.lhe"))
1290 except:
1291 pass
1292
1293
1294 needed_event = goal_lum*C.get('axsec')
1295 if needed_event == 0:
1296 continue
1297
1298 if C.get('nunwgt') > 0:
1299 nevents = needed_event * (C.get('nevents') / C.get('nunwgt'))
1300
1301 nevents = int(nevents / (2**self.min_iter-1))
1302 else:
1303 nb_split = int(max(1,((needed_event-1)// self.max_request_event) +1))
1304 if not self.split_channels:
1305 nb_split = 1
1306 if nb_split > self.max_splitting:
1307 nb_split = self.max_splitting
1308 nevents = self.max_event_in_iter * self.max_splitting
1309 else:
1310 nevents = self.max_event_in_iter * nb_split
1311
1312 if nevents > self.max_splitting*self.max_event_in_iter:
1313 logger.warning("Channel %s/%s has a very low efficiency of unweighting. Might not be possible to reach target" % \
1314 (C.name, C.parent_name))
1315 nevents = self.max_event_in_iter * self.max_splitting
1316
1317 total_ps_points += nevents
1318 channel_to_ps_point.append((C, nevents))
1319
1320 if self.cmd.options["run_mode"] == 1:
1321 if self.cmd.options["cluster_size"]:
1322 nb_ps_by_job = total_ps_points /int(self.cmd.options["cluster_size"])
1323 else:
1324 nb_ps_by_job = self.nb_ps_by_job
1325 elif self.cmd.options["run_mode"] == 2:
1326 remain = total_ps_points % self.cmd.options["nb_core"]
1327 if remain:
1328 nb_ps_by_job = 1 + (total_ps_points - remain) / self.cmd.options["nb_core"]
1329 else:
1330 nb_ps_by_job = total_ps_points / self.cmd.options["nb_core"]
1331 else:
1332 nb_ps_by_job = self.nb_ps_by_job
1333
1334 nb_ps_by_job = int(max(nb_ps_by_job, 500))
1335
1336 for C, nevents in channel_to_ps_point:
1337 if nevents % nb_ps_by_job:
1338 nb_job = 1 + int(nevents // nb_ps_by_job)
1339 else:
1340 nb_job = int(nevents // nb_ps_by_job)
1341 submit_ps = min(nevents, nb_ps_by_job)
1342 if nb_job == 1:
1343 submit_ps = max(submit_ps, self.min_event_in_iter)
1344 self.create_resubmit_one_iter(C.parent_name, C.name[1:], submit_ps, nb_job, step=0)
1345 needed_event = goal_lum*C.get('xsec')
1346 logger.debug("%s/%s : need %s event. Need %s split job of %s points", C.parent_name, C.name, needed_event, nb_job, submit_ps)
1347
1348
1350
1351 grid_calculator, cross, error = self.combine_grid(Pdir, G, step)
1352
1353
1354 Gdirs = []
1355 for i in range(self.splitted_for_dir(Pdir, G)):
1356 path = pjoin(Pdir, "G%s_%s" % (G, i+1))
1357 Gdirs.append(path)
1358 assert len(grid_calculator.results) == len(Gdirs) == self.splitted_for_dir(Pdir, G)
1359
1360
1361
1362 needed_event = cross * self.goal_lum
1363 if needed_event == 0:
1364 return 0
1365
1366
1367 if self.err_goal >=1:
1368 if needed_event > self.gen_events_security * self.err_goal:
1369 needed_event = int(self.gen_events_security * self.err_goal)
1370
1371 if (Pdir, G) in self.generated_events:
1372 old_nunwgt, old_maxwgt = self.generated_events[(Pdir, G)]
1373 else:
1374 old_nunwgt, old_maxwgt = 0, 0
1375
1376 if old_nunwgt == 0 and os.path.exists(pjoin(Pdir,"G%s" % G, "events.lhe")):
1377
1378 lhe = lhe_parser.EventFile(pjoin(Pdir,"G%s" % G, "events.lhe"))
1379 old_nunwgt = lhe.unweight(None, trunc_error=0.005, log_level=0)
1380 old_maxwgt = lhe.max_wgt
1381
1382
1383
1384 maxwgt = max(grid_calculator.get_max_wgt(), old_maxwgt)
1385 new_evt = grid_calculator.get_nunwgt(maxwgt)
1386 efficiency = new_evt / sum([R.nevents for R in grid_calculator.results])
1387 nunwgt = old_nunwgt * old_maxwgt / maxwgt
1388 nunwgt += new_evt
1389
1390
1391 one_iter_nb_event = grid_calculator.get_nunwgt()
1392 drop_previous_iteration = False
1393
1394 n_target_one_iter = (needed_event-one_iter_nb_event) / ( one_iter_nb_event/ sum([R.nevents for R in grid_calculator.results]))
1395 n_target_combined = (needed_event-nunwgt) / efficiency
1396 if n_target_one_iter < n_target_combined:
1397
1398
1399 drop_previous_iteration = True
1400 nunwgt = one_iter_nb_event
1401 maxwgt = grid_calculator.get_max_wgt()
1402 new_evt = nunwgt
1403 efficiency = ( one_iter_nb_event/ sum([R.nevents for R in grid_calculator.results]))
1404
1405 try:
1406 if drop_previous_iteration:
1407 raise IOError
1408 output_file = open(pjoin(Pdir,"G%s" % G, "events.lhe"), 'a')
1409 except IOError:
1410 output_file = open(pjoin(Pdir,"G%s" % G, "events.lhe"), 'w')
1411
1412 misc.call(["cat"] + [pjoin(d, "events.lhe") for d in Gdirs],
1413 stdout=output_file)
1414 output_file.close()
1415
1416
1417 if nunwgt < 0.6 * needed_event and step > self.min_iter:
1418 lhe = lhe_parser.EventFile(output_file.name)
1419 old_nunwgt =nunwgt
1420 nunwgt = lhe.unweight(None, trunc_error=0.01, log_level=0)
1421
1422
1423 self.generated_events[(Pdir, G)] = (nunwgt, maxwgt)
1424
1425
1426
1427 if nunwgt >= int(0.96*needed_event)+1:
1428
1429 logger.info("found enough event for %s/G%s" % (os.path.basename(Pdir), G))
1430 self.write_results(grid_calculator, cross, error, Pdir, G, step, efficiency)
1431 return 0
1432 elif step >= self.max_iter:
1433 logger.debug("fail to find enough event")
1434 self.write_results(grid_calculator, cross, error, Pdir, G, step, efficiency)
1435 return 0
1436
1437 nb_split_before = len(grid_calculator.results)
1438 nevents = grid_calculator.results[0].nevents
1439 if nevents == 0:
1440 nevents = max(g.nevents for g in grid_calculator.results)
1441
1442 need_ps_point = (needed_event - nunwgt)/(efficiency+1e-99)
1443 need_job = need_ps_point // nevents + 1
1444
1445 if step < self.min_iter:
1446
1447 job_at_first_iter = nb_split_before/2**(step-1)
1448 expected_total_job = job_at_first_iter * (2**self.min_iter-1)
1449 done_job = job_at_first_iter * (2**step-1)
1450 expected_remaining_job = expected_total_job - done_job
1451
1452 logger.debug("efficiency status (smaller is better): %s", need_job/expected_remaining_job)
1453
1454 need_job = min(need_job, expected_remaining_job*1.25)
1455
1456 nb_job = (need_job-0.5)//(2**(self.min_iter-step)-1) + 1
1457 nb_job = max(1, nb_job)
1458 grid_calculator.write_grid_for_submission(Pdir,G,
1459 self.splitted_for_dir(Pdir, G), nb_job*nevents ,mode=self.mode,
1460 conservative_factor=self.max_iter)
1461 logger.info("%s/G%s is at %i/%i (%.2g%%) event. Resubmit %i job at iteration %i." \
1462 % (os.path.basename(Pdir), G, int(nunwgt),int(needed_event)+1,
1463 (float(nunwgt)/needed_event)*100.0 if needed_event>0.0 else 0.0,
1464 nb_job, step))
1465 self.create_resubmit_one_iter(Pdir, G, nevents, nb_job, step)
1466
1467
1468 elif step < self.max_iter:
1469 if step + 1 == self.max_iter:
1470 need_job = 1.20 * need_job
1471
1472 nb_job = int(min(need_job, nb_split_before*1.5))
1473 grid_calculator.write_grid_for_submission(Pdir,G,
1474 self.splitted_for_dir(Pdir, G), nb_job*nevents ,mode=self.mode,
1475 conservative_factor=self.max_iter)
1476
1477
1478 logger.info("%s/G%s is at %i/%i ('%.2g%%') event. Resubmit %i job at iteration %i." \
1479 % (os.path.basename(Pdir), G, int(nunwgt),int(needed_event)+1,
1480 (float(nunwgt)/needed_event)*100.0 if needed_event>0.0 else 0.0,
1481 nb_job, step))
1482 self.create_resubmit_one_iter(Pdir, G, nevents, nb_job, step)
1483
1484
1485
1486 return 0
1487
1488
1489 - def write_results(self, grid_calculator, cross, error, Pdir, G, step, efficiency):
1490
1491
1492 if cross == 0:
1493 abscross,nw, luminosity = 0, 0, 0
1494 wgt, maxit,nunwgt, wgt, nevents = 0,0,0,0,0
1495 error = 0
1496 else:
1497 grid_calculator.results.compute_values()
1498 abscross = self.abscross[(Pdir,G)]/self.sigma[(Pdir,G)]
1499 nunwgt, wgt = self.generated_events[(Pdir, G)]
1500 nw = int(nunwgt / efficiency)
1501 nunwgt = int(nunwgt)
1502 maxit = step
1503 nevents = nunwgt
1504
1505 luminosity = nunwgt/cross
1506
1507
1508 def fstr(nb):
1509 data = '%E' % nb
1510 nb, power = data.split('E')
1511 nb = float(nb) /10
1512 power = int(power) + 1
1513 return '%.5fE%+03i' %(nb,power)
1514 line = '%s %s %s %i %i %i %i %s %s %s 0.0 0.0 0\n' % \
1515 (fstr(cross), fstr(error*cross), fstr(error*cross),
1516 nevents, nw, maxit,nunwgt,
1517 fstr(luminosity), fstr(wgt), fstr(abscross))
1518
1519 fsock = open(pjoin(self.me_dir,'SubProcesses' , Pdir, 'G%s' % G,
1520 'results.dat'),'w')
1521 fsock.writelines(line)
1522 fsock.close()
1523