AliPhysics  d0c3a41 (d0c3a41)
 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  fAnchorRun(-1),
76  fNPtHardBins(1),
77  fPtHardBin(-1),
78  fRandomEventNumberAccess(kFALSE),
79  fRandomFileAccess(kTRUE),
80  fCreateHisto(true),
81  fAutoConfigurePtHardBins(false),
82  fAutoConfigureBasePath(""),
83  fAutoConfigureTrainTypePath(""),
84  fAutoConfigureIdentifier(""),
85  fFilePattern(""),
86  fInputFilename(""),
87  fFileListFilename(""),
88  fFilenameIndex(-1),
89  fFilenames(),
90  fPythiaCrossSectionFilenames(),
91  fExternalFile(nullptr),
92  fChain(nullptr),
93  fCurrentEntry(0),
94  fLowerEntry(0),
95  fUpperEntry(0),
96  fOffset(0),
97  fMaxNumberOfFiles(0),
98  fFileNumber(0),
99  fHistManager(),
100  fOutput(nullptr),
101  fExternalEvent(nullptr),
102  fExternalHeader(nullptr),
103  fPythiaHeader(nullptr),
104  fPythiaTrials(0),
105  fPythiaTrialsFromFile(0),
106  fPythiaCrossSection(0.),
107  fPythiaCrossSectionFromFile(0.),
108  fPythiaPtHard(0.)
109 {
110  if (fgInstance != nullptr) {
111  AliError("An instance of AliAnalysisTaskEmcalEmbeddingHelper already exists: it will be deleted!!!");
112  delete fgInstance;
113  }
114 
115  fgInstance = this;
116 }
117 
124  AliAnalysisTaskSE(name),
125  fTriggerMask(AliVEvent::kAny),
126  fMCRejectOutliers(false),
127  fPtHardJetPtRejectionFactor(4),
128  fZVertexCut(10),
129  fMaxVertexDist(999),
130  fInitializedConfiguration(false),
131  fInitializedNewFile(false),
132  fInitializedEmbedding(false),
133  fWrappedAroundTree(false),
134  fTreeName("aodTree"),
135  fAnchorRun(-1),
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  fPythiaCrossSectionFilenames(),
151  fExternalFile(nullptr),
152  fChain(nullptr),
153  fCurrentEntry(0),
154  fLowerEntry(0),
155  fUpperEntry(0),
156  fOffset(0),
157  fMaxNumberOfFiles(0),
158  fFileNumber(0),
159  fHistManager(name),
160  fOutput(nullptr),
161  fExternalEvent(nullptr),
162  fExternalHeader(nullptr),
163  fPythiaHeader(nullptr),
164  fPythiaTrials(0),
165  fPythiaTrialsFromFile(0),
166  fPythiaCrossSection(0.),
167  fPythiaCrossSectionFromFile(0.),
168  fPythiaPtHard(0.)
169 {
170  if (fgInstance != 0) {
171  AliError("An instance of AliAnalysisTaskEmcalEmbeddingHelper already exists: it will be deleted!!!");
172  delete fgInstance;
173  }
174 
175  fgInstance = this;
176 
177  if (fCreateHisto) {
178  DefineOutput(1, AliEmcalList::Class());
179  }
180 }
181 
188 {
189  if (fgInstance == this) fgInstance = nullptr;
190  if (fExternalEvent) delete fExternalEvent;
191  if (fExternalFile) {
192  fExternalFile->Close();
193  delete fExternalFile;
194  }
195 }
196 
202 {
203  // Get file list
204  bool result = GetFilenames();
205 
206  if (result) {
208  }
209 
210  return result;
211 }
212 
237 {
238  // Determine the pattern filename if not yet set
239  if (fInputFilename == "") {
240  if (fTreeName == "aodTree") {
241  fInputFilename = "AliAOD.root";
242  }
243  else if (fTreeName == "esdTree") {
244  fInputFilename = "AliESDs.root";
245  }
246  else {
247  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()));
248  }
249  }
250 
251  // Retrieve filenames if we don't have them yet.
252  if (fFilenames.size() == 0)
253  {
254  // Handle pt hard bin auto configuration
256  {
257  if (fPtHardBin > 0) {
258  AliFatal("Requested both pt hard bin auto configuration and selected a non-zero pt hard bin. These are incompatible options. Please check your configuration.");
259  }
260  bool success = AutoConfigurePtHardBins();
261  if (success == false) {
262  AliFatal("Pt hard bin auto configuration requested, but it failed. Please check the logs.\n");
263  }
264  }
265 
266  // Handle if fPtHardBin or fAnchorRun are set
267  // This will require formatting the file pattern in the proper way to support these substitutions
268  if (fPtHardBin != -1 && fFilePattern != "") {
269  if (fAnchorRun > 0) {
270  fFilePattern = TString::Format(fFilePattern, fAnchorRun, fPtHardBin);
271  }
272  else {
273  fFilePattern = TString::Format(fFilePattern, fPtHardBin);
274  }
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  // "turl" corresponds to the full AliEn url
313  outFile << result->GetKey(i, "turl") << "\n";
314  }
315  outFile.close();
316  }
317  else {
318  AliErrorStream() << "Failed to run grid query\n";
319  return false;
320  }
321  }
322 
323  // Handle a filelist on AliEn
324  if (fFileListFilename.Contains("alien://")) {
325  // Check if we already used the file pattern
326  if (usedFilePattern) {
327  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";
328  }
329 
330  // Determine the local filename and copy file to local directory
331  std::string alienFilename = fFileListFilename.Data();
332  fFileListFilename = gSystem->BaseName(alienFilename.c_str());
334 
335  TFile::Cp(alienFilename.c_str(), fFileListFilename.Data());
336  }
337 
338  std::ifstream inputFile(fFileListFilename);
339 
340  // Copy available files into the filenames vector
341  // From:: https://stackoverflow.com/a/8365247
342  std::copy(std::istream_iterator<std::string>(inputFile),
343  std::istream_iterator<std::string>(),
344  std::back_inserter(fFilenames));
345 
346  inputFile.close();
347  }
348 
349  if (fFilenames.size() == 0) {
350  AliFatal(TString::Format("Filenames from pattern \"%s\" and file list \"%s\" yielded an empty list!", fFilePattern.Data(), fFileListFilename.Data()));
351  }
352 
353  // Add "#" to files in there are any zip files
354  // It is require to open the proper root file within the zip
355  for (auto filename : fFilenames)
356  {
357  if (filename.find(".zip") != std::string::npos && filename.find("#") == std::string::npos) {
358  filename += "#";
360  if (fTreeName == "aodTree") {
361  filename += "#AliAOD.root";
362  }
363  else if (fTreeName == "esdTree") {
364  filename += "#AliESDs.root";
365  }
366  else {
367  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()));
368  return false;
369  }
370  }
371  }
372 
373  AliInfoStream() << "Found " << fFilenames.size() << " files to embed\n";
374  return true;
375 }
376 
393 {
394  bool returnValue = false;
395 
396  AliInfoStream() << "Attempting to auto configure pt hard bins.\n";
397  // YAML configuration containing pt hard bin to train number mapping
399 
400  // Handle AliEn explicitly here since the default base path contains "alien://"
401  if (fAutoConfigureBasePath.find("alien://") != std::string::npos && !gGrid) {
402  AliInfo("Trying to connect to AliEn ...");
403  TGrid::Connect("alien://");
404  }
405 
406  // Get train ID
407  // Need to get the char * directly because it may be null.
408  const char * trainNumberStr = gSystem->Getenv("TRAIN_RUN_ID");
409  std::stringstream trainNumberSS;
410  if (trainNumberStr) {
411  trainNumberSS << trainNumberStr;
412  }
413  if (trainNumberSS.str() == "") {
414  AliFatal("Cannot retrieve train ID.");
415  }
416  // Extract train number from the string
417  int trainNumber;
418  trainNumberSS >> trainNumber;
419 
420  // Determine the file path
422  filename += "/";
424  filename += "/";
426  // Add ".yaml" if it is not already there
427  std::string yamlExtension = ".yaml";
428  if (filename.find(yamlExtension) == std::string::npos) {
429  filename += yamlExtension;
430  }
431 
432  // Check if file exists
433  if (gSystem->AccessPathName(filename.c_str())) {
434  // File _does not_ exist
435  AliInfoStream() << "Train pt hard bin configuration file not available, so creating a new empty configuration named \"" << fAutoConfigureIdentifier << "\".\n";
436  // Use an empty configuration
438  }
439  else {
440  AliInfoStream() << "Opening configuration located at \"" << filename << "\".\n";
441  // Use the existing configuration
443  }
444 
445  // Look for each pt hard bin, and then retrieve the corresponding train number
446  // Once an open pt hard bin is found, add the current train number
447  int tempTrainNumber = -1;
448  bool getPropertyReturnValue = false;
449  std::stringstream propertyName;
450  for (int ptHardBin = 1; ptHardBin <= fNPtHardBins; ptHardBin++)
451  {
452  propertyName.str("");
453  propertyName << ptHardBin;
454  getPropertyReturnValue = config.GetProperty(propertyName.str(), tempTrainNumber, false);
455  if (getPropertyReturnValue != true) {
456  AliInfoStream() << "Train " << trainNumber << " will use pt hard bin " << ptHardBin << ".\n";
457  // We have determine our pt hard bin!
458  fPtHardBin = ptHardBin;
459 
460  // Write the train number back out to the YAML configuration and save it
461  config.WriteProperty(propertyName.str(), trainNumber, fAutoConfigureIdentifier);
463 
464  // NOTE: Cannot clean up the yaml file on the last pt hard bin because the train can be launched
465  // multiple times due to tests, etc. Therefore, we have to accept that we are leaving around used
466  // yaml config files.
467 
468  // We are done - continue on.
469  returnValue = true;
470  break;
471  }
472  else {
473  AliDebugStream(2) << "Found pt hard bin " << ptHardBin << " corresponding to train number " << trainNumber << ".\n";
474  // If train was already allocated (say, by a test train), then use that pt hard bin
475  if (tempTrainNumber == trainNumber) {
476  AliInfoStream() << "Train run number " << trainNumber << " was already found assigned to pt hard bin " << ptHardBin << ". That pt hard bin will be used.\n";
477  fPtHardBin = ptHardBin;
478 
479  // We are done - continue on.
480  returnValue = true;
481  break;
482  }
483  // Otherwise, nothing to be done.
484  }
485  }
486 
487  return returnValue;
488 }
489 
498 {
499  std::string tempStr = "";
500  if (fFileListFilename == "") {
501  tempStr = "fileList";
502  }
503  TUUID tempUUID;
504  tempStr += ".";
505  tempStr += tempUUID.AsString();
506  tempStr += ".txt";
507 
508  return tempStr;
509 }
510 
519 {
520  while (filename.rbegin() != filename.rend() && *(filename.rbegin()) == '/') {
521  filename.pop_back();
522  }
523 
524  return filename;
525 }
526 
532 {
533  // This determines which file is added first to the TChain, thus determining the order of processing
534  // Random file access. Only do this if the user has no set the filename index and request random file access
535  if (fFilenameIndex == -1 && fRandomFileAccess) {
536  // Floor ensures that we it doesn't overflow
537  TRandom3 rand(0);
538  fFilenameIndex = TMath::FloorNint(rand.Rndm()*fFilenames.size());
539  // +1 to account for the fact that the filenames vector is 0 indexed.
540  AliInfo(TString::Format("Starting with random file number %i!", fFilenameIndex+1));
541  }
542  // If not random file access, then start from the beginning
543  if (fFilenameIndex < 0 || static_cast<UInt_t>(fFilenameIndex) >= fFilenames.size()) {
544  // Skip notifying on -1 since it will likely be set there due to constructor.
545  if (fFilenameIndex != -1) {
546  AliWarning(TString::Format("File index %i out of range from 0 to %lu! Resetting to 0!", fFilenameIndex, fFilenames.size()));
547  }
548  fFilenameIndex = 0;
549  }
550 
551  // +1 to account for the fact that the filenames vector is 0 indexed.
552  AliInfo(TString::Format("Starting with file number %i out of %lu", fFilenameIndex+1, fFilenames.size()));
553 }
554 
564 {
565  Int_t attempts = -1;
566 
567  do {
568  // Reset to start of tree
569  if (fCurrentEntry == fUpperEntry) {
571  fWrappedAroundTree = true;
572  }
573 
575  // Continue with GetEntry as normal
576  }
577  else {
578  // NOTE: On transition from one file to the next, this calls the next entry that would be expected.
579  // However, if it is for the last file, it tries to GetEntry() of one entry past the end of the last file.
580  // Normally, this would be a problem, however GetEntry() just doesn't fill the fields of an invalid index
581  // instead of throwing an error. So "invalid values" are filled for a file that doesn't exist, but then
582  // they are immediately replaced by the lines below that reset the access values and re-init the tree.
583  // The benefit of this approach is it simplies file counting (we don't need to carefully increment here
584  // and in InitTree()) and preserves the desired behavior when we are not at the last file.
585  InitTree();
586  }
587 
588  // Load current event
589  // Can be a simple less than, because fFileNumber counts from 0.
591  fChain->GetEntry(fCurrentEntry);
592  }
593  else {
594  AliError("====================================================================================================");
595  AliError("== No more files available to embed from the TChain! Restarting from the beginning of the TChain! ==");
596  AliError("== Be careful to check that this is the desired action! ==");
597  AliError("====================================================================================================");
598 
599  // Reset the relevant access values
600  // fCurrentEntry and fLowerEntry are automatically reset in InitTree()
601  fFileNumber = 0;
602  fUpperEntry = 0;
603 
604  // Re-init back to the start
605  InitTree();
606 
607  // Access the relevant entry
608  // We are certain that fFileNumber is less than fMaxNumberOfFiles, so we are resetting to start
609  fChain->GetEntry(fCurrentEntry);
610  }
611  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));
612 
613  // Set relevant event properties
615 
616  // Increment current entry
617  fCurrentEntry++;
618 
619  // Provide a check for number of attempts
620  attempts++;
621  if (attempts == 1000)
622  AliWarning("After 1000 attempts no event has been accepted by the event selection (trigger, centrality...)!");
623 
624  // Record event properties
625  if (fCreateHisto) {
627  }
628 
629  } while (!IsEventSelected());
630 
631  if (fCreateHisto) {
632  fHistManager.FillTH1("fHistEventCount", "Accepted");
633  fHistManager.FillTH1("fHistEmbeddedEventsAttempted", attempts);
634  }
635 
636  if (!fChain) return kFALSE;
637 
638  return kTRUE;
639 }
640 
646 {
647  AliDebug(4, "Set event properties");
648  fExternalHeader = fExternalEvent->GetHeader();
649 
650  // Handle pythia header if AOD
651  AliAODMCHeader* aodMCH = dynamic_cast<AliAODMCHeader*>(fExternalEvent->FindListObject(AliAODMCHeader::StdBranchName()));
652  if (aodMCH) {
653  for (UInt_t i = 0;i<aodMCH->GetNCocktailHeaders();i++) {
654  fPythiaHeader = dynamic_cast<AliGenPythiaEventHeader*>(aodMCH->GetCocktailHeader(i));
655  if (fPythiaHeader) break;
656  }
657  }
658 
659  if (fPythiaHeader)
660  {
661  fPythiaCrossSection = fPythiaHeader->GetXsection();
662  fPythiaTrials = fPythiaHeader->Trials();
663  fPythiaPtHard = fPythiaHeader->GetPtHard();
664  // It is identically zero if the available is not available
665  if (fPythiaCrossSection == 0.) {
666  AliDebugStream(4) << "Taking the pythia cross section avg from the xsec file.\n";
668  }
669  // It is identically zero if the available is not available
670  if (fPythiaTrials == 0.) {
671  AliDebugStream(4) << "Taking the pythia trials avg from the xsec file.\n";
673  }
674  // Pt hard is inherently event-by-event and cannot by taken as a avg quantity.
675 
676  AliDebugStream(4) << "Pythia header is defined!\n";
677  AliDebugStream(4) << "fPythiaCrossSection: " << fPythiaCrossSection << "\n";
678  }
679 }
680 
685 {
686  // Fill trials, xsec, pt hard
687  fHistManager.FillTH1("fHistTrials", fPtHardBin, fPythiaTrials);
689  fHistManager.FillTH1("fHistPtHard", fPythiaPtHard);
690 }
691 
698 {
700  return kTRUE;
701  }
702 
703  if (fCreateHisto) {
704  // Keep count of number of rejected events
705  fHistManager.FillTH1("fHistEventCount", "Rejected");
706  }
707 
708  return kFALSE;
709 }
710 
717 {
718  // Physics selection
719  if (fTriggerMask != AliVEvent::kAny) {
720  UInt_t res = 0;
721  const AliESDEvent *eev = dynamic_cast<const AliESDEvent*>(fExternalEvent);
722  if (eev) {
723  AliFatal("Event selection is not implemented for embedding ESDs.");
724  // Unfortunately, the normal method of retrieving the trigger mask (commented out below) doesn't work for the embedded event since we don't
725  // 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
726  // probably best to avoid it if possible.
727  //
728  // Suggestions are welcome here!
729  //res = (dynamic_cast<AliInputEventHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected();
730  } else {
731  const AliAODEvent *aev = dynamic_cast<const AliAODEvent*>(fExternalEvent);
732  if (aev) {
733  res = (dynamic_cast<AliVAODHeader*>(aev->GetHeader()))->GetOfflineTrigger();
734  }
735  }
736 
737  if ((res & fTriggerMask) == 0) {
738  AliDebug(3, Form("Event rejected due to physics selection. Event trigger mask: %d, trigger mask selection: %d.",
739  res, fTriggerMask));
740  if (fCreateHisto) {
741  fHistManager.FillTH1("fHistEmbeddedEventRejection", "PhysSel", 1);
742  }
743  return kFALSE;
744  }
745  }
746 
747  // Vertex selection
748  Double_t externalVertex[3]={0};
749  Double_t inputVertex[3]={0};
750  const AliVVertex *externalVert = fExternalEvent->GetPrimaryVertex();
751  const AliVVertex *inputVert = AliAnalysisTaskSE::InputEvent()->GetPrimaryVertex();
752  if (externalVert && inputVert) {
753  externalVert->GetXYZ(externalVertex);
754  inputVert->GetXYZ(inputVertex);
755 
756  if (TMath::Abs(externalVertex[2]) > fZVertexCut) {
757  AliDebug(3, Form("Event rejected due to Z vertex selection. Event Z vertex: %f, Z vertex cut: %f",
758  externalVertex[2], fZVertexCut));
759  if (fCreateHisto) {
760  fHistManager.FillTH1("fHistEmbeddedEventRejection", "Vz", 1);
761  }
762  return kFALSE;
763  }
764  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]));
765  if (dist > fMaxVertexDist) {
766  AliDebug(3, Form("Event rejected because the distance between the current and embedded vertices is > %f. "
767  "Current event vertex (%f, %f, %f), embedded event vertex (%f, %f, %f). Distance = %f",
768  fMaxVertexDist, inputVertex[0], inputVertex[1], inputVertex[2], externalVertex[0], externalVertex[1], externalVertex[2], dist));
769  if (fCreateHisto) {
770  fHistManager.FillTH1("fHistEmbeddedEventRejection", "VertexDist", 1);
771  }
772  return kFALSE;
773  }
774  }
775 
776  // Check for pt hard bin outliers
778  {
779  // Pythia jet / pT-hard > factor
780  // This corresponds to "condition 1" in AliAnalysisTaskEmcal
781  // NOTE: The other "conditions" defined there are not really suitable to define here, since they
782  // depend on the input objects of the event
783  if (fPtHardJetPtRejectionFactor > 0.) {
784  TLorentzVector jet;
785 
786  Int_t nTriggerJets = fPythiaHeader->NTriggerJets();
787 
788  AliDebugStream(4) << "Pythia Njets: " << nTriggerJets << ", pT Hard: " << fPythiaPtHard << "\n";
789 
790  Float_t tmpjet[]={0,0,0,0};
791  for (Int_t iJet = 0; iJet< nTriggerJets; iJet++) {
792  fPythiaHeader->TriggerJet(iJet, tmpjet);
793 
794  jet.SetPxPyPzE(tmpjet[0],tmpjet[1],tmpjet[2],tmpjet[3]);
795 
796  AliDebugStream(5) << "Pythia jet " << iJet << ", pycell jet pT: " << jet.Pt() << "\n";
797 
798  //Compare jet pT and pt Hard
799  if (jet.Pt() > fPtHardJetPtRejectionFactor * fPythiaPtHard) {
800  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";
801  fHistManager.FillTH1("fHistEmbeddedEventRejection", "MCOutlier", 1);
802  return kFALSE;
803  }
804  }
805  }
806  }
807 
808  return kTRUE;
809 }
810 
817 {
818  if (!fChain) return kFALSE;
819 
820  if (!fExternalEvent) {
821  if (fTreeName == "aodTree") {
822  fExternalEvent = new AliAODEvent();
823  }
824  else if (fTreeName == "esdTree") {
825  fExternalEvent = new AliESDEvent();
826  }
827  else {
828  AliError(Form("Tree name %s not recognized!", fTreeName.Data()));
829  return kFALSE;
830  }
831  }
832 
833  fExternalEvent->ReadFromTree(fChain, fTreeName);
834 
835  return kTRUE;
836 }
837 
844 {
845  SetupEmbedding();
846 
847  if (!fCreateHisto) {
848  return;
849  }
850 
851  // Create output list
852  OpenFile(1);
853  fOutput = new AliEmcalList();
854  fOutput->SetOwner();
855 
856  // Create histograms
857  TString histName;
858  TString histTitle;
859 
860  // Cross section
861  histName = "fHistXsection";
862  histTitle = "Pythia Cross Section;p_{T} hard bin; XSection";
863  fHistManager.CreateTProfile(histName, histTitle, fNPtHardBins, 0, fNPtHardBins);
864 
865  // Trials
866  histName = "fHistTrials";
867  histTitle = "Number of Pythia Trials;p_{T} hard bin;Trials";
868  fHistManager.CreateTH1(histName, histTitle, fNPtHardBins, 0, fNPtHardBins);
869 
870  // Pt hard spectra
871  histName = "fHistPtHard";
872  histTitle = "p_{T} Hard Spectra;p_{T} hard;Counts";
873  fHistManager.CreateTH1(histName, histTitle, 500, 0, 1000);
874 
875  // Count of accepted and rejected events
876  histName = "fHistEventCount";
877  histTitle = "fHistEventCount;Result;Count";
878  auto histEventCount = fHistManager.CreateTH1(histName, histTitle, 2, 0, 2);
879  histEventCount->GetXaxis()->SetBinLabel(1,"Accepted");
880  histEventCount->GetXaxis()->SetBinLabel(2,"Rejected");
881 
882  // Event rejection reason
883  histName = "fHistEmbeddedEventRejection";
884  histTitle = "Reasons to reject embedded event";
885  std::vector<std::string> binLabels = {"PhysSel", "MCOutlier", "Vz", "VertexDist"};
886  auto fHistEmbeddedEventRejection = fHistManager.CreateTH1(histName, histTitle, binLabels.size(), 0, binLabels.size());
887  // Set label names
888  for (unsigned int i = 1; i <= binLabels.size(); i++) {
889  fHistEmbeddedEventRejection->GetXaxis()->SetBinLabel(i, binLabels.at(i-1).c_str());
890  }
891  fHistEmbeddedEventRejection->GetYaxis()->SetTitle("Counts");
892 
893  // Rejected events in embedded event selection
894  histName = "fHistEmbeddedEventsAttempted";
895  histTitle = "Number of embedded events rejected by event selection before success;Number of rejected events;Counts";
896  fHistManager.CreateTH1(histName, histTitle, 200, 0, 200);
897 
898  // Number of files embedded
899  histName = "fHistNumberOfFilesEmbedded";
900  histTitle = "Number of files which contributed events to be embedded";
901  fHistManager.CreateTH1(histName, histTitle, 1, 0, 2);
902 
903  // File number which was embedded
904  histName = "fHistAbsoluteFileNumber";
905  histTitle = "Number of times each absolute file number was embedded";
906  fHistManager.CreateTH1(histName, histTitle, fMaxNumberOfFiles, 0, fMaxNumberOfFiles);
907 
908  // Add all histograms to output list
909  TIter next(fHistManager.GetListOfHistograms());
910  TObject* obj = 0;
911  while ((obj = next())) {
912  fOutput->Add(obj);
913  }
914 
915  PostData(1, fOutput);
916 }
917 
925 {
926  // Determine which file to start with
928 
929  // Setup TChain
930  fChain = new TChain(fTreeName);
931 
932  // Determine whether AliEn is needed
933  bool requiresAlien = false;
934  for (auto filename : fFilenames)
935  {
936  if (filename.find("alien://") != std::string::npos) {
937  requiresAlien = true;
938  }
939  }
940 
941  if (requiresAlien && !gGrid) {
942  AliInfo("Trying to connect to AliEn ...");
943  TGrid::Connect("alien://");
944  }
945 
946  // Add files for TChain
947  // See: https://stackoverflow.com/a/8533198
948  bool wrapped = false;
949  TString baseFileName = "";
950  // Hanlde the pythia cross section file list
951  bool failedEntirelyToFindFile = false;
952  TString pythiaXSecFilename = "";
953  TString pythiaBaseFilename = "";
954  std::vector <std::string> pythiaBaseFilenames = {"pyxsec.root", "pyxsec_hists.root"};
955  for (auto filename = fFilenames.begin() + fFilenameIndex; (filename != fFilenames.begin() + fFilenameIndex || !wrapped); filename++)
956  {
957  // Wraps the loop back around to the beginning
958  if (filename == fFilenames.end())
959  {
960  // Explicit check is needed. Otherwise, an offset of 0 would load the 0th entry twice.
961  if (fFilenameIndex == 0) {
962  break;
963  }
964  filename = fFilenames.begin();
965  wrapped = true;
966  }
967 
968  // AccessPathName() cannot handle the "#", so we need to strip it to check that the file exists.
969  baseFileName = filename->c_str();
970  if (baseFileName.Contains(".zip#")) {
971  Ssiz_t pos = baseFileName.Last('#');
972  baseFileName.Remove(pos);
973  }
974 
975  // Ensure that the file is accessible
976  if (gSystem->AccessPathName(baseFileName)) {
977  AliError(Form("File %s does not exist! Skipping!", baseFileName.Data()));
978  // Do not process the file if it is unaccessible, but continue processing
979  continue;
980  }
981 
982  // Add to the Chain
983  AliDebugStream(4) << "Adding file to the embedded input chain \"" << filename->c_str() << "\".\n";
984  fChain->Add(filename->c_str());
985 
986  // Handle the pythia cross section (if it exists)
987  // Determiner which file it exists in (if it does exist)
988  if (pythiaBaseFilename == "" && failedEntirelyToFindFile == false) {
989  AliInfoStream() << "Attempting to determine pythia cross section filename. It can be normal to see some TFile::Init() errors!\n";
990  for (auto name : pythiaBaseFilenames) {
991  pythiaXSecFilename = DeterminePythiaXSecFilename(baseFileName, name, true);
992  if (pythiaXSecFilename != "") {
993  AliDebugStream(4) << "Found pythia cross section base filename \"" << name.c_str() << "\"\n";
994  pythiaBaseFilename = name;
995  break;
996  }
997  }
998 
999  if (pythiaBaseFilename == "") {
1000  // Failed entirely - just give up on this
1001  AliErrorStream() << "Failed to find pythia x sec file! Continuing with only the pythia header!\n";
1002  failedEntirelyToFindFile = true;
1003  }
1004  else {
1005  AliInfoStream() << "Found pythia cross section file \"" << pythiaBaseFilename.Data() << "\".\n";
1006  }
1007  }
1008  // Retrieve the value based on the previously determined filename
1009  // 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
1010  if (failedEntirelyToFindFile == false) {
1011  // Can still check whether it exists here, but we don't necessarily have to!
1012  // However, we won't check to ensure that rapid file access on AliEn doesn't cause it to crash!
1013  pythiaXSecFilename = DeterminePythiaXSecFilename(baseFileName, pythiaBaseFilename, false);
1014 
1015  AliDebugStream(4) << "Adding pythia cross section file \"" << pythiaXSecFilename.Data() << "\".\n";
1016 
1017  // They will automatically be ordered the same as the files to embed!
1018  fPythiaCrossSectionFilenames.push_back(pythiaXSecFilename.Data());
1019  }
1020  }
1021 
1022  // Keep track of the total number of files in the TChain to ensure that we don't start repeating within the chain
1023  fMaxNumberOfFiles = fChain->GetListOfFiles()->GetEntries();
1024 
1025  if (fFilenames.size() > fMaxNumberOfFiles) {
1026  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));
1027  }
1028 
1029  // Setup input event
1030  Bool_t res = InitEvent();
1031  if (!res) return kFALSE;
1032 
1033  return kTRUE;
1034 }
1035 
1046 std::string AliAnalysisTaskEmcalEmbeddingHelper::DeterminePythiaXSecFilename(TString baseFileName, TString pythiaBaseFilename, bool testIfExists) const
1047 {
1048  std::string pythiaXSecFilename = "";
1049 
1050  // Handle different file types
1051  if (baseFileName.Contains(".zip"))
1052  {
1053  // Hanlde zip files
1054  pythiaXSecFilename = baseFileName;
1055  pythiaXSecFilename += "#";
1056  pythiaXSecFilename += pythiaBaseFilename;
1057 
1058  // Check if the file is accessible
1059  if (testIfExists) {
1060  // Unfortunately, we cannot test for the existence of a file in an archive.
1061  // Instead, we have to tolerate TFile throwing an error (maximum of two).
1062  std::unique_ptr<TFile> fTemp(TFile::Open(pythiaXSecFilename.c_str(), "READ"));
1063 
1064  if (!fTemp) {
1065  AliDebugStream(4) << "File " << pythiaXSecFilename.c_str() << " does not exist!\n";
1066  pythiaXSecFilename = "";
1067  }
1068  else {
1069  AliDebugStream(4) << "Found pythia cross section file \"" << pythiaXSecFilename.c_str() << "\".\n";
1070  }
1071  }
1072  }
1073  else
1074  {
1075  // Hanlde normal root files
1076  pythiaXSecFilename = gSystem->DirName(baseFileName);
1077  pythiaXSecFilename += "/";
1078  pythiaXSecFilename += pythiaBaseFilename;
1079 
1080  // Check if the file is accessible
1081  if (testIfExists) {
1082  if (gSystem->AccessPathName(pythiaXSecFilename.c_str())) {
1083  AliDebugStream(4) << "File " << pythiaXSecFilename.c_str() << " does not exist!\n";
1084  pythiaXSecFilename = "";
1085  }
1086  else {
1087  AliDebugStream(4) << "Found pythia cross section file \"" << pythiaXSecFilename.c_str() << "\".\n";
1088  }
1089  }
1090  }
1091 
1092  return pythiaXSecFilename;
1093 }
1094 
1101 {
1102  if (fInitializedConfiguration == false) {
1103  AliFatal("The configuration is not initialized. Check that Initialize() was called!");
1104  }
1105 
1106  // Setup TChain
1107  Bool_t res = SetupInputFiles();
1108  if (!res) { return; }
1109 
1110  // Note if getting random event access
1112  AliInfo("Random event number access enabled!");
1113  }
1114 
1115  fInitializedEmbedding = kTRUE;
1116 }
1117 
1129 {
1130  // Load first entry of the (next) file so that we can query information about it
1131  // (it is unaccessible otherwise).
1132  // Since fUpperEntry is the total number of entries, loading it will retrieve the
1133  // next tree (in the next file) since entries are indexed starting from 0.
1134  fChain->GetEntry(fUpperEntry);
1135 
1136  // Determine tree size and current entry
1137  // Set the limits of the new tree
1139  // Fine to be += as long as we started at 0
1140  fUpperEntry += fChain->GetTree()->GetEntries();
1141 
1142  // Jump ahead at random if desired
1143  // Determines the offset into the tree
1145  TRandom3 rand(0);
1146  fOffset = TMath::Nint(rand.Rndm()*(fUpperEntry-fLowerEntry))-1;
1147  }
1148  else {
1149  fOffset = 0;
1150  }
1151 
1152  // Sets which entry to start if the try
1154 
1155  // Keep track of the number of files that we have gone through
1156  // To start from 0, we only increment if fLowerEntry > 0
1157  if (fLowerEntry > 0) {
1158  fFileNumber++;
1159  }
1160 
1161  // Add to the count the number of files which were embedded
1162  fHistManager.FillTH1("fHistNumberOfFilesEmbedded", 1);
1163  fHistManager.FillTH1("fHistAbsoluteFileNumber", (fFileNumber + fFilenameIndex) % fMaxNumberOfFiles);
1164 
1165  // Check for pythia cross section and extract if possible
1166  // fFileNumber corresponds to the next file
1167  // If there are pythia filenames, the number of match the file number of the tree.
1168  // If we previously gave up on extracting then there should be no entires
1169  if (fPythiaCrossSectionFilenames.size() > 0) {
1170  // Need to check that fFileNumber is smaller than the size of the vector because we don't check if
1173 
1174  if (!success) {
1175  AliDebugStream(3) << "Failed to retrieve cross section from xsec file. Will still attempt to get the information from the header.\n";
1176  }
1177  }
1178  else {
1179  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";
1180  }
1181  }
1182 
1183  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));
1184  // NOTE: Cannot use this print message, as it is possible that fMaxNumberOfFiles != fFilenames.size() because
1185  // invalid filenames may be included in the fFilenames count!
1186  //AliDebug(2, TString::Format("Will start embedding file %i as the %ith file beginning from entry %i.", (fFilenameIndex + fFileNumber) % fMaxNumberOfFiles, fFileNumber, fCurrentEntry));
1187 
1188  // (re)set whether we have wrapped the tree
1189  fWrappedAroundTree = false;
1190 
1191  // Note that the tree in the new file has been initialized
1192  fInitializedNewFile = kTRUE;
1193 }
1194 
1203 {
1204  std::unique_ptr<TFile> fxsec(TFile::Open(pythiaFileName.c_str()));
1205 
1206  if (fxsec)
1207  {
1208  int trials = 0;
1209  double crossSection = 0;
1210  double nEvents = 0;
1211  // Check if it's a tree
1212  TTree *xtree = dynamic_cast<TTree*>(fxsec->Get("Xsection"));
1213  if (xtree) {
1214  UInt_t ntrials = 0;
1215  Double_t xsection = 0;
1216  xtree->SetBranchAddress("xsection",&xsection);
1217  xtree->SetBranchAddress("ntrials",&ntrials);
1218  xtree->GetEntry(0);
1219  trials = ntrials;
1220  crossSection = xsection;
1221  // TODO: Test this on a file which has pyxsec.root!
1222  nEvents = 1.;
1223  AliFatal("Have no tested pyxsec.root files. Need to determine the proper way to get nevents!!");
1224  }
1225  else {
1226  // Check if it's instead the histograms
1227  // find the tlist we want to be independtent of the name so use the Tkey
1228  TKey* key = static_cast<TKey*>(fxsec->GetListOfKeys()->At(0));
1229  if (!key) return false;
1230  TList *list = dynamic_cast<TList*>(key->ReadObj());
1231  if (!list) return false;
1232  TProfile * crossSectionHist = static_cast<TProfile*>(list->FindObject("h1Xsec"));
1233  // check for failure
1234  if(!(crossSectionHist->GetEntries())) {
1235  // No cross seciton information available - fall back to raw
1236  AliErrorStream() << "No cross section information available in file \"" << fxsec->GetName() << "\". Will still attempt to extract cross section information from pythia header.\n";
1237  } else {
1238  // Cross section histogram filled - take it from there
1239  crossSection = crossSectionHist->GetBinContent(1);
1240  if(!crossSection) AliErrorStream() << GetName() << ": Cross section 0 for file " << pythiaFileName << std::endl;
1241  }
1242  TH1F * trialsHist = static_cast<TH1F*>(list->FindObject("h1Trials"));
1243  trials = trialsHist->GetBinContent(1);
1244  nEvents = trialsHist->GetEntries();
1245  }
1246 
1247  // If successful in retrieveing the values, normalizae the xsec and trials by the number of events
1248  // in the file. This way, we can use it as an approximate event-by-event value
1249  // We do not want to just use the overall value because some of the events may be rejected by various
1250  // event selections, so we only want that ones that were actually use. The easiest way to do so is by
1251  // filling it for each event.
1252  fPythiaTrialsFromFile = trials/nEvents;
1253  // Do __NOT__ divide by nEvents here! The value is already from a TProfile and therefore is already the mean!
1254  fPythiaCrossSectionFromFile = crossSection;
1255 
1256  return true;
1257  }
1258  else {
1259  AliDebugStream(3) << "Unable to open file \"" << pythiaFileName << "\". Will attempt to use values from the hader.";
1260  }
1261 
1262  // Could not open file
1263  return false;
1264 }
1265 
1272 {
1273  if (!fInitializedEmbedding) {
1274  AliError("Chain not initialized before running! Setting up now.");
1275  SetupEmbedding();
1276  }
1277 
1278  if (!fInitializedNewFile) {
1279  InitTree();
1280  }
1281 
1282  Bool_t res = GetNextEntry();
1283 
1284  if (!res) {
1285  AliError("Unable to get the event to embed. Nothing will be embedded.");
1286  return;
1287  }
1288 
1289  if (fCreateHisto && fOutput) {
1290  PostData(1, fOutput);
1291  }
1292 }
1293 
1298 {
1299 }
1300 
1309 {
1310  // Get the pointer to the existing analysis manager via the static access method.
1311  //==============================================================================
1312  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1313  if (!mgr)
1314  {
1315  ::Error("AddTaskEmcalEmbeddingHelper", "No analysis manager to connect to.");
1316  return 0;
1317  }
1318 
1319  // Check the analysis type using the event handlers connected to the analysis manager.
1320  //==============================================================================
1321  AliVEventHandler* handler = mgr->GetInputEventHandler();
1322  if (!handler)
1323  {
1324  ::Error("AddTaskEmcalEmbeddingHelper", "This task requires an input event handler");
1325  return 0;
1326  }
1327 
1328  TString name = "AliAnalysisTaskEmcalEmbeddingHelper";
1329 
1330  AliAnalysisTaskEmcalEmbeddingHelper * mgrTask = static_cast<AliAnalysisTaskEmcalEmbeddingHelper *>(mgr->GetTask(name.Data()));
1331  if (mgrTask) return mgrTask;
1332 
1333  // Create the task that manages
1334  AliAnalysisTaskEmcalEmbeddingHelper * embeddingHelper = new AliAnalysisTaskEmcalEmbeddingHelper(name.Data());
1335 
1336  //-------------------------------------------------------
1337  // Final settings, pass to manager and set the containers
1338  //-------------------------------------------------------
1339 
1340  mgr->AddTask(embeddingHelper);
1341 
1342  // Create containers for input/output
1343  AliAnalysisDataContainer* cInput = mgr->GetCommonInputContainer();
1344 
1345  TString outputContainerName(name);
1346  outputContainerName += "_histos";
1347 
1348  AliAnalysisDataContainer * cOutput = mgr->CreateContainer(outputContainerName.Data(),
1349  TList::Class(),
1350  AliAnalysisManager::kOutputContainer,
1351  Form("%s", AliAnalysisManager::GetCommonFileName()));
1352 
1353  mgr->ConnectInput(embeddingHelper, 0, cInput);
1354  mgr->ConnectOutput(embeddingHelper, 1, cOutput);
1355 
1356  return embeddingHelper;
1357 }
1358 
1364 std::string AliAnalysisTaskEmcalEmbeddingHelper::toString(bool includeFileList) const
1365 {
1366  std::stringstream tempSS;
1367 
1368  // Show the correction components
1369  tempSS << std::boolalpha;
1370  tempSS << GetName() << ": Embedding helper configuration:\n";
1371  tempSS << "Create histos: " << fCreateHisto << "\n";
1372  tempSS << "Pt Hard Bin: " << fPtHardBin << "\n";
1373  tempSS << "N Pt Hard Bins: " << fNPtHardBins << "\n";
1374  tempSS << "Anchor Run: " << fAnchorRun << "\n";
1375  tempSS << "File pattern: \"" << fFilePattern << "\"\n";
1376  tempSS << "Input filename: \"" << fInputFilename << "\"\n";
1377  tempSS << "File list filename: \"" << fFileListFilename << "\"\n";
1378  tempSS << "Tree name: " << fTreeName << "\n";
1379  tempSS << "Random event number access: " << fRandomEventNumberAccess << "\n";
1380  tempSS << "Random file access: " << fRandomFileAccess << "\n";
1381  tempSS << "Starting file index: " << fFilenameIndex << "\n";
1382  tempSS << "Number of files to embed: " << fFilenames.size() << "\n";
1383 
1384  std::bitset<32> triggerMask(fTriggerMask);
1385  tempSS << "\nEmbedded event settings:\n";
1386  tempSS << "Trigger mask (binary): " << triggerMask << "\n";
1387  tempSS << "Reject outliers: " << fMCRejectOutliers << "\n";
1388  tempSS << "Pt hard jet pt rejection factor: " << fPtHardJetPtRejectionFactor << "\n";
1389  tempSS << "Z vertex cut: " << fZVertexCut << "\n";
1390  tempSS << "Max vertex distance: " << fMaxVertexDist << "\n";
1391 
1392  if (includeFileList) {
1393  tempSS << "\nFiles to embed:\n";
1394  for (auto filename : fFilenames) {
1395  tempSS << "\t" << filename << "\n";
1396  }
1397  }
1398 
1399  return tempSS.str();
1400 }
1401 
1409 std::ostream & AliAnalysisTaskEmcalEmbeddingHelper::Print(std::ostream & in) const {
1410  in << toString();
1411  return in;
1412 }
1413 
1422 std::ostream & operator<<(std::ostream & in, const AliAnalysisTaskEmcalEmbeddingHelper & myTask)
1423 {
1424  std::ostream & result = myTask.Print(in);
1425  return result;
1426 }
1427 
1435 {
1436  std::string temp(opt);
1437  bool includeFileList = false;
1438  if (temp == "FILELIST") {
1439  includeFileList = true;
1440  }
1441  Printf("%s", toString(includeFileList).c_str());
1442 }
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
Int_t fAnchorRun
Anchor run for the given pythia production.
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
TFile * fExternalFile
! External file used for embedding
TList * list
TDirectory file where lists per trigger are stored in train ouput.
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.
AliVHeader * fExternalHeader
! Header of the current external event
AliGenPythiaEventHeader * fPythiaHeader
! Pythia header of the current external event
bool WriteConfiguration(const std::string &filename, const unsigned int i) const
bool GetProperty(std::vector< std::string > propertyPath, const std::string &propertyName, T &property, const bool requiredProperty) const
TString fInputFilename
Filename of input root files.
std::string fAutoConfigureBasePath
The base path to the auto configuration (for example, "/alice/cern.ch/user/a/alitrain/") ...
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.
int AddEmptyConfiguration(const std::string &configurationName)
Add YAML configuration at configurationFilename to available configurations.
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
int AddConfiguration(std::string configurationFilename, std::string configurationName="")
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...
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
bool WriteProperty(std::string propertyName, T &property, std::string configurationName="")
std::string RemoveTrailingSlashes(std::string filename) const
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