Merge lp:~maddevelopers/mg5amcnlo/2.2.0_tutofix into lp:~maddevelopers/mg5amcnlo/2.2.0
- 2.2.0_tutofix
- Merge into 2.2.0
Proposed by
Olivier Mattelaer
Status: | Merged |
---|---|
Merged at revision: | 342 |
Proposed branch: | lp:~maddevelopers/mg5amcnlo/2.2.0_tutofix |
Merge into: | lp:~maddevelopers/mg5amcnlo/2.2.0 |
Diff against target: |
771 lines (+324/-197) 7 files modified
Template/LO/bin/internal/plot_tree.C (+5/-5) UpdateNotes.txt (+6/-0) madgraph/interface/amcatnlo_run_interface.py (+16/-5) madgraph/interface/common_run_interface.py (+203/-4) madgraph/interface/madevent_interface.py (+3/-177) madgraph/various/gen_crossxhtml.py (+6/-0) tests/test_manager.py (+85/-6) |
To merge this branch: | bzr merge lp:~maddevelopers/mg5amcnlo/2.2.0_tutofix |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Valentin Hirschi | Approve | ||
Review via email:
|
Commit message
Description of the change
A couple of small change that I would like to have release for tommorow (sorry for that).
the change are
- allow madwidth for NLO model/generation
- have automatic plot for HW6 (with MA4)
- adding the possibility to script the use of showerkt merging
- fixing a bug for DJR plot with root6
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Template/LO/bin/internal/plot_tree.C' | |||
2 | --- Template/LO/bin/internal/plot_tree.C 2011-06-29 14:15:21 +0000 | |||
3 | +++ Template/LO/bin/internal/plot_tree.C 2014-09-24 19:46:10 +0000 | |||
4 | @@ -32,11 +32,11 @@ | |||
5 | 32 | Float_t Xsecfact; | 32 | Float_t Xsecfact; |
6 | 33 | leaf_Xsec->SetAddress(&Xsecfact); | 33 | leaf_Xsec->SetAddress(&Xsecfact); |
7 | 34 | xsecs->GetEntry(0); | 34 | xsecs->GetEntry(0); |
10 | 35 | 35 | if (events->GetEntries()>0) { | |
11 | 36 | for(int i=0;i<maxjets && events->GetEntries()>0;i++){ | 36 | for(int i=0;i<maxjets;i++){ |
12 | 37 | events->SetLineWidth(2); | 37 | events->SetLineWidth(2); |
15 | 38 | events->SetLineColor(color[i]); | 38 | events->SetLineColor(i+2); |
16 | 39 | events->SetLineStyle(style[i]); | 39 | events->SetLineStyle(i+2); |
17 | 40 | 40 | ||
18 | 41 | if(log) | 41 | if(log) |
19 | 42 | sprintf(tmp1,"log10(%s)>>%s%i%s",quantity,quantity,i,plotdim); | 42 | sprintf(tmp1,"log10(%s)>>%s%i%s",quantity,quantity,i,plotdim); |
20 | @@ -54,7 +54,7 @@ | |||
21 | 54 | return false; | 54 | return false; |
22 | 55 | } | 55 | } |
23 | 56 | } | 56 | } |
25 | 57 | 57 | } | |
26 | 58 | 58 | ||
27 | 59 | TH1F *hsum = (TH1F*)hists[0]->Clone(); | 59 | TH1F *hsum = (TH1F*)hists[0]->Clone(); |
28 | 60 | sprintf(tmp3,"%ssum",quantity); | 60 | sprintf(tmp3,"%ssum",quantity); |
29 | 61 | 61 | ||
30 | === modified file 'UpdateNotes.txt' | |||
31 | --- UpdateNotes.txt 2014-09-17 11:50:05 +0000 | |||
32 | +++ UpdateNotes.txt 2014-09-24 19:46:10 +0000 | |||
33 | @@ -36,10 +36,16 @@ | |||
34 | 36 | set lhc 14 # configure for LHC 14TeV | 36 | set lhc 14 # configure for LHC 14TeV |
35 | 37 | set ilc 1000 # configure for ilc 1TeV | 37 | set ilc 1000 # configure for ilc 1TeV |
36 | 38 | set fixed_scale 100 # set all scale to fixed and at 100GeV | 38 | set fixed_scale 100 # set all scale to fixed and at 100GeV |
37 | 39 | set showerkt T # set showerkt on T in the shower card | ||
38 | 40 | set qcut 20 # set the qctu to 20 in the shower card | ||
39 | 39 | OM: Fix a bug in the card edition mode which was sometimes returning to default value | 41 | OM: Fix a bug in the card edition mode which was sometimes returning to default value |
40 | 40 | which were edited by hand and not via the set command. | 42 | which were edited by hand and not via the set command. |
41 | 41 | Seoyoung Kim (by OM): Implementation of the htcaas (super-)cluster support. | 43 | Seoyoung Kim (by OM): Implementation of the htcaas (super-)cluster support. |
42 | 42 | Juan Rojo (by RF): extended the 3 internal NNPDF sets for scales relevant for a 100TeV collider. | 44 | Juan Rojo (by RF): extended the 3 internal NNPDF sets for scales relevant for a 100TeV collider. |
43 | 45 | OM: Fix a problem with the creation of DJR plot with root 6 | ||
44 | 46 | OM: allow the set the width to Auto in NLO computation (width computated at LO accuracy) | ||
45 | 47 | OM: Adding the possibility to have automatic plot after the parton shower for Herwig6/Pythia6. | ||
46 | 48 | This require MadAnalysis and the pythia-pgs package. | ||
47 | 43 | 49 | ||
48 | 44 | 2.1.2(03/07/14) OM: Fix a bug in ALOHA in presence of customized propagator (Thanks Saurabh) | 50 | 2.1.2(03/07/14) OM: Fix a bug in ALOHA in presence of customized propagator (Thanks Saurabh) |
49 | 45 | OM: Fixing some compilation issue with MadWeight (Thanks A. Pin) | 51 | OM: Fixing some compilation issue with MadWeight (Thanks A. Pin) |
50 | 46 | 52 | ||
51 | === modified file 'madgraph/interface/amcatnlo_run_interface.py' | |||
52 | --- madgraph/interface/amcatnlo_run_interface.py 2014-09-17 07:02:56 +0000 | |||
53 | +++ madgraph/interface/amcatnlo_run_interface.py 2014-09-24 19:46:10 +0000 | |||
54 | @@ -404,8 +404,6 @@ | |||
55 | 404 | """Check the argument for the plot command | 404 | """Check the argument for the plot command |
56 | 405 | plot run_name modes""" | 405 | plot run_name modes""" |
57 | 406 | 406 | ||
58 | 407 | if options['force']: | ||
59 | 408 | self.force = True | ||
60 | 409 | 407 | ||
61 | 410 | madir = self.options['madanalysis_path'] | 408 | madir = self.options['madanalysis_path'] |
62 | 411 | td = self.options['td_path'] | 409 | td = self.options['td_path'] |
63 | @@ -966,7 +964,8 @@ | |||
64 | 966 | self.check_plot(args) | 964 | self.check_plot(args) |
65 | 967 | logger.info('plot for run %s' % self.run_name) | 965 | logger.info('plot for run %s' % self.run_name) |
66 | 968 | 966 | ||
68 | 969 | self.ask_edit_cards([], args, plot=True) | 967 | if not self.force: |
69 | 968 | self.ask_edit_cards([], args, plot=True) | ||
70 | 970 | 969 | ||
71 | 971 | if any([arg in ['parton'] for arg in args]): | 970 | if any([arg in ['parton'] for arg in args]): |
72 | 972 | filename = pjoin(self.me_dir, 'Events', self.run_name, 'events.lhe') | 971 | filename = pjoin(self.me_dir, 'Events', self.run_name, 'events.lhe') |
73 | @@ -1024,14 +1023,17 @@ | |||
74 | 1024 | misc.gunzip(filename, keep=True, stdout=pjoin(self.me_dir, 'Events','pythia_events.hep')) | 1023 | misc.gunzip(filename, keep=True, stdout=pjoin(self.me_dir, 'Events','pythia_events.hep')) |
75 | 1025 | 1024 | ||
76 | 1026 | if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pythia_card.dat')): | 1025 | if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pythia_card.dat')): |
78 | 1027 | files.cp(pjoin(self.me_dir, 'Cards', 'pythia_card_default.dat'), | 1026 | if aMCatNLO and not self.options['mg5_path']: |
79 | 1027 | raise "plotting NLO HEP file needs MG5 utilities" | ||
80 | 1028 | |||
81 | 1029 | files.cp(pjoin(self.options['mg5_path'], 'Template','LO', 'Cards', 'pythia_card_default.dat'), | ||
82 | 1028 | pjoin(self.me_dir, 'Cards', 'pythia_card.dat')) | 1030 | pjoin(self.me_dir, 'Cards', 'pythia_card.dat')) |
83 | 1029 | self.run_hep2lhe() | 1031 | self.run_hep2lhe() |
84 | 1030 | else: | 1032 | else: |
85 | 1031 | filename = filenames[0] | 1033 | filename = filenames[0] |
86 | 1032 | misc.gunzip(filename, keep=True, stdout=pjoin(self.me_dir, 'Events','pythia_events.hep')) | 1034 | misc.gunzip(filename, keep=True, stdout=pjoin(self.me_dir, 'Events','pythia_events.hep')) |
87 | 1033 | 1035 | ||
89 | 1034 | self.create_plot('Pythia') | 1036 | self.create_plot('shower') |
90 | 1035 | lhe_file_name = filename.replace('.hep.gz', '.lhe') | 1037 | lhe_file_name = filename.replace('.hep.gz', '.lhe') |
91 | 1036 | shutil.move(pjoin(self.me_dir, 'Events','pythia_events.lhe'), | 1038 | shutil.move(pjoin(self.me_dir, 'Events','pythia_events.lhe'), |
92 | 1037 | lhe_file_name) | 1039 | lhe_file_name) |
93 | @@ -1125,6 +1127,8 @@ | |||
94 | 1125 | ############################################################################ | 1127 | ############################################################################ |
95 | 1126 | def do_treatcards(self, line, amcatnlo=True): | 1128 | def do_treatcards(self, line, amcatnlo=True): |
96 | 1127 | """Advanced commands: this is for creating the correct run_card.inc from the nlo format""" | 1129 | """Advanced commands: this is for creating the correct run_card.inc from the nlo format""" |
97 | 1130 | #check if no 'Auto' are present in the file | ||
98 | 1131 | self.check_param_card(pjoin(self.me_dir, 'Cards','param_card.dat')) | ||
99 | 1128 | return super(aMCatNLOCmd,self).do_treatcards(line, amcatnlo) | 1132 | return super(aMCatNLOCmd,self).do_treatcards(line, amcatnlo) |
100 | 1129 | 1133 | ||
101 | 1130 | ############################################################################ | 1134 | ############################################################################ |
102 | @@ -2545,6 +2549,13 @@ | |||
103 | 2545 | raise aMCatNLOError('No file has been generated, an error occurred.'+\ | 2549 | raise aMCatNLOError('No file has been generated, an error occurred.'+\ |
104 | 2546 | ' More information in %s' % pjoin(os.getcwd(), 'amcatnlo_run.log')) | 2550 | ' More information in %s' % pjoin(os.getcwd(), 'amcatnlo_run.log')) |
105 | 2547 | 2551 | ||
106 | 2552 | # run the plot creation in a secure way | ||
107 | 2553 | try: | ||
108 | 2554 | self.do_plot('%s -f' % self.run_name) | ||
109 | 2555 | except Exception, error: | ||
110 | 2556 | logger.info("Fail to make the plot. Continue...") | ||
111 | 2557 | pass | ||
112 | 2558 | |||
113 | 2548 | elif out_id == 'TOP': | 2559 | elif out_id == 'TOP': |
114 | 2549 | #copy the topdrawer file(s) back in events | 2560 | #copy the topdrawer file(s) back in events |
115 | 2550 | topfiles = [] | 2561 | topfiles = [] |
116 | 2551 | 2562 | ||
117 | === modified file 'madgraph/interface/common_run_interface.py' | |||
118 | --- madgraph/interface/common_run_interface.py 2014-09-17 07:02:56 +0000 | |||
119 | +++ madgraph/interface/common_run_interface.py 2014-09-24 19:46:10 +0000 | |||
120 | @@ -111,6 +111,14 @@ | |||
121 | 111 | logger.info(" will be performed automaticaly during the event generation.") | 111 | logger.info(" will be performed automaticaly during the event generation.") |
122 | 112 | logger.info(" -f options: answer all question by default.") | 112 | logger.info(" -f options: answer all question by default.") |
123 | 113 | 113 | ||
124 | 114 | def help_compute_widths(self): | ||
125 | 115 | logger.info("syntax: compute_widths Particle [Particles] [--precision=] [--path=Param_card] [--output=PATH]") | ||
126 | 116 | logger.info("-- Compute the widths for the particles specified.") | ||
127 | 117 | logger.info(" By default, this takes the current param_card and overwrites it.") | ||
128 | 118 | logger.info(" Precision allows to define when to include three/four/... body decays (LO).") | ||
129 | 119 | logger.info(" If this number is an integer then all N-body decay will be included.") | ||
130 | 120 | |||
131 | 121 | |||
132 | 114 | def help_pythia(self): | 122 | def help_pythia(self): |
133 | 115 | logger.info("syntax: pythia [RUN] [--run_options]") | 123 | logger.info("syntax: pythia [RUN] [--run_options]") |
134 | 116 | logger.info("-- run pythia on RUN (current one by default)") | 124 | logger.info("-- run pythia on RUN (current one by default)") |
135 | @@ -168,6 +176,111 @@ | |||
136 | 168 | if not args[1].isdigit(): | 176 | if not args[1].isdigit(): |
137 | 169 | raise self.InvalidCmd('timeout values should be a integer') | 177 | raise self.InvalidCmd('timeout values should be a integer') |
138 | 170 | 178 | ||
139 | 179 | def check_compute_widths(self, args): | ||
140 | 180 | """check that the model is loadable and check that the format is of the | ||
141 | 181 | type: PART PATH --output=PATH -f --precision=N | ||
142 | 182 | return the model. | ||
143 | 183 | """ | ||
144 | 184 | |||
145 | 185 | # Check that MG5 directory is present . | ||
146 | 186 | if MADEVENT and not self.options['mg5_path']: | ||
147 | 187 | raise self.InvalidCmd, '''The automatic computations of widths requires that MG5 is installed on the system. | ||
148 | 188 | You can install it and set his path in ./Cards/me5_configuration.txt''' | ||
149 | 189 | elif MADEVENT: | ||
150 | 190 | sys.path.append(self.options['mg5_path']) | ||
151 | 191 | try: | ||
152 | 192 | import models.model_reader as model_reader | ||
153 | 193 | import models.import_ufo as import_ufo | ||
154 | 194 | except ImportError: | ||
155 | 195 | raise self.ConfigurationError, '''Can\'t load MG5. | ||
156 | 196 | The variable mg5_path should not be correctly configure.''' | ||
157 | 197 | |||
158 | 198 | ufo_path = pjoin(self.me_dir,'bin','internal', 'ufomodel') | ||
159 | 199 | # Import model | ||
160 | 200 | if not MADEVENT: | ||
161 | 201 | modelname = self.find_model_name() | ||
162 | 202 | #restrict_file = None | ||
163 | 203 | #if os.path.exists(pjoin(ufo_path, 'restrict_default.dat')): | ||
164 | 204 | # restrict_file = pjoin(ufo_path, 'restrict_default.dat') | ||
165 | 205 | model = import_ufo.import_model(modelname, decay=True, | ||
166 | 206 | restrict=True) | ||
167 | 207 | if self.mother and self.mother.options['complex_mass_scheme']: | ||
168 | 208 | model.change_mass_to_complex_scheme() | ||
169 | 209 | else: | ||
170 | 210 | model = import_ufo.import_model(pjoin(self.me_dir,'bin','internal', 'ufomodel'), | ||
171 | 211 | decay=True) | ||
172 | 212 | #pattern for checking complex mass scheme. | ||
173 | 213 | has_cms = re.compile(r'''set\s+complex_mass_scheme\s*(True|T|1|true|$|;)''') | ||
174 | 214 | if has_cms.search(open(pjoin(self.me_dir,'Cards','proc_card_mg5.dat')\ | ||
175 | 215 | ).read()): | ||
176 | 216 | model.change_mass_to_complex_scheme() | ||
177 | 217 | |||
178 | 218 | |||
179 | 219 | # if not hasattr(model.get('particles')[0], 'partial_widths'): | ||
180 | 220 | # raise self.InvalidCmd, 'The UFO model does not include partial widths information. Impossible to compute widths automatically' | ||
181 | 221 | |||
182 | 222 | # check if the name are passed to default MG5 | ||
183 | 223 | if '-modelname' in open(pjoin(self.me_dir,'Cards','proc_card_mg5.dat')).read(): | ||
184 | 224 | model.pass_particles_name_in_mg_default() | ||
185 | 225 | model = model_reader.ModelReader(model) | ||
186 | 226 | particles_name = dict([(p.get('name'), p.get('pdg_code')) | ||
187 | 227 | for p in model.get('particles')]) | ||
188 | 228 | particles_name.update(dict([(p.get('antiname'), p.get('pdg_code')) | ||
189 | 229 | for p in model.get('particles')])) | ||
190 | 230 | |||
191 | 231 | output = {'model': model, 'force': False, 'output': None, | ||
192 | 232 | 'path':None, 'particles': set(), 'body_decay':4.0025, | ||
193 | 233 | 'min_br':None, 'precision_channel':0.01} | ||
194 | 234 | for arg in args: | ||
195 | 235 | if arg.startswith('--output='): | ||
196 | 236 | output_path = arg.split('=',1)[1] | ||
197 | 237 | if not os.path.exists(output_path): | ||
198 | 238 | raise self.InvalidCmd, 'Invalid Path for the output. Please retry.' | ||
199 | 239 | if not os.path.isfile(output_path): | ||
200 | 240 | output_path = pjoin(output_path, 'param_card.dat') | ||
201 | 241 | output['output'] = output_path | ||
202 | 242 | elif arg == '-f': | ||
203 | 243 | output['force'] = True | ||
204 | 244 | elif os.path.isfile(arg): | ||
205 | 245 | ftype = self.detect_card_type(arg) | ||
206 | 246 | if ftype != 'param_card.dat': | ||
207 | 247 | raise self.InvalidCmd , '%s is not a valid param_card.' % arg | ||
208 | 248 | output['path'] = arg | ||
209 | 249 | elif arg.startswith('--path='): | ||
210 | 250 | arg = arg.split('=',1)[1] | ||
211 | 251 | ftype = self.detect_card_type(arg) | ||
212 | 252 | if ftype != 'param_card.dat': | ||
213 | 253 | raise self.InvalidCmd , '%s is not a valid param_card.' % arg | ||
214 | 254 | output['path'] = arg | ||
215 | 255 | elif arg.startswith('--'): | ||
216 | 256 | name, value = arg.split('=',1) | ||
217 | 257 | try: | ||
218 | 258 | value = float(value) | ||
219 | 259 | except Exception: | ||
220 | 260 | raise self.InvalidCmd, '--%s requires integer or a float' % name | ||
221 | 261 | output[name[2:]] = float(value) | ||
222 | 262 | elif arg in particles_name: | ||
223 | 263 | # should be a particles | ||
224 | 264 | output['particles'].add(particles_name[arg]) | ||
225 | 265 | elif arg.isdigit() and int(arg) in particles_name.values(): | ||
226 | 266 | output['particles'].add(eval(arg)) | ||
227 | 267 | elif arg == 'all': | ||
228 | 268 | output['particles'] = set(['all']) | ||
229 | 269 | else: | ||
230 | 270 | self.help_compute_widths() | ||
231 | 271 | raise self.InvalidCmd, '%s is not a valid argument for compute_widths' % arg | ||
232 | 272 | if self.force: | ||
233 | 273 | output['force'] = True | ||
234 | 274 | |||
235 | 275 | if not output['particles']: | ||
236 | 276 | raise self.InvalidCmd, '''This routines requires at least one particle in order to compute | ||
237 | 277 | the related width''' | ||
238 | 278 | |||
239 | 279 | if output['output'] is None: | ||
240 | 280 | output['output'] = output['path'] | ||
241 | 281 | |||
242 | 282 | return output | ||
243 | 283 | |||
244 | 171 | def check_open(self, args): | 284 | def check_open(self, args): |
245 | 172 | """ check the validity of the line """ | 285 | """ check the validity of the line """ |
246 | 173 | 286 | ||
247 | @@ -739,6 +852,12 @@ | |||
248 | 739 | event_path = pjoin(self.me_dir, 'Events', self.run_name,'%s_delphes_events.lhco' % tag) | 852 | event_path = pjoin(self.me_dir, 'Events', self.run_name,'%s_delphes_events.lhco' % tag) |
249 | 740 | output = pjoin(self.me_dir, 'HTML',self.run_name, | 853 | output = pjoin(self.me_dir, 'HTML',self.run_name, |
250 | 741 | 'plots_delphes_%s.html' % tag) | 854 | 'plots_delphes_%s.html' % tag) |
251 | 855 | elif mode == "shower": | ||
252 | 856 | event_path = pjoin(self.me_dir, 'Events','pythia_events.lhe') | ||
253 | 857 | output = pjoin(self.me_dir, 'HTML',self.run_name, | ||
254 | 858 | 'plots_shower_%s.html' % tag) | ||
255 | 859 | if not self.options['pythia-pgs_path']: | ||
256 | 860 | return | ||
257 | 742 | else: | 861 | else: |
258 | 743 | raise self.InvalidCmd, 'Invalid mode %s' % mode | 862 | raise self.InvalidCmd, 'Invalid mode %s' % mode |
259 | 744 | elif mode == 'reweight' and not output: | 863 | elif mode == 'reweight' and not output: |
260 | @@ -815,7 +934,7 @@ | |||
261 | 815 | 934 | ||
262 | 816 | # Creating LHE file | 935 | # Creating LHE file |
263 | 817 | if misc.is_executable(pjoin(pydir, 'hep2lhe')): | 936 | if misc.is_executable(pjoin(pydir, 'hep2lhe')): |
265 | 818 | self.update_status('Creating Pythia LHE File', level='pythia') | 937 | self.update_status('Creating shower LHE File (for plot)', level='pythia') |
266 | 819 | # Write the banner to the LHE file | 938 | # Write the banner to the LHE file |
267 | 820 | out = open(pjoin(self.me_dir,'Events','pythia_events.lhe'), 'w') | 939 | out = open(pjoin(self.me_dir,'Events','pythia_events.lhe'), 'w') |
268 | 821 | #out.writelines('<LesHouchesEvents version=\"1.0\">\n') | 940 | #out.writelines('<LesHouchesEvents version=\"1.0\">\n') |
269 | @@ -829,9 +948,10 @@ | |||
270 | 829 | 948 | ||
271 | 830 | self.cluster.launch_and_wait(self.dirbin+'/run_hep2lhe', | 949 | self.cluster.launch_and_wait(self.dirbin+'/run_hep2lhe', |
272 | 831 | argument= [pydir], | 950 | argument= [pydir], |
274 | 832 | cwd=pjoin(self.me_dir,'Events')) | 951 | cwd=pjoin(self.me_dir,'Events'), |
275 | 952 | stdout=open(os.devnull,'w')) | ||
276 | 833 | 953 | ||
278 | 834 | logger.info('Warning! Never use this pythia lhe file for detector studies!') | 954 | logger.info('Warning! Never use this lhe file for detector studies!') |
279 | 835 | # Creating ROOT file | 955 | # Creating ROOT file |
280 | 836 | if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHEFConverter')): | 956 | if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHEFConverter')): |
281 | 837 | self.update_status('Creating Pythia LHE Root File', level='pythia') | 957 | self.update_status('Creating Pythia LHE Root File', level='pythia') |
282 | @@ -960,6 +1080,33 @@ | |||
283 | 960 | 1080 | ||
284 | 961 | self.update_status('finish', level='pgs', makehtml=False) | 1081 | self.update_status('finish', level='pgs', makehtml=False) |
285 | 962 | 1082 | ||
286 | 1083 | ############################################################################ | ||
287 | 1084 | def do_compute_widths(self, line): | ||
288 | 1085 | """Require MG5 directory: Compute automatically the widths of a set | ||
289 | 1086 | of particles""" | ||
290 | 1087 | |||
291 | 1088 | args = self.split_arg(line) | ||
292 | 1089 | opts = self.check_compute_widths(args) | ||
293 | 1090 | |||
294 | 1091 | |||
295 | 1092 | from madgraph.interface.master_interface import MasterCmd | ||
296 | 1093 | cmd = MasterCmd() | ||
297 | 1094 | self.define_child_cmd_interface(cmd, interface=False) | ||
298 | 1095 | cmd.exec_cmd('set automatic_html_opening False --no_save') | ||
299 | 1096 | if not opts['path']: | ||
300 | 1097 | opts['path'] = pjoin(self.me_dir, 'Cards', 'param_card.dat') | ||
301 | 1098 | if not opts['force'] : | ||
302 | 1099 | self.ask_edit_cards(['param_card'],[], plot=False) | ||
303 | 1100 | |||
304 | 1101 | |||
305 | 1102 | line = 'compute_widths %s %s' % \ | ||
306 | 1103 | (' '.join([str(i) for i in opts['particles']]), | ||
307 | 1104 | ' '.join('--%s=%s' % (key,value) for (key,value) in opts.items() | ||
308 | 1105 | if key not in ['model', 'force', 'particles'] and value)) | ||
309 | 1106 | |||
310 | 1107 | cmd.exec_cmd(line, model=opts['model']) | ||
311 | 1108 | self.child = None | ||
312 | 1109 | del cmd | ||
313 | 963 | 1110 | ||
314 | 964 | ############################################################################ | 1111 | ############################################################################ |
315 | 965 | def do_print_results(self, line): | 1112 | def do_print_results(self, line): |
316 | @@ -1313,6 +1460,24 @@ | |||
317 | 1313 | cluster_name = opt['cluster_type'] | 1460 | cluster_name = opt['cluster_type'] |
318 | 1314 | self.cluster = cluster.from_name[cluster_name](**opt) | 1461 | self.cluster = cluster.from_name[cluster_name](**opt) |
319 | 1315 | 1462 | ||
320 | 1463 | def check_param_card(self, path, run=True): | ||
321 | 1464 | """Check that all the width are define in the param_card. | ||
322 | 1465 | If some width are set on 'Auto', call the computation tools.""" | ||
323 | 1466 | |||
324 | 1467 | pattern = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto''',re.I) | ||
325 | 1468 | text = open(path).read() | ||
326 | 1469 | pdg = pattern.findall(text) | ||
327 | 1470 | if pdg: | ||
328 | 1471 | if run: | ||
329 | 1472 | logger.info('Computing the width set on auto in the param_card.dat') | ||
330 | 1473 | self.do_compute_widths('%s %s' % (' '.join(pdg), path)) | ||
331 | 1474 | else: | ||
332 | 1475 | logger.info('''Some width are on Auto in the card. | ||
333 | 1476 | Those will be computed as soon as you have finish the edition of the cards. | ||
334 | 1477 | If you want to force the computation right now and being able to re-edit | ||
335 | 1478 | the cards afterwards, you can type \"compute_wdiths\".''') | ||
336 | 1479 | |||
337 | 1480 | |||
338 | 1316 | def add_error_log_in_html(self, errortype=None): | 1481 | def add_error_log_in_html(self, errortype=None): |
339 | 1317 | """If a ME run is currently running add a link in the html output""" | 1482 | """If a ME run is currently running add a link in the html output""" |
340 | 1318 | 1483 | ||
341 | @@ -1696,6 +1861,27 @@ | |||
342 | 1696 | os.path.join('.',*[a for a in args \ | 1861 | os.path.join('.',*[a for a in args \ |
343 | 1697 | if a.endswith(os.path.sep)])) | 1862 | if a.endswith(os.path.sep)])) |
344 | 1698 | 1863 | ||
345 | 1864 | def complete_compute_widths(self, text, line, begidx, endidx): | ||
346 | 1865 | "Complete the compute_widths command" | ||
347 | 1866 | |||
348 | 1867 | args = self.split_arg(line[0:begidx]) | ||
349 | 1868 | |||
350 | 1869 | if args[-1] in ['--path=', '--output=']: | ||
351 | 1870 | completion = {'path': self.path_completion(text)} | ||
352 | 1871 | elif line[begidx-1] == os.path.sep: | ||
353 | 1872 | current_dir = pjoin(*[a for a in args if a.endswith(os.path.sep)]) | ||
354 | 1873 | if current_dir.startswith('--path='): | ||
355 | 1874 | current_dir = current_dir[7:] | ||
356 | 1875 | if current_dir.startswith('--output='): | ||
357 | 1876 | current_dir = current_dir[9:] | ||
358 | 1877 | completion = {'path': self.path_completion(text, current_dir)} | ||
359 | 1878 | else: | ||
360 | 1879 | completion = {} | ||
361 | 1880 | completion['options'] = self.list_completion(text, | ||
362 | 1881 | ['--path=', '--output=', '--min_br=0.\$' | ||
363 | 1882 | '--precision_channel=0.\$', '--body_decay=']) | ||
364 | 1883 | |||
365 | 1884 | return self.deal_multiple_categories(completion) | ||
366 | 1699 | 1885 | ||
367 | 1700 | 1886 | ||
368 | 1701 | # lhapdf-related functions | 1887 | # lhapdf-related functions |
369 | @@ -2080,7 +2266,7 @@ | |||
370 | 2080 | self.list_completion(text, categories) | 2266 | self.list_completion(text, categories) |
371 | 2081 | 2267 | ||
372 | 2082 | if 'shortcut' in allowed.keys(): | 2268 | if 'shortcut' in allowed.keys(): |
374 | 2083 | possibilities['special values'] = self.list_completion(text, self.special_shortcut.keys()+['qcut']) | 2269 | possibilities['special values'] = self.list_completion(text, self.special_shortcut.keys()+['qcut', 'showerkt']) |
375 | 2084 | 2270 | ||
376 | 2085 | if 'run_card' in allowed.keys(): | 2271 | if 'run_card' in allowed.keys(): |
377 | 2086 | opts = self.run_set | 2272 | opts = self.run_set |
378 | @@ -2219,6 +2405,19 @@ | |||
379 | 2219 | p_card = '%s \n QCUT= %s' % (p_card, args[1]) | 2405 | p_card = '%s \n QCUT= %s' % (p_card, args[1]) |
380 | 2220 | open(pythia_path, 'w').write(p_card) | 2406 | open(pythia_path, 'w').write(p_card) |
381 | 2221 | return | 2407 | return |
382 | 2408 | # Special case for the showerkt value | ||
383 | 2409 | if args[0].lower() == 'showerkt': | ||
384 | 2410 | pythia_path = pjoin(self.me_dir, 'Cards','pythia_card.dat') | ||
385 | 2411 | if os.path.exists(pythia_path): | ||
386 | 2412 | logger.info('add line SHOWERKT = %s in pythia_card.dat' % args[1].upper()) | ||
387 | 2413 | p_card = open(pythia_path,'r').read() | ||
388 | 2414 | p_card, n = re.subn('''^\s*SHOWERKT\s*=\s*[default\de\+\-\.]*\s*$''', | ||
389 | 2415 | ''' SHOWERKT = %s ''' % args[1].upper(), \ | ||
390 | 2416 | p_card, flags=(re.M+re.I)) | ||
391 | 2417 | if n==0: | ||
392 | 2418 | p_card = '%s \n SHOWERKT= %s' % (p_card, args[1].upper()) | ||
393 | 2419 | open(pythia_path, 'w').write(p_card) | ||
394 | 2420 | return | ||
395 | 2222 | 2421 | ||
396 | 2223 | 2422 | ||
397 | 2224 | card = '' #store which card need to be modify (for name conflict) | 2423 | card = '' #store which card need to be modify (for name conflict) |
398 | 2225 | 2424 | ||
399 | === modified file 'madgraph/interface/madevent_interface.py' | |||
400 | --- madgraph/interface/madevent_interface.py 2014-09-20 07:40:10 +0000 | |||
401 | +++ madgraph/interface/madevent_interface.py 2014-09-24 19:46:10 +0000 | |||
402 | @@ -418,13 +418,6 @@ | |||
403 | 418 | logger.info(" asked in the run_card.") | 418 | logger.info(" asked in the run_card.") |
404 | 419 | self.run_options_help([]) | 419 | self.run_options_help([]) |
405 | 420 | 420 | ||
406 | 421 | def help_compute_widths(self): | ||
407 | 422 | logger.info("syntax: compute_widths Particle [Particles] [--precision=] [--path=Param_card] [--output=PATH]") | ||
408 | 423 | logger.info("-- Compute the widths for the particles specified.") | ||
409 | 424 | logger.info(" By default, this takes the current param_card and overwrites it.") | ||
410 | 425 | logger.info(" Precision allows to define when to include three/four/... body decays.") | ||
411 | 426 | logger.info(" If this number is an integer then all N-body decay will be included.") | ||
412 | 427 | |||
413 | 428 | def help_store_events(self): | 421 | def help_store_events(self): |
414 | 429 | """ """ | 422 | """ """ |
415 | 430 | logger.info("syntax: store_events [--run_options]") | 423 | logger.info("syntax: store_events [--run_options]") |
416 | @@ -867,112 +860,7 @@ | |||
417 | 867 | raise self.InvalidCmd('refine arguments are suppose to be number') | 860 | raise self.InvalidCmd('refine arguments are suppose to be number') |
418 | 868 | 861 | ||
419 | 869 | return True | 862 | return True |
526 | 870 | 863 | ||
421 | 871 | def check_compute_widths(self, args): | ||
422 | 872 | """check that the model is loadable and check that the format is of the | ||
423 | 873 | type: PART PATH --output=PATH -f --precision=N | ||
424 | 874 | return the model. | ||
425 | 875 | """ | ||
426 | 876 | |||
427 | 877 | # Check that MG5 directory is present . | ||
428 | 878 | if MADEVENT and not self.options['mg5_path']: | ||
429 | 879 | raise self.InvalidCmd, '''The automatic computations of widths requires that MG5 is installed on the system. | ||
430 | 880 | You can install it and set his path in ./Cards/me5_configuration.txt''' | ||
431 | 881 | elif MADEVENT: | ||
432 | 882 | sys.path.append(self.options['mg5_path']) | ||
433 | 883 | try: | ||
434 | 884 | import models.model_reader as model_reader | ||
435 | 885 | import models.import_ufo as import_ufo | ||
436 | 886 | except ImportError: | ||
437 | 887 | raise self.ConfigurationError, '''Can\'t load MG5. | ||
438 | 888 | The variable mg5_path should not be correctly configure.''' | ||
439 | 889 | |||
440 | 890 | ufo_path = pjoin(self.me_dir,'bin','internal', 'ufomodel') | ||
441 | 891 | # Import model | ||
442 | 892 | if not MADEVENT: | ||
443 | 893 | modelname = self.find_model_name() | ||
444 | 894 | #restrict_file = None | ||
445 | 895 | #if os.path.exists(pjoin(ufo_path, 'restrict_default.dat')): | ||
446 | 896 | # restrict_file = pjoin(ufo_path, 'restrict_default.dat') | ||
447 | 897 | model = import_ufo.import_model(modelname, decay=True, | ||
448 | 898 | restrict=True) | ||
449 | 899 | if self.mother and self.mother.options['complex_mass_scheme']: | ||
450 | 900 | model.change_mass_to_complex_scheme() | ||
451 | 901 | else: | ||
452 | 902 | model = import_ufo.import_model(pjoin(self.me_dir,'bin','internal', 'ufomodel'), | ||
453 | 903 | decay=True) | ||
454 | 904 | #pattern for checking complex mass scheme. | ||
455 | 905 | has_cms = re.compile(r'''set\s+complex_mass_scheme\s*(True|T|1|true|$|;)''') | ||
456 | 906 | if has_cms.search(open(pjoin(self.me_dir,'Cards','proc_card_mg5.dat')\ | ||
457 | 907 | ).read()): | ||
458 | 908 | model.change_mass_to_complex_scheme() | ||
459 | 909 | |||
460 | 910 | |||
461 | 911 | # if not hasattr(model.get('particles')[0], 'partial_widths'): | ||
462 | 912 | # raise self.InvalidCmd, 'The UFO model does not include partial widths information. Impossible to compute widths automatically' | ||
463 | 913 | |||
464 | 914 | # check if the name are passed to default MG5 | ||
465 | 915 | if '-modelname' in open(pjoin(self.me_dir,'Cards','proc_card_mg5.dat')).read(): | ||
466 | 916 | model.pass_particles_name_in_mg_default() | ||
467 | 917 | model = model_reader.ModelReader(model) | ||
468 | 918 | particles_name = dict([(p.get('name'), p.get('pdg_code')) | ||
469 | 919 | for p in model.get('particles')]) | ||
470 | 920 | particles_name.update(dict([(p.get('antiname'), p.get('pdg_code')) | ||
471 | 921 | for p in model.get('particles')])) | ||
472 | 922 | |||
473 | 923 | output = {'model': model, 'force': False, 'output': None, | ||
474 | 924 | 'path':None, 'particles': set(), 'body_decay':4.0025, | ||
475 | 925 | 'min_br':None, 'precision_channel':0.01} | ||
476 | 926 | for arg in args: | ||
477 | 927 | if arg.startswith('--output='): | ||
478 | 928 | output_path = arg.split('=',1)[1] | ||
479 | 929 | if not os.path.exists(output_path): | ||
480 | 930 | raise self.InvalidCmd, 'Invalid Path for the output. Please retry.' | ||
481 | 931 | if not os.path.isfile(output_path): | ||
482 | 932 | output_path = pjoin(output_path, 'param_card.dat') | ||
483 | 933 | output['output'] = output_path | ||
484 | 934 | elif arg == '-f': | ||
485 | 935 | output['force'] = True | ||
486 | 936 | elif os.path.isfile(arg): | ||
487 | 937 | type = self.detect_card_type(arg) | ||
488 | 938 | if type != 'param_card.dat': | ||
489 | 939 | raise self.InvalidCmd , '%s is not a valid param_card.' % arg | ||
490 | 940 | output['path'] = arg | ||
491 | 941 | elif arg.startswith('--path='): | ||
492 | 942 | arg = arg.split('=',1)[1] | ||
493 | 943 | type = self.detect_card_type(arg) | ||
494 | 944 | if type != 'param_card.dat': | ||
495 | 945 | raise self.InvalidCmd , '%s is not a valid param_card.' % arg | ||
496 | 946 | output['path'] = arg | ||
497 | 947 | elif arg.startswith('--'): | ||
498 | 948 | name, value = arg.split('=',1) | ||
499 | 949 | try: | ||
500 | 950 | value = float(value) | ||
501 | 951 | except Exception: | ||
502 | 952 | raise self.InvalidCmd, '--%s requires integer or a float' % name | ||
503 | 953 | output[name[2:]] = float(value) | ||
504 | 954 | elif arg in particles_name: | ||
505 | 955 | # should be a particles | ||
506 | 956 | output['particles'].add(particles_name[arg]) | ||
507 | 957 | elif arg.isdigit() and int(arg) in particles_name.values(): | ||
508 | 958 | output['particles'].add(eval(arg)) | ||
509 | 959 | elif arg == 'all': | ||
510 | 960 | output['particles'] = set(['all']) | ||
511 | 961 | else: | ||
512 | 962 | self.help_compute_widths() | ||
513 | 963 | raise self.InvalidCmd, '%s is not a valid argument for compute_widths' % arg | ||
514 | 964 | if self.force: | ||
515 | 965 | output['force'] = True | ||
516 | 966 | |||
517 | 967 | if not output['particles']: | ||
518 | 968 | raise self.InvalidCmd, '''This routines requires at least one particle in order to compute | ||
519 | 969 | the related width''' | ||
520 | 970 | |||
521 | 971 | if output['output'] is None: | ||
522 | 972 | output['output'] = output['path'] | ||
523 | 973 | |||
524 | 974 | return output | ||
525 | 975 | |||
527 | 976 | def check_combine_events(self, arg): | 864 | def check_combine_events(self, arg): |
528 | 977 | """ Check the argument for the combine events command """ | 865 | """ Check the argument for the combine events command """ |
529 | 978 | 866 | ||
530 | @@ -1506,28 +1394,6 @@ | |||
531 | 1506 | else: | 1394 | else: |
532 | 1507 | return self.complete_generate_events(*args, **opts) | 1395 | return self.complete_generate_events(*args, **opts) |
533 | 1508 | 1396 | ||
534 | 1509 | def complete_compute_widths(self, text, line, begidx, endidx): | ||
535 | 1510 | "Complete the compute_widths command" | ||
536 | 1511 | |||
537 | 1512 | args = self.split_arg(line[0:begidx]) | ||
538 | 1513 | |||
539 | 1514 | if args[-1] in ['--path=', '--output=']: | ||
540 | 1515 | completion = {'path': self.path_completion(text)} | ||
541 | 1516 | elif line[begidx-1] == os.path.sep: | ||
542 | 1517 | current_dir = pjoin(*[a for a in args if a.endswith(os.path.sep)]) | ||
543 | 1518 | if current_dir.startswith('--path='): | ||
544 | 1519 | current_dir = current_dir[7:] | ||
545 | 1520 | if current_dir.startswith('--output='): | ||
546 | 1521 | current_dir = current_dir[9:] | ||
547 | 1522 | completion = {'path': self.path_completion(text, current_dir)} | ||
548 | 1523 | else: | ||
549 | 1524 | completion = {} | ||
550 | 1525 | completion['options'] = self.list_completion(text, | ||
551 | 1526 | ['--path=', '--output=', '--min_br=0.\$' | ||
552 | 1527 | '--precision_channel=0.\$', '--body_decay=']) | ||
553 | 1528 | |||
554 | 1529 | return self.deal_multiple_categories(completion) | ||
555 | 1530 | |||
556 | 1531 | def complete_calculate_decay_widths(self, text, line, begidx, endidx): | 1397 | def complete_calculate_decay_widths(self, text, line, begidx, endidx): |
557 | 1532 | """ Complete the calculate_decay_widths command""" | 1398 | """ Complete the calculate_decay_widths command""" |
558 | 1533 | 1399 | ||
559 | @@ -2694,33 +2560,7 @@ | |||
560 | 2694 | self.create_root_file(output='%s/unweighted_events.root' % \ | 2560 | self.create_root_file(output='%s/unweighted_events.root' % \ |
561 | 2695 | self.run_name) | 2561 | self.run_name) |
562 | 2696 | 2562 | ||
563 | 2697 | ############################################################################ | ||
564 | 2698 | def do_compute_widths(self, line): | ||
565 | 2699 | """Require MG5 directory: Compute automatically the widths of a set | ||
566 | 2700 | of particles""" | ||
567 | 2701 | 2563 | ||
568 | 2702 | args = self.split_arg(line) | ||
569 | 2703 | opts = self.check_compute_widths(args) | ||
570 | 2704 | |||
571 | 2705 | |||
572 | 2706 | from madgraph.interface.master_interface import MasterCmd | ||
573 | 2707 | cmd = MasterCmd() | ||
574 | 2708 | self.define_child_cmd_interface(cmd, interface=False) | ||
575 | 2709 | cmd.exec_cmd('set automatic_html_opening False --no_save') | ||
576 | 2710 | if not opts['path']: | ||
577 | 2711 | opts['path'] = pjoin(self.me_dir, 'Cards', 'param_card.dat') | ||
578 | 2712 | if not opts['force'] : | ||
579 | 2713 | self.ask_edit_cards(['param_card'],[], plot=False) | ||
580 | 2714 | |||
581 | 2715 | |||
582 | 2716 | line = 'compute_widths %s %s' % \ | ||
583 | 2717 | (' '.join([str(i) for i in opts['particles']]), | ||
584 | 2718 | ' '.join('--%s=%s' % (key,value) for (key,value) in opts.items() | ||
585 | 2719 | if key not in ['model', 'force', 'particles'] and value)) | ||
586 | 2720 | |||
587 | 2721 | cmd.exec_cmd(line, model=opts['model']) | ||
588 | 2722 | self.child = None | ||
589 | 2723 | del cmd | ||
590 | 2724 | 2564 | ||
591 | 2725 | 2565 | ||
592 | 2726 | 2566 | ||
593 | @@ -4048,22 +3888,8 @@ | |||
594 | 4048 | 3888 | ||
595 | 4049 | 3889 | ||
596 | 4050 | 3890 | ||
613 | 4051 | def check_param_card(self, path, run=True): | 3891 | |
614 | 4052 | """Check that all the width are define in the param_card. | 3892 | |
599 | 4053 | If some width are set on 'Auto', call the computation tools.""" | ||
600 | 4054 | |||
601 | 4055 | pattern = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto''',re.I) | ||
602 | 4056 | text = open(path).read() | ||
603 | 4057 | pdg = pattern.findall(text) | ||
604 | 4058 | if pdg: | ||
605 | 4059 | if run: | ||
606 | 4060 | logger.info('Computing the width set on auto in the param_card.dat') | ||
607 | 4061 | self.do_compute_widths('%s %s' % (' '.join(pdg), path)) | ||
608 | 4062 | else: | ||
609 | 4063 | logger.info('''Some width are on Auto in the card. | ||
610 | 4064 | Those will be computed as soon as you have finish the edition of the cards. | ||
611 | 4065 | If you want to force the computation right now and being able to re-edit | ||
612 | 4066 | the cards afterwards, you can type \"compute_wdiths\".''') | ||
615 | 4067 | #=============================================================================== | 3893 | #=============================================================================== |
616 | 4068 | # MadEventCmd | 3894 | # MadEventCmd |
617 | 4069 | #=============================================================================== | 3895 | #=============================================================================== |
618 | 4070 | 3896 | ||
619 | === modified file 'madgraph/various/gen_crossxhtml.py' | |||
620 | --- madgraph/various/gen_crossxhtml.py 2014-09-22 07:17:43 +0000 | |||
621 | +++ madgraph/various/gen_crossxhtml.py 2014-09-24 19:46:10 +0000 | |||
622 | @@ -791,6 +791,10 @@ | |||
623 | 791 | glob.glob(pjoin(path,"*.hep.gz")): | 791 | glob.glob(pjoin(path,"*.hep.gz")): |
624 | 792 | self.shower.append('hep') | 792 | self.shower.append('hep') |
625 | 793 | 793 | ||
626 | 794 | if 'plot' not in self.shower and \ | ||
627 | 795 | exists(pjoin(html_path,"plots_shower_%s.html" % tag)): | ||
628 | 796 | self.shower.append('plot') | ||
629 | 797 | |||
630 | 794 | if glob.glob(pjoin(path,"*.hepmc")) + \ | 798 | if glob.glob(pjoin(path,"*.hepmc")) + \ |
631 | 795 | glob.glob(pjoin(path,"*.hepmc.gz")): | 799 | glob.glob(pjoin(path,"*.hepmc.gz")): |
632 | 796 | self.shower.append('hepmc') | 800 | self.shower.append('hepmc') |
633 | @@ -988,6 +992,8 @@ | |||
634 | 988 | glob.glob(pjoin(self.me_dir, 'Events', self['run_name'], '*.' + kind)) + \ | 992 | glob.glob(pjoin(self.me_dir, 'Events', self['run_name'], '*.' + kind)) + \ |
635 | 989 | glob.glob(pjoin(self.me_dir, 'Events', self['run_name'], '*.' + kind + '.gz')): | 993 | glob.glob(pjoin(self.me_dir, 'Events', self['run_name'], '*.' + kind + '.gz')): |
636 | 990 | out += " <a href=\"%s\">%s</a> " % (f, kind.upper()) | 994 | out += " <a href=\"%s\">%s</a> " % (f, kind.upper()) |
637 | 995 | if 'plot' in self.shower: | ||
638 | 996 | out += """ <a href="./HTML/%(run_name)s/plots_shower_%(tag)s.html">plots</a>""" | ||
639 | 991 | 997 | ||
640 | 992 | return out % self | 998 | return out % self |
641 | 993 | 999 | ||
642 | 994 | 1000 | ||
643 | === modified file 'tests/test_manager.py' | |||
644 | --- tests/test_manager.py 2014-05-15 00:02:06 +0000 | |||
645 | +++ tests/test_manager.py 2014-09-24 19:46:10 +0000 | |||
646 | @@ -115,6 +115,38 @@ | |||
647 | 115 | self.stream.writeln(" ".join(self.bypassed)) | 115 | self.stream.writeln(" ".join(self.bypassed)) |
648 | 116 | return result | 116 | return result |
649 | 117 | 117 | ||
650 | 118 | def run_border(self, test): | ||
651 | 119 | "Run the given test case or test suite." | ||
652 | 120 | MyTextTestRunner.stream = self.stream | ||
653 | 121 | result = self._makeResult() | ||
654 | 122 | startTime = time.time() | ||
655 | 123 | test(result) | ||
656 | 124 | stopTime = time.time() | ||
657 | 125 | timeTaken = float(stopTime - startTime) | ||
658 | 126 | result.printErrors() | ||
659 | 127 | self.stream.writeln(result.separator2) | ||
660 | 128 | run = result.testsRun | ||
661 | 129 | #self.stream.writeln("Ran %d test%s in %.3fs" % | ||
662 | 130 | # (run, run != 1 and "s" or "", timeTaken)) | ||
663 | 131 | #self.stream.writeln() | ||
664 | 132 | if not result.wasSuccessful(): | ||
665 | 133 | self.stream.write("FAILED (") | ||
666 | 134 | failed, errored = map(len, (result.failures, result.errors)) | ||
667 | 135 | if failed: | ||
668 | 136 | self.stream.write("failures=%d" % failed) | ||
669 | 137 | if errored: | ||
670 | 138 | if failed: self.stream.write(", ") | ||
671 | 139 | self.stream.write("errors=%d" % errored) | ||
672 | 140 | self.stream.writeln(")") | ||
673 | 141 | sys.exit(0) | ||
674 | 142 | #else: | ||
675 | 143 | # self.stream.writeln("OK") | ||
676 | 144 | #if self.bypassed: | ||
677 | 145 | # self.stream.writeln("Bypassed %s:" % len(self.bypassed)) | ||
678 | 146 | # self.stream.writeln(" ".join(self.bypassed)) | ||
679 | 147 | return result | ||
680 | 148 | |||
681 | 149 | |||
682 | 118 | 150 | ||
683 | 119 | #=============================================================================== | 151 | #=============================================================================== |
684 | 120 | # run | 152 | # run |
685 | @@ -153,6 +185,46 @@ | |||
686 | 153 | #return out | 185 | #return out |
687 | 154 | 186 | ||
688 | 155 | #=============================================================================== | 187 | #=============================================================================== |
689 | 188 | # run | ||
690 | 189 | #=============================================================================== | ||
691 | 190 | def run_border_search(to_crash='',expression='', re_opt=0, package='./tests/unit_tests', verbosity=1, | ||
692 | 191 | timelimit=0): | ||
693 | 192 | """ running the test associated to expression one by one. and follow them by the to_crash one | ||
694 | 193 | up to the time that to_crash is actually crashing. Then the run stops and print the list of the | ||
695 | 194 | routine tested. Then the code re-run itself(via a fork) to restrict the list. | ||
696 | 195 | The code stops when the list is of order 1. The order of the test is randomize at each level! | ||
697 | 196 | """ | ||
698 | 197 | #init a test suite | ||
699 | 198 | collect = unittest.TestLoader() | ||
700 | 199 | TestSuiteModified.time_limit = float(timelimit) | ||
701 | 200 | all_test = TestFinder(package=package, expression=expression, re_opt=re_opt) | ||
702 | 201 | import random | ||
703 | 202 | random.shuffle(all_test) | ||
704 | 203 | print "to_crash" | ||
705 | 204 | to_crash = TestFinder(package=package, expression=to_crash, re_opt=re_opt) | ||
706 | 205 | to_crash.collect_dir(package, checking=True) | ||
707 | 206 | print dir(to_crash) | ||
708 | 207 | |||
709 | 208 | for test_fct in all_test: | ||
710 | 209 | testsuite = unittest.TestSuite() | ||
711 | 210 | data = collect.loadTestsFromName(test_fct) | ||
712 | 211 | assert(isinstance(data,unittest.TestSuite)) | ||
713 | 212 | data.__class__ = TestSuiteModified | ||
714 | 213 | testsuite.addTest(data) | ||
715 | 214 | data = collect.loadTestsFromName(to_crash[0]) | ||
716 | 215 | assert(isinstance(data,unittest.TestSuite)) | ||
717 | 216 | data.__class__ = TestSuiteModified | ||
718 | 217 | testsuite.addTest(data) | ||
719 | 218 | # Running it | ||
720 | 219 | print "run it for %s" % test_fct | ||
721 | 220 | output = MyTextTestRunner(verbosity=verbosity).run_border(testsuite) | ||
722 | 221 | |||
723 | 222 | return output | ||
724 | 223 | #import tests | ||
725 | 224 | #print 'runned %s checks' % tests.NBTEST | ||
726 | 225 | #return out | ||
727 | 226 | |||
728 | 227 | #=============================================================================== | ||
729 | 156 | # listIOTests | 228 | # listIOTests |
730 | 157 | #=============================================================================== | 229 | #=============================================================================== |
731 | 158 | 230 | ||
732 | @@ -262,8 +334,8 @@ | |||
733 | 262 | IOTestManager.testFolders_filter = arg.split('/')[0].split('&') | 334 | IOTestManager.testFolders_filter = arg.split('/')[0].split('&') |
734 | 263 | IOTestManager.testNames_filter = arg.split('/')[1].split('&') | 335 | IOTestManager.testNames_filter = arg.split('/')[1].split('&') |
735 | 264 | IOTestManager.filesChecked_filter = '/'.join(arg.split('/')[2:]).split('&') | 336 | IOTestManager.filesChecked_filter = '/'.join(arg.split('/')[2:]).split('&') |
738 | 265 | #print "INFO:: Using folders %s"%str(IOTestManager.testFolders_filter) | 337 | #print "INFO:: Using folders %s"%str(IOTestManager.testFolders_filter) |
739 | 266 | #print "INFO:: Using test names %s"%str(IOTestManager.testNames_filter) | 338 | #print "INFO:: Using test names %s"%str(IOTestManager.testNames_filter) |
740 | 267 | #print "INFO:: Using file paths %s"%str(IOTestManager.filesChecked_filter) | 339 | #print "INFO:: Using file paths %s"%str(IOTestManager.filesChecked_filter) |
741 | 268 | 340 | ||
742 | 269 | # Initiate all the IOTests from all the setUp() | 341 | # Initiate all the IOTests from all the setUp() |
743 | @@ -820,7 +892,10 @@ | |||
744 | 820 | "content of the folder IOTestsComparison") | 892 | "content of the folder IOTestsComparison") |
745 | 821 | parser.add_option("-t", "--timed", default="Auto", | 893 | parser.add_option("-t", "--timed", default="Auto", |
746 | 822 | help="limit the duration of each test. Negative number re-writes the information file.") | 894 | help="limit the duration of each test. Negative number re-writes the information file.") |
748 | 823 | 895 | ||
749 | 896 | parser.add_option("", "--border_effect", default=None, | ||
750 | 897 | help="Define the test which are sensitive to a border effect, the test will find which test creates this border effect") | ||
751 | 898 | |||
752 | 824 | (options, args) = parser.parse_args() | 899 | (options, args) = parser.parse_args() |
753 | 825 | 900 | ||
754 | 826 | if options.IOTestsUpdate: | 901 | if options.IOTestsUpdate: |
755 | @@ -897,9 +972,13 @@ | |||
756 | 897 | " MadGraph5_aMCatNLO is configured not to compress the references files." | 972 | " MadGraph5_aMCatNLO is configured not to compress the references files." |
757 | 898 | 973 | ||
758 | 899 | if options.IOTests=='No' and not options.synchronize: | 974 | if options.IOTests=='No' and not options.synchronize: |
762 | 900 | #logging.basicConfig(level=vars(logging)[options.logging]) | 975 | if not options.border_effect: |
763 | 901 | run(args, re_opt=options.reopt, verbosity=options.verbose, \ | 976 | #logging.basicConfig(level=vars(logging)[options.logging]) |
764 | 902 | package=options.path, timelimit=options.timed) | 977 | run(args, re_opt=options.reopt, verbosity=options.verbose, \ |
765 | 978 | package=options.path, timelimit=options.timed) | ||
766 | 979 | else: | ||
767 | 980 | run_border_search(options.border_effect, args, re_opt=options.reopt, verbosity=options.verbose, \ | ||
768 | 981 | package=options.path, timelimit=options.timed) | ||
769 | 903 | else: | 982 | else: |
770 | 904 | if options.IOTests=='L': | 983 | if options.IOTests=='L': |
771 | 905 | print "Listing all tests defined in the reference files ..." | 984 | print "Listing all tests defined in the reference files ..." |
Reviewed via skype.