AliPhysics  fe039ad (fe039ad)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliAnalysisTaskEmcalEmbeddingHelper.cxx
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright(c) 1998-2016, 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 #include <string>
17 #include <sstream>
18 #include <vector>
19 #include <algorithm>
20 #include <memory>
21 #include <fstream>
22 #include <iostream>
23 #include <bitset>
24 
25 #include <TFile.h>
26 #include <TMath.h>
27 #include <TRandom.h>
28 #include <TChain.h>
29 #include <TGrid.h>
30 #include <TGridResult.h>
31 #include <TSystem.h>
32 #include <TUUID.h>
33 #include <TKey.h>
34 #include <TProfile.h>
35 #include <TH1F.h>
36 #include <TRandom3.h>
37 
38 #include <AliLog.h>
39 #include <AliAnalysisManager.h>
40 #include <AliVEvent.h>
41 #include <AliAODEvent.h>
42 #include <AliESDEvent.h>
43 #include <AliMCEvent.h>
44 #include <AliInputEventHandler.h>
45 #include <AliVHeader.h>
46 #include <AliAODMCHeader.h>
47 #include <AliGenPythiaEventHeader.h>
48 
49 #include "AliYAMLConfiguration.h"
50 #include "AliEmcalList.h"
51 
53 
57 
59 
65  fTriggerMask(AliVEvent::kAny),
66  fMCRejectOutliers(false),
67  fPtHardJetPtRejectionFactor(4),
68  fZVertexCut(10),
69  fMaxVertexDist(999),
70  fInitializedConfiguration(false),
71  fInitializedNewFile(false),
72  fInitializedEmbedding(false),
73  fWrappedAroundTree(false),
74  fTreeName(""),
75  fNPtHardBins(1),
76  fPtHardBin(-1),
77  fRandomEventNumberAccess(kFALSE),
78  fRandomFileAccess(kTRUE),
79  fCreateHisto(true),
80  fAutoConfigurePtHardBins(false),
81  fAutoConfigureBasePath(""),
82  fAutoConfigureTrainTypePath(""),
83  fAutoConfigureIdentifier(""),
84  fFilePattern(""),
85  fInputFilename(""),
86  fFileListFilename(""),
87  fFilenameIndex(-1),
88  fFilenames(),
89  fConfigurationPath(""),
90  fEmbeddedRunlist(),
91  fPythiaCrossSectionFilenames(),
92  fExternalFile(nullptr),
93  fChain(nullptr),
94  fCurrentEntry(0),
95  fLowerEntry(0),
96  fUpperEntry(0),
97  fOffset(0),
98  fMaxNumberOfFiles(0),
99  fFileNumber(0),
100  fHistManager(),
101  fOutput(nullptr),
102  fExternalEvent(nullptr),
103  fExternalHeader(nullptr),
104  fPythiaHeader(nullptr),
105  fPythiaTrials(0),
106  fPythiaTrialsFromFile(0),
107  fPythiaCrossSection(0.),
108  fPythiaCrossSectionFromFile(0.),
109  fPythiaPtHard(0.)
110 {
111  if (fgInstance != nullptr) {
112  AliError("An instance of AliAnalysisTaskEmcalEmbeddingHelper already exists: it will be deleted!!!");
113  delete fgInstance;
114  }
115 
116  fgInstance = this;
117 }
118 
125  AliAnalysisTaskSE(name),
126  fTriggerMask(AliVEvent::kAny),
127  fMCRejectOutliers(false),
128  fPtHardJetPtRejectionFactor(4),
129  fZVertexCut(10),
130  fMaxVertexDist(999),
131  fInitializedConfiguration(false),
132  fInitializedNewFile(false),
133  fInitializedEmbedding(false),
134  fWrappedAroundTree(false),
135  fTreeName("aodTree"),
136  fNPtHardBins(1),
137  fPtHardBin(-1),
138  fRandomEventNumberAccess(kFALSE),
139  fRandomFileAccess(kTRUE),
140  fCreateHisto(true),
141  fAutoConfigurePtHardBins(false),
142  fAutoConfigureBasePath("alien:///alice/cern.ch/user/a/alitrain/"),
143  fAutoConfigureTrainTypePath("PWGJE/Jets_EMC_PbPb/"),
144  fAutoConfigureIdentifier("autoConfigIdentifier"),
145  fFilePattern(""),
146  fInputFilename(""),
147  fFileListFilename(""),
148  fFilenameIndex(-1),
149  fFilenames(),
150  fConfigurationPath(""),
151  fEmbeddedRunlist(),
152  fPythiaCrossSectionFilenames(),
153  fExternalFile(nullptr),
154  fChain(nullptr),
155  fCurrentEntry(0),
156  fLowerEntry(0),
157  fUpperEntry(0),
158  fOffset(0),
159  fMaxNumberOfFiles(0),
160  fFileNumber(0),
161  fHistManager(name),
162  fOutput(nullptr),
163  fExternalEvent(nullptr),
164  fExternalHeader(nullptr),
165  fPythiaHeader(nullptr),
166  fPythiaTrials(0),
167  fPythiaTrialsFromFile(0),
168  fPythiaCrossSection(0.),
169  fPythiaCrossSectionFromFile(0.),
170  fPythiaPtHard(0.)
171 {
172  if (fgInstance != 0) {
173  AliError("An instance of AliAnalysisTaskEmcalEmbeddingHelper already exists: it will be deleted!!!");
174  delete fgInstance;
175  }
176 
177  fgInstance = this;
178 
179  if (fCreateHisto) {
180  DefineOutput(1, AliEmcalList::Class());
181  }
182 }
183 
190 {
191  if (fgInstance == this) fgInstance = nullptr;
192  if (fExternalEvent) delete fExternalEvent;
193  if (fExternalFile) {
194  fExternalFile->Close();
195  delete fExternalFile;
196  }
197 }
198 
204 {
205  // Initialize YAML configuration, if one is given
206  bool initializedYAML = InitializeYamlConfig();
207 
208  // Get file list
209  bool result = GetFilenames();
210 
211  if (result && initializedYAML) {
213  }
214 
215  return result;
216 }
217 
242 {
243  // Determine the pattern filename if not yet set
244  if (fInputFilename == "") {
245  if (fTreeName == "aodTree") {
246  fInputFilename = "AliAOD.root";
247  }
248  else if (fTreeName == "esdTree") {
249  fInputFilename = "AliESDs.root";
250  }
251  else {
252  AliFatal(TString::Format("Requested default (pattern) input filename, but could not determine file type from tree name \"%s\". Please check the tree name and set the pattern input filename", fTreeName.Data()));
253  }
254  }
255 
256  // Retrieve filenames if we don't have them yet.
257  if (fFilenames.size() == 0)
258  {
259  // Handle pt hard bin auto configuration
261  {
262  if (fPtHardBin > 0) {
263  AliFatal("Requested both pt hard bin auto configuration and selected a non-zero pt hard bin. These are incompatible options. Please check your configuration.");
264  }
265  bool success = AutoConfigurePtHardBins();
266  if (success == false) {
267  AliFatal("Pt hard bin auto configuration requested, but it failed. Please check the logs.\n");
268  }
269  }
270 
271  // Handle if fPtHardBin is set
272  // This will require formatting the file pattern in the proper way to support these substitutions
273  if (fPtHardBin != -1 && fFilePattern != "") {
274  fFilePattern = TString::Format(fFilePattern, fPtHardBin);
275  }
276 
277  // Setup AliEn access if needed
278  if (fFilePattern.Contains("alien://") || fFileListFilename.Contains("alien://")) {
279  if (!gGrid) {
280  AliInfo("Trying to connect to AliEn ...");
281  TGrid::Connect("alien://");
282  }
283  if (!gGrid) {
284  AliFatal(TString::Format("Cannot access AliEn to retrieve file list with pattern %s!", fFilePattern.Data()));
285  }
286  }
287 
288  // Retrieve AliEn filenames directly from AliEn
289  bool usedFilePattern = false;
290  if (fFilePattern.Contains("alien://")) {
291  usedFilePattern = true;
292  AliDebug(2, TString::Format("Trying to retrieve file list from AliEn with pattern file %s...", fFilePattern.Data()));
293 
294  // Create a temporary filename based on a UUID to make sure that it doesn't overwrite any files
295  if (fFileListFilename == "") {
297  }
298 
299  // The query command cannot handle "alien://" in the file pattern, so we need to remove it for the command
300  TString filePattern = fFilePattern;
301  filePattern.ReplaceAll("alien://", "");
302 
303  // Execute the grid query to get the filenames
304  AliDebug(2, TString::Format("Trying to retrieve file list from AliEn with pattern \"%s\" and input filename \"%s\"", filePattern.Data(), fInputFilename.Data()));
305  auto result = gGrid->Query(filePattern.Data(), fInputFilename.Data());
306 
307  if (result) {
308  // Loop over the result to store it in the fileList file
309  std::ofstream outFile(fFileListFilename);
310  for (int i = 0; i < result->GetEntries(); i++)
311  {
312  TString path = result->GetKey(i, "turl");
313  // "turl" corresponds to the full AliEn url
314 
315  // If a runlist is specified for good embedded runs, only include the file if it is in this runlist
316  if (IsGoodEmbeddedRun(path)) {
317  outFile << path << "\n";
318  }
319  }
320  outFile.close();
321  }
322  else {
323  AliErrorStream() << "Failed to run grid query\n";
324  return false;
325  }
326  }
327 
328  // Handle a filelist on AliEn
329  if (fFileListFilename.Contains("alien://")) {
330  // Check if we already used the file pattern
331  if (usedFilePattern) {
332  AliErrorStream() << "You set both the file pattern and the file list filename! The file list filename will override the pattern! Pattern: \"" << fFilePattern << "\", filename: \"" << fFileListFilename << "\"\nPlease check that this is the desired behavior!\n";
333  }
334 
335  // Determine the local filename and copy file to local directory
336  std::string alienFilename = fFileListFilename.Data();
337  fFileListFilename = gSystem->BaseName(alienFilename.c_str());
339 
340  TFile::Cp(alienFilename.c_str(), fFileListFilename.Data());
341  }
342 
343  std::ifstream inputFile(fFileListFilename);
344 
345  // Copy available files into the filenames vector
346  // From:: https://stackoverflow.com/a/8365247
347  std::copy(std::istream_iterator<std::string>(inputFile),
348  std::istream_iterator<std::string>(),
349  std::back_inserter(fFilenames));
350 
351  inputFile.close();
352  }
353 
354  if (fFilenames.size() == 0) {
355  AliFatal(TString::Format("Filenames from pattern \"%s\" and file list \"%s\" yielded an empty list!", fFilePattern.Data(), fFileListFilename.Data()));
356  }
357 
358  // Add "#" to files in there are any zip files
359  // It is require to open the proper root file within the zip
360  for (auto filename : fFilenames)
361  {
362  if (filename.find(".zip") != std::string::npos && filename.find("#") == std::string::npos) {
363  filename += "#";
365  if (fTreeName == "aodTree") {
366  filename += "#AliAOD.root";
367  }
368  else if (fTreeName == "esdTree") {
369  filename += "#AliESDs.root";
370  }
371  else {
372  AliError(TString::Format("Filename %s contains \".zip\" and not \"#\", but tree name %s is not recognized. Please check the file list to ensure that the proper path is set.", filename.c_str(), fTreeName.Data()));
373  return false;
374  }
375  }
376  }
377 
378  AliInfoStream() << "Found " << fFilenames.size() << " files to embed\n";
379  return true;
380 }
381 
389 {
390  if (fEmbeddedRunlist.size() == 0) {
391  return true;
392  }
393 
394  for (auto run : fEmbeddedRunlist) {
395  if (path.Contains(run)) {
396  return true;
397  }
398  }
399  return false;
400 
401 }
402 
404 {
405  if (fConfigurationPath == "") {
406  AliInfo("No Embedding YAML configuration was provided");
407  }
408  else {
409  AliInfoStream() << "Embedding YAML configuration was provided: \"" << fConfigurationPath << "\".\n";
410 
412 
413  int addedConfig = config.AddConfiguration(fConfigurationPath, "yamlConfig");
414  if (addedConfig < 0) {
415  AliError("YAML Configuration not found!");
416  return false;
417  }
418 
419  config.GetProperty("runlist", fEmbeddedRunlist, false);
420 
421  }
422  return true;
423 }
424 
441 {
442  bool returnValue = false;
443 
444  AliInfoStream() << "Attempting to auto configure pt hard bins.\n";
445  // YAML configuration containing pt hard bin to train number mapping
447 
448  // Handle AliEn explicitly here since the default base path contains "alien://"
449  if (fAutoConfigureBasePath.find("alien://") != std::string::npos && !gGrid) {
450  AliInfo("Trying to connect to AliEn ...");
451  TGrid::Connect("alien://");
452  }
453 
454  // Get train ID
455  // Need to get the char * directly because it may be null.
456  const char * trainNumberStr = gSystem->Getenv("TRAIN_RUN_ID");
457  std::stringstream trainNumberSS;
458  if (trainNumberStr) {
459  trainNumberSS << trainNumberStr;
460  }
461  if (trainNumberSS.str() == "") {
462  AliFatal("Cannot retrieve train ID.");
463  }
464  // Extract train number from the string
465  int trainNumber;
466  trainNumberSS >> trainNumber;
467 
468  // Determine the file path
470  filename += "/";
472  filename += "/";
474  // Add ".yaml" if it is not already there
475  std::string yamlExtension = ".yaml";
476  if (filename.find(yamlExtension) == std::string::npos) {
477  filename += yamlExtension;
478  }
479 
480  // Check if file exists
481  if (gSystem->AccessPathName(filename.c_str())) {
482  // File _does not_ exist
483  AliInfoStream() << "Train pt hard bin configuration file not available, so creating a new empty configuration named \"" << fAutoConfigureIdentifier << "\".\n";
484  // Use an empty configuration
486  }
487  else {
488  AliInfoStream() << "Opening configuration located at \"" << filename << "\".\n";
489  // Use the existing configuration
491  }
492 
493  // Look for each pt hard bin, and then retrieve the corresponding train number
494  // Once an open pt hard bin is found, add the current train number
495  int tempTrainNumber = -1;
496  bool getPropertyReturnValue = false;
497  std::stringstream propertyName;
498  for (int ptHardBin = 1; ptHardBin <= fNPtHardBins; ptHardBin++)
499  {
500  propertyName.str("");
501  propertyName << ptHardBin;
502  getPropertyReturnValue = config.GetProperty(propertyName.str(), tempTrainNumber, false);
503  if (getPropertyReturnValue != true) {
504  AliInfoStream() << "Train " << trainNumber << " will use pt hard bin " << ptHardBin << ".\n";
505  // We have determine our pt hard bin!
506  fPtHardBin = ptHardBin;
507 
508  // Write the train number back out to the YAML configuration and save it
509  config.WriteProperty(propertyName.str(), trainNumber, fAutoConfigureIdentifier);
511 
512  // NOTE: Cannot clean up the yaml file on the last pt hard bin because the train can be launched
513  // multiple times due to tests, etc. Therefore, we have to accept that we are leaving around used
514  // yaml config files.
515 
516  // We are done - continue on.
517  returnValue = true;
518  break;
519  }
520  else {
521  AliDebugStream(2) << "Found pt hard bin " << ptHardBin << " corresponding to train number " << trainNumber << ".\n";
522  // If train was already allocated (say, by a test train), then use that pt hard bin
523  if (tempTrainNumber == trainNumber) {
524  AliInfoStream() << "Train run number " << trainNumber << " was already found assigned to pt hard bin " << ptHardBin << ". That pt hard bin will be used.\n";
525  fPtHardBin = ptHardBin;
526 
527  // We are done - continue on.
528  returnValue = true;
529  break;
530  }
531  // Otherwise, nothing to be done.
532  }
533  }
534 
535  return returnValue;
536 }
537 
546 {
547  std::string tempStr = "";
548  if (fFileListFilename == "") {
549  tempStr = "fileList";
550  }
551  TUUID tempUUID;
552  tempStr += ".";
553  tempStr += tempUUID.AsString();
554  tempStr += ".txt";
555 
556  return tempStr;
557 }
558 
567 {
568  while (filename.rbegin() != filename.rend() && *(filename.rbegin()) == '/') {
569  filename.pop_back();
570  }
571 
572  return filename;
573 }
574 
580 {
581  // This determines which file is added first to the TChain, thus determining the order of processing
582  // Random file access. Only do this if the user has no set the filename index and request random file access
583  if (fFilenameIndex == -1 && fRandomFileAccess) {
584  // Floor ensures that we it doesn't overflow
585  TRandom3 rand(0);
586  fFilenameIndex = TMath::FloorNint(rand.Rndm()*fFilenames.size());
587  // +1 to account for the fact that the filenames vector is 0 indexed.
588  AliInfo(TString::Format("Starting with random file number %i!", fFilenameIndex+1));
589  }
590  // If not random file access, then start from the beginning
591  if (fFilenameIndex < 0 || static_cast<UInt_t>(fFilenameIndex) >= fFilenames.size()) {
592  // Skip notifying on -1 since it will likely be set there due to constructor.
593  if (fFilenameIndex != -1) {
594  AliWarning(TString::Format("File index %i out of range from 0 to %lu! Resetting to 0!", fFilenameIndex, fFilenames.size()));
595  }
596  fFilenameIndex = 0;
597  }
598 
599  // +1 to account for the fact that the filenames vector is 0 indexed.
600  AliInfo(TString::Format("Starting with file number %i out of %lu", fFilenameIndex+1, fFilenames.size()));
601 }
602 
612 {
613  Int_t attempts = -1;
614 
615  do {
616  // Reset to start of tree
617  if (fCurrentEntry == fUpperEntry) {
619  fWrappedAroundTree = true;
620  }
621 
623  // Continue with GetEntry as normal
624  }
625  else {
626  // NOTE: On transition from one file to the next, this calls the next entry that would be expected.
627  // However, if it is for the last file, it tries to GetEntry() of one entry past the end of the last file.
628  // Normally, this would be a problem, however GetEntry() just doesn't fill the fields of an invalid index
629  // instead of throwing an error. So "invalid values" are filled for a file that doesn't exist, but then
630  // they are immediately replaced by the lines below that reset the access values and re-init the tree.
631  // The benefit of this approach is it simplies file counting (we don't need to carefully increment here
632  // and in InitTree()) and preserves the desired behavior when we are not at the last file.
633  InitTree();
634  }
635 
636  // Load current event
637  // Can be a simple less than, because fFileNumber counts from 0.
639  fChain->GetEntry(fCurrentEntry);
640  }
641  else {
642  AliError("====================================================================================================");
643  AliError("== No more files available to embed from the TChain! Restarting from the beginning of the TChain! ==");
644  AliError("== Be careful to check that this is the desired action! ==");
645  AliError("====================================================================================================");
646 
647  // Reset the relevant access values
648  // fCurrentEntry and fLowerEntry are automatically reset in InitTree()
649  fFileNumber = 0;
650  fUpperEntry = 0;
651 
652  // Re-init back to the start
653  InitTree();
654 
655  // Access the relevant entry
656  // We are certain that fFileNumber is less than fMaxNumberOfFiles, so we are resetting to start
657  fChain->GetEntry(fCurrentEntry);
658  }
659  AliDebug(4, TString::Format("Loading entry %i between %i-%i, starting with offset %i from the lower bound of %i", fCurrentEntry, fLowerEntry, fUpperEntry, fOffset, fLowerEntry));
660 
661  // Set relevant event properties
663 
664  // Increment current entry
665  fCurrentEntry++;
666 
667  // Provide a check for number of attempts
668  attempts++;
669  if (attempts == 1000)
670  AliWarning("After 1000 attempts no event has been accepted by the event selection (trigger, centrality...)!");
671 
672  // Record event properties
673  if (fCreateHisto) {
675  }
676 
677  } while (!IsEventSelected());
678 
679  if (fCreateHisto) {
680  fHistManager.FillTH1("fHistEventCount", "Accepted");
681  fHistManager.FillTH1("fHistEmbeddedEventsAttempted", attempts);
682  }
683 
684  if (!fChain) return kFALSE;
685 
686  return kTRUE;
687 }
688 
694 {
695  AliDebug(4, "Set event properties");
696  fExternalHeader = fExternalEvent->GetHeader();
697 
698  // Handle pythia header if AOD
699  AliAODMCHeader* aodMCH = dynamic_cast<AliAODMCHeader*>(fExternalEvent->FindListObject(AliAODMCHeader::StdBranchName()));
700  if (aodMCH) {
701  for (UInt_t i = 0;i<aodMCH->GetNCocktailHeaders();i++) {
702  fPythiaHeader = dynamic_cast<AliGenPythiaEventHeader*>(aodMCH->GetCocktailHeader(i));
703  if (fPythiaHeader) break;
704  }
705  }
706 
707  if (fPythiaHeader)
708  {
709  fPythiaCrossSection = fPythiaHeader->GetXsection();
710  fPythiaTrials = fPythiaHeader->Trials();
711  fPythiaPtHard = fPythiaHeader->GetPtHard();
712  // It is identically zero if the available is not available
713  if (fPythiaCrossSection == 0.) {
714  AliDebugStream(4) << "Taking the pythia cross section avg from the xsec file.\n";
716  }
717  // It is identically zero if the available is not available
718  if (fPythiaTrials == 0.) {
719  AliDebugStream(4) << "Taking the pythia trials avg from the xsec file.\n";
721  }
722  // Pt hard is inherently event-by-event and cannot by taken as a avg quantity.
723 
724  AliDebugStream(4) << "Pythia header is defined!\n";
725  AliDebugStream(4) << "fPythiaCrossSection: " << fPythiaCrossSection << "\n";
726  }
727 }
728 
733 {
734  // Fill trials, xsec, pt hard
735  fHistManager.FillTH1("fHistTrials", fPtHardBin, fPythiaTrials);
737  fHistManager.FillTH1("fHistPtHard", fPythiaPtHard);
738 }
739 
746 {
748  return kTRUE;
749  }
750 
751  if (fCreateHisto) {
752  // Keep count of number of rejected events
753  fHistManager.FillTH1("fHistEventCount", "Rejected");
754  }
755 
756  return kFALSE;
757 }
758 
765 {
766  // Physics selection
767  if (fTriggerMask != AliVEvent::kAny) {
768  UInt_t res = 0;
769  const AliESDEvent *eev = dynamic_cast<const AliESDEvent*>(fExternalEvent);
770  if (eev) {
771  AliFatal("Event selection is not implemented for embedding ESDs.");
772  // Unfortunately, the normal method of retrieving the trigger mask (commented out below) doesn't work for the embedded event since we don't
773  // create an input handler and I am not an expert on getting a trigger mask. Further, embedding ESDs is likely to be inefficient, so it is
774  // probably best to avoid it if possible.
775  //
776  // Suggestions are welcome here!
777  //res = (dynamic_cast<AliInputEventHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected();
778  } else {
779  const AliAODEvent *aev = dynamic_cast<const AliAODEvent*>(fExternalEvent);
780  if (aev) {
781  res = (dynamic_cast<AliVAODHeader*>(aev->GetHeader()))->GetOfflineTrigger();
782  }
783  }
784 
785  if ((res & fTriggerMask) == 0) {
786  AliDebug(3, Form("Event rejected due to physics selection. Event trigger mask: %d, trigger mask selection: %d.",
787  res, fTriggerMask));
788  if (fCreateHisto) {
789  fHistManager.FillTH1("fHistEmbeddedEventRejection", "PhysSel", 1);
790  }
791  return kFALSE;
792  }
793  }
794 
795  // Vertex selection
796  Double_t externalVertex[3]={0};
797  Double_t inputVertex[3]={0};
798  const AliVVertex *externalVert = fExternalEvent->GetPrimaryVertex();
799  const AliVVertex *inputVert = AliAnalysisTaskSE::InputEvent()->GetPrimaryVertex();
800  if (externalVert && inputVert) {
801  externalVert->GetXYZ(externalVertex);
802  inputVert->GetXYZ(inputVertex);
803 
804  if (TMath::Abs(externalVertex[2]) > fZVertexCut) {
805  AliDebug(3, Form("Event rejected due to Z vertex selection. Event Z vertex: %f, Z vertex cut: %f",
806  externalVertex[2], fZVertexCut));
807  if (fCreateHisto) {
808  fHistManager.FillTH1("fHistEmbeddedEventRejection", "Vz", 1);
809  }
810  return kFALSE;
811  }
812  Double_t dist = TMath::Sqrt((externalVertex[0]-inputVertex[0])*(externalVertex[0]-inputVertex[0])+(externalVertex[1]-inputVertex[1])*(externalVertex[1]-inputVertex[1])+(externalVertex[2]-inputVertex[2])*(externalVertex[2]-inputVertex[2]));
813  if (dist > fMaxVertexDist) {
814  AliDebug(3, Form("Event rejected because the distance between the current and embedded vertices is > %f. "
815  "Current event vertex (%f, %f, %f), embedded event vertex (%f, %f, %f). Distance = %f",
816  fMaxVertexDist, inputVertex[0], inputVertex[1], inputVertex[2], externalVertex[0], externalVertex[1], externalVertex[2], dist));
817  if (fCreateHisto) {
818  fHistManager.FillTH1("fHistEmbeddedEventRejection", "VertexDist", 1);
819  }
820  return kFALSE;
821  }
822  }
823 
824  // Check for pt hard bin outliers
826  {
827  // Pythia jet / pT-hard > factor
828  // This corresponds to "condition 1" in AliAnalysisTaskEmcal
829  // NOTE: The other "conditions" defined there are not really suitable to define here, since they
830  // depend on the input objects of the event
831  if (fPtHardJetPtRejectionFactor > 0.) {
832  TLorentzVector jet;
833 
834  Int_t nTriggerJets = fPythiaHeader->NTriggerJets();
835 
836  AliDebugStream(4) << "Pythia Njets: " << nTriggerJets << ", pT Hard: " << fPythiaPtHard << "\n";
837 
838  Float_t tmpjet[]={0,0,0,0};
839  for (Int_t iJet = 0; iJet< nTriggerJets; iJet++) {
840  fPythiaHeader->TriggerJet(iJet, tmpjet);
841 
842  jet.SetPxPyPzE(tmpjet[0],tmpjet[1],tmpjet[2],tmpjet[3]);
843 
844  AliDebugStream(5) << "Pythia jet " << iJet << ", pycell jet pT: " << jet.Pt() << "\n";
845 
846  //Compare jet pT and pt Hard
847  if (jet.Pt() > fPtHardJetPtRejectionFactor * fPythiaPtHard) {
848  AliDebugStream(3) << "Event rejected because of MC outlier removal. Pythia header jet with: pT Hard " << fPythiaPtHard << ", pycell jet pT " << jet.Pt() << ", rejection factor " << fPtHardJetPtRejectionFactor << "\n";
849  fHistManager.FillTH1("fHistEmbeddedEventRejection", "MCOutlier", 1);
850  return kFALSE;
851  }
852  }
853  }
854  }
855 
856  return kTRUE;
857 }
858 
865 {
866  if (!fChain) return kFALSE;
867 
868  if (!fExternalEvent) {
869  if (fTreeName == "aodTree") {
870  fExternalEvent = new AliAODEvent();
871  }
872  else if (fTreeName == "esdTree") {
873  fExternalEvent = new AliESDEvent();
874  }
875  else {
876  AliError(Form("Tree name %s not recognized!", fTreeName.Data()));
877  return kFALSE;
878  }
879  }
880 
881  fExternalEvent->ReadFromTree(fChain, fTreeName);
882 
883  return kTRUE;
884 }
885 
892 {
893  SetupEmbedding();
894 
895  if (!fCreateHisto) {
896  return;
897  }
898 
899  // Create output list
900  OpenFile(1);
901  fOutput = new AliEmcalList();
902  fOutput->SetOwner();
903 
904  // Create histograms
905  TString histName;
906  TString histTitle;
907 
908  // Cross section
909  histName = "fHistXsection";
910  histTitle = "Pythia Cross Section;p_{T} hard bin; XSection";
911  fHistManager.CreateTProfile(histName, histTitle, fNPtHardBins, 0, fNPtHardBins);
912 
913  // Trials
914  histName = "fHistTrials";
915  histTitle = "Number of Pythia Trials;p_{T} hard bin;Trials";
916  fHistManager.CreateTH1(histName, histTitle, fNPtHardBins, 0, fNPtHardBins);
917 
918  // Pt hard spectra
919  histName = "fHistPtHard";
920  histTitle = "p_{T} Hard Spectra;p_{T} hard;Counts";
921  fHistManager.CreateTH1(histName, histTitle, 500, 0, 1000);
922 
923  // Count of accepted and rejected events
924  histName = "fHistEventCount";
925  histTitle = "fHistEventCount;Result;Count";
926  auto histEventCount = fHistManager.CreateTH1(histName, histTitle, 2, 0, 2);
927  histEventCount->GetXaxis()->SetBinLabel(1,"Accepted");
928  histEventCount->GetXaxis()->SetBinLabel(2,"Rejected");
929 
930  // Event rejection reason
931  histName = "fHistEmbeddedEventRejection";
932  histTitle = "Reasons to reject embedded event";
933  std::vector<std::string> binLabels = {"PhysSel", "MCOutlier", "Vz", "VertexDist"};
934  auto fHistEmbeddedEventRejection = fHistManager.CreateTH1(histName, histTitle, binLabels.size(), 0, binLabels.size());
935  // Set label names
936  for (unsigned int i = 1; i <= binLabels.size(); i++) {
937  fHistEmbeddedEventRejection->GetXaxis()->SetBinLabel(i, binLabels.at(i-1).c_str());
938  }
939  fHistEmbeddedEventRejection->GetYaxis()->SetTitle("Counts");
940 
941  // Rejected events in embedded event selection
942  histName = "fHistEmbeddedEventsAttempted";
943  histTitle = "Number of embedded events rejected by event selection before success;Number of rejected events;Counts";
944  fHistManager.CreateTH1(histName, histTitle, 200, 0, 200);
945 
946  // Number of files embedded
947  histName = "fHistNumberOfFilesEmbedded";
948  histTitle = "Number of files which contributed events to be embedded";
949  fHistManager.CreateTH1(histName, histTitle, 1, 0, 2);
950 
951  // File number which was embedded
952  histName = "fHistAbsoluteFileNumber";
953  histTitle = "Number of times each absolute file number was embedded";
954  fHistManager.CreateTH1(histName, histTitle, fMaxNumberOfFiles, 0, fMaxNumberOfFiles);
955 
956  // Add all histograms to output list
957  TIter next(fHistManager.GetListOfHistograms());
958  TObject* obj = 0;
959  while ((obj = next())) {
960  fOutput->Add(obj);
961  }
962 
963  PostData(1, fOutput);
964 }
965 
973 {
974  // Determine which file to start with
976 
977  // Setup TChain
978  fChain = new TChain(fTreeName);
979 
980  // Determine whether AliEn is needed
981  bool requiresAlien = false;
982  for (auto filename : fFilenames)
983  {
984  if (filename.find("alien://") != std::string::npos) {
985  requiresAlien = true;
986  }
987  }
988 
989  if (requiresAlien && !gGrid) {
990  AliInfo("Trying to connect to AliEn ...");
991  TGrid::Connect("alien://");
992  }
993 
994  // Add files for TChain
995  // See: https://stackoverflow.com/a/8533198
996  bool wrapped = false;
997  TString baseFileName = "";
998  // Hanlde the pythia cross section file list
999  bool failedEntirelyToFindFile = false;
1000  TString pythiaXSecFilename = "";
1001  TString pythiaBaseFilename = "";
1002  std::vector <std::string> pythiaBaseFilenames = {"pyxsec.root", "pyxsec_hists.root"};
1003  for (auto filename = fFilenames.begin() + fFilenameIndex; (filename != fFilenames.begin() + fFilenameIndex || !wrapped); filename++)
1004  {
1005  // Wraps the loop back around to the beginning
1006  if (filename == fFilenames.end())
1007  {
1008  // Explicit check is needed. Otherwise, an offset of 0 would load the 0th entry twice.
1009  if (fFilenameIndex == 0) {
1010  break;
1011  }
1012  filename = fFilenames.begin();
1013  wrapped = true;
1014  }
1015 
1016  // AccessPathName() cannot handle the "#", so we need to strip it to check that the file exists.
1017  baseFileName = filename->c_str();
1018  if (baseFileName.Contains(".zip#")) {
1019  Ssiz_t pos = baseFileName.Last('#');
1020  baseFileName.Remove(pos);
1021  }
1022 
1023  // Ensure that the file is accessible
1024  if (gSystem->AccessPathName(baseFileName)) {
1025  AliError(Form("File %s does not exist! Skipping!", baseFileName.Data()));
1026  // Do not process the file if it is unaccessible, but continue processing
1027  continue;
1028  }
1029 
1030  // Add to the Chain
1031  AliDebugStream(4) << "Adding file to the embedded input chain \"" << filename->c_str() << "\".\n";
1032  fChain->Add(filename->c_str());
1033 
1034  // Handle the pythia cross section (if it exists)
1035  // Determiner which file it exists in (if it does exist)
1036  if (pythiaBaseFilename == "" && failedEntirelyToFindFile == false) {
1037  AliInfoStream() << "Attempting to determine pythia cross section filename. It can be normal to see some TFile::Init() errors!\n";
1038  for (auto name : pythiaBaseFilenames) {
1039  pythiaXSecFilename = DeterminePythiaXSecFilename(baseFileName, name, true);
1040  if (pythiaXSecFilename != "") {
1041  AliDebugStream(4) << "Found pythia cross section base filename \"" << name.c_str() << "\"\n";
1042  pythiaBaseFilename = name;
1043  break;
1044  }
1045  }
1046 
1047  if (pythiaBaseFilename == "") {
1048  // Failed entirely - just give up on this
1049  AliErrorStream() << "Failed to find pythia x sec file! Continuing with only the pythia header!\n";
1050  failedEntirelyToFindFile = true;
1051  }
1052  else {
1053  AliInfoStream() << "Found pythia cross section file \"" << pythiaBaseFilename.Data() << "\".\n";
1054  }
1055  }
1056  // Retrieve the value based on the previously determined filename
1057  // If we have determined that it doesn't exist in the first loop then we don't repeated attempt to fail to open the file
1058  if (failedEntirelyToFindFile == false) {
1059  // Can still check whether it exists here, but we don't necessarily have to!
1060  // However, we won't check to ensure that rapid file access on AliEn doesn't cause it to crash!
1061  pythiaXSecFilename = DeterminePythiaXSecFilename(baseFileName, pythiaBaseFilename, false);
1062 
1063  AliDebugStream(4) << "Adding pythia cross section file \"" << pythiaXSecFilename.Data() << "\".\n";
1064 
1065  // They will automatically be ordered the same as the files to embed!
1066  fPythiaCrossSectionFilenames.push_back(pythiaXSecFilename.Data());
1067  }
1068  }
1069 
1070  // Keep track of the total number of files in the TChain to ensure that we don't start repeating within the chain
1071  fMaxNumberOfFiles = fChain->GetListOfFiles()->GetEntries();
1072 
1073  if (fFilenames.size() > fMaxNumberOfFiles) {
1074  AliWarning(TString::Format("Number of input files (%lu) is larger than the number of available files (%i). Some filenames were likely invalid!", fFilenames.size(), fMaxNumberOfFiles));
1075  }
1076 
1077  // Setup input event
1078  Bool_t res = InitEvent();
1079  if (!res) return kFALSE;
1080 
1081  return kTRUE;
1082 }
1083 
1094 std::string AliAnalysisTaskEmcalEmbeddingHelper::DeterminePythiaXSecFilename(TString baseFileName, TString pythiaBaseFilename, bool testIfExists) const
1095 {
1096  std::string pythiaXSecFilename = "";
1097 
1098  // Handle different file types
1099  if (baseFileName.Contains(".zip"))
1100  {
1101  // Hanlde zip files
1102  pythiaXSecFilename = baseFileName;
1103  pythiaXSecFilename += "#";
1104  pythiaXSecFilename += pythiaBaseFilename;
1105 
1106  // Check if the file is accessible
1107  if (testIfExists) {
1108  // Unfortunately, we cannot test for the existence of a file in an archive.
1109  // Instead, we have to tolerate TFile throwing an error (maximum of two).
1110  std::unique_ptr<TFile> fTemp(TFile::Open(pythiaXSecFilename.c_str(), "READ"));
1111 
1112  if (!fTemp) {
1113  AliDebugStream(4) << "File " << pythiaXSecFilename.c_str() << " does not exist!\n";
1114  pythiaXSecFilename = "";
1115  }
1116  else {
1117  AliDebugStream(4) << "Found pythia cross section file \"" << pythiaXSecFilename.c_str() << "\".\n";
1118  }
1119  }
1120  }
1121  else
1122  {
1123  // Hanlde normal root files
1124  pythiaXSecFilename = gSystem->DirName(baseFileName);
1125  pythiaXSecFilename += "/";
1126  pythiaXSecFilename += pythiaBaseFilename;
1127 
1128  // Check if the file is accessible
1129  if (testIfExists) {
1130  if (gSystem->AccessPathName(pythiaXSecFilename.c_str())) {
1131  AliDebugStream(4) << "File " << pythiaXSecFilename.c_str() << " does not exist!\n";
1132  pythiaXSecFilename = "";
1133  }
1134  else {
1135  AliDebugStream(4) << "Found pythia cross section file \"" << pythiaXSecFilename.c_str() << "\".\n";
1136  }
1137  }
1138  }
1139 
1140  return pythiaXSecFilename;
1141 }
1142 
1149 {
1150  if (fInitializedConfiguration == false) {
1151  AliFatal("The configuration is not initialized. Check that Initialize() was called!");
1152  }
1153 
1154  // Setup TChain
1155  Bool_t res = SetupInputFiles();
1156  if (!res) { return; }
1157 
1158  // Note if getting random event access
1160  AliInfo("Random event number access enabled!");
1161  }
1162 
1163  fInitializedEmbedding = kTRUE;
1164 }
1165 
1177 {
1178  // Load first entry of the (next) file so that we can query information about it
1179  // (it is unaccessible otherwise).
1180  // Since fUpperEntry is the total number of entries, loading it will retrieve the
1181  // next tree (in the next file) since entries are indexed starting from 0.
1182  fChain->GetEntry(fUpperEntry);
1183 
1184  // Determine tree size and current entry
1185  // Set the limits of the new tree
1187  // Fine to be += as long as we started at 0
1188  fUpperEntry += fChain->GetTree()->GetEntries();
1189 
1190  // Jump ahead at random if desired
1191  // Determines the offset into the tree
1193  TRandom3 rand(0);
1194  fOffset = TMath::Nint(rand.Rndm()*(fUpperEntry-fLowerEntry))-1;
1195  }
1196  else {
1197  fOffset = 0;
1198  }
1199 
1200  // Sets which entry to start if the try
1202 
1203  // Keep track of the number of files that we have gone through
1204  // To start from 0, we only increment if fLowerEntry > 0
1205  if (fLowerEntry > 0) {
1206  fFileNumber++;
1207  }
1208 
1209  // Add to the count the number of files which were embedded
1210  fHistManager.FillTH1("fHistNumberOfFilesEmbedded", 1);
1211  fHistManager.FillTH1("fHistAbsoluteFileNumber", (fFileNumber + fFilenameIndex) % fMaxNumberOfFiles);
1212 
1213  // Check for pythia cross section and extract if possible
1214  // fFileNumber corresponds to the next file
1215  // If there are pythia filenames, the number of match the file number of the tree.
1216  // If we previously gave up on extracting then there should be no entires
1217  if (fPythiaCrossSectionFilenames.size() > 0) {
1218  // Need to check that fFileNumber is smaller than the size of the vector because we don't check if
1221 
1222  if (!success) {
1223  AliDebugStream(3) << "Failed to retrieve cross section from xsec file. Will still attempt to get the information from the header.\n";
1224  }
1225  }
1226  else {
1227  AliErrorStream() << "Attempted to read past the end of the pythia cross section filenames vector. File number: " << fFileNumber << ", vector size: " << fPythiaCrossSectionFilenames.size() << ".\nThis should only occur if we have run out of files to embed!\n";
1228  }
1229  }
1230 
1231  AliDebug(2, TString::Format("Will start embedding file %i beginning from entry %i (entry %i within the file). NOTE: This file number is not equal to the absolute file number in the file list!", fFileNumber, fCurrentEntry, fCurrentEntry - fLowerEntry));
1232  // NOTE: Cannot use this print message, as it is possible that fMaxNumberOfFiles != fFilenames.size() because
1233  // invalid filenames may be included in the fFilenames count!
1234  //AliDebug(2, TString::Format("Will start embedding file %i as the %ith file beginning from entry %i.", (fFilenameIndex + fFileNumber) % fMaxNumberOfFiles, fFileNumber, fCurrentEntry));
1235 
1236  // (re)set whether we have wrapped the tree
1237  fWrappedAroundTree = false;
1238 
1239  // Note that the tree in the new file has been initialized
1240  fInitializedNewFile = kTRUE;
1241 }
1242 
1251 {
1252  std::unique_ptr<TFile> fxsec(TFile::Open(pythiaFileName.c_str()));
1253 
1254  if (fxsec)
1255  {
1256  int trials = 0;
1257  double crossSection = 0;
1258  double nEvents = 0;
1259  // Check if it's a tree
1260  TTree *xtree = dynamic_cast<TTree*>(fxsec->Get("Xsection"));
1261  if (xtree) {
1262  UInt_t ntrials = 0;
1263  Double_t xsection = 0;
1264  xtree->SetBranchAddress("xsection",&xsection);
1265  xtree->SetBranchAddress("ntrials",&ntrials);
1266  xtree->GetEntry(0);
1267  trials = ntrials;
1268  crossSection = xsection;
1269  // TODO: Test this on a file which has pyxsec.root!
1270  nEvents = 1.;
1271  AliFatal("Have no tested pyxsec.root files. Need to determine the proper way to get nevents!!");
1272  }
1273  else {
1274  // Check if it's instead the histograms
1275  // find the tlist we want to be independtent of the name so use the Tkey
1276  TKey* key = static_cast<TKey*>(fxsec->GetListOfKeys()->At(0));
1277  if (!key) return false;
1278  TList *list = dynamic_cast<TList*>(key->ReadObj());
1279  if (!list) return false;
1280  TProfile * crossSectionHist = static_cast<TProfile*>(list->FindObject("h1Xsec"));
1281  // check for failure
1282  if(!(crossSectionHist->GetEntries())) {
1283  // No cross seciton information available - fall back to raw
1284  AliErrorStream() << "No cross section information available in file \"" << fxsec->GetName() << "\". Will still attempt to extract cross section information from pythia header.\n";
1285  } else {
1286  // Cross section histogram filled - take it from there
1287  crossSection = crossSectionHist->GetBinContent(1);
1288  if(!crossSection) AliErrorStream() << GetName() << ": Cross section 0 for file " << pythiaFileName << std::endl;
1289  }
1290  TH1F * trialsHist = static_cast<TH1F*>(list->FindObject("h1Trials"));
1291  trials = trialsHist->GetBinContent(1);
1292  nEvents = trialsHist->GetEntries();
1293  }
1294 
1295  // If successful in retrieveing the values, normalizae the xsec and trials by the number of events
1296  // in the file. This way, we can use it as an approximate event-by-event value
1297  // We do not want to just use the overall value because some of the events may be rejected by various
1298  // event selections, so we only want that ones that were actually use. The easiest way to do so is by
1299  // filling it for each event.
1300  fPythiaTrialsFromFile = trials/nEvents;
1301  // Do __NOT__ divide by nEvents here! The value is already from a TProfile and therefore is already the mean!
1302  fPythiaCrossSectionFromFile = crossSection;
1303 
1304  return true;
1305  }
1306  else {
1307  AliDebugStream(3) << "Unable to open file \"" << pythiaFileName << "\". Will attempt to use values from the hader.";
1308  }
1309 
1310  // Could not open file
1311  return false;
1312 }
1313 
1320 {
1321  if (!fInitializedEmbedding) {
1322  AliError("Chain not initialized before running! Setting up now.");
1323  SetupEmbedding();
1324  }
1325 
1326  if (!fInitializedNewFile) {
1327  InitTree();
1328  }
1329 
1330  Bool_t res = GetNextEntry();
1331 
1332  if (!res) {
1333  AliError("Unable to get the event to embed. Nothing will be embedded.");
1334  return;
1335  }
1336 
1337  if (fCreateHisto && fOutput) {
1338  PostData(1, fOutput);
1339  }
1340 }
1341 
1346 {
1347 }
1348 
1357 {
1358  // Get the pointer to the existing analysis manager via the static access method.
1359  //==============================================================================
1360  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1361  if (!mgr)
1362  {
1363  ::Error("AddTaskEmcalEmbeddingHelper", "No analysis manager to connect to.");
1364  return 0;
1365  }
1366 
1367  // Check the analysis type using the event handlers connected to the analysis manager.
1368  //==============================================================================
1369  AliVEventHandler* handler = mgr->GetInputEventHandler();
1370  if (!handler)
1371  {
1372  ::Error("AddTaskEmcalEmbeddingHelper", "This task requires an input event handler");
1373  return 0;
1374  }
1375 
1376  TString name = "AliAnalysisTaskEmcalEmbeddingHelper";
1377 
1378  AliAnalysisTaskEmcalEmbeddingHelper * mgrTask = static_cast<AliAnalysisTaskEmcalEmbeddingHelper *>(mgr->GetTask(name.Data()));
1379  if (mgrTask) return mgrTask;
1380 
1381  // Create the task that manages
1382  AliAnalysisTaskEmcalEmbeddingHelper * embeddingHelper = new AliAnalysisTaskEmcalEmbeddingHelper(name.Data());
1383 
1384  //-------------------------------------------------------
1385  // Final settings, pass to manager and set the containers
1386  //-------------------------------------------------------
1387 
1388  mgr->AddTask(embeddingHelper);
1389 
1390  // Create containers for input/output
1391  AliAnalysisDataContainer* cInput = mgr->GetCommonInputContainer();
1392 
1393  TString outputContainerName(name);
1394  outputContainerName += "_histos";
1395 
1396  AliAnalysisDataContainer * cOutput = mgr->CreateContainer(outputContainerName.Data(),
1397  TList::Class(),
1398  AliAnalysisManager::kOutputContainer,
1399  Form("%s", AliAnalysisManager::GetCommonFileName()));
1400 
1401  mgr->ConnectInput(embeddingHelper, 0, cInput);
1402  mgr->ConnectOutput(embeddingHelper, 1, cOutput);
1403 
1404  return embeddingHelper;
1405 }
1406 
1412 std::string AliAnalysisTaskEmcalEmbeddingHelper::toString(bool includeFileList) const
1413 {
1414  std::stringstream tempSS;
1415 
1416  // Show the correction components
1417  tempSS << std::boolalpha;
1418  tempSS << GetName() << ": Embedding helper configuration:\n";
1419  tempSS << "Create histos: " << fCreateHisto << "\n";
1420  tempSS << "Pt Hard Bin: " << fPtHardBin << "\n";
1421  tempSS << "N Pt Hard Bins: " << fNPtHardBins << "\n";
1422  tempSS << "File pattern: \"" << fFilePattern << "\"\n";
1423  tempSS << "Input filename: \"" << fInputFilename << "\"\n";
1424  tempSS << "File list filename: \"" << fFileListFilename << "\"\n";
1425  tempSS << "Tree name: " << fTreeName << "\n";
1426  tempSS << "Random event number access: " << fRandomEventNumberAccess << "\n";
1427  tempSS << "Random file access: " << fRandomFileAccess << "\n";
1428  tempSS << "Starting file index: " << fFilenameIndex << "\n";
1429  tempSS << "Number of files to embed: " << fFilenames.size() << "\n";
1430  tempSS << "YAML configuration path: " << fConfigurationPath << "\n";
1431 
1432  std::bitset<32> triggerMask(fTriggerMask);
1433  tempSS << "\nEmbedded event settings:\n";
1434  tempSS << "Trigger mask (binary): " << triggerMask << "\n";
1435  tempSS << "Reject outliers: " << fMCRejectOutliers << "\n";
1436  tempSS << "Pt hard jet pt rejection factor: " << fPtHardJetPtRejectionFactor << "\n";
1437  tempSS << "Z vertex cut: " << fZVertexCut << "\n";
1438  tempSS << "Max vertex distance: " << fMaxVertexDist << "\n";
1439 
1440  if (includeFileList) {
1441  tempSS << "\nFiles to embed:\n";
1442  for (auto filename : fFilenames) {
1443  tempSS << "\t" << filename << "\n";
1444  }
1445  }
1446 
1447  return tempSS.str();
1448 }
1449 
1457 std::ostream & AliAnalysisTaskEmcalEmbeddingHelper::Print(std::ostream & in) const {
1458  in << toString();
1459  return in;
1460 }
1461 
1470 std::ostream & operator<<(std::ostream & in, const AliAnalysisTaskEmcalEmbeddingHelper & myTask)
1471 {
1472  std::ostream & result = myTask.Print(in);
1473  return result;
1474 }
1475 
1483 {
1484  std::string temp(opt);
1485  bool includeFileList = false;
1486  if (temp == "FILELIST") {
1487  includeFileList = true;
1488  }
1489  Printf("%s", toString(includeFileList).c_str());
1490 }
Bool_t fRandomEventNumberAccess
If true, it will start embedding from a random entry in the file rather than from the first...
Double_t fZVertexCut
Z vertex cut on embedded event.
const char * filename
Definition: TestFCM.C:1
double Double_t
Definition: External.C:58
Int_t fPtHardBin
ptHard bin for the given pythia production
bool fMCRejectOutliers
If true, MC outliers will be rejected.
double fPythiaCrossSection
! Pythia cross section for the current event (extracted from the pythia header).
Int_t fLowerEntry
! First entry of the current tree to be used for embedding
TString fFileListFilename
Name of the file list containing paths to files to embed.
int fPythiaTrialsFromFile
! Average number of trials extracted from a xsec file.
Bool_t fRandomFileAccess
If true, it will start embedding from a random file in the input files list.
TSystem * gSystem
Int_t fCurrentEntry
! Current entry in the current tree
bool WriteConfiguration(const std::string &filename, const unsigned int i) const
TFile * fExternalFile
! External file used for embedding
Int_t fNPtHardBins
Total number of pt hard bins.
TChain * fChain
! External TChain (tree) containing the events available for embedding
Declaration of class AliAnalysisTaskEmcalEmbeddingHelper.
bool fAutoConfigurePtHardBins
If true, attempt to auto configure pt hard bins. Only works on the LEGO train.
bool fInitializedConfiguration
Notes if the configuration has been initialized.
bool GetProperty(std::vector< std::string > propertyPath, const std::string &propertyName, T &property, const bool requiredProperty) const
AliVHeader * fExternalHeader
! Header of the current external event
AliGenPythiaEventHeader * fPythiaHeader
! Pythia header of the current external event
TString fInputFilename
Filename of input root files.
std::vector< std::string > fEmbeddedRunlist
Good runlist for files to embed.
std::string fAutoConfigureBasePath
The base path to the auto configuration (for example, "/alice/cern.ch/user/a/alitrain/") ...
std::string fConfigurationPath
Path to YAML configuration.
int Int_t
Definition: External.C:63
void CreateTProfile(const char *name, const char *title, int nbinsX, double xmin, double xmax, Option_t *opt="")
Create a new TProfile within the container.
unsigned int UInt_t
Definition: External.C:33
THashList * GetListOfHistograms() const
Get the list of histograms.
Definition: THistManager.h:671
float Float_t
Definition: External.C:68
bool fInitializedEmbedding
! Notes where the TChain has been initialized for embedding
std::string toString(bool includeFileList=false) const
Implementation of task to embed external events.
UInt_t fMaxNumberOfFiles
! Max number of files that are in the TChain
TH1 * CreateTH1(const char *name, const char *title, int nbins, double xmin, double xmax, Option_t *opt="")
Create a new TH1 within the container.
void FillProfile(const char *name, double x, double y, double weight=1.)
Double_t nEvents
plot quality messages
Double_t fMaxVertexDist
Max distance between Z vertex of internal and embedded event.
AliVEvent * fExternalEvent
! Current external event available for embedding
std::vector< std::string > fPythiaCrossSectionFilenames
Paths to the pythia xsection files.
void FillTH1(const char *hname, double x, double weight=1., Option_t *opt="")
Fill a 1D histogram within the container.
TString fTreeName
Name of the ESD/AOD tree where the events are to be found.
Int_t fOffset
! Offset from fLowerEntry where the loop over the tree should start
bool fCreateHisto
If true, create QA histograms.
Enhanced TList-derived class that implements correct merging for pt_hard binned production.
Definition: AliEmcalList.h:25
bool fWrappedAroundTree
! Notes whether we have wrapped around the tree, which is important if the offset into the tree is no...
Double_t fPtHardJetPtRejectionFactor
Factor which the pt hard bin is multiplied by to compare against pythia header jets pt...
int AddEmptyConfiguration(const std::string &configurationName)
Add YAML configuration at configurationFilename to available configurations.
double fPythiaPtHard
! Pt hard of the current event (extracted from the pythia header).
static AliAnalysisTaskEmcalEmbeddingHelper * AddTaskEmcalEmbeddingHelper()
std::ostream & operator<<(std::ostream &in, const AliAnalysisTaskEmcalEmbeddingHelper &myTask)
THistManager fHistManager
Manages access to all histograms.
bool fInitializedNewFile
! Notes where the entry indices have been initialized for a new tree in the chain ...
static AliAnalysisTaskEmcalEmbeddingHelper * fgInstance
! Global instance of this class
UInt_t fFileNumber
! File number corresponding to the current tree
YAML configuration class for AliPhysics.
bool WriteProperty(std::string propertyName, T &property, std::string configurationName="")
std::string RemoveTrailingSlashes(std::string filename) const
int AddConfiguration(std::string configurationFilename, std::string configurationName="")
const char Option_t
Definition: External.C:48
AliEmcalList * fOutput
! List which owns the output histograms to be saved
bool Bool_t
Definition: External.C:53
std::string fAutoConfigureIdentifier
How the auto configuration YAML file should be identified. (for example, "rehlersTrain") ...
std::string DeterminePythiaXSecFilename(TString baseFileName, TString pythiaBaseFilename, bool testIfExists) const
Int_t fUpperEntry
! Last entry of the current tree to be used for embedding
Int_t fFilenameIndex
Index of vector containing paths to files to embed.
double fPythiaCrossSectionFromFile
! Average pythia cross section extracted from a xsec file.
std::vector< std::string > fFilenames
Paths to the files to embed.
std::string fAutoConfigureTrainTypePath
The path associated with the train type (for example, "PWGJE/Jets_EMC_PbPb/")
TString fFilePattern
File pattern to select AliEn files using alien_find.
int fPythiaTrials
! Number of pythia trials for the current event (extracted from the pythia header).
TList * OpenFile(const char *fname)
Definition: DrawAnaELoss.C:65