AliPhysics  master (3d17d9d)
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 <AliAnalysisManager.h>
19 #include <AliVEventHandler.h>
20 #include <AliESDEvent.h>
21 #include <AliAODEvent.h>
22 #include <AliEMCALGeometry.h>
23 #include <AliVCaloCells.h>
24 #include <AliLog.h>
25 #include <AliCentrality.h>
26 #include "AliMultSelection.h"
28 
30 ClassImp(AliEmcalCorrectionTask);
32 
36 
41  AliAnalysisTaskSE("AliEmcalCorrectionTask"),
42  fYAMLConfig(),
43  fSuffix(""),
44  fUserConfigurationFilename(""),
45  fDefaultConfigurationFilename(""),
46  fOrderedComponentsToExecute(),
47  fCorrectionComponents(),
48  fConfigurationInitialized(false),
49  fIsEsd(false),
50  fEventInitialized(false),
51  fCent(0),
52  fCentBin(-1),
53  fMinCent(-999),
54  fMaxCent(-999),
55  fNcentBins(4),
56  fCentEst("V0M"),
57  fUseNewCentralityEstimation(kFALSE),
58  fVertex{0},
59  fNVertCont(0),
60  fBeamType(kNA),
62  fNeedEmcalGeom(kTRUE),
63  fGeom(0),
67  fOutput(0)
68 {
69  // Default constructor
70  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
71 
72  fParticleCollArray.SetOwner(kTRUE);
73  fClusterCollArray.SetOwner(kTRUE);
74 }
75 
86  AliAnalysisTaskSE(name),
87  fYAMLConfig(),
88  fSuffix(""),
94  fIsEsd(false),
95  fEventInitialized(false),
96  fCent(0),
97  fCentBin(-1),
98  fMinCent(-999),
99  fMaxCent(-999),
100  fNcentBins(4),
101  fCentEst("V0M"),
103  fVertex{0},
104  fNVertCont(0),
105  fBeamType(kNA),
107  fNeedEmcalGeom(kTRUE),
108  fGeom(0),
111  fCellCollArray(),
112  fOutput(0)
113 {
114  // Standard constructor
115  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
116 
117  fParticleCollArray.SetOwner(kTRUE);
118  fClusterCollArray.SetOwner(kTRUE);
119 
120  DefineInput(0, TChain::Class());
121  DefineOutput(1, TList::Class());
122 }
123 
132  fYAMLConfig(task.fYAMLConfig),
133  fSuffix(task.fSuffix),
137  fCorrectionComponents(task.fCorrectionComponents), // TODO: These should be copied!
139  fIsEsd(task.fIsEsd),
141  fCent(task.fCent),
142  fCentBin(task.fCentBin),
143  fMinCent(task.fMinCent),
144  fMaxCent(task.fMaxCent),
145  fNcentBins(task.fNcentBins),
146  fCentEst(task.fCentEst),
148  fVertex{0.},
149  fNVertCont(task.fNVertCont),
150  fBeamType(task.fBeamType),
151  fForceBeamType(task.fForceBeamType),
152  fNeedEmcalGeom(task.fNeedEmcalGeom),
153  fGeom(task.fGeom),
154  fParticleCollArray(*(static_cast<TObjArray *>(task.fParticleCollArray.Clone()))),
155  fClusterCollArray(*(static_cast<TObjArray *>(task.fClusterCollArray.Clone()))),
156  fOutput(task.fOutput) // TODO: More care is needed here!
157 {
158  // Vertex position
159  std::copy(std::begin(task.fVertex), std::end(task.fVertex), std::begin(fVertex));
160 
161  // Cell Collections
162  for (auto cellCont : task.fCellCollArray)
163  {
164  fCellCollArray.push_back(new AliEmcalCorrectionCellContainer(*cellCont));
165  }
166 }
167 
173 {
174  swap(*this, other);
175 }
176 
182 {
183  swap(*this, other);
184 
185  return *this;
186 }
187 
192 {
193  using std::swap;
194 
195  swap(first.fYAMLConfig, second.fYAMLConfig);
196  swap(first.fSuffix, second.fSuffix);
202  swap(first.fIsEsd, second.fIsEsd);
204  swap(first.fCent, second.fCent);
205  swap(first.fCentBin, second.fCentBin);
206  swap(first.fMinCent, second.fMinCent);
207  swap(first.fMaxCent, second.fMaxCent);
208  swap(first.fNcentBins, second.fNcentBins);
209  swap(first.fCentEst, second.fCentEst);
211  swap(first.fVertex, second.fVertex);
212  swap(first.fNVertCont, second.fNVertCont);
213  swap(first.fBeamType, second.fBeamType);
214  swap(first.fForceBeamType, second.fForceBeamType);
215  swap(first.fNeedEmcalGeom, second.fNeedEmcalGeom);
216  swap(first.fGeom, second.fGeom);
219  swap(first.fCellCollArray, second.fCellCollArray);
220  swap(first.fOutput, second.fOutput);
221 }
222 
228 {
229  // Destructor
230 }
231 
232 void AliEmcalCorrectionTask::Initialize(bool removeDummyTask)
233 {
234  // Determine file type
235  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
236  if (mgr) {
237  AliVEventHandler *evhand = mgr->GetInputEventHandler();
238  if (evhand) {
239  if (evhand->InheritsFrom("AliESDInputHandler")) {
240  fIsEsd = true;
241  }
242  else {
243  fIsEsd = false;
244  }
245  }
246  else {
247  AliError("Event handler not found!");
248  }
249  }
250  else {
251  AliError("Analysis manager not found!");
252  }
253 
254  // Determine the suffix of the correction task
255  std::string tempName = GetName();
256  std::size_t foundSuffix = tempName.find("_");
257  if (foundSuffix != std::string::npos) {
258  // +1 to skip "_"
259  fSuffix = tempName.substr(foundSuffix + 1).c_str();
260  }
261 
262  if (fSuffix != "") {
263  AliInfoStream() << "Initializing correction task with suffix \"" << fSuffix << "\"" << std::endl;
264  }
265 
266  // Initialize %YAML configuration
268  // Check that the configuration is initialized
269  if (fConfigurationInitialized != true)
270  {
271  AliFatal("YAML configuration must be initialized before running (ie. in the run macro or wagon)!");
272  }
273 
274  // Determine component execution order
276 
277  // Check for user defined settings that are not in the default file
279 
280  // Setup input objects
281  // Setup Cells
282  // Cannot do this entirely yet because we need input objects
285  // Create cluster input objects
288  // Create track input objects
291 
292  // Initialize components
294 
295  if (removeDummyTask == true) {
296  RemoveDummyTask();
297  }
298 
299  // Print the results of the initialization
300  // Print outside of the ALICE Log system to ensure that it is always available!
301  std::cout << GetName() << " Settings:\n" << *this;
302 }
303 
309 {
310  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
311  if (!mgr)
312  {
313  AliErrorStream() << "No analysis manager to connect to.\n";
314  return;
315  }
316 
317  // Remove the dummy task
318  std::string dummyTaskName = GetName();
319  dummyTaskName += "_dummyTask";
320  TObjArray * tasks = mgr->GetTasks();
321  if (tasks) {
322  AliAnalysisTaskSE * dummyTask = dynamic_cast<AliAnalysisTaskSE *>(tasks->FindObject(dummyTaskName.c_str()));
323  if (!dummyTask) {
324  AliErrorStream() << "Could not remove dummy task \"" << dummyTaskName << "\" from analysis manager! Was it added?\n";
325  }
326  // Actually remove the task
327  tasks->Remove(dummyTask);
328  AliDebugStream(1) << "Removed dummy task named \"" << dummyTaskName << "\".\n";
329  }
330  else {
331  AliErrorStream() << "Could not retrieve tasks from the analysis manager.\n";
332  }
333 }
334 
344 {
345  // Determine file path
347  {
348  // Use the default if nothing is set
349  fDefaultConfigurationFilename = "$ALICE_PHYSICS/PWG/EMCAL/config/AliEmcalCorrectionConfiguration.yaml";
350  }
351 
352  // Setup and initialize configurations
353  // default is added first so that it will be checked last.
354  // Default file
355  int returnValue = fYAMLConfig.AddConfiguration(fDefaultConfigurationFilename, "default");
356  if (returnValue >= 0) {
357  AliInfoStream() << "Using default EMCal corrections configuration located at \"" << fDefaultConfigurationFilename << "\"\n";
358  }
359  else {
360  AliFatal(TString::Format("Default file located at \"%s\" does not exist!", fDefaultConfigurationFilename.c_str()));
361  }
362 
363  // User file
365  if (returnValue >= 0) {
366  AliInfoStream() << "Using user EMCal corrections configuration located at \"" << fUserConfigurationFilename << "\"\n";
367  }
368  else {
369  // For any tasks to be enabled, we must have a user config. So we make a missing user config a fatal.
370  AliFatal(TString::Format("User config file at \"%s\" does not exist! Please check the user config filename!", fUserConfigurationFilename.c_str()));
371  }
372 
373  // Initialize
375 
376  // Note that it is initialized properly so that the analysis can proceed
378 }
379 
390 void AliEmcalCorrectionTask::DetermineComponentsToExecute(std::vector <std::string> & correctionComponents)
391 {
392  std::vector <std::string> executionOrder;
393  // executionOrder determines the order of tasks to execute, but it doesn't name the particular tasks
394  fYAMLConfig.GetProperty("executionOrder", executionOrder, true);
395 
396  // Possible components to create from both the user and default configurations
397  // Use set so that the possible components are not repeated
398  std::set <std::string> possibleComponents;
399  if (fYAMLConfig.DoesConfigurationExist("user")) {
400  for (const auto node : fYAMLConfig.GetConfiguration("user").second) {
401  possibleComponents.insert(node.first.as<std::string>());
402  }
403  }
404  for (const auto node : fYAMLConfig.GetConfiguration("default").second) {
405  possibleComponents.insert(node.first.as<std::string>());
406  }
407 
408  // Determine the correction names associated with the correction task
409  std::string expectedComponentName = "";
410  bool foundSuffixComponent = false;
411  bool foundComponent = false;
412  bool componentEnabled = true;
413 
414  // Execution order determines the order that corrections should be added to our execution list
415  for (auto & execName : executionOrder)
416  {
417  // Construct the expected component name with the suffix
418  expectedComponentName = TString::Format("%s_%s", execName.c_str(), fSuffix.c_str()).Data();
419  foundComponent = false;
420  componentEnabled = false;
421 
422  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
423  if (foundComponent)
424  {
425  // Check if the component is enabled
426  fYAMLConfig.GetProperty({expectedComponentName, "enabled"}, componentEnabled, true);
427  // If enabled, then store the name so that it can be executed
428  if (componentEnabled == true) {
429  foundSuffixComponent = true;
430  correctionComponents.push_back(expectedComponentName);
431  }
432  else {
433  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
434  }
435 
436  continue;
437  }
438  else
439  {
440  // Look for the normal component
441  expectedComponentName = execName;
442  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
443  // Check if it is enabled
444  fYAMLConfig.GetProperty({expectedComponentName, "enabled"}, componentEnabled, true);
445 
446  if (componentEnabled == true) {
447  if (foundSuffixComponent == true) {
448  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()));
449  }
450  else {
451  // Take the normal component and store it to be executed
452  correctionComponents.push_back(expectedComponentName);
453  }
454  }
455  else {
456  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
457  }
458  }
459  }
460 
461  // Need to append "AliEmcalCorrection" to allow the tasks to be found!
462  AliDebug(2, "Found EMCal Correction Components: ");
463  for (auto & component : correctionComponents)
464  {
465  component = "AliEmcalCorrection" + component;
466  AliDebug(2, TString::Format("%s", component.c_str()) );
467  }
468 }
469 
483 {
484  // Names of properties for a particular component in the user and default configurations
485  std::set <std::string> userPropertyNames;
486  std::set <std::string> defaultPropertyNames;
487  // Notes whether a match was found between user and default properties
488  bool foundMatch = false;
489  std::string tempComponentName = "";
490 
491  // Loop over all components
492  for (const auto componentName : fOrderedComponentsToExecute)
493  {
494  // Reset for each loop
495  userPropertyNames.clear();
496  defaultPropertyNames.clear();
497  // We need to remove "AliEmcalCorrection" so that the correction will be found in the configuration
498  std::string prefix = "AliEmcalCorrection";
499  tempComponentName = componentName.substr(componentName.find(prefix) + prefix.length());
500 
501  AliDebugStream(2) << "Checking component " << componentName << " for unmatched user settings" << std::endl;
502 
503  // Get the user property names
504  GetPropertyNamesFromNode("user", tempComponentName, userPropertyNames, false);
505 
506  // Get the same from default
507  // Not required here because the default configuration may not have the specialized component
508  GetPropertyNamesFromNode("default", tempComponentName, defaultPropertyNames, false);
509 
510  // We need to check the base correction as well to fill out the options
511  if (tempComponentName.find("_") != std::string::npos) {
512  // Get the base user component
513  GetPropertyNamesFromNode("user", tempComponentName.substr(0, tempComponentName.find("_")), userPropertyNames, false);
514 
515  // Required here because the default must have the base component!
516  GetPropertyNamesFromNode("default", tempComponentName.substr(0, tempComponentName.find("_")), defaultPropertyNames, true);
517  }
518 
519  // Check each property defined in the user file for a match to the properties in the default file
520  for (auto userPropertyName : userPropertyNames)
521  {
522  AliDebugStream(2) << "Checking property " << userPropertyName << std::endl;
523  foundMatch = false;
524  for (auto defaultPropertyName : defaultPropertyNames)
525  {
526  if (userPropertyName == defaultPropertyName) {
527  AliDebugStream(2) << "Found match of " << userPropertyName << " with " << defaultPropertyName << std::endl;
528  foundMatch = true;
529  }
530  }
531  if (foundMatch == false) {
532  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()));
533  }
534  }
535  }
536 }
537 
545 {
546  // Iterate over the ordered components list and create the components
547  AliEmcalCorrectionComponent * component = 0;
548  for (auto componentName : fOrderedComponentsToExecute)
549  {
550  std::string noPrefixComponentName = componentName.substr(0, componentName.find("_" + fSuffix));
551  component = AliEmcalCorrectionComponentFactory::createInstance(noPrefixComponentName);
552  if (!component)
553  {
554  AliFatal(TString::Format("Failed to create requested component %s!", componentName.c_str()));
555  }
556 
557  // For setting names of tasks to differentiate between tasks of the same class
558  component->SetName(componentName.c_str());
559  component->SetTitle(componentName.c_str());
560 
561  // Initialize the %YAML configurations in each component
562  component->SetYAMLConfiguration(fYAMLConfig);
563 
564  // configure needed fields for components to properly initialize
565  component->SetIsESD(fIsEsd);
566 
567  // Add the require containers to the component
568  // Cells must be set during UserExec() because we need to add them as a pointer
571 
572  // Initialize each component
573  bool initialized = component->Initialize();
574 
575  if (component && initialized)
576  {
577  AliInfo(TString::Format("Successfully added correction task: %s", componentName.c_str()));
578  fCorrectionComponents.push_back(component);
579  }
580  }
581 }
582 
598 {
599  // Get container node
600  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
601 
602  // Determine which containers we need based on which are requested by the enabled correction tasks
603  std::set <std::string> requestedContainers;
604  std::vector <std::string> componentRequest;
605  for ( const auto & componentName : fOrderedComponentsToExecute )
606  {
607  componentRequest.clear();
608  // Not required because not all components will have all kinds of containers
609  std::string selectionName = "AliEmcalCorrection";
610  // Expliecitly initialize as a vector to avoid ambiguity.
611  fYAMLConfig.GetProperty(std::vector<std::string>{componentName.substr(componentName.find(selectionName) + selectionName.length()), inputObjectName + "Names"}, componentRequest, false);
612  for ( auto & req : componentRequest )
613  {
614  AliDebugStream(3) << "Component " << componentName << " requested container name " << req << std::endl;
615  requestedContainers.insert(req);
616  }
617  }
618 
619  AliDebugStream(2) << inputObjectName << " Containers requested by components: " << std::endl;
620  for (auto & str : requestedContainers) {
621  AliDebugStream(2) << "\t" << str << std::endl;;
622  }
623 
624  // Create all requested containers
625  AliDebug(2, TString::Format("Setting up requested containers!"));
626  SetupContainersFromInputNodes(inputObjectType, requestedContainers);
627 }
628 
638 {
639  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
640  // Need to be of the form "clusterContainersNames"
641  inputObjectName = inputObjectName + "Names";
642 
643  std::vector <std::string> inputObjects;
644  // Property is not required, because not all components need Clusters or Tracks
645  // Expliecitly initialize as a vector to avoid ambiguity.
646  fYAMLConfig.GetProperty(std::vector<std::string>{component->GetName(), inputObjectName.c_str()}, inputObjects, false);
647 
648  //AliDebugStream(4) << "inputObjects.size(): " << inputObjects.size() << std::endl;
649 
650  // If it is not found, then there will be nothing to iterate over, so we don't need to explicitly check the return value
651  for (auto const & str : inputObjects)
652  {
653  // 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()!
654  if (inputObjectType == AliEmcalContainerUtils::kCluster)
655  {
656  AliEmcalContainer * cont = GetClusterContainer(str.c_str());
657  AliDebugStream(2) << "Adding cluster container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
658 
659  if (checkObjectExists && !cont) {
660  AliError(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
661  }
662  component->AdoptClusterContainer(GetClusterContainer(str.c_str()));
663 
664  // Check that we are using the standard input event
665  if (!(cont->GetIsEmbedding())) {
666  component->SetUsingInputEvent(true);
667  }
668  }
669  else if (inputObjectType == AliEmcalContainerUtils::kTrack)
670  {
671  AliEmcalContainer * cont = GetParticleContainer(str.c_str());
672  AliDebugStream(2) << "Adding particle container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
673 
674  if (checkObjectExists && !cont) {
675  AliFatal(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
676  }
677  component->AdoptParticleContainer(GetParticleContainer(str.c_str()));
678 
679  // Check that we are using the standard input event
680  if (!(cont->GetIsEmbedding())) {
681  component->SetUsingInputEvent(true);
682  }
683  }
684  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells)
685  {
686  // NOTE: This operates different than the others. This should be executed during run time rather than during initialization!
687  if (inputObjects.size() > 1) {
688  AliFatal(TString::Format("Component %s requested more than one cell branch, but this is not supported! Check the configuration!", component->GetName()));
689  }
690 
691  // If we've made it here, this must be at least one entry
693  AliDebugStream(2) << "Adding calo cells \"" << cellCont->GetName() << "\" of branch name \"" << cellCont->GetBranchName() << "\" to component " << component->GetName() << std::endl;
694 
695  if (!(cellCont->GetCells())) {
696  // Attempt to re-initialize the cells.
697  // NOTE: This may not succeed. Adding the container may need to be repeated after the
698  // object is created
700  }
701 
702  if (checkObjectExists && !(cellCont->GetCells())) {
703  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()));
704  }
705 
706  // Set the calo cells (may be null)
707  component->SetCaloCells(cellCont->GetCells());
708 
709  // It is possible that the cells pointer is null because it may not be created yet. For example,
710  // when combining cells. Thus, we must first check whether the pointer is available before checking
711  // for the number of cells. This could potentially decrease the amount of debug information, but this
712  // should rarely be an issue.
713  if (component->GetCaloCells()) {
714  AliDebugStream(3) << "Component GetNumberOfCells(): " << component->GetCaloCells()->GetNumberOfCells() << std::endl;
715  }
716 
717  // Check that we are using the standard input event
718  if (!(cellCont->GetIsEmbedding())) {
719  component->SetUsingInputEvent(true);
720  }
721  }
722  }
723 }
724 
731 void AliEmcalCorrectionTask::SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, std::set <std::string> & requestedContainers)
732 {
733  // Our node contains all of the objects that we will want to create.
734  for(auto & containerName : requestedContainers)
735  {
736  // The section is the container name
737  //std::string containerName = it->first.as<std::string>();
738  // Skip if the particle or cluster container already exists
739  if (GetParticleContainer(containerName.c_str()) || GetClusterContainer(containerName.c_str())) {
740  continue;
741  }
742 
743  AliDebug(2, TString::Format("Processing container %s of inputType %d", containerName.c_str(), inputObjectType));
744  if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
745  SetupContainer(inputObjectType, containerName);
746  }
747  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
748  SetupCellsInfo(containerName);
749  }
750  }
751 }
752 
761 void AliEmcalCorrectionTask::SetupCellsInfo(std::string containerName)
762 {
763  // Define cell info
765 
766  // Set properties
767  // Cells (object) name
768  cellObj->SetName(containerName);
769  // Branch name
770  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(AliEmcalContainerUtils::kCaloCells), containerName};
771  std::string tempString = "";
772  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "branchName", tempString, true);
773  if (tempString == "usedefault") {
775  }
776  cellObj->SetBranchName(tempString);
777 
778  // IsEmbedding
779  bool tempBool = false;
780  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "embedding", tempBool, false);
781  cellObj->SetIsEmbedding(tempBool);
782 
783  // Add to the array to keep track of it
784  fCellCollArray.push_back(cellObj);
785 }
786 
802 void AliEmcalCorrectionTask::SetupContainer(const AliEmcalContainerUtils::InputObject_t inputObjectType, const std::string containerName)
803 {
804  // Create container
805  AliDebugStream(2) << "Adding container" << std::endl;
806  AliEmcalContainer * cont = AddContainer(inputObjectType, containerName);
807  AliDebugStream(2) << "Added container" << std::endl;
808 
809  // Set the container properties
810  //
811  // TODO: Consider if this can be converted to a map to function pointers. There are a number of details
812  // which can make it a bit complicated. Those details include inheritance, pointing to member
813  // functions, etc. It should all be possible, but may not be worth all of the extra work and code.
814  // Example ccode:
815  // SetValueInContainer(inputObjectPropertiesPath, "minPt", &cont::SetMinPt, tempDouble, false);
816  // SetValueInContainer(inputObjectPropertiesPath, "minE", &cont::SetMinE, tempDouble, false);
817  // std::function may be easier?
818  // See: https://isocpp.org/wiki/faq/pointers-to-members
821  // type void (AliEmcalContainer::*EmcalContainerFn)(double val);
822  // // Potential map?
823  // std::map<std::string, EmcalContainerFn> EmcalContFunctionMap;
824  // EmcalContFunctionMap["minPt"] = &AliEmcalContainer::SetMinPt;
825  // EmcalContFunctionMap["minE"] = &AliEmcalContainer::SetMinE;
826  // // Define functions (use map?)
827  // EmcalContainerFn minPt = &AliEmcalContainer::SetMinPt;
828  // EmcalContainerFn minE = &AliEmcalContainer::SetMinE;
829  // // Example invocation
830  // (cont->*minPt)(tempDouble);
831 
832  // Path to the various properties
833  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(inputObjectType), containerName};
834 
835  // Temporary variables to store requested properties
836  std::string tempString = "";
837  Double_t tempDouble = 0;
838  bool tempBool = false;
839 
840  // AliEmcalContainer properties
841  // Min Pt
842  bool result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minPt", tempDouble, false);
843  if (result) {
844  AliDebugStream(2) << cont->GetName() << ": Setting minPt of " << tempDouble << std::endl;
845  cont->SetMinPt(tempDouble);
846  }
847  // Min E
848  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minE", tempDouble, false);
849  if (result) {
850  AliDebugStream(2) << cont->GetName() << ": Setting minE of " << tempDouble << std::endl;
851  cont->SetMinE(tempDouble);
852  }
853  // Eta min, max
854  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minEta", tempDouble, false);
855  if (result) {
856  // Only continue checking if the min is there, since we must set both together
857  Double_t tempDouble2 = 0;
858  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "maxEta", tempDouble2, false);
859  if (result) {
860  AliDebugStream(2) << cont->GetName() << ": Setting eta limits of " << tempDouble << " to " << tempDouble2 << std::endl;
861  cont->SetEtaLimits(tempDouble, tempDouble2);
862  }
863  }
864  // Phi min, max
865  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minPhi", tempDouble, false);
866  if (result) {
867  // Only continue checking if the min is there, since we must set both together
868  Double_t tempDouble2 = 0;
869  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "maxPhi", tempDouble2, false);
870  if (result) {
871  AliDebugStream(2) << cont->GetName() << ": Setting phi limits of " << tempDouble << " to " << tempDouble2 << std::endl;
872  cont->SetPhiLimits(tempDouble, tempDouble2);
873  }
874  }
875  // Embedded
876  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "embedding", tempBool, false);
877  if (result) {
878  AliDebugStream(2) << cont->GetName() << ": Setting embedding to " << (tempBool ? "enabled" : "disabled") << std::endl;
879  cont->SetIsEmbedding(tempBool);
880  }
881 
882  // Cluster specific properties
883  AliClusterContainer * clusterContainer = dynamic_cast<AliClusterContainer *>(cont);
884  if (clusterContainer) {
885  // Default energy
886  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "defaultClusterEnergy", tempString, false);
887  if (result) {
888  // Need to get the enumeration
889  AliVCluster::VCluUserDefEnergy_t clusterEnergyType = AliClusterContainer::fgkClusterEnergyTypeMap.at(tempString);
890  AliDebugStream(2) << clusterContainer->GetName() << ": Setting cluster energy type to " << clusterEnergyType << std::endl;
891  clusterContainer->SetDefaultClusterEnergy(clusterEnergyType);
892  }
893 
894  // NonLinCorrEnergyCut
895  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "clusNonLinCorrEnergyCut", tempDouble, false);
896  if (result) {
897  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusNonLinCorrEnergyCut of " << tempDouble << std::endl;
898  clusterContainer->SetClusNonLinCorrEnergyCut(tempDouble);
899  }
900 
901  // HadCorrEnergyCut
902  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "clusHadCorrEnergyCut", tempDouble, false);
903  if (result) {
904  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusHadCorrEnergyCut of " << tempDouble << std::endl;
905  clusterContainer->SetClusHadCorrEnergyCut(tempDouble);
906  }
907 
908  // SetIncludePHOS
909  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "includePHOS", tempBool, false);
910  if (result) {
911  AliDebugStream(2) << clusterContainer->GetName() << ": Setting Include PHOS to " << (tempBool ? "enabled" : "disabled") << std::endl;
912  clusterContainer->SetIncludePHOS(tempBool);
913  }
914  }
915 
916  // Track specific
917  AliTrackContainer * trackContainer = dynamic_cast<AliTrackContainer *>(cont);
918  if (trackContainer) {
919  // Track selection
920  // AOD Filter bits as a sequence
921  std::vector <UInt_t> filterBitsVector;
922  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "aodFilterBits", filterBitsVector, false);
923  if (result){
924  UInt_t filterBits = 0;
925  for (int filterBit : filterBitsVector) {
926  filterBits += filterBit;
927  }
928  AliDebugStream(2) << trackContainer->GetName() << ": Setting filterBits of " << filterBits << std::endl;
929  trackContainer->SetAODFilterBits(filterBits);
930  }
931 
932  // SetTrackFilterType enum
933  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "trackFilterType", tempString, false);
934  if (result) {
935  // Need to get the enumeration
937  AliDebugStream(2) << trackContainer->GetName() << ": Setting trackFilterType of " << trackFilterType << " (" << tempString << ")\n";
938  trackContainer->SetTrackFilterType(trackFilterType);
939  }
940 
941  // Track cuts period
942  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "trackCutsPeriod", tempString, false);
943  if (result) {
944  // Need to get the enumeration
945  AliDebugStream(2) << trackContainer->GetName() << ": Setting track cuts period to " << tempString << std::endl;
946  trackContainer->SetTrackCutsPeriod(tempString.c_str());
947  }
948  }
949 }
950 
967 {
968  // Determine the type of branch to request
969  std::string containerBranch = "";
971  AliFatal("Must specify type of container when requesting branch.");
972  }
973 
974  // Path to the various properties
975  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(contType), containerName};
976 
977  // Retrieve branch name
978  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "branchName", containerBranch, true);
979  // Should be unnecessary, since the user can only do this if done explicitly.
980  /*if (containerBranch == "")
981  {
982  AliFatal(TString::Format("Request %i container, but the container branch is empty!", contType));
983  }*/
984 
985  // Determine proper name if using "usedefault" pattern
986  if (containerBranch == "usedefault") {
987  containerBranch = AliEmcalContainerUtils::DetermineUseDefaultName(contType, fIsEsd);
988  }
989 
990  // Create containers and set them to the name of the component
991  AliEmcalContainer * cont = 0;
992  if (contType == AliEmcalContainerUtils::kCluster)
993  {
994  cont = new AliClusterContainer(containerBranch.c_str());
995  AdoptClusterContainer(dynamic_cast<AliClusterContainer *>(cont));
996  }
997  else if (contType == AliEmcalContainerUtils::kTrack)
998  {
999  if (containerBranch == "mcparticles") {
1000  cont = new AliMCParticleContainer(containerBranch.c_str());
1001  }
1002  else {
1003  cont = new AliTrackContainer(containerBranch.c_str());
1004  }
1005  AdoptParticleContainer(dynamic_cast<AliParticleContainer *>(cont));
1006  }
1007  cont->SetName(containerName.c_str());
1008 
1009  return cont;
1010 }
1011 
1021 {
1022  // Check that the configuration is initialized
1023  if (fConfigurationInitialized != true)
1024  {
1025  AliFatal("YAML configuration must be initialized before running (ie. the AddTask, run macro or wagon)!");
1026  }
1027 
1028  // %YAML Objects cannot be streamed, so we need to reinitialize them here.
1030 
1031  if (fForceBeamType == kpp)
1032  fNcentBins = 1;
1033 
1034  // Allow for output files
1035  OpenFile(1);
1036  fOutput = new TList();
1037  fOutput->SetOwner();
1038 
1040 
1041  PostData(1, fOutput);
1042 }
1043 
1051 {
1052  // Run the initialization for all derived classes.
1053  for (auto component : fCorrectionComponents)
1054  {
1055  // Set cent bins (usually used for hist creation)
1056  // It cannot be set until now because it can be changed after initialization
1057  // For instance, by SetForceBeamType()
1058  component->SetNcentralityBins(fNcentBins);
1059 
1060  component->UserCreateOutputObjects();
1061 
1062  if (component->GetOutputList() != 0)
1063  {
1064  // Adds a list to the list -- this doesn't work for some unknown reason
1065  //fOutput->Add(component->GetOutputList());
1066 
1067  // iterate through lists for each component, and fill in output
1068  TList* t = new TList();
1069  t->SetName(component->GetName());
1070  fOutput->AddLast(t);
1071  t = (TList*)fOutput->Last();
1072  TIter next(component->GetOutputList());
1073  while (TObject *obj = next()){
1074  t->Add(obj);
1075  }
1076 
1077  AliDebug(1, TString::Format("Added output list from task %s to output.", component->GetName()));
1078  }
1079  }
1080 }
1081 
1087 {
1088  // Initialize the event if not initialized
1089  if (!fEventInitialized)
1090  ExecOnce();
1091 
1092  // Only continue if we are initialized successfully
1093  if (!fEventInitialized)
1094  return;
1095 
1096  // Get the objects for each event
1097  if (!RetrieveEventObjects())
1098  return;
1099 
1100  // Call run for each correction
1101  if (!Run())
1102  return;
1103 }
1104 
1116 {
1117  if (!InputEvent()) {
1118  AliError("Could not retrieve event! Returning!");
1119  return;
1120  }
1121 
1122  // This warning was extracted out from the cell components
1123  if (dynamic_cast<AliAODEvent*>(InputEvent())) {
1124  AliWarning("=============================================================");
1125  AliWarning("=== Running on AOD is not equivalent to running on ESD! ===");
1126  AliWarning("=============================================================");
1127  }
1128 
1129  if (fNeedEmcalGeom) {
1130  fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(InputEvent()->GetRunNumber());
1131  if (!fGeom) {
1132  AliFatal("Can not get EMCal geometry instance. If you do not need the EMCal geometry, disable it by setting task->SetNeedEmcalGeometry(kFALSE).");
1133  return;
1134  }
1135  }
1136 
1137  // Load all requested track branches - each container knows name already
1138  for (Int_t i =0; i<fParticleCollArray.GetEntriesFast(); i++) {
1139  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
1141  cont->SetArray(InputEvent());
1142  }
1143 
1144  // Load all requested cluster branches - each container knows name already
1145  for (Int_t i =0; i<fClusterCollArray.GetEntriesFast(); i++) {
1146  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
1148  cont->SetArray(InputEvent());
1149  }
1150 
1151  // Determine the proper pointer for each cell object and save them to the cell container
1152  // At this point, they should all be created
1153  for (auto cellObj : fCellCollArray)
1154  {
1156  }
1157 
1158  fEventInitialized = kTRUE;
1159 
1160  // Print warning to the user that the rest of the configuration information is available in the generation log
1161  // when the Analysis Manager was created. Using cout to be certain that it is shown on the train!
1162  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";
1163 
1164  // Setup the components
1166 }
1167 
1173 {
1174  // Run the initialization for all derived classes.
1175  for (auto component : fCorrectionComponents)
1176  {
1177  // Setup geometry
1178  component->SetEMCALGeometry(fGeom);
1179 
1180  // Add the requested cells to the component
1182 
1183  // Set the input events. This is redundant to where it is set during Run(), but the events need to be
1184  // available to components, and they are only called one extra time.
1185  component->SetInputEvent(InputEvent());
1186  component->SetMCEvent(MCEvent());
1187 
1188  // Component ExecOnce()
1189  component->ExecOnce();
1190 
1191  // If the cells were created during ExecOnce(), then we need to re-initialize the pointer to ensure
1192  // that it is not null!
1193  if (!(component->GetCaloCells())) {
1194  AliDebugStream(2) << "Re-initializing cells for component " << component->GetName() << std::endl;
1196  }
1197  }
1198 }
1199 
1205 {
1206  fVertex[0] = 0;
1207  fVertex[1] = 0;
1208  fVertex[2] = 0;
1209  fNVertCont = 0;
1210 
1211  const AliVVertex *vert = InputEvent()->GetPrimaryVertex();
1212  if (vert) {
1213  vert->GetXYZ(fVertex);
1214  fNVertCont = vert->GetNContributors();
1215  }
1216 
1217  fBeamType = GetBeamType();
1218 
1219  if (fBeamType == kAA || fBeamType == kpA ) {
1221  AliMultSelection *MultSelection = static_cast<AliMultSelection*>(InputEvent()->FindListObject("MultSelection"));
1222  if (MultSelection) {
1223  fCent = MultSelection->GetMultiplicityPercentile(fCentEst.Data());
1224  }
1225  else {
1226  AliWarning("Could not retrieve centrality information! Assuming 99");
1227  }
1228  }
1229  else { // old centrality estimation < 2015
1230  AliCentrality *aliCent = InputEvent()->GetCentrality();
1231  if (aliCent) {
1232  fCent = aliCent->GetCentralityPercentile(fCentEst.Data());
1233  }
1234  else {
1235  AliWarning("Could not retrieve centrality information! Assuming 99");
1236  }
1237  }
1238 
1239  if (fNcentBins==4) {
1240  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1241  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1242  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1243  else if (fCent >= 50 && fCent <= 100) fCentBin = 3;
1244  else {
1245  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1246  fCentBin = fNcentBins-1;
1247  }
1248  }
1249  else if (fNcentBins==5) { // for PbPb 2015
1250  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1251  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1252  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1253  else if (fCent >= 50 && fCent <= 90) fCentBin = 3;
1254  else if (fCent > 90) {
1255  fCent = 99;
1256  fCentBin = 4;
1257  }
1258  else {
1259  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1260  fCentBin = fNcentBins-1;
1261  }
1262  }
1263  else {
1264  Double_t centWidth = (fMaxCent-fMinCent)/(Double_t)fNcentBins;
1265  if(centWidth>0.) {
1266  fCentBin = TMath::FloorNint(fCent/centWidth);
1267  }
1268  else {
1269  fCentBin = 0;
1270  }
1271  if (fCentBin>=fNcentBins) {
1272  AliWarning(Form("fCentBin too large: cent = %f fCentBin = %d. Assuming 99", fCent, fCentBin));
1273  fCentBin = fNcentBins-1;
1274  }
1275  }
1276  }
1277  else {
1278  fCent = 99;
1279  fCentBin = 0;
1280  }
1281 
1282  AliEmcalContainer* cont = 0;
1283 
1284  TIter nextPartColl(&fParticleCollArray);
1285  while ((cont = static_cast<AliEmcalContainer*>(nextPartColl()))) cont->NextEvent(InputEvent());
1286 
1287  TIter nextClusColl(&fClusterCollArray);
1288  while ((cont = static_cast<AliEmcalContainer*>(nextClusColl()))) cont->NextEvent(InputEvent());
1289 
1290  return kTRUE;
1291 }
1292 
1298 {
1299  // Run the initialization for all derived classes.
1300  for (auto component : fCorrectionComponents)
1301  {
1302  component->SetInputEvent(InputEvent());
1303  component->SetMCEvent(MCEvent());
1304  component->SetCentralityBin(fCentBin);
1305  component->SetCentrality(fCent);
1306  component->SetVertex(fVertex);
1307 
1308  component->Run();
1309  }
1310 
1311  PostData(1, fOutput);
1312 
1313  return kTRUE;
1314 }
1315 
1320 {
1321  // Run the initialization for all derived classes.
1322  for (auto component : fCorrectionComponents)
1323  {
1324  component->UserNotify();
1325  }
1326 
1327  return kTRUE;
1328 }
1329 
1336 std::ostream & AliEmcalCorrectionTask::PrintConfiguration(std::ostream & in, bool userConfig) const
1337 {
1338  std::string configurationName = userConfig ? "user" : "default";
1339  if (fYAMLConfig.DoesConfigurationExist(configurationName)) {
1340  auto configPair = fYAMLConfig.GetConfiguration(configurationName);
1341  if (configPair.second.IsNull() == true) {
1342  AliWarning(TString::Format("%s configuration is empty!", configPair.first.c_str()));
1343  }
1344  in << configPair.second;
1345  }
1346  else {
1347  in << "Configuration \"" << configurationName << "\" does not exist!\n";
1348  }
1349 
1350  return in;
1351 }
1352 
1360 bool AliEmcalCorrectionTask::WriteConfigurationFile(std::string filename, bool userConfig) const
1361 {
1362  return fYAMLConfig.WriteConfiguration(filename, userConfig ? "user" : "default");
1363 }
1364 
1374 {
1375  // Setup
1376  // It's important to reinitialize the configuration so the %YAML nodes are defined!
1378  std::string tempConfigName = "tempConfig";
1379  fYAMLConfig.AddConfiguration(filename, tempConfigName);
1380 
1381  // Compare
1382  bool returnValue = fYAMLConfig.CompareConfigurations(tempConfigName, userConfig ? "user" : "default");
1383 
1384  // Cleanup
1385  fYAMLConfig.RemoveConfiguration(tempConfigName);
1386 
1387  return returnValue;
1388 }
1389 
1397 {
1398  AliDebugStream(2) << "Retrieving cells object " << cellContainer->GetName() << std::endl;
1399  // Check for embedding and return object
1400  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cellContainer->GetIsEmbedding());
1401 
1402  cellContainer->SetCells(dynamic_cast<AliVCaloCells *>(event->FindListObject(cellContainer->GetBranchName().c_str())));
1403 }
1404 
1415 {
1416  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cont->GetIsEmbedding());
1417 
1418  TClonesArray * array = dynamic_cast<TClonesArray *>(event->FindListObject(cont->GetArrayName()));
1419  if (!array) {
1420  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()));
1421  array = new TClonesArray(AliEmcalContainerUtils::DetermineUseDefaultName(objectType, fIsEsd, true).c_str());
1422  array->SetName(cont->GetArrayName());
1423  event->AddObject(array);
1424  }
1425 }
1426 
1435 {
1436  // Get container node
1437  std::string inputObjectName = "";
1438  if (inputObjectType == AliEmcalContainerUtils::kCluster) {
1439  inputObjectName = "clusterContainers";
1440  }
1441  else if (inputObjectType == AliEmcalContainerUtils::kTrack) {
1442  inputObjectName = "trackContainers";
1443  }
1444  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1445  inputObjectName = "cells";
1446  }
1447  else {
1448  AliFatal(TString::Format("Unrecognized input object type %d", inputObjectType));
1449  }
1450 
1451  return inputObjectName;
1452 }
1453 
1465 bool AliEmcalCorrectionTask::CheckPossibleNamesForComponentName(std::string & name, std::set <std::string> & possibleComponents)
1466 {
1467  bool foundComponent = false;
1468  for (auto & possibleComponent : possibleComponents)
1469  {
1470  if (possibleComponent == name) {
1471  foundComponent = true;
1472  break;
1473  }
1474  }
1475 
1476  return foundComponent;
1477 }
1478 
1486 {
1487  if (fForceBeamType != kNA)
1488  return fForceBeamType;
1489 
1490  AliESDEvent *esd = dynamic_cast<AliESDEvent*>(InputEvent());
1491  if (esd) {
1492  const AliESDRun *run = esd->GetESDRun();
1493  TString beamType = run->GetBeamType();
1494  if (beamType == "p-p")
1495  return kpp;
1496  else if (beamType == "A-A")
1497  return kAA;
1498  else if (beamType == "p-A")
1499  return kpA;
1500  else
1501  return kNA;
1502  } else {
1503  Int_t runNumber = InputEvent()->GetRunNumber();
1504  // All run number ranges taken from the RCT
1505  if ((runNumber >= 136833 && runNumber <= 139517) || // LHC10h
1506  (runNumber >= 167693 && runNumber <= 170593) || // LHC11h
1507  (runNumber >= 244824 && runNumber <= 246994)) { // LHC15o
1508  return kAA;
1509  } else if ((runNumber >= 188356 && runNumber <= 188366) || // LHC12g
1510  (runNumber >= 195164 && runNumber <= 197388) || // LHC13b-f
1511  (runNumber >= 265015 && runNumber <= 267166)) { // LHC16q-t
1512  return kpA;
1513  } else {
1514  return kpp;
1515  }
1516  }
1517 }
1518 
1523 {
1524  if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1525  stream << "Cells info: " << std::endl;
1526  for (auto cellInfo : fCellCollArray) {
1527  stream << "\tName: " << cellInfo->GetName() << "\tBranch: " << cellInfo->GetBranchName() << "\tIsEmbedding: " << std::boolalpha << cellInfo->GetIsEmbedding() << std::endl;
1528  }
1529  }
1530  else if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
1531  stream << (inputObjectType == AliEmcalContainerUtils::kCluster ? "Cluster" : "Track") << " container info: " << std::endl;
1532  AliEmcalContainer * cont = 0;
1533  for (auto containerInfo : (inputObjectType == AliEmcalContainerUtils::kCluster ? fClusterCollArray : fParticleCollArray) ) {
1534  cont = static_cast<AliEmcalContainer *>(containerInfo);
1535  stream << "\tName: " << cont->GetName() << "\tBranch: " << cont->GetArrayName() << "\tTitle: " << cont->GetTitle() << "\tIsEmbedding: " << std::boolalpha << cont->GetIsEmbedding() << std::endl;
1536  }
1537  }
1538  else {
1539  AliErrorStream() << "Unrecognized input object type " << inputObjectType << std::endl;
1540  }
1541 }
1542 
1556 void AliEmcalCorrectionTask::GetPropertyNamesFromNode(const std::string configurationName, const std::string componentName, std::set <std::string> & propertyNames, const bool nodeRequired)
1557 {
1558  bool retrievedPropertyNames = false;
1559  if (fYAMLConfig.DoesConfigurationExist(configurationName)) {
1560  AliDebugStream(3) << "Looking for nodes in component \"" << componentName << "\" in the \"" << configurationName << "\" configuration\n";
1561  auto configPair = fYAMLConfig.GetConfiguration(configurationName);
1562  if (configPair.second[componentName])
1563  {
1564  for (auto propertyName : configPair.second[componentName])
1565  {
1566  AliDebugStream(4) << "Node property name " << propertyName.first.as<std::string>() << "\n";
1567  propertyNames.insert(propertyName.first.as<std::string>());
1568  }
1569  retrievedPropertyNames = true;
1570  }
1571  }
1572 
1573  if (retrievedPropertyNames == false && nodeRequired) {
1574  std::stringstream message;
1575  message << "Failed to retrieve required property \""
1576  << componentName << "\" from the \"" << configurationName << "\" configuration!" << std::endl;
1577  AliFatal(message.str().c_str());
1578  }
1579 }
1580 
1590 {
1591  AliEmcalCorrectionComponent * returnComponent = nullptr;
1592  for (auto component : fCorrectionComponents)
1593  {
1594  if (name == component->GetName()) {
1595  returnComponent = component;
1596  break;
1597  }
1598  }
1599  return returnComponent;
1600 }
1601 
1609 AliEmcalCorrectionCellContainer * AliEmcalCorrectionTask::GetCellContainer(const std::string & cellsContainerName) const
1610 {
1611  for (auto cellContainer : fCellCollArray)
1612  {
1613  if (cellContainer->GetName() == cellsContainerName) {
1614  return cellContainer;
1615  }
1616  }
1617 
1618  return 0;
1619 }
1620 
1622 {
1623  // Get the pointer to the existing analysis manager via the static access method.
1624  //==============================================================================
1625  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1626  if (!mgr)
1627  {
1628  ::Error("AddTaskEmcalCorrectionTask", "No analysis manager to connect to.");
1629  return nullptr;
1630  }
1631 
1632  // Check the analysis type using the event handlers connected to the analysis manager.
1633  //==============================================================================
1634  AliVEventHandler* handler = mgr->GetInputEventHandler();
1635  if (!handler)
1636  {
1637  ::Error("AddTaskEmcalCorrectionTask", "This task requires an input event handler");
1638  return nullptr;
1639  }
1640 
1641  TString name = "AliEmcalCorrectionTask";
1642  if (suffix != "") {
1643  name += TString::Format("_%s", suffix.Data());
1644  }
1645 
1646  AliEmcalCorrectionTask* mgrTask = static_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.Data()));
1647  if (mgrTask) return mgrTask;
1648 
1649  // Create the task that manages the corrections
1650  AliEmcalCorrectionTask* correctionTask = new AliEmcalCorrectionTask(name.Data());
1651 
1652  //-------------------------------------------------------
1653  // Final settings, pass to manager and set the containers
1654  //-------------------------------------------------------
1655 
1656  mgr->AddTask(correctionTask);
1657 
1658  // Create containers for input/output
1659  AliAnalysisDataContainer* cInput = mgr->GetCommonInputContainer();
1660 
1661  TString outputContainerName(name);
1662  outputContainerName += "_histos";
1663 
1664  AliAnalysisDataContainer * cOutput = mgr->CreateContainer(outputContainerName.Data(),
1665  TList::Class(),
1666  AliAnalysisManager::kOutputContainer,
1667  Form("%s", AliAnalysisManager::GetCommonFileName()));
1668 
1669  mgr->ConnectInput(correctionTask, 0, cInput);
1670  mgr->ConnectOutput(correctionTask, 1, cOutput);
1671 
1672  //TObjArray* cnt = mgr->GetContainers();
1673 
1674  return correctionTask;
1675 }
1676 
1678 {
1679  // Get the pointer to the existing analysis manager via the static access method.
1680  //==============================================================================
1681  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1682  if (!mgr)
1683  {
1684  ::Error("ConfigureEmcalCorrectionTaskOnLEGOTrain", "No analysis manager to connect to.");
1685  return nullptr;
1686  }
1687 
1688  // Find the correction task
1689  AliEmcalCorrectionTask * correctionTask = nullptr;
1690  const std::string taskName = "AliEmcalCorrectionTask";
1691  std::string foundTaskName = "";
1692  bool taskFound = false;
1693  std::vector<std::string> namesToSearch = {taskName};
1694 
1695  // Determine if the suffix name should be searched for.
1696  // If a suffix is given, it will be looked for first, followed by the generically named task.
1697  // This way, a user's configuration can be uniquely identified in the case of multiple correction tasks, but
1698  // if there is only one correction task without a suffix, this method will still fall back to that one and
1699  // return a correction task to be configured.
1700  if (suffix != "")
1701  {
1702  std::string suffixName = taskName;
1703  suffixName += "_";
1704  suffixName += suffix.Data();
1705  namesToSearch.insert(namesToSearch.begin(), suffixName);
1706  }
1707 
1708  // Attempt to retrieve the task from the analysis manager
1709  for (auto name : namesToSearch)
1710  {
1711  correctionTask = dynamic_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.c_str()));
1712  if (correctionTask != nullptr) {
1713  taskFound = true;
1714  foundTaskName = name;
1715  break;
1716  }
1717  }
1718 
1719  // Fatal if we can't find the task
1720  if (taskFound == false) {
1721  AliFatalClassF("Could not find correction task, checking for both the suffix \"%s\" and the main task. Did you remember to create it?", suffix.Data());
1722  }
1723 
1724  AliInfoClassStream() << "Found correction task named \"" << foundTaskName <<"\" to configure.\n";
1725 
1726  // AliAnalysisTaskCfg will require a task to be returned, so we add a dummy task to the analysis manager,
1727  // which will be removed when the user calls Initialize(true) on the correction task.
1728  std::string dummyTaskName = foundTaskName + "_dummyTask";
1729  mgr->AddTask(new AliAnalysisTaskSE(dummyTaskName.c_str()));
1730 
1731  return correctionTask;
1732 }
1733 
1739 std::string AliEmcalCorrectionTask::toString(bool includeYAMLConfigurationInfo) const
1740 {
1741  std::stringstream tempSS;
1742 
1743  // Show the correction components
1744  tempSS << "Correction components:\n";
1745  for (auto component : fOrderedComponentsToExecute) {
1746  tempSS << "\t" << component << "\n";
1747  }
1748  // Input objects
1749  tempSS << "\nInput objects:\n";
1753 
1754  if (includeYAMLConfigurationInfo == true) {
1755  tempSS << "\nUser Configuration:\n";
1756  PrintConfiguration(tempSS, true);
1757  tempSS << "\n\nDefault Configuration:\n";
1758  PrintConfiguration(tempSS);
1759  tempSS << "\n";
1760  }
1761 
1762  return tempSS.str();
1763 }
1764 
1771 std::ostream & AliEmcalCorrectionTask::Print(std::ostream & in) const {
1772  in << toString();
1773  return in;
1774 }
1775 
1783 std::ostream & operator<<(std::ostream & in, const AliEmcalCorrectionTask & myTask)
1784 {
1785  std::ostream & result = myTask.Print(in);
1786  return result;
1787 }
1788 
1796 {
1797  std::string temp(opt);
1798  bool includeYAMLConfig = false;
1799  if (temp == "YAML") {
1800  includeYAMLConfig = true;
1801  }
1802  Printf("%s", toString(includeYAMLConfig).c_str());
1803 }
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 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
void SetName(const char *n)
Set the name of the class of the objets inside the underlying array.
std::vector< std::string > fOrderedComponentsToExecute
Ordered set of components to execute.
bool WriteConfigurationFile(std::string filename, bool userConfig=false) const
void SetMinE(Double_t min)
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
void SetMinPt(Double_t min)
Double_t fMaxCent
max centrality for event selection
Double_t fVertex[3]
! Event vertex
Declaration of class AliAnalysisTaskEmcalEmbeddingHelper.
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)
void SetEtaLimits(Double_t min, Double_t max)
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)
virtual void NextEvent(const AliVEvent *event)
Preparation for the next event.
AliParticleContainer * GetParticleContainer(Int_t i=0) const
friend void swap(AliEmcalCorrectionTask &first, AliEmcalCorrectionTask &second)
Container for particles within the EMCAL framework.
void SetIsEmbedding(Bool_t b)
Set embedding status.
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.
Bool_t GetIsEmbedding() const
Get embedding status.
BeamType
Switch for the beam type.
void AdoptParticleContainer(AliParticleContainer *cont)
Base class for container structures within the EMCAL framework.
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
std::string GetBranchName() const
Get the name of the cells branch (NOT the same as the name!)
static const std::map< std::string, AliEmcalTrackSelection::ETrackFilterType_t > fgkTrackFilterTypeMap
Relates string to the track filter enumeration for YAML configuration.
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
const TString & GetArrayName() const
TObjArray fParticleCollArray
Particle/track collection array.
const char * GetName() const
TObjArray fClusterCollArray
Cluster collection array.
ETrackFilterType_t
Pre-defined track filters.
void AdoptParticleContainer(AliParticleContainer *cont)
bool RemoveConfiguration(const unsigned int i)
AliEmcalCorrectionComponent * GetCorrectionComponent(const std::string &name) const
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 SetPhiLimits(Double_t min, Double_t max)
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
void SetDefaultClusterEnergy(Int_t d)
std::vector< AliEmcalCorrectionCellContainer * > fCellCollArray
Cells collection array.
Container structure for EMCAL clusters.
static const std::map< std::string, VCluUserDefEnergy_t > fgkClusterEnergyTypeMap
Relates string to the cluster energy enumeration for YAML configuration.
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