]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG/muondep/AccEffTemplates/AODtrain.C
A customizable LHAPDF and MC mode option for AODtrain.C
[u/mrichter/AliRoot.git] / PWG / muondep / AccEffTemplates / AODtrain.C
CommitLineData
b7a421b8 1// ### Settings that make sense when using the Alien plugin
2//==============================================================================
3Int_t runOnData = 1; // Set to 1 if processing real data
4Int_t iCollision = 1; // 0=pp, 1=Pb-Pb
5//==============================================================================
6Bool_t usePhysicsSelection = kFALSE; // use physics selection
7Bool_t useTender = kFALSE; // use tender wagon
8Bool_t useCentrality = kFALSE; // centrality
9Bool_t useV0tender = kFALSE; // use V0 correction in tender
10Bool_t useDBG = kFALSE; // activate debugging
11Bool_t useMC = kTRUE; // use MC info
12Bool_t useKFILTER = kTRUE; // use Kinematics filter
13Bool_t useTR = kTRUE; // use track references
14Bool_t useCORRFW = kFALSE; // do not change
15Bool_t useAODTAGS = kFALSE; // use AOD tags
16Bool_t useSysInfo = kFALSE; // use sys info
17
18// ### Analysis modules to be included. Some may not be yet fully implemented.
19//==============================================================================
20Int_t iAODhandler = 1; // Analysis produces an AOD or dAOD's
21Int_t iESDMCLabelAddition= 1;
22Int_t iESDfilter = 1; // ESD to AOD filter (barrel + muon tracks)
23Int_t iMUONcopyAOD = 1; // Task that copies only muon events in a separate AOD (PWG3)
24Int_t iMUONRefit = 0; // Refit ESD muon tracks before producing AODs
25Int_t iMUONPerformance = 0; // Task to study the muon performances in MC simulation
26Int_t iMUONEfficiency = 0; // Task to measure the muon efficiency
27Int_t iJETAN = 0; // Jet analysis (PWG4)
28Int_t iJETANdelta = 0; // Jet delta AODs
29Int_t iPWG3vertexing = 0; // Vertexing HF task (PWG3)
30Int_t iPWG3JPSIfilter = 0; // JPSI filtering (PWG3)
31Int_t iPWG3d2h = 0; // D0->2 hadrons (PWG3)
32
33// ### Configuration macros used for each module
34//==============================================================================
35TString configPWG3d2h = (iCollision==0)?"$ALICE_ROOT/PWG3/vertexingHF/ConfigVertexingHF.C"
36:"$ALICE_ROOT/PWG3/vertexingHF/ConfigVertexingHF_highmult.C";
37
38// Temporaries.
39class AliOADBPhysicsSelection;
40AliOADBPhysicsSelection *CreateOADBphysicsSelection();
41void AODmerge();
42void AddAnalysisTasks(Int_t);
43Bool_t LoadCommonLibraries();
44Bool_t LoadAnalysisLibraries();
45Bool_t LoadLibrary(const char *);
46TChain *CreateChain();
47
48//______________________________________________________________________________
49void AODtrain(Int_t merge=0)
50{
51 // Main analysis train macro.
52 // merge = 0: production
53 // merge = 1: intermediate merging
54 // merge = 2: final merging + terminate
55
56 if (merge) {
57 TGrid::Connect("alien://");
58 if (!gGrid || !gGrid->IsConnected()) {
59 ::Error("QAtrain", "No grid connection");
60 return;
61 }
62 }
63 // Set temporary merging directory to current one
64 gSystem->Setenv("TMPDIR", gSystem->pwd());
65 // Set temporary compilation directory to current one
66 gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
67 printf("==================================================================\n");
68 printf("=========== RUNNING FILTERING TRAIN ==========\n");
69 printf("==================================================================\n");
70 printf("= Configuring analysis train for: =\n");
71 if (usePhysicsSelection) printf("= Physics selection =\n");
72 if (useTender) printf("= TENDER =\n");
73 if (iESDfilter) printf("= ESD filter =\n");
74 if (iMUONcopyAOD) printf("= MUON copy AOD =\n");
75 if (iJETAN) printf("= Jet analysis =\n");
76 if (iJETANdelta) printf("= Jet delta AODs =\n");
77 if (iPWG3vertexing) printf("= PWG3 vertexing =\n");
78 if (iPWG3JPSIfilter) printf("= PWG3 j/psi filter =\n");
79 if (iPWG3d2h) printf("= PWG3 D0->2 hadrons QA =\n");
80
81 // Load common libraries and set include path
82 if (!LoadCommonLibraries()) {
83 ::Error("AnalysisTrain", "Could not load common libraries");
84 return;
85 }
86
87 // Make the analysis manager and connect event handlers
88 AliAnalysisManager *mgr = new AliAnalysisManager("Analysis Train", "Production train");
89 if (useSysInfo) mgr->SetNSysInfo(100);
90 // Load analysis specific libraries
91 if (!LoadAnalysisLibraries()) {
92 ::Error("AnalysisTrain", "Could not load analysis libraries");
93 return;
94 }
95
96 // Create input handler (input container created automatically)
97 // ESD input handler
98 AliESDInputHandler *esdHandler = new AliESDInputHandler();
99 mgr->SetInputEventHandler(esdHandler);
100 // Monte Carlo handler
101 if (useMC) {
102 AliMCEventHandler* mcHandler = new AliMCEventHandler();
103 mgr->SetMCtruthEventHandler(mcHandler);
104 mcHandler->SetReadTR(useTR);
105 }
106 // AOD output container, created automatically when setting an AOD handler
107 if (iAODhandler) {
108 // AOD output handler
109 AliAODHandler* aodHandler = new AliAODHandler();
110 aodHandler->SetOutputFileName("AliAOD.root");
111 mgr->SetOutputEventHandler(aodHandler);
112 }
113 // Debugging if needed
114 if (useDBG) mgr->SetDebugLevel(3);
115
116 AddAnalysisTasks(merge);
117 if (merge) {
118 AODmerge();
119 if (merge > 1) {
120 mgr->InitAnalysis();
121 mgr->SetGridHandler(new AliAnalysisAlien());
122 mgr->StartAnalysis("grid terminate",0);
123 }
124 return;
125 }
126 // Run the analysis
127 //
128 TChain *chain = CreateChain();
129 if (!chain) return;
130
131 TStopwatch timer;
132 timer.Start();
133 mgr->SetSkipTerminate(kTRUE);
134 if (mgr->InitAnalysis()) {
135 mgr->PrintStatus();
136 mgr->StartAnalysis("local", chain);
137 }
138 timer.Print();
139}
140
141//______________________________________________________________________________
142void AddAnalysisTasks(Int_t merge){
143 // Add all analysis task wagons to the train
144 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
145
146 //
147 // Tender and supplies. Needs to be called for every event.
148 //
149 //AliAnalysisManager::SetCommonFileName("AODQA.root");
150 if (useTender) {
151 gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/TenderSupplies/AddTaskTender.C");
152 // IF V0 tender needed, put kTRUE below
153 AliAnalysisTaskSE *tender = AddTaskTender(useV0tender);
154 // tender->SetDebugLevel(2);
155 }
156
157 if (usePhysicsSelection) {
158 // Physics selection task
159 gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
160 mgr->RegisterExtraFile("event_stat.root");
161 AliPhysicsSelectionTask *physSelTask = AddTaskPhysicsSelection(kFALSE);
162 // AliOADBPhysicsSelection * oadbDefaultPbPb = CreateOADBphysicsSelection();
163 // physSelTask->GetPhysicsSelection()->SetCustomOADBObjects(oadbDefaultPbPb,0,0);
164 // if (!merge) mgr->AddStatisticsTask(AliVEvent::kAny);
165 }
166 // Centrality (only Pb-Pb)
167 if (iCollision && useCentrality) {
168 gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
169 AliCentralitySelectionTask *taskCentrality = AddTaskCentrality();
170 taskCentrality->SelectCollisionCandidates(AliVEvent::kAny);
171 }
172
173 if (iMUONRefit) {
174 gROOT->LoadMacro("$ALICE_ROOT/PWG/muondep/AddTaskMuonRefit.C");
175 AliAnalysisTaskMuonRefit* refit = AddTaskMuonRefit(-1., -1., kTRUE, -1., -1.);
176 refit->RemoveMonoCathodClusters(kTRUE, kFALSE);
177 }
178
179 if(iESDMCLabelAddition) {
180 gROOT->LoadMacro("$ALICE_ROOT/PWG/muondep/AddTaskESDMCLabelAddition.C");
181 AliAnalysisTaskESDMCLabelAddition *esdmclabel = AddTaskESDMCLabelAddition();
182 }
183
184 if (useMC && useTR && iMUONPerformance) {
185 gROOT->LoadMacro("$ALICE_ROOT/PWGPP/MUON/dep/AddTaskMuonPerformance.C");
186 AliAnalysisTaskMuonPerformance* muonPerformance = AddTaskMuonPerformance();
187 if (usePhysicsSelection) muonPerformance->SelectCollisionCandidates(AliVEvent::kAny);
188 muonPerformance->UseMCKinematics(kTRUE);
189 muonPerformance->SetMCTrigLevelFromMatchTrk(kTRUE);
190 }
191
192 if (iMUONEfficiency) {
193 gROOT->LoadMacro("$ALICE_ROOT/PWGPP/MUON/dep/AddTaskMUONTrackingEfficiency.C");
194 AliAnalysisTaskMuonTrackingEff* muonEfficiency = AddTaskMUONTrackingEfficiency(kTRUE, kTRUE);
195 if (usePhysicsSelection) muonEfficiency->SelectCollisionCandidates(AliVEvent::kAny);
196 muonEfficiency->UseMCLabel(kTRUE);
197 }
198
199 if (iESDfilter) {
200 // ESD filter task configuration.
5654b406 201 gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/ESDfilter/macros/AddTaskESDFilter.C");
b7a421b8 202 if (iMUONcopyAOD) {
203 printf("Registering delta AOD file\n");
204 mgr->RegisterExtraFile("AliAOD.Muons.root");
205 mgr->RegisterExtraFile("AliAOD.Dimuons.root");
57843125 206 int muonMCMode=VAR_MUONMCMODE; // 1 to keep all ancestors, whether or not we get something in the muon arm
3e7b6e7b 207 AliAnalysisTaskESDfilter *taskesdfilter = AddTaskESDFilter(useKFILTER, kTRUE, kFALSE, kFALSE /*usePhysicsSelection*/,kFALSE,kTRUE,kTRUE,kTRUE,1100,muonMCMode); // others
b7a421b8 208 } else {
3e7b6e7b 209 AliAnalysisTaskESDfilter *taskesdfilter = AddTaskESDFilter(useKFILTER, kFALSE, kFALSE, kFALSE /*usePhysicsSelection*/,kFALSE,kTRUE,kTRUE,kTRUE,1100,muonMCMode); // others
30138a88 210 }
211
212 if ( 0 && VAR_USE_ITS_RECO ) /* 0 for the moment to get this macro running also with AliRoot <= .... */
213 {
214 AliAnalysisTaskESDMuonFilter* muFilter = mgr->GetTask("ESD Muon Filter");
215 if ( !muFilter )
216 {
217 std::cout << "ERROR : got a NULL muFilter ! so I cannot ask to keep SPD tracklets !" << std::endl;
218 }
219 else
220 {
221 muFilter->SetWithSPDtracklets(kTRUE);
222 }
223 }
b7a421b8 224 }
225
226 // ********** PWG3 wagons ******************************************************
227 // PWG3 vertexing
228 if (iPWG3vertexing) {
229 gROOT->LoadMacro("$ALICE_ROOT/PWG3/vertexingHF/macros/AddTaskVertexingHF.C");
230 if (!iPWG3d2h) TFile::Cp(gSystem->ExpandPathName(configPWG3d2h.Data()), "file:ConfigVertexingHF.C");
231 AliAnalysisTaskSEVertexingHF *taskvertexingHF = AddTaskVertexingHF();
232 if (!taskvertexingHF) ::Warning("AnalysisTrainNew", "AliAnalysisTaskSEVertexingHF cannot run for this train conditions - EXCLUDED");
233 else mgr->RegisterExtraFile("AliAOD.VertexingHF.root");
234 taskvertexingHF->SelectCollisionCandidates(0);
235 }
236
237 // PWG3 JPSI filtering (only pp)
238 if (iPWG3JPSIfilter && (iCollision==0)) {
239 gROOT->LoadMacro("$ALICE_ROOT/PWG3/dielectron/macros/AddTaskJPSIFilter.C");
240 AliAnalysisTaskSE *taskJPSIfilter = AddTaskJPSIFilter();
241 if (!taskJPSIfilter) ::Warning("AnalysisTrainNew", "AliAnalysisTaskDielectronFilter cannot run for this train conditions - EXCLUDED");
242 else mgr->RegisterExtraFile("AliAOD.Dielectron.root");
243 taskJPSIfilter->SelectCollisionCandidates(0);
244 }
245
246 // PWG3 D2h
247 if (iPWG3d2h) {
248 gROOT->LoadMacro("$ALICE_ROOT/PWG3/vertexingHF/AddD2HTrain.C");
249 TFile::Cp(gSystem->ExpandPathName(configPWG3d2h.Data()), "file:ConfigVertexingHF.C");
250 AddD2HTrain(kFALSE, 1,0,0,0,0,0,0,0,0,0,0);
251 }
252
253 // ********** PWG4 wagons ******************************************************
254 // Jet analysis
255
256 // Configurations flags, move up?
257 TString kDeltaAODJetName = "AliAOD.Jets.root"; //
258 Bool_t kIsPbPb = (iCollision==0)?false:true; // can be more intlligent checking the name of the data set
259 TString kDefaultJetBackgroundBranch = "";
260 TString kJetSubtractBranches = "";
261 UInt_t kHighPtFilterMask = 128;// from esd filter
262 UInt_t iPhysicsSelectionFlag = AliVEvent::kMB;
263 if (iJETAN) {
264 gROOT->LoadMacro("$ALICE_ROOT/PWG4/macros/AddTaskJets.C");
265 // Default jet reconstructor running on ESD's
266 AliAnalysisTaskJets *taskjets = AddTaskJets("AOD","UA1",0.4,kHighPtFilterMask,1.,0); // no background subtraction
267 if (!taskjets) ::Fatal("AnalysisTrainNew", "AliAnalysisTaskJets cannot run for this train conditions - EXCLUDED");
268 if(kDeltaAODJetName.Length()>0) taskjets->SetNonStdOutputFile(kDeltaAODJetName.Data());
269 if (iJETANdelta) {
270 // AddTaskJetsDelta("AliAOD.Jets.root"); // need to modify this accordingly in the add task jets
271 mgr->RegisterExtraFile(kDeltaAODJetName.Data());
272 TString cTmp("");
273 if(kIsPbPb){
274 // UA1 intrinsic background subtraction
275 taskjets = AddTaskJets("AOD","UA1",0.4,kHighPtFilterMask,1.,2); // background subtraction
276 if(kDeltaAODJetName.Length()>0)taskjets->SetNonStdOutputFile(kDeltaAODJetName.Data());
277 }
278 // SICONE
279 taskjets = AddTaskJets("AOD","SISCONE",0.4,kHighPtFilterMask,0.15,0); //no background subtration to be done later....
280 if(kDeltaAODJetName.Length()>0)taskjets->SetNonStdOutputFile(kDeltaAODJetName.Data());
281 cTmp = taskjets->GetNonStdBranch();
282 if(cTmp.Length()>0)kJetSubtractBranches += Form("%s ",cTmp.Data());
283
284 // Add the clusters..
285 gROOT->LoadMacro("$ALICE_ROOT/PWG4/macros/AddTaskJetCluster.C");
286 AliAnalysisTaskJetCluster *taskCl = 0;
287 Float_t fCenUp = 0;
288 Float_t fCenLo = 0;
289 Float_t fTrackEtaWindow = 0.9;
290 taskCl = AddTaskJetCluster("AOD","",kHighPtFilterMask,iPhysicsSelectionFlag,"KT",0.4,0,1, kDeltaAODJetName.Data(),0.15,fTrackEtaWindow,0); // this one is for the background and random jets, random cones with no skip
291 taskCl->SetBackgroundCalc(kTRUE);
292 taskCl->SetNRandomCones(10);
293 taskCl->SetCentralityCut(fCenLo,fCenUp);
294 taskCl->SetGhostEtamax(fTrackEtaWindow);
295 kDefaultJetBackgroundBranch = Form("%s_%s",AliAODJetEventBackground::StdBranchName(),taskCl->GetJetOutputBranch());
296
297 taskCl = AddTaskJetCluster("AOD","",kHighPtFilterMask,iPhysicsSelectionFlag,"ANTIKT",0.4,2,1,kDeltaAODJetName.Data(),0.15);
298 taskCl->SetCentralityCut(fCenLo,fCenUp);
299 if(kIsPbPb)taskCl->SetBackgroundBranch(kDefaultJetBackgroundBranch.Data());
300 taskCl->SetNRandomCones(10);
301 kJetSubtractBranches += Form("%s ",taskCl->GetJetOutputBranch());
302
303 taskCl = AddTaskJetCluster("AOD","",kHighPtFilterMask,iPhysicsSelectionFlag,"ANTIKT",0.2,0,1,kDeltaAODJetName.Data(),0.15);
304 taskCl->SetCentralityCut(fCenLo,fCenUp);
305 if(kIsPbPb)taskCl->SetBackgroundBranch(kDefaultJetBackgroundBranch.Data());
306 kJetSubtractBranches += Form("%s ",taskCl->GetJetOutputBranch());
307
308 // DO THE BACKGROUND SUBTRACTION
309 if(kIsPbPb&&kJetSubtractBranches.Length()){
310 gROOT->LoadMacro("$ALICE_ROOT/PWG4/macros/AddTaskJetBackgroundSubtract.C");
311 AliAnalysisTaskJetBackgroundSubtract *taskSubtract = 0;
312 taskSubtract = AddTaskJetBackgroundSubtract(kJetSubtractBranches,1,"B0","B%d");
313 taskSubtract->SetBackgroundBranch(kDefaultJetBackgroundBranch.Data());
314 if(kDeltaAODJetName.Length()>0)taskSubtract->SetNonStdOutputFile(kDeltaAODJetName.Data());
315 }
316 }
317 }
318}
319
320//______________________________________________________________________________
321Bool_t LoadCommonLibraries()
322{
323 // Load common analysis libraries.
324 if (!gSystem->Getenv("ALICE_ROOT")) {
325 ::Error("AnalysisTrainNew.C::LoadCommonLibraries", "Analysis train requires that analysis libraries are compiled with a local AliRoot");
326 return kFALSE;
327 }
328 Bool_t success = kTRUE;
329 // Load framework classes. Par option ignored here.
330 success &= LoadLibrary("libSTEERBase.so");
331 success &= LoadLibrary("libESD.so");
332 success &= LoadLibrary("libAOD.so");
333 success &= LoadLibrary("libANALYSIS.so");
334 success &= LoadLibrary("libOADB.so");
335 success &= LoadLibrary("libANALYSISalice.so");
336 success &= LoadLibrary("libCORRFW.so");
5654b406 337 success &= LoadLibrary("libESDfilter.so");
b7a421b8 338 gROOT->ProcessLine(".include $ALICE_ROOT/include");
339 if (success) {
340 ::Info("AnalysisTrainNew.C::LoadCommodLibraries", "Load common libraries: SUCCESS");
341 ::Info("AnalysisTrainNew.C::LoadCommodLibraries", "Include path for Aclic compilation:\n%s",
342 gSystem->GetIncludePath());
343 } else {
344 ::Info("AnalysisTrainNew.C::LoadCommodLibraries", "Load common libraries: FAILED");
345 }
346 return success;
347}
348
349//______________________________________________________________________________
350Bool_t LoadAnalysisLibraries()
351{
352 // Load common analysis libraries.
353 if (useTender) {
354 if (!LoadLibrary("TENDER") ||
355 !LoadLibrary("TENDERSupplies")) return kFALSE;
356 }
357 if (iESDfilter || iPWG3MuonTrain) {
358 if (!LoadLibrary("PWGmuon")) return kFALSE;
359 // if (!LoadLibrary("PWG3base")) return kFALSE;
360 // if (!LoadLibrary("PWG3muon")) return kFALSE;
361 }
362 if (iMUONRefit || iESDMCLabelAddition) {
363 if (!LoadLibrary("PWGmuondep")) return kFALSE;
364 }
365 if ((useMC && useTR && iMUONPerformance) || iMUONEfficiency) {
366 if (!LoadLibrary("PWGPPMUONdep")) return kFALSE;
367 }
368 // JETAN
369 if (iJETAN) {
370 if (!LoadLibrary("JETAN")) return kFALSE;
371 }
372 if (iJETANdelta) {
373 if (!LoadLibrary("JETAN") ||
374 !LoadLibrary("CGAL") ||
375 !LoadLibrary("fastjet") ||
376 !LoadLibrary("siscone") ||
377 !LoadLibrary("SISConePlugin") ||
378 !LoadLibrary("FASTJETAN")) return kFALSE;
379 }
380 // PWG3 Vertexing HF
381 if (iPWG3vertexing || iPWG3d2h) {
382 if (!LoadLibrary("PWG3base") ||
383 !LoadLibrary("PWG3vertexingHF")) return kFALSE;
384 }
385 // PWG3 dielectron
386 if (iPWG3JPSIfilter) {
387 if (!LoadLibrary("PWG3dielectron")) return kFALSE;
388 }
389
390 ::Info("AnalysisTrainNew.C::LoadAnalysisLibraries", "Load other libraries: SUCCESS");
391 return kTRUE;
392}
393
394//______________________________________________________________________________
395Bool_t LoadLibrary(const char *module)
396{
397 // Load a module library in a given mode. Reports success.
398 Int_t result;
399 TString mod(module);
400 if (!mod.Length()) {
401 ::Error("AnalysisTrainNew.C::LoadLibrary", "Empty module name");
402 return kFALSE;
403 }
404 // If a library is specified, just load it
405 if (mod.EndsWith(".so")) {
406 mod.Remove(mod.Index(".so"));
407 result = gSystem->Load(mod);
408 if (result < 0) {
409 ::Error("AnalysisTrainNew.C::LoadLibrary", "Could not load library %s", module);
410 return kFALSE;
411 }
412 return kTRUE;
413 }
414 // Check if the library is already loaded
415 if (strlen(gSystem->GetLibraries(Form("%s.so", module), "", kFALSE)) > 0) return kTRUE;
416 result = gSystem->Load(Form("lib%s.so", module));
417 if (result < 0) {
418 ::Error("AnalysisTrainNew.C::LoadLibrary", "Could not load module %s", module);
419 return kFALSE;
420 }
421 return kTRUE;
422}
423
424
425//______________________________________________________________________________
426TChain *CreateChain()
427{
428 // Create the input chain
429 chain = new TChain("esdTree");
430 if (gSystem->AccessPathName("AliESDs.root"))
431 ::Error("AnalysisTrainNew.C::CreateChain", "File: AliESDs.root not in ./data dir");
432 else
433 chain->Add("AliESDs.root");
434 if (chain->GetNtrees()) return chain;
435 return NULL;
436}
437
438//______________________________________________________________________________
439void AODmerge()
440{
441 // Merging method. No staging and no terminate phase.
442 TStopwatch timer;
443 timer.Start();
444 TString outputDir = "wn.xml";
445 TString outputFiles = "AliAOD.root,AliAOD.Muons.root";
446 TString mergeExcludes = "";
447 TObjArray *list = outputFiles.Tokenize(",");
448 TIter *iter = new TIter(list);
449 TObjString *str;
450 TString outputFile;
451 Bool_t merged = kTRUE;
452 while((str=(TObjString*)iter->Next())) {
453 outputFile = str->GetString();
454 // Skip already merged outputs
455 if (!gSystem->AccessPathName(outputFile)) {
456 printf("Output file <%s> found. Not merging again.",outputFile.Data());
457 continue;
458 }
459 if (mergeExcludes.Contains(outputFile.Data())) continue;
460 merged = AliAnalysisAlien::MergeOutput(outputFile, outputDir, 10, 0);
461 if (!merged) {
462 printf("ERROR: Cannot merge %s\n", outputFile.Data());
463 return;
464 }
465 }
466 // all outputs merged, validate
467 ofstream out;
468 out.open("outputs_valid_merge", ios::out);
469 out.close();
470 timer.Print();
471}