AliPhysics  5364b50 (5364b50)
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 
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  fRecycleUnusedEmbeddedEventsMode(false),
66  fCent(0),
67  fCentBin(-1),
68  fMinCent(-999),
69  fMaxCent(-999),
70  fNcentBins(4),
71  fCentEst("V0M"),
72  fUseNewCentralityEstimation(kFALSE),
73  fVertex{0},
74  fNVertCont(0),
75  fBeamType(kNA),
77  fNeedEmcalGeom(kTRUE),
78  fGeom(0),
82  fOutput(0)
83 {
84  // Default constructor
85  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
86 
87  fParticleCollArray.SetOwner(kTRUE);
88  fClusterCollArray.SetOwner(kTRUE);
89 }
90 
101  AliAnalysisTaskSE(name),
102  fYAMLConfig(),
103  fSuffix(""),
109  fIsEsd(false),
110  fEventInitialized(false),
112  fCent(0),
113  fCentBin(-1),
114  fMinCent(-999),
115  fMaxCent(-999),
116  fNcentBins(4),
117  fCentEst("V0M"),
119  fVertex{0},
120  fNVertCont(0),
121  fBeamType(kNA),
123  fNeedEmcalGeom(kTRUE),
124  fGeom(0),
127  fCellCollArray(),
128  fOutput(0)
129 {
130  // Standard constructor
131  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
132 
133  fParticleCollArray.SetOwner(kTRUE);
134  fClusterCollArray.SetOwner(kTRUE);
135 
136  DefineInput(0, TChain::Class());
137  DefineOutput(1, TList::Class());
138 }
139 
148  fYAMLConfig(task.fYAMLConfig),
149  fSuffix(task.fSuffix),
153  fCorrectionComponents(task.fCorrectionComponents), // TODO: These should be copied!
155  fIsEsd(task.fIsEsd),
158  fCent(task.fCent),
159  fCentBin(task.fCentBin),
160  fMinCent(task.fMinCent),
161  fMaxCent(task.fMaxCent),
162  fNcentBins(task.fNcentBins),
163  fCentEst(task.fCentEst),
165  fVertex{0.},
166  fNVertCont(task.fNVertCont),
167  fBeamType(task.fBeamType),
168  fForceBeamType(task.fForceBeamType),
169  fNeedEmcalGeom(task.fNeedEmcalGeom),
170  fGeom(task.fGeom),
171  fParticleCollArray(*(static_cast<TObjArray *>(task.fParticleCollArray.Clone()))),
172  fClusterCollArray(*(static_cast<TObjArray *>(task.fClusterCollArray.Clone()))),
173  fOutput(task.fOutput) // TODO: More care is needed here!
174 {
175  // Vertex position
176  std::copy(std::begin(task.fVertex), std::end(task.fVertex), std::begin(fVertex));
177 
178  // Cell Collections
179  for (auto cellCont : task.fCellCollArray)
180  {
181  fCellCollArray.push_back(new AliEmcalCorrectionCellContainer(*cellCont));
182  }
183 }
184 
190 {
191  swap(*this, other);
192 }
193 
199 {
200  swap(*this, other);
201 
202  return *this;
203 }
204 
209 {
210  using std::swap;
211 
212  swap(first.fYAMLConfig, second.fYAMLConfig);
213  swap(first.fSuffix, second.fSuffix);
219  swap(first.fIsEsd, second.fIsEsd);
222  swap(first.fCent, second.fCent);
223  swap(first.fCentBin, second.fCentBin);
224  swap(first.fMinCent, second.fMinCent);
225  swap(first.fMaxCent, second.fMaxCent);
226  swap(first.fNcentBins, second.fNcentBins);
227  swap(first.fCentEst, second.fCentEst);
229  swap(first.fVertex, second.fVertex);
230  swap(first.fNVertCont, second.fNVertCont);
231  swap(first.fBeamType, second.fBeamType);
232  swap(first.fForceBeamType, second.fForceBeamType);
233  swap(first.fNeedEmcalGeom, second.fNeedEmcalGeom);
234  swap(first.fGeom, second.fGeom);
237  swap(first.fCellCollArray, second.fCellCollArray);
238  swap(first.fOutput, second.fOutput);
239 }
240 
246 {
247  // Destructor
248 }
249 
250 void AliEmcalCorrectionTask::Initialize(bool removeDummyTask)
251 {
252  // Determine file type
253  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
254  if (mgr) {
255  AliVEventHandler *evhand = mgr->GetInputEventHandler();
256  if (evhand) {
257  if (evhand->InheritsFrom("AliESDInputHandler")) {
258  fIsEsd = true;
259  }
260  else {
261  fIsEsd = false;
262  }
263  }
264  else {
265  AliError("Event handler not found!");
266  }
267  }
268  else {
269  AliError("Analysis manager not found!");
270  }
271 
272  // Determine the suffix of the correction task
273  std::string tempName = GetName();
274  std::size_t foundSuffix = tempName.find("_");
275  if (foundSuffix != std::string::npos) {
276  // +1 to skip "_"
277  fSuffix = tempName.substr(foundSuffix + 1).c_str();
278  }
279 
280  if (fSuffix != "") {
281  AliInfoStream() << "Initializing correction task with suffix \"" << fSuffix << "\"" << std::endl;
282  }
283 
284  // Initialize %YAML configuration
286  // Check that the configuration is initialized
287  if (fConfigurationInitialized != true)
288  {
289  AliFatal("YAML configuration must be initialized before running (ie. in the run macro or wagon)!");
290  }
291 
292  // Determine component execution order
294 
295  // Check for user defined settings that are not in the default file
297 
298  // Setup input objects
299  // Setup Cells
300  // Cannot do this entirely yet because we need input objects
303  // Create cluster input objects
306  // Create track input objects
309 
310  // Initialize components
312 
313  // Determine whether to determine event selection via the embedding helper
314  // so embedded events can be "recycled"
315  fYAMLConfig.GetProperty("recycleUnusedEmbeddedEventsMode", fRecycleUnusedEmbeddedEventsMode);
316 
317  if (removeDummyTask == true) {
318  RemoveDummyTask();
319  }
320 
321  // Print the results of the initialization
322  // Print outside of the ALICE Log system to ensure that it is always available!
323  std::cout << GetName() << " Settings:\n" << *this;
324 }
325 
331 {
332  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
333  if (!mgr)
334  {
335  AliErrorStream() << "No analysis manager to connect to.\n";
336  return;
337  }
338 
339  // Remove the dummy task
340  std::string dummyTaskName = GetName();
341  dummyTaskName += "_dummyTask";
342  TObjArray * tasks = mgr->GetTasks();
343  if (tasks) {
344  AliAnalysisTaskSE * dummyTask = dynamic_cast<AliAnalysisTaskSE *>(tasks->FindObject(dummyTaskName.c_str()));
345  if (!dummyTask) {
346  AliErrorStream() << "Could not remove dummy task \"" << dummyTaskName << "\" from analysis manager! Was it added?\n";
347  }
348  // Actually remove the task
349  tasks->Remove(dummyTask);
350  AliDebugStream(1) << "Removed dummy task named \"" << dummyTaskName << "\".\n";
351  }
352  else {
353  AliErrorStream() << "Could not retrieve tasks from the analysis manager.\n";
354  }
355 }
356 
366 {
367  // Determine file path
369  {
370  // Use the default if nothing is set
371  fDefaultConfigurationFilename = "$ALICE_PHYSICS/PWG/EMCAL/config/AliEmcalCorrectionConfiguration.yaml";
372  }
373 
374  // Setup and initialize configurations
375  // user is added first so that it will be checked first.
376  // User file
377  int returnValue = fYAMLConfig.AddConfiguration(fUserConfigurationFilename, "user");
378  if (returnValue >= 0) {
379  AliInfoStream() << "Using user EMCal corrections configuration located at \"" << fUserConfigurationFilename << "\"\n";
380  }
381  else {
382  AliInfoStream() << "User file at \"" << fUserConfigurationFilename << "\" does not exist! All settings will be from the default file!\n";
383  }
384 
385  // Default file
387  if (returnValue >= 0) {
388  AliInfoStream() << "Using default EMCal corrections configuration located at \"" << fDefaultConfigurationFilename << "\"\n";
389  }
390  else {
391  AliFatal(TString::Format("Default file located at \"%s\" does not exist!", fDefaultConfigurationFilename.c_str()));
392  }
393 
394  // Initialize
396 
397  // Note that it is initialized properly so that the analysis can proceed
399 }
400 
411 void AliEmcalCorrectionTask::DetermineComponentsToExecute(std::vector <std::string> & correctionComponents)
412 {
413  std::vector <std::string> executionOrder;
414  // executionOrder determines the order of tasks to execute, but it doesn't name the particular tasks
415  fYAMLConfig.GetProperty("executionOrder", executionOrder, true);
416 
417  // Possible components to create from both the user and default configurations
418  // Use set so that the possible components are not repeated
419  std::set <std::string> possibleComponents;
420  if (fYAMLConfig.DoesConfigurationExist("user")) {
421  for (const auto node : fYAMLConfig.GetConfiguration("user").second) {
422  possibleComponents.insert(node.first.as<std::string>());
423  }
424  }
425  for (const auto node : fYAMLConfig.GetConfiguration("default").second) {
426  possibleComponents.insert(node.first.as<std::string>());
427  }
428 
429  // Determine the correction names associated with the correction task
430  std::string expectedComponentName = "";
431  bool foundSuffixComponent = false;
432  bool foundComponent = false;
433  bool componentEnabled = true;
434 
435  // Execution order determines the order that corrections should be added to our execution list
436  for (auto & execName : executionOrder)
437  {
438  // Construct the expected component name with the suffix
439  expectedComponentName = TString::Format("%s_%s", execName.c_str(), fSuffix.c_str()).Data();
440  foundComponent = false;
441  componentEnabled = false;
442 
443  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
444  if (foundComponent)
445  {
446  // Check if the component is enabled
447  fYAMLConfig.GetProperty({expectedComponentName, "enabled"}, componentEnabled, true);
448  // If enabled, then store the name so that it can be executed
449  if (componentEnabled == true) {
450  foundSuffixComponent = true;
451  correctionComponents.push_back(expectedComponentName);
452  }
453  else {
454  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
455  }
456 
457  continue;
458  }
459  else
460  {
461  // Look for the normal component
462  expectedComponentName = execName;
463  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
464  // Check if it is enabled
465  fYAMLConfig.GetProperty({expectedComponentName, "enabled"}, componentEnabled, true);
466 
467  if (componentEnabled == true) {
468  if (foundSuffixComponent == true) {
469  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()));
470  }
471  else {
472  // Take the normal component and store it to be executed
473  correctionComponents.push_back(expectedComponentName);
474  }
475  }
476  else {
477  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
478  }
479  }
480  }
481 
482  // Need to append "AliEmcalCorrection" to allow the tasks to be found!
483  AliDebug(2, "Found EMCal Correction Components: ");
484  for (auto & component : correctionComponents)
485  {
486  component = "AliEmcalCorrection" + component;
487  AliDebug(2, TString::Format("%s", component.c_str()) );
488  }
489 }
490 
504 {
505  // Names of properties for a particular component in the user and default configurations
506  std::set <std::string> userPropertyNames;
507  std::set <std::string> defaultPropertyNames;
508  // Notes whether a match was found between user and default properties
509  bool foundMatch = false;
510  std::string tempComponentName = "";
511 
512  // Loop over all components
513  for (const auto componentName : fOrderedComponentsToExecute)
514  {
515  // Reset for each loop
516  userPropertyNames.clear();
517  defaultPropertyNames.clear();
518  // We need to remove "AliEmcalCorrection" so that the correction will be found in the configuration
519  std::string prefix = "AliEmcalCorrection";
520  tempComponentName = componentName.substr(componentName.find(prefix) + prefix.length());
521 
522  AliDebugStream(2) << "Checking component " << componentName << " for unmatched user settings" << std::endl;
523 
524  // Get the user property names
525  GetPropertyNamesFromNode("user", tempComponentName, userPropertyNames, false);
526 
527  // Get the same from default
528  // Not required here because the default configuration may not have the specialized component
529  GetPropertyNamesFromNode("default", tempComponentName, defaultPropertyNames, false);
530 
531  // We need to check the base correction as well to fill out the options
532  if (tempComponentName.find("_") != std::string::npos) {
533  // Get the base user component
534  GetPropertyNamesFromNode("user", tempComponentName.substr(0, tempComponentName.find("_")), userPropertyNames, false);
535 
536  // Required here because the default must have the base component!
537  GetPropertyNamesFromNode("default", tempComponentName.substr(0, tempComponentName.find("_")), defaultPropertyNames, true);
538  }
539 
540  // Check each property defined in the user file for a match to the properties in the default file
541  for (auto userPropertyName : userPropertyNames)
542  {
543  AliDebugStream(2) << "Checking property " << userPropertyName << std::endl;
544  foundMatch = false;
545  for (auto defaultPropertyName : defaultPropertyNames)
546  {
547  if (userPropertyName == defaultPropertyName) {
548  AliDebugStream(2) << "Found match of " << userPropertyName << " with " << defaultPropertyName << std::endl;
549  foundMatch = true;
550  }
551  }
552  if (foundMatch == false) {
553  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()));
554  }
555  }
556  }
557 }
558 
566 {
567  // Iterate over the ordered components list and create the components
568  AliEmcalCorrectionComponent * component = 0;
569  for (auto componentName : fOrderedComponentsToExecute)
570  {
571  std::string noPrefixComponentName = componentName.substr(0, componentName.find("_" + fSuffix));
572  component = AliEmcalCorrectionComponentFactory::createInstance(noPrefixComponentName);
573  if (!component)
574  {
575  AliFatal(TString::Format("Failed to create requested component %s!", componentName.c_str()));
576  }
577 
578  // For setting names of tasks to differentiate between tasks of the same class
579  component->SetName(componentName.c_str());
580  component->SetTitle(componentName.c_str());
581 
582  // Initialize the %YAML configurations in each component
583  component->SetYAMLConfiguration(fYAMLConfig);
584 
585  // configure needed fields for components to properly initialize
586  component->SetIsESD(fIsEsd);
587 
588  // Add the require containers to the component
589  // Cells must be set during UserExec() because we need to add them as a pointer
592 
593  // Initialize each component
594  bool initialized = component->Initialize();
595 
596  if (component && initialized)
597  {
598  AliInfo(TString::Format("Successfully added correction task: %s", componentName.c_str()));
599  fCorrectionComponents.push_back(component);
600  }
601  }
602 }
603 
619 {
620  // Get container node
621  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
622 
623  // Determine which containers we need based on which are requested by the enabled correction tasks
624  std::set <std::string> requestedContainers;
625  std::vector <std::string> componentRequest;
626  for ( const auto & componentName : fOrderedComponentsToExecute )
627  {
628  componentRequest.clear();
629  // Not required because not all components will have all kinds of containers
630  std::string selectionName = "AliEmcalCorrection";
631  // Expliecitly initialize as a vector to avoid ambiguity.
632  fYAMLConfig.GetProperty(std::vector<std::string>{componentName.substr(componentName.find(selectionName) + selectionName.length()), inputObjectName + "Names"}, componentRequest, false);
633  for ( auto & req : componentRequest )
634  {
635  AliDebugStream(3) << "Component " << componentName << " requested container name " << req << std::endl;
636  requestedContainers.insert(req);
637  }
638  }
639 
640  AliDebugStream(2) << inputObjectName << " Containers requested by components: " << std::endl;
641  for (auto & str : requestedContainers) {
642  AliDebugStream(2) << "\t" << str << std::endl;;
643  }
644 
645  // Create all requested containers
646  AliDebug(2, TString::Format("Setting up requested containers!"));
647  SetupContainersFromInputNodes(inputObjectType, requestedContainers);
648 }
649 
659 {
660  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
661  // Need to be of the form "clusterContainersNames"
662  inputObjectName = inputObjectName + "Names";
663 
664  std::vector <std::string> inputObjects;
665  // Property is not required, because not all components need Clusters or Tracks
666  // Expliecitly initialize as a vector to avoid ambiguity.
667  fYAMLConfig.GetProperty(std::vector<std::string>{component->GetName(), inputObjectName.c_str()}, inputObjects, false);
668 
669  //AliDebugStream(4) << "inputObjects.size(): " << inputObjects.size() << std::endl;
670 
671  // If it is not found, then there will be nothing to iterate over, so we don't need to explicitly check the return value
672  for (auto const & str : inputObjects)
673  {
674  // 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()!
675  if (inputObjectType == AliEmcalContainerUtils::kCluster)
676  {
677  AliEmcalContainer * cont = GetClusterContainer(str.c_str());
678  AliDebugStream(2) << "Adding cluster container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
679 
680  if (checkObjectExists && !cont) {
681  AliError(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
682  }
683  component->AdoptClusterContainer(GetClusterContainer(str.c_str()));
684 
685  // Check that we are using the standard input event
686  if (!(cont->GetIsEmbedding())) {
687  component->SetUsingInputEvent(true);
688  }
689  }
690  else if (inputObjectType == AliEmcalContainerUtils::kTrack)
691  {
692  AliEmcalContainer * cont = GetParticleContainer(str.c_str());
693  AliDebugStream(2) << "Adding particle container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
694 
695  if (checkObjectExists && !cont) {
696  AliFatal(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
697  }
698  component->AdoptParticleContainer(GetParticleContainer(str.c_str()));
699 
700  // Check that we are using the standard input event
701  if (!(cont->GetIsEmbedding())) {
702  component->SetUsingInputEvent(true);
703  }
704  }
705  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells)
706  {
707  // NOTE: This operates different than the others. This should be executed during run time rather than during initialization!
708  if (inputObjects.size() > 1) {
709  AliFatal(TString::Format("Component %s requested more than one cell branch, but this is not supported! Check the configuration!", component->GetName()));
710  }
711 
712  // If we've made it here, this must be at least one entry
714  AliDebugStream(2) << "Adding calo cells \"" << cellCont->GetName() << "\" of branch name \"" << cellCont->GetBranchName() << "\" to component " << component->GetName() << std::endl;
715 
716  if (!(cellCont->GetCells())) {
717  // Attempt to re-initialize the cells.
718  // NOTE: This may not succeed. Adding the container may need to be repeated after the
719  // object is created
721  }
722 
723  if (checkObjectExists && !(cellCont->GetCells())) {
724  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()));
725  }
726 
727  // Set the calo cells (may be null)
728  component->SetCaloCells(cellCont->GetCells());
729 
730  // It is possible that the cells pointer is null because it may not be created yet. For example,
731  // when combining cells. Thus, we must first check whether the pointer is available before checking
732  // for the number of cells. This could potentially decrease the amount of debug information, but this
733  // should rarely be an issue.
734  if (component->GetCaloCells()) {
735  AliDebugStream(3) << "Component GetNumberOfCells(): " << component->GetCaloCells()->GetNumberOfCells() << std::endl;
736  }
737 
738  // Check that we are using the standard input event
739  if (!(cellCont->GetIsEmbedding())) {
740  component->SetUsingInputEvent(true);
741  }
742  }
743  }
744 }
745 
752 void AliEmcalCorrectionTask::SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, std::set <std::string> & requestedContainers)
753 {
754  // Our node contains all of the objects that we will want to create.
755  for(auto & containerName : requestedContainers)
756  {
757  // The section is the container name
758  //std::string containerName = it->first.as<std::string>();
759  // Skip if the particle or cluster container already exists
760  if (GetParticleContainer(containerName.c_str()) || GetClusterContainer(containerName.c_str())) {
761  continue;
762  }
763 
764  AliDebug(2, TString::Format("Processing container %s of inputType %d", containerName.c_str(), inputObjectType));
765  if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
766  SetupContainer(inputObjectType, containerName);
767  }
768  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
769  SetupCellsInfo(containerName);
770  }
771  }
772 }
773 
782 void AliEmcalCorrectionTask::SetupCellsInfo(std::string containerName)
783 {
784  // Define cell info
786 
787  // Set properties
788  // Cells (object) name
789  cellObj->SetName(containerName);
790  // Branch name
791  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(AliEmcalContainerUtils::kCaloCells), containerName};
792  std::string tempString = "";
793  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "branchName", tempString, true);
794  if (tempString == "usedefault") {
796  }
797  cellObj->SetBranchName(tempString);
798 
799  // IsEmbedding
800  bool tempBool = false;
801  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "embedding", tempBool, false);
802  cellObj->SetIsEmbedding(tempBool);
803 
804  // Add to the array to keep track of it
805  fCellCollArray.push_back(cellObj);
806 }
807 
823 void AliEmcalCorrectionTask::SetupContainer(const AliEmcalContainerUtils::InputObject_t inputObjectType, const std::string containerName)
824 {
825  // Create container
826  AliDebugStream(2) << "Adding container" << std::endl;
827  AliEmcalContainer * cont = AddContainer(inputObjectType, containerName);
828  AliDebugStream(2) << "Added container" << std::endl;
829 
830  // Set the container properties
831  //
832  // TODO: Consider if this can be converted to a map to function pointers. There are a number of details
833  // which can make it a bit complicated. Those details include inheritance, pointing to member
834  // functions, etc. It should all be possible, but may not be worth all of the extra work and code.
835  // Example ccode:
836  // SetValueInContainer(inputObjectPropertiesPath, "minPt", &cont::SetMinPt, tempDouble, false);
837  // SetValueInContainer(inputObjectPropertiesPath, "minE", &cont::SetMinE, tempDouble, false);
838  // std::function may be easier?
839  // See: https://isocpp.org/wiki/faq/pointers-to-members
842  // type void (AliEmcalContainer::*EmcalContainerFn)(double val);
843  // // Potential map?
844  // std::map<std::string, EmcalContainerFn> EmcalContFunctionMap;
845  // EmcalContFunctionMap["minPt"] = &AliEmcalContainer::SetMinPt;
846  // EmcalContFunctionMap["minE"] = &AliEmcalContainer::SetMinE;
847  // // Define functions (use map?)
848  // EmcalContainerFn minPt = &AliEmcalContainer::SetMinPt;
849  // EmcalContainerFn minE = &AliEmcalContainer::SetMinE;
850  // // Example invocation
851  // (cont->*minPt)(tempDouble);
852 
853  // Path to the various properties
854  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(inputObjectType), containerName};
855 
856  // Temporary variables to store requested properties
857  std::string tempString = "";
858  Double_t tempDouble = 0;
859  bool tempBool = false;
860 
861  // AliEmcalContainer properties
862  // Min Pt
863  bool result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minPt", tempDouble, false);
864  if (result) {
865  AliDebugStream(2) << cont->GetName() << ": Setting minPt of " << tempDouble << std::endl;
866  cont->SetMinPt(tempDouble);
867  }
868  // Min E
869  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minE", tempDouble, false);
870  if (result) {
871  AliDebugStream(2) << cont->GetName() << ": Setting minE of " << tempDouble << std::endl;
872  cont->SetMinE(tempDouble);
873  }
874  // Eta min, max
875  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minEta", tempDouble, false);
876  if (result) {
877  // Only continue checking if the min is there, since we must set both together
878  Double_t tempDouble2 = 0;
879  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "maxEta", tempDouble, false);
880  if (result) {
881  AliDebugStream(2) << cont->GetName() << ": Setting eta limits of " << tempDouble << " to " << tempDouble2 << std::endl;
882  cont->SetEtaLimits(tempDouble, tempDouble2);
883  }
884  }
885  // Phi min, max
886  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minPhi", tempDouble, false);
887  if (result) {
888  // Only continue checking if the min is there, since we must set both together
889  Double_t tempDouble2 = 0;
890  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "maxPhi", tempDouble, false);
891  if (result) {
892  AliDebugStream(2) << cont->GetName() << ": Setting phi limits of " << tempDouble << " to " << tempDouble2 << std::endl;
893  cont->SetPhiLimits(tempDouble, tempDouble2);
894  }
895  }
896  // Embedded
897  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "embedding", tempBool, false);
898  if (result) {
899  AliDebugStream(2) << cont->GetName() << ": Setting embedding to " << (tempBool ? "enabled" : "disabled") << std::endl;
900  cont->SetIsEmbedding(tempBool);
901  }
902 
903  // Cluster specific properties
904  AliClusterContainer * clusterContainer = dynamic_cast<AliClusterContainer *>(cont);
905  if (clusterContainer) {
906  // Default energy
907  // Probably not needed for the corrections
908  /*result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "defaultClusterEnergy", tempString, false);
909  if (result) {
910  // Need to get the enumeration
911  AliVCluster::VCluUserDefEnergy_t clusterEnergyType = fgkClusterEnergyTypeMap.at(tempString);
912  AliDebugStream(2) << clusterContainer->GetName() << ": Setting cluster energy type to " << clusterEnergyType << std::endl;
913  clusterContainer->SetDefaultClusterEnergy(clusterEnergyType);
914  }*/
915 
916  // NonLinCorrEnergyCut
917  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "clusNonLinCorrEnergyCut", tempDouble, false);
918  if (result) {
919  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusNonLinCorrEnergyCut of " << tempDouble << std::endl;
920  clusterContainer->SetClusNonLinCorrEnergyCut(tempDouble);
921  }
922 
923  // HadCorrEnergyCut
924  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "clusHadCorrEnergyCut", tempDouble, false);
925  if (result) {
926  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusHadCorrEnergyCut of " << tempDouble << std::endl;
927  clusterContainer->SetClusHadCorrEnergyCut(tempDouble);
928  }
929 
930  // SetIncludePHOS
931  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "includePHOS", tempBool, false);
932  if (result) {
933  AliDebugStream(2) << clusterContainer->GetName() << ": Setting Include PHOS to " << (tempBool ? "enabled" : "disabled") << std::endl;
934  clusterContainer->SetIncludePHOS(tempBool);
935  }
936  }
937 
938  // Track specific
939  AliTrackContainer * trackContainer = dynamic_cast<AliTrackContainer *>(cont);
940  if (trackContainer) {
941  // Track selection
942  // AOD Filter bits as a sequence
943  std::vector <UInt_t> filterBitsVector;
944  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "aodFilterBits", filterBitsVector, false);
945  if (result){
946  UInt_t filterBits = 0;
947  for (int filterBit : filterBitsVector) {
948  filterBits += filterBit;
949  }
950  AliDebugStream(2) << trackContainer->GetName() << ": Setting filterBits of " << filterBits << std::endl;
951  trackContainer->SetAODFilterBits(filterBits);
952  }
953 
954  // SetTrackFilterType enum
955  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "trackFilterType", tempString, false);
956  if (result) {
957  // Need to get the enumeration
958  AliEmcalTrackSelection::ETrackFilterType_t trackFilterType = fgkTrackFilterTypeMap.at(tempString);
959  AliDebugStream(2) << trackContainer->GetName() << ": Setting trackFilterType of " << trackFilterType << std::endl;
960  trackContainer->SetTrackFilterType(trackFilterType);
961  }
962 
963  // Track cuts period
964  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "trackCutsPeriod", tempString, false);
965  if (result) {
966  // Need to get the enumeration
967  AliDebugStream(2) << trackContainer->GetName() << ": Setting track cuts period to " << tempString << std::endl;
968  trackContainer->SetTrackCutsPeriod(tempString.c_str());
969  }
970  }
971 }
972 
988 AliEmcalContainer * AliEmcalCorrectionTask::AddContainer(const AliEmcalContainerUtils::InputObject_t contType, const std::string containerName)
989 {
990  // Determine the type of branch to request
991  std::string containerBranch = "";
993  AliFatal("Must specify type of container when requesting branch.");
994  }
995 
996  // Path to the various properties
997  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(contType), containerName};
998 
999  // Retrieve branch name
1000  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "branchName", containerBranch, true);
1001  // Should be unnecessary, since the user can only do this if done explicitly.
1002  /*if (containerBranch == "")
1003  {
1004  AliFatal(TString::Format("Request %i container, but the container branch is empty!", contType));
1005  }*/
1006 
1007  // Determine proper name if using "usedefault" pattern
1008  if (containerBranch == "usedefault") {
1009  containerBranch = AliEmcalContainerUtils::DetermineUseDefaultName(contType, fIsEsd);
1010  }
1011 
1012  // Create containers and set them to the name of the component
1013  AliEmcalContainer * cont = 0;
1014  if (contType == AliEmcalContainerUtils::kCluster)
1015  {
1016  cont = new AliClusterContainer(containerBranch.c_str());
1017  AdoptClusterContainer(dynamic_cast<AliClusterContainer *>(cont));
1018  }
1019  else if (contType == AliEmcalContainerUtils::kTrack)
1020  {
1021  if (containerBranch == "mcparticles") {
1022  cont = new AliMCParticleContainer(containerBranch.c_str());
1023  }
1024  else {
1025  cont = new AliTrackContainer(containerBranch.c_str());
1026  }
1027  AdoptParticleContainer(dynamic_cast<AliParticleContainer *>(cont));
1028  }
1029  cont->SetName(containerName.c_str());
1030 
1031  return cont;
1032 }
1033 
1043 {
1044  // Check that the configuration is initialized
1045  if (fConfigurationInitialized != true)
1046  {
1047  AliFatal("YAML configuration must be initialized before running (ie. the AddTask, run macro or wagon)!");
1048  }
1049 
1050  // %YAML Objects cannot be streamed, so we need to reinitialize them here.
1052 
1053  if (fForceBeamType == kpp)
1054  fNcentBins = 1;
1055 
1056  // Allow for output files
1057  OpenFile(1);
1058  fOutput = new TList();
1059  fOutput->SetOwner();
1060 
1062 
1063  PostData(1, fOutput);
1064 }
1065 
1073 {
1074  // Run the initialization for all derived classes.
1075  for (auto component : fCorrectionComponents)
1076  {
1077  // Set cent bins (usually used for hist creation)
1078  // It cannot be set until now because it can be changed after initialization
1079  // For instance, by SetForceBeamType()
1080  component->SetNcentralityBins(fNcentBins);
1081 
1082  component->UserCreateOutputObjects();
1083 
1084  if (component->GetOutputList() != 0)
1085  {
1086  // Adds a list to the list -- this doesn't work for some unknown reason
1087  //fOutput->Add(component->GetOutputList());
1088 
1089  // iterate through lists for each component, and fill in output
1090  TList* t = new TList();
1091  t->SetName(component->GetName());
1092  fOutput->AddLast(t);
1093  t = (TList*)fOutput->Last();
1094  TIter next(component->GetOutputList());
1095  while (TObject *obj = next()){
1096  t->Add(obj);
1097  }
1098 
1099  AliDebug(1, TString::Format("Added output list from task %s to output.", component->GetName()));
1100  }
1101  }
1102 }
1103 
1109 {
1110  // Recycle embedded events which do not pass the internal event selection in the embedding helper
1112  auto embeddingHelper = AliAnalysisTaskEmcalEmbeddingHelper::GetInstance();
1113  if (embeddingHelper && embeddingHelper->EmbeddedEventUsed() == false) {
1114  AliDebugStream(4) << "Embedding helper rejected the internal event. Skipping this event.\n";
1115  return;
1116  }
1117  }
1118 
1119  // Initialize the event if not initialized
1120  if (!fEventInitialized)
1121  ExecOnce();
1122 
1123  // Only continue if we are initialized successfully
1124  if (!fEventInitialized)
1125  return;
1126 
1127  // Get the objects for each event
1128  if (!RetrieveEventObjects())
1129  return;
1130 
1131  // Call run for each correction
1132  if (!Run())
1133  return;
1134 }
1135 
1147 {
1148  if (!InputEvent()) {
1149  AliError("Could not retrieve event! Returning!");
1150  return;
1151  }
1152 
1153  // This warning was extracted out from the cell components
1154  if (dynamic_cast<AliAODEvent*>(InputEvent())) {
1155  AliWarning("=============================================================");
1156  AliWarning("=== Running on AOD is not equivalent to running on ESD! ===");
1157  AliWarning("=============================================================");
1158  }
1159 
1160  if (fNeedEmcalGeom) {
1161  fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(InputEvent()->GetRunNumber());
1162  if (!fGeom) {
1163  AliFatal("Can not get EMCal geometry instance. If you do not need the EMCal geometry, disable it by setting task->SetNeedEmcalGeometry(kFALSE).");
1164  return;
1165  }
1166  }
1167 
1168  // Load all requested track branches - each container knows name already
1169  for (Int_t i =0; i<fParticleCollArray.GetEntriesFast(); i++) {
1170  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
1172  cont->SetArray(InputEvent());
1173  }
1174 
1175  // Load all requested cluster branches - each container knows name already
1176  for (Int_t i =0; i<fClusterCollArray.GetEntriesFast(); i++) {
1177  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
1179  cont->SetArray(InputEvent());
1180  }
1181 
1182  // Determine the proper pointer for each cell object and save them to the cell container
1183  // At this point, they should all be created
1184  for (auto cellObj : fCellCollArray)
1185  {
1187  }
1188 
1189  fEventInitialized = kTRUE;
1190 
1191  // Print warning to the user that the rest of the configuration information is available in the generation log
1192  // when the Analysis Manager was created. Using cout to be certain that it is shown on the train!
1193  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";
1194 
1195  // Setup the components
1197 }
1198 
1204 {
1205  // Run the initialization for all derived classes.
1206  for (auto component : fCorrectionComponents)
1207  {
1208  // Setup geometry
1209  component->SetEMCALGeometry(fGeom);
1210 
1211  // Add the requested cells to the component
1213 
1214  // Set the input events. This is redundant to where it is set during Run(), but the events need to be
1215  // available to components, and they are only called one extra time.
1216  component->SetInputEvent(InputEvent());
1217  component->SetMCEvent(MCEvent());
1218 
1219  // Component ExecOnce()
1220  component->ExecOnce();
1221 
1222  // If the cells were created during ExecOnce(), then we need to re-initialize the pointer to ensure
1223  // that it is not null!
1224  if (!(component->GetCaloCells())) {
1225  AliDebugStream(2) << "Re-initializing cells for component " << component->GetName() << std::endl;
1227  }
1228  }
1229 }
1230 
1236 {
1237  fVertex[0] = 0;
1238  fVertex[1] = 0;
1239  fVertex[2] = 0;
1240  fNVertCont = 0;
1241 
1242  const AliVVertex *vert = InputEvent()->GetPrimaryVertex();
1243  if (vert) {
1244  vert->GetXYZ(fVertex);
1245  fNVertCont = vert->GetNContributors();
1246  }
1247 
1248  fBeamType = GetBeamType();
1249 
1250  if (fBeamType == kAA || fBeamType == kpA ) {
1252  AliMultSelection *MultSelection = static_cast<AliMultSelection*>(InputEvent()->FindListObject("MultSelection"));
1253  if (MultSelection) {
1254  fCent = MultSelection->GetMultiplicityPercentile(fCentEst.Data());
1255  }
1256  else {
1257  AliWarning("Could not retrieve centrality information! Assuming 99");
1258  }
1259  }
1260  else { // old centrality estimation < 2015
1261  AliCentrality *aliCent = InputEvent()->GetCentrality();
1262  if (aliCent) {
1263  fCent = aliCent->GetCentralityPercentile(fCentEst.Data());
1264  }
1265  else {
1266  AliWarning("Could not retrieve centrality information! Assuming 99");
1267  }
1268  }
1269 
1270  if (fNcentBins==4) {
1271  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1272  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1273  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1274  else if (fCent >= 50 && fCent <= 100) fCentBin = 3;
1275  else {
1276  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1277  fCentBin = fNcentBins-1;
1278  }
1279  }
1280  else if (fNcentBins==5) { // for PbPb 2015
1281  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1282  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1283  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1284  else if (fCent >= 50 && fCent <= 90) fCentBin = 3;
1285  else if (fCent > 90) {
1286  fCent = 99;
1287  fCentBin = 4;
1288  }
1289  else {
1290  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1291  fCentBin = fNcentBins-1;
1292  }
1293  }
1294  else {
1295  Double_t centWidth = (fMaxCent-fMinCent)/(Double_t)fNcentBins;
1296  if(centWidth>0.) {
1297  fCentBin = TMath::FloorNint(fCent/centWidth);
1298  }
1299  else {
1300  fCentBin = 0;
1301  }
1302  if (fCentBin>=fNcentBins) {
1303  AliWarning(Form("fCentBin too large: cent = %f fCentBin = %d. Assuming 99", fCent, fCentBin));
1304  fCentBin = fNcentBins-1;
1305  }
1306  }
1307  }
1308  else {
1309  fCent = 99;
1310  fCentBin = 0;
1311  }
1312 
1313  AliEmcalContainer* cont = 0;
1314 
1315  TIter nextPartColl(&fParticleCollArray);
1316  while ((cont = static_cast<AliEmcalContainer*>(nextPartColl()))) cont->NextEvent(InputEvent());
1317 
1318  TIter nextClusColl(&fClusterCollArray);
1319  while ((cont = static_cast<AliEmcalContainer*>(nextClusColl()))) cont->NextEvent(InputEvent());
1320 
1321  return kTRUE;
1322 }
1323 
1329 {
1330  // Run the initialization for all derived classes.
1331  for (auto component : fCorrectionComponents)
1332  {
1333  component->SetInputEvent(InputEvent());
1334  component->SetMCEvent(MCEvent());
1335  component->SetCentralityBin(fCentBin);
1336  component->SetCentrality(fCent);
1337  component->SetVertex(fVertex);
1338 
1339  component->Run();
1340  }
1341 
1342  PostData(1, fOutput);
1343 
1344  return kTRUE;
1345 }
1346 
1351 {
1352  // Run the initialization for all derived classes.
1353  for (auto component : fCorrectionComponents)
1354  {
1355  component->UserNotify();
1356  }
1357 
1358  return kTRUE;
1359 }
1360 
1367 std::ostream & AliEmcalCorrectionTask::PrintConfiguration(std::ostream & in, bool userConfig) const
1368 {
1369  std::string configurationName = userConfig ? "user" : "default";
1370  if (fYAMLConfig.DoesConfigurationExist(configurationName)) {
1371  auto configPair = fYAMLConfig.GetConfiguration(configurationName);
1372  if (configPair.second.IsNull() == true) {
1373  AliWarning(TString::Format("%s configuration is empty!", configPair.first.c_str()));
1374  }
1375  in << configPair.second;
1376  }
1377  else {
1378  in << "Configuration \"" << configurationName << "\" does not exist!\n";
1379  }
1380 
1381  return in;
1382 }
1383 
1391 bool AliEmcalCorrectionTask::WriteConfigurationFile(std::string filename, bool userConfig) const
1392 {
1393  return fYAMLConfig.WriteConfiguration(filename, userConfig ? "user" : "default");
1394 }
1395 
1405 {
1406  // Setup
1407  // It's important to reinitialize the configuration so the %YAML nodes are defined!
1409  std::string tempConfigName = "tempConfig";
1410  fYAMLConfig.AddConfiguration(filename, tempConfigName);
1411 
1412  // Compare
1413  bool returnValue = fYAMLConfig.CompareConfigurations(tempConfigName, userConfig ? "user" : "default");
1414 
1415  // Cleanup
1416  fYAMLConfig.RemoveConfiguration(tempConfigName);
1417 
1418  return returnValue;
1419 }
1420 
1428 {
1429  AliDebugStream(2) << "Retrieving cells object " << cellContainer->GetName() << std::endl;
1430  // Check for embedding and return object
1431  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cellContainer->GetIsEmbedding());
1432 
1433  cellContainer->SetCells(dynamic_cast<AliVCaloCells *>(event->FindListObject(cellContainer->GetBranchName().c_str())));
1434 }
1435 
1446 {
1447  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cont->GetIsEmbedding());
1448 
1449  TClonesArray * array = dynamic_cast<TClonesArray *>(event->FindListObject(cont->GetArrayName()));
1450  if (!array) {
1451  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()));
1452  array = new TClonesArray(AliEmcalContainerUtils::DetermineUseDefaultName(objectType, fIsEsd, true).c_str());
1453  array->SetName(cont->GetArrayName());
1454  event->AddObject(array);
1455  }
1456 }
1457 
1466 {
1467  // Get container node
1468  std::string inputObjectName = "";
1469  if (inputObjectType == AliEmcalContainerUtils::kCluster) {
1470  inputObjectName = "clusterContainers";
1471  }
1472  else if (inputObjectType == AliEmcalContainerUtils::kTrack) {
1473  inputObjectName = "trackContainers";
1474  }
1475  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1476  inputObjectName = "cells";
1477  }
1478  else {
1479  AliFatal(TString::Format("Unrecognized input object type %d", inputObjectType));
1480  }
1481 
1482  return inputObjectName;
1483 }
1484 
1496 bool AliEmcalCorrectionTask::CheckPossibleNamesForComponentName(std::string & name, std::set <std::string> & possibleComponents)
1497 {
1498  bool foundComponent = false;
1499  for (auto & possibleComponent : possibleComponents)
1500  {
1501  if (possibleComponent == name) {
1502  foundComponent = true;
1503  break;
1504  }
1505  }
1506 
1507  return foundComponent;
1508 }
1509 
1517 {
1518  if (fForceBeamType != kNA)
1519  return fForceBeamType;
1520 
1521  AliESDEvent *esd = dynamic_cast<AliESDEvent*>(InputEvent());
1522  if (esd) {
1523  const AliESDRun *run = esd->GetESDRun();
1524  TString beamType = run->GetBeamType();
1525  if (beamType == "p-p")
1526  return kpp;
1527  else if (beamType == "A-A")
1528  return kAA;
1529  else if (beamType == "p-A")
1530  return kpA;
1531  else
1532  return kNA;
1533  } else {
1534  Int_t runNumber = InputEvent()->GetRunNumber();
1535  // All run number ranges taken from the RCT
1536  if ((runNumber >= 136833 && runNumber <= 139517) || // LHC10h
1537  (runNumber >= 167693 && runNumber <= 170593) || // LHC11h
1538  (runNumber >= 244824 && runNumber <= 246994)) { // LHC15o
1539  return kAA;
1540  } else if ((runNumber >= 188356 && runNumber <= 188366) || // LHC12g
1541  (runNumber >= 195164 && runNumber <= 197388) || // LHC13b-f
1542  (runNumber >= 265015 && runNumber <= 267166)) { // LHC16q-t
1543  return kpA;
1544  } else {
1545  return kpp;
1546  }
1547  }
1548 }
1549 
1554 {
1555  if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1556  stream << "Cells info: " << std::endl;
1557  for (auto cellInfo : fCellCollArray) {
1558  stream << "\tName: " << cellInfo->GetName() << "\tBranch: " << cellInfo->GetBranchName() << "\tIsEmbedding: " << std::boolalpha << cellInfo->GetIsEmbedding() << std::endl;
1559  }
1560  }
1561  else if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
1562  stream << (inputObjectType == AliEmcalContainerUtils::kCluster ? "Cluster" : "Track") << " container info: " << std::endl;
1563  AliEmcalContainer * cont = 0;
1564  for (auto containerInfo : (inputObjectType == AliEmcalContainerUtils::kCluster ? fClusterCollArray : fParticleCollArray) ) {
1565  cont = static_cast<AliEmcalContainer *>(containerInfo);
1566  stream << "\tName: " << cont->GetName() << "\tBranch: " << cont->GetArrayName() << "\tTitle: " << cont->GetTitle() << "\tIsEmbedding: " << std::boolalpha << cont->GetIsEmbedding() << std::endl;
1567  }
1568  }
1569  else {
1570  AliErrorStream() << "Unrecognized input object type " << inputObjectType << std::endl;
1571  }
1572 }
1573 
1587 void AliEmcalCorrectionTask::GetPropertyNamesFromNode(const std::string configurationName, const std::string componentName, std::set <std::string> & propertyNames, const bool nodeRequired)
1588 {
1589  bool retrievedPropertyNames = false;
1590  if (fYAMLConfig.DoesConfigurationExist(configurationName)) {
1591  AliDebugStream(3) << "Looking for nodes in component \"" << componentName << "\" in the \"" << configurationName << "\" configuration\n";
1592  auto configPair = fYAMLConfig.GetConfiguration(configurationName);
1593  if (configPair.second[componentName])
1594  {
1595  for (auto propertyName : configPair.second[componentName])
1596  {
1597  AliDebugStream(4) << "Node property name " << propertyName.first.as<std::string>() << "\n";
1598  propertyNames.insert(propertyName.first.as<std::string>());
1599  }
1600  retrievedPropertyNames = true;
1601  }
1602  }
1603 
1604  if (retrievedPropertyNames == false && nodeRequired) {
1605  std::stringstream message;
1606  message << "Failed to retrieve required property \""
1607  << componentName << "\" from the \"" << configurationName << "\" configuration!" << std::endl;
1608  AliFatal(message.str().c_str());
1609  }
1610 }
1611 
1621 {
1622  AliEmcalCorrectionComponent * returnComponent = nullptr;
1623  for (auto component : fCorrectionComponents)
1624  {
1625  if (name == component->GetName()) {
1626  returnComponent = component;
1627  break;
1628  }
1629  }
1630  return returnComponent;
1631 }
1632 
1640 AliEmcalCorrectionCellContainer * AliEmcalCorrectionTask::GetCellContainer(const std::string & cellsContainerName) const
1641 {
1642  for (auto cellContainer : fCellCollArray)
1643  {
1644  if (cellContainer->GetName() == cellsContainerName) {
1645  return cellContainer;
1646  }
1647  }
1648 
1649  return 0;
1650 }
1651 
1653 {
1654  // Get the pointer to the existing analysis manager via the static access method.
1655  //==============================================================================
1656  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1657  if (!mgr)
1658  {
1659  ::Error("AddTaskEmcalCorrectionTask", "No analysis manager to connect to.");
1660  return nullptr;
1661  }
1662 
1663  // Check the analysis type using the event handlers connected to the analysis manager.
1664  //==============================================================================
1665  AliVEventHandler* handler = mgr->GetInputEventHandler();
1666  if (!handler)
1667  {
1668  ::Error("AddTaskEmcalCorrectionTask", "This task requires an input event handler");
1669  return nullptr;
1670  }
1671 
1672  TString name = "AliEmcalCorrectionTask";
1673  if (suffix != "") {
1674  name += TString::Format("_%s", suffix.Data());
1675  }
1676 
1677  AliEmcalCorrectionTask* mgrTask = static_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.Data()));
1678  if (mgrTask) return mgrTask;
1679 
1680  // Create the task that manages the corrections
1681  AliEmcalCorrectionTask* correctionTask = new AliEmcalCorrectionTask(name.Data());
1682 
1683  //-------------------------------------------------------
1684  // Final settings, pass to manager and set the containers
1685  //-------------------------------------------------------
1686 
1687  mgr->AddTask(correctionTask);
1688 
1689  // Create containers for input/output
1690  AliAnalysisDataContainer* cInput = mgr->GetCommonInputContainer();
1691 
1692  TString outputContainerName(name);
1693  outputContainerName += "_histos";
1694 
1695  AliAnalysisDataContainer * cOutput = mgr->CreateContainer(outputContainerName.Data(),
1696  TList::Class(),
1697  AliAnalysisManager::kOutputContainer,
1698  Form("%s", AliAnalysisManager::GetCommonFileName()));
1699 
1700  mgr->ConnectInput(correctionTask, 0, cInput);
1701  mgr->ConnectOutput(correctionTask, 1, cOutput);
1702 
1703  //TObjArray* cnt = mgr->GetContainers();
1704 
1705  return correctionTask;
1706 }
1707 
1709 {
1710  // Get the pointer to the existing analysis manager via the static access method.
1711  //==============================================================================
1712  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1713  if (!mgr)
1714  {
1715  ::Error("ConfigureEmcalCorrectionTaskOnLEGOTrain", "No analysis manager to connect to.");
1716  return nullptr;
1717  }
1718 
1719  // Find the correction task
1720  AliEmcalCorrectionTask * correctionTask = nullptr;
1721  const std::string taskName = "AliEmcalCorrectionTask";
1722  std::string foundTaskName = "";
1723  bool taskFound = false;
1724  std::vector<std::string> namesToSearch = {taskName};
1725 
1726  // Determine if the suffix name should be searched for.
1727  // If a suffix is given, it will be looked for first, followed by the generically named task.
1728  // This way, a user's configuration can be uniquely identified in the case of multiple correction tasks, but
1729  // if there is only one correction task without a suffix, this method will still fall back to that one and
1730  // return a correction task to be configured.
1731  if (suffix != "")
1732  {
1733  std::string suffixName = taskName;
1734  suffixName += "_";
1735  suffixName += suffix.Data();
1736  namesToSearch.insert(namesToSearch.begin(), suffixName);
1737  }
1738 
1739  // Attempt to retrieve the task from the analysis manager
1740  for (auto name : namesToSearch)
1741  {
1742  correctionTask = dynamic_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.c_str()));
1743  if (correctionTask != nullptr) {
1744  taskFound = true;
1745  foundTaskName = name;
1746  break;
1747  }
1748  }
1749 
1750  // Fatal if we can't find the task
1751  if (taskFound == false) {
1752  AliFatalClassF("Could not find correction task, checking for both the suffix \"%s\" and the main task. Did you remember to create it?", suffix.Data());
1753  }
1754 
1755  AliInfoClassStream() << "Found correction task named \"" << foundTaskName <<"\" to configure.\n";
1756 
1757  // AliAnalysisTaskCfg will require a task to be returned, so we add a dummy task to the analysis manager,
1758  // which will be removed when the user calls Initialize(true) on the correction task.
1759  std::string dummyTaskName = foundTaskName + "_dummyTask";
1760  mgr->AddTask(new AliAnalysisTaskSE(dummyTaskName.c_str()));
1761 
1762  return correctionTask;
1763 }
1764 
1770 std::string AliEmcalCorrectionTask::toString(bool includeYAMLConfigurationInfo) const
1771 {
1772  std::stringstream tempSS;
1773 
1774  // Show the correction components
1775  tempSS << "Correction components:\n";
1776  for (auto component : fOrderedComponentsToExecute) {
1777  tempSS << "\t" << component << "\n";
1778  }
1779  // Input objects
1780  tempSS << "\nInput objects:\n";
1784 
1785  if (includeYAMLConfigurationInfo == true) {
1786  tempSS << "\nUser Configuration:\n";
1787  PrintConfiguration(tempSS, true);
1788  tempSS << "\n\nDefault Configuration:\n";
1789  PrintConfiguration(tempSS);
1790  tempSS << "\n";
1791  }
1792 
1793  return tempSS.str();
1794 }
1795 
1802 std::ostream & AliEmcalCorrectionTask::Print(std::ostream & in) const {
1803  in << toString();
1804  return in;
1805 }
1806 
1814 std::ostream & operator<<(std::ostream & in, const AliEmcalCorrectionTask & myTask)
1815 {
1816  std::ostream & result = myTask.Print(in);
1817  return result;
1818 }
1819 
1827 {
1828  std::string temp(opt);
1829  bool includeYAMLConfig = false;
1830  if (temp == "YAML") {
1831  includeYAMLConfig = true;
1832  }
1833  Printf("%s", toString(includeYAMLConfig).c_str());
1834 }
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
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)
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.
bool fRecycleUnusedEmbeddedEventsMode
Allows the recycling of embedded events which fail internal event selection. See the embedding helper...
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 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)
static const AliAnalysisTaskEmcalEmbeddingHelper * GetInstance()
BeamType fForceBeamType
forced beam type