]>
Commit | Line | Data |
---|---|---|
1afce1ce | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | // | |
17 | // AliMuonAccEffSubmitter : a class to help submit Acc x Eff simulations | |
18 | // anchored to real runs for J/psi, upsilon, single muons, etc... | |
19 | // | |
20 | // This class is dealing with 3 different directories : | |
21 | // | |
22 | // - template directory ($ALICE_ROOT/PWG/muondep/AccEffTemplates) containing the | |
23 | // basic template files to be used for a simuation. A template can contain | |
24 | // some variables that will be replaced during during the copy from template | |
25 | // to local dir | |
26 | // | |
27 | // - local directory, where the files from the template directory, are copied | |
28 | // once the class has been configured properly (i.e. using the various Set, Use, | |
29 | // etc... methods). Some other files (e.g. JDL ones) are generated from | |
30 | // scratch and also copied into this directory. | |
31 | // At this point one could(should) check the files, as they are the ones | |
32 | // to be copied to the remote directory for the production | |
33 | // | |
34 | // - remote directory, the alien directory where the files will be copied | |
35 | // (from the local directory) before the actual submission | |
36 | // | |
37 | // ========================================================== | |
38 | // | |
39 | // Basic usage | |
40 | // | |
30138a88 | 41 | // AliMuonAccEffSubmitter a; // (1) |
1afce1ce | 42 | // a.UseOCDBSnapshots(kFALSE); |
43 | // a.SetRemoteDir("/alice/cern.ch/user/l/laphecet/Analysis/LHC13d/simjpsi/pp503z0"); | |
44 | // a.ShouldOverwriteFiles(true); | |
45 | // a.MakeNofEventsPropToTriggerCount("CMUL7-B-NOPF-MUON"); | |
46 | // a.SetVar("VAR_GENLIB_PARNAME","\"pp 5.03\""); | |
47 | // a.SetRunList(195682); | |
48 | // a.Print(); | |
49 | // a.Run("test"); // will do everything but the submit | |
50 | // a.Submit(false); // actual submission | |
51 | // | |
30138a88 | 52 | // (1) note that for this to work in the Root prompt you need to load (for instance |
53 | // in your rootlogon.C) all the chain of libraries up to libPWGmuondep. As | |
54 | // the time of this writing (March 2014), this means : | |
1afce1ce | 55 | // |
30138a88 | 56 | // gSystem->Load("libVMC"); |
57 | // gSystem->Load("libTree"); | |
58 | // gSystem->Load("libProofPlayer"); | |
59 | // gSystem->Load("libPhysics"); | |
60 | // gSystem->Load("libMatrix"); | |
61 | // gSystem->Load("libMinuit"); | |
62 | // gSystem->Load("libXMLParser"); | |
63 | // gSystem->Load("libGui"); | |
64 | // gSystem->Load("libSTEERBase"); | |
65 | // gSystem->Load("libESD"); | |
66 | // gSystem->Load("libAOD"); | |
67 | // gSystem->Load("libANALYSIS"); | |
68 | // gSystem->Load("libRAWDatabase"); | |
69 | // gSystem->Load("libCDB"); | |
70 | // gSystem->Load("libSTEER"); | |
71 | // gSystem->Load("libANALYSISalice"); | |
72 | // gSystem->Load("libCORRFW"); | |
73 | // gSystem->Load("libPWGmuon"); | |
74 | // gSystem->Load("libMUONcore"); | |
75 | // gSystem->Load("libMUONmapping"); | |
76 | // gSystem->Load("libMUONcalib"); | |
77 | // gSystem->Load("libMUONgeometry"); | |
78 | // gSystem->Load("libMUONtrigger"); | |
79 | // gSystem->Load("libRAWDatabase"); | |
80 | // gSystem->Load("libMUONraw"); | |
81 | // gSystem->Load("libMUONbase"); | |
82 | // gSystem->Load("libMUONshuttle"); | |
83 | // gSystem->Load("libMUONrec"); | |
84 | // gSystem->Load("libPWGmuondep"); | |
85 | // | |
86 | // author: Laurent Aphecetche (Subatech) | |
1afce1ce | 87 | // |
88 | ||
a58729a5 | 89 | #include "AliMuonAccEffSubmitter.h" |
90 | ||
91 | #include "AliAnalysisTriggerScalers.h" | |
92 | #include "AliLog.h" | |
93 | #include "TFile.h" | |
94 | #include "TGrid.h" | |
95 | #include "TGridResult.h" | |
96 | #include "TMap.h" | |
97 | #include "TMath.h" | |
98 | #include "TObjString.h" | |
1afce1ce | 99 | #include "TROOT.h" |
a58729a5 | 100 | #include "TString.h" |
101 | #include "TSystem.h" | |
102 | #include <vector> | |
c2aad3ae | 103 | #include <fstream> |
104 | using std::ifstream; | |
a58729a5 | 105 | namespace |
106 | { | |
107 | Int_t splitLevel=10; | |
108 | } | |
109 | ||
81190958 | 110 | ClassImp(AliMuonAccEffSubmitter) |
111 | ||
a58729a5 | 112 | //______________________________________________________________________________ |
30138a88 | 113 | AliMuonAccEffSubmitter::AliMuonAccEffSubmitter(const char* generator, Bool_t localOnly, |
3e7b6e7b | 114 | const char* generatorVersion) |
eb5de7ee | 115 | : AliMuonGridSubmitter(AliMuonGridSubmitter::kAccEff,localOnly), |
81190958 | 116 | fRatio(-1.0), |
1afce1ce | 117 | fFixedNofEvents(10000), |
a58729a5 | 118 | fMaxEventsPerChunk(5000), |
d484adc1 | 119 | fOCDBPath(""), |
a58729a5 | 120 | fSplitMaxInputFileNumber(20), |
121 | fCompactMode(1), | |
a58729a5 | 122 | fExternalConfig(""), |
81190958 | 123 | fUseOCDBSnapshots(kFALSE), |
d484adc1 | 124 | fSnapshotDir(""), |
a3c2a88b | 125 | fUseAODMerging(kFALSE) |
a58729a5 | 126 | { |
127 | // ctor | |
30138a88 | 128 | // |
3e7b6e7b | 129 | // if generator contains "pythia8" and generatorVersion is given then |
130 | // the pythiaversion must represent the integer part XXX of the | |
30138a88 | 131 | // include directory $ALICE_ROOT/PYTHI8/pythiaXXX/include where the file |
132 | // Analysis.h is to be found. | |
3e7b6e7b | 133 | // |
134 | // if generator contains "pythia6" then generatorVersion should be the | |
135 | // X.YY part of libpythia6.X.YY.so | |
136 | // | |
30138a88 | 137 | |
3e7b6e7b | 138 | AddIncludePath("-I$ALICE_ROOT/STEER/STEER -I$ALICE_ROOT/PYTHIA6 -I$ALICE_ROOT/LHAPDF -I$ALICE_ROOT/PWG/muon -I$ALICE_ROOT/PWG/muondep -I$ALICE_ROOT/MUON -I$ALICE_ROOT/include -I$ALICE_ROOT/EVGEN -I$ALICE_ROOT/FASTSIM"); |
a58729a5 | 139 | |
eb5de7ee | 140 | TString ocdbPath("raw://"); |
141 | ||
142 | if (localOnly) { | |
143 | ocdbPath = "local://$ALICE_ROOT/OCDB"; | |
144 | } | |
145 | ||
146 | SetOCDBPath(ocdbPath.Data()); | |
81190958 | 147 | |
148 | SetLocalDirectory("Snapshot",LocalDir()); | |
a58729a5 | 149 | |
eb5de7ee | 150 | SetVar("VAR_OCDB_PATH",Form("\"%s\"",ocdbPath.Data())); |
a2e95afc | 151 | SetVar("VAR_AOD_MERGE_FILES","\"AliAOD.root,AliAOD.Muons.root\""); |
1afce1ce | 152 | |
30138a88 | 153 | SetVar("VAR_GENPARAM_INCLUDE","AliGenMUONlib.h"); |
eb5de7ee | 154 | SetVar("VAR_GENPARAM_NPART","1"); |
1afce1ce | 155 | SetVar("VAR_GENPARAM_GENLIB_TYPE","AliGenMUONlib::kJpsi"); |
156 | SetVar("VAR_GENPARAM_GENLIB_PARNAME","\"pPb 5.03\""); | |
157 | ||
158 | SetVar("VAR_GENCORRHF_QUARK","5"); | |
159 | SetVar("VAR_GENCORRHF_ENERGY","5"); | |
160 | ||
a3c2a88b | 161 | // some default values for J/psi |
1afce1ce | 162 | SetVar("VAR_GENPARAMCUSTOM_PDGPARTICLECODE","443"); |
163 | ||
164 | // default values below are from J/psi p+Pb (from muon_calo pass) | |
165 | SetVar("VAR_GENPARAMCUSTOM_Y_P0","4.08E5"); | |
166 | SetVar("VAR_GENPARAMCUSTOM_Y_P1","7.1E4"); | |
167 | ||
168 | SetVar("VAR_GENPARAMCUSTOM_PT_P0","1.13E9"); | |
169 | SetVar("VAR_GENPARAMCUSTOM_PT_P1","18.05"); | |
170 | SetVar("VAR_GENPARAMCUSTOM_PT_P2","2.05"); | |
171 | SetVar("VAR_GENPARAMCUSTOM_PT_P3","3.34"); | |
172 | ||
a3c2a88b | 173 | // some default values for single muons |
174 | SetVar("VAR_GENPARAMCUSTOMSINGLE_PTMIN","0.35"); | |
175 | ||
176 | SetVar("VAR_GENPARAMCUSTOMSINGLE_PT_P0","4.05962"); | |
177 | SetVar("VAR_GENPARAMCUSTOMSINGLE_PT_P1","1.0"); | |
178 | SetVar("VAR_GENPARAMCUSTOMSINGLE_PT_P2","2.46187"); | |
179 | SetVar("VAR_GENPARAMCUSTOMSINGLE_PT_P3","2.08644"); | |
180 | ||
181 | SetVar("VAR_GENPARAMCUSTOMSINGLE_Y_P0","0.729545"); | |
182 | SetVar("VAR_GENPARAMCUSTOMSINGLE_Y_P1","0.53837"); | |
183 | SetVar("VAR_GENPARAMCUSTOMSINGLE_Y_P2","0.141776"); | |
184 | SetVar("VAR_GENPARAMCUSTOMSINGLE_Y_P3","0.0130173"); | |
185 | ||
f9fda76e | 186 | // some default values for GenBox |
187 | ||
188 | SetVar("VAR_GENMUBOX_PTMIN","0"); | |
189 | SetVar("VAR_GENMUBOX_PTMAX","20"); | |
190 | SetVar("VAR_GENMUBOX_YMIN","-4.1"); | |
191 | SetVar("VAR_GENMUBOX_YMAX","-2.4"); | |
192 | ||
30138a88 | 193 | SetVar("VAR_PYTHIA8_CMS_ENERGY","8000"); |
3e7b6e7b | 194 | SetVar("VAR_PYTHIA6_CMS_ENERGY","8000"); |
30138a88 | 195 | |
eb5de7ee | 196 | SetVar("VAR_PURELY_LOCAL",Form("%d",localOnly)); |
197 | ||
8907673b | 198 | SetVar("VAR_SIM_ALIGNDATA","\"alien://folder=/alice/simulation/2008/v4-15-Release/Ideal\""); |
199 | ||
200 | SetVar("VAR_REC_ALIGNDATA","\"alien://folder=/alice/simulation/2008/v4-15-Release/Residual\""); | |
201 | ||
30138a88 | 202 | SetVar("VAR_USE_ITS_RECO","0"); |
203 | ||
81190958 | 204 | UseOCDBSnapshots(fUseOCDBSnapshots); |
30138a88 | 205 | |
206 | gSystem->Load("libEVGEN"); | |
207 | ||
3e7b6e7b | 208 | SetVar("VAR_TRIGGER_CONFIGURATION",""); |
209 | ||
210 | SetVar("VAR_PYTHIA8_INCLUDES",""); | |
211 | SetVar("VAR_PYTHIA8_SETENV",""); | |
212 | ||
213 | SetVar("VAR_PYTHIA6_INCLUDES",""); | |
214 | SetVar("VAR_PYTHIA6_SETENV",""); | |
215 | ||
57843125 | 216 | SetVar("VAR_LHAPDF","liblhapdf"); |
217 | SetVar("VAR_MUONMCMODE","1"); | |
218 | ||
30138a88 | 219 | if ( TString(generator).Contains("pythia8",TString::kIgnoreCase) ) |
220 | { | |
221 | fMaxEventsPerChunk = 500; // 5000 is not reasonable with Pythia8 (and ITS+MUON...) | |
222 | ||
223 | fCompactMode = 2; // keep AOD as for the time being the filtering driven from AODtrain.C cannot | |
224 | // add SPD tracklets to muon AODs. | |
225 | ||
226 | SetVar("VAR_USE_ITS_RECO","1"); | |
227 | ||
3e7b6e7b | 228 | if (gSystem->AccessPathName(gSystem->ExpandPathName(Form("$ALICE_ROOT/PYTHIA8/pythia%s",generatorVersion)))) |
30138a88 | 229 | { |
3e7b6e7b | 230 | AliError(Form("Directory -I$ALICE_ROOT/PYTHIA8/pythia%s/include not found",generatorVersion)); |
30138a88 | 231 | Invalidate(); |
232 | return; | |
233 | } | |
3e7b6e7b | 234 | AddIncludePath(Form("-I$ALICE_ROOT/PYTHIA8 -I$ALICE_ROOT/PYTHIA8/pythia%s/include",generatorVersion)); |
30138a88 | 235 | // SetVar("VAR_PYTHIA8_VERSION",Form("\"%d\"",pythia8version)); |
236 | ||
3e7b6e7b | 237 | SetVar("VAR_PYTHIA8_INCLUDES",Form("gSystem->AddIncludePath(\"-I$ALICE_ROOT/PYTHIA6 -I$ALICE_ROOT/STEER/STEER -I$ALICE_ROOT/LHAPDF -I$ALICE_ROOT/PYTHIA8 -I$ALICE_ROOT/PYTHIA8/pythia%s/include\");\n",generatorVersion)); |
30138a88 | 238 | |
239 | TString p8env; | |
240 | ||
3e7b6e7b | 241 | p8env += Form(" gSystem->Setenv(\"PYTHIA8DATA\", gSystem->ExpandPathName(\"$ALICE_ROOT/PYTHIA8/pythia%s/xmldoc\"));\n",generatorVersion); |
30138a88 | 242 | |
243 | p8env += " gSystem->Setenv(\"LHAPDF\",gSystem->ExpandPathName(\"$ALICE_ROOT/LHAPDF\"));\n"; | |
244 | ||
245 | p8env += " gSystem->Setenv(\"LHAPATH\",gSystem->ExpandPathName(\"$ALICE_ROOT/LHAPDF/PDFsets\"));\n"; | |
246 | ||
247 | SetVar("VAR_PYTHIA8_SETENV",p8env.Data()); | |
248 | ||
249 | gSystem->Load("libFASTSIM"); | |
250 | gSystem->Load("liblhapdf"); // Parton density functions | |
251 | gSystem->Load("libEGPythia6"); // TGenerator interface | |
3e7b6e7b | 252 | // gSystem->Load("libpythia6"); // Pythia 6.2 |
30138a88 | 253 | gSystem->Load("libAliPythia6"); // ALICE specific implementations |
3e7b6e7b | 254 | gSystem->Load("libpythia8"); |
255 | gSystem->Load("libAliPythia8"); | |
256 | ||
257 | SetVar("VAR_PYTHIA8_SETUP_STRINGS","\"\""); | |
258 | ||
259 | SetVar("VAR_TRIGGER_CONFIGURATION","p-p"); | |
30138a88 | 260 | } |
3e7b6e7b | 261 | |
262 | if ( TString(generator).Contains("pythia6",TString::kIgnoreCase) ) | |
30138a88 | 263 | { |
3e7b6e7b | 264 | fMaxEventsPerChunk = 500; // 5000 is not reasonable with Pythia6 (and ITS+MUON...) |
265 | ||
266 | fCompactMode = 2; // keep AOD as for the time being the filtering driven from AODtrain.C cannot | |
267 | // add SPD tracklets to muon AODs. | |
268 | ||
269 | gSystem->Load("libFASTSIM"); | |
270 | gSystem->Load("liblhapdf"); // Parton density functions | |
271 | gSystem->Load("libEGPythia6"); // TGenerator interface | |
272 | gSystem->Load(Form("libpythia6.%s",generatorVersion)); | |
273 | gSystem->Load("libAliPythia6"); | |
274 | ||
275 | SetVar("VAR_PYTHIA6_INCLUDES","gSystem->AddIncludePath(\"-I$ALICE_ROOT/PYTHIA6 -I$ALICE_ROOT/STEER/STEER -I$ALICE_ROOT/STEER/STEERBase -I$ALICE_ROOT/LHAPDF -I$ALICE_ROOT/FASTSIM\");"); | |
276 | ||
277 | TString p6env; | |
278 | ||
279 | p6env += Form("gSystem->Load(\"libpythia6.%s\");",generatorVersion); | |
280 | ||
281 | SetVar("VAR_PYTHIA6_SETENV",p6env.Data()); | |
282 | ||
283 | SetVar("VAR_USE_ITS_RECO","1"); | |
284 | ||
285 | SetVar("VAR_TRIGGER_CONFIGURATION","p-p"); | |
30138a88 | 286 | } |
3e7b6e7b | 287 | |
b8ebdef6 | 288 | SetVar("VAR_EVENTS_PER_JOB",Form("%i",fMaxEventsPerChunk)); |
289 | ||
1afce1ce | 290 | SetGenerator(generator); |
1afce1ce | 291 | |
30138a88 | 292 | if (localOnly) |
293 | { | |
294 | MakeNofEventsFixed(10); | |
295 | } | |
296 | else | |
297 | { | |
298 | MakeNofEventsPropToTriggerCount(); | |
299 | } | |
1afce1ce | 300 | |
81190958 | 301 | AddToTemplateFileList("CheckESD.C"); |
302 | AddToTemplateFileList("CheckAOD.C"); | |
060f4572 | 303 | AddToTemplateFileList("AODtrainsim.C"); |
304 | // AddToTemplateFileList("validation.sh"); | |
1afce1ce | 305 | |
81190958 | 306 | AddToTemplateFileList("Config.C"); |
307 | AddToTemplateFileList("rec.C"); | |
308 | AddToTemplateFileList("sim.C"); | |
060f4572 | 309 | AddToTemplateFileList("simrun.sh"); |
81190958 | 310 | AddToTemplateFileList(RunJDLName().Data()); |
1afce1ce | 311 | |
81190958 | 312 | UseExternalConfig(fExternalConfig); |
1afce1ce | 313 | } |
314 | ||
a58729a5 | 315 | //______________________________________________________________________________ |
81190958 | 316 | AliMuonAccEffSubmitter::~AliMuonAccEffSubmitter() |
a58729a5 | 317 | { |
81190958 | 318 | // dtor |
a58729a5 | 319 | } |
320 | ||
81190958 | 321 | ///______________________________________________________________________________ |
322 | Bool_t AliMuonAccEffSubmitter::Generate(const char* jdlname) const | |
a58729a5 | 323 | { |
81190958 | 324 | if ( TString(jdlname).Contains("merge",TString::kIgnoreCase) ) |
a58729a5 | 325 | { |
81190958 | 326 | return GenerateMergeJDL(jdlname); |
a58729a5 | 327 | } |
328 | else | |
329 | { | |
81190958 | 330 | return GenerateRunJDL(jdlname); |
a58729a5 | 331 | } |
a58729a5 | 332 | } |
333 | ||
334 | ///______________________________________________________________________________ | |
81190958 | 335 | Bool_t AliMuonAccEffSubmitter::GenerateMergeJDL(const char* name) const |
a58729a5 | 336 | { |
1afce1ce | 337 | /// Create the JDL for merging jobs |
338 | /// FIXME: not checked ! | |
339 | ||
340 | AliDebug(1,""); | |
341 | ||
a58729a5 | 342 | std::ostream* os = CreateJDLFile(name); |
343 | ||
344 | if (!os) | |
345 | { | |
346 | return kFALSE; | |
347 | } | |
348 | ||
349 | Bool_t final = TString(name).Contains("merge",TString::kIgnoreCase); | |
350 | ||
351 | (*os) << "# Generated merging jdl (production mode)" << std::endl | |
352 | << "# $1 = run number" << std::endl | |
353 | << "# $2 = merging stage" << std::endl | |
354 | << "# Stage_<n>.xml made via: find <OutputDir> *Stage<n-1>/*root_archive.zip" << std::endl; | |
355 | ||
81190958 | 356 | OutputToJDL(*os,"Packages", |
357 | GetMapValue("AliRoot"), | |
358 | GetMapValue("Geant3"), | |
359 | GetMapValue("Root"), | |
360 | GetMapValue("API")); | |
a58729a5 | 361 | |
81190958 | 362 | OutputToJDL(*os,"Executable","AOD_merge.sh"); |
a58729a5 | 363 | |
81190958 | 364 | OutputToJDL(*os,"Price","1"); |
a58729a5 | 365 | |
366 | if ( final ) | |
367 | { | |
81190958 | 368 | OutputToJDL(*os,"Jobtag","comment: AliMuonAccEffSubmitter final merging"); |
a58729a5 | 369 | } |
370 | else | |
371 | { | |
81190958 | 372 | OutputToJDL(*os,"Jobtag","comment: AliMuonAccEffSubmitter merging stage $2"); |
a58729a5 | 373 | } |
374 | ||
81190958 | 375 | OutputToJDL(*os,"Workdirectorysize","5000MB"); |
a58729a5 | 376 | |
81190958 | 377 | OutputToJDL(*os,"Validationcommand",Form("%s/validation_merge.sh",RemoteDir().Data())); |
a58729a5 | 378 | |
3e7b6e7b | 379 | OutputToJDL(*os,"TTL","14400"); |
30138a88 | 380 | |
81190958 | 381 | OutputToJDL(*os,"OutputArchive", |
a58729a5 | 382 | "log_archive.zip:stderr,stdout@disk=1", |
383 | "root_archive.zip:AliAOD.root,AliAOD.Muons.root,AnalysisResults.root@disk=3" | |
384 | ); | |
385 | ||
81190958 | 386 | OutputToJDL(*os,"Arguments",(final ? "2":"1")); // for AOD_merge.sh, 1 means intermediate merging stage, 2 means final merging |
a58729a5 | 387 | |
388 | if ( !final ) | |
389 | { | |
060f4572 | 390 | OutputToJDL(*os,"InputFile",Form("LF:%s/AODtrainsim.C",RemoteDir().Data())); |
81190958 | 391 | OutputToJDL(*os,"OutputDir",Form("%s/$1/Stage_$2/#alien_counter_03i#",RemoteDir().Data())); |
392 | OutputToJDL(*os,"InputDataCollection",Form("%s/$1/Stage_$2.xml,nodownload",RemoteDir().Data())); | |
393 | OutputToJDL(*os,"split","se"); | |
394 | OutputToJDL(*os,"SplitMaxInputFileNumber",GetSplitMaxInputFileNumber()); | |
395 | OutputToJDL(*os,"InputDataListFormat","xml-single"); | |
396 | OutputToJDL(*os,"InputDataList","wn.xml"); | |
a58729a5 | 397 | } |
398 | else | |
399 | { | |
060f4572 | 400 | OutputToJDL(*os,"InputFile",Form("LF:%s/AODtrainsim.C",RemoteDir().Data()), |
81190958 | 401 | Form("LF:%s/$1/wn.xml",RemoteDir().Data())); |
402 | OutputToJDL(*os,"OutputDir",Form("%s/$1",RemoteDir().Data())); | |
a58729a5 | 403 | } |
404 | ||
405 | return kTRUE; | |
406 | } | |
407 | ||
408 | //______________________________________________________________________________ | |
81190958 | 409 | Bool_t AliMuonAccEffSubmitter::GenerateRunJDL(const char* name) const |
a58729a5 | 410 | { |
411 | /// Generate (locally) the JDL to perform the simulation+reco+aod filtering | |
412 | /// (to be then copied to the grid and finally submitted) | |
413 | ||
1afce1ce | 414 | AliDebug(1,""); |
415 | ||
a58729a5 | 416 | std::ostream* os = CreateJDLFile(name); |
417 | ||
418 | if (!os) | |
419 | { | |
420 | return kFALSE; | |
421 | } | |
422 | ||
81190958 | 423 | OutputToJDL(*os,"Packages", |
424 | GetMapValue("AliRoot"), | |
425 | GetMapValue("Geant3"), | |
426 | GetMapValue("Root"), | |
427 | GetMapValue("API")); | |
428 | ||
429 | OutputToJDL(*os,"Jobtag","comment: AliMuonAccEffSubmitter RUN $1"); | |
a58729a5 | 430 | |
b8ebdef6 | 431 | OutputToJDL(*os,"split","production:$2-$3"); |
a58729a5 | 432 | |
81190958 | 433 | OutputToJDL(*os,"Price","1"); |
a58729a5 | 434 | |
81190958 | 435 | OutputToJDL(*os,"OutputDir",Form("%s/$1/#alien_counter_03i#",RemoteDir().Data())); |
a58729a5 | 436 | |
81190958 | 437 | OutputToJDL(*os,"Executable","/alice/bin/aliroot_new"); |
a58729a5 | 438 | |
439 | TObjArray files; | |
440 | files.SetOwner(kTRUE); | |
670f3174 | 441 | TIter next(LocalFileList()); |
a58729a5 | 442 | TObjString* file; |
443 | ||
444 | while ( ( file = static_cast<TObjString*>(next())) ) | |
445 | { | |
b8ebdef6 | 446 | if ( !file->String().Contains("jdl",TString::kIgnoreCase) && |
a58729a5 | 447 | !file->String().Contains("OCDB_") ) |
448 | { | |
81190958 | 449 | files.Add(new TObjString(Form("LF:%s/%s",RemoteDir().Data(),file->String().Data()))); |
a58729a5 | 450 | } |
451 | } | |
452 | ||
453 | if ( fUseOCDBSnapshots ) | |
454 | { | |
81190958 | 455 | files.Add(new TObjString(Form("LF:%s/OCDB/$1/OCDB_sim.root",RemoteDir().Data()))); |
456 | files.Add(new TObjString(Form("LF:%s/OCDB/$1/OCDB_rec.root",RemoteDir().Data()))); | |
a58729a5 | 457 | } |
458 | ||
81190958 | 459 | OutputToJDL(*os,"InputFile",files); |
a58729a5 | 460 | |
461 | if ( CompactMode() == 0 ) | |
462 | { | |
463 | // store everything | |
81190958 | 464 | OutputToJDL(*os,"OutputArchive", "log_archive.zip:stderr,stdout,aod.log,checkaod.log,checkesd.log,rec.log,sim.log@disk=1", |
a58729a5 | 465 | "root_archive.zip:galice*.root,Kinematics*.root,TrackRefs*.root,AliESDs.root,AliAOD.root,AliAOD.Muons.root,Merged.QA.Data.root,Run*.root@disk=2"); |
466 | } | |
467 | else if ( CompactMode() == 1 ) | |
468 | { | |
81190958 | 469 | // keep only muon AODs and QA |
3e7b6e7b | 470 | OutputToJDL(*os,"OutputArchive", "log_archive.zip:stderr,stdout,*.log@disk=1", |
ba776170 | 471 | "root_archive.zip:AliAOD.Muons.root,Merged.QA.Data.root@disk=2"); |
a58729a5 | 472 | } |
30138a88 | 473 | else if ( CompactMode() == 2 ) |
474 | { | |
475 | // keep only AODs and QA | |
476 | OutputToJDL(*os,"OutputArchive", "log_archive.zip:stderr,stdout,aod.log,checkaod.log,checkesd.log,rec.log,sim.log@disk=1", | |
477 | "root_archive.zip:galice*.root,AliAOD.root,Merged.QA.Data.root@disk=2"); | |
478 | } | |
a58729a5 | 479 | else |
480 | { | |
481 | AliError(Form("Unknown CompactMode %d",CompactMode())); | |
482 | delete os; | |
483 | return kFALSE; | |
484 | } | |
485 | ||
b8ebdef6 | 486 | OutputToJDL(*os,"splitarguments","--run $1 --event #alien_counter# --eventsPerJob $4"); |
a58729a5 | 487 | |
81190958 | 488 | OutputToJDL(*os,"Workdirectorysize","5000MB"); |
a58729a5 | 489 | |
81190958 | 490 | OutputToJDL(*os,"JDLVariables","Packages","OutputDir"); |
a58729a5 | 491 | |
060f4572 | 492 | OutputToJDL(*os,"Validationcommand","/alice/validation/validation.sh"); |
a58729a5 | 493 | |
30138a88 | 494 | if ( GetVar("VAR_GENERATOR").Contains("pythia",TString::kIgnoreCase) ) |
495 | { | |
496 | OutputToJDL(*os,"TTL","36000"); | |
497 | } | |
498 | else | |
499 | { | |
3e7b6e7b | 500 | OutputToJDL(*os,"TTL","14400"); |
30138a88 | 501 | } |
a58729a5 | 502 | |
503 | return kTRUE; | |
504 | } | |
505 | ||
a58729a5 | 506 | //______________________________________________________________________________ |
507 | Bool_t AliMuonAccEffSubmitter::MakeOCDBSnapshots() | |
508 | { | |
509 | /// Run sim.C and rec.C in a special mode to generate OCDB snapshots | |
510 | /// Can only be done after the templates have been copied locally | |
511 | ||
512 | if (!IsValid()) return kFALSE; | |
513 | ||
514 | if (!fUseOCDBSnapshots) return kTRUE; | |
515 | ||
81190958 | 516 | if (!NofRuns()) return kFALSE; |
a58729a5 | 517 | |
1afce1ce | 518 | AliDebug(1,""); |
519 | ||
a58729a5 | 520 | Bool_t ok(kTRUE); |
521 | ||
81190958 | 522 | const std::vector<int>& runs = RunList(); |
523 | ||
a58729a5 | 524 | for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i ) |
525 | { | |
526 | Int_t runNumber = runs[i]; | |
527 | ||
528 | TString ocdbSim(Form("%s/OCDB/%d/OCDB_sim.root",SnapshotDir().Data(),runNumber)); | |
529 | TString ocdbRec(Form("%s/OCDB/%d/OCDB_rec.root",SnapshotDir().Data(),runNumber)); | |
530 | ||
1afce1ce | 531 | if ( !gSystem->AccessPathName(ocdbSim.Data()) && |
a58729a5 | 532 | !gSystem->AccessPathName(ocdbRec.Data()) ) |
533 | { | |
534 | AliWarning(Form("Local OCDB snapshots already there for run %d. Will not redo them. If you want to force them, delete them by hand !",runNumber)); | |
1afce1ce | 535 | continue; |
a58729a5 | 536 | } |
537 | else | |
538 | { | |
060f4572 | 539 | gSystem->Exec(Form("simrun.sh --run %d --snapshot",runNumber)); |
a58729a5 | 540 | |
541 | if ( gSystem->AccessPathName(ocdbSim.Data()) ) | |
542 | { | |
543 | AliError(Form("Could not create OCDB snapshot for simulation")); | |
544 | ok = kFALSE; | |
545 | } | |
546 | ||
547 | if ( gSystem->AccessPathName(ocdbRec.Data()) ) | |
548 | { | |
549 | AliError(Form("Could not create OCDB snapshot for reconstruction")); | |
550 | ok = kFALSE; | |
551 | } | |
552 | } | |
553 | ||
eb5de7ee | 554 | AddToLocalFileList(ocdbSim); |
555 | AddToLocalFileList(ocdbRec); | |
a58729a5 | 556 | } |
557 | ||
558 | return ok; | |
559 | } | |
560 | ||
561 | //______________________________________________________________________________ | |
562 | Bool_t AliMuonAccEffSubmitter::Merge(Int_t stage, Bool_t dryRun) | |
563 | { | |
564 | /// Submit multiple merging jobs with the format "submit AOD_merge(_final).jdl run# (stage#)". | |
565 | /// Also produce the xml collection before sending jobs | |
566 | /// Initial AODs will be taken from fRemoteDir/[RUNNUMBER] while the merged | |
567 | /// ones will be put into fMergedDir/AODs/[RUNNUMBER] | |
568 | /// | |
569 | /// Example: | |
570 | /// - inDir = "/alice/sim/2012/LHC12a10_bis" (where to find the data to merge) | |
571 | /// = 0x0 --> inDir = homeDir/outDir/resDir | |
572 | /// - outDir = "Sim/LHC11h/embedding/AODs" (where to store merged results) | |
573 | /// - runList.txt must contains the list of run number | |
574 | /// - stage=0 --> final merging / stage>0 --> intermediate merging i | |
575 | /// | |
576 | ||
81190958 | 577 | if (!RemoteDirectoryExists(MergedDir().Data())) { |
578 | AliError(Form("directory %s does not exist", MergedDir().Data())); | |
a58729a5 | 579 | return kFALSE; |
580 | } | |
581 | ||
81190958 | 582 | gGrid->Cd(MergedDir().Data()); |
a58729a5 | 583 | |
584 | TString jdl = MergeJDLName(stage==0); | |
585 | ||
586 | if (!RemoteFileExists(jdl.Data())) | |
587 | { | |
81190958 | 588 | AliError(Form("file %s does not exist in %s\n", jdl.Data(), RemoteDir().Data())); |
a58729a5 | 589 | return kFALSE; |
590 | } | |
591 | ||
81190958 | 592 | const std::vector<int>& runs = RunList(); |
a58729a5 | 593 | |
594 | if (runs.empty()) | |
595 | { | |
596 | AliError("No run to work with"); | |
3e7b6e7b | 597 | return 0; |
a58729a5 | 598 | } |
599 | ||
600 | TString currRun; | |
601 | TString reply = ""; | |
602 | gSystem->Exec("rm -f __failed__"); | |
603 | Bool_t failedRun = kFALSE; | |
604 | ||
605 | for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i ) | |
606 | { | |
607 | Int_t run = runs[i]; | |
608 | AliInfo(Form("\n --- processing run %d ---\n", run)); | |
609 | ||
81190958 | 610 | TString runDir = Form("%s/%d", MergedDir().Data(), run); |
a58729a5 | 611 | |
612 | if (!RemoteDirectoryExists(runDir.Data())) | |
613 | { | |
614 | AliInfo(Form(" - creating output directory %s\n", runDir.Data())); | |
615 | gSystem->Exec(Form("alien_mkdir -p %s", runDir.Data())); | |
616 | } | |
617 | ||
618 | if (RemoteFileExists(Form("%s/root_archive.zip", runDir.Data()))) | |
619 | { | |
620 | AliWarning(" ! final merging already done"); | |
621 | continue; | |
622 | } | |
623 | ||
624 | Int_t lastStage = GetLastStage(runDir.Data()); | |
625 | ||
626 | if (stage > 0 && stage != lastStage+1) | |
627 | { | |
628 | AliError(Form(" ! lastest merging stage = %d. Next must be stage %d or final stage\n", lastStage, lastStage+1)); | |
629 | continue; | |
630 | } | |
631 | ||
632 | TString wn = (stage > 0) ? Form("Stage_%d.xml", stage) : "wn.xml"; | |
633 | TString find = (lastStage == 0) ? | |
81190958 | 634 | Form("alien_find -x %s %s/%d *root_archive.zip", wn.Data(), RemoteDir().Data(), run) : |
635 | Form("alien_find -x %s %s/%d/Stage_%d *root_archive.zip", wn.Data(), RemoteDir().Data(), run, lastStage); | |
a58729a5 | 636 | gSystem->Exec(Form("%s 1> %s 2>/dev/null", find.Data(), wn.Data())); |
637 | gSystem->Exec(Form("grep -c /event %s > __nfiles__", wn.Data())); | |
638 | ifstream f2("__nfiles__"); | |
639 | TString nFiles; | |
640 | nFiles.ReadLine(f2,kTRUE); | |
641 | f2.close(); | |
642 | gSystem->Exec("rm -f __nfiles__"); | |
643 | printf(" - number of files to merge = %d\n", nFiles.Atoi()); | |
644 | if (nFiles.Atoi() == 0) { | |
645 | printf(" ! collection of files to merge is empty\n"); | |
646 | gSystem->Exec(Form("rm -f %s", wn.Data())); | |
647 | continue; | |
648 | } else if (stage > 0 && nFiles.Atoi() <= splitLevel && !reply.BeginsWith("y")) { | |
649 | if (!reply.BeginsWith("n")) { | |
650 | printf(" ! number of files to merge <= split level (%d). Continue? [Y/n] ", splitLevel); | |
651 | fflush(stdout); | |
652 | reply.Gets(stdin,kTRUE); | |
653 | reply.ToLower(); | |
654 | } | |
655 | if (reply.BeginsWith("n")) { | |
656 | gSystem->Exec(Form("rm -f %s", wn.Data())); | |
657 | continue; | |
658 | } else reply = "y"; | |
659 | } | |
660 | ||
661 | if (!dryRun) | |
662 | { | |
663 | TString dirwn = Form("%s/%s", runDir.Data(), wn.Data()); | |
664 | if (RemoteFileExists(dirwn.Data())) gGrid->Rm(dirwn.Data()); | |
665 | gSystem->Exec(Form("alien_cp file:%s alien://%s", wn.Data(), dirwn.Data())); | |
666 | gSystem->Exec(Form("rm -f %s", wn.Data())); | |
667 | } | |
668 | ||
669 | TString query; | |
670 | if (stage > 0) query = Form("submit %s %d %d", jdl.Data(), run, stage); | |
671 | else query = Form("submit %s %d", jdl.Data(), run); | |
672 | printf(" - %s ...", query.Data()); | |
673 | fflush(stdout); | |
674 | ||
675 | if (dryRun) | |
676 | { | |
677 | AliInfo(" dry run"); | |
678 | continue; | |
679 | } | |
680 | ||
681 | Bool_t done = kFALSE; | |
682 | TGridResult *res = gGrid->Command(query); | |
683 | if (res) | |
684 | { | |
685 | TString cjobId1 = res->GetKey(0,"jobId"); | |
686 | if (!cjobId1.IsDec()) | |
687 | { | |
688 | AliError(" FAILED"); | |
689 | gGrid->Stdout(); | |
690 | gGrid->Stderr(); | |
691 | } | |
692 | else | |
693 | { | |
694 | AliInfo(Form(" DONE\n --> the job Id is: %s \n", cjobId1.Data())); | |
695 | done = kTRUE; | |
696 | } | |
697 | delete res; | |
698 | } | |
699 | else | |
700 | { | |
701 | AliError(" FAILED"); | |
702 | } | |
703 | ||
704 | if (!done) | |
705 | { | |
706 | gSystem->Exec(Form("echo %d >> __failed__", run)); | |
707 | failedRun = kTRUE; | |
708 | } | |
709 | ||
710 | } | |
711 | ||
712 | if (failedRun) | |
713 | { | |
714 | AliInfo("\n--------------------\n"); | |
715 | AliInfo("list of failed runs:\n"); | |
716 | gSystem->Exec("cat __failed__"); | |
717 | gSystem->Exec("rm -f __failed__"); | |
718 | return kFALSE; | |
719 | } | |
720 | ||
721 | return kTRUE; | |
722 | } | |
723 | ||
724 | //______________________________________________________________________________ | |
81190958 | 725 | void AliMuonAccEffSubmitter::Print(Option_t* opt) const |
a58729a5 | 726 | { |
1afce1ce | 727 | /// Printout |
728 | ||
81190958 | 729 | AliMuonGridSubmitter::Print(opt); |
730 | ||
a58729a5 | 731 | if ( fRatio > 0 ) |
732 | { | |
30138a88 | 733 | std::cout << std::endl << Form("-- For each run, will generate %5.2f times the number of real events for trigger %s", |
81190958 | 734 | fRatio,ReferenceTrigger().Data()) << std::endl; |
a58729a5 | 735 | } |
736 | else | |
737 | { | |
30138a88 | 738 | std::cout << std::endl << Form("-- For each run, will generate %10d events",fFixedNofEvents) << std::endl; |
a58729a5 | 739 | } |
740 | ||
30138a88 | 741 | std::cout << "-- MaxEventsPerChunk = " << fMaxEventsPerChunk << std::endl; |
a58729a5 | 742 | |
30138a88 | 743 | std::cout << "-- Will" << (fUseOCDBSnapshots ? "" : " NOT") << " use OCDB snaphosts" << std::endl; |
a58729a5 | 744 | } |
745 | ||
746 | //______________________________________________________________________________ | |
747 | Bool_t AliMuonAccEffSubmitter::Run(const char* mode) | |
748 | { | |
749 | /// mode can be one of (case insensitive) | |
750 | /// | |
751 | /// LOCAL : copy the template files from the template directory to the local one | |
752 | /// UPLOAD : copy the local files to the grid (requires LOCAL) | |
753 | /// OCDB : make ocdb snapshots (requires LOCAL) | |
754 | /// SUBMIT : submit the jobs (requires LOCAL + UPLOAD) | |
755 | /// FULL : all of the above (requires all of the above) | |
756 | /// | |
757 | /// TEST : as SUBMIT, but in dry mode (does not actually submit the jobs) | |
eb5de7ee | 758 | /// |
759 | /// LOCALTEST : completely local test (including execution) | |
a58729a5 | 760 | |
761 | if (!IsValid()) return kFALSE; | |
762 | ||
a2e95afc | 763 | if ( fCompactMode == 1 ) SetVar("VAR_AOD_MERGE_FILES","\"AliAOD.Muons.root\""); |
764 | ||
a58729a5 | 765 | TString smode(mode); |
766 | smode.ToUpper(); | |
767 | ||
768 | if ( smode == "FULL") | |
769 | { | |
770 | return ( Run("LOCAL") && Run("OCDB") && Run("UPLOAD") && Run("SUBMIT") ); | |
771 | } | |
772 | ||
773 | if ( smode == "LOCAL") | |
774 | { | |
775 | return CopyTemplateFilesToLocal(); | |
776 | } | |
777 | ||
778 | if ( smode == "UPLOAD" ) | |
779 | { | |
780 | return (CopyLocalFilesToRemote()); | |
781 | } | |
782 | ||
783 | if ( smode == "OCDB" ) | |
784 | { | |
785 | Bool_t ok = Run("LOCAL"); | |
786 | if (ok) | |
787 | { | |
788 | ok = MakeOCDBSnapshots(); | |
789 | } | |
790 | return ok; | |
791 | } | |
792 | ||
793 | if ( smode == "TEST" ) | |
794 | { | |
795 | Bool_t ok = Run("LOCAL") && Run("OCDB") && Run("UPLOAD"); | |
796 | if ( ok ) | |
797 | { | |
798 | ok = (Submit(kTRUE)>0); | |
799 | } | |
800 | return ok; | |
801 | } | |
802 | ||
803 | if ( smode == "FULL" ) | |
804 | { | |
805 | Bool_t ok = Run("LOCAL") && Run("OCDB") && Run("UPLOAD"); | |
806 | if ( ok ) | |
807 | { | |
808 | ok = (Submit(kFALSE)>0); | |
809 | } | |
810 | return ok; | |
811 | } | |
812 | ||
813 | if( smode == "SUBMIT" ) | |
814 | { | |
815 | return (Submit(kFALSE)>0); | |
816 | } | |
817 | ||
eb5de7ee | 818 | if ( smode == "LOCALTEST" ) |
819 | { | |
820 | Bool_t ok = Run("LOCAL"); | |
821 | if ( ok ) | |
822 | { | |
823 | ok = LocalTest(); | |
824 | } | |
825 | return ok; | |
826 | } | |
827 | ||
a58729a5 | 828 | return kFALSE; |
829 | } | |
830 | ||
1afce1ce | 831 | //______________________________________________________________________________ |
832 | Bool_t AliMuonAccEffSubmitter::SetGenerator(const char* generator) | |
833 | { | |
834 | // set the variable to select the generator macro in Config.C | |
835 | ||
836 | gSystem->Load("libEVGEN"); | |
1afce1ce | 837 | |
81190958 | 838 | Invalidate(); |
839 | ||
840 | TString generatorFile(Form("%s/%s.C",TemplateDir().Data(),generator)); | |
1afce1ce | 841 | |
842 | Int_t nofMissingVariables(0); | |
843 | ||
844 | // first check we indeed have such a macro | |
845 | if (!gSystem->AccessPathName(generatorFile.Data())) | |
846 | { | |
847 | TObjArray* variables = GetVariables(generatorFile.Data()); | |
848 | ||
849 | TIter next(variables); | |
850 | TObjString* var; | |
851 | ||
852 | while ( ( var = static_cast<TObjString*>(next())) ) | |
853 | { | |
81190958 | 854 | if ( !Vars()->GetValue(var->String()) ) |
1afce1ce | 855 | { |
856 | ++nofMissingVariables; | |
857 | AliError(Form("file %s expect the variable %s to be defined, but we've not defined it !",generatorFile.Data(),var->String().Data())); | |
858 | } | |
859 | } | |
860 | ||
861 | delete variables; | |
862 | ||
863 | if ( !nofMissingVariables ) | |
864 | { | |
865 | if (CheckCompilation(generatorFile.Data())) | |
866 | { | |
81190958 | 867 | Validate(); |
1afce1ce | 868 | SetVar("VAR_GENERATOR",Form("%s",generator)); |
81190958 | 869 | AddToTemplateFileList(Form("%s.C",generator)); |
1afce1ce | 870 | return kTRUE; |
871 | } | |
872 | } | |
873 | else | |
874 | { | |
875 | return kFALSE; | |
876 | } | |
877 | } | |
878 | else | |
879 | { | |
880 | AliError(Form("Can not work with the macro %s",generatorFile.Data())); | |
881 | } | |
882 | return kFALSE; | |
883 | } | |
884 | ||
1afce1ce | 885 | //______________________________________________________________________________ |
886 | void AliMuonAccEffSubmitter::SetOCDBPath(const char* ocdbPath) | |
887 | { | |
888 | /// Sets the OCDB path to be used | |
889 | ||
81190958 | 890 | SetMapKeyValue("OCDBPath",ocdbPath); |
1afce1ce | 891 | } |
892 | ||
893 | ||
894 | //______________________________________________________________________________ | |
895 | void AliMuonAccEffSubmitter::SetOCDBSnapshotDir(const char* dir) | |
896 | { | |
897 | // change the directory used for snapshot | |
898 | ||
899 | if (gSystem->AccessPathName(Form("%s/OCDB",dir))) | |
900 | { | |
901 | AliError(Form("Snapshot top directory (%s) should contain an OCDB subdir with runnumbers in there",dir)); | |
902 | } | |
903 | else | |
904 | { | |
81190958 | 905 | SetMapKeyValue("OCDBSnapshot",dir); |
1afce1ce | 906 | } |
907 | } | |
908 | ||
a58729a5 | 909 | //______________________________________________________________________________ |
81190958 | 910 | void AliMuonAccEffSubmitter::MakeNofEventsPropToTriggerCount(const char* trigger, Float_t ratio) |
a58729a5 | 911 | { |
81190958 | 912 | SetMapKeyValue("ReferenceTrigger",trigger); |
913 | fRatio = ratio; | |
914 | } | |
915 | ||
916 | //______________________________________________________________________________ | |
917 | void AliMuonAccEffSubmitter::MakeNofEventsFixed(Int_t nevents) | |
918 | { | |
919 | fFixedNofEvents = nevents; | |
920 | fRatio=0.0; | |
921 | SetMapKeyValue("ReferenceTrigger",""); | |
a58729a5 | 922 | } |
923 | ||
eb5de7ee | 924 | //______________________________________________________________________________ |
925 | Int_t AliMuonAccEffSubmitter::LocalTest() | |
926 | { | |
927 | /// Generate a local macro (simrun.sh) to execute locally a full scale test | |
928 | /// Can only be used with a fixed number of events (and runnumber is fixed to zero) | |
929 | ||
930 | if ( fRatio > 0 ) | |
931 | { | |
932 | AliError("Can only work in local test with a fixed number of events"); | |
933 | return 0; | |
934 | } | |
935 | ||
936 | if ( fFixedNofEvents <= 0 ) | |
937 | { | |
938 | AliError("Please fix the number of input events using MakeNofEventsFixed()"); | |
939 | return 0; | |
940 | } | |
8907673b | 941 | |
942 | const std::vector<int>& runs = RunList(); | |
eb5de7ee | 943 | |
3e7b6e7b | 944 | if ( runs.empty() ) |
945 | { | |
946 | AliError("No run to work with"); | |
947 | return 0; | |
948 | } | |
949 | ||
060f4572 | 950 | // std::cout << "Generating script to execute : ./simrun.sh" << std::endl; |
951 | // | |
952 | // std::ofstream out("simrun.sh"); | |
953 | // | |
954 | // out << "#!/bin/bash" << std::endl; | |
955 | //// root.exe -b -q simrun.C --run <x> --chunk <y> --event <n> | |
956 | // out << "root.exe -b -q simrun.C --run "<< runs[0] <<" --event " << fFixedNofEvents << std::endl; | |
957 | // | |
958 | // out.close(); | |
f9208637 | 959 | |
eb5de7ee | 960 | gSystem->Exec("chmod +x simrun.sh"); |
b8ebdef6 | 961 | gSystem->Exec("alien_cp alien:///alice/bin/aliroot_new file:"); |
962 | gSystem->Exec("chmod u+x aliroot_new"); | |
3e7b6e7b | 963 | |
964 | std::cout << "Cleaning up left-over files from previous simulation/reconstructions" << std::endl; | |
b8ebdef6 | 965 | |
3e7b6e7b | 966 | gSystem->Exec("rm -rf TrackRefs.root *.SDigits*.root Kinematics.root *.Hits.root geometry.root gphysi.dat Run*.tag.root HLT*.root *.ps *.Digits.root *.RecPoints.root galice.root *QA*.root Trigger.root *.log AliESD* AliAOD* *.d *.so *.stat"); |
967 | ||
b8ebdef6 | 968 | TString command = Form("./aliroot_new --run %i --event 1 --eventsPerJob %i", runs[0], fFixedNofEvents); |
060f4572 | 969 | |
970 | std::cout << "Executing the script : " << command.Data() << std::endl; | |
eb5de7ee | 971 | |
3e7b6e7b | 972 | |
060f4572 | 973 | gSystem->Exec(command.Data()); |
eb5de7ee | 974 | |
975 | return 1; | |
976 | } | |
81190958 | 977 | |
3e7b6e7b | 978 | namespace { |
979 | ||
980 | void OutputRunList(const char* filename, const std::vector<int>& runlist) | |
981 | { | |
982 | /// output a runlist to ASCII file | |
983 | ||
984 | std::ofstream out(filename); | |
985 | ||
986 | for ( std::vector<int>::size_type j = 0; j < runlist.size(); ++j ) | |
987 | { | |
988 | out << runlist[j] << std::endl; | |
989 | } | |
990 | } | |
991 | } | |
992 | ||
993 | //______________________________________________________________________________ | |
994 | Int_t AliMuonAccEffSubmitter::SplitRunList(const char* inputList, int maxJobs) | |
995 | { | |
996 | /// In order to be able to submit, split a given runlist into chunks that will | |
997 | /// fit within maxJobs (1500 for a typical user) | |
998 | ||
999 | std::vector<int> runs; | |
1000 | ||
1001 | AliAnalysisTriggerScalers tmp(inputList); | |
1002 | runs = tmp.GetRunList(); | |
1003 | ||
1004 | AliAnalysisTriggerScalers* ts(0x0); | |
1005 | std::vector<int> currentRunList; | |
1006 | ||
1007 | int nJobs(0); | |
1008 | int nTotalJobs(0); | |
1009 | int nEvts(0); | |
1010 | int nFiles(0); | |
1011 | ||
1012 | for (std::vector<int>::size_type i=0; i < runs.size(); ++i) | |
1013 | { | |
1014 | Int_t runNumber = runs[i]; | |
1015 | ||
1016 | Int_t nEvtRun(fFixedNofEvents); | |
1017 | ||
1018 | if ( fRatio > 0 ) | |
1019 | { | |
1020 | if (!ts) | |
1021 | { | |
1022 | AliInfo(Form("Creating AliAnalysisTriggerScalers from OCDB=%s",OCDBPath().Data())); | |
1023 | ts = new AliAnalysisTriggerScalers(runs,OCDBPath().Data()); | |
1024 | } | |
1025 | ||
1026 | AliAnalysisTriggerScalerItem* trigger = ts->GetTriggerScaler(runNumber, "L2A", ReferenceTrigger().Data()); | |
1027 | ||
1028 | if (!trigger) | |
1029 | { | |
1030 | AliError(Form("Could not get trigger %s for run %09d",ReferenceTrigger().Data(),runNumber)); | |
1031 | continue; | |
1032 | } | |
1033 | nEvtRun = TMath::Nint(fRatio * trigger->Value()); | |
1034 | } | |
1035 | ||
1036 | Int_t nChunk = 1; | |
1037 | ||
1038 | while (nEvtRun/nChunk+0.5 > MaxEventsPerChunk()) | |
1039 | { | |
1040 | ++nChunk; | |
1041 | } | |
1042 | ||
1043 | Int_t nEvtChunk = TMath::Nint(nEvtRun/nChunk + 0.5); | |
1044 | ||
1045 | nJobs += nChunk; | |
1046 | ||
1047 | nTotalJobs += nChunk; | |
1048 | ||
1049 | nEvts += nChunk*nEvtChunk; | |
1050 | ||
1051 | if ( nJobs > maxJobs ) | |
1052 | { | |
1053 | ++nFiles; | |
1054 | ||
1055 | OutputRunList(Form("%s.%d",inputList,nFiles),currentRunList); | |
1056 | nJobs = 0; | |
1057 | currentRunList.clear(); | |
1058 | } | |
1059 | ||
1060 | ||
1061 | currentRunList.push_back(runNumber); | |
1062 | ||
1063 | } | |
1064 | ||
1065 | if ( !currentRunList.empty() ) | |
1066 | { | |
1067 | ++nFiles; | |
1068 | OutputRunList(Form("%s.%d",inputList,nFiles),currentRunList); | |
1069 | ||
1070 | } | |
1071 | ||
1072 | delete ts; | |
1073 | ||
1074 | std::cout << Form("input run list was split into %d files. Total number of jobs %d. Total number of events %d", | |
1075 | nFiles,nTotalJobs,nEvts) << std::endl; | |
1076 | ||
1077 | return nFiles; | |
1078 | } | |
1079 | ||
1080 | ||
a58729a5 | 1081 | //______________________________________________________________________________ |
1082 | Int_t AliMuonAccEffSubmitter::Submit(Bool_t dryRun) | |
1083 | { | |
1084 | /// Submit multiple production jobs with the format "submit jdl 000run#.xml 000run#". | |
1085 | /// | |
1086 | /// Return the number of submitted (master) jobs | |
1087 | /// | |
1088 | /// Example: | |
1089 | /// - outputDir = "/alice/cern.ch/user/p/ppillot/Sim/LHC10h/JPsiPbPb276/AlignRawVtxRaw/ESDs" | |
1090 | /// - runList must contains the list of run number | |
1091 | /// - trigger is the (fully qualified) trigger name used to compute the base number of events | |
1092 | /// - mult is the factor to apply to the number of trigger to get the number of events to be generated | |
1093 | /// (# generated events = # triggers x mult | |
1094 | ||
1095 | if (!IsValid()) return 0; | |
1096 | ||
1afce1ce | 1097 | AliDebug(1,""); |
1098 | ||
a58729a5 | 1099 | gGrid->Cd(RemoteDir()); |
1100 | ||
1101 | if (!RemoteFileExists(RunJDLName())) | |
1102 | { | |
1103 | AliError(Form("file %s does not exist in %s", RunJDLName().Data(), RemoteDir().Data())); | |
1104 | return 0; | |
1105 | } | |
1106 | ||
81190958 | 1107 | if ( !NofRuns() ) |
a58729a5 | 1108 | { |
1109 | AliError("No run list set. Use SetRunList"); | |
1110 | return 0; | |
1111 | } | |
81190958 | 1112 | const std::vector<int>& runs = RunList(); |
a58729a5 | 1113 | |
1114 | if (runs.empty()) | |
1115 | { | |
1116 | AliError("No run to work with"); | |
1117 | return 0; | |
1118 | } | |
1119 | ||
1120 | // cout << "total number of selected MB events = " << totEvt << endl; | |
1121 | // cout << "required number of generated events = " << nGenEvents << endl; | |
1122 | // cout << "number of generated events per MB event = " << ratio << endl; | |
1123 | // cout << endl; | |
1124 | ||
b8ebdef6 | 1125 | std::cout << "run\tfirstChunk\tlastChunk\teventsPerJob" << std::endl; |
a58729a5 | 1126 | std::cout << "----------------------" << std::endl; |
1127 | ||
1128 | Int_t nJobs(0); | |
1129 | Int_t nEvts(0); | |
1130 | ||
81190958 | 1131 | AliAnalysisTriggerScalers* ts(0x0); |
1132 | ||
a58729a5 | 1133 | for (std::vector<int>::size_type i=0; i < runs.size(); ++i) |
1134 | { | |
1135 | Int_t runNumber = runs[i]; | |
1136 | ||
1137 | Int_t nEvtRun(fFixedNofEvents); | |
1138 | ||
1139 | if ( fRatio > 0 ) | |
1140 | { | |
81190958 | 1141 | if (!ts) |
1142 | { | |
1143 | AliInfo(Form("Creating AliAnalysisTriggerScalers from OCDB=%s",OCDBPath().Data())); | |
1144 | ts = new AliAnalysisTriggerScalers(runs,OCDBPath().Data()); | |
1145 | } | |
1146 | ||
1147 | AliAnalysisTriggerScalerItem* trigger = ts->GetTriggerScaler(runNumber, "L2A", ReferenceTrigger().Data()); | |
a58729a5 | 1148 | |
1149 | if (!trigger) | |
1150 | { | |
1151 | AliError(Form("Could not get trigger %s for run %09d",ReferenceTrigger().Data(),runNumber)); | |
1152 | continue; | |
1153 | } | |
1154 | nEvtRun = TMath::Nint(fRatio * trigger->Value()); | |
1155 | } | |
1156 | ||
1157 | Int_t nChunk = 1; | |
1158 | ||
1159 | while (nEvtRun/nChunk+0.5 > MaxEventsPerChunk()) | |
1160 | { | |
1161 | ++nChunk; | |
1162 | } | |
1163 | ||
1164 | Int_t nEvtChunk = TMath::Nint(nEvtRun/nChunk + 0.5); | |
1165 | ||
1166 | nJobs += nChunk; | |
1167 | ||
1168 | nEvts += nChunk*nEvtChunk; | |
1169 | ||
b8ebdef6 | 1170 | std::cout << runNumber << "\t1\t" << nChunk << "\t" << nEvtChunk << std::endl; |
a58729a5 | 1171 | |
b8ebdef6 | 1172 | TString query(Form("submit %s %d 1 %d %d", RunJDLName().Data(), runNumber, nChunk, nEvtChunk)); |
a58729a5 | 1173 | |
1174 | std::cout << query.Data() << " ..." << std::flush; | |
1175 | ||
1176 | TGridResult* res = 0x0; | |
1177 | ||
1178 | if (!dryRun) | |
1179 | { | |
1180 | res = gGrid->Command(query); | |
1181 | } | |
1182 | ||
1183 | if (res) | |
1184 | { | |
1185 | TString cjobId1 = res->GetKey(0,"jobId"); | |
1186 | ||
1187 | if (!cjobId1.Length()) | |
1188 | { | |
1189 | std::cout << " FAILED" << std::endl << std::endl; | |
1190 | gGrid->Stdout(); | |
1191 | gGrid->Stderr(); | |
1192 | } | |
1193 | else | |
1194 | { | |
1195 | std::cout << "DONE" << std::endl; | |
1196 | std::cout << Form(" --> the job Id is: %s",cjobId1.Data()) << std::endl << std::endl; | |
1197 | } | |
1198 | } | |
1199 | else | |
1200 | { | |
1201 | std::cout << " FAILED" << std::endl << std::endl; | |
1202 | } | |
1203 | ||
1204 | delete res; | |
1205 | } | |
1206 | ||
1207 | std::cout << std::endl | |
1208 | << "total number of jobs = " << nJobs << std::endl | |
1209 | << "total number of generated events = " << nEvts << std::endl | |
1210 | << std::endl; | |
1211 | ||
81190958 | 1212 | delete ts; |
a58729a5 | 1213 | |
81190958 | 1214 | return nJobs; |
a58729a5 | 1215 | } |
1216 | ||
1217 | //______________________________________________________________________________ | |
1218 | void AliMuonAccEffSubmitter::UpdateLocalFileList(Bool_t clearSnapshots) | |
1219 | { | |
1afce1ce | 1220 | /// Update the list of local files |
1221 | ||
81190958 | 1222 | AliMuonGridSubmitter::UpdateLocalFileList(); |
1223 | ||
1224 | if (!NofRuns()) return; | |
a58729a5 | 1225 | |
1226 | if ( clearSnapshots ) | |
1227 | { | |
1228 | TIter next(LocalFileList()); | |
1229 | TObjString* file; | |
1230 | ||
1231 | while ( ( file = static_cast<TObjString*>(next())) ) | |
1232 | { | |
1233 | if ( file->String().Contains("OCDB_") ) | |
1234 | { | |
1235 | LocalFileList()->Remove(file); | |
1236 | } | |
1237 | } | |
1238 | LocalFileList()->Compress(); | |
1239 | } | |
1240 | ||
a58729a5 | 1241 | const char* type[] = { "sim","rec" }; |
1242 | ||
81190958 | 1243 | const std::vector<int>& runs = RunList(); |
1244 | ||
a58729a5 | 1245 | for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i ) |
1246 | { | |
1247 | Int_t runNumber = runs[i]; | |
1248 | ||
1249 | for ( Int_t t = 0; t < 2; ++t ) | |
1250 | { | |
1251 | TString snapshot(Form("%s/OCDB/%d/OCDB_%s.root",SnapshotDir().Data(),runNumber,type[t])); | |
1252 | ||
1253 | if ( !gSystem->AccessPathName(snapshot.Data()) ) | |
1254 | { | |
eb5de7ee | 1255 | AddToLocalFileList(snapshot); |
a58729a5 | 1256 | } |
1257 | } | |
1258 | } | |
a58729a5 | 1259 | } |
1260 | ||
1261 | //______________________________________________________________________________ | |
1262 | void AliMuonAccEffSubmitter::UseOCDBSnapshots(Bool_t flag) | |
1263 | { | |
1afce1ce | 1264 | /// Whether or not to use OCDB snapshots |
1265 | /// Using OCDB snapshots will speed-up both the sim and reco initialization | |
1266 | /// phases on each worker node, but takes time to produce... | |
1267 | /// So using them is not always a win-win... | |
1268 | ||
a58729a5 | 1269 | fUseOCDBSnapshots = flag; |
1270 | if ( flag ) | |
1271 | { | |
1272 | SetVar("VAR_OCDB_SNAPSHOT","kTRUE"); | |
30138a88 | 1273 | |
1274 | // for some reason must include ITS objects in the snapshot | |
1275 | // (to be able to instantiante the vertexer later on ?) | |
1276 | ||
1277 | SetVar("VAR_USE_ITS_RECO","1"); | |
a58729a5 | 1278 | } |
1279 | else | |
1280 | { | |
1281 | SetVar("VAR_OCDB_SNAPSHOT","kFALSE"); | |
1282 | } | |
1283 | ||
1284 | UpdateLocalFileList(); | |
1285 | } | |
1286 | ||
a3c2a88b | 1287 | //______________________________________________________________________________ |
1288 | void AliMuonAccEffSubmitter::UseAODMerging(Bool_t flag) | |
1289 | { | |
1290 | /// whether or not we should generate JDL for merging AODs | |
1291 | ||
1292 | fUseAODMerging = flag; | |
81190958 | 1293 | |
1294 | AddToTemplateFileList(MergeJDLName(kFALSE).Data()); | |
1295 | AddToTemplateFileList(MergeJDLName(kTRUE).Data()); | |
1296 | AddToTemplateFileList("AOD_merge.sh"); | |
1297 | AddToTemplateFileList("validation_merge.sh"); | |
1298 | } | |
1299 | ||
1300 | //______________________________________________________________________________ | |
1301 | void AliMuonAccEffSubmitter::UseExternalConfig(const char* externalConfigFullFilePath) | |
1302 | { | |
1303 | // use an external config (or the default Config.C if externalConfigFullFilePath="") | |
1304 | ||
1305 | fExternalConfig = externalConfigFullFilePath; | |
1306 | if ( fExternalConfig.Length() > 0 ) | |
1307 | { | |
1308 | AddToTemplateFileList(fExternalConfig); | |
1309 | } | |
1310 | else | |
1311 | { | |
1312 | AddToTemplateFileList("Config.C"); | |
1313 | } | |
a3c2a88b | 1314 | } |