Merge lp:~maddm/mg5amcnlo/maddm_dev2 into lp:~mg5core1/mg5amcnlo/2.6.2
- maddm_dev2
- Merge into 2.6.2
Status: | Merged |
---|---|
Approved by: | Valentin Hirschi |
Approved revision: | 393 |
Merged at revision: | 333 |
Proposed branch: | lp:~maddm/mg5amcnlo/maddm_dev2 |
Merge into: | lp:~mg5core1/mg5amcnlo/2.6.2 |
Diff against target: |
3994 lines (+1303/-702) 34 files modified
MadSpin/decay.py (+1/-1) MadSpin/interface_madspin.py (+1/-0) Template/LO/Cards/run_card.dat (+3/-0) Template/LO/SubProcesses/genps.f (+9/-10) Template/LO/SubProcesses/setcuts.f (+4/-2) Template/LO/bin/generate_events (+9/-9) Template/LO/bin/madevent (+52/-47) Template/NLO/Cards/run_card.dat (+3/-0) UpdateNotes.txt (+14/-1) VERSION (+2/-2) madgraph/core/base_objects.py (+10/-4) madgraph/interface/.mg5_logging.conf (+13/-3) madgraph/interface/amcatnlo_run_interface.py (+3/-3) madgraph/interface/coloring_logging.py (+20/-4) madgraph/interface/common_run_interface.py (+522/-245) madgraph/interface/extended_cmd.py (+111/-53) madgraph/interface/launch_ext_program.py (+67/-65) madgraph/interface/loop_interface.py (+1/-1) madgraph/interface/madevent_interface.py (+2/-2) madgraph/interface/madgraph_interface.py (+149/-115) madgraph/interface/madweight_interface.py (+1/-1) madgraph/interface/master_interface.py (+7/-4) madgraph/interface/reweight_interface.py (+47/-23) madgraph/interface/tutorial_text.py (+11/-8) madgraph/iolibs/export_v4.py (+11/-1) madgraph/iolibs/file_writers.py (+8/-3) madgraph/iolibs/files.py (+1/-0) madgraph/loop/loop_exporters.py (+2/-2) madgraph/various/banner.py (+92/-64) madgraph/various/misc.py (+48/-2) models/__init__.py (+5/-7) models/check_param_card.py (+11/-8) models/usermod.py (+62/-12) tests/acceptance_tests/test_cmd_madevent.py (+1/-0) |
To merge this branch: | bzr merge lp:~maddm/mg5amcnlo/maddm_dev2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Valentin Hirschi | Pending | ||
Review via email: mp+342008@code.launchpad.net |
Commit message
Description of the change
Change to increase plugin flexibility
this include
1) improve the tutorial capabilities
2) refactor the question about the card edition to have it more manageable
3) more possiblity for help message
4) possibility to control an entry of the cards to check that they are in an allowed range
5) allow --loop_filter for loop-induced [should have done that directly in 2.6.2 but ok]
6) New possibility for handling the RunWeb file (both via context manager or decorator)
-> before crashing it checks if the associated pid is still running.
-> use context manager for LO but NOT for gridpack/NLO.
7) fix some issue with add model (for some NLO model)
8) add "update to_full" to display all hidden options of the run_card
Olivier Mattelaer (olivier-mattelaer) wrote : | # |
- 380. By olivier-mattelaer
-
allow plugin to have control on detect_card + better handling of the edit/add functionality
- 381. By olivier-mattelaer
-
refactoring to allow the plugin to define itself how the pdg of the <init> block should be written
- 382. By olivier-mattelaer
-
add hidden syntax import model --last: loading last modified model
- 383. By olivier-mattelaer
-
add a clean_process function to ease the job of plugin function
- 384. By olivier-mattelaer
-
fixing issue with re-weighting when doing rewgt from two different process directory
- 385. By olivier-mattelaer
-
1) set new runweb handling for file ./bin/madevent
2) better fix for t-channel
3) fix issue for set lep 1.2 (avoid the crash) - 386. By olivier-mattelaer
-
forbids install maddm for the temporary release
- 387. By olivier-mattelaer
-
correct date
- 388. By olivier-mattelaer
-
fixing issue with version
- 389. By olivier-mattelaer
-
fix an issue with NLO model
- 390. By olivier-mattelaer
-
remove pointless printout
- 391. By olivier-mattelaer
-
UPdate note
- 392. By olivier-mattelaer
-
small change for the installer
- 393. By olivier-mattelaer
-
revert release creation script + improve install
- 394. By olivier-mattelaer
-
comment from the review
- 395. By olivier-mattelaer
-
improve UpdateNotes and merge with lastest 2.6.2
Preview Diff
1 | === modified file 'MadSpin/decay.py' |
2 | --- MadSpin/decay.py 2018-02-05 12:41:25 +0000 |
3 | +++ MadSpin/decay.py 2018-04-20 08:32:43 +0000 |
4 | @@ -3848,7 +3848,7 @@ |
5 | min_br = min([m['total_br'] for m in self.all_ME.values()]) |
6 | logger.info('''All production process does not have the same total Branching Ratio. |
7 | Therefore the total number of events after decay will be lower than the original file. |
8 | - [max_br = %s, min_br = %s]''' % (max_br, min_br),'$MG:color:BLACK') |
9 | + [max_br = %s, min_br = %s]''' % (max_br, min_br),'$MG:BOLD') |
10 | fake_decay = {'br': max_br - production['total_br'], |
11 | 'path': None, 'matrix_element': None, |
12 | 'finals': None, 'base_order': None, |
13 | |
14 | === modified file 'MadSpin/interface_madspin.py' |
15 | --- MadSpin/interface_madspin.py 2018-02-21 17:03:42 +0000 |
16 | +++ MadSpin/interface_madspin.py 2018-04-20 08:32:43 +0000 |
17 | @@ -1022,6 +1022,7 @@ |
18 | |
19 | run_card["iseed"] = self.seed |
20 | run_card['gridpack'] = True |
21 | + run_card['systematics_program'] = 'False' |
22 | run_card['use_syst'] = False |
23 | run_card.write(pjoin(decay_dir, "Cards", "run_card.dat")) |
24 | param_card = self.banner['slha'] |
25 | |
26 | === modified file 'Template/LO/Cards/run_card.dat' |
27 | --- Template/LO/Cards/run_card.dat 2017-11-18 00:45:31 +0000 |
28 | +++ Template/LO/Cards/run_card.dat 2018-04-20 08:32:43 +0000 |
29 | @@ -10,6 +10,9 @@ |
30 | # Lines starting with a '# ' are info or comments * |
31 | # * |
32 | # mind the format: value = variable ! comment * |
33 | +# * |
34 | +# To display more options, you can type the command: * |
35 | +* update full_run_card * |
36 | #********************************************************************* |
37 | # |
38 | #******************* |
39 | |
40 | === modified file 'Template/LO/SubProcesses/genps.f' |
41 | --- Template/LO/SubProcesses/genps.f 2017-08-09 12:56:57 +0000 |
42 | +++ Template/LO/SubProcesses/genps.f 2018-04-20 08:32:43 +0000 |
43 | @@ -863,21 +863,20 @@ |
44 | |
45 | c write(*,*) 'tmin, tmax',tmin,tmax |
46 | |
47 | - tmax = max(tmax,0d0) !This line if want really t freedom |
48 | + if (tmax.gt.-0.01.and.tmin.lt.-0.02)then |
49 | +c set tmax to 0. The idea is to be sure to be able to hit zero |
50 | +c and not to be block by numerical inacuracy |
51 | +c tmax = max(tmax,0d0) !This line if want really t freedom |
52 | + call sample_get_x(wgt,x(-ibranch),-ibranch,iconfig, |
53 | + $ 0, -tmin/stot) |
54 | + t = stot*(-x(-ibranch)) |
55 | |
56 | + else |
57 | call sample_get_x(wgt,x(-ibranch),-ibranch,iconfig, |
58 | $ -tmax/stot, -tmin/stot) |
59 | t = stot*(-x(-ibranch)) |
60 | -c |
61 | -c now reset tmax if messed it up for t freedom 3 lines above |
62 | -c |
63 | - call yminmax(s1,t,m12,ma2,mb2,mn2,tmin,tmax) |
64 | + endif |
65 | |
66 | -c write(*,*) tmin,t,tmax |
67 | -c if (t .eq. 0d0) then |
68 | -c jac = -3 |
69 | -c return |
70 | -c endif |
71 | if (t .lt. tmin .or. t .gt. tmax) then |
72 | jac=-3d0 |
73 | return |
74 | |
75 | === modified file 'Template/LO/SubProcesses/setcuts.f' |
76 | --- Template/LO/SubProcesses/setcuts.f 2018-02-23 15:30:14 +0000 |
77 | +++ Template/LO/SubProcesses/setcuts.f 2018-04-20 08:32:43 +0000 |
78 | @@ -138,8 +138,10 @@ |
79 | lpp(2)=0 |
80 | ebeam(1)=pmass(1)/2d0 |
81 | ebeam(2)=pmass(1)/2d0 |
82 | - scale=pmass(1) |
83 | - fixed_ren_scale=.true. |
84 | + if (.not.fixed_ren_scale)then |
85 | + scale=pmass(1) |
86 | + fixed_ren_scale=.true. |
87 | + endif |
88 | fixed_fac_scale=.true. |
89 | use_syst=.false. |
90 | endif |
91 | |
92 | === modified file 'Template/LO/bin/generate_events' |
93 | --- Template/LO/bin/generate_events 2015-10-24 19:53:10 +0000 |
94 | +++ Template/LO/bin/generate_events 2018-04-20 08:32:43 +0000 |
95 | @@ -33,7 +33,6 @@ |
96 | |
97 | # Check if optimize mode is (and should be) activated |
98 | if __debug__ and (not os.path.exists(pjoin(root_path,'../..', 'bin','create_release.py'))): |
99 | - print 'launch in debug mode' |
100 | subprocess.call([sys.executable] + ['-O'] + sys.argv) |
101 | sys.exit() |
102 | |
103 | @@ -146,18 +145,22 @@ |
104 | # Check that python version is valid |
105 | |
106 | set_configuration() |
107 | - argument = sys.argv |
108 | + argument = sys.argv |
109 | try: |
110 | if '-h' in argument or '--help' in argument: |
111 | - launch = ME.MadEventCmdShell(me_dir=root_path) |
112 | + launch = ME.MadEventCmdShell(me_dir=root_path, force_run=True) |
113 | launch.exec_cmd('help generate_events') |
114 | sys.exit() |
115 | elif len(argument) > 1 and argument[1] in ['0', '1', '2']: |
116 | argument = treat_old_argument(argument) |
117 | |
118 | - launch = ME.MadEventCmdShell(me_dir=root_path) |
119 | - launch.run_cmd('generate_events %s' % ' '.join(argument[1:])) |
120 | - launch.run_cmd('quit') |
121 | + with ME.MadEventCmdShell.RunWebHandling(root_path, ): |
122 | + launch = ME.MadEventCmdShell(me_dir=root_path, force_run=True) |
123 | + launch.run_cmd('generate_events %s' % ' '.join(argument[1:])) |
124 | + launch.run_cmd('quit') |
125 | + except ME.MadEventAlreadyRunning, message: |
126 | + logging.getLogger('madgraph').log(40, str(message)) |
127 | + sys.exit(1) |
128 | except KeyboardInterrupt: |
129 | try: |
130 | launch.run_cmd('quit') |
131 | @@ -166,9 +169,6 @@ |
132 | except Exception, error: |
133 | logging.error(str(error)) |
134 | sys.exit() |
135 | - |
136 | - if os.path.exists(pjoin(root_path, 'RunWeb')): |
137 | - os.remove(pjoin(root_path, 'RunWeb')) |
138 | |
139 | # reconfigure path for the web |
140 | #if len(argument) == 5: |
141 | |
142 | === modified file 'Template/LO/bin/madevent' |
143 | --- Template/LO/bin/madevent 2016-04-25 14:02:24 +0000 |
144 | +++ Template/LO/bin/madevent 2018-04-20 08:32:43 +0000 |
145 | @@ -146,53 +146,58 @@ |
146 | |
147 | # Call the cmd interface main loop |
148 | try: |
149 | - if (args and os.path.isfile(args[0])): |
150 | - # They are an input file |
151 | - input_file = args[0] |
152 | - if options.web: |
153 | - cmd_line = cmd_interface.MadEventCmd() |
154 | - cmd_line.debug_output = os.path.join(os.path.dirname(input_file),'generation.log') |
155 | - cmd_line.use_rawinput = False |
156 | - cmd_line.haspiping = False |
157 | - cmd_line.run_cmd('import command ' + input_file) |
158 | - cmd_line.run_cmd('quit') |
159 | - else: |
160 | - cmd_line = cmd_interface.MadEventCmdShell() |
161 | - cmd_line.use_rawinput = False |
162 | - cmd_line.haspiping = False |
163 | - cmd_line.run_cmd('import command ' + input_file) |
164 | - cmd_line.run_cmd('quit') |
165 | - elif args: |
166 | - # a single command is provided |
167 | - if options.web: |
168 | - cmd_line = cmd_interface.MadEventCmd() |
169 | - else: |
170 | - cmd_line = cmd_interface.MadEventCmdShell() |
171 | - if not hasattr(cmd_line, 'do_%s' % args[0]): |
172 | - if parser_error: |
173 | - print parser_error |
174 | - print 'and %s can not be interpreted as a valid command.' % args[0] |
175 | - else: |
176 | - print 'ERROR: %s not a valid command. Please retry' % args[0] |
177 | - else: |
178 | - cmd_line.use_rawinput = False |
179 | - cmd_line.run_cmd(' '.join(args)) |
180 | - cmd_line.run_cmd('quit') |
181 | - else: |
182 | - # Interactive mode |
183 | - if options.web: |
184 | - cmd_line = cmd_interface.MadEventCmd() |
185 | - cmd_line.cmdloop() |
186 | - else: |
187 | - cmd_line = cmd_interface.MadEventCmdShell() |
188 | - cmd_line.cmdloop() |
189 | - |
190 | + if '-h' in args or '--help' in args: |
191 | + launch = ME.MadEventCmdShell(me_dir=os.path.dirname(root_path), force_run=True) |
192 | + launch.exec_cmd('help generate_events') |
193 | + sys.exit(0) |
194 | + with cmd_interface.MadEventCmdShell.RunWebHandling(os.path.dirname(root_path), ): |
195 | + if (args and os.path.isfile(args[0])): |
196 | + # They are an input file |
197 | + input_file = args[0] |
198 | + if options.web: |
199 | + cmd_line = cmd_interface.MadEventCmd(force_run=True) |
200 | + cmd_line.debug_output = os.path.join(os.path.dirname(input_file),'generation.log') |
201 | + cmd_line.use_rawinput = False |
202 | + cmd_line.haspiping = False |
203 | + cmd_line.run_cmd('import command ' + input_file) |
204 | + cmd_line.run_cmd('quit') |
205 | + else: |
206 | + cmd_line = cmd_interface.MadEventCmdShell(force_run=True) |
207 | + cmd_line.use_rawinput = False |
208 | + cmd_line.haspiping = False |
209 | + cmd_line.run_cmd('import command ' + input_file) |
210 | + cmd_line.run_cmd('quit') |
211 | + elif args: |
212 | + # a single command is provided |
213 | + if options.web: |
214 | + cmd_line = cmd_interface.MadEventCmd(force_run=True) |
215 | + else: |
216 | + cmd_line = cmd_interface.MadEventCmdShell(force_run=True) |
217 | + if not hasattr(cmd_line, 'do_%s' % args[0]): |
218 | + if parser_error: |
219 | + print parser_error |
220 | + print 'and %s can not be interpreted as a valid command.' % args[0] |
221 | + else: |
222 | + print 'ERROR: %s not a valid command. Please retry' % args[0] |
223 | + else: |
224 | + cmd_line.use_rawinput = False |
225 | + cmd_line.run_cmd(' '.join(args)) |
226 | + cmd_line.run_cmd('quit') |
227 | + else: |
228 | + # Interactive mode |
229 | + if options.web: |
230 | + cmd_line = cmd_interface.MadEventCmd(force_run=True) |
231 | + cmd_line.cmdloop() |
232 | + else: |
233 | + cmd_line = cmd_interface.MadEventCmdShell(force_run=True) |
234 | + cmd_line.cmdloop() |
235 | except KeyboardInterrupt: |
236 | print 'writting history and directory and quit on KeyboardInterrupt' |
237 | pass |
238 | except cmd_interface.MadEventAlreadyRunning, error: |
239 | logging.error(str(error)) |
240 | - sys.exit() |
241 | + sys.exit(1) |
242 | + |
243 | try: |
244 | readline.set_history_length(100) |
245 | if not os.path.exists(os.path.join(os.environ['HOME'], '.mg5')): |
246 | @@ -208,8 +213,8 @@ |
247 | pass |
248 | |
249 | |
250 | -try: |
251 | - # Remove lock file |
252 | - os.remove(os.path.join(root_path,os.pardir, 'RunWeb')) |
253 | -except: |
254 | - pass |
255 | +#try: |
256 | +# # Remove lock file |
257 | +# os.remove(os.path.join(root_path,os.pardir, 'RunWeb')) |
258 | +#except: |
259 | +# pass |
260 | |
261 | === modified file 'Template/NLO/Cards/run_card.dat' |
262 | --- Template/NLO/Cards/run_card.dat 2017-11-17 16:07:39 +0000 |
263 | +++ Template/NLO/Cards/run_card.dat 2018-04-20 08:32:43 +0000 |
264 | @@ -13,6 +13,9 @@ |
265 | # * |
266 | # Some of the values of variables can be list. These can either be * |
267 | # comma or space separated. * |
268 | +# * |
269 | +# To display additional parameter, you can use the command: * |
270 | +# update to_full * |
271 | #*********************************************************************** |
272 | # |
273 | #******************* |
274 | |
275 | === modified file 'UpdateNotes.txt' |
276 | --- UpdateNotes.txt 2018-04-03 15:01:12 +0000 |
277 | +++ UpdateNotes.txt 2018-04-20 08:32:43 +0000 |
278 | @@ -1,10 +1,18 @@ |
279 | Update notes for MadGraph5_aMC@NLO (in reverse time order) |
280 | |
281 | -2.6.2 () |
282 | + |
283 | +2.6.2.beta (30-04-02) |
284 | OM: Fix issue with madspin introduced in 2.6.1 (failing to generate correct diagram for NLO process) |
285 | + OM: introduce "update to_full" command to display all the hidden parameter |
286 | + OM: improve handling of (some) run_card parameter: |
287 | + - add comment that can be displayed via "help NAME" |
288 | + - add autocompletion for some parameter |
289 | + - add direct rejection of parameter edition if not in some allowed list/range |
290 | OM: add the value of all the widths in Auto-width in the scan summary file |
291 | OM: fix crash in 1>N reweighting |
292 | RF: Fixed an issue where too many files were opened for fNLO runs in rare cases |
293 | + OM: For 1>N, if the user set fixed_run_scale to True, then the scale is choose accordingly |
294 | + and not following the mass of the inital state anymore |
295 | RF: For the HwU histograms, if no gnuplot installation is found, write the gnuplot scripts in v5 |
296 | format (instead of the very old v4 format). |
297 | RF+MZ: Fixed a problem with (f)NLO(+PS) runs in case the Born has identical QCD-charged |
298 | @@ -18,8 +26,13 @@ |
299 | RF: Fixed a bug for ApplGrid: in rare cases the ApplGrid tables were filled twice for the same event |
300 | OM: Fixed a bug for fixed target experiment when the energy of the beam was set to 0. |
301 | RF: Fixed an issue with the computation of (partial) decay width processes at NLO. |
302 | + OM: loop-filter commands are now working for loop-induced processes |
303 | + OM: New method avoiding that two process are running inside the same output directory. |
304 | + This is implemented only for Gridpack and LO run so far. |
305 | + The new method should be more robust in case of crash (i.e. not wrongly trigger as before) |
306 | |
307 | 2.6.1 (12/12/17) |
308 | + |
309 | RF+MZ: It is now possible to add LO matrix elements (with [LOonly]) |
310 | to Fx-Fx merged samples. Thanks to Josh Bendavid for testing. |
311 | OM: Re-factoring the code asking which program to use (both at LO and NLO) |
312 | |
313 | === modified file 'VERSION' |
314 | --- VERSION 2017-12-12 21:11:08 +0000 |
315 | +++ VERSION 2018-04-20 08:32:43 +0000 |
316 | @@ -1,5 +1,5 @@ |
317 | -version = 2.6.1 |
318 | -date = 2017-12-12 |
319 | +version = 2.6.2.beta |
320 | +date = 2018-04-02 |
321 | |
322 | |
323 | |
324 | |
325 | === modified file 'madgraph/core/base_objects.py' |
326 | --- madgraph/core/base_objects.py 2018-02-28 14:10:19 +0000 |
327 | +++ madgraph/core/base_objects.py 2018-04-20 08:32:43 +0000 |
328 | @@ -2972,8 +2972,10 @@ |
329 | the user-defined list of orders, it can be ommitted for some info |
330 | displays.""" |
331 | |
332 | - if prefix: |
333 | + if isinstance(prefix, bool): |
334 | mystr = " " * indent + "Process: " |
335 | + elif isinstance(prefix, str): |
336 | + mystr = prefix |
337 | else: |
338 | mystr = "" |
339 | prevleg = None |
340 | @@ -3354,10 +3356,14 @@ |
341 | def get_initial_pdg(self, number): |
342 | """Return the pdg codes for initial state particles for beam number""" |
343 | |
344 | - return filter(lambda leg: leg.get('state') == False and\ |
345 | + legs = filter(lambda leg: leg.get('state') == False and\ |
346 | leg.get('number') == number, |
347 | - self.get('legs'))[0].get('id') |
348 | - |
349 | + self.get('legs')) |
350 | + if not legs: |
351 | + return None |
352 | + else: |
353 | + return legs[0].get('id') |
354 | + |
355 | def get_initial_final_ids(self): |
356 | """return a tuple of two tuple containing the id of the initial/final |
357 | state particles. Each list is ordered""" |
358 | |
359 | === modified file 'madgraph/interface/.mg5_logging.conf' |
360 | --- madgraph/interface/.mg5_logging.conf 2013-11-27 17:25:48 +0000 |
361 | +++ madgraph/interface/.mg5_logging.conf 2018-04-20 08:32:43 +0000 |
362 | @@ -1,11 +1,11 @@ |
363 | [formatters] |
364 | -keys: cmdprint,simple,madgraph |
365 | +keys: cmdprint,simple,madgraph,tutorial |
366 | |
367 | [handlers] |
368 | keys: cmdprint,root,madgraph,fatalerror,tutorial,tutorial_aMCatNLO,tutorial_MadLoop,decay,cmdprint2 |
369 | |
370 | [loggers] |
371 | -keys: root,cmdprint,madgraph,fatalerror,tutorial,tutorial,tutorial_aMCatNLO,tutorial_MadLoop,madevent,amcatnlo,decay,cmdprint2 |
372 | +keys: root,cmdprint,madgraph,fatalerror,tutorial,tutorial,tutorial_aMCatNLO,tutorial_MadLoop,madevent,amcatnlo,decay,cmdprint2,tutorial_plugin |
373 | |
374 | |
375 | [formatter_cmdprint] |
376 | @@ -20,6 +20,10 @@ |
377 | class: logging.ColorFormatter |
378 | format: $COLOR%(levelname)s: %(message)s $RESET |
379 | |
380 | +[formatter_tutorial] |
381 | +class: logging.ColorFormatter |
382 | +format: $_BOLD========== Tutorial ==========$_RESET$BR$COLOR%(message)s $RESET$BR$_BOLD========== Tutorial ==========$_RESET |
383 | + |
384 | [handler_cmdprint] |
385 | class: StreamHandler |
386 | args: [sys.stdout] |
387 | @@ -38,7 +42,7 @@ |
388 | [handler_tutorial] |
389 | class: StreamHandler |
390 | args: [sys.stdout] |
391 | -formatter: simple |
392 | +formatter: tutorial |
393 | |
394 | [handler_tutorial_aMCatNLO] |
395 | class: StreamHandler |
396 | @@ -122,6 +126,12 @@ |
397 | qualname=tutorial |
398 | propagate=0 |
399 | |
400 | +[logger_tutorial_plugin] |
401 | +level : ERROR |
402 | +handlers: tutorial |
403 | +qualname=tutorial_plugin |
404 | +propagate=0 |
405 | + |
406 | [logger_tutorial_MadLoop] |
407 | level : ERROR |
408 | handlers: tutorial_MadLoop |
409 | |
410 | === modified file 'madgraph/interface/amcatnlo_run_interface.py' |
411 | --- madgraph/interface/amcatnlo_run_interface.py 2018-02-07 21:30:27 +0000 |
412 | +++ madgraph/interface/amcatnlo_run_interface.py 2018-04-20 08:32:43 +0000 |
413 | @@ -1729,7 +1729,7 @@ |
414 | param_card_iterator.write(pjoin(self.me_dir,'Cards','param_card.dat')) |
415 | name = misc.get_scan_name(orig_name, self.run_name) |
416 | path = pjoin(self.me_dir, 'Events','scan_%s.txt' % name) |
417 | - logger.info("write all cross-section results in %s" % path, '$MG:color:BLACK') |
418 | + logger.info("write all cross-section results in %s" % path, '$MG:BOLD') |
419 | param_card_iterator.write_summary(path) |
420 | |
421 | if self.allow_notification_center: |
422 | @@ -5187,7 +5187,7 @@ |
423 | """read and parse the test_ME/MC.log file""" |
424 | content = open(log).read() |
425 | if 'FAILED' in content: |
426 | - logger.info('Output of the failing test:\n'+content[:-1],'$MG:color:BLACK') |
427 | + logger.info('Output of the failing test:\n'+content[:-1],'$MG:BOLD') |
428 | raise aMCatNLOError('Some tests failed, run cannot continue.\n' + \ |
429 | 'Please check that widths of final state particles (e.g. top) have been' + \ |
430 | ' set to 0 in the param_card.dat.') |
431 | @@ -5310,7 +5310,7 @@ |
432 | else: |
433 | logger.info("""Your Parton-shower choice is not available for running. |
434 | The events will be generated for the associated Parton-Shower. |
435 | - Remember that NLO events without showering are NOT physical.""", '$MG:color:BLACK') |
436 | + Remember that NLO events without showering are NOT physical.""", '$MG:BOLD') |
437 | |
438 | |
439 | # specify the cards which are needed for this run. |
440 | |
441 | === modified file 'madgraph/interface/coloring_logging.py' |
442 | --- madgraph/interface/coloring_logging.py 2016-02-19 13:21:31 +0000 |
443 | +++ madgraph/interface/coloring_logging.py 2018-04-20 08:32:43 +0000 |
444 | @@ -1,6 +1,7 @@ |
445 | import logging |
446 | # method to add color to a logging.info add a second argument: |
447 | -# '$MG:color:BLACK' |
448 | +# '$MG:BOLD' |
449 | +# '$MG:color:RED' |
450 | |
451 | |
452 | BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8) |
453 | @@ -31,7 +32,7 @@ |
454 | class ColorFormatter(logging.Formatter): |
455 | |
456 | def __init__(self, *args, **kwargs): |
457 | - # can't do super(...) here because Formatter is an old school class |
458 | + # can't do super(...) here because Formatter is an old school class) |
459 | logging.Formatter.__init__(self, *args, **kwargs) |
460 | |
461 | def format(self, record): |
462 | @@ -44,6 +45,7 @@ |
463 | # A not-so-nice but working way of passing arguments to this formatter |
464 | # from MadGraph. |
465 | color_specified = False |
466 | + bold_specified = False |
467 | for arg in record.args: |
468 | if isinstance(arg,str) and arg.startswith('$MG'): |
469 | elems=arg.split(':') |
470 | @@ -53,12 +55,26 @@ |
471 | color_choice = COLORS[elems[2]] |
472 | if color_choice == 0: |
473 | color_choice = 30 |
474 | + if len(elems)==2 and elems[1].lower()=='bold': |
475 | + bold_specified = True |
476 | else: |
477 | new_args.append(arg) |
478 | + |
479 | + |
480 | record.args = tuple(new_args) |
481 | - color = COLOR_SEQ % (30 + color_choice) |
482 | + if bold_specified: |
483 | + color = BOLD_SEQ |
484 | + color_specified = True |
485 | + else: |
486 | + color = COLOR_SEQ % (30 + color_choice) |
487 | message = logging.Formatter.format(self, record) |
488 | - if not message.endswith('$RESET'): |
489 | + if not message: |
490 | + return message |
491 | + # if some need to be applied no matter what: |
492 | + message = message.replace('$_BOLD', BOLD_SEQ).replace('$_RESET', RESET_SEQ).replace('$BR','\n') |
493 | + |
494 | + # for the conditional one |
495 | + if '$RESET' not in message: |
496 | message += '$RESET' |
497 | for k,v in COLORS.items(): |
498 | color_flag = COLOR_SEQ % (v+30) |
499 | |
500 | === modified file 'madgraph/interface/common_run_interface.py' |
501 | --- madgraph/interface/common_run_interface.py 2018-03-28 20:42:08 +0000 |
502 | +++ madgraph/interface/common_run_interface.py 2018-04-20 08:32:43 +0000 |
503 | @@ -21,6 +21,7 @@ |
504 | |
505 | import ast |
506 | import logging |
507 | +import math |
508 | import os |
509 | import re |
510 | import shutil |
511 | @@ -485,6 +486,12 @@ |
512 | args.remove('-from_cards') |
513 | opts.append('-from_cards') |
514 | |
515 | + if any(t.startswith('--plugin=') for t in args): |
516 | + plugin = [t for t in args if t.startswith('--plugin')][0] |
517 | + args.remove(plugin) |
518 | + opts.append(plugin) |
519 | + |
520 | + |
521 | if len(args) == 0: |
522 | if self.run_name: |
523 | args.insert(0, self.run_name) |
524 | @@ -501,6 +508,7 @@ |
525 | |
526 | args += opts |
527 | |
528 | + |
529 | def check_check_events(self,args): |
530 | """Check the argument for decay_events command |
531 | syntax is "decay_events [NAME]" |
532 | @@ -611,6 +619,7 @@ |
533 | """common""" |
534 | |
535 | self.force_run = False # this flag force the run even if RunWeb is present |
536 | + self.stop_for_runweb = False # this flag indicates if we stop this run because of RunWeb. |
537 | if 'force_run' in opts and opts['force_run']: |
538 | self.force_run = True |
539 | del opts['force_run'] |
540 | @@ -641,6 +650,7 @@ |
541 | (for this exact same directory) Please wait that this is instance is |
542 | closed. If no instance is running, you can delete the file |
543 | %s and try again.''' % pjoin(me_dir,'RunWeb') |
544 | + self.stop_for_runweb = True |
545 | raise AlreadyRunning, message |
546 | else: |
547 | self.write_RunWeb(me_dir) |
548 | @@ -677,12 +687,82 @@ |
549 | |
550 | |
551 | def write_RunWeb(self, me_dir): |
552 | + self.writeRunWeb(me_dir) |
553 | + self.gen_card_html() |
554 | + |
555 | + @staticmethod |
556 | + def writeRunWeb(me_dir): |
557 | pid = os.getpid() |
558 | fsock = open(pjoin(me_dir,'RunWeb'),'w') |
559 | fsock.write(`pid`) |
560 | - fsock.close() |
561 | - self.gen_card_html() |
562 | - |
563 | + fsock.close() |
564 | + |
565 | + class RunWebHandling(object): |
566 | + |
567 | + def __init__(self, me_dir, crashifpresent=True, warnifpresent=True): |
568 | + """raise error if RunWeb already exists |
569 | + me_dir is the directory where the write RunWeb""" |
570 | + |
571 | + self.remove_run_web = True |
572 | + self.me_dir = me_dir |
573 | + |
574 | + if crashifpresent or warnifpresent: |
575 | + if os.path.exists(pjoin(me_dir, 'RunWeb')): |
576 | + pid = open(pjoin(me_dir, 'RunWeb')).read() |
577 | + try: |
578 | + pid = int(pid) |
579 | + except Exception: |
580 | + pid = "unknown" |
581 | + |
582 | + if pid == 'unknown' or misc.pid_exists(pid): |
583 | + # bad situation |
584 | + if crashifpresent: |
585 | + if isinstance(crashifpresent, Exception): |
586 | + raise crashifpresent |
587 | + else: |
588 | + message = '''Another instance of the program is currently running (pid = %s). |
589 | + (for this exact same directory). Please wait that this is instance is |
590 | + closed. If no instance is running, you can delete the file |
591 | + %s and try again.''' % (pid, pjoin(me_dir, 'RunWeb')) |
592 | + raise AlreadyRunning, message |
593 | + elif warnifpresent: |
594 | + if isinstance( warnifpresent, bool): |
595 | + logger.warning("%s/RunWeb is present. Please check that only one run is running in that directory.") |
596 | + else: |
597 | + logger.log(warnifpresent, "%s/RunWeb is present. Please check that only one run is running in that directory.") |
598 | + self.remove_run_web = False |
599 | + else: |
600 | + logger.debug('RunWeb exists but no associated process. Will Ignore it!') |
601 | + return |
602 | + |
603 | + # write RunWeb |
604 | + |
605 | + CommonRunCmd.writeRunWeb(me_dir) |
606 | + |
607 | + def __enter__(self): |
608 | + return |
609 | + |
610 | + def __exit__(self,exc_type, exc_value, traceback): |
611 | + |
612 | + if self.remove_run_web: |
613 | + try: |
614 | + os.remove(pjoin(self.me_dir,'RunWeb')) |
615 | + except Exception: |
616 | + if os.path.exists(pjoin(self.me_dir,'RunWeb')): |
617 | + logger.warning('fail to remove: %s' % pjoin(self.me_dir,'RunWeb')) |
618 | + return |
619 | + |
620 | + def __call__(self, f): |
621 | + """allow to use this as decorator as well""" |
622 | + def wrapper(*args, **kw): |
623 | + with self: |
624 | + return f(*args, **kw) |
625 | + return wrapper |
626 | + |
627 | + |
628 | + |
629 | + |
630 | + |
631 | ############################################################################ |
632 | def split_arg(self, line, error=False): |
633 | """split argument and remove run_options""" |
634 | @@ -887,6 +967,16 @@ |
635 | |
636 | self.ask_edit_card_static(cards, mode, plot, self.options['timeout'], |
637 | self.ask, first_cmd=first_cmd) |
638 | + |
639 | + for c in cards: |
640 | + if not os.path.isabs(c): |
641 | + c = pjoin(self.me_dir, c) |
642 | + if not os.path.exists(c): |
643 | + default = c.replace('dat', '_default.dat') |
644 | + if os.path.exists(default): |
645 | + files.cp(default, c) |
646 | + |
647 | + |
648 | |
649 | @staticmethod |
650 | def ask_edit_card_static(cards, mode='fixed', plot=True, |
651 | @@ -950,6 +1040,7 @@ |
652 | path_msg='enter path', ask_class = AskforEditCard, |
653 | cards=cards, mode=mode, **opt) |
654 | |
655 | + |
656 | @staticmethod |
657 | def detect_card_type(path): |
658 | """detect the type of the card. Return value are |
659 | @@ -1212,7 +1303,7 @@ |
660 | else: |
661 | PY8_plots_root_path = pjoin(self.me_dir,'HTML', |
662 | self.run_name,'%s_PY8_plots'%tag) |
663 | - |
664 | + |
665 | if 'ickkw' in self.run_card: |
666 | if int(self.run_card['ickkw']) and mode == 'Pythia': |
667 | self.update_status('Create matching plots for Pythia', level='pythia') |
668 | @@ -1473,12 +1564,12 @@ |
669 | ############################################################################ |
670 | def help_systematics(self): |
671 | """help for systematics command""" |
672 | - logger.info("syntax: systematics RUN_NAME [OUTPUT] [options]",'$MG:color:BLACK') |
673 | + logger.info("syntax: systematics RUN_NAME [OUTPUT] [options]",'$MG:BOLD') |
674 | logger.info("-- Run the systematics run on the RUN_NAME run.") |
675 | logger.info(" RUN_NAME can be a path to a lhef file.") |
676 | logger.info(" OUTPUT can be the path to the output lhe file, otherwise the input file will be overwritten") |
677 | logger.info("") |
678 | - logger.info("options: (values written are the default)", '$MG:color:BLACK') |
679 | + logger.info("options: (values written are the default)", '$MG:BOLD') |
680 | logger.info("") |
681 | logger.info(" --mur=0.5,1,2 # specify the values for renormalisation scale variation") |
682 | logger.info(" --muf=0.5,1,2 # specify the values for factorisation scale variation") |
683 | @@ -1494,7 +1585,7 @@ |
684 | logger.info(" --keep_weights= # force to keep the weight even if in the list of remove_weights") |
685 | logger.info(" --start_id= # define the starting digit for the additial weight. If not specify it is determine automatically") |
686 | logger.info("") |
687 | - logger.info(" Allowed value for the pdf options:", '$MG:color:BLACK') |
688 | + logger.info(" Allowed value for the pdf options:", '$MG:BOLD') |
689 | logger.info(" central : Do not perform any pdf variation" ) |
690 | logger.info(" errorset : runs over the all the members of the PDF set used to generate the events") |
691 | logger.info(" 244800 : runs over the associated set and all its members") |
692 | @@ -1505,7 +1596,7 @@ |
693 | logger.info(" CT10@X : runs over the Xth member of the associated PDF set") |
694 | logger.info(" XX,YY,ZZ : runs over the sets for XX,YY,ZZ (those three follows above syntax)") |
695 | logger.info("") |
696 | - logger.info(" Allowed value for the keep/remove_wgts options:", '$MG:color:BLACK') |
697 | + logger.info(" Allowed value for the keep/remove_wgts options:", '$MG:BOLD') |
698 | logger.info(" all : keep/remove all weights") |
699 | logger.info(" name : keep/remove that particular weight") |
700 | logger.info(" id1,id2 : keep/remove all the weights between those two values --included--") |
701 | @@ -1792,6 +1883,7 @@ |
702 | cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Reweight |
703 | """ |
704 | |
705 | + |
706 | #### Utility function |
707 | def check_multicore(self): |
708 | """ determine if the cards are save for multicore use""" |
709 | @@ -1843,7 +1935,7 @@ |
710 | elif hasattr(self, 'switch') and self.switch['reweight'] not in ['ON','OFF']: |
711 | plugin=self.switch['reweight'] |
712 | |
713 | - |
714 | + |
715 | |
716 | # Check that MG5 directory is present . |
717 | if MADEVENT and not self.options['mg5_path']: |
718 | @@ -1865,6 +1957,9 @@ |
719 | |
720 | # load the name of the event file |
721 | args = self.split_arg(line) |
722 | + if plugin and '--plugin=' not in line: |
723 | + args.append('--plugin=%s' % plugin) |
724 | + |
725 | |
726 | if not self.force_run: |
727 | # forbid this function to create an empty item in results. |
728 | @@ -1884,8 +1979,6 @@ |
729 | if not isinstance(self, cmd.CmdShell): |
730 | command.append('--web') |
731 | command.append('reweight') |
732 | - if plugin: |
733 | - command.append('--plugin=%s' % plugin) |
734 | |
735 | ######### START SINGLE CORE MODE ############ |
736 | if self.options['nb_core']==1 or self.run_card['nevents'] < 101 or not check_multicore(self): |
737 | @@ -1971,6 +2064,8 @@ |
738 | |
739 | if '-from_cards' not in command: |
740 | new_command.append('-from_cards') |
741 | + if plugin: |
742 | + new_command.append('--plugin=%s' % plugin) |
743 | if i==0: |
744 | if __debug__: |
745 | stdout = None |
746 | @@ -3214,7 +3309,10 @@ |
747 | #Force class default |
748 | self.debug_output = CommonRunCmd.debug_output |
749 | if os.path.exists('ME5_debug') and not 'ME5_debug' in self.debug_output: |
750 | - os.remove('ME5_debug') |
751 | + try: |
752 | + os.remove('ME5_debug') |
753 | + except Exception: |
754 | + pass |
755 | if not 'ME5_debug' in self.debug_output: |
756 | os.system('ln -s %s ME5_debug &> /dev/null' % self.debug_output) |
757 | |
758 | @@ -3245,6 +3343,15 @@ |
759 | do_EOF = do_quit |
760 | do_exit = do_quit |
761 | |
762 | + def __del__(self): |
763 | + """try to remove RunWeb?""" |
764 | + |
765 | + if not self.stop_for_runweb and not self.force_run: |
766 | + try: |
767 | + os.remove(pjoin(self.me_dir,'RunWeb')) |
768 | + except Exception: |
769 | + pass |
770 | + |
771 | |
772 | def update_status(self, status, level, makehtml=True, force=True, |
773 | error=False, starttime = None, update_results=True, |
774 | @@ -4084,56 +4191,31 @@ |
775 | |
776 | class AskforEditCard(cmd.OneLinePathCompletion): |
777 | """A class for asking a question where in addition you can have the |
778 | - set command define and modifying the param_card/run_card correctly""" |
779 | + set command define and modifying the param_card/run_card correctly |
780 | + |
781 | + special action can be trigger via trigger_XXXX when the user start a line |
782 | + with XXXX. the output of such function should be new line that can be handle. |
783 | + (return False to repeat the question) |
784 | + """ |
785 | |
786 | all_card_name = ['param_card', 'run_card', 'pythia_card', 'pythia8_card', |
787 | 'madweight_card', 'MadLoopParams', 'shower_card'] |
788 | - |
789 | - special_shortcut = {'ebeam':([float],['run_card ebeam1 %(0)s', 'run_card ebeam2 %(0)s']), |
790 | - 'lpp': ([int],['run_card lpp1 %(0)s', 'run_card lpp2 %(0)s' ]), |
791 | - 'lhc': ([int],['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2']), |
792 | - 'lep': ([int],['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2']), |
793 | - 'ilc': ([int],['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2']), |
794 | - 'lcc': ([int],['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2']), |
795 | - 'fixed_scale': ([float],['run_card fixed_fac_scale T', 'run_card fixed_ren_scale T', 'run_card scale %(0)s', 'run_card dsqrt_q2fact1 %(0)s' ,'run_card dsqrt_q2fact2 %(0)s']), |
796 | - 'simplepy8':([],['pythia8_card hadronlevel:all False', |
797 | - 'pythia8_card partonlevel:mpi False', |
798 | - 'pythia8_card BeamRemnants:primordialKT False', |
799 | - 'pythia8_card PartonLevel:Remnants False', |
800 | - 'pythia8_card Check:event False', |
801 | - 'pythia8_card TimeShower:QEDshowerByQ False', |
802 | - 'pythia8_card TimeShower:QEDshowerByL False', |
803 | - 'pythia8_card SpaceShower:QEDshowerByQ False', |
804 | - 'pythia8_card SpaceShower:QEDshowerByL False', |
805 | - 'pythia8_card PartonLevel:FSRinResonances False', |
806 | - 'pythia8_card ProcessLevel:resonanceDecays False', |
807 | - ]), |
808 | - 'mpi':([bool],['pythia8_card partonlevel:mpi %(0)s']), |
809 | - 'no_parton_cut':([],['run_card nocut T']) |
810 | - } |
811 | - |
812 | - special_shortcut_help = { |
813 | - 'ebeam' : 'syntax: set ebeam VALUE:\n This parameter sets the energy to both beam to the value in GeV', |
814 | - 'lpp' : 'syntax: set ebeam VALUE:\n'+\ |
815 | - ' Set the type of beam to a given value for both beam\n'+\ |
816 | - ' 0 : means no PDF\n'+\ |
817 | - ' 1 : means proton PDF\n'+\ |
818 | - ' -1 : means antiproton PDF\n'+\ |
819 | - ' 2 : means PDF for elastic photon emited from a proton\n'+\ |
820 | - ' 3 : means PDF for elastic photon emited from an electron', |
821 | - 'lhc' : 'syntax: set lhc VALUE:\n Set for a proton-proton collision with that given center of mass energy (in TeV)', |
822 | - 'lep' : 'syntax: set lep VALUE:\n Set for a electron-positron collision with that given center of mass energy (in GeV)', |
823 | - 'fixed_scale' : 'syntax: set fixed_scale VALUE:\n Set all scales to the give value (in GeV)', |
824 | - 'simplepy8' : 'Turn off non-perturbative slow features of Pythia8.', |
825 | - 'mpi' : 'syntax: set mpi value: allow to turn mpi in Pythia8 on/off' |
826 | - } |
827 | + to_init_card = ['param', 'run', 'madweight', 'madloop', |
828 | + 'shower', 'pythia8','delphes','madspin'] |
829 | + special_shortcut = {} |
830 | + special_shortcut_help = {} |
831 | + |
832 | + integer_bias = 1 # integer corresponding to the first entry in self.cards |
833 | + |
834 | + PY8Card_class = banner_mod.PY8Card |
835 | |
836 | def load_default(self): |
837 | """ define all default variable. No load of card here. |
838 | This allow to subclass this class and just change init and still have |
839 | all variables defined.""" |
840 | |
841 | - self.me_dir = None |
842 | + if not hasattr(self, 'me_dir'): |
843 | + self.me_dir = None |
844 | self.param_card = None |
845 | self.run_card = {} |
846 | self.pname2block = {} |
847 | @@ -4146,6 +4228,7 @@ |
848 | self.has_ml = False |
849 | self.has_shower = False |
850 | self.has_PY8 = False |
851 | + self.has_delphes = False |
852 | self.paths = {} |
853 | |
854 | |
855 | @@ -4186,22 +4269,110 @@ |
856 | self.paths['madanalysis5_hadron_default'] = pjoin(self.me_dir,'Cards','madanalysis5_hadron_card_default.dat') |
857 | self.paths['FO_analyse'] = pjoin(self.me_dir,'Cards', 'FO_analyse_card.dat') |
858 | |
859 | + |
860 | + |
861 | + |
862 | def __init__(self, question, cards=[], mode='auto', *args, **opt): |
863 | |
864 | + |
865 | self.load_default() |
866 | self.define_paths(**opt) |
867 | + self.last_editline_pos = 0 |
868 | + |
869 | + if 'allow_arg' not in opt or not opt['allow_arg']: |
870 | + # add some mininal content for this: |
871 | + opt['allow_arg'] = range(self.integer_bias, self.integer_bias+len(cards)) |
872 | + |
873 | + self.param_consistency = True |
874 | + if 'param_consistency' in opt: |
875 | + self.param_consistency = opt['param_consistency'] |
876 | + |
877 | cmd.OneLinePathCompletion.__init__(self, question, *args, **opt) |
878 | |
879 | - |
880 | + self.conflict = set() |
881 | + self.mode = mode |
882 | + self.cards = cards |
883 | + self.all_vars = set() |
884 | + |
885 | + #update default path by custom one if specify in cards |
886 | + for card in cards: |
887 | + if os.path.exists(card): |
888 | + card_name = CommonRunCmd.detect_card_type(card) |
889 | + card_name = card_name.split('_',1)[0] |
890 | + self.paths[card_name] = card |
891 | + |
892 | + # go trough the initialisation of each card and detect conflict |
893 | + for name in self.to_init_card: |
894 | + new_vars = set(getattr(self, 'init_%s' % name)(cards)) |
895 | + new_conflict = self.all_vars.intersection(new_vars) |
896 | + self.conflict.union(new_conflict) |
897 | + self.all_vars.union(new_vars) |
898 | + |
899 | + def get_path(self, name, cards): |
900 | + """initialise the path if requested""" |
901 | + |
902 | + defname = '%s_default' % name |
903 | + if isinstance(cards, list): |
904 | + if name in cards: |
905 | + return True |
906 | + elif '%s_card.dat' % name in cards: |
907 | + return True |
908 | + elif name in self.paths and self.paths[name] in cards: |
909 | + return True |
910 | + else: |
911 | + cardnames = [os.path.basename(p) for p in cards] |
912 | + if '%s_card.dat' % name in cardnames: |
913 | + return True |
914 | + else: |
915 | + return False |
916 | + |
917 | + elif isinstance(cards, dict) and name in cards: |
918 | + self.paths[name]= cards[name] |
919 | + if defname in cards: |
920 | + self.paths[defname] = cards[defname] |
921 | + elif os.path.isfile(cards[name].replace('.dat', '_default.dat')): |
922 | + self.paths[defname] = cards[name].replace('.dat', '_default.dat') |
923 | + else: |
924 | + self.paths[defname] = self.paths[name] |
925 | + |
926 | + return True |
927 | + else: |
928 | + return False |
929 | + |
930 | + def init_param(self, cards): |
931 | + """check if we need to load the param_card""" |
932 | + |
933 | + self.pname2block = {} |
934 | + self.restricted_value = {} |
935 | + self.param_card = {} |
936 | + if not self.get_path('param', cards): |
937 | + self.param_consistency = False |
938 | + return [] |
939 | + |
940 | try: |
941 | self.param_card = check_param_card.ParamCard(self.paths['param']) |
942 | except (check_param_card.InvalidParamCard, ValueError) as e: |
943 | logger.error('Current param_card is not valid. We are going to use the default one.') |
944 | logger.error('problem detected: %s' % e) |
945 | files.cp(self.paths['param_default'], self.paths['param']) |
946 | - self.param_card = check_param_card.ParamCard(self.paths['param']) |
947 | - default_param = check_param_card.ParamCard(self.paths['param_default']) |
948 | + self.param_card = check_param_card.ParamCard(self.paths['param']) |
949 | + |
950 | + # Read the comment of the param_card_default to find name variable for |
951 | + # the param_card also check which value seems to be constrained in the |
952 | + # model. |
953 | + if os.path.exists(self.paths['param_default']): |
954 | + default_param = check_param_card.ParamCard(self.paths['param_default']) |
955 | + else: |
956 | + default_param = check_param_card.ParamCard(self.param_card) |
957 | + self.pname2block, self.restricted_value = default_param.analyze_param_card() |
958 | self.param_card_default = default_param |
959 | + return self.pname2block.keys() |
960 | + |
961 | + def init_run(self, cards): |
962 | + |
963 | + self.run_set = [] |
964 | + if not self.get_path('run', cards): |
965 | + return [] |
966 | |
967 | try: |
968 | self.run_card = banner_mod.RunCard(self.paths['run'], consistency='warning') |
969 | @@ -4212,124 +4383,186 @@ |
970 | except IOError: |
971 | run_card_def = {} |
972 | |
973 | - self.pname2block = {} |
974 | - self.conflict = [] |
975 | - self.restricted_value = {} |
976 | - self.mode = mode |
977 | - self.cards = cards |
978 | - self.last_editline_pos=0 |
979 | - |
980 | - # Read the comment of the param_card_default to find name variable for |
981 | - # the param_card also check which value seems to be constrained in the |
982 | - # model. |
983 | - self.pname2block, self.restricted_value = \ |
984 | - default_param.analyze_param_card() |
985 | - |
986 | if run_card_def: |
987 | - self.run_set = run_card_def.keys() + self.run_card.hidden_param |
988 | + if self.run_card: |
989 | + self.run_set = run_card_def.keys() + self.run_card.hidden_param |
990 | + else: |
991 | + self.run_set = run_card_def.keys() + run_card_def.hidden_param |
992 | elif self.run_card: |
993 | self.run_set = self.run_card.keys() |
994 | else: |
995 | self.run_set = [] |
996 | - # check for conflict with run_card |
997 | - for var in self.pname2block: |
998 | - if var in self.run_set: |
999 | - self.conflict.append(var) |
1000 | - |
1001 | - |
1002 | - self.has_delphes = False |
1003 | - if 'delphes_card.dat' in cards: |
1004 | - self.has_delphes = True |
1005 | - |
1006 | - #check if Madweight_card is present: |
1007 | + |
1008 | + if self.run_set: |
1009 | + self.special_shortcut.update( |
1010 | + {'ebeam':([float],['run_card ebeam1 %(0)s', 'run_card ebeam2 %(0)s']), |
1011 | + 'lpp': ([int],['run_card lpp1 %(0)s', 'run_card lpp2 %(0)s' ]), |
1012 | + 'lhc': ([int],['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2']), |
1013 | + 'lep': ([int],['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2']), |
1014 | + 'ilc': ([int],['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2']), |
1015 | + 'lcc': ([int],['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2']), |
1016 | + 'fixed_scale': ([float],['run_card fixed_fac_scale T', 'run_card fixed_ren_scale T', 'run_card scale %(0)s', 'run_card dsqrt_q2fact1 %(0)s' ,'run_card dsqrt_q2fact2 %(0)s']), |
1017 | + 'no_parton_cut':([],['run_card nocut T']), |
1018 | + 'cm_velocity':([float], [lambda self :self.set_CM_velocity]) |
1019 | + }) |
1020 | + |
1021 | + self.special_shortcut_help.update({ |
1022 | + 'ebeam' : 'syntax: set ebeam VALUE:\n This parameter sets the energy to both beam to the value in GeV', |
1023 | + 'lpp' : 'syntax: set ebeam VALUE:\n'+\ |
1024 | + ' Set the type of beam to a given value for both beam\n'+\ |
1025 | + ' 0 : means no PDF\n'+\ |
1026 | + ' 1 : means proton PDF\n'+\ |
1027 | + ' -1 : means antiproton PDF\n'+\ |
1028 | + ' 2 : means PDF for elastic photon emited from a proton\n'+\ |
1029 | + ' 3 : means PDF for elastic photon emited from an electron', |
1030 | + 'lhc' : 'syntax: set lhc VALUE:\n Set for a proton-proton collision with that given center of mass energy (in TeV)', |
1031 | + 'lep' : 'syntax: set lep VALUE:\n Set for a electron-positron collision with that given center of mass energy (in GeV)', |
1032 | + 'fixed_scale' : 'syntax: set fixed_scale VALUE:\n Set all scales to the give value (in GeV)', |
1033 | + 'no_parton_cut': 'remove all cut (but BW_cutoff)', |
1034 | + 'cm_velocity': 'set sqrts to have the above velocity for the incoming particles', |
1035 | + }) |
1036 | + |
1037 | + return self.run_set |
1038 | + |
1039 | + def init_madweight(self, cards): |
1040 | + |
1041 | self.has_mw = False |
1042 | - if 'madweight_card.dat' in cards: |
1043 | - |
1044 | - self.do_change_tf = self.mother_interface.do_define_transfer_fct |
1045 | - self.complete_change_tf = self.mother_interface.complete_define_transfer_fct |
1046 | - self.help_change_tf = self.mother_interface.help_define_transfer_fct |
1047 | - if not os.path.exists(self.paths['transfer']): |
1048 | - logger.warning('No transfer function currently define. Please use the change_tf command to define one.') |
1049 | - |
1050 | - |
1051 | - self.has_mw = True |
1052 | - try: |
1053 | - import madgraph.madweight.Cards as mwcards |
1054 | - except: |
1055 | - import internal.madweight.Cards as mwcards |
1056 | - self.mw_card = mwcards.Card(self.paths['MadWeight']) |
1057 | - self.mw_card = self.mw_card.info |
1058 | - self.mw_vars = [] |
1059 | - for key in self.mw_card: |
1060 | - if key == 'comment': |
1061 | - continue |
1062 | - for key2 in self.mw_card.info[key]: |
1063 | - if isinstance(key2, str) and not key2.isdigit(): |
1064 | - self.mw_vars.append(key2) |
1065 | - |
1066 | - # check for conflict with run_card/param_card |
1067 | - for var in self.pname2block: |
1068 | - if var in self.mw_vars: |
1069 | - self.conflict.append(var) |
1070 | - for var in self.mw_vars: |
1071 | - if var in self.run_card: |
1072 | - self.conflict.append(var) |
1073 | - |
1074 | - #check if MadLoopParams.dat is present: |
1075 | + if not self.get_path('madweight', cards): |
1076 | + return [] |
1077 | + |
1078 | + #add special function associated to MW |
1079 | + self.do_change_tf = self.mother_interface.do_define_transfer_fct |
1080 | + self.complete_change_tf = self.mother_interface.complete_define_transfer_fct |
1081 | + self.help_change_tf = self.mother_interface.help_define_transfer_fct |
1082 | + if not os.path.exists(self.paths['transfer']): |
1083 | + logger.warning('No transfer function currently define. Please use the change_tf command to define one.') |
1084 | + |
1085 | + self.has_mw = True |
1086 | + try: |
1087 | + import madgraph.madweight.Cards as mwcards |
1088 | + except: |
1089 | + import internal.madweight.Cards as mwcards |
1090 | + self.mw_card = mwcards.Card(self.paths['MadWeight']) |
1091 | + self.mw_card = self.mw_card.info |
1092 | + self.mw_vars = [] |
1093 | + for key in self.mw_card: |
1094 | + if key == 'comment': |
1095 | + continue |
1096 | + for key2 in self.mw_card.info[key]: |
1097 | + if isinstance(key2, str) and not key2.isdigit(): |
1098 | + self.mw_vars.append(key2) |
1099 | + return self.mw_vars |
1100 | + |
1101 | + def init_madloop(self, cards): |
1102 | + |
1103 | + if isinstance(cards, dict): |
1104 | + for key in ['ML', 'madloop','MadLoop']: |
1105 | + if key in cards: |
1106 | + self.paths['ML'] = cards[key] |
1107 | + |
1108 | self.has_ml = False |
1109 | if os.path.isfile(self.paths['ML']): |
1110 | self.has_ml = True |
1111 | self.MLcard = banner_mod.MadLoopParam(self.paths['ML']) |
1112 | self.MLcardDefault = banner_mod.MadLoopParam() |
1113 | - |
1114 | self.ml_vars = [k.lower() for k in self.MLcard.keys()] |
1115 | - # check for conflict |
1116 | - for var in self.ml_vars: |
1117 | - if var in self.run_card: |
1118 | - self.conflict.append(var) |
1119 | - if var in self.pname2block: |
1120 | - self.conflict.append(var) |
1121 | - if self.has_mw and var in self.mw_vars: |
1122 | - self.conflict.append(var) |
1123 | - |
1124 | - #check if shower_card is present: |
1125 | + return self.ml_vars |
1126 | + return [] |
1127 | + |
1128 | + def init_shower(self, cards): |
1129 | + |
1130 | self.has_shower = False |
1131 | - if 'shower_card.dat' in cards: |
1132 | - self.has_shower = True |
1133 | - self.shower_card = shower_card_mod.ShowerCard(self.paths['shower']) |
1134 | - self.shower_vars = self.shower_card.keys() |
1135 | - |
1136 | - # check for conflict with run_card/param_card |
1137 | - for var in self.pname2block: |
1138 | - if var in self.shower_vars: |
1139 | - self.conflict.append(var) |
1140 | - for var in self.shower_vars: |
1141 | - if var in self.run_card: |
1142 | - self.conflict.append(var) |
1143 | - |
1144 | - #check if pythia8_card.dat is present: |
1145 | + if not self.get_path('shower', cards): |
1146 | + return [] |
1147 | + self.has_shower = True |
1148 | + self.shower_card = shower_card_mod.ShowerCard(self.paths['shower']) |
1149 | + self.shower_vars = self.shower_card.keys() |
1150 | + return self.shower_vars |
1151 | + |
1152 | + def init_pythia8(self, cards): |
1153 | + |
1154 | self.has_PY8 = False |
1155 | - if 'pythia8_card.dat' in cards: |
1156 | - self.has_PY8 = True |
1157 | - self.PY8Card = banner_mod.PY8Card(self.paths['pythia8']) |
1158 | - self.PY8CardDefault = banner_mod.PY8Card() |
1159 | - |
1160 | - self.py8_vars = [k.lower() for k in self.PY8Card.keys()] |
1161 | - # check for conflict |
1162 | - for var in self.py8_vars: |
1163 | - if var in self.run_card: |
1164 | - self.conflict.append(var) |
1165 | - if var in self.pname2block: |
1166 | - self.conflict.append(var) |
1167 | - if self.has_mw and var in self.mw_vars: |
1168 | - self.conflict.append(var) |
1169 | - if self.has_ml and var in self.ml_vars: |
1170 | - self.conflict.append(var) |
1171 | - |
1172 | - def do_help(self, line, conflict_raise=False, banner=True): |
1173 | + if not self.get_path('pythia8', cards): |
1174 | + return [] |
1175 | + |
1176 | + self.has_PY8 = True |
1177 | + self.PY8Card = self.PY8Card_class(self.paths['pythia8']) |
1178 | + self.PY8CardDefault = self.PY8Card_class() |
1179 | + |
1180 | + self.py8_vars = [k.lower() for k in self.PY8Card.keys()] |
1181 | + |
1182 | + self.special_shortcut.update({ |
1183 | + 'simplepy8':([],['pythia8_card hadronlevel:all False', |
1184 | + 'pythia8_card partonlevel:mpi False', |
1185 | + 'pythia8_card BeamRemnants:primordialKT False', |
1186 | + 'pythia8_card PartonLevel:Remnants False', |
1187 | + 'pythia8_card Check:event False', |
1188 | + 'pythia8_card TimeShower:QEDshowerByQ False', |
1189 | + 'pythia8_card TimeShower:QEDshowerByL False', |
1190 | + 'pythia8_card SpaceShower:QEDshowerByQ False', |
1191 | + 'pythia8_card SpaceShower:QEDshowerByL False', |
1192 | + 'pythia8_card PartonLevel:FSRinResonances False', |
1193 | + 'pythia8_card ProcessLevel:resonanceDecays False', |
1194 | + ]), |
1195 | + 'mpi':([bool],['pythia8_card partonlevel:mpi %(0)s']), |
1196 | + }) |
1197 | + self.special_shortcut_help.update({ |
1198 | + 'simplepy8' : 'Turn off non-perturbative slow features of Pythia8.', |
1199 | + 'mpi' : 'syntax: set mpi value: allow to turn mpi in Pythia8 on/off', |
1200 | + }) |
1201 | + return [] |
1202 | + |
1203 | + def init_madspin(self, cards): |
1204 | + |
1205 | + if not self.get_path('madspin', cards): |
1206 | + return [] |
1207 | + |
1208 | + self.special_shortcut.update({ |
1209 | + 'spinmode':([str], ['add madspin_card --before_line="launch" set spinmode %(0)s']) |
1210 | + }) |
1211 | + self.special_shortcut_help.update({ |
1212 | + 'spinmode' : 'full|none|onshell. Choose the mode of madspin.\n - full: spin-correlation and off-shell effect\n - onshell: only spin-correlation,]\n - none: no spin-correlation and not offshell effects.' |
1213 | + }) |
1214 | + return [] |
1215 | + |
1216 | + def init_delphes(self, cards): |
1217 | + |
1218 | + self.has_delphes = False |
1219 | + if not self.get_path('pythia8', cards): |
1220 | + return [] |
1221 | + self.has_delphes = True |
1222 | + return [] |
1223 | + |
1224 | + |
1225 | + def set_CM_velocity(self, line): |
1226 | + """compute sqrts from the velocity in the center of mass frame""" |
1227 | + |
1228 | + v = banner_mod.ConfigFile.format_variable(line, float, 'velocity') |
1229 | + # Define self.proc_characteristics |
1230 | + self.mother_interface.get_characteristics() |
1231 | + proc_info = self.mother_interface.proc_characteristics |
1232 | + if 'pdg_initial1' not in proc_info: |
1233 | + logger.warning('command not supported') |
1234 | + |
1235 | + if len(proc_info['pdg_initial1']) == 1 == len(proc_info['pdg_initial2']) and\ |
1236 | + abs(proc_info['pdg_initial1'][0]) == abs(proc_info['pdg_initial2'][0]): |
1237 | + |
1238 | + m = self.param_card.get_value('mass', abs(proc_info['pdg_initial1'][0])) |
1239 | + sqrts = 2*m/ math.sqrt(1-v**2) |
1240 | + self.do_set('run_card ebeam1 %s' % (sqrts/2.0)) |
1241 | + self.do_set('run_card ebeam2 %s' % (sqrts/2.0)) |
1242 | + self.do_set('run_card lpp 0') |
1243 | + else: |
1244 | + logger.warning('This is only possible for a single particle in the initial state') |
1245 | + |
1246 | + |
1247 | + |
1248 | + def do_help(self, line, conflict_raise=False, banner=True): |
1249 | + # TODO nicer factorization ! |
1250 | + |
1251 | # try: |
1252 | if banner: |
1253 | - logger.info('*** HELP MESSAGE ***', '$MG:color:BLACK') |
1254 | + logger.info('*** HELP MESSAGE ***', '$MG:BOLD') |
1255 | |
1256 | args = self.split_arg(line) |
1257 | # handle comand related help |
1258 | @@ -4346,7 +4579,7 @@ |
1259 | print '\t'.join(self.special_shortcut) |
1260 | |
1261 | if banner: |
1262 | - logger.info('*** END HELP ***', '$MG:color:BLACK') |
1263 | + logger.info('*** END HELP ***', '$MG:BOLD') |
1264 | return out |
1265 | # check for special shortcut. |
1266 | # special shortcut: |
1267 | @@ -4354,7 +4587,7 @@ |
1268 | if args[0] in self.special_shortcut_help: |
1269 | print self.special_shortcut_help[args[0]] |
1270 | if banner: |
1271 | - logger.info('*** END HELP ***', '$MG:color:BLACK') |
1272 | + logger.info('*** END HELP ***', '$MG:BOLD') |
1273 | return |
1274 | |
1275 | start = 0 |
1276 | @@ -4391,8 +4624,8 @@ |
1277 | logger.info("List of parameter associated", '$MG:color:BLUE') |
1278 | print "\t".join(eval('self.%s' % args[0]).keys()) |
1279 | if banner: |
1280 | - logger.info('*** END HELP ***', '$MG:color:BLACK') |
1281 | - return |
1282 | + logger.info('*** END HELP ***', '$MG:BOLD') |
1283 | + return card |
1284 | |
1285 | #### RUN CARD |
1286 | if args[start] in [l.lower() for l in self.run_card.keys()] and card in ['', 'run_card']: |
1287 | @@ -4401,9 +4634,9 @@ |
1288 | |
1289 | if args[start] in self.conflict and not conflict_raise: |
1290 | conflict_raise = True |
1291 | - logger.info('** AMBIGUOUS NAME: %s **', args[start], '$MG:color:BLACK') |
1292 | + logger.info('** AMBIGUOUS NAME: %s **', args[start], '$MG:BOLD') |
1293 | if card == '': |
1294 | - logger.info('** If not explicitely speficy this parameter will modif the run_card file', '$MG:color:BLACK') |
1295 | + logger.info('** If not explicitely speficy this parameter will modif the run_card file', '$MG:BOLD') |
1296 | |
1297 | self.run_card.do_help(args[start]) |
1298 | ### PARAM_CARD WITH BLOCK NAME ----------------------------------------- |
1299 | @@ -4436,7 +4669,7 @@ |
1300 | key = tuple([int(i) for i in args[start+1:]]) |
1301 | except ValueError: |
1302 | logger.warning('Failed to identify LHA information') |
1303 | - return |
1304 | + return card |
1305 | |
1306 | if key in self.param_card[args[start]].param_dict: |
1307 | self.param_card.do_help(args[start], key, default=self.param_card_default) |
1308 | @@ -4481,13 +4714,13 @@ |
1309 | print 'MA5' |
1310 | |
1311 | |
1312 | - else: |
1313 | + elif banner: |
1314 | print "no help available" |
1315 | |
1316 | if banner: |
1317 | logger.info('*** END HELP ***', '$MG:color:BLACK') |
1318 | #raw_input('press enter to quit the help') |
1319 | - return |
1320 | + return card |
1321 | # except Exception, error: |
1322 | # if __debug__: |
1323 | # import traceback |
1324 | @@ -4522,8 +4755,9 @@ |
1325 | |
1326 | arg = line[:begidx].split() |
1327 | if len(arg) <=1: |
1328 | - return self.list_completion(text, ['dependent', 'missing', 'to_slha1', 'to_slha2'], line) |
1329 | - |
1330 | + return self.list_completion(text, ['dependent', 'missing', 'to_slha1', 'to_slha2', 'to_full'], line) |
1331 | + elif arg[0] == 'to_full': |
1332 | + return self.list_completion(text, self.cards , line) |
1333 | |
1334 | def complete_set(self, text, line, begidx, endidx, formatting=True): |
1335 | """ Complete the set command""" |
1336 | @@ -4560,7 +4794,7 @@ |
1337 | allowed = {'run_card':'default'} |
1338 | elif args[1] == 'param_card': |
1339 | allowed = {'block':'all', 'param_card':'default'} |
1340 | - elif args[1] in self.param_card.keys(): |
1341 | + elif self.param_card and args[1] in self.param_card.keys(): |
1342 | allowed = {'block':args[1]} |
1343 | elif args[1] == 'width': |
1344 | allowed = {'block': 'decay'} |
1345 | @@ -4689,12 +4923,13 @@ |
1346 | |
1347 | possibilities['Special Value'] = self.list_completion(text, opts) |
1348 | |
1349 | - if 'block' in allowed.keys(): |
1350 | - if allowed['block'] == 'all': |
1351 | + if 'block' in allowed.keys() and self.param_card: |
1352 | + if allowed['block'] == 'all' and self.param_card: |
1353 | allowed_block = [i for i in self.param_card.keys() if 'qnumbers' not in i] |
1354 | allowed_block.append('width') |
1355 | possibilities['Param Card Block' ] = \ |
1356 | self.list_completion(text, allowed_block) |
1357 | + |
1358 | elif isinstance(allowed['block'], basestring): |
1359 | block = self.param_card[allowed['block']].param_dict |
1360 | ids = [str(i[0]) for i in block |
1361 | @@ -4750,6 +4985,8 @@ |
1362 | |
1363 | |
1364 | args = self.split_arg(line) |
1365 | + |
1366 | + |
1367 | if len(args) == 0: |
1368 | logger.warning("No argument. For help type 'help set'.") |
1369 | # fix some formatting problem |
1370 | @@ -4776,20 +5013,35 @@ |
1371 | except ValueError as e: |
1372 | logger.warning("Wrong argument: The entry #%s should be of type %s.", i+1, argtype) |
1373 | return |
1374 | + except InvalidCmd as e: |
1375 | + logger.warning(str(e)) |
1376 | + return |
1377 | #else: |
1378 | # logger.warning("too many argument for this command") |
1379 | # return |
1380 | for arg in cmd: |
1381 | - try: |
1382 | - text = arg % values |
1383 | - except KeyError: |
1384 | - logger.warning("This command requires one argument") |
1385 | - return |
1386 | - except Exception as e: |
1387 | - logger.warning(str(e)) |
1388 | - return |
1389 | + if isinstance(arg, str): |
1390 | + try: |
1391 | + text = arg % values |
1392 | + except KeyError: |
1393 | + logger.warning("This command requires one argument") |
1394 | + return |
1395 | + except Exception as e: |
1396 | + logger.warning(str(e)) |
1397 | + return |
1398 | + else: |
1399 | + split = text.split() |
1400 | + if hasattr(self, 'do_%s' % split[0]): |
1401 | + getattr(self, 'do_%s' % split[0])(' '.join(split[1:])) |
1402 | + else: |
1403 | + self.do_set(text) |
1404 | + #need to call a function |
1405 | else: |
1406 | - self.do_set(arg % values) |
1407 | + val = [values[str(i)] for i in range(len(values))] |
1408 | + try: |
1409 | + arg(self)(*val) |
1410 | + except Exception, e: |
1411 | + logger.warning(str(e)) |
1412 | return |
1413 | |
1414 | |
1415 | @@ -4902,7 +5154,7 @@ |
1416 | elif args[0] in ['pythia8_card']: |
1417 | if args[1] == 'default': |
1418 | logger.info('replace pythia8_card.dat by the default card','$MG:color:BLACK') |
1419 | - self.PY8Card = banner_mod.PY8Card(self.PY8CardDefault) |
1420 | + self.PY8Card = self.PY8Card_class(self.PY8CardDefault) |
1421 | self.PY8Card.write(pjoin(self.me_dir,'Cards','pythia8_card.dat'), |
1422 | pjoin(self.me_dir,'Cards','pythia8_card_default.dat'), |
1423 | print_only_visible=True) |
1424 | @@ -5308,7 +5560,7 @@ |
1425 | self.do_set('run_card store_rwgt_info True') |
1426 | |
1427 | # @LO if PY6 shower => event_norm on sum |
1428 | - if 'pythia_card.dat' in self.cards: |
1429 | + if 'pythia_card.dat' in self.cards and 'run' in self.allow_arg: |
1430 | if self.run_card['event_norm'] != 'sum': |
1431 | logger.info('Pythia6 needs a specific normalisation of the events. We will change it accordingly.', '$MG:color:BLACK' ) |
1432 | self.do_set('run_card event_norm sum') |
1433 | @@ -5391,19 +5643,20 @@ |
1434 | |
1435 | if ending_question: |
1436 | self.check_card_consistency() |
1437 | - try: |
1438 | - self.do_update('dependent', timer=20) |
1439 | - except MadGraph5Error, error: |
1440 | - if 'Missing block:' in str(error): |
1441 | - self.fail_due_to_format +=1 |
1442 | - if self.fail_due_to_format == 10: |
1443 | - missing, unknow = str(error).split('\n')[-2:] |
1444 | - logger.warning("Invalid param_card:\n%s\n%s\n" % (missing, unknow)) |
1445 | - logger.info("Type \"update missing\" to use default value.\n ", '$MG:color:BLACK') |
1446 | - self.value = False # to avoid that entering a command stop the question |
1447 | - return self.reask(True) |
1448 | - else: |
1449 | - raise |
1450 | + if self.param_consistency: |
1451 | + try: |
1452 | + self.do_update('dependent', timer=20) |
1453 | + except MadGraph5Error, error: |
1454 | + if 'Missing block:' in str(error): |
1455 | + self.fail_due_to_format +=1 |
1456 | + if self.fail_due_to_format == 10: |
1457 | + missing, unknow = str(error).split('\n')[-2:] |
1458 | + logger.warning("Invalid param_card:\n%s\n%s\n" % (missing, unknow)) |
1459 | + logger.info("Type \"update missing\" to use default value.\n ", '$MG:color:BLACK') |
1460 | + self.value = False # to avoid that entering a command stop the question |
1461 | + return self.reask(True) |
1462 | + else: |
1463 | + raise |
1464 | |
1465 | return ending_question |
1466 | |
1467 | @@ -5415,8 +5668,9 @@ |
1468 | """ syntax: update dependent: Change the mass/width of particles which are not free parameter for the model. |
1469 | update missing: add to the current param_card missing blocks/parameters. |
1470 | update to_slha1: pass SLHA2 card to SLHA1 convention. (beta) |
1471 | - update to_slha2: pass SLHA1 card to SLHA2 convention. (beta)""" |
1472 | - |
1473 | + update to_slha2: pass SLHA1 card to SLHA2 convention. (beta) |
1474 | + update to_full [run_card] |
1475 | + """ |
1476 | args = self.split_arg(line) |
1477 | if len(args)==0: |
1478 | logger.warning('miss an argument (dependent or missing). Please retry') |
1479 | @@ -5461,7 +5715,16 @@ |
1480 | except Exception, error: |
1481 | logger.warning('failed to update to slha1 due to %s' % error) |
1482 | self.param_card = check_param_card.ParamCard(self.paths['param']) |
1483 | - |
1484 | + elif args[0] == 'to_full': |
1485 | + return self.update_to_full(args[1:]) |
1486 | + |
1487 | + |
1488 | + def update_to_full(self, line): |
1489 | + """ trigger via update to_full LINE""" |
1490 | + |
1491 | + logger.info("update the run_card by including all the hidden parameter") |
1492 | + self.run_card.write(self.paths['run'], self.paths['run_default'], write_hidden=True) |
1493 | + |
1494 | @staticmethod |
1495 | def update_dependent(mecmd, me_dir, param_card, path ,timer=0): |
1496 | """static method which can also be called from outside the class |
1497 | @@ -5471,6 +5734,7 @@ |
1498 | |
1499 | if not param_card: |
1500 | return False |
1501 | + |
1502 | logger.info('Update the dependent parameter of the param_card.dat') |
1503 | modify = True |
1504 | class TimeOutError(Exception): |
1505 | @@ -5638,12 +5902,34 @@ |
1506 | logger.info(' set run_card default') |
1507 | logger.info('********************* HELP SET ***************************') |
1508 | |
1509 | + def trigger(self, line): |
1510 | + |
1511 | + line = line.strip() |
1512 | + args = line.split() |
1513 | + |
1514 | + if not args: |
1515 | + return line |
1516 | + if not hasattr(self, 'trigger_%s' % args[0]): |
1517 | + return line |
1518 | + |
1519 | + triggerfct = getattr(self, 'trigger_%s' % args[0]) |
1520 | + |
1521 | + # run the trigger function |
1522 | + outline = triggerfct(' '.join(args[1:])) |
1523 | + if not outline: |
1524 | + return 'repeat' |
1525 | + return outline |
1526 | |
1527 | def default(self, line): |
1528 | """Default action if line is not recognized""" |
1529 | |
1530 | + # check if the line need to be modified by a trigger |
1531 | + line = self.trigger(line) |
1532 | + |
1533 | + # splitting the line |
1534 | line = line.strip() |
1535 | args = line.split() |
1536 | + |
1537 | if line == '' and self.default_value is not None: |
1538 | self.value = self.default_value |
1539 | # check if input is a file |
1540 | @@ -5681,6 +5967,7 @@ |
1541 | |
1542 | return line |
1543 | |
1544 | + |
1545 | def do_decay(self, line): |
1546 | """edit the madspin_card to define the decay of the associate particle""" |
1547 | signal.alarm(0) # avoid timer if any |
1548 | @@ -5841,7 +6128,7 @@ |
1549 | pjoin(self.me_dir,'Cards','pythia8_card_default.dat'), |
1550 | print_only_visible=True) |
1551 | logger.info("add in the pythia8_card the parameter \"%s\" with value \"%s\"" % (name, value), '$MG:color:BLACK') |
1552 | - elif len(args) > 0: |
1553 | + elif len(args) > 0: |
1554 | if args[0] in self.cards: |
1555 | card = args[0] |
1556 | elif "%s.dat" % args[0] in self.cards: |
1557 | @@ -5853,46 +6140,56 @@ |
1558 | else: |
1559 | logger.error("unknow card %s. Please retry." % args[0]) |
1560 | return |
1561 | + |
1562 | + if card in self.paths: |
1563 | + path = self.paths[card] |
1564 | + elif os.path.exists(card): |
1565 | + path = card |
1566 | + elif os.path.exists(pjoin(self.me_dir,'Cards',card)): |
1567 | + path = pjoin(self.me_dir,'Cards',card) |
1568 | + else: |
1569 | + raise Exception, 'unknow path' |
1570 | + |
1571 | # handling the various option on where to write the line |
1572 | if args[1] == '--clean': |
1573 | - ff = open(pjoin(self.me_dir,'Cards',card),'w') |
1574 | + ff = open(path,'w') |
1575 | ff.write("# %s \n" % card) |
1576 | ff.write("%s \n" % line.split(None,2)[2]) |
1577 | ff.close() |
1578 | logger.info("writing the line in %s (empty file) the line: \"%s\"" %(card, line.split(None,2)[2] ),'$MG:color:BLACK') |
1579 | elif args[1].startswith('--line_position=afterlast'): |
1580 | #position in file determined by user |
1581 | - text = open(pjoin(self.me_dir,'Cards',card)).read() |
1582 | + text = open(path).read() |
1583 | split = text.split('\n') |
1584 | if self.last_editline_pos > 0: |
1585 | pos = self.last_editline_pos +1 |
1586 | newline = line.split(None,2)[2] |
1587 | split.insert(pos, newline) |
1588 | - ff = open(pjoin(self.me_dir,'Cards',card),'w') |
1589 | + ff = open(path,'w') |
1590 | ff.write('\n'.join(split)) |
1591 | logger.info("writting at line %d of the file %s the line: \"%s\"" %(pos, card, line.split(None,2)[2] ),'$MG:color:BLACK') |
1592 | self.last_editline_pos = pos |
1593 | elif args[1].startswith('--line_position='): |
1594 | #position in file determined by user |
1595 | - text = open(pjoin(self.me_dir,'Cards',card)).read() |
1596 | + text = open(path).read() |
1597 | split = text.split('\n') |
1598 | pos = int(args[1].split('=',1)[1]) |
1599 | newline = line.split(None,2)[2] |
1600 | split.insert(pos, newline) |
1601 | - ff = open(pjoin(self.me_dir,'Cards',card),'w') |
1602 | + ff = open(path,'w') |
1603 | ff.write('\n'.join(split)) |
1604 | logger.info("writting at line %d of the file %s the line: \"%s\"" %(pos, card, line.split(None,2)[2] ),'$MG:color:BLACK') |
1605 | self.last_editline_pos = pos |
1606 | |
1607 | elif args[1].startswith('--after_line=banner'): |
1608 | # write the line at the first not commented line |
1609 | - text = open(pjoin(self.me_dir,'Cards',card)).read() |
1610 | + text = open(path).read() |
1611 | split = text.split('\n') |
1612 | for posline,l in enumerate(split): |
1613 | if not l.startswith('#'): |
1614 | break |
1615 | split.insert(posline, line.split(None,2)[2]) |
1616 | - ff = open(pjoin(self.me_dir,'Cards',card),'w') |
1617 | + ff = open(path,'w') |
1618 | ff.write('\n'.join(split)) |
1619 | logger.info("writting at line %d of the file %s the line: \"%s\"" %(posline, card, line.split(None,2)[2] ),'$MG:color:BLACK') |
1620 | self.last_editline_pos = posline |
1621 | @@ -5900,7 +6197,7 @@ |
1622 | elif args[1].startswith('--replace_line='): |
1623 | # catch the line/regular expression and replace the associate line |
1624 | # if no line match go to check if args[2] has other instruction starting with -- |
1625 | - text = open(pjoin(self.me_dir,'Cards',card)).read() |
1626 | + text = open(path).read() |
1627 | split = text.split('\n') |
1628 | search_pattern=r'''replace_line=(?P<quote>["'])(?:(?=(\\?))\2.)*?\1''' |
1629 | pattern = '^\s*' + re.search(search_pattern, line).group()[14:-1] |
1630 | @@ -5921,7 +6218,7 @@ |
1631 | # overwrite the previous line |
1632 | old_line = split[posline] |
1633 | split[posline] = new_line |
1634 | - ff = open(pjoin(self.me_dir,'Cards',card),'w') |
1635 | + ff = open(path,'w') |
1636 | ff.write('\n'.join(split)) |
1637 | logger.info("Replacing the line \"%s\" [line %d of %s] by \"%s\"" % |
1638 | (old_line, posline, card, new_line ),'$MG:color:BLACK') |
1639 | @@ -5930,7 +6227,7 @@ |
1640 | |
1641 | elif args[1].startswith('--before_line='): |
1642 | # catch the line/regular expression and write before that line |
1643 | - text = open(pjoin(self.me_dir,'Cards',card)).read() |
1644 | + text = open(path).read() |
1645 | split = text.split('\n') |
1646 | search_pattern=r'''before_line=(?P<quote>["'])(?:(?=(\\?))\2.)*?\1''' |
1647 | pattern = '^\s*' + re.search(search_pattern, line).group()[13:-1] |
1648 | @@ -5940,14 +6237,14 @@ |
1649 | else: |
1650 | raise Exception, 'invalid regular expression: not found in file' |
1651 | split.insert(posline, re.split(search_pattern,line)[-1]) |
1652 | - ff = open(pjoin(self.me_dir,'Cards',card),'w') |
1653 | + ff = open(path,'w') |
1654 | ff.write('\n'.join(split)) |
1655 | logger.info("writting at line %d of the file %s the line: \"%s\"" %(posline, card, line.split(None,2)[2] ),'$MG:color:BLACK') |
1656 | self.last_editline_pos = posline |
1657 | |
1658 | elif args[1].startswith('--after_line='): |
1659 | # catch the line/regular expression and write after that line |
1660 | - text = open(pjoin(self.me_dir,'Cards',card)).read() |
1661 | + text = open(path).read() |
1662 | split = text.split('\n') |
1663 | search_pattern = r'''after_line=(?P<quote>["'])(?:(?=(\\?))\2.)*?\1''' |
1664 | pattern = '^\s*' + re.search(search_pattern, line).group()[12:-1] |
1665 | @@ -5957,19 +6254,20 @@ |
1666 | else: |
1667 | posline=len(split) |
1668 | split.insert(posline+1, re.split(search_pattern,line)[-1]) |
1669 | - ff = open(pjoin(self.me_dir,'Cards',card),'w') |
1670 | + ff = open(path,'w') |
1671 | ff.write('\n'.join(split)) |
1672 | - logger.info("writting at line %d o the file %s the line: \"%s\"" %(posline, card, line.split(None,1)[1] ),'$MG:color:BLACK') |
1673 | + |
1674 | + logger.info("writting at line %d of the file %s the line: \"%s\"" %(posline, card, line.split(None,2)[2] ),'$MG:color:BLACK') |
1675 | self.last_editline_pos = posline |
1676 | |
1677 | else: |
1678 | - ff = open(pjoin(self.me_dir,'Cards',card),'a') |
1679 | + ff = open(path,'a') |
1680 | ff.write("%s \n" % line.split(None,1)[1]) |
1681 | ff.close() |
1682 | logger.info("adding at the end of the file %s the line: \"%s\"" %(card, line.split(None,1)[1] ),'$MG:color:BLACK') |
1683 | self.last_editline_pos = -1 |
1684 | |
1685 | - self.reload_card(pjoin(self.me_dir,'Cards',card)) |
1686 | + self.reload_card(path) |
1687 | |
1688 | do_edit = do_add |
1689 | complete_edit = complete_add |
1690 | @@ -6052,7 +6350,7 @@ |
1691 | self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir)) |
1692 | return |
1693 | else: |
1694 | - card_name = CommonRunCmd.detect_card_type(path) |
1695 | + card_name = self.detect_card_type(path) |
1696 | |
1697 | if card_name == 'unknown': |
1698 | logger.warning('Fail to determine the type of the file. Not copied') |
1699 | @@ -6068,6 +6366,11 @@ |
1700 | for card_name in self.cards: |
1701 | self.reload_card(pjoin(self.me_dir, 'Cards', card_name)) |
1702 | |
1703 | + def detect_card_type(self, path): |
1704 | + """detect card type""" |
1705 | + |
1706 | + return CommonRunCmd.detect_card_type(path) |
1707 | + |
1708 | def open_file(self, answer): |
1709 | """open the file""" |
1710 | try: |
1711 | @@ -6079,7 +6382,7 @@ |
1712 | if answer == '9': |
1713 | answer = 'plot' |
1714 | else: |
1715 | - answer = self.cards[int(answer)-1] |
1716 | + answer = self.cards[int(answer)-self.integer_bias] |
1717 | |
1718 | if 'madweight' in answer: |
1719 | answer = answer.replace('madweight', 'MadWeight') |
1720 | @@ -6147,7 +6450,7 @@ |
1721 | # Use the read function so that modified/new parameters are correctly |
1722 | # set as 'user_set' |
1723 | if not self.PY8Card: |
1724 | - self.PY8Card = banner_mod.PY8Card(self.paths['pythia8_default']) |
1725 | + self.PY8Card = self.PY8Card_class(self.paths['pythia8_default']) |
1726 | |
1727 | self.PY8Card.read(self.paths['pythia8'], setter='user') |
1728 | self.py8_vars = [k.lower() for k in self.PY8Card.keys()] |
1729 | @@ -6161,29 +6464,3 @@ |
1730 | logger.debug('not keep in sync: %s', path) |
1731 | return path |
1732 | |
1733 | -class EditParamCard(AskforEditCard): |
1734 | - """a dedicated module for the param""" |
1735 | - |
1736 | - special_shortcut ={} |
1737 | - |
1738 | - def __init__(self, question, card=[], mode='auto', *args, **opt): |
1739 | - |
1740 | - self.load_default() |
1741 | - cmd.OneLinePathCompletion.__init__(self, question, *args, **opt) |
1742 | - if os.path.isfile(card[0]): |
1743 | - self.param_card = check_param_card.ParamCard(card[0]) |
1744 | - self.paths['param'] = card[0] |
1745 | - if os.path.isfile(card[0].replace('.dat', '_default.dat')): |
1746 | - self.paths['param_default'] = card[0].replace('.dat', '_default.dat') |
1747 | - else: |
1748 | - self.paths['param_default'] = card[0] |
1749 | - else: |
1750 | - raise Exception, 'path %s do not exists' % card[0] |
1751 | - |
1752 | - self.pname2block, self.restricted_value = self.param_card.analyze_param_card() |
1753 | - self.cards=['param'] |
1754 | - |
1755 | - def do_asperge(self, *args, **opts): |
1756 | - "Not available" |
1757 | - logger.warning("asperge not available in this mode") |
1758 | - |
1759 | |
1760 | === modified file 'madgraph/interface/extended_cmd.py' |
1761 | --- madgraph/interface/extended_cmd.py 2018-02-21 22:35:09 +0000 |
1762 | +++ madgraph/interface/extended_cmd.py 2018-04-20 08:32:43 +0000 |
1763 | @@ -12,7 +12,6 @@ |
1764 | # For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch |
1765 | # |
1766 | ################################################################################ |
1767 | -from __builtin__ import True |
1768 | """ A file containing different extension of the cmd basic python library""" |
1769 | |
1770 | |
1771 | @@ -35,6 +34,8 @@ |
1772 | |
1773 | logger = logging.getLogger('cmdprint') # for stdout |
1774 | logger_stderr = logging.getLogger('fatalerror') # for stderr |
1775 | +logger_tuto = logging.getLogger('tutorial') # for stdout |
1776 | +logger_plugin = logging.getLogger('tutorial_plugin') # for stdout |
1777 | |
1778 | try: |
1779 | import madgraph.various.misc as misc |
1780 | @@ -468,7 +469,7 @@ |
1781 | out = [] |
1782 | for name, opt in dico.items(): |
1783 | out += opt |
1784 | - return out |
1785 | + return list(set(out)) |
1786 | |
1787 | # check if more than one categories but only one value: |
1788 | if not forceCategory and all(len(s) <= 1 for s in dico.values() ): |
1789 | @@ -768,13 +769,13 @@ |
1790 | |
1791 | def help_quit(self): |
1792 | logger.info("-- terminates the application",'$MG:color:BLUE') |
1793 | - logger.info("syntax: quit",'$MG:color:BLACK') |
1794 | + logger.info("syntax: quit",'$MG:BOLD') |
1795 | |
1796 | help_EOF = help_quit |
1797 | |
1798 | def help_history(self): |
1799 | logger.info("-- interact with the command history.",'$MG:color:BLUE') |
1800 | - logger.info("syntax: history [FILEPATH|clean|.] ",'$MG:color:BLACK') |
1801 | + logger.info("syntax: history [FILEPATH|clean|.] ",'$MG:BOLD') |
1802 | logger.info(" > If FILEPATH is \'.\' and \'output\' is done,") |
1803 | logger.info(" Cards/proc_card_mg5.dat will be used.") |
1804 | logger.info(" > If FILEPATH is omitted, the history will be output to stdout.") |
1805 | @@ -782,17 +783,17 @@ |
1806 | |
1807 | def help_help(self): |
1808 | logger.info("-- access to the in-line help",'$MG:color:BLUE') |
1809 | - logger.info("syntax: help",'$MG:color:BLACK') |
1810 | + logger.info("syntax: help",'$MG:BOLD') |
1811 | |
1812 | def help_save(self): |
1813 | """help text for save""" |
1814 | logger.info("-- save options configuration to filepath.",'$MG:color:BLUE') |
1815 | - logger.info("syntax: save [options] [FILEPATH]",'$MG:color:BLACK') |
1816 | + logger.info("syntax: save [options] [FILEPATH]",'$MG:BOLD') |
1817 | |
1818 | def help_display(self): |
1819 | """help for display command""" |
1820 | logger.info("-- display a the status of various internal state variables",'$MG:color:BLUE') |
1821 | - logger.info("syntax: display " + "|".join(self._display_opts),'$MG:color:BLACK') |
1822 | + logger.info("syntax: display " + "|".join(self._display_opts),'$MG:BOLD') |
1823 | |
1824 | class CompleteCmd(object): |
1825 | """Extension of the cmd object for only the complete command""" |
1826 | @@ -1187,8 +1188,8 @@ |
1827 | self.store_line(line) |
1828 | return None # print the question and use the pipe |
1829 | logger.info(question_instance.question) |
1830 | - logger.info('The answer to the previous question is not set in your input file', '$MG:color:BLACK') |
1831 | - logger.info('Use %s value' % default, '$MG:color:BLACK') |
1832 | + logger.info('The answer to the previous question is not set in your input file', '$MG:BOLD') |
1833 | + logger.info('Use %s value' % default, '$MG:BOLD') |
1834 | return str(default) |
1835 | |
1836 | line = line.replace('\n','').strip() |
1837 | @@ -1455,7 +1456,7 @@ |
1838 | me_dir = os.path.basename(me_dir) + ' ' |
1839 | |
1840 | misc.EasterEgg('error') |
1841 | - stop=True |
1842 | + stop=False |
1843 | try: |
1844 | raise |
1845 | except self.InvalidCmd as error: |
1846 | @@ -1486,6 +1487,7 @@ |
1847 | if __debug__: |
1848 | self.nice_config_error(error, line) |
1849 | logger.error(self.keyboard_stop_msg) |
1850 | + |
1851 | |
1852 | if stop: |
1853 | self.do_quit('all') |
1854 | @@ -2018,11 +2020,11 @@ |
1855 | def help_shell(self): |
1856 | """help for the shell""" |
1857 | logger.info("-- run the shell command CMD and catch output",'$MG:color:BLUE') |
1858 | - logger.info("syntax: shell CMD (or ! CMD)",'$MG:color:BLACK') |
1859 | - |
1860 | - |
1861 | - |
1862 | - |
1863 | + logger.info("syntax: shell CMD (or ! CMD)",'$MG:BOLD') |
1864 | + |
1865 | + |
1866 | + |
1867 | +class NotValidInput(Exception): pass |
1868 | #=============================================================================== |
1869 | # Question with auto-completion |
1870 | #=============================================================================== |
1871 | @@ -2042,6 +2044,7 @@ |
1872 | |
1873 | def __init__(self, question, allow_arg=[], default=None, |
1874 | mother_interface=None, *arg, **opt): |
1875 | + |
1876 | self.question = question |
1877 | self.wrong_answer = 0 # forbids infinite loop |
1878 | self.allow_arg = [str(a) for a in allow_arg] |
1879 | @@ -2066,6 +2069,8 @@ |
1880 | setattr(self, key, value) |
1881 | if reprint_opt: |
1882 | print question |
1883 | + logger_tuto.info("Need help here? type 'help'", '$MG:BOLD') |
1884 | + logger_plugin.info("Need help here? type 'help'" , '$MG:BOLD') |
1885 | return self.cmdloop() |
1886 | |
1887 | |
1888 | @@ -2157,21 +2162,21 @@ |
1889 | |
1890 | if not text: |
1891 | if out['Options']: |
1892 | - logger.info( "Here is the list of all valid options:", '$MG:color:BLACK') |
1893 | + logger.info( "Here is the list of all valid options:", '$MG:BOLD') |
1894 | logger.info( " "+ "\n ".join(out['Options'])) |
1895 | if out['command']: |
1896 | - logger.info( "Here is the list of command available:", '$MG:color:BLACK') |
1897 | + logger.info( "Here is the list of command available:", '$MG:BOLD') |
1898 | logger.info( " "+ "\n ".join(out['command'])) |
1899 | else: |
1900 | if out['Options']: |
1901 | - logger.info( "Here is the list of all valid options starting with \'%s\'" % text, '$MG:color:BLACK') |
1902 | + logger.info( "Here is the list of all valid options starting with \'%s\'" % text, '$MG:BOLD') |
1903 | logger.info( " "+ "\n ".join(out['Options'])) |
1904 | if out['command']: |
1905 | - logger.info( "Here is the list of command available starting with \'%s\':" % text, '$MG:color:BLACK') |
1906 | + logger.info( "Here is the list of command available starting with \'%s\':" % text, '$MG:BOLD') |
1907 | logger.info( " "+ "\n ".join(out['command'])) |
1908 | elif not out['Options']: |
1909 | - logger.info( "No possibility starting with \'%s\'" % text, '$MG:color:BLACK') |
1910 | - logger.info( "You can type help XXX, to see all command starting with XXX", '$MG:color:BLACK') |
1911 | + logger.info( "No possibility starting with \'%s\'" % text, '$MG:BOLD') |
1912 | + logger.info( "You can type help XXX, to see all command starting with XXX", '$MG:BOLD') |
1913 | def complete_help(self, text, line, begidx, endidx): |
1914 | """ """ |
1915 | return self.completenames(text, line) |
1916 | @@ -2338,6 +2343,7 @@ |
1917 | |
1918 | Behavior for each switch can be customize via: |
1919 | set_default_XXXX() -> set default value |
1920 | + This is super-seeded by self.default_switch if that attribute is defined (and has a key for XXXX) |
1921 | get_allowed_XXXX() -> return list of possible value |
1922 | check_value_XXXX(value) -> return True/False if the user can set such value |
1923 | switch_off_XXXXX() -> set it off (called for special mode) |
1924 | @@ -2399,9 +2405,9 @@ |
1925 | if 'allow_arg' in opts: |
1926 | allowed_args += opts['allow_arg'] |
1927 | del opts['allow_arg'] |
1928 | - |
1929 | + |
1930 | allowed_args +=["0", "done"] |
1931 | - super(ControlSwitch, self).__init__(question, allowed_args, *args, **opts) |
1932 | + SmartQuestion.__init__(self, question, allowed_args, *args, **opts) |
1933 | self.options = self.mother_interface.options |
1934 | |
1935 | def special_check_answer_in_input_file(self, line, default): |
1936 | @@ -2439,11 +2445,14 @@ |
1937 | |
1938 | for key,_ in self.to_control: |
1939 | key = key.lower() |
1940 | + if hasattr(self, 'default_switch') and key in self.default_switch: |
1941 | + self.switch[key] = self.default_switch[key] |
1942 | + continue |
1943 | if hasattr(self, 'set_default_%s' % key): |
1944 | getattr(self, 'set_default_%s' % key)() |
1945 | else: |
1946 | self.default_switch_for(key) |
1947 | - |
1948 | + |
1949 | def default_switch_for(self, key): |
1950 | """use this if they are no dedicated function for such key""" |
1951 | |
1952 | @@ -2498,8 +2507,8 @@ |
1953 | return getattr(self, 'get_allowed_%s' % key)() |
1954 | else: |
1955 | return ['ON', 'OFF'] |
1956 | - |
1957 | - def default(self, line): |
1958 | + |
1959 | + def default(self, line, raise_error=False): |
1960 | """Default action if line is not recognized""" |
1961 | |
1962 | line=line.strip().replace('@', '__at__') |
1963 | @@ -2511,6 +2520,8 @@ |
1964 | |
1965 | if '=' in line: |
1966 | base, value = line.split('=',1) |
1967 | + base = base.strip() |
1968 | + value = value.strip() |
1969 | # allow 1=OFF |
1970 | if base.isdigit() : |
1971 | try: |
1972 | @@ -2521,7 +2532,7 @@ |
1973 | base, value = line.split(' ', 1) |
1974 | elif hasattr(self, 'ans_%s' % line.lower()): |
1975 | base, value = line.lower(), None |
1976 | - elif line.isdigit() and line in [`i` for i in range(1, len(self.switch)+1)]: |
1977 | + elif line.isdigit() and line in [`i` for i in range(1, len(self.to_control)+1)]: |
1978 | # go from one valid option to the next in the get_allowed for that option |
1979 | base = self.to_control[int(line)-1][0].lower() |
1980 | return self.default(base) # just recall this function with the associate name |
1981 | @@ -2533,7 +2544,7 @@ |
1982 | except: |
1983 | if self.get_allowed(base): |
1984 | value = self.get_allowed(base)[0] |
1985 | - else: |
1986 | + else: |
1987 | logger.warning('Can not switch "%s" to another value via number', base) |
1988 | self.value='reask' |
1989 | return |
1990 | @@ -2548,6 +2559,8 @@ |
1991 | elif line in 'auto': |
1992 | self.switch['dynamical'] = True |
1993 | return super(ControlSwitch, self).default(line) |
1994 | + elif raise_error: |
1995 | + raise NotValidInput('unknow command: %s' % line) |
1996 | else: |
1997 | logger.warning('unknow command: %s' % line) |
1998 | self.value = 'reask' |
1999 | @@ -2560,7 +2573,9 @@ |
2000 | value = value.lower() |
2001 | getattr(self, 'ans_%s' % base)(value) |
2002 | elif base in self.switch: |
2003 | - self.set_switch(base, value) |
2004 | + self.set_switch(base, value) |
2005 | + elif raise_error: |
2006 | + raise NotValidInput('Not valid command: %s' % line) |
2007 | else: |
2008 | logger.warning('Not valid command: %s' % line) |
2009 | |
2010 | @@ -2608,8 +2623,6 @@ |
2011 | """change a switch to a given value""" |
2012 | |
2013 | assert key in self.switch |
2014 | - |
2015 | - |
2016 | |
2017 | if hasattr(self, 'ans_%s' % key): |
2018 | if not self.is_case_sensitive(key): |
2019 | @@ -2827,6 +2840,52 @@ |
2020 | if info == '': |
2021 | info = 'Please install module' |
2022 | return info |
2023 | + |
2024 | + def do_help(self, line, list_command=False): |
2025 | + """dedicated help for the control switch""" |
2026 | + |
2027 | + if line: |
2028 | + return self.print_help_for_switch(line) |
2029 | + |
2030 | + # here for simple "help" |
2031 | + logger.info(" ") |
2032 | + logger.info(" In order to change a switch you can:") |
2033 | + logger.info(" - type 'NAME = VALUE' to set the switch NAME to a given value.") |
2034 | + logger.info(" - type 'ID = VALUE' to set the switch correspond to the line ID to a given value.") |
2035 | + logger.info(" - type 'ID' where ID is the value of the line to pass from one value to the next.") |
2036 | + logger.info(" - type 'NAME' to set the switch NAME to the next value.") |
2037 | + logger.info("") |
2038 | + logger.info(" You can type 'help NAME' for more help on a given switch") |
2039 | + logger.info("") |
2040 | + logger.info(" Special keyword:", '$MG:BOLD') |
2041 | + logger.info(" %s" % '\t'.join([p[4:] for p in dir(self) if p.startswith('ans_')]) ) |
2042 | + logger.info(" type 'help XXX' for more information") |
2043 | + if list_command: |
2044 | + super(ControlSwitch, self).do_help(line) |
2045 | + |
2046 | + |
2047 | + def print_help_for_switch(self, line): |
2048 | + """ """ |
2049 | + |
2050 | + arg = line.split()[0] |
2051 | + |
2052 | + if hasattr(self, 'help_%s' % arg): |
2053 | + return getattr(self, 'help_%s' % arg)('') |
2054 | + |
2055 | + if hasattr(self, 'ans_%s' % arg): |
2056 | + return getattr(self, 'help_%s' % arg).__doc__ |
2057 | + |
2058 | + if arg in self.switch: |
2059 | + logger.info(" information for switch %s: ", arg, '$MG:BOLD') |
2060 | + logger.info(" allowed value:") |
2061 | + logger.info(" %s", '\t'.join(self.get_allowed(arg))) |
2062 | + if hasattr(self, 'help_text_%s' % arg): |
2063 | + logger.info("") |
2064 | + for line in getattr(self, 'help_text_%s' % arg): |
2065 | + logger.info(line) |
2066 | + |
2067 | + |
2068 | + |
2069 | |
2070 | def question_formatting(self, nb_col = 80, |
2071 | ldescription=0, |
2072 | @@ -3000,7 +3059,7 @@ |
2073 | |
2074 | return upper, lower, f1, f2 |
2075 | |
2076 | - def create_question(self): |
2077 | + def create_question(self, help_text=True): |
2078 | """ create the question with correct formatting""" |
2079 | |
2080 | # geth the number of line and column of the shell to adapt the printing |
2081 | @@ -3090,31 +3149,30 @@ |
2082 | |
2083 | if not example: |
2084 | example = ('KEY', 'VALUE') |
2085 | - |
2086 | - text += \ |
2087 | - ["Either type the switch number (1 to %s) to change its setting," % len(self.to_control), |
2088 | - "Set any switch explicitly (e.g. type '%s=%s' at the prompt)" % example, |
2089 | - "Type 'help' for the list of all valid option", |
2090 | - "Type '0', 'auto', 'done' or just press enter when you are done."] |
2091 | - |
2092 | - # check on the number of row: |
2093 | - if len(text) > nb_rows: |
2094 | - # too many lines. Remove some |
2095 | - to_remove = [ -2, #Type 'help' for the list of all valid option |
2096 | - -5, # \====/ |
2097 | - -4, #Either type the switch number (1 to %s) to change its setting, |
2098 | - -3, # Set any switch explicitly |
2099 | - -1, # Type '0', 'auto', 'done' or just press enter when you are done. |
2100 | - ] |
2101 | - to_remove = to_remove[:min(len(to_remove), len(text)-nb_rows)] |
2102 | - text = [t for i,t in enumerate(text) if i-len(text) not in to_remove] |
2103 | - |
2104 | + |
2105 | + if help_text: |
2106 | + text += \ |
2107 | + ["Either type the switch number (1 to %s) to change its setting," % len(self.to_control), |
2108 | + "Set any switch explicitly (e.g. type '%s=%s' at the prompt)" % example, |
2109 | + "Type 'help' for the list of all valid option", |
2110 | + "Type '0', 'auto', 'done' or just press enter when you are done."] |
2111 | + |
2112 | + # check on the number of row: |
2113 | + if len(text) > nb_rows: |
2114 | + # too many lines. Remove some |
2115 | + to_remove = [ -2, #Type 'help' for the list of all valid option |
2116 | + -5, # \====/ |
2117 | + -4, #Either type the switch number (1 to %s) to change its setting, |
2118 | + -3, # Set any switch explicitly |
2119 | + -1, # Type '0', 'auto', 'done' or just press enter when you are done. |
2120 | + ] |
2121 | + to_remove = to_remove[:min(len(to_remove), len(text)-nb_rows)] |
2122 | + text = [t for i,t in enumerate(text) if i-len(text) not in to_remove] |
2123 | + |
2124 | self.question = "\n".join(text) |
2125 | return self.question |
2126 | |
2127 | |
2128 | - |
2129 | - |
2130 | #=============================================================================== |
2131 | # |
2132 | #=============================================================================== |
2133 | |
2134 | === modified file 'madgraph/interface/launch_ext_program.py' |
2135 | --- madgraph/interface/launch_ext_program.py 2018-02-21 22:35:09 +0000 |
2136 | +++ madgraph/interface/launch_ext_program.py 2018-04-20 08:32:43 +0000 |
2137 | @@ -625,73 +625,75 @@ |
2138 | import madgraph.interface.madevent_interface as ME |
2139 | |
2140 | stdout_level = self.cmd_int.options['stdout_level'] |
2141 | - if self.shell: |
2142 | - usecmd = ME.MadEventCmdShell(me_dir=self.running_dir, options=self.options) |
2143 | - else: |
2144 | - usecmd = ME.MadEventCmd(me_dir=self.running_dir, options=self.options) |
2145 | - usecmd.pass_in_web_mode() |
2146 | - #Check if some configuration were overwritten by a command. If so use it |
2147 | - set_cmd = [l for l in self.cmd_int.history if l.strip().startswith('set')] |
2148 | - all_options = usecmd.options_configuration.keys() + usecmd.options_madgraph.keys() + usecmd.options_madevent.keys() |
2149 | - for line in set_cmd: |
2150 | - arg = line.split() |
2151 | - if arg[1] not in all_options: |
2152 | - continue |
2153 | + |
2154 | + with ME.MadEventCmd.RunWebHandling(self.running_dir): |
2155 | + if self.shell: |
2156 | + usecmd = ME.MadEventCmdShell(me_dir=self.running_dir, options=self.options, force_run=True) |
2157 | + else: |
2158 | + usecmd = ME.MadEventCmd(me_dir=self.running_dir, options=self.options, force_run=True) |
2159 | + usecmd.pass_in_web_mode() |
2160 | + #Check if some configuration were overwritten by a command. If so use it |
2161 | + set_cmd = [l for l in self.cmd_int.history if l.strip().startswith('set')] |
2162 | + all_options = usecmd.options_configuration.keys() + usecmd.options_madgraph.keys() + usecmd.options_madevent.keys() |
2163 | + for line in set_cmd: |
2164 | + arg = line.split() |
2165 | + if arg[1] not in all_options: |
2166 | + continue |
2167 | + try: |
2168 | + usecmd.do_set(line[3:], log=False) |
2169 | + except usecmd.InvalidCmd: |
2170 | + pass |
2171 | + usecmd.do_set('stdout_level %s' % stdout_level,log=False) |
2172 | + #ensure that the logger level |
2173 | + launch = self.cmd_int.define_child_cmd_interface( |
2174 | + usecmd, interface=False) |
2175 | + #launch.me_dir = self.running_dir |
2176 | + if self.unit == 'pb': |
2177 | + command = 'generate_events %s' % self.name |
2178 | + else: |
2179 | + warning_text = '''\ |
2180 | + Note that since 2.3. The launch for 1>N pass in event generation |
2181 | + For efficient width computation see arXiv:1402.1178.''' |
2182 | + logger.warning(warning_text) |
2183 | + command = 'generate_events %s' % self.name |
2184 | + if mode == "1": |
2185 | + command += " --cluster" |
2186 | + elif mode == "2": |
2187 | + command += " --nb_core=%s" % nb_node |
2188 | + |
2189 | + if self.force: |
2190 | + command+= " -f" |
2191 | + |
2192 | + if self.laststep: |
2193 | + command += ' --laststep=%s' % self.laststep |
2194 | + if self.reweight: |
2195 | + command += ' -R ' |
2196 | + if self.madspin: |
2197 | + command += ' -M ' |
2198 | + |
2199 | + |
2200 | try: |
2201 | - usecmd.do_set(line[3:], log=False) |
2202 | - except usecmd.InvalidCmd: |
2203 | + os.remove('ME5_debug') |
2204 | + except: |
2205 | pass |
2206 | - usecmd.do_set('stdout_level %s' % stdout_level,log=False) |
2207 | - #ensure that the logger level |
2208 | - launch = self.cmd_int.define_child_cmd_interface( |
2209 | - usecmd, interface=False) |
2210 | - #launch.me_dir = self.running_dir |
2211 | - if self.unit == 'pb': |
2212 | - command = 'generate_events %s' % self.name |
2213 | - else: |
2214 | - warning_text = '''\ |
2215 | - Note that since 2.3. The launch for 1>N pass in event generation |
2216 | - For efficient width computation see arXiv:1402.1178.''' |
2217 | - logger.warning(warning_text) |
2218 | - command = 'generate_events %s' % self.name |
2219 | - if mode == "1": |
2220 | - command += " --cluster" |
2221 | - elif mode == "2": |
2222 | - command += " --nb_core=%s" % nb_node |
2223 | - |
2224 | - if self.force: |
2225 | - command+= " -f" |
2226 | - |
2227 | - if self.laststep: |
2228 | - command += ' --laststep=%s' % self.laststep |
2229 | - if self.reweight: |
2230 | - command += ' -R ' |
2231 | - if self.madspin: |
2232 | - command += ' -M ' |
2233 | - |
2234 | - |
2235 | - try: |
2236 | - os.remove('ME5_debug') |
2237 | - except: |
2238 | - pass |
2239 | - |
2240 | - launch.run_cmd(command) |
2241 | - launch.run_cmd('quit') |
2242 | - |
2243 | - if os.path.exists('ME5_debug'): |
2244 | - return True |
2245 | - |
2246 | - # Display the cross-section to the screen |
2247 | - path = os.path.join(self.running_dir, 'SubProcesses', 'results.dat') |
2248 | - if not os.path.exists(path): |
2249 | - logger.error('Generation failed (no results.dat file found)') |
2250 | - return |
2251 | - fsock = open(path) |
2252 | - line = fsock.readline() |
2253 | - cross, error = line.split()[0:2] |
2254 | - |
2255 | - logger.info('more information in %s' |
2256 | - % os.path.join(self.running_dir, 'index.html')) |
2257 | + |
2258 | + launch.run_cmd(command) |
2259 | + launch.run_cmd('quit') |
2260 | + |
2261 | + if os.path.exists('ME5_debug'): |
2262 | + return True |
2263 | + |
2264 | + # Display the cross-section to the screen |
2265 | + path = os.path.join(self.running_dir, 'SubProcesses', 'results.dat') |
2266 | + if not os.path.exists(path): |
2267 | + logger.error('Generation failed (no results.dat file found)') |
2268 | + return |
2269 | + fsock = open(path) |
2270 | + line = fsock.readline() |
2271 | + cross, error = line.split()[0:2] |
2272 | + |
2273 | + logger.info('more information in %s' |
2274 | + % os.path.join(self.running_dir, 'index.html')) |
2275 | |
2276 | |
2277 | class Pythia8Launcher(ExtLauncher): |
2278 | |
2279 | === modified file 'madgraph/interface/loop_interface.py' |
2280 | --- madgraph/interface/loop_interface.py 2017-08-04 15:48:15 +0000 |
2281 | +++ madgraph/interface/loop_interface.py 2018-04-20 08:32:43 +0000 |
2282 | @@ -503,7 +503,7 @@ |
2283 | if (opt['ninja'] is None) or (os.path.isfile(pjoin(MG5DIR, opt['ninja'],'libninja.a'))): |
2284 | return |
2285 | |
2286 | - logger.info("First output using loop matrix-elements has been detected. Now asking for loop reduction:", '$MG:color:BLACK') |
2287 | + logger.info("First output using loop matrix-elements has been detected. Now asking for loop reduction:", '$MG:BOLD') |
2288 | to_install = self.ask('install', '0', ask_class=AskLoopInstaller, timeout=300, |
2289 | path_msg=' ') |
2290 | |
2291 | |
2292 | === modified file 'madgraph/interface/madevent_interface.py' |
2293 | --- madgraph/interface/madevent_interface.py 2018-04-06 09:56:08 +0000 |
2294 | +++ madgraph/interface/madevent_interface.py 2018-04-20 08:32:43 +0000 |
2295 | @@ -2590,7 +2590,7 @@ |
2296 | param_card_iterator.write(path) |
2297 | name = misc.get_scan_name(orig_name, self.run_name) |
2298 | path = pjoin(self.me_dir, 'Events','scan_%s.txt' % name) |
2299 | - logger.info("write all cross-section results in %s" % path ,'$MG:color:BLACK') |
2300 | + logger.info("write all cross-section results in %s" % path ,'$MG:BOLD') |
2301 | param_card_iterator.write_summary(path) |
2302 | |
2303 | |
2304 | @@ -2988,7 +2988,7 @@ |
2305 | param_card_iterator.write(pjoin(self.me_dir,'Cards','param_card.dat')) |
2306 | scan_name = misc.get_scan_name(orig_name, self.run_name) |
2307 | path = pjoin(self.me_dir, 'Events','scan_%s.txt' % scan_name) |
2308 | - logger.info("write all cross-section results in %s" % path, '$MG:color:BLACK') |
2309 | + logger.info("write all cross-section results in %s" % path, '$MG:BOLD') |
2310 | param_card_iterator.write_summary(path) |
2311 | |
2312 | |
2313 | |
2314 | === modified file 'madgraph/interface/madgraph_interface.py' |
2315 | --- madgraph/interface/madgraph_interface.py 2018-03-27 19:11:45 +0000 |
2316 | +++ madgraph/interface/madgraph_interface.py 2018-04-20 08:32:43 +0000 |
2317 | @@ -297,7 +297,7 @@ |
2318 | |
2319 | def help_save(self): |
2320 | logger.info("syntax: save %s FILENAME" % "|".join(self._save_opts),'$MG:color:BLUE') |
2321 | - logger.info("-- save information as file FILENAME",'$MG:color:BLACK') |
2322 | + logger.info("-- save information as file FILENAME",'$MG:BOLD') |
2323 | logger.info(" FILENAME is optional for saving 'options'.") |
2324 | logger.info(' By default it uses ./input/mg5_configuration.txt') |
2325 | logger.info(' If you put "global" for FILENAME it will use ~/.mg5/mg5_configuration.txt') |
2326 | @@ -306,14 +306,14 @@ |
2327 | |
2328 | def help_load(self): |
2329 | logger.info("syntax: load %s FILENAME" % "|".join(self._save_opts),'$MG:color:BLUE') |
2330 | - logger.info("-- load information from file FILENAME",'$MG:color:BLACK') |
2331 | + logger.info("-- load information from file FILENAME",'$MG:BOLD') |
2332 | |
2333 | def help_import(self): |
2334 | logger.info("syntax: import " + "|".join(self._import_formats) + \ |
2335 | " FILENAME",'$MG:color:BLUE') |
2336 | logger.info("-- imports file(s) in various formats",'$MG:color:GREEN') |
2337 | logger.info("") |
2338 | - logger.info(" import model MODEL[-RESTRICTION] [OPTIONS]:",'$MG:color:BLACK') |
2339 | + logger.info(" import model MODEL[-RESTRICTION] [OPTIONS]:",'$MG:BOLD') |
2340 | logger.info(" Import a UFO model.") |
2341 | logger.info(" MODEL should be a valid UFO model name") |
2342 | logger.info(" Model restrictions are specified by MODEL-RESTRICTION") |
2343 | @@ -324,21 +324,21 @@ |
2344 | logger.info("") |
2345 | logger.info(" Type 'display modellist' to have the list of all model available.",'$MG:color:GREEN') |
2346 | logger.info("") |
2347 | - logger.info(" import model_v4 MODEL [--modelname] :",'$MG:color:BLACK') |
2348 | + logger.info(" import model_v4 MODEL [--modelname] :",'$MG:BOLD') |
2349 | logger.info(" Import an MG4 model.") |
2350 | logger.info(" Model should be the name of the model") |
2351 | logger.info(" or the path to theMG4 model directory") |
2352 | logger.info(" '--modelname' keeps the original particle names for the model") |
2353 | logger.info("") |
2354 | - logger.info(" import proc_v4 [PATH] :",'$MG:color:BLACK') |
2355 | + logger.info(" import proc_v4 [PATH] :",'$MG:BOLD') |
2356 | logger.info(" Execute MG5 based on a proc_card.dat in MG4 format.") |
2357 | logger.info(" Path to the proc_card is optional if you are in a") |
2358 | logger.info(" madevent directory") |
2359 | logger.info("") |
2360 | - logger.info(" import command PATH :",'$MG:color:BLACK') |
2361 | + logger.info(" import command PATH :",'$MG:BOLD') |
2362 | logger.info(" Execute the list of command in the file at PATH") |
2363 | logger.info("") |
2364 | - logger.info(" import banner PATH [--no_launch]:",'$MG:color:BLACK') |
2365 | + logger.info(" import banner PATH [--no_launch]:",'$MG:BOLD') |
2366 | logger.info(" Rerun the exact same run define in the valid banner.") |
2367 | |
2368 | def help_install(self): |
2369 | @@ -354,7 +354,7 @@ |
2370 | logger.info(" --force Overwrite without asking any existing installation.") |
2371 | logger.info(" --keep_source Keep a local copy of the sources of the tools MG5_aMC installed from.") |
2372 | logger.info(" ") |
2373 | - logger.info(" \"install update\"",'$MG:color:BLACK') |
2374 | + logger.info(" \"install update\"",'$MG:BOLD') |
2375 | logger.info(" check if your MG5 installation is the latest one.") |
2376 | logger.info(" If not it load the difference between your current version and the latest one,") |
2377 | logger.info(" and apply it to the code. Two options are available for this command:") |
2378 | @@ -378,11 +378,11 @@ |
2379 | # color schemes. |
2380 | #_launch_parser.print_help() |
2381 | logger.info("syntax: launch <dir_path> <options>",'$MG:color:BLUE') |
2382 | - logger.info("-- execute the aMC@NLO/madevent/standalone/pythia8 output present in dir_path",'$MG:color:BLACK') |
2383 | + logger.info("-- execute the aMC@NLO/madevent/standalone/pythia8 output present in dir_path",'$MG:BOLD') |
2384 | logger.info("By default, dir_path points to the last created directory.") |
2385 | logger.info("(for pythia8, it should be the Pythia 8 main directory)") |
2386 | logger.info("") |
2387 | - logger.info("Launch on madevent/pythia8/standalone outputs:",'$MG:color:BLACK') |
2388 | + logger.info("Launch on madevent/pythia8/standalone outputs:",'$MG:BOLD') |
2389 | logger.info(" o Example: launch PROC_sm_1 --name=run2",'$MG:color:GREEN') |
2390 | logger.info(" o Example: launch ../pythia8",'$MG:color:GREEN') |
2391 | logger.info(" > Options:") |
2392 | @@ -397,7 +397,7 @@ |
2393 | logger.info(" last program run in MadEvent run.") |
2394 | logger.info(" [auto|parton|pythia|pgs|delphes]") |
2395 | logger.info("") |
2396 | - logger.info("Launch on MadLoop standalone output:",'$MG:color:BLACK') |
2397 | + logger.info("Launch on MadLoop standalone output:",'$MG:BOLD') |
2398 | logger.info(" o Example: launch PROC_loop_sm_1 -f",'$MG:color:GREEN') |
2399 | logger.info(" > Simple check of a single Phase-space points.") |
2400 | logger.info(" > You will be asked whether you want to edit the MadLoop ") |
2401 | @@ -405,7 +405,7 @@ |
2402 | logger.info(" the -f option is specified. All other options are ") |
2403 | logger.info(" irrelevant for this kind of launch.") |
2404 | logger.info("") |
2405 | - logger.info("Launch on aMC@NLO output:",'$MG:color:BLACK') |
2406 | + logger.info("Launch on aMC@NLO output:",'$MG:BOLD') |
2407 | logger.info(" > launch <dir_path> <mode> <options>",'$MG:color:BLUE') |
2408 | logger.info(" o Example: launch MyProc aMC@NLO -f -p",'$MG:color:GREEN') |
2409 | |
2410 | @@ -417,7 +417,7 @@ |
2411 | |
2412 | def help_open(self): |
2413 | logger.info("syntax: open FILE ",'$MG:color:BLUE') |
2414 | - logger.info("-- open a file with the appropriate editor.",'$MG:color:BLACK') |
2415 | + logger.info("-- open a file with the appropriate editor.",'$MG:BOLD') |
2416 | logger.info(' If FILE belongs to index.html, param_card.dat, run_card.dat') |
2417 | logger.info(' the path to the last created/used directory is used') |
2418 | logger.info(' The program used to open those files can be chosen in the') |
2419 | @@ -425,16 +425,16 @@ |
2420 | |
2421 | def help_customize_model(self): |
2422 | logger.info("syntax: customize_model --save=NAME",'$MG:color:BLUE') |
2423 | - logger.info("-- Open an invite where you options to tweak the model.",'$MG:color:BLACK') |
2424 | + logger.info("-- Open an invite where you options to tweak the model.",'$MG:BOLD') |
2425 | logger.info(" If you specify the option --save=NAME, this tweak will be") |
2426 | logger.info(" available for future import with the command 'import model XXXX-NAME'") |
2427 | |
2428 | def help_output(self): |
2429 | logger.info("syntax: output [" + "|".join(self._export_formats) + \ |
2430 | "] [path|.|auto] [options]",'$MG:color:BLUE') |
2431 | - logger.info("-- Output any generated process(es) to file.",'$MG:color:BLACK') |
2432 | + logger.info("-- Output any generated process(es) to file.",'$MG:BOLD') |
2433 | logger.info(" Default mode is madevent. Default path is \'.\' or auto.") |
2434 | - logger.info(" mode:",'$MG:color:BLACK') |
2435 | + logger.info(" mode:",'$MG:BOLD') |
2436 | logger.info(" - For MadLoop and aMC@NLO runs, there is only one mode and") |
2437 | logger.info(" it is set by default.") |
2438 | logger.info(" - If mode is madevent, create a MadEvent process directory.") |
2439 | @@ -452,10 +452,10 @@ |
2440 | logger.info(" valid options for aloha output are:") |
2441 | logger.info(" --format=Fortran|Python|Cpp : defining the output language") |
2442 | logger.info(" --output= : defining output directory") |
2443 | - logger.info(" path: The path of the process directory.",'$MG:color:BLACK') |
2444 | + logger.info(" path: The path of the process directory.",'$MG:BOLD') |
2445 | logger.info(" If you put '.' as path, your pwd will be used.") |
2446 | logger.info(" If you put 'auto', an automatic directory PROC_XX_n will be created.") |
2447 | - logger.info(" options:",'$MG:color:BLACK') |
2448 | + logger.info(" options:",'$MG:BOLD') |
2449 | logger.info(" -f: force cleaning of the directory if it already exists") |
2450 | logger.info(" -d: specify other MG/ME directory") |
2451 | logger.info(" -noclean: no cleaning performed in \"path\".") |
2452 | @@ -468,8 +468,8 @@ |
2453 | |
2454 | def help_check(self): |
2455 | logger.info("syntax: check [" + "|".join(self._check_opts) + "] [param_card] process_definition [--energy=] [--split_orders=] [--reduction=]",'$MG:color:BLUE') |
2456 | - logger.info("-- check a process or set of processes.",'$MG:color:BLACK') |
2457 | - logger.info("General options:",'$MG:color:BLACK') |
2458 | + logger.info("-- check a process or set of processes.",'$MG:BOLD') |
2459 | + logger.info("General options:",'$MG:BOLD') |
2460 | logger.info("o full:",'$MG:color:GREEN') |
2461 | logger.info(" Perform all four checks described below:") |
2462 | logger.info(" permutation, brs, gauge and lorentz_invariance.") |
2463 | @@ -530,7 +530,7 @@ |
2464 | logger.info(" > Except for the 'gauge' test, all checks above are also") |
2465 | logger.info(" available for loop processes with ML5 ('virt=' mode)") |
2466 | logger.info("Example: check full p p > j j",'$MG:color:GREEN') |
2467 | - logger.info("Options for loop processes only:",'$MG:color:BLACK') |
2468 | + logger.info("Options for loop processes only:",'$MG:BOLD') |
2469 | logger.info("o timing:",'$MG:color:GREEN') |
2470 | logger.info(" Generate and output a process and returns detailed") |
2471 | logger.info(" information about the code and a timing benchmark.") |
2472 | @@ -560,7 +560,7 @@ |
2473 | def help_generate(self): |
2474 | |
2475 | logger.info("-- generate diagrams for a given process",'$MG:color:BLUE') |
2476 | - logger.info("General leading-order syntax:",'$MG:color:BLACK') |
2477 | + logger.info("General leading-order syntax:",'$MG:BOLD') |
2478 | logger.info(" o generate INITIAL STATE > REQ S-CHANNEL > FINAL STATE $ EXCL S-CHANNEL / FORBIDDEN PARTICLES COUP1=ORDER1 COUP2^2=ORDER2 @N") |
2479 | logger.info(" o Example: generate l+ vl > w+ > l+ vl a $ z / a h QED<=3 QCD=0 @1",'$MG:color:GREEN') |
2480 | logger.info(" > Alternative required s-channels can be separated by \"|\":") |
2481 | @@ -576,11 +576,11 @@ |
2482 | logger.info(" > allowed coupling operator are: \"==\", \"=\", \"<=\" and \">\".") |
2483 | logger.info(" \"==\" request exactly that number of coupling while \"=\" is interpreted as \"<=\".") |
2484 | logger.info(" > To generate a second process use the \"add process\" command") |
2485 | - logger.info("Decay chain syntax:",'$MG:color:BLACK') |
2486 | + logger.info("Decay chain syntax:",'$MG:BOLD') |
2487 | logger.info(" o core process, decay1, (decay2, (decay2', ...)), ... etc") |
2488 | logger.info(" o Example: generate p p > t~ t QED=0, (t~ > W- b~, W- > l- vl~), t > j j b @2",'$MG:color:GREEN') |
2489 | logger.info(" > Note that identical particles will all be decayed.") |
2490 | - logger.info("Loop processes syntax:",'$MG:color:BLACK') |
2491 | + logger.info("Loop processes syntax:",'$MG:BOLD') |
2492 | logger.info(" o core process [ <NLO_mode=> LoopOrder1 LoopOrder2 ... ] SQUAREDCOUPi=ORDERi") |
2493 | logger.info(" o Example: generate p p > t~ t QED=0 QCD=2 [ all= QCD ] QCD=6",'$MG:color:GREEN') |
2494 | logger.info(" > Notice that in this format, decay chains are not allowed.") |
2495 | @@ -604,7 +604,7 @@ |
2496 | logger.info(" OR merge two model",'$MG:color:BLUE') |
2497 | logger.info('') |
2498 | logger.info("-- generate diagrams for a process and add to existing processes",'$MG:color:BLUE') |
2499 | - logger.info("General leading-order syntax:",'$MG:color:BLACK') |
2500 | + logger.info("General leading-order syntax:",'$MG:BOLD') |
2501 | logger.info(" o add process INITIAL STATE > REQ S-CHANNEL > FINAL STATE $ EXCL S-CHANNEL / FORBIDDEN PARTICLES COUP1=ORDER1 COUP2=ORDER2 @N") |
2502 | logger.info(" o Example: add process l+ vl > w+ > l+ vl a $ z / a h QED=3 QCD=0 @1",'$MG:color:GREEN') |
2503 | logger.info(" > Alternative required s-channels can be separated by \"|\":") |
2504 | @@ -613,11 +613,11 @@ |
2505 | logger.info(" orders to ensure maximum number of QCD vertices.") |
2506 | logger.info(" > Note that if there are more than one non-QCD coupling type,") |
2507 | logger.info(" coupling orders need to be specified by hand.") |
2508 | - logger.info("Decay chain syntax:",'$MG:color:BLACK') |
2509 | + logger.info("Decay chain syntax:",'$MG:BOLD') |
2510 | logger.info(" o core process, decay1, (decay2, (decay2', ...)), ... etc") |
2511 | logger.info(" o Example: add process p p > t~ t QED=0, (t~ > W- b~, W- > l- vl~), t > j j b @2",'$MG:color:GREEN') |
2512 | logger.info(" > Note that identical particles will all be decayed.") |
2513 | - logger.info("Loop processes syntax:",'$MG:color:BLACK') |
2514 | + logger.info("Loop processes syntax:",'$MG:BOLD') |
2515 | logger.info(" o core process [ <NLO_mode=> LoopOrder1 LoopOrder2 ... ] SQUAREDCOUPi=ORDERi") |
2516 | logger.info(" o Example: add process p p > t~ t QED=0 QCD=2 [ all= QCD ] QCD=6",'$MG:color:GREEN') |
2517 | logger.info(" > Notice that in this format, decay chains are not allowed.") |
2518 | @@ -637,7 +637,7 @@ |
2519 | logger.info(" can still handle these.") |
2520 | |
2521 | logger.info("-- merge two model to create a new one", '$MG:color:BLUE') |
2522 | - logger.info("syntax:",'$MG:color:BLACK') |
2523 | + logger.info("syntax:",'$MG:BOLD') |
2524 | logger.info(" o add model MODELNAME [OPTIONS]") |
2525 | logger.info(" o Example: add model taudecay",'$MG:color:GREEN') |
2526 | logger.info(" > Merge the two model in a single one. If that same merge was done before.") |
2527 | @@ -706,7 +706,7 @@ |
2528 | |
2529 | def help_set(self): |
2530 | logger.info("-- set options for generation or output.",'$MG:color:BLUE') |
2531 | - logger.info("syntax: set <option_name> <option_value>",'$MG:color:BLACK') |
2532 | + logger.info("syntax: set <option_name> <option_value>",'$MG:BOLD') |
2533 | logger.info("Possible options are: ") |
2534 | for opts in [self._set_options[i*3:(i+1)*3] for i in \ |
2535 | range((len(self._set_options)//4)+1)]: |
2536 | @@ -716,8 +716,8 @@ |
2537 | logger.info(" > (default Auto) Smart grouping of subprocesses into ") |
2538 | logger.info(" directories, mirroring of initial states, and ") |
2539 | logger.info(" combination of integration channels.") |
2540 | - logger.info(" > Example: p p > j j j w+ gives 5 directories and 184 channels",'$MG:color:BLACK') |
2541 | - logger.info(" (cf. 65 directories and 1048 channels for regular output)",'$MG:color:BLACK') |
2542 | + logger.info(" > Example: p p > j j j w+ gives 5 directories and 184 channels",'$MG:BOLD') |
2543 | + logger.info(" (cf. 65 directories and 1048 channels for regular output)",'$MG:BOLD') |
2544 | logger.info(" > Auto means False for decay computation and True for collisions.") |
2545 | logger.info("ignore_six_quark_processes multi_part_label",'$MG:color:GREEN') |
2546 | logger.info(" > (default none) ignore processes with at least 6 of any") |
2547 | @@ -1081,7 +1081,7 @@ |
2548 | |
2549 | def check_import(self, args): |
2550 | """check the validity of line""" |
2551 | - |
2552 | + |
2553 | modelname = False |
2554 | prefix = True |
2555 | if '-modelname' in args: |
2556 | @@ -1095,6 +1095,26 @@ |
2557 | args.remove('--noprefix') |
2558 | prefix = False |
2559 | |
2560 | + if args and args[0] == 'model' and '--last' in args: |
2561 | + # finding last created directory |
2562 | + args.remove('--last') |
2563 | + last_change = 0 |
2564 | + to_search = [pjoin(MG5DIR,'models')] |
2565 | + if 'PYTHONPATH' in os.environ: |
2566 | + to_search += os.environ['PYTHONPATH'].split(':') |
2567 | + to_search = [d for d in to_search if os.path.exists(d)] |
2568 | + |
2569 | + models = [] |
2570 | + for d in to_search: |
2571 | + for p in misc.glob('*/particles.py', path=d ): |
2572 | + if p.endswith(('__REAL/particles.py','__COMPLEX/particles.py')): |
2573 | + continue |
2574 | + models.append(os.path.dirname(p)) |
2575 | + |
2576 | + lastmodel = max(models, key=os.path.getmtime) |
2577 | + logger.info('last model found is %s', lastmodel) |
2578 | + args.insert(1, lastmodel) |
2579 | + |
2580 | if not args: |
2581 | self.help_import() |
2582 | raise self.InvalidCmd('wrong \"import\" format') |
2583 | @@ -1160,7 +1180,7 @@ |
2584 | # to install as argument. |
2585 | args = args[:1] |
2586 | |
2587 | - if args[0] not in self._install_opts + hidden_prog: |
2588 | + if args[0] not in self._install_opts + hidden_prog + self._advanced_install_opts: |
2589 | if not args[0].startswith('td'): |
2590 | self.help_install() |
2591 | raise self.InvalidCmd('Not recognize program %s ' % args[0]) |
2592 | @@ -1499,7 +1519,6 @@ |
2593 | def check_output(self, args, default='madevent'): |
2594 | """ check the validity of the line""" |
2595 | |
2596 | - |
2597 | if args and args[0] in self._export_formats: |
2598 | self._export_format = args.pop(0) |
2599 | elif args: |
2600 | @@ -2717,7 +2736,7 @@ |
2601 | args = self.split_arg(line[0:begidx]) |
2602 | # Format |
2603 | if len(args) == 1: |
2604 | - return self.list_completion(text, self._install_opts) |
2605 | + return self.list_completion(text, self._install_opts + self._advanced_install_opts) |
2606 | elif len(args) and args[0] == 'update': |
2607 | return self.list_completion(text, ['-f','--timeout=']) |
2608 | elif len(args)>=2 and args[1] in self._advanced_install_opts: |
2609 | @@ -2763,7 +2782,7 @@ |
2610 | 'gauge','lorentz', 'brs', 'cms'] |
2611 | _import_formats = ['model_v4', 'model', 'proc_v4', 'command', 'banner'] |
2612 | _install_opts = ['Delphes', 'MadAnalysis4', 'ExRootAnalysis', |
2613 | - 'update', 'SysCalc', 'Golem95', 'PJFry', 'QCDLoop', 'maddm'] |
2614 | + 'update', 'SysCalc', 'Golem95', 'PJFry', 'QCDLoop'] |
2615 | |
2616 | # The targets below are installed using the HEPToolsInstaller.py script |
2617 | _advanced_install_opts = ['pythia8','zlib','boost','lhapdf6','lhapdf5','collier', |
2618 | @@ -4422,23 +4441,32 @@ |
2619 | if not options['reuse']: |
2620 | process_checks.clean_up(self._mgme_dir) |
2621 | |
2622 | + |
2623 | + def clean_process(self): |
2624 | + """ensure that all processes are cleaned from memory. |
2625 | + typically called from import model and generate XXX command |
2626 | + """ |
2627 | + |
2628 | + aloha_lib.KERNEL.clean() |
2629 | + # Reset amplitudes |
2630 | + self._curr_amps = diagram_generation.AmplitudeList() |
2631 | + # Reset Process definition |
2632 | + self._curr_proc_defs = base_objects.ProcessDefinitionList() |
2633 | + # Reset Helas matrix elements |
2634 | + self._curr_matrix_elements = helas_objects.HelasMultiProcess() |
2635 | + self._generate_info = "" |
2636 | + # Reset _done_export, since we have new process |
2637 | + self._done_export = False |
2638 | + # Also reset _export_format and _export_dir |
2639 | + self._export_format = None |
2640 | + |
2641 | + |
2642 | # Generate a new amplitude |
2643 | def do_generate(self, line): |
2644 | """Main commands: Generate an amplitude for a given process""" |
2645 | |
2646 | - aloha_lib.KERNEL.clean() |
2647 | - # Reset amplitudes |
2648 | - self._curr_amps = diagram_generation.AmplitudeList() |
2649 | - # Reset Process definition |
2650 | - self._curr_proc_defs = base_objects.ProcessDefinitionList() |
2651 | - # Reset Helas matrix elements |
2652 | - self._curr_matrix_elements = helas_objects.HelasMultiProcess() |
2653 | + self.clean_process() |
2654 | self._generate_info = line |
2655 | - # Reset _done_export, since we have new process |
2656 | - self._done_export = False |
2657 | - # Also reset _export_format and _export_dir |
2658 | - self._export_format = None |
2659 | - |
2660 | |
2661 | # Call add process |
2662 | args = self.split_arg(line) |
2663 | @@ -4563,7 +4591,7 @@ |
2664 | if name not in orders and name not in squared_orders] |
2665 | if to_set: |
2666 | logger.info('the following coupling will be allowed up to the maximal value of %s: %s' % |
2667 | - (self.options['default_unset_couplings'], ', '.join(to_set)), '$MG:color:BLACK') |
2668 | + (self.options['default_unset_couplings'], ', '.join(to_set)), '$MG:BOLD') |
2669 | for name in to_set: |
2670 | orders[name] = self.options['default_unset_couplings'] |
2671 | |
2672 | @@ -4791,7 +4819,15 @@ |
2673 | else: |
2674 | optimize = False |
2675 | |
2676 | - |
2677 | + # Extract potential loop_filter |
2678 | + loop_filter=None |
2679 | + for arg in args: |
2680 | + if arg.startswith('--loop_filter='): |
2681 | + loop_filter = arg[14:] |
2682 | + #if not isinstance(self, extended_cmd.CmdShell): |
2683 | + # raise self.InvalidCmd, "loop_filter is not allowed in web mode" |
2684 | + args = [a for a in args if not a.startswith('--loop_filter=')] |
2685 | + |
2686 | if not myprocdef: |
2687 | myprocdef = self.extract_process(' '.join(args)) |
2688 | |
2689 | @@ -4840,7 +4876,8 @@ |
2690 | myproc = loop_diagram_generation.LoopInducedMultiProcess(myprocdef, |
2691 | collect_mirror_procs = collect_mirror_procs, |
2692 | ignore_six_quark_processes = ignore_six_quark_processes, |
2693 | - optimize=optimize) |
2694 | + optimize=optimize, |
2695 | + loop_filter=loop_filter) |
2696 | |
2697 | for amp in myproc.get('amplitudes'): |
2698 | if amp not in self._curr_amps: |
2699 | @@ -5149,10 +5186,7 @@ |
2700 | if args[0].startswith('model'): |
2701 | self._model_v4_path = None |
2702 | # Reset amplitudes and matrix elements |
2703 | - self._curr_amps = diagram_generation.AmplitudeList() |
2704 | - # Reset proc defs |
2705 | - self._curr_proc_defs = base_objects.ProcessDefinitionList() |
2706 | - self._curr_matrix_elements = helas_objects.HelasMultiProcess() |
2707 | + self.clean_process() |
2708 | # Import model |
2709 | if args[0].endswith('_v4'): |
2710 | self._curr_model, self._model_v4_path = \ |
2711 | @@ -5638,9 +5672,9 @@ |
2712 | |
2713 | if tool=='madanalysis5': |
2714 | if not any(o.startswith(('--with_','--veto_','--update')) for o in add_options): |
2715 | - logger.info(' To install recasting capabilities of madanalysis5 and/or', '$MG:color:BLACK') |
2716 | - logger.info(' to allow delphes analysis at parton level.','$MG:color:BLACK') |
2717 | - logger.info(' Please run \'install MadAnalysis5 --with_delphes --update\':', '$MG:color:BLACK') |
2718 | + logger.info(' To install recasting capabilities of madanalysis5 and/or', '$MG:BOLD') |
2719 | + logger.info(' to allow delphes analysis at parton level.','$MG:BOLD') |
2720 | + logger.info(' Please run \'install MadAnalysis5 --with_delphes --update\':', '$MG:BOLD') |
2721 | |
2722 | elif return_code == 66: |
2723 | answer = self.ask(question= |
2724 | @@ -5712,6 +5746,9 @@ |
2725 | MG5aMC that supports quadruple precision (typically g++ based on gcc 4.6+).""") |
2726 | self.options['ninja'] = pjoin(prefix,'lib') |
2727 | self.exec_cmd('save options %s ninja' % config_file, printcmd=False, log=False) |
2728 | + elif '%s_path' % tool in self.options: |
2729 | + self.options['%s_path' % tool] = pjoin(prefix, tool) |
2730 | + self.exec_cmd('save options %s %s_path' % (config_file,tool), printcmd=False, log=False) |
2731 | |
2732 | # Now warn the user if he didn't add HEPTools first in his environment |
2733 | # variables. |
2734 | @@ -5761,34 +5798,8 @@ |
2735 | # Return true for successful installation |
2736 | return True |
2737 | |
2738 | - def do_install(self, line, paths=None, additional_options=[]): |
2739 | - """Install optional package from the MG suite. |
2740 | - The argument 'additional_options' will be passed to the advanced_install |
2741 | - functions. If it contains the option '--force', then the advanced_install |
2742 | - function will overwrite any existing installation of the tool without |
2743 | - warnings. |
2744 | - """ |
2745 | - |
2746 | - # Make sure to avoid any border effect on custom_additional_options |
2747 | - add_options = list(additional_options) |
2748 | - |
2749 | - args = self.split_arg(line) |
2750 | - #check the validity of the arguments |
2751 | - install_options = self.check_install(args) |
2752 | - |
2753 | - if sys.platform == "darwin": |
2754 | - program = "curl" |
2755 | - else: |
2756 | - program = "wget" |
2757 | - |
2758 | - # special command for auto-update |
2759 | - if args[0] == 'update': |
2760 | - self.install_update(['update']+install_options['update_options'],wget=program) |
2761 | - return |
2762 | - |
2763 | - plugin = ['maddm'] |
2764 | - |
2765 | - advertisements = {'pythia-pgs':['arXiv:0603175'], |
2766 | + install_plugin = ['maddm'] |
2767 | + install_ad = {'pythia-pgs':['arXiv:0603175'], |
2768 | 'Delphes':['arXiv:1307.6346'], |
2769 | 'Delphes2':['arXiv:0903.2225'], |
2770 | 'SysCalc':['arXiv:1801.08401'], |
2771 | @@ -5806,15 +5817,54 @@ |
2772 | 'collier':['arXiv:1604.06792'], |
2773 | 'oneloop':['arXiv:1007.4716'], |
2774 | 'maddm':['arXiv:1505.04190']} |
2775 | + install_server = ['http://madgraph.phys.ucl.ac.be/package_info.dat', |
2776 | + 'http://madgraph.physics.illinois.edu/package_info.dat'] |
2777 | + install_name = {'td_mac': 'td', 'td_linux':'td', 'Delphes2':'Delphes', |
2778 | + 'Delphes3':'Delphes', 'pythia-pgs':'pythia-pgs', |
2779 | + 'ExRootAnalysis': 'ExRootAnalysis','MadAnalysis':'madanalysis5', |
2780 | + 'MadAnalysis4':'MadAnalysis', |
2781 | + 'SysCalc':'SysCalc', 'Golem95': 'golem95', |
2782 | + 'PJFry':'PJFry','QCDLoop':'QCDLoop','MadAnalysis5':'madanalysis5', |
2783 | + 'maddm':'maddm' |
2784 | + } |
2785 | + |
2786 | + def do_install(self, line, paths=None, additional_options=[]): |
2787 | + """Install optional package from the MG suite. |
2788 | + The argument 'additional_options' will be passed to the advanced_install |
2789 | + functions. If it contains the option '--force', then the advanced_install |
2790 | + function will overwrite any existing installation of the tool without |
2791 | + warnings. |
2792 | + """ |
2793 | + |
2794 | + # Make sure to avoid any border effect on custom_additional_options |
2795 | + add_options = list(additional_options) |
2796 | + |
2797 | + args = self.split_arg(line) |
2798 | + #check the validity of the arguments |
2799 | + install_options = self.check_install(args) |
2800 | + |
2801 | + if sys.platform == "darwin": |
2802 | + program = "curl" |
2803 | + else: |
2804 | + program = "wget" |
2805 | + |
2806 | + # special command for auto-update |
2807 | + if args[0] == 'update': |
2808 | + self.install_update(['update']+install_options['update_options'],wget=program) |
2809 | + return |
2810 | + |
2811 | + plugin = self.install_plugin |
2812 | + |
2813 | + advertisements = self.install_ad |
2814 | |
2815 | |
2816 | if args[0] in advertisements: |
2817 | -# logger.info('{:^80}'.format("-"*70), '$MG:color:BLACK') |
2818 | -# logger.info('{:^80}'.format("You are installing '%s', please cite ref(s):"%args[0]), '$MG:color:BLACK') |
2819 | +# logger.info('{:^80}'.format("-"*70), '$MG:BOLD') |
2820 | +# logger.info('{:^80}'.format("You are installing '%s', please cite ref(s):"%args[0]), '$MG:BOLD') |
2821 | # logger.info('{:^80}'.format(', '.join(advertisements[args[0]])), '$MG:color:GREEN') |
2822 | -# logger.info('{:^80}'.format("when using results produced with this tool."), '$MG:color:BLACK') |
2823 | -# logger.info('{:^80}'.format("-"*70), '$MG:color:BLACK') |
2824 | - logger.info(" You are installing '%s', please cite ref(s): \033[92m%s\033[0m. " % (args[0], ', '.join(advertisements[args[0]])), '$MG:color:BLACK') |
2825 | +# logger.info('{:^80}'.format("when using results produced with this tool."), '$MG:BOLD') |
2826 | +# logger.info('{:^80}'.format("-"*70), '$MG:BOLD') |
2827 | + logger.info(" You are installing '%s', please cite ref(s): \033[92m%s\033[0m. " % (args[0], ', '.join(advertisements[args[0]])), '$MG:BOLD') |
2828 | |
2829 | # Load file with path of the different program: |
2830 | import urllib |
2831 | @@ -5823,8 +5873,7 @@ |
2832 | else: |
2833 | path = {} |
2834 | |
2835 | - data_path = ['http://madgraph.phys.ucl.ac.be/package_info.dat', |
2836 | - 'http://madgraph.physics.illinois.edu/package_info.dat'] |
2837 | + data_path = self.install_server |
2838 | |
2839 | # Force here to choose one particular server |
2840 | if any(a.startswith('--source=') for a in args): |
2841 | @@ -5864,15 +5913,11 @@ |
2842 | |
2843 | if args[0] == 'Delphes': |
2844 | args[0] = 'Delphes3' |
2845 | + if args[0] == 'MadAnalysis4': |
2846 | + args[0] = 'MadAnalysis' |
2847 | |
2848 | try: |
2849 | - name = {'td_mac': 'td', 'td_linux':'td', 'Delphes2':'Delphes', |
2850 | - 'Delphes3':'Delphes', 'pythia-pgs':'pythia-pgs', |
2851 | - 'ExRootAnalysis': 'ExRootAnalysis','MadAnalysis':'madanalysis5', |
2852 | - 'MadAnalysis4':'MadAnalysis', |
2853 | - 'SysCalc':'SysCalc', 'Golem95': 'golem95', |
2854 | - 'PJFry':'PJFry','QCDLoop':'QCDLoop','MadAnalysis5':'madanalysis5' |
2855 | - } |
2856 | + name = self.install_name |
2857 | name = name[args[0]] |
2858 | except KeyError: |
2859 | name = args[0] |
2860 | @@ -5900,19 +5945,7 @@ |
2861 | |
2862 | if args[0] == 'Delphes': |
2863 | args[0] = 'Delphes3' |
2864 | - if args[0] == 'MadAnalysis4': |
2865 | - args[0] = 'MadAnalysis' |
2866 | - try: |
2867 | - name = {'td_mac': 'td', 'td_linux':'td', 'Delphes2':'Delphes', |
2868 | - 'Delphes3':'Delphes', 'pythia-pgs':'pythia-pgs', |
2869 | - 'ExRootAnalysis': 'ExRootAnalysis','MadAnalysis':'MadAnalysis', |
2870 | - 'SysCalc':'SysCalc', 'Golem95': 'golem95', |
2871 | - 'PJFry':'PJFry','QCDLoop':'QCDLoop', |
2872 | - 'maddm':'maddm' |
2873 | - } |
2874 | - name = name[args[0]] |
2875 | - except: |
2876 | - pass |
2877 | + |
2878 | |
2879 | #check outdated install |
2880 | substitution={'Delphes2':'Delphes','pythia-pgs':'pythia8'} |
2881 | @@ -5948,6 +5981,8 @@ |
2882 | created_name = created_name[0] |
2883 | files.mv(pjoin(MG5DIR, created_name), pjoin(MG5DIR, name)) |
2884 | |
2885 | + if hasattr(self, 'post_install_%s' %name): |
2886 | + return getattr(self, 'post_install_%s' %name)() |
2887 | |
2888 | logger.info('compile %s. This might take a while.' % name) |
2889 | |
2890 | @@ -7402,7 +7437,6 @@ |
2891 | # Check Argument validity |
2892 | self.check_output(args) |
2893 | |
2894 | - |
2895 | noclean = '-noclean' in args |
2896 | force = '-f' in args |
2897 | nojpeg = '-nojpeg' in args |
2898 | @@ -8182,7 +8216,7 @@ |
2899 | #compile the code |
2900 | if not os.path.exists(pjoin(model_path, 'SMWidth','smwidth')): |
2901 | logger.info('Compiling SMWidth. This has to be done only once and'+\ |
2902 | - ' can take a couple of minutes.','$MG:color:BLACK') |
2903 | + ' can take a couple of minutes.','$MG:BOLD') |
2904 | current = misc.detect_current_compiler(pjoin(model_path, 'SMWidth', |
2905 | 'makefile_MW5')) |
2906 | new = 'gfortran' if self.options_configuration['fortran_compiler'] is None else \ |
2907 | |
2908 | === modified file 'madgraph/interface/madweight_interface.py' |
2909 | --- madgraph/interface/madweight_interface.py 2017-07-13 15:12:05 +0000 |
2910 | +++ madgraph/interface/madweight_interface.py 2018-04-20 08:32:43 +0000 |
2911 | @@ -275,7 +275,7 @@ |
2912 | if not self.options['cluster_temp_path']: |
2913 | if self.options['run_mode'] == 2: |
2914 | logger.info('Options cluster_temp_path is required for MW run. Trying to run with /tmp', |
2915 | - '$MG:color:BLACK') |
2916 | + '$MG:BOLD') |
2917 | self.exec_cmd('set cluster_temp_path /tmp --no_save') |
2918 | elif self.options['cluster_type'] != 'condor': |
2919 | raise Exception, 'cluster_temp_path needs to be define for MW. Please retry.' |
2920 | |
2921 | === modified file 'madgraph/interface/master_interface.py' |
2922 | --- madgraph/interface/master_interface.py 2017-11-30 23:06:17 +0000 |
2923 | +++ madgraph/interface/master_interface.py 2018-04-20 08:32:43 +0000 |
2924 | @@ -216,13 +216,15 @@ |
2925 | coupling_type=orders) |
2926 | self.change_principal_cmd('MadGraph') |
2927 | return self.cmd.create_loop_induced(self, line, *args, **opts) |
2928 | + else: |
2929 | + self.change_principal_cmd('MadGraph') |
2930 | try: |
2931 | return self.cmd.do_add(self, line, *args, **opts) |
2932 | except fks_base.NoBornException: |
2933 | - logger.info("------------------------------------------------------------------------", '$MG:color:BLACK') |
2934 | - logger.info(" No Born diagrams found. Now switching to the loop-induced mode. ", '$MG:color:BLACK') |
2935 | - logger.info(" Please cite ref. 'arXiv:1507.00020' when using results from this mode. ", '$MG:color:BLACK') |
2936 | - logger.info("------------------------------------------------------------------------", '$MG:color:BLACK') |
2937 | + logger.info("------------------------------------------------------------------------", '$MG:BOLD') |
2938 | + logger.info(" No Born diagrams found. Now switching to the loop-induced mode. ", '$MG:BOLD') |
2939 | + logger.info(" Please cite ref. 'arXiv:1507.00020' when using results from this mode. ", '$MG:BOLD') |
2940 | + logger.info("------------------------------------------------------------------------", '$MG:BOLD') |
2941 | self.change_principal_cmd('MadGraph') |
2942 | return self.cmd.create_loop_induced(self, line, *args, **opts) |
2943 | |
2944 | @@ -607,6 +609,7 @@ |
2945 | %','.join(interface_quick_name.keys())) |
2946 | |
2947 | def change_principal_cmd(self, name): |
2948 | + |
2949 | old_cmd=self.current_interface |
2950 | if name in self.interface_names.keys(): |
2951 | self.prompt= self.interface_names[name][0]+'>' |
2952 | |
2953 | === modified file 'madgraph/interface/reweight_interface.py' |
2954 | --- madgraph/interface/reweight_interface.py 2018-03-28 08:21:22 +0000 |
2955 | +++ madgraph/interface/reweight_interface.py 2018-04-20 08:32:43 +0000 |
2956 | @@ -915,6 +915,33 @@ |
2957 | def do_compute_widths(self, line): |
2958 | return self.mother.do_compute_widths(line) |
2959 | |
2960 | + |
2961 | + dynamical_scale_warning=True |
2962 | + def change_kinematics(self, event): |
2963 | + |
2964 | + |
2965 | + if isinstance(self.run_card, banner.RunCardLO): |
2966 | + jac = event.change_ext_mass(self.new_param_card) |
2967 | + new_event = event |
2968 | + else: |
2969 | + jac =1 |
2970 | + new_event = event |
2971 | + |
2972 | + if jac != 1: |
2973 | + if self.output_type == 'default': |
2974 | + logger.critical('mass reweighting requires dedicated lhe output!. Please include "change output 2.0" in your reweight_card') |
2975 | + raise Exception |
2976 | + mode = self.run_card['dynamical_scale_choice'] |
2977 | + if mode == -1: |
2978 | + if self.dynamical_scale_warning: |
2979 | + logger.warning('dynamical_scale is set to -1. New sample will be with HT/2 dynamical scale for renormalisation scale') |
2980 | + mode = 3 |
2981 | + new_event.scale = event.get_scale(mode) |
2982 | + new_event.aqcd = self.lhe_input.get_alphas(new_event.scale, lhapdf_config=self.mother.options['lhapdf']) |
2983 | + |
2984 | + return jac, new_event |
2985 | + |
2986 | + |
2987 | def calculate_weight(self, event): |
2988 | """space defines where to find the calculator (in multicore)""" |
2989 | |
2990 | @@ -927,27 +954,15 @@ |
2991 | orig_wgt = event.wgt |
2992 | # LO reweighting |
2993 | w_orig = self.calculate_matrix_element(event, 0) |
2994 | + |
2995 | # reshuffle event for mass effect # external mass only |
2996 | - if isinstance(self.run_card, banner.RunCardLO): |
2997 | - jac = event.change_ext_mass(self.new_param_card) |
2998 | - else: |
2999 | - jac =1 |
3000 | - |
3001 | - if jac != 1: |
3002 | - if self.output_type == 'default': |
3003 | - logger.critical('mass reweighting requires dedicated lhe output!. Please include "change output 2.0" in your reweight_card') |
3004 | - raise Exception |
3005 | - mode = self.run_card['dynamical_scale_choice'] |
3006 | - if mode == -1: |
3007 | - logger.warning('dynamical_scale is set to -1. New sample will be with HT/2 dynamical scale for renormalisation scale') |
3008 | - mode = 3 |
3009 | - event.scale = event.get_scale(mode) |
3010 | - event.aqcd = self.lhe_input.get_alphas(event.scale, lhapdf_config=self.mother.options['lhapdf']) |
3011 | - |
3012 | + # carefull that new_event can sometimes be = to event |
3013 | + # (i.e. change can be in place) |
3014 | + jac, new_event = self.change_kinematics(event) |
3015 | |
3016 | |
3017 | if event.wgt != 0: # impossible reshuffling |
3018 | - w_new = self.calculate_matrix_element(event, 1) |
3019 | + w_new = self.calculate_matrix_element(new_event, 1) |
3020 | else: |
3021 | w_new = 0 |
3022 | |
3023 | @@ -1697,9 +1712,19 @@ |
3024 | continue |
3025 | pdir = pjoin(path_me, onedir, 'SubProcesses') |
3026 | for tag in [2*metag,2*metag+1]: |
3027 | - with misc.TMP_variable(sys, 'path', [pjoin(path_me)]+sys.path): |
3028 | - mymod = __import__('%s.SubProcesses.allmatrix%spy' % (onedir, tag), globals(), locals(), [],-1) |
3029 | - reload(mymod) |
3030 | + with misc.TMP_variable(sys, 'path', [pjoin(path_me)]+sys.path): |
3031 | + mod_name = '%s.SubProcesses.allmatrix%spy' % (onedir, tag) |
3032 | + #mymod = __import__('%s.SubProcesses.allmatrix%spy' % (onedir, tag), globals(), locals(), [],-1) |
3033 | + if mod_name in sys.modules.keys(): |
3034 | + del sys.modules[mod_name] |
3035 | + tmp_mod_name = mod_name |
3036 | + while '.' in tmp_mod_name: |
3037 | + tmp_mod_name = tmp_mod_name.rsplit('.',1)[0] |
3038 | + del sys.modules[tmp_mod_name] |
3039 | + mymod = __import__(mod_name, globals(), locals(), [],-1) |
3040 | + else: |
3041 | + mymod = __import__(mod_name, globals(), locals(), [],-1) |
3042 | + |
3043 | S = mymod.SubProcesses |
3044 | mymod = getattr(S, 'allmatrix%spy' % tag) |
3045 | |
3046 | @@ -1713,7 +1738,7 @@ |
3047 | data = self.id_to_path |
3048 | if '_second' in onedir: |
3049 | data = self.id_to_path_second |
3050 | - |
3051 | + |
3052 | # get all the information |
3053 | all_pdgs = mymod.get_pdg_order() |
3054 | all_pdgs = [[pdg for pdg in pdgs if pdg!=0] for pdgs in mymod.get_pdg_order()] |
3055 | @@ -1746,7 +1771,6 @@ |
3056 | else: |
3057 | incoming = pdg[0:2] |
3058 | outgoing = pdg[2:] |
3059 | - misc.sprint(incoming, outgoing) |
3060 | order = (list(incoming), list(outgoing)) |
3061 | incoming.sort() |
3062 | outgoing.sort() |
3063 | @@ -1774,7 +1798,7 @@ |
3064 | misc.sprint(data[tag][:-1]) |
3065 | misc.sprint(order, pdir,) |
3066 | raise Exception |
3067 | - |
3068 | + |
3069 | data[tag] = order, pdir, hel |
3070 | |
3071 | |
3072 | |
3073 | === modified file 'madgraph/interface/tutorial_text.py' |
3074 | --- madgraph/interface/tutorial_text.py 2015-10-01 16:00:08 +0000 |
3075 | +++ madgraph/interface/tutorial_text.py 2018-04-20 08:32:43 +0000 |
3076 | @@ -1,6 +1,6 @@ |
3077 | ################################################################################ |
3078 | # |
3079 | -# Copyright (c) 2009 The MadGraph5_aMC@NLO Development team and Contributors |
3080 | +# Copyright (c) 2018 The MadGraph5_aMC@NLO Development team and Contributors |
3081 | # |
3082 | # This file is a part of the MadGraph5_aMC@NLO project, an application which |
3083 | # automatically generates Feynman diagrams and matrix elements for arbitrary |
3084 | @@ -77,11 +77,10 @@ |
3085 | """ |
3086 | output = """ |
3087 | If you are following the tutorial, a directory MY_FIRST_MG5_RUN has |
3088 | -been created which can be used in order to run MadEvent exactly as if |
3089 | -it was coming from MG4. |
3090 | +been created which can be used in order to generate LO events/compute cross-section. |
3091 | |
3092 | -Additionally to the MG4 command (see MY_FIRST_MG5_RUN/README), you can also |
3093 | -generate your events/compute the cross-section from this interface: |
3094 | +From that directory you can run the command './bin/generate_events' |
3095 | +You can also generate your events/compute the cross-section from this interface: |
3096 | Please Enter: |
3097 | MG5_aMC> launch MY_FIRST_MG5_RUN |
3098 | (you can interrupt the computation to continue the tutorial by pressing Ctrl-C) |
3099 | @@ -110,13 +109,17 @@ |
3100 | MadEvent output |
3101 | |
3102 | To import a model, write: |
3103 | -MG5_aMC>import model mssm |
3104 | +MG5_aMC>import model MSSM_SLHA2 |
3105 | """ |
3106 | |
3107 | import_model =""" |
3108 | You have successfully imported a model. If you followed the tutorial |
3109 | this is the MSSM. |
3110 | |
3111 | +MadGraph can auto-download a large class of model (and more can be used). |
3112 | +To see the full list of model, write: |
3113 | +MG5_aMC>display modellist |
3114 | + |
3115 | If you want to know more information about this model you can use the |
3116 | following commands: |
3117 | MG5_aMC>display particles |
3118 | @@ -194,9 +197,9 @@ |
3119 | different command in a single line: |
3120 | MG5_aMC>generate p p > go go; display diagrams |
3121 | |
3122 | -Note that when you run output [madevent_v4], the diagrams are |
3123 | +Note that when you run output [madevent], the diagrams are |
3124 | automatically written to the matrix.ps files in subprocess |
3125 | -directory, just like with MadGraph 4. |
3126 | +directory. |
3127 | """ |
3128 | |
3129 | display_diagrams = """ |
3130 | |
3131 | === modified file 'madgraph/iolibs/export_v4.py' |
3132 | --- madgraph/iolibs/export_v4.py 2018-02-20 18:09:19 +0000 |
3133 | +++ madgraph/iolibs/export_v4.py 2018-04-20 08:32:43 +0000 |
3134 | @@ -3784,7 +3784,17 @@ |
3135 | if not isinstance(self, ProcessExporterFortranMEGroup): |
3136 | self.proc_characteristic['grouped_matrix'] = False |
3137 | self.proc_characteristic['complex_mass_scheme'] = mg5options['complex_mass_scheme'] |
3138 | - |
3139 | + # indicate the PDG of all initial particle |
3140 | + try: |
3141 | + pdgs1 = [p.get_initial_pdg(1) for me in matrix_elements for m in me.get('matrix_elements') for p in m.get('processes') if p.get_initial_pdg(1)] |
3142 | + pdgs2 = [p.get_initial_pdg(2) for me in matrix_elements for m in me.get('matrix_elements') for p in m.get('processes') if p.get_initial_pdg(2)] |
3143 | + except AttributeError: |
3144 | + pdgs1 = [p.get_initial_pdg(1) for m in matrix_elements.get('matrix_elements') for p in m.get('processes') if p.get_initial_pdg(1)] |
3145 | + pdgs2 = [p.get_initial_pdg(2) for m in matrix_elements.get('matrix_elements') for p in m.get('processes') if p.get_initial_pdg(2)] |
3146 | + self.proc_characteristic['pdg_initial1'] = pdgs1 |
3147 | + self.proc_characteristic['pdg_initial2'] = pdgs2 |
3148 | + |
3149 | + |
3150 | modelname = self.opt['model'] |
3151 | if modelname == 'mssm' or modelname.startswith('mssm-'): |
3152 | param_card = pjoin(self.dir_path, 'Cards','param_card.dat') |
3153 | |
3154 | === modified file 'madgraph/iolibs/file_writers.py' |
3155 | --- madgraph/iolibs/file_writers.py 2016-12-01 22:06:31 +0000 |
3156 | +++ madgraph/iolibs/file_writers.py 2018-04-20 08:32:43 +0000 |
3157 | @@ -86,7 +86,7 @@ |
3158 | |
3159 | pass |
3160 | |
3161 | - def writelines(self, lines, context={}): |
3162 | + def writelines(self, lines, context={}, formatting=True): |
3163 | """Extends the regular file.writeline() function to write out |
3164 | nicely formatted code. When defining a context, then the lines |
3165 | will be preprocessed to apply possible conditional statements on the |
3166 | @@ -107,7 +107,10 @@ |
3167 | splitlines = self.preprocess_template(splitlines,context=context) |
3168 | |
3169 | for line in splitlines: |
3170 | - res_lines = self.write_line(line) |
3171 | + if formatting: |
3172 | + res_lines = self.write_line(line) |
3173 | + else: |
3174 | + res_lines = [line+'\n'] |
3175 | for line_to_write in res_lines: |
3176 | self.write(line_to_write) |
3177 | |
3178 | @@ -200,6 +203,7 @@ |
3179 | __indent = 0 |
3180 | __keyword_list = [] |
3181 | __comment_pattern = re.compile(r"^(\s*#|c$|(c\s+([^=]|$))|cf2py|c\-\-|c\*\*)", re.IGNORECASE) |
3182 | + __continuation_line = re.compile(r"(?: )[$&]") |
3183 | |
3184 | def write_line(self, line): |
3185 | """Write a fortran line, with correct indent and line splits""" |
3186 | @@ -220,7 +224,8 @@ |
3187 | # This is a comment |
3188 | res_lines = self.write_comment_line(line.lstrip()[1:]) |
3189 | return res_lines |
3190 | - |
3191 | + elif self.__continuation_line.search(line): |
3192 | + return line+'\n' |
3193 | else: |
3194 | # This is a regular Fortran line |
3195 | |
3196 | |
3197 | === modified file 'madgraph/iolibs/files.py' |
3198 | --- madgraph/iolibs/files.py 2017-09-24 21:24:55 +0000 |
3199 | +++ madgraph/iolibs/files.py 2018-04-20 08:32:43 +0000 |
3200 | @@ -227,6 +227,7 @@ |
3201 | os.symlink(target, os.path.join(starting_dir, name)) |
3202 | except Exception, error: |
3203 | if log: |
3204 | + logger.debug(error) |
3205 | logger.warning('Could not link %s at position: %s' % (file_pos, \ |
3206 | os.path.realpath(starting_dir))) |
3207 | |
3208 | |
3209 | === modified file 'madgraph/loop/loop_exporters.py' |
3210 | --- madgraph/loop/loop_exporters.py 2017-07-31 12:50:36 +0000 |
3211 | +++ madgraph/loop/loop_exporters.py 2018-04-20 08:32:43 +0000 |
3212 | @@ -155,7 +155,7 @@ |
3213 | elif self.dependencies=='external': |
3214 | if not os.path.exists(os.path.join(self.cuttools_dir,'includects','libcts.a')): |
3215 | logger.info('Compiling CutTools. This has to be done only once and'+\ |
3216 | - ' can take a couple of minutes.','$MG:color:BLACK') |
3217 | + ' can take a couple of minutes.','$MG:BOLD') |
3218 | current = misc.detect_current_compiler(os.path.join(\ |
3219 | self.cuttools_dir,'makefile')) |
3220 | new = 'gfortran' if self.fortran_compiler is None else \ |
3221 | @@ -1978,7 +1978,7 @@ |
3222 | |
3223 | |
3224 | logger.info('Compiling IREGI. This has to be done only once and'+\ |
3225 | - ' can take a couple of minutes.','$MG:color:BLACK') |
3226 | + ' can take a couple of minutes.','$MG:BOLD') |
3227 | |
3228 | current = misc.detect_current_compiler(os.path.join(\ |
3229 | libpath,'makefile_ML5_lib')) |
3230 | |
3231 | === modified file 'madgraph/various/banner.py' |
3232 | --- madgraph/various/banner.py 2018-03-09 15:38:21 +0000 |
3233 | +++ madgraph/various/banner.py 2018-04-20 08:32:43 +0000 |
3234 | @@ -1086,7 +1086,7 @@ |
3235 | val = val.lower() |
3236 | allowed = allowed.lower() |
3237 | if value in allowed: |
3238 | - i = allowed.find(value) |
3239 | + i = allowed.index(value) |
3240 | new_values.append(self.allowed_value[i]) |
3241 | continue |
3242 | # no continue -> bad input |
3243 | @@ -1186,10 +1186,10 @@ |
3244 | valid=True |
3245 | elif isinstance(value, str): |
3246 | value = value.lower() |
3247 | - allowed = allowed.lower() |
3248 | + allowed = [v.lower() for v in allowed] |
3249 | if value in allowed: |
3250 | - i = allowed.find(value) |
3251 | - value = self.allowed_value[i] |
3252 | + i = allowed.index(value) |
3253 | + value = self.allowed_value[lower_name][i] |
3254 | valid=True |
3255 | |
3256 | if not valid: |
3257 | @@ -1288,10 +1288,10 @@ |
3258 | if new_value == value: |
3259 | value = new_value |
3260 | else: |
3261 | - raise Exception, "Wrong input type for %s found %s and expecting %s for value %s" %\ |
3262 | + raise InvalidCmd, "Wrong input type for %s found %s and expecting %s for value %s" %\ |
3263 | (name, type(value), targettype, value) |
3264 | else: |
3265 | - raise Exception, "Wrong input type for %s found %s and expecting %s for value %s" %\ |
3266 | + raise InvalidCmd, "Wrong input type for %s found %s and expecting %s for value %s" %\ |
3267 | (name, type(value), targettype, value) |
3268 | else: |
3269 | # We have a string we have to format the attribute from the string |
3270 | @@ -1305,7 +1305,7 @@ |
3271 | elif value.lower() in ['1', '.true.', 't', 'true', 'on']: |
3272 | value = True |
3273 | else: |
3274 | - raise Exception, "%s can not be mapped to True/False for %s" % (repr(value),name) |
3275 | + raise InvalidCmd, "%s can not be mapped to True/False for %s" % (repr(value),name) |
3276 | elif targettype == str: |
3277 | value = value.strip() |
3278 | if value.startswith('\'') and value.endswith('\''): |
3279 | @@ -1324,16 +1324,16 @@ |
3280 | try: |
3281 | value = float(value.replace('d','e')) |
3282 | except ValueError: |
3283 | - raise Exception, "%s can not be mapped to an integer" % value |
3284 | + raise InvalidCmd, "%s can not be mapped to an integer" % value |
3285 | try: |
3286 | new_value = int(value) |
3287 | except ValueError: |
3288 | - raise Exception, "%s can not be mapped to an integer" % value |
3289 | + raise InvalidCmd, "%s can not be mapped to an integer" % value |
3290 | else: |
3291 | if value == new_value: |
3292 | value = new_value |
3293 | else: |
3294 | - raise Exception, "incorect input: %s need an integer for %s" % (value,name) |
3295 | + raise InvalidCmd, "incorect input: %s need an integer for %s" % (value,name) |
3296 | elif targettype == float: |
3297 | value = value.replace('d','e') # pass from Fortran formatting |
3298 | try: |
3299 | @@ -1349,11 +1349,11 @@ |
3300 | v /= float(split[2*i+2]) |
3301 | except: |
3302 | v=0 |
3303 | - raise Exception, "%s can not be mapped to a float" % value |
3304 | + raise InvalidCmd, "%s can not be mapped to a float" % value |
3305 | finally: |
3306 | value = v |
3307 | else: |
3308 | - raise Exception, "type %s is not handle by the card" % targettype |
3309 | + raise InvalidCmd, "type %s is not handle by the card" % targettype |
3310 | |
3311 | return value |
3312 | |
3313 | @@ -1409,7 +1409,9 @@ |
3314 | self.add_param('bias_module','None') |
3315 | self.add_param('max_n_matched_jets', 0) |
3316 | self.add_param('colored_pdgs', [1,2,3,4,5]) |
3317 | - self.add_param('complex_mass_scheme', False) |
3318 | + self.add_param('complex_mass_scheme', False) |
3319 | + self.add_param('pdg_initial1', [0]) |
3320 | + self.add_param('pdg_initial2', [0]) |
3321 | |
3322 | def read(self, finput): |
3323 | """Read the input file, this can be a path to a file, |
3324 | @@ -1883,7 +1885,9 @@ |
3325 | started_subrun_reading = False |
3326 | while line!='': |
3327 | # Skip comments |
3328 | - if line.strip().startswith('!') or line.strip().startswith('\n'): |
3329 | + if line.strip().startswith('!') or \ |
3330 | + line.strip().startswith('\n') or\ |
3331 | + line.strip() == '': |
3332 | output.write(line) |
3333 | # Proceed to next line |
3334 | last_pos = tmpl.tell() |
3335 | @@ -2033,8 +2037,8 @@ |
3336 | # If 'LHEFInputs:nSubruns' is not user_set, then make sure it is |
3337 | # updated at least larger or equal to the maximum SubRunID |
3338 | if 'LHEFInputs:nSubruns'.lower() not in self.user_set and \ |
3339 | - len(subruns_to_write)>0 and self['LHEFInputs:nSubruns']<\ |
3340 | - max(subruns_to_write.keys()): |
3341 | + len(subruns_to_write)>0 and 'LHEFInputs:nSubruns' in self\ |
3342 | + and self['LHEFInputs:nSubruns']<max(subruns_to_write.keys()): |
3343 | logger.info("Updating PY8 parameter 'LHEFInputs:nSubruns' to "+ |
3344 | "%d so as to cover all defined subruns."%max(subruns_to_write.keys())) |
3345 | self['LHEFInputs:nSubruns'] = max(subruns_to_write.keys()) |
3346 | @@ -2206,6 +2210,8 @@ |
3347 | self.cuts_parameter = [] |
3348 | # parameter added where legacy requires an older value. |
3349 | self.system_default = {} |
3350 | + |
3351 | + self.warned=False |
3352 | |
3353 | |
3354 | |
3355 | @@ -2238,10 +2244,7 @@ |
3356 | if legacy: |
3357 | self.legacy_parameter[name] = value |
3358 | include = False |
3359 | - if include is True: |
3360 | - self.includepath[True].append(name) |
3361 | - elif include: |
3362 | - self.includepath[include].append(name) |
3363 | + self.includepath[include].append(name) |
3364 | if hidden or system: |
3365 | self.hidden_param.append(name) |
3366 | if cut: |
3367 | @@ -2287,11 +2290,13 @@ |
3368 | raise |
3369 | |
3370 | |
3371 | - def write(self, output_file, template=None, python_template=False): |
3372 | + def write(self, output_file, template=None, python_template=False, |
3373 | + write_hidden=False): |
3374 | """Write the run_card in output_file according to template |
3375 | (a path to a valid run_card)""" |
3376 | |
3377 | to_write = set(self.user_set) |
3378 | + written = set() |
3379 | if not template: |
3380 | raise Exception |
3381 | |
3382 | @@ -2324,23 +2329,37 @@ |
3383 | endline = '\n' |
3384 | else: |
3385 | endline = '' |
3386 | - text += ' %s\t= %s %s%s' % (value, name, comment, endline) |
3387 | + text += ' %s\t= %s %s%s' % (value, name, comment, endline) |
3388 | + written.add(name) |
3389 | |
3390 | if name.lower() in to_write: |
3391 | to_write.remove(nline[1].strip().lower()) |
3392 | else: |
3393 | logger.info('Adding missing parameter %s to current %s (with default value)', |
3394 | (name, self.filename)) |
3395 | + written.add(name) |
3396 | text += line |
3397 | |
3398 | - if to_write: |
3399 | + if to_write or write_hidden: |
3400 | text+="""#********************************************************************* |
3401 | -# Additional parameter |
3402 | +# Additional hidden parameters |
3403 | #********************************************************************* |
3404 | -""" |
3405 | - |
3406 | +""" |
3407 | + if write_hidden: |
3408 | + # |
3409 | + # do not write hidden parameter not hidden for this template |
3410 | + # |
3411 | + if python_template: |
3412 | + written = written.union(set(re.findall('\%\((\w*)\)s', file(template,'r').read(), re.M))) |
3413 | + to_write = to_write.union(set(self.hidden_param)) |
3414 | + to_write = to_write.difference(written) |
3415 | + |
3416 | for key in to_write: |
3417 | - text += ' %s\t= %s # %s\n' % (self[key], key, 'hidden parameter') |
3418 | + if key in self.system_only: |
3419 | + continue |
3420 | + |
3421 | + comment = self.comments.get(key,'hidden_parameter').replace('\n','\n#') |
3422 | + text += ' %s\t= %s # %s\n' % (self[key], key, comment) |
3423 | |
3424 | if isinstance(output_file, str): |
3425 | fsock = open(output_file,'w') |
3426 | @@ -2367,6 +2386,7 @@ |
3427 | log_level = 20 |
3428 | if not default: |
3429 | default = dict.__getitem__(self, name.lower()) |
3430 | + |
3431 | logger.log(log_level, '%s missed argument %s. Takes default: %s' |
3432 | % (self.filename, name, default)) |
3433 | self[name] = default |
3434 | @@ -2426,11 +2446,18 @@ |
3435 | return "'%s'" % value |
3436 | |
3437 | |
3438 | - def check_validity(self): |
3439 | + |
3440 | + def check_validity(self, log_level=30): |
3441 | """check that parameter missing in the card are set to the expected value""" |
3442 | |
3443 | for name, value in self.system_default.items(): |
3444 | self.set(name, value, changeifuserset=False) |
3445 | + |
3446 | + |
3447 | + for name in self.includepath[False]: |
3448 | + to_bypass = self.hidden_param + self.legacy_parameter.keys() |
3449 | + if name not in to_bypass: |
3450 | + self.get_default(name, log_level=log_level) |
3451 | |
3452 | for name in self.legacy_parameter: |
3453 | if self[name] != self.legacy_parameter[name]: |
3454 | @@ -2457,6 +2484,8 @@ |
3455 | for incname in self.includepath: |
3456 | if incname is True: |
3457 | pathinc = self.default_include_file |
3458 | + elif incname is False: |
3459 | + continue |
3460 | else: |
3461 | pathinc = incname |
3462 | |
3463 | @@ -2498,28 +2527,26 @@ |
3464 | fsock.writelines(line) |
3465 | fsock.close() |
3466 | |
3467 | + @staticmethod |
3468 | + def get_idbmup(lpp): |
3469 | + """return the particle colliding pdg code""" |
3470 | + if lpp in (1,2, -1,-2): |
3471 | + return math.copysign(2212, lpp) |
3472 | + elif lpp in (3,-3): |
3473 | + return math.copysign(11, lpp) |
3474 | + elif lpp == 0: |
3475 | + #logger.critical("Fail to write correct idbmup in the lhe file. Please correct those by hand") |
3476 | + return 0 |
3477 | + else: |
3478 | + return lpp |
3479 | |
3480 | def get_banner_init_information(self): |
3481 | """return a dictionary with the information needed to write |
3482 | the first line of the <init> block of the lhe file.""" |
3483 | |
3484 | output = {} |
3485 | - |
3486 | - def get_idbmup(lpp): |
3487 | - """return the particle colliding pdg code""" |
3488 | - if lpp in (1,2, -1,-2): |
3489 | - return math.copysign(2212, lpp) |
3490 | - elif lpp in (3,-3): |
3491 | - return math.copysign(11, lpp) |
3492 | - elif lpp == 0: |
3493 | - #logger.critical("Fail to write correct idbmup in the lhe file. Please correct those by hand") |
3494 | - return 0 |
3495 | - else: |
3496 | - return lpp |
3497 | - |
3498 | - |
3499 | - output["idbmup1"] = get_idbmup(self['lpp1']) |
3500 | - output["idbmup2"] = get_idbmup(self['lpp2']) |
3501 | + output["idbmup1"] = self.get_idbmup(self['lpp1']) |
3502 | + output["idbmup2"] = self.get_idbmup(self['lpp2']) |
3503 | output["ebmup1"] = self["ebeam1"] |
3504 | output["ebmup2"] = self["ebeam2"] |
3505 | output["pdfgup1"] = 0 |
3506 | @@ -2570,7 +2597,7 @@ |
3507 | |
3508 | self.add_param("run_tag", "tag_1", include=False) |
3509 | self.add_param("gridpack", False) |
3510 | - self.add_param("time_of_flight", -1.0, include=False, hidden=True) |
3511 | + self.add_param("time_of_flight", -1.0, include=False) |
3512 | self.add_param("nevents", 10000) |
3513 | self.add_param("iseed", 0) |
3514 | self.add_param("lpp1", 1, fortran_name="lpp(1)", allowed=[-1,1,0,2,3,9, -2,-3], |
3515 | @@ -2738,7 +2765,7 @@ |
3516 | self.add_param("sys_alpsfact", "None", include=False) |
3517 | self.add_param("sys_matchscale", "auto", include=False) |
3518 | self.add_param("sys_pdf", "NNPDF23_lo_as_0130_qed", include=False) |
3519 | - self.add_param("sys_scalecorrelation", -1, include=False) |
3520 | + self.add_param("sys_scalecorrelation", -1, include=False, hidden=True) |
3521 | |
3522 | #parameter not in the run_card by default |
3523 | self.add_param('gridrun', False, hidden=True) |
3524 | @@ -2763,17 +2790,17 @@ |
3525 | self.add_param('eta_min_pdg',{'__type__':0.}, include=False) |
3526 | self.add_param('eta_max_pdg',{'__type__':0.}, include=False) |
3527 | self.add_param('mxx_min_pdg',{'__type__':0.}, include=False) |
3528 | - self.add_param('mxx_only_part_antipart', {'default':False}, include=False, hidden=True) |
3529 | + self.add_param('mxx_only_part_antipart', {'default':False}, include=False) |
3530 | |
3531 | - self.add_param('pdg_cut',[0], hidden=True, system=True) # store which PDG are tracked |
3532 | - self.add_param('ptmin4pdg',[0.], hidden=True, system=True) # store pt min |
3533 | - self.add_param('ptmax4pdg',[-1.], hidden=True, system=True) |
3534 | - self.add_param('Emin4pdg',[0.], hidden=True, system=True) # store pt min |
3535 | - self.add_param('Emax4pdg',[-1.], hidden=True, system=True) |
3536 | - self.add_param('etamin4pdg',[0.], hidden=True, system=True) # store pt min |
3537 | - self.add_param('etamax4pdg',[-1.], hidden=True, system=True) |
3538 | - self.add_param('mxxmin4pdg',[-1.], hidden=True, system=True) |
3539 | - self.add_param('mxxpart_antipart', [False], hidden=True, system=True) |
3540 | + self.add_param('pdg_cut',[0], system=True) # store which PDG are tracked |
3541 | + self.add_param('ptmin4pdg',[0.], system=True) # store pt min |
3542 | + self.add_param('ptmax4pdg',[-1.], system=True) |
3543 | + self.add_param('Emin4pdg',[0.], system=True) # store pt min |
3544 | + self.add_param('Emax4pdg',[-1.], system=True) |
3545 | + self.add_param('etamin4pdg',[0.], system=True) # store pt min |
3546 | + self.add_param('etamax4pdg',[-1.], system=True) |
3547 | + self.add_param('mxxmin4pdg',[-1.], system=True) |
3548 | + self.add_param('mxxpart_antipart', [False], system=True) |
3549 | # Not implemetented right now (double particle cut) |
3550 | #self.add_param('pdg_cut_2',[0], hidden=True, system=True) |
3551 | # self.add_param('M_min_pdg',[0.], hidden=True, system=True) # store pt min |
3552 | @@ -3031,7 +3058,8 @@ |
3553 | self['use_syst'] = False |
3554 | self['systematics_program'] = 'none' |
3555 | |
3556 | - def write(self, output_file, template=None, python_template=False): |
3557 | + def write(self, output_file, template=None, python_template=False, |
3558 | + **opt): |
3559 | """Write the run_card in output_file according to template |
3560 | (a path to a valid run_card)""" |
3561 | |
3562 | @@ -3045,7 +3073,7 @@ |
3563 | python_template = False |
3564 | |
3565 | super(RunCardLO, self).write(output_file, template=template, |
3566 | - python_template=python_template) |
3567 | + python_template=python_template, **opt) |
3568 | |
3569 | |
3570 | class InvalidMadAnalysis5Card(InvalidCmd): |
3571 | @@ -3598,28 +3626,28 @@ |
3572 | for scale in scales: |
3573 | if self[scale]: |
3574 | logger.warning('''For consistency in the FxFx merging, \'%s\' has been set to false''' |
3575 | - % scale,'$MG:color:BLACK') |
3576 | + % scale,'$MG:BOLD') |
3577 | self[scale]= False |
3578 | #and left to default dynamical scale |
3579 | if len(self["dynamical_scale_choice"]) > 1 or self["dynamical_scale_choice"][0] != -1: |
3580 | self["dynamical_scale_choice"] = [-1] |
3581 | self["reweight_scale"]=[self["reweight_scale"][0]] |
3582 | logger.warning('''For consistency in the FxFx merging, dynamical_scale_choice has been set to -1 (default)''' |
3583 | - ,'$MG:color:BLACK') |
3584 | + ,'$MG:BOLD') |
3585 | |
3586 | # 2. Use kT algorithm for jets with pseudo-code size R=1.0 |
3587 | jetparams=['jetradius','jetalgo'] |
3588 | for jetparam in jetparams: |
3589 | if float(self[jetparam]) != 1.0: |
3590 | logger.info('''For consistency in the FxFx merging, \'%s\' has been set to 1.0''' |
3591 | - % jetparam ,'$MG:color:BLACK') |
3592 | + % jetparam ,'$MG:BOLD') |
3593 | self[jetparam] = 1.0 |
3594 | elif self['ickkw'] == -1 and (self["dynamical_scale_choice"][0] != -1 or |
3595 | len(self["dynamical_scale_choice"]) > 1): |
3596 | self["dynamical_scale_choice"] = [-1] |
3597 | self["reweight_scale"]=[self["reweight_scale"][0]] |
3598 | logger.warning('''For consistency with the jet veto, the scale which will be used is ptj. dynamical_scale_choice will be set at -1.''' |
3599 | - ,'$MG:color:BLACK') |
3600 | + ,'$MG:BOLD') |
3601 | |
3602 | # For interface to APPLGRID, need to use LHAPDF and reweighting to get scale uncertainties |
3603 | if self['iappl'] != 0 and self['pdlabel'].lower() != 'lhapdf': |
3604 | @@ -3773,7 +3801,7 @@ |
3605 | self['mxxmin4pdg'] = [0.] |
3606 | self['mxxpart_antipart'] = [False] |
3607 | |
3608 | - def write(self, output_file, template=None, python_template=False): |
3609 | + def write(self, output_file, template=None, python_template=False, **opt): |
3610 | """Write the run_card in output_file according to template |
3611 | (a path to a valid run_card)""" |
3612 | |
3613 | @@ -3787,7 +3815,7 @@ |
3614 | python_template = False |
3615 | |
3616 | super(RunCardNLO, self).write(output_file, template=template, |
3617 | - python_template=python_template) |
3618 | + python_template=python_template, **opt) |
3619 | |
3620 | |
3621 | def create_default_for_process(self, proc_characteristic, history, proc_def): |
3622 | |
3623 | === modified file 'madgraph/various/misc.py' |
3624 | --- madgraph/various/misc.py 2018-03-27 17:23:29 +0000 |
3625 | +++ madgraph/various/misc.py 2018-04-20 08:32:43 +0000 |
3626 | @@ -575,6 +575,37 @@ |
3627 | # reset it to change the next file |
3628 | mod = False |
3629 | |
3630 | +def pid_exists(pid): |
3631 | + """Check whether pid exists in the current process table. |
3632 | + UNIX only. |
3633 | + https://stackoverflow.com/questions/568271/how-to-check-if-there-exists-a-process-with-a-given-pid-in-python |
3634 | + """ |
3635 | + import errno |
3636 | + |
3637 | + if pid < 0: |
3638 | + return False |
3639 | + if pid == 0: |
3640 | + # According to "man 2 kill" PID 0 refers to every process |
3641 | + # in the process group of the calling process. |
3642 | + # On certain systems 0 is a valid PID but we have no way |
3643 | + # to know that in a portable fashion. |
3644 | + raise ValueError('invalid PID 0') |
3645 | + try: |
3646 | + os.kill(pid, 0) |
3647 | + except OSError as err: |
3648 | + if err.errno == errno.ESRCH: |
3649 | + # ESRCH == No such process |
3650 | + return False |
3651 | + elif err.errno == errno.EPERM: |
3652 | + # EPERM clearly means there's a process to deny access to |
3653 | + return True |
3654 | + else: |
3655 | + # According to "man 2 kill" possible error values are |
3656 | + # (EINVAL, EPERM, ESRCH) |
3657 | + raise |
3658 | + else: |
3659 | + return True |
3660 | + |
3661 | #=============================================================================== |
3662 | # mute_logger (designed to work as with statement) |
3663 | #=============================================================================== |
3664 | @@ -874,6 +905,19 @@ |
3665 | """nice way to call an external program with nice error treatment""" |
3666 | return subprocess.Popen(arg, *args, **opt) |
3667 | |
3668 | +@check_system_error() |
3669 | +def call_stdout(arg, *args, **opt): |
3670 | + """nice way to call an external program with nice error treatment""" |
3671 | + try: |
3672 | + out = subprocess.Popen(arg, *args, stdout=subprocess.PIPE, **opt) |
3673 | + except OSError: |
3674 | + arg[0] = './%s' % arg[0] |
3675 | + out = subprocess.call(arg, *args, stdout=subprocess.PIPE, **opt) |
3676 | + |
3677 | + str_out = out.stdout.read().strip() |
3678 | + return str_out |
3679 | + |
3680 | + |
3681 | @multiple_try() |
3682 | def mult_try_open(filepath, *args, **opt): |
3683 | """try to open a file with multiple try to ensure that filesystem is sync""" |
3684 | @@ -1397,6 +1441,8 @@ |
3685 | |
3686 | if wait: |
3687 | raw_input('press_enter to continue') |
3688 | + elif opt.has_key('sleep'): |
3689 | + time.sleep(int(opt['sleep'])) |
3690 | |
3691 | return |
3692 | |
3693 | @@ -1901,9 +1947,9 @@ |
3694 | else: |
3695 | if keyname in getattr(plugin, target_type): |
3696 | if not info: |
3697 | - logger.info('Using from plugin %s mode %s' % (plug, keyname), '$MG:color:BLACK') |
3698 | + logger.info('Using from plugin %s mode %s' % (plug, keyname), '$MG:BOLD') |
3699 | else: |
3700 | - logger.info(info % {'plug': plug, 'key':keyname}, '$MG:color:BLACK') |
3701 | + logger.info(info % {'plug': plug, 'key':keyname}, '$MG:BOLD') |
3702 | return getattr(plugin, target_type)[keyname] |
3703 | |
3704 | if not keyname: |
3705 | |
3706 | === modified file 'models/__init__.py' |
3707 | --- models/__init__.py 2017-02-16 14:49:57 +0000 |
3708 | +++ models/__init__.py 2018-04-20 08:32:43 +0000 |
3709 | @@ -16,6 +16,7 @@ |
3710 | |
3711 | import os |
3712 | import sys |
3713 | +import madgraph.various.misc as misc |
3714 | |
3715 | def load_model(name, decay=False): |
3716 | |
3717 | @@ -24,6 +25,7 @@ |
3718 | name = name[:-1] |
3719 | |
3720 | |
3721 | + |
3722 | path_split = name.split(os.sep) |
3723 | if len(path_split) == 1: |
3724 | model_pos = 'models.%s' % name |
3725 | @@ -36,8 +38,8 @@ |
3726 | raise Exception, 'name %s already consider as a python library cann\'t be reassigned(%s!=%s)' % \ |
3727 | (path_split[-1], model_path, sys_path) |
3728 | |
3729 | - sys.path.insert(0, os.sep.join(path_split[:-1])) |
3730 | - __import__(path_split[-1]) |
3731 | + with misc.TMP_variable(sys, 'path', [os.sep.join(path_split[:-1])]): |
3732 | + __import__(path_split[-1]) |
3733 | output = sys.modules[path_split[-1]] |
3734 | if decay: |
3735 | dec_name = '%s.decays' % path_split[-1] |
3736 | @@ -47,9 +49,5 @@ |
3737 | pass |
3738 | else: |
3739 | output.all_decays = sys.modules[dec_name].all_decays |
3740 | - |
3741 | - sys.path.pop(0) |
3742 | - |
3743 | - |
3744 | - |
3745 | + |
3746 | return sys.modules[path_split[-1]] |
3747 | |
3748 | === modified file 'models/check_param_card.py' |
3749 | --- models/check_param_card.py 2018-02-20 18:09:19 +0000 |
3750 | +++ models/check_param_card.py 2018-04-20 08:32:43 +0000 |
3751 | @@ -488,7 +488,7 @@ |
3752 | if not misc.equal(model_value, param_value, 4): |
3753 | modify = True |
3754 | if loglevel == 20: |
3755 | - logger.info('For consistency, the mass of particle %s (%s) is changed to %s.' % (lhacode, particle.get('name'), model_value), '$MG:color:BLACK') |
3756 | + logger.info('For consistency, the mass of particle %s (%s) is changed to %s.' % (lhacode, particle.get('name'), model_value), '$MG:BOLD') |
3757 | else: |
3758 | logger.log(loglevel, 'For consistency, the mass of particle %s (%s) is changed to %s.' % (lhacode, particle.get('name'), model_value)) |
3759 | #logger.debug('was %s', param_value) |
3760 | @@ -511,7 +511,7 @@ |
3761 | if not misc.equal(model_value, param_value, 4): |
3762 | modify = True |
3763 | if loglevel == 20: |
3764 | - logger.info('For consistency, the width of particle %s (%s) is changed to %s.' % (lhacode, particle.get('name'), model_value), '$MG:color:BLACK') |
3765 | + logger.info('For consistency, the width of particle %s (%s) is changed to %s.' % (lhacode, particle.get('name'), model_value), '$MG:BOLD') |
3766 | else: |
3767 | logger.log(loglevel,'For consistency, the width of particle %s (%s) is changed to %s.' % (lhacode, particle.get('name'), model_value)) |
3768 | #logger.debug('was %s', param_value) |
3769 | @@ -955,7 +955,7 @@ |
3770 | for positions in itertools.product(*lengths): |
3771 | self.itertag = [] |
3772 | if self.logging: |
3773 | - logger.info("Create the next param_card in the scan definition", '$MG:color:BLACK') |
3774 | + logger.info("Create the next param_card in the scan definition", '$MG:BOLD') |
3775 | for i, pos in enumerate(positions): |
3776 | key = keys[i] |
3777 | for param, values in all_iterators[key]: |
3778 | @@ -988,6 +988,7 @@ |
3779 | for param in self.autowidth: |
3780 | self.cross[-1]['width#%s' % param.lhacode[0]] = paramcard.get_value(param.lhablock, param.lhacode) |
3781 | |
3782 | + |
3783 | def write_summary(self, path, order=None, lastline=False, nbcol=20): |
3784 | """ """ |
3785 | |
3786 | @@ -1016,11 +1017,13 @@ |
3787 | ff.write(formatting % tuple(['run_name'] + self.param_order + keys)) |
3788 | formatting = "%s%s%s\n" %('%%-%is ' % (nbcol), ('%%-%ie ' % (nbcol))* len(self.param_order), |
3789 | ('%%-%ie ' % (nbcol))* len(keys)) |
3790 | - |
3791 | + |
3792 | + |
3793 | if not lastline: |
3794 | to_print = self.cross |
3795 | else: |
3796 | to_print = self.cross[-1:] |
3797 | + |
3798 | for info in to_print: |
3799 | name = info['run_name'] |
3800 | bench = info['bench'] |
3801 | @@ -1268,7 +1271,7 @@ |
3802 | is_modified = True |
3803 | if log ==20: |
3804 | logger.log(log,'For model consistency, update %s with id %s to value %s', |
3805 | - block, id, 0.0, '$MG:color:BLACK') |
3806 | + block, id, 0.0, '$MG:BOLD') |
3807 | elif log: |
3808 | logger.log(log,'For model consistency, update %s with id %s to value %s', |
3809 | block, id, 0.0) |
3810 | @@ -1299,7 +1302,7 @@ |
3811 | is_modified = True |
3812 | if log ==20: |
3813 | logger.log(log,'For model consistency, update %s with id %s to value %s', |
3814 | - (block, id, 1.0), '$MG:color:BLACK') |
3815 | + (block, id, 1.0), '$MG:BOLD') |
3816 | elif log: |
3817 | logger.log(log,'For model consistency, update %s with id %s to value %s', |
3818 | (block, id, 1.0)) |
3819 | @@ -1336,7 +1339,7 @@ |
3820 | is_modified = True |
3821 | if log ==20: |
3822 | logger.log(log,'For model consistency, update %s with id %s to value %s since it should be equal to parameter with id %s', |
3823 | - block, id1, value2, id2, '$MG:color:BLACK') |
3824 | + block, id1, value2, id2, '$MG:BOLD') |
3825 | elif log: |
3826 | logger.log(log,'For model consistency, update %s with id %s to value %s since it should be equal to parameter with id %s', |
3827 | block, id1, value2, id2) |
3828 | @@ -1365,7 +1368,7 @@ |
3829 | is_modified = True |
3830 | if log ==20: |
3831 | logger.log(log,'For model consistency, update %s with id %s to value %s since it should be equal to the opposite of the parameter with id %s', |
3832 | - block, id1, -value2, id2, '$MG:color:BLACK') |
3833 | + block, id1, -value2, id2, '$MG:BOLD') |
3834 | elif log: |
3835 | logger.log(log,'For model consistency, update %s with id %s to value %s since it should be equal to the opposite of the parameter with id %s', |
3836 | block, id1, -value2, id2) |
3837 | |
3838 | === modified file 'models/usermod.py' |
3839 | --- models/usermod.py 2017-11-30 23:09:49 +0000 |
3840 | +++ models/usermod.py 2018-04-20 08:32:43 +0000 |
3841 | @@ -96,6 +96,12 @@ |
3842 | self.CTvertices = list(model.all_CTvertices) |
3843 | else: |
3844 | self.CTvertices = [] |
3845 | + # UFO NLO extension |
3846 | + if hasattr(model, 'all_CTparameters'): |
3847 | + self.CTparameters = list(model.all_CTparameters) |
3848 | + else: |
3849 | + self.CTparameters = [] |
3850 | + |
3851 | |
3852 | #translate for how to write the python file |
3853 | if 'self.expr = expression' in open(pjoin(self.modelpath, 'object_library.py')).read(): |
3854 | @@ -132,6 +138,7 @@ |
3855 | self.write_functions(outputdir) |
3856 | self.write_propagators(outputdir) |
3857 | self.write_ctvertices(outputdir) |
3858 | + self.write_ctparameters(outputdir) |
3859 | |
3860 | self.write_external_files(outputdir) |
3861 | self.write_restrict_card(outputdir) |
3862 | @@ -144,10 +151,7 @@ |
3863 | to_change = {} |
3864 | to_change.update(self.translate) |
3865 | to_change.update(self.old_new) |
3866 | - for particle in self.particles: |
3867 | - if hasattr(particle, 'replace') and particle.replace: |
3868 | - misc.sprint(particle.get('name'), particle.replace.get('name')) |
3869 | - |
3870 | + |
3871 | pattern = re.compile(r'\b(%s)\b' % ('|'.join(to_change))) |
3872 | |
3873 | #need to check that all particle are written correctly <- Fix potential issue |
3874 | @@ -204,19 +208,12 @@ |
3875 | # all added -> write it |
3876 | param_card.write(pjoin(outputdir, p), precision=7) |
3877 | |
3878 | - |
3879 | - |
3880 | - |
3881 | - |
3882 | - |
3883 | - |
3884 | - |
3885 | def format_param(self, param): |
3886 | """convert param to string in order to have it written correctly for the |
3887 | UFO file""" |
3888 | |
3889 | if isinstance(param, basestring): |
3890 | - return "'%s'" % param.replace('\'', '\\\'').replace('\"', '\\\"') |
3891 | + return "'%s'" % param.replace("\\", "\\\\").replace('\'', '\\\'').replace('\"', '\\\"') |
3892 | elif isinstance(param, int) or isinstance(param, float) or \ |
3893 | isinstance(param, complex): |
3894 | return "%s" % param |
3895 | @@ -271,6 +268,9 @@ |
3896 | add_space = len(text) |
3897 | else: |
3898 | add_space = 0 |
3899 | + |
3900 | + if ',' in data: |
3901 | + continue |
3902 | |
3903 | try: |
3904 | expr = getattr(obj, data) |
3905 | @@ -294,6 +294,10 @@ |
3906 | else: |
3907 | other_attr = obj.__dict__.keys() |
3908 | |
3909 | + if str(obj.__class__.__name__) == 'CTParameter' and 'nature' in other_attr: |
3910 | + logger.critical('UFO model is outdated (including some bugs). Please update object_library.py to latest version') |
3911 | + other_attr.remove('nature') |
3912 | + |
3913 | other_attr.sort() |
3914 | if other_attr == ['GhostNumber', 'LeptonNumber', 'Y', 'partial_widths', 'selfconjugate']: |
3915 | other_attr=['GhostNumber', 'LeptonNumber', 'Y','selfconjugate'] |
3916 | @@ -417,6 +421,26 @@ |
3917 | ff.close() |
3918 | return |
3919 | |
3920 | + def write_ctparameters(self, outputdir): |
3921 | + """ """ |
3922 | + if not self.CTparameters: |
3923 | + return |
3924 | + |
3925 | + text = """ |
3926 | +# This file was automatically created by The UFO_usermod |
3927 | + |
3928 | +from object_library import all_CTparameters, CTParameter |
3929 | + |
3930 | +from function_library import complexconjugate, re, im, csc, sec, acsc, asec, cot |
3931 | +""" |
3932 | + |
3933 | + text += self.create_file_content(self.CTparameters) |
3934 | + ff = open(os.path.join(outputdir, 'CT_parameters.py'), 'w') |
3935 | + ff.writelines(text) |
3936 | + ff.close() |
3937 | + return |
3938 | + |
3939 | + |
3940 | def write_orders(self, outputdir): |
3941 | """ """ |
3942 | text = """ |
3943 | @@ -588,6 +612,9 @@ |
3944 | elif p_plugin.mass.name.lower() == 'zero': |
3945 | pass |
3946 | else: |
3947 | + misc.sprint(p_base.mass.value, p_plugin.mass.value, dir(p_base.mass)) |
3948 | + misc.sprint(p_base.mass.nature, p_plugin.mass.nature) |
3949 | + misc.sprint(self.old_new) |
3950 | raise USRMODERROR, 'Some inconsistency in the mass assignment in the model\n' + \ |
3951 | ' Mass: %s and %s\n' %(p_base.mass.name, p_plugin.mass.name) + \ |
3952 | ' conflict name %s\n' % self.old_new + \ |
3953 | @@ -657,6 +684,29 @@ |
3954 | self.old_new[parameter.name] = old_param.name |
3955 | # self.add_internal_parameter(iden_param) |
3956 | |
3957 | + elif parameter.lhablock.lower() in ['mass', 'decay'] and int(parameter.lhacode[0]) in identify_pid: |
3958 | + # this means that the parameter is an internal parameter in the original model... |
3959 | + #find it via the particle name |
3960 | + orig_particle = self.particle_dict[lhacode[0]] |
3961 | + if parameter.lhablock.lower() == 'mass': |
3962 | + old_param = orig_particle.mass |
3963 | + else: |
3964 | + old_param = orig_particle.width |
3965 | + if old_param.name.lower() == 'zero': |
3966 | + #Just add the new parameter to the current list |
3967 | + self.parameters.append(parameter) |
3968 | + self.new_external.append(parameter) |
3969 | + else: |
3970 | + logger.info('The two model defines the parameter for block \'%s\' with id \'%s\' with different parameter name \'%s\', \'%s\'\n'\ |
3971 | + % (parameter.lhablock.lower(), lhacode[0], parameter.name, old_param.name) + \ |
3972 | + ' We will merge those two parameters in a single one') |
3973 | + if parameter.name in self.old_new.values(): |
3974 | + key = [k for k in self.old_new if self.old_new[k] == parameter.name][0] |
3975 | + self.old_new[key] = old_param.name |
3976 | + self.old_new[parameter.name] = old_param.name |
3977 | + else: |
3978 | + self.old_new[parameter.name] = old_param.name |
3979 | + # self.add_internal_parameter(iden_param) |
3980 | else: |
3981 | #Just add the new parameter to the current list |
3982 | self.parameters.append(parameter) |
3983 | |
3984 | === modified file 'tests/acceptance_tests/test_cmd_madevent.py' |
3985 | --- tests/acceptance_tests/test_cmd_madevent.py 2017-05-22 09:11:33 +0000 |
3986 | +++ tests/acceptance_tests/test_cmd_madevent.py 2018-04-20 08:32:43 +0000 |
3987 | @@ -634,6 +634,7 @@ |
3988 | |
3989 | if not self.debuging: |
3990 | shutil.rmtree(self.path) |
3991 | + self.assertFalse(self.debuging) |
3992 | |
3993 | def test_add_time_of_flight(self): |
3994 | """checking time of flight is working fine""" |
made a quick look and found three stuff to change (see below)