AliPhysics  d497afb (d497afb)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliEmcalCorrectionTask.cxx
Go to the documentation of this file.
1 // AliEmcalCorrectionTask
2 //
3 // Runs the cell and cluster level corrections for the EMCal
4 //
5 
8 
9 #include <vector>
10 #include <set>
11 #include <fstream>
12 #include <sstream>
13 #include <iostream>
14 #include <algorithm>
15 
16 #include <TChain.h>
17 
18 #include "AliVEventHandler.h"
19 #include "AliEMCALGeometry.h"
20 #include "AliVCaloCells.h"
21 #include "AliVCluster.h"
22 #include "AliLog.h"
23 #include "AliMultSelection.h"
24 #include "AliCentrality.h"
25 #include "AliESDEvent.h"
26 #include "AliAnalysisManager.h"
27 #include "AliAODEvent.h"
28 
30 ClassImp(AliEmcalCorrectionTask);
32 
36 
37 const std::map <std::string, AliVCluster::VCluUserDefEnergy_t> AliEmcalCorrectionTask::fgkClusterEnergyTypeMap = {
38  {"kNonLinCorr", AliVCluster::kNonLinCorr },
39  {"kHadCorr", AliVCluster::kHadCorr },
40  {"kUserDefEnergy1", AliVCluster::kUserDefEnergy1 },
41  {"kUserDefEnergy2", AliVCluster::kUserDefEnergy2 }
42 };
43 
44 const std::map <std::string, AliEmcalTrackSelection::ETrackFilterType_t> AliEmcalCorrectionTask::fgkTrackFilterTypeMap = {
45  {"kNoTrackFilter", AliEmcalTrackSelection::kNoTrackFilter },
46  {"kCustomTrackFilter", AliEmcalTrackSelection::kCustomTrackFilter },
47  {"kHybridTracks", AliEmcalTrackSelection::kHybridTracks },
48  {"kTPCOnlyTracks", AliEmcalTrackSelection::kTPCOnlyTracks }
49 };
50 
55  AliAnalysisTaskSE("AliEmcalCorrectionTask"),
56  fYAMLConfig(),
57  fSuffix(""),
58  fUserConfigurationFilename(""),
59  fDefaultConfigurationFilename(""),
60  fOrderedComponentsToExecute(),
61  fCorrectionComponents(),
62  fConfigurationInitialized(false),
63  fIsEsd(false),
64  fEventInitialized(false),
65  fCent(0),
66  fCentBin(-1),
67  fMinCent(-999),
68  fMaxCent(-999),
69  fNcentBins(4),
70  fCentEst("V0M"),
71  fUseNewCentralityEstimation(kFALSE),
72  fVertex{0},
73  fNVertCont(0),
74  fBeamType(kNA),
75  fForceBeamType(kNA),
76  fNeedEmcalGeom(kTRUE),
77  fGeom(0),
78  fParticleCollArray(),
79  fClusterCollArray(),
80  fCellCollArray(),
81  fOutput(0)
82 {
83  // Default constructor
84  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
85 
86  fParticleCollArray.SetOwner(kTRUE);
87  fClusterCollArray.SetOwner(kTRUE);
88 }
89 
100  AliAnalysisTaskSE(name),
101  fYAMLConfig(),
102  fSuffix(""),
103  fUserConfigurationFilename(""),
104  fDefaultConfigurationFilename(""),
105  fOrderedComponentsToExecute(),
106  fCorrectionComponents(),
107  fConfigurationInitialized(false),
108  fIsEsd(false),
109  fEventInitialized(false),
110  fCent(0),
111  fCentBin(-1),
112  fMinCent(-999),
113  fMaxCent(-999),
114  fNcentBins(4),
115  fCentEst("V0M"),
116  fUseNewCentralityEstimation(kFALSE),
117  fVertex{0},
118  fNVertCont(0),
119  fBeamType(kNA),
120  fForceBeamType(kNA),
121  fNeedEmcalGeom(kTRUE),
122  fGeom(0),
123  fParticleCollArray(),
124  fClusterCollArray(),
125  fCellCollArray(),
126  fOutput(0)
127 {
128  // Standard constructor
129  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
130 
131  fParticleCollArray.SetOwner(kTRUE);
132  fClusterCollArray.SetOwner(kTRUE);
133 
134  DefineInput(0, TChain::Class());
135  DefineOutput(1, TList::Class());
136 }
137 
146  fYAMLConfig(task.fYAMLConfig),
147  fSuffix(task.fSuffix),
148  fUserConfigurationFilename(task.fUserConfigurationFilename),
149  fDefaultConfigurationFilename(task.fDefaultConfigurationFilename),
150  fOrderedComponentsToExecute(task.fOrderedComponentsToExecute),
151  fCorrectionComponents(task.fCorrectionComponents), // TODO: These should be copied!
152  fConfigurationInitialized(task.fConfigurationInitialized),
153  fIsEsd(task.fIsEsd),
154  fEventInitialized(task.fEventInitialized),
155  fCent(task.fCent),
156  fCentBin(task.fCentBin),
157  fMinCent(task.fMinCent),
158  fMaxCent(task.fMaxCent),
159  fNcentBins(task.fNcentBins),
160  fCentEst(task.fCentEst),
161  fUseNewCentralityEstimation(task.fUseNewCentralityEstimation),
162  fVertex{0.},
163  fNVertCont(task.fNVertCont),
164  fBeamType(task.fBeamType),
165  fForceBeamType(task.fForceBeamType),
166  fNeedEmcalGeom(task.fNeedEmcalGeom),
167  fGeom(task.fGeom),
168  fParticleCollArray(*(static_cast<TObjArray *>(task.fParticleCollArray.Clone()))),
169  fClusterCollArray(*(static_cast<TObjArray *>(task.fClusterCollArray.Clone()))),
170  fOutput(task.fOutput) // TODO: More care is needed here!
171 {
172  // Vertex position
173  std::copy(std::begin(task.fVertex), std::end(task.fVertex), std::begin(fVertex));
174 
175  // Cell Collections
176  for (auto cellCont : task.fCellCollArray)
177  {
178  fCellCollArray.push_back(new AliEmcalCorrectionCellContainer(*cellCont));
179  }
180 }
181 
187 {
188  swap(*this, other);
189 }
190 
196 {
197  swap(*this, other);
198 
199  return *this;
200 }
201 
206 {
207  using std::swap;
208 
209  swap(first.fYAMLConfig, second.fYAMLConfig);
210  swap(first.fSuffix, second.fSuffix);
216  swap(first.fIsEsd, second.fIsEsd);
218  swap(first.fCent, second.fCent);
219  swap(first.fCentBin, second.fCentBin);
220  swap(first.fMinCent, second.fMinCent);
221  swap(first.fMaxCent, second.fMaxCent);
222  swap(first.fNcentBins, second.fNcentBins);
223  swap(first.fCentEst, second.fCentEst);
225  swap(first.fVertex, second.fVertex);
226  swap(first.fNVertCont, second.fNVertCont);
227  swap(first.fBeamType, second.fBeamType);
228  swap(first.fForceBeamType, second.fForceBeamType);
229  swap(first.fNeedEmcalGeom, second.fNeedEmcalGeom);
230  swap(first.fGeom, second.fGeom);
233  swap(first.fCellCollArray, second.fCellCollArray);
234  swap(first.fOutput, second.fOutput);
235 }
236 
242 {
243  // Destructor
244 }
245 
246 void AliEmcalCorrectionTask::Initialize(bool removeDummyTask)
247 {
248  // Determine file type
249  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
250  if (mgr) {
251  AliVEventHandler *evhand = mgr->GetInputEventHandler();
252  if (evhand) {
253  if (evhand->InheritsFrom("AliESDInputHandler")) {
254  fIsEsd = true;
255  }
256  else {
257  fIsEsd = false;
258  }
259  }
260  else {
261  AliError("Event handler not found!");
262  }
263  }
264  else {
265  AliError("Analysis manager not found!");
266  }
267 
268  // Determine the suffix of the correction task
269  std::string tempName = GetName();
270  std::size_t foundSuffix = tempName.find("_");
271  if (foundSuffix != std::string::npos) {
272  // +1 to skip "_"
273  fSuffix = tempName.substr(foundSuffix + 1).c_str();
274  }
275 
276  if (fSuffix != "") {
277  AliInfoStream() << "Initializing correction task with suffix \"" << fSuffix << "\"" << std::endl;
278  }
279 
280  // Initialize YAML configuration
282  // Check that the configuration is initialized
283  if (fConfigurationInitialized != true)
284  {
285  AliFatal("YAML configuration must be initialized before running (ie. in the run macro or wagon)!");
286  }
287 
288  // Determine component execution order
290 
291  // Check for user defined settings that are not in the default file
293 
294  // Setup input objects
295  // Setup Cells
296  // Cannot do this entirely yet because we need input objects
299  // Create cluster input objects
302  // Create track input objects
305 
306  // Initialize components
308 
309  if (removeDummyTask == true) {
310  RemoveDummyTask();
311  }
312 
313  // Print the results of the initialization
314  // Print outside of the ALICE Log system to ensure that it is always available!
315  std::cout << GetName() << " Settings:\n" << *this;
316 }
317 
323 {
324  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
325  if (!mgr)
326  {
327  AliErrorStream() << "No analysis manager to connect to.\n";
328  return;
329  }
330 
331  // Remove the dummy task
332  std::string dummyTaskName = GetName();
333  dummyTaskName += "_dummyTask";
334  TObjArray * tasks = mgr->GetTasks();
335  if (tasks) {
336  AliAnalysisTaskSE * dummyTask = dynamic_cast<AliAnalysisTaskSE *>(tasks->FindObject(dummyTaskName.c_str()));
337  if (!dummyTask) {
338  AliErrorStream() << "Could not remove dummy task \"" << dummyTaskName << "\" from analysis manager! Was it added?\n";
339  }
340  // Actually remove the task
341  tasks->Remove(dummyTask);
342  AliDebugStream(1) << "Removed dummy task named \"" << dummyTaskName << "\".\n";
343  }
344  else {
345  AliErrorStream() << "Could not retrieve tasks from the analysis manager.\n";
346  }
347 }
348 
358 {
359  // Determine file path
361  {
362  // Use the default if nothing is set
363  fDefaultConfigurationFilename = "$ALICE_PHYSICS/PWG/EMCAL/config/AliEmcalCorrectionConfiguration.yaml";
364  }
365 
366  // Setup and initialize configurations
367  // user is added first so that it will be checked first.
368  // User file
369  int returnValue = fYAMLConfig.AddConfiguration(fUserConfigurationFilename, "user");
370  if (returnValue >= 0) {
371  AliInfoStream() << "Using user EMCal corrections configuration located at \"" << fUserConfigurationFilename << "\"\n";
372  }
373  else {
374  AliInfoStream() << "User file at \"" << fUserConfigurationFilename << "\" does not exist! All settings will be from the default file!\n";
375  }
376 
377  // Default file
379  if (returnValue >= 0) {
380  AliInfoStream() << "Using default EMCal corrections configuration located at \"" << fDefaultConfigurationFilename << "\"\n";
381  }
382  else {
383  AliFatal(TString::Format("Default file located at \"%s\" does not exist!", fDefaultConfigurationFilename.c_str()));
384  }
385 
386  // Initialize
388 
389  // Note that it is initialized properly so that the analysis can proceed
391 }
392 
403 void AliEmcalCorrectionTask::DetermineComponentsToExecute(std::vector <std::string> & correctionComponents)
404 {
405  std::vector <std::string> executionOrder;
406  // executionOrder determines the order of tasks to execute, but it doesn't name the particular tasks
407  fYAMLConfig.GetProperty("executionOrder", executionOrder, true);
408 
409  // Possible components to create from both the user and default configurations
410  // Use set so that the possible components are not repeated
411  std::set <std::string> possibleComponents;
412  if (fYAMLConfig.DoesConfigurationExist("user")) {
413  for (const auto node : fYAMLConfig.GetConfiguration("user").second) {
414  possibleComponents.insert(node.first.as<std::string>());
415  }
416  }
417  for (const auto node : fYAMLConfig.GetConfiguration("default").second) {
418  possibleComponents.insert(node.first.as<std::string>());
419  }
420 
421  // Determine the correction names associated with the correction task
422  std::string expectedComponentName = "";
423  bool foundSuffixComponent = false;
424  bool foundComponent = false;
425  bool componentEnabled = true;
426 
427  // Execution order determines the order that corrections should be added to our execution list
428  for (auto & execName : executionOrder)
429  {
430  // Construct the expected component name with the suffix
431  expectedComponentName = TString::Format("%s_%s", execName.c_str(), fSuffix.c_str()).Data();
432  foundComponent = false;
433  componentEnabled = false;
434 
435  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
436  if (foundComponent)
437  {
438  // Check if the component is enabled
439  fYAMLConfig.GetProperty({expectedComponentName, "enabled"}, componentEnabled, true);
440  // If enabled, then store the name so that it can be executed
441  if (componentEnabled == true) {
442  foundSuffixComponent = true;
443  correctionComponents.push_back(expectedComponentName);
444  }
445  else {
446  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
447  }
448 
449  continue;
450  }
451  else
452  {
453  // Look for the normal component
454  expectedComponentName = execName;
455  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
456  // Check if it is enabled
457  fYAMLConfig.GetProperty({expectedComponentName, "enabled"}, componentEnabled, true);
458 
459  if (componentEnabled == true) {
460  if (foundSuffixComponent == true) {
461  AliFatal(TString::Format("Found earlier component %s with suffix \"%s\", but could not found component %s with that same suffix!", correctionComponents.back().c_str(), fSuffix.c_str(), expectedComponentName.c_str()));
462  }
463  else {
464  // Take the normal component and store it to be executed
465  correctionComponents.push_back(expectedComponentName);
466  }
467  }
468  else {
469  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
470  }
471  }
472  }
473 
474  // Need to append "AliEmcalCorrection" to allow the tasks to be found!
475  AliDebug(2, "Found EMCal Correction Components: ");
476  for (auto & component : correctionComponents)
477  {
478  component = "AliEmcalCorrection" + component;
479  AliDebug(2, TString::Format("%s", component.c_str()) );
480  }
481 }
482 
496 {
497  // Names of properties for a particular component in the user and default configurations
498  std::set <std::string> userPropertyNames;
499  std::set <std::string> defaultPropertyNames;
500  // Notes whether a match was found between user and default properties
501  bool foundMatch = false;
502  std::string tempComponentName = "";
503 
504  // Loop over all components
505  for (const auto componentName : fOrderedComponentsToExecute)
506  {
507  // Reset for each loop
508  userPropertyNames.clear();
509  defaultPropertyNames.clear();
510  // We need to remove "AliEmcalCorrection" so that the correction will be found in the configuration
511  std::string prefix = "AliEmcalCorrection";
512  tempComponentName = componentName.substr(componentName.find(prefix) + prefix.length());
513 
514  AliDebugStream(2) << "Checking component " << componentName << " for unmatched user settings" << std::endl;
515 
516  // Get the user property names
517  GetPropertyNamesFromNode("user", tempComponentName, userPropertyNames, false);
518 
519  // Get the same from default
520  // Not required here because the default configuration may not have the specialized component
521  GetPropertyNamesFromNode("default", tempComponentName, defaultPropertyNames, false);
522 
523  // We need to check the base correction as well to fill out the options
524  if (tempComponentName.find("_") != std::string::npos) {
525  // Get the base user component
526  GetPropertyNamesFromNode("user", tempComponentName.substr(0, tempComponentName.find("_")), userPropertyNames, false);
527 
528  // Required here because the default must have the base component!
529  GetPropertyNamesFromNode("default", tempComponentName.substr(0, tempComponentName.find("_")), defaultPropertyNames, true);
530  }
531 
532  // Check each property defined in the user file for a match to the properties in the default file
533  for (auto userPropertyName : userPropertyNames)
534  {
535  AliDebugStream(2) << "Checking property " << userPropertyName << std::endl;
536  foundMatch = false;
537  for (auto defaultPropertyName : defaultPropertyNames)
538  {
539  if (userPropertyName == defaultPropertyName) {
540  AliDebugStream(2) << "Found match of " << userPropertyName << " with " << defaultPropertyName << std::endl;
541  foundMatch = true;
542  }
543  }
544  if (foundMatch == false) {
545  AliFatal(TString::Format("Property \"%s:%s\" defined in the user configuration file cannot be found in the default configuration file! Check the spelling in your user file!", tempComponentName.c_str(), userPropertyName.c_str()));
546  }
547  }
548  }
549 }
550 
558 {
559  // Iterate over the ordered components list and create the components
560  AliEmcalCorrectionComponent * component = 0;
561  for (auto componentName : fOrderedComponentsToExecute)
562  {
563  std::string noPrefixComponentName = componentName.substr(0, componentName.find("_" + fSuffix));
564  component = AliEmcalCorrectionComponentFactory::createInstance(noPrefixComponentName);
565  if (!component)
566  {
567  AliFatal(TString::Format("Failed to create requested component %s!", componentName.c_str()));
568  }
569 
570  // For setting names of tasks to differentiate between tasks of the same class
571  component->SetName(componentName.c_str());
572  component->SetTitle(componentName.c_str());
573 
574  // Initialize the YAML configurations in each component
575  component->SetYAMLConfiguration(fYAMLConfig);
576 
577  // configure needed fields for components to properly initialize
578  component->SetIsESD(fIsEsd);
579 
580  // Add the require containers to the component
581  // Cells must be set during UserExec() because we need to add them as a pointer
584 
585  // Initialize each component
586  bool initialized = component->Initialize();
587 
588  if (component && initialized)
589  {
590  AliInfo(TString::Format("Successfully added correction task: %s", componentName.c_str()));
591  fCorrectionComponents.push_back(component);
592  }
593  }
594 }
595 
611 {
612  // Get container node
613  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
614 
615  // Determine which containers we need based on which are requested by the enabled correction tasks
616  std::set <std::string> requestedContainers;
617  std::vector <std::string> componentRequest;
618  for ( const auto & componentName : fOrderedComponentsToExecute )
619  {
620  componentRequest.clear();
621  // Not required because not all components will have all kinds of containers
622  std::string selectionName = "AliEmcalCorrection";
623  // Expliecitly initialize as a vector to avoid ambiguity.
624  fYAMLConfig.GetProperty(std::vector<std::string>{componentName.substr(componentName.find(selectionName) + selectionName.length()), inputObjectName + "Names"}, componentRequest, false);
625  for ( auto & req : componentRequest )
626  {
627  AliDebugStream(3) << "Component " << componentName << " requested container name " << req << std::endl;
628  requestedContainers.insert(req);
629  }
630  }
631 
632  AliDebugStream(2) << inputObjectName << " Containers requested by components: " << std::endl;
633  for (auto & str : requestedContainers) {
634  AliDebugStream(2) << "\t" << str << std::endl;;
635  }
636 
637  // Create all requested containers
638  AliDebug(2, TString::Format("Setting up requested containers!"));
639  SetupContainersFromInputNodes(inputObjectType, requestedContainers);
640 }
641 
651 {
652  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
653  // Need to be of the form "clusterContainersNames"
654  inputObjectName = inputObjectName + "Names";
655 
656  std::vector <std::string> inputObjects;
657  // Property is not required, because not all components need Clusters or Tracks
658  // Expliecitly initialize as a vector to avoid ambiguity.
659  fYAMLConfig.GetProperty(std::vector<std::string>{component->GetName(), inputObjectName.c_str()}, inputObjects, false);
660 
661  //AliDebugStream(4) << "inputObjects.size(): " << inputObjects.size() << std::endl;
662 
663  // If it is not found, then there will be nothing to iterate over, so we don't need to explicitly check the return value
664  for (auto const & str : inputObjects)
665  {
666  // NOTE: The AliEmcalContainer derived objects operate differently than the cells. The containers should be added during initialization while the cells should be added during ExecOnce()!
667  if (inputObjectType == AliEmcalContainerUtils::kCluster)
668  {
669  AliEmcalContainer * cont = GetClusterContainer(str.c_str());
670  AliDebugStream(2) << "Adding cluster container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
671 
672  if (checkObjectExists && !cont) {
673  AliError(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
674  }
675  component->AdoptClusterContainer(GetClusterContainer(str.c_str()));
676 
677  // Check that we are using the standard input event
678  if (!(cont->GetIsEmbedding())) {
679  component->SetUsingInputEvent(true);
680  }
681  }
682  else if (inputObjectType == AliEmcalContainerUtils::kTrack)
683  {
684  AliEmcalContainer * cont = GetParticleContainer(str.c_str());
685  AliDebugStream(2) << "Adding particle container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
686 
687  if (checkObjectExists && !cont) {
688  AliFatal(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
689  }
690  component->AdoptParticleContainer(GetParticleContainer(str.c_str()));
691 
692  // Check that we are using the standard input event
693  if (!(cont->GetIsEmbedding())) {
694  component->SetUsingInputEvent(true);
695  }
696  }
697  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells)
698  {
699  // NOTE: This operates different than the others. This should be executed during run time rather than during initialization!
700  if (inputObjects.size() > 1) {
701  AliFatal(TString::Format("Component %s requested more than one cell branch, but this is not supported! Check the configuration!", component->GetName()));
702  }
703 
704  // If we've made it here, this must be at least one entry
706  AliDebugStream(2) << "Adding calo cells \"" << cellCont->GetName() << "\" of branch name \"" << cellCont->GetBranchName() << "\" to component " << component->GetName() << std::endl;
707 
708  if (!(cellCont->GetCells())) {
709  // Attempt to re-initialize the cells.
710  // NOTE: This may not succeed. Adding the container may need to be repeated after the
711  // object is created
713  }
714 
715  if (checkObjectExists && !(cellCont->GetCells())) {
716  AliFatal(TString::Format("%s: Unable to retrieve cells \"%s\" in input object \"%s\" because the cells are null. Please check your configuration!", GetName(), cellCont->GetBranchName().c_str(), str.c_str()));
717  }
718 
719  // Set the calo cells (may be null)
720  component->SetCaloCells(cellCont->GetCells());
721 
722  // It is possible that the cells pointer is null because it may not be created yet. For example,
723  // when combining cells. Thus, we must first check whether the pointer is available before checking
724  // for the number of cells. This could potentially decrease the amount of debug information, but this
725  // should rarely be an issue.
726  if (component->GetCaloCells()) {
727  AliDebugStream(3) << "Component GetNumberOfCells(): " << component->GetCaloCells()->GetNumberOfCells() << std::endl;
728  }
729 
730  // Check that we are using the standard input event
731  if (!(cellCont->GetIsEmbedding())) {
732  component->SetUsingInputEvent(true);
733  }
734  }
735  }
736 }
737 
744 void AliEmcalCorrectionTask::SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, std::set <std::string> & requestedContainers)
745 {
746  // Our node contains all of the objects that we will want to create.
747  for(auto & containerName : requestedContainers)
748  {
749  // The section is the container name
750  //std::string containerName = it->first.as<std::string>();
751  // Skip if the particle or cluster container already exists
752  if (GetParticleContainer(containerName.c_str()) || GetClusterContainer(containerName.c_str())) {
753  continue;
754  }
755 
756  AliDebug(2, TString::Format("Processing container %s of inputType %d", containerName.c_str(), inputObjectType));
757  if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
758  SetupContainer(inputObjectType, containerName);
759  }
760  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
761  SetupCellsInfo(containerName);
762  }
763  }
764 }
765 
774 void AliEmcalCorrectionTask::SetupCellsInfo(std::string containerName)
775 {
776  // Define cell info
778 
779  // Set properties
780  // Cells (object) name
781  cellObj->SetName(containerName);
782  // Branch name
783  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(AliEmcalContainerUtils::kCaloCells), containerName};
784  std::string tempString = "";
785  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "branchName", tempString, true);
786  if (tempString == "usedefault") {
788  }
789  cellObj->SetBranchName(tempString);
790 
791  // IsEmbedding
792  bool tempBool = false;
793  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "embedding", tempBool, false);
794  cellObj->SetIsEmbedding(tempBool);
795 
796  // Add to the array to keep track of it
797  fCellCollArray.push_back(cellObj);
798 }
799 
815 void AliEmcalCorrectionTask::SetupContainer(const AliEmcalContainerUtils::InputObject_t inputObjectType, const std::string containerName)
816 {
817  // Create container
818  AliDebugStream(2) << "Adding container" << std::endl;
819  AliEmcalContainer * cont = AddContainer(inputObjectType, containerName);
820  AliDebugStream(2) << "Added container" << std::endl;
821 
822  // Set the container properties
823  //
824  // TODO: Consider if this can be converted to a map to function pointers. There are a number of details
825  // which can make it a bit complicated. Those details include inheritance, pointing to member
826  // functions, etc. It should all be possible, but may not be worth all of the extra work and code.
827  // Example ccode:
828  // SetValueInContainer(inputObjectPropertiesPath, "minPt", &cont::SetMinPt, tempDouble, false);
829  // SetValueInContainer(inputObjectPropertiesPath, "minE", &cont::SetMinE, tempDouble, false);
830  // std::function may be easier?
831  // See: https://isocpp.org/wiki/faq/pointers-to-members
834  // type void (AliEmcalContainer::*EmcalContainerFn)(double val);
835  // // Potential map?
836  // std::map<std::string, EmcalContainerFn> EmcalContFunctionMap;
837  // EmcalContFunctionMap["minPt"] = &AliEmcalContainer::SetMinPt;
838  // EmcalContFunctionMap["minE"] = &AliEmcalContainer::SetMinE;
839  // // Define functions (use map?)
840  // EmcalContainerFn minPt = &AliEmcalContainer::SetMinPt;
841  // EmcalContainerFn minE = &AliEmcalContainer::SetMinE;
842  // // Example invocation
843  // (cont->*minPt)(tempDouble);
844 
845  // Path to the various properties
846  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(inputObjectType), containerName};
847 
848  // Temporary variables to store requested properties
849  std::string tempString = "";
850  Double_t tempDouble = 0;
851  bool tempBool = false;
852 
853  // AliEmcalContainer properties
854  // Min Pt
855  bool result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minPt", tempDouble, false);
856  if (result) {
857  AliDebugStream(2) << cont->GetName() << ": Setting minPt of " << tempDouble << std::endl;
858  cont->SetMinPt(tempDouble);
859  }
860  // Min E
861  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minE", tempDouble, false);
862  if (result) {
863  AliDebugStream(2) << cont->GetName() << ": Setting minE of " << tempDouble << std::endl;
864  cont->SetMinE(tempDouble);
865  }
866  // Eta min, max
867  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minEta", tempDouble, false);
868  if (result) {
869  // Only continue checking if the min is there, since we must set both together
870  Double_t tempDouble2 = 0;
871  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "maxEta", tempDouble, false);
872  if (result) {
873  AliDebugStream(2) << cont->GetName() << ": Setting eta limits of " << tempDouble << " to " << tempDouble2 << std::endl;
874  cont->SetEtaLimits(tempDouble, tempDouble2);
875  }
876  }
877  // Phi min, max
878  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minPhi", tempDouble, false);
879  if (result) {
880  // Only continue checking if the min is there, since we must set both together
881  Double_t tempDouble2 = 0;
882  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "maxPhi", tempDouble, false);
883  if (result) {
884  AliDebugStream(2) << cont->GetName() << ": Setting phi limits of " << tempDouble << " to " << tempDouble2 << std::endl;
885  cont->SetPhiLimits(tempDouble, tempDouble2);
886  }
887  }
888  // Embedded
889  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "embedding", tempBool, false);
890  if (result) {
891  AliDebugStream(2) << cont->GetName() << ": Setting embedding to " << (tempBool ? "enabled" : "disabled") << std::endl;
892  cont->SetIsEmbedding(tempBool);
893  }
894 
895  // Cluster specific properties
896  AliClusterContainer * clusterContainer = dynamic_cast<AliClusterContainer *>(cont);
897  if (clusterContainer) {
898  // Default energy
899  // Probably not needed for the corrections
900  /*result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "defaultClusterEnergy", tempString, false);
901  if (result) {
902  // Need to get the enumeration
903  AliVCluster::VCluUserDefEnergy_t clusterEnergyType = fgkClusterEnergyTypeMap.at(tempString);
904  AliDebugStream(2) << clusterContainer->GetName() << ": Setting cluster energy type to " << clusterEnergyType << std::endl;
905  clusterContainer->SetDefaultClusterEnergy(clusterEnergyType);
906  }*/
907 
908  // NonLinCorrEnergyCut
909  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "clusNonLinCorrEnergyCut", tempDouble, false);
910  if (result) {
911  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusNonLinCorrEnergyCut of " << tempDouble << std::endl;
912  clusterContainer->SetClusNonLinCorrEnergyCut(tempDouble);
913  }
914 
915  // HadCorrEnergyCut
916  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "clusHadCorrEnergyCut", tempDouble, false);
917  if (result) {
918  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusHadCorrEnergyCut of " << tempDouble << std::endl;
919  clusterContainer->SetClusHadCorrEnergyCut(tempDouble);
920  }
921 
922  // SetIncludePHOS
923  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "includePHOS", tempBool, false);
924  if (result) {
925  AliDebugStream(2) << clusterContainer->GetName() << ": Setting Include PHOS to " << (tempBool ? "enabled" : "disabled") << std::endl;
926  clusterContainer->SetIncludePHOS(tempBool);
927  }
928  }
929 
930  // Track specific
931  AliTrackContainer * trackContainer = dynamic_cast<AliTrackContainer *>(cont);
932  if (trackContainer) {
933  // Track selection
934  // AOD Filter bits as a sequence
935  std::vector <UInt_t> filterBitsVector;
936  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "aodFilterBits", filterBitsVector, false);
937  if (result){
938  UInt_t filterBits = 0;
939  for (int filterBit : filterBitsVector) {
940  filterBits += filterBit;
941  }
942  AliDebugStream(2) << trackContainer->GetName() << ": Setting filterBits of " << filterBits << std::endl;
943  trackContainer->SetAODFilterBits(filterBits);
944  }
945 
946  // SetTrackFilterType enum
947  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "trackFilterType", tempString, false);
948  if (result) {
949  // Need to get the enumeration
950  AliEmcalTrackSelection::ETrackFilterType_t trackFilterType = fgkTrackFilterTypeMap.at(tempString);
951  AliDebugStream(2) << trackContainer->GetName() << ": Setting trackFilterType of " << trackFilterType << std::endl;
952  trackContainer->SetTrackFilterType(trackFilterType);
953  }
954 
955  // Track cuts period
956  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "trackCutsPeriod", tempString, false);
957  if (result) {
958  // Need to get the enumeration
959  AliDebugStream(2) << trackContainer->GetName() << ": Setting track cuts period to " << tempString << std::endl;
960  trackContainer->SetTrackCutsPeriod(tempString.c_str());
961  }
962  }
963 }
964 
980 AliEmcalContainer * AliEmcalCorrectionTask::AddContainer(const AliEmcalContainerUtils::InputObject_t contType, const std::string containerName)
981 {
982  // Determine the type of branch to request
983  std::string containerBranch = "";
985  AliFatal("Must specify type of container when requesting branch.");
986  }
987 
988  // Path to the various properties
989  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(contType), containerName};
990 
991  // Retrieve branch name
992  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "branchName", containerBranch, true);
993  // Should be unnecessary, since the user can only do this if done explicitly.
994  /*if (containerBranch == "")
995  {
996  AliFatal(TString::Format("Request %i container, but the container branch is empty!", contType));
997  }*/
998 
999  // Determine proper name if using "usedefault" pattern
1000  if (containerBranch == "usedefault") {
1001  containerBranch = AliEmcalContainerUtils::DetermineUseDefaultName(contType, fIsEsd);
1002  }
1003 
1004  // Create containers and set them to the name of the component
1005  AliEmcalContainer * cont = 0;
1006  if (contType == AliEmcalContainerUtils::kCluster)
1007  {
1008  cont = new AliClusterContainer(containerBranch.c_str());
1009  AdoptClusterContainer(dynamic_cast<AliClusterContainer *>(cont));
1010  }
1011  else if (contType == AliEmcalContainerUtils::kTrack)
1012  {
1013  if (containerBranch == "mcparticles") {
1014  cont = new AliMCParticleContainer(containerBranch.c_str());
1015  }
1016  else {
1017  cont = new AliTrackContainer(containerBranch.c_str());
1018  }
1019  AdoptParticleContainer(dynamic_cast<AliParticleContainer *>(cont));
1020  }
1021  cont->SetName(containerName.c_str());
1022 
1023  return cont;
1024 }
1025 
1035 {
1036  // Check that the configuration is initialized
1037  if (fConfigurationInitialized != true)
1038  {
1039  AliFatal("YAML configuration must be initialized before running (ie. the AddTask, run macro or wagon)!");
1040  }
1041 
1042  // YAML Objects cannot be streamed, so we need to reinitialize them here.
1044 
1045  if (fForceBeamType == kpp)
1046  fNcentBins = 1;
1047 
1048  // Allow for output files
1049  OpenFile(1);
1050  fOutput = new TList();
1051  fOutput->SetOwner();
1052 
1054 
1055  PostData(1, fOutput);
1056 }
1057 
1065 {
1066  // Run the initialization for all derived classes.
1067  for (auto component : fCorrectionComponents)
1068  {
1069  // Set cent bins (usually used for hist creation)
1070  // It cannot be set until now because it can be changed after initialization
1071  // For instance, by SetForceBeamType()
1072  component->SetNcentralityBins(fNcentBins);
1073 
1074  component->UserCreateOutputObjects();
1075 
1076  if (component->GetOutputList() != 0)
1077  {
1078  // Adds a list to the list -- this doesn't work for some unknown reason
1079  //fOutput->Add(component->GetOutputList());
1080 
1081  // iterate through lists for each component, and fill in output
1082  TList* t = new TList();
1083  t->SetName(component->GetName());
1084  fOutput->AddLast(t);
1085  t = (TList*)fOutput->Last();
1086  TIter next(component->GetOutputList());
1087  while (TObject *obj = next()){
1088  t->Add(obj);
1089  }
1090 
1091  AliDebug(1, TString::Format("Added output list from task %s to output.", component->GetName()));
1092  }
1093  }
1094 }
1095 
1101 {
1102  // Initialize the event if not initialized
1103  if (!fEventInitialized)
1104  ExecOnce();
1105 
1106  // Only continue if we are initialized successfully
1107  if (!fEventInitialized)
1108  return;
1109 
1110  // Get the objects for each event
1111  if (!RetrieveEventObjects())
1112  return;
1113 
1114  // Call run for each correction
1115  if (!Run())
1116  return;
1117 }
1118 
1130 {
1131  if (!InputEvent()) {
1132  AliError("Could not retrieve event! Returning!");
1133  return;
1134  }
1135 
1136  // This warning was extracted out from the cell components
1137  if (dynamic_cast<AliAODEvent*>(InputEvent())) {
1138  AliWarning("=============================================================");
1139  AliWarning("=== Running on AOD is not equivalent to running on ESD! ===");
1140  AliWarning("=============================================================");
1141  }
1142 
1143  if (fNeedEmcalGeom) {
1144  fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(InputEvent()->GetRunNumber());
1145  if (!fGeom) {
1146  AliFatal("Can not get EMCal geometry instance. If you do not need the EMCal geometry, disable it by setting task->SetNeedEmcalGeometry(kFALSE).");
1147  return;
1148  }
1149  }
1150 
1151  // Load all requested track branches - each container knows name already
1152  for (Int_t i =0; i<fParticleCollArray.GetEntriesFast(); i++) {
1153  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
1155  cont->SetArray(InputEvent());
1156  }
1157 
1158  // Load all requested cluster branches - each container knows name already
1159  for (Int_t i =0; i<fClusterCollArray.GetEntriesFast(); i++) {
1160  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
1162  cont->SetArray(InputEvent());
1163  }
1164 
1165  // Determine the proper pointer for each cell object and save them to the cell container
1166  // At this point, they should all be created
1167  for (auto cellObj : fCellCollArray)
1168  {
1170  }
1171 
1172  fEventInitialized = kTRUE;
1173 
1174  // Print warning to the user that the rest of the configuration information is available in the generation log
1175  // when the Analysis Manager was created. Using cout to be certain that it is shown on the train!
1176  std::cout << "=== NOTE: Additional EMCal Corrections configuration information can be found when the Analysis Manager is configured. For a run macro, see above, while for a LEGO train, see the generation.log ===\n";
1177 
1178  // Setup the components
1180 }
1181 
1187 {
1188  // Run the initialization for all derived classes.
1189  for (auto component : fCorrectionComponents)
1190  {
1191  // Setup geometry
1192  component->SetEMCALGeometry(fGeom);
1193 
1194  // Add the requested cells to the component
1196 
1197  // Set the input events. This is redundant to where it is set during Run(), but the events need to be
1198  // available to components, and they are only called one extra time.
1199  component->SetInputEvent(InputEvent());
1200  component->SetMCEvent(MCEvent());
1201 
1202  // Component ExecOnce()
1203  component->ExecOnce();
1204 
1205  // If the cells were created during ExecOnce(), then we need to re-initialize the pointer to ensure
1206  // that it is not null!
1207  if (!(component->GetCaloCells())) {
1208  AliDebugStream(2) << "Re-initializing cells for component " << component->GetName() << std::endl;
1210  }
1211  }
1212 }
1213 
1219 {
1220  fVertex[0] = 0;
1221  fVertex[1] = 0;
1222  fVertex[2] = 0;
1223  fNVertCont = 0;
1224 
1225  const AliVVertex *vert = InputEvent()->GetPrimaryVertex();
1226  if (vert) {
1227  vert->GetXYZ(fVertex);
1228  fNVertCont = vert->GetNContributors();
1229  }
1230 
1231  fBeamType = GetBeamType();
1232 
1233  if (fBeamType == kAA || fBeamType == kpA ) {
1235  AliMultSelection *MultSelection = static_cast<AliMultSelection*>(InputEvent()->FindListObject("MultSelection"));
1236  if (MultSelection) {
1237  fCent = MultSelection->GetMultiplicityPercentile(fCentEst.Data());
1238  }
1239  else {
1240  AliWarning("Could not retrieve centrality information! Assuming 99");
1241  }
1242  }
1243  else { // old centrality estimation < 2015
1244  AliCentrality *aliCent = InputEvent()->GetCentrality();
1245  if (aliCent) {
1246  fCent = aliCent->GetCentralityPercentile(fCentEst.Data());
1247  }
1248  else {
1249  AliWarning("Could not retrieve centrality information! Assuming 99");
1250  }
1251  }
1252 
1253  if (fNcentBins==4) {
1254  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1255  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1256  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1257  else if (fCent >= 50 && fCent <= 100) fCentBin = 3;
1258  else {
1259  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1260  fCentBin = fNcentBins-1;
1261  }
1262  }
1263  else if (fNcentBins==5) { // for PbPb 2015
1264  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1265  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1266  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1267  else if (fCent >= 50 && fCent <= 90) fCentBin = 3;
1268  else if (fCent > 90) {
1269  fCent = 99;
1270  fCentBin = 4;
1271  }
1272  else {
1273  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1274  fCentBin = fNcentBins-1;
1275  }
1276  }
1277  else {
1278  Double_t centWidth = (fMaxCent-fMinCent)/(Double_t)fNcentBins;
1279  if(centWidth>0.) {
1280  fCentBin = TMath::FloorNint(fCent/centWidth);
1281  }
1282  else {
1283  fCentBin = 0;
1284  }
1285  if (fCentBin>=fNcentBins) {
1286  AliWarning(Form("fCentBin too large: cent = %f fCentBin = %d. Assuming 99", fCent, fCentBin));
1287  fCentBin = fNcentBins-1;
1288  }
1289  }
1290  }
1291  else {
1292  fCent = 99;
1293  fCentBin = 0;
1294  }
1295 
1296  AliEmcalContainer* cont = 0;
1297 
1298  TIter nextPartColl(&fParticleCollArray);
1299  while ((cont = static_cast<AliEmcalContainer*>(nextPartColl()))) cont->NextEvent(InputEvent());
1300 
1301  TIter nextClusColl(&fClusterCollArray);
1302  while ((cont = static_cast<AliEmcalContainer*>(nextClusColl()))) cont->NextEvent(InputEvent());
1303 
1304  return kTRUE;
1305 }
1306 
1312 {
1313  // Run the initialization for all derived classes.
1314  for (auto component : fCorrectionComponents)
1315  {
1316  component->SetInputEvent(InputEvent());
1317  component->SetMCEvent(MCEvent());
1318  component->SetCentralityBin(fCentBin);
1319  component->SetCentrality(fCent);
1320  component->SetVertex(fVertex);
1321 
1322  component->Run();
1323  }
1324 
1325  PostData(1, fOutput);
1326 
1327  return kTRUE;
1328 }
1329 
1334 {
1335  // Run the initialization for all derived classes.
1336  for (auto component : fCorrectionComponents)
1337  {
1338  component->UserNotify();
1339  }
1340 
1341  return kTRUE;
1342 }
1343 
1350 std::ostream & AliEmcalCorrectionTask::PrintConfiguration(std::ostream & in, bool userConfig) const
1351 {
1352  std::string configurationName = userConfig ? "user" : "default";
1353  if (fYAMLConfig.DoesConfigurationExist(configurationName)) {
1354  auto configPair = fYAMLConfig.GetConfiguration(configurationName);
1355  if (configPair.second.IsNull() == true) {
1356  AliWarning(TString::Format("%s configuration is empty!", configPair.first.c_str()));
1357  }
1358  in << configPair.second;
1359  }
1360  else {
1361  in << "Configuration \"" << configurationName << "\" does not exist!\n";
1362  }
1363 
1364  return in;
1365 }
1366 
1374 bool AliEmcalCorrectionTask::WriteConfigurationFile(std::string filename, bool userConfig) const
1375 {
1376  return fYAMLConfig.WriteConfiguration(filename, userConfig ? "user" : "default");
1377 }
1378 
1388 {
1389  // Setup
1390  // It's important to reinitialize the configuration so the YAML nodes are defined!
1392  std::string tempConfigName = "tempConfig";
1393  fYAMLConfig.AddConfiguration(filename, tempConfigName);
1394 
1395  // Compare
1396  bool returnValue = fYAMLConfig.CompareConfigurations(tempConfigName, userConfig ? "user" : "default");
1397 
1398  // Cleanup
1399  fYAMLConfig.RemoveConfiguration(tempConfigName);
1400 
1401  return returnValue;
1402 }
1403 
1411 {
1412  AliDebugStream(2) << "Retrieving cells object " << cellContainer->GetName() << std::endl;
1413  // Check for embedding and return object
1414  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cellContainer->GetIsEmbedding());
1415 
1416  cellContainer->SetCells(dynamic_cast<AliVCaloCells *>(event->FindListObject(cellContainer->GetBranchName().c_str())));
1417 }
1418 
1429 {
1430  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cont->GetIsEmbedding());
1431 
1432  TClonesArray * array = dynamic_cast<TClonesArray *>(event->FindListObject(cont->GetArrayName()));
1433  if (!array) {
1434  AliWarning(TString::Format("Container %s requested branch %s, but it does not exist! Creating it for you! Please check that this is the proper action!", cont->GetName(), cont->GetArrayName().Data()));
1435  array = new TClonesArray(AliEmcalContainerUtils::DetermineUseDefaultName(objectType, fIsEsd, true).c_str());
1436  array->SetName(cont->GetArrayName());
1437  event->AddObject(array);
1438  }
1439 }
1440 
1449 {
1450  // Get container node
1451  std::string inputObjectName = "";
1452  if (inputObjectType == AliEmcalContainerUtils::kCluster) {
1453  inputObjectName = "clusterContainers";
1454  }
1455  else if (inputObjectType == AliEmcalContainerUtils::kTrack) {
1456  inputObjectName = "trackContainers";
1457  }
1458  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1459  inputObjectName = "cells";
1460  }
1461  else {
1462  AliFatal(TString::Format("Unrecognized input object type %d", inputObjectType));
1463  }
1464 
1465  return inputObjectName;
1466 }
1467 
1479 bool AliEmcalCorrectionTask::CheckPossibleNamesForComponentName(std::string & name, std::set <std::string> & possibleComponents)
1480 {
1481  bool foundComponent = false;
1482  for (auto & possibleComponent : possibleComponents)
1483  {
1484  if (possibleComponent == name) {
1485  foundComponent = true;
1486  break;
1487  }
1488  }
1489 
1490  return foundComponent;
1491 }
1492 
1500 {
1501  if (fForceBeamType != kNA)
1502  return fForceBeamType;
1503 
1504  AliESDEvent *esd = dynamic_cast<AliESDEvent*>(InputEvent());
1505  if (esd) {
1506  const AliESDRun *run = esd->GetESDRun();
1507  TString beamType = run->GetBeamType();
1508  if (beamType == "p-p")
1509  return kpp;
1510  else if (beamType == "A-A")
1511  return kAA;
1512  else if (beamType == "p-A")
1513  return kpA;
1514  else
1515  return kNA;
1516  } else {
1517  Int_t runNumber = InputEvent()->GetRunNumber();
1518  // All run number ranges taken from the RCT
1519  if ((runNumber >= 136833 && runNumber <= 139517) || // LHC10h
1520  (runNumber >= 167693 && runNumber <= 170593) || // LHC11h
1521  (runNumber >= 244824 && runNumber <= 246994)) { // LHC15o
1522  return kAA;
1523  } else if ((runNumber >= 188356 && runNumber <= 188366) || // LHC12g
1524  (runNumber >= 195164 && runNumber <= 197388) || // LHC13b-f
1525  (runNumber >= 265015 && runNumber <= 267166)) { // LHC16q-t
1526  return kpA;
1527  } else {
1528  return kpp;
1529  }
1530  }
1531 }
1532 
1537 {
1538  if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1539  stream << "Cells info: " << std::endl;
1540  for (auto cellInfo : fCellCollArray) {
1541  stream << "\tName: " << cellInfo->GetName() << "\tBranch: " << cellInfo->GetBranchName() << "\tIsEmbedding: " << std::boolalpha << cellInfo->GetIsEmbedding() << std::endl;
1542  }
1543  }
1544  else if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
1545  stream << (inputObjectType == AliEmcalContainerUtils::kCluster ? "Cluster" : "Track") << " container info: " << std::endl;
1546  AliEmcalContainer * cont = 0;
1547  for (auto containerInfo : (inputObjectType == AliEmcalContainerUtils::kCluster ? fClusterCollArray : fParticleCollArray) ) {
1548  cont = static_cast<AliEmcalContainer *>(containerInfo);
1549  stream << "\tName: " << cont->GetName() << "\tBranch: " << cont->GetArrayName() << "\tTitle: " << cont->GetTitle() << "\tIsEmbedding: " << std::boolalpha << cont->GetIsEmbedding() << std::endl;
1550  }
1551  }
1552  else {
1553  AliErrorStream() << "Unrecognized input object type " << inputObjectType << std::endl;
1554  }
1555 }
1556 
1570 void AliEmcalCorrectionTask::GetPropertyNamesFromNode(const std::string configurationName, const std::string componentName, std::set <std::string> & propertyNames, const bool nodeRequired)
1571 {
1572  bool retrievedPropertyNames = false;
1573  if (fYAMLConfig.DoesConfigurationExist(configurationName)) {
1574  AliDebugStream(3) << "Looking for nodes in component \"" << componentName << "\" in the \"" << configurationName << "\" configuration\n";
1575  auto configPair = fYAMLConfig.GetConfiguration(configurationName);
1576  if (configPair.second[componentName])
1577  {
1578  for (auto propertyName : configPair.second[componentName])
1579  {
1580  AliDebugStream(4) << "Node property name " << propertyName.first.as<std::string>() << "\n";
1581  propertyNames.insert(propertyName.first.as<std::string>());
1582  }
1583  retrievedPropertyNames = true;
1584  }
1585  }
1586 
1587  if (retrievedPropertyNames == false && nodeRequired) {
1588  std::stringstream message;
1589  message << "Failed to retrieve required property \""
1590  << componentName << "\" from the \"" << configurationName << "\" configuration!" << std::endl;
1591  AliFatal(message.str().c_str());
1592  }
1593 }
1594 
1602 AliEmcalCorrectionCellContainer * AliEmcalCorrectionTask::GetCellContainer(const std::string & cellsContainerName) const
1603 {
1604  for (auto cellContainer : fCellCollArray)
1605  {
1606  if (cellContainer->GetName() == cellsContainerName) {
1607  return cellContainer;
1608  }
1609  }
1610 
1611  return 0;
1612 }
1613 
1615 {
1616  // Get the pointer to the existing analysis manager via the static access method.
1617  //==============================================================================
1618  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1619  if (!mgr)
1620  {
1621  ::Error("AddTaskEmcalCorrectionTask", "No analysis manager to connect to.");
1622  return nullptr;
1623  }
1624 
1625  // Check the analysis type using the event handlers connected to the analysis manager.
1626  //==============================================================================
1627  AliVEventHandler* handler = mgr->GetInputEventHandler();
1628  if (!handler)
1629  {
1630  ::Error("AddTaskEmcalCorrectionTask", "This task requires an input event handler");
1631  return nullptr;
1632  }
1633 
1634  TString name = "AliEmcalCorrectionTask";
1635  if (suffix != "") {
1636  name += TString::Format("_%s", suffix.Data());
1637  }
1638 
1639  AliEmcalCorrectionTask* mgrTask = static_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.Data()));
1640  if (mgrTask) return mgrTask;
1641 
1642  // Create the task that manages the corrections
1643  AliEmcalCorrectionTask* correctionTask = new AliEmcalCorrectionTask(name.Data());
1644 
1645  //-------------------------------------------------------
1646  // Final settings, pass to manager and set the containers
1647  //-------------------------------------------------------
1648 
1649  mgr->AddTask(correctionTask);
1650 
1651  // Create containers for input/output
1652  AliAnalysisDataContainer* cInput = mgr->GetCommonInputContainer();
1653 
1654  TString outputContainerName(name);
1655  outputContainerName += "_histos";
1656 
1657  AliAnalysisDataContainer * cOutput = mgr->CreateContainer(outputContainerName.Data(),
1658  TList::Class(),
1659  AliAnalysisManager::kOutputContainer,
1660  Form("%s", AliAnalysisManager::GetCommonFileName()));
1661 
1662  mgr->ConnectInput(correctionTask, 0, cInput);
1663  mgr->ConnectOutput(correctionTask, 1, cOutput);
1664 
1665  //TObjArray* cnt = mgr->GetContainers();
1666 
1667  return correctionTask;
1668 }
1669 
1671 {
1672  // Get the pointer to the existing analysis manager via the static access method.
1673  //==============================================================================
1674  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1675  if (!mgr)
1676  {
1677  ::Error("ConfigureEmcalCorrectionTaskOnLEGOTrain", "No analysis manager to connect to.");
1678  return nullptr;
1679  }
1680 
1681  // Find the correction task
1682  AliEmcalCorrectionTask * correctionTask = nullptr;
1683  const std::string taskName = "AliEmcalCorrectionTask";
1684  std::string foundTaskName = "";
1685  bool taskFound = false;
1686  std::vector<std::string> namesToSearch = {taskName};
1687 
1688  // Determine if the suffix name should be searched for.
1689  // If a suffix is given, it will be looked for first, followed by the generically named task.
1690  // This way, a user's configuration can be uniquely identified in the case of multiple correction tasks, but
1691  // if there is only one correction task without a suffix, this method will still fall back to that one and
1692  // return a correction task to be configured.
1693  if (suffix != "")
1694  {
1695  std::string suffixName = taskName;
1696  suffixName += "_";
1697  suffixName += suffix.Data();
1698  namesToSearch.insert(namesToSearch.begin(), suffixName);
1699  }
1700 
1701  // Attempt to retrieve the task from the analysis manager
1702  for (auto name : namesToSearch)
1703  {
1704  correctionTask = dynamic_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.c_str()));
1705  if (correctionTask != nullptr) {
1706  taskFound = true;
1707  foundTaskName = name;
1708  break;
1709  }
1710  }
1711 
1712  // Fatal if we can't find the task
1713  if (taskFound == false) {
1714  AliFatalClassF("Could not find correction task, checking for both the suffix \"%s\" and the main task. Did you remember to create it?", suffix.Data());
1715  }
1716 
1717  AliInfoClassStream() << "Found correction task named \"" << foundTaskName <<"\" to configure.\n";
1718 
1719  // AliAnalysisTaskCfg will require a task to be returned, so we add a dummy task to the analysis manager,
1720  // which will be removed when the user calls Initialize(true) on the correction task.
1721  std::string dummyTaskName = foundTaskName + "_dummyTask";
1722  mgr->AddTask(new AliAnalysisTaskSE(dummyTaskName.c_str()));
1723 
1724  return correctionTask;
1725 }
1726 
1732 std::string AliEmcalCorrectionTask::toString(bool includeYAMLConfigurationInfo) const
1733 {
1734  std::stringstream tempSS;
1735 
1736  // Show the correction components
1737  tempSS << "Correction components:\n";
1738  for (auto component : fOrderedComponentsToExecute) {
1739  tempSS << "\t" << component << "\n";
1740  }
1741  // Input objects
1742  tempSS << "\nInput objects:\n";
1746 
1747  if (includeYAMLConfigurationInfo == true) {
1748  tempSS << "\nUser Configuration:\n";
1749  PrintConfiguration(tempSS, true);
1750  tempSS << "\n\nDefault Configuration:\n";
1751  PrintConfiguration(tempSS);
1752  tempSS << "\n";
1753  }
1754 
1755  return tempSS.str();
1756 }
1757 
1764 std::ostream & AliEmcalCorrectionTask::Print(std::ostream & in) const {
1765  in << toString();
1766  return in;
1767 }
1768 
1776 std::ostream & operator<<(std::ostream & in, const AliEmcalCorrectionTask & myTask)
1777 {
1778  std::ostream & result = myTask.Print(in);
1779  return result;
1780 }
1781 
1789 {
1790  std::string temp(opt);
1791  bool includeYAMLConfig = false;
1792  if (temp == "YAML") {
1793  includeYAMLConfig = true;
1794  }
1795  Printf("%s", toString(includeYAMLConfig).c_str());
1796 }
void AdoptClusterContainer(AliClusterContainer *cont)
Int_t fNcentBins
how many centrality bins
void SetBranchName(std::string branchName)
Set the name of the cells branch (NOT the same as the name!)
std::string fSuffix
Suffix of the Correction Task (used to select specialized components)
void PrintRequestedContainersInformation(AliEmcalContainerUtils::InputObject_t inputObjectType, std::ostream &stream) const
Steering task for the EMCal correction framework.
AliEMCALGeometry * fGeom
! Emcal geometry
const char * filename
Definition: TestFCM.C:1
static const std::map< std::string, AliVCluster::VCluUserDefEnergy_t > fgkClusterEnergyTypeMap
Relates string to the cluster energy enumeration for YAML configuration.
static const AliVEvent * GetEvent(const AliVEvent *inputEvent, bool isEmbedding=false)
void SetTrackCutsPeriod(const char *period)
static AliEmcalCorrectionTask * ConfigureEmcalCorrectionTaskOnLEGOTrain(TString suffix)
std::string GetName() const
Get the name of the cells object (NOT the same as the branch!)
double Double_t
Definition: External.C:58
void SetArray(const AliVEvent *event)
void SetupContainer(const AliEmcalContainerUtils::InputObject_t inputObjectType, const std::string containerName)
AliVCaloCells * GetCaloCells() const
std::vector< std::string > fOrderedComponentsToExecute
Ordered set of components to execute.
bool WriteConfigurationFile(std::string filename, bool userConfig=false) const
bool CheckPossibleNamesForComponentName(std::string &name, std::set< std::string > &possibleComponents)
std::vector< AliEmcalCorrectionComponent * > fCorrectionComponents
Contains the correction components.
Container with name, TClonesArray and cuts for particles.
std::string GetInputFieldNameFromInputObjectType(AliEmcalContainerUtils::InputObject_t inputObjectType)
bool CompareConfigurations(const int config1, const int config2) const
void AdoptClusterContainer(AliClusterContainer *cont)
bool WriteConfiguration(const std::string &filename, const unsigned int i) const
void UserExec(Option_t *option)
AliEmcalCorrectionTask & operator=(AliEmcalCorrectionTask other)
const std::pair< std::string, YAML::Node > & GetConfiguration(const int i) const
Double_t fMaxCent
max centrality for event selection
Double_t fVertex[3]
! Event vertex
AliEmcalContainer * AddContainer(const AliEmcalContainerUtils::InputObject_t contType, const std::string containerName)
void DetermineComponentsToExecute(std::vector< std::string > &componentsToExecute)
bool GetProperty(std::vector< std::string > propertyPath, const std::string &propertyName, T &property, const bool requiredProperty) const
TList * fOutput
! Output for histograms
bool CompareToStoredConfiguration(std::string filename, bool userConfig=false)
Wrapper around cells objects for the EMCal Correction Task.
bool fConfigurationInitialized
True if the YAML configuration files are initialized.
bool DoesConfigurationExist(const int i) const
void CheckForContainerArray(AliEmcalContainer *cont, AliEmcalContainerUtils::InputObject_t objectType)
AliParticleContainer * GetParticleContainer(Int_t i=0) const
friend void swap(AliEmcalCorrectionTask &first, AliEmcalCorrectionTask &second)
Container for particles within the EMCAL framework.
void SetupCellsInfo(std::string containerName)
PWG::Tools::AliYAMLConfiguration fYAMLConfig
Handles configuration from YAML.
AliVCaloCells * GetCells() const
Pointer to the actual CaloCells object.
bool fEventInitialized
If the event is initialized properly.
TString fCentEst
name of V0 centrality estimator
void SetAODFilterBits(UInt_t bits)
void SetYAMLConfiguration(PWG::Tools::AliYAMLConfiguration config)
Set YAML Configuration.
int Int_t
Definition: External.C:63
std::string fUserConfigurationFilename
! User YAML configruation filename
void GetPropertyNamesFromNode(const std::string configurationName, const std::string componentName, std::set< std::string > &propertyNames, const bool nodeRequired)
InputObject_t
Type of input object to be created
AliClusterContainer * GetClusterContainer(Int_t i=0) const
unsigned int UInt_t
Definition: External.C:33
void SetClusNonLinCorrEnergyCut(Double_t cut)
static AliEmcalCorrectionTask * AddTaskEmcalCorrectionTask(TString suffix="")
void SetCells(AliVCaloCells *cells)
Sets the Pointer to the actual CaloCells object.
Double_t fCent
! Event centrality
void CreateInputObjects(AliEmcalContainerUtils::InputObject_t inputObjectType)
Base class for correction components in the EMCal correction framework.
BeamType
Switch for the beam type.
void AdoptParticleContainer(AliParticleContainer *cont)
void SetIncludePHOS(Bool_t b)
friend std::ostream & operator<<(std::ostream &in, const AliEmcalCorrectionTask &myTask)
Bool_t fNeedEmcalGeom
whether or not the task needs the emcal geometry
static const std::map< std::string, AliEmcalTrackSelection::ETrackFilterType_t > fgkTrackFilterTypeMap
Relates string to the track filter enumeration for YAML configuration.
std::string GetBranchName() const
Get the name of the cells branch (NOT the same as the name!)
void SetCellsObjectInCellContainerBasedOnProperties(AliEmcalCorrectionCellContainer *cellContainer)
Bool_t fUseNewCentralityEstimation
Use new centrality estimation (for 2015 data)
bool GetIsEmbedding() const
True if the cells are located in the event that is being embedded.
Bool_t Data(TH1F *h, Double_t *rangefit, Bool_t writefit, Double_t &sgn, Double_t &errsgn, Double_t &bkg, Double_t &errbkg, Double_t &sgnf, Double_t &errsgnf, Double_t &sigmafit, Int_t &status)
AliEmcalCorrectionCellContainer * GetCellContainer(const std::string &cellsContainerName) const
std::string fDefaultConfigurationFilename
! Default YAML configuration filename
TObjArray fParticleCollArray
Particle/track collection array.
TObjArray fClusterCollArray
Cluster collection array.
ETrackFilterType_t
Pre-defined track filters.
void AdoptParticleContainer(AliParticleContainer *cont)
bool RemoveConfiguration(const unsigned int i)
void SetIsEmbedding(bool isEmbedded)
Set to true if the cells are located in the event that is being embedded.
void SetCaloCells(AliVCaloCells *cells)
BeamType fBeamType
! Event beam type
static std::string DetermineUseDefaultName(InputObject_t objType)
void SetArray(const AliVEvent *event)
int AddConfiguration(std::string configurationFilename, std::string configurationName="")
Int_t GetRunNumber(TString)
Definition: PlotMuonQA.C:2235
void SetTrackFilterType(ETrackFilterType_t f)
std::string toString(bool includeYAMLConfigurationInfo=false) const
std::ostream & PrintConfiguration(std::ostream &in, bool userConfig=false) const
const char Option_t
Definition: External.C:48
void Print(Option_t *opt="") const
Int_t fNVertCont
! Event vertex number of contributors
static AliEmcalCorrectionComponent * createInstance(std::string const &s)
Creates an instance of an object based on the name if the name is registered in the map...
void SetName(std::string name)
Set the name of the cells object (NOT the same as the branch!)
bool Bool_t
Definition: External.C:53
Int_t fCentBin
! Event centrality bin
void SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, std::set< std::string > &requestedContainers)
Double_t fMinCent
min centrality for event selection
std::vector< AliEmcalCorrectionCellContainer * > fCellCollArray
Cells collection array.
Container structure for EMCAL clusters.
Container for MC-true particles within the EMCAL framework.
void AddContainersToComponent(AliEmcalCorrectionComponent *component, AliEmcalContainerUtils::InputObject_t inputObjectType, bool checkObjectExists=false)
void Initialize(bool removeDummyTask=false)
TList * OpenFile(const char *fname)
Definition: DrawAnaELoss.C:65
void SetClusHadCorrEnergyCut(Double_t cut)
void swap(AliEmcalCorrectionTask &first, AliEmcalCorrectionTask &second)
BeamType fForceBeamType
forced beam type