AliPhysics  2c6b7ad (2c6b7ad)
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  fRecycleUnusedEmbeddedEventsMode(false),
52  fCent(0),
53  fCentBin(-1),
54  fMinCent(-999),
55  fMaxCent(-999),
56  fNcentBins(4),
57  fCentEst("V0M"),
58  fUseNewCentralityEstimation(kFALSE),
59  fVertex{0},
60  fNVertCont(0),
61  fBeamType(kNA),
63  fNeedEmcalGeom(kTRUE),
64  fGeom(0),
68  fOutput(0)
69 {
70  // Default constructor
71  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
72 
73  fParticleCollArray.SetOwner(kTRUE);
74  fClusterCollArray.SetOwner(kTRUE);
75 }
76 
87  AliAnalysisTaskSE(name),
88  fYAMLConfig(),
89  fSuffix(""),
95  fIsEsd(false),
96  fEventInitialized(false),
98  fCent(0),
99  fCentBin(-1),
100  fMinCent(-999),
101  fMaxCent(-999),
102  fNcentBins(4),
103  fCentEst("V0M"),
105  fVertex{0},
106  fNVertCont(0),
107  fBeamType(kNA),
109  fNeedEmcalGeom(kTRUE),
110  fGeom(0),
113  fCellCollArray(),
114  fOutput(0)
115 {
116  // Standard constructor
117  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
118 
119  fParticleCollArray.SetOwner(kTRUE);
120  fClusterCollArray.SetOwner(kTRUE);
121 
122  DefineInput(0, TChain::Class());
123  DefineOutput(1, TList::Class());
124 }
125 
134  fYAMLConfig(task.fYAMLConfig),
135  fSuffix(task.fSuffix),
139  fCorrectionComponents(task.fCorrectionComponents), // TODO: These should be copied!
141  fIsEsd(task.fIsEsd),
144  fCent(task.fCent),
145  fCentBin(task.fCentBin),
146  fMinCent(task.fMinCent),
147  fMaxCent(task.fMaxCent),
148  fNcentBins(task.fNcentBins),
149  fCentEst(task.fCentEst),
151  fVertex{0.},
152  fNVertCont(task.fNVertCont),
153  fBeamType(task.fBeamType),
154  fForceBeamType(task.fForceBeamType),
155  fNeedEmcalGeom(task.fNeedEmcalGeom),
156  fGeom(task.fGeom),
157  fParticleCollArray(*(static_cast<TObjArray *>(task.fParticleCollArray.Clone()))),
158  fClusterCollArray(*(static_cast<TObjArray *>(task.fClusterCollArray.Clone()))),
159  fOutput(task.fOutput) // TODO: More care is needed here!
160 {
161  // Vertex position
162  std::copy(std::begin(task.fVertex), std::end(task.fVertex), std::begin(fVertex));
163 
164  // Cell Collections
165  for (auto cellCont : task.fCellCollArray)
166  {
167  fCellCollArray.push_back(new AliEmcalCorrectionCellContainer(*cellCont));
168  }
169 }
170 
176 {
177  swap(*this, other);
178 }
179 
185 {
186  swap(*this, other);
187 
188  return *this;
189 }
190 
195 {
196  using std::swap;
197 
198  swap(first.fYAMLConfig, second.fYAMLConfig);
199  swap(first.fSuffix, second.fSuffix);
205  swap(first.fIsEsd, second.fIsEsd);
208  swap(first.fCent, second.fCent);
209  swap(first.fCentBin, second.fCentBin);
210  swap(first.fMinCent, second.fMinCent);
211  swap(first.fMaxCent, second.fMaxCent);
212  swap(first.fNcentBins, second.fNcentBins);
213  swap(first.fCentEst, second.fCentEst);
215  swap(first.fVertex, second.fVertex);
216  swap(first.fNVertCont, second.fNVertCont);
217  swap(first.fBeamType, second.fBeamType);
218  swap(first.fForceBeamType, second.fForceBeamType);
219  swap(first.fNeedEmcalGeom, second.fNeedEmcalGeom);
220  swap(first.fGeom, second.fGeom);
223  swap(first.fCellCollArray, second.fCellCollArray);
224  swap(first.fOutput, second.fOutput);
225 }
226 
232 {
233  // Destructor
234 }
235 
236 void AliEmcalCorrectionTask::Initialize(bool removeDummyTask)
237 {
238  // Determine file type
239  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
240  if (mgr) {
241  AliVEventHandler *evhand = mgr->GetInputEventHandler();
242  if (evhand) {
243  if (evhand->InheritsFrom("AliESDInputHandler")) {
244  fIsEsd = true;
245  }
246  else {
247  fIsEsd = false;
248  }
249  }
250  else {
251  AliError("Event handler not found!");
252  }
253  }
254  else {
255  AliError("Analysis manager not found!");
256  }
257 
258  // Determine the suffix of the correction task
259  std::string tempName = GetName();
260  std::size_t foundSuffix = tempName.find("_");
261  if (foundSuffix != std::string::npos) {
262  // +1 to skip "_"
263  fSuffix = tempName.substr(foundSuffix + 1).c_str();
264  }
265 
266  if (fSuffix != "") {
267  AliInfoStream() << "Initializing correction task with suffix \"" << fSuffix << "\"" << std::endl;
268  }
269 
270  // Initialize %YAML configuration
272  // Check that the configuration is initialized
273  if (fConfigurationInitialized != true)
274  {
275  AliFatal("YAML configuration must be initialized before running (ie. in the run macro or wagon)!");
276  }
277 
278  // Determine component execution order
280 
281  // Check for user defined settings that are not in the default file
283 
284  // Setup input objects
285  // Setup Cells
286  // Cannot do this entirely yet because we need input objects
289  // Create cluster input objects
292  // Create track input objects
295 
296  // Initialize components
298 
299  // Determine whether to determine event selection via the embedding helper
300  // so embedded events can be "recycled"
301  fYAMLConfig.GetProperty("recycleUnusedEmbeddedEventsMode", fRecycleUnusedEmbeddedEventsMode);
302 
303  if (removeDummyTask == true) {
304  RemoveDummyTask();
305  }
306 
307  // Print the results of the initialization
308  // Print outside of the ALICE Log system to ensure that it is always available!
309  std::cout << GetName() << " Settings:\n" << *this;
310 }
311 
317 {
318  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
319  if (!mgr)
320  {
321  AliErrorStream() << "No analysis manager to connect to.\n";
322  return;
323  }
324 
325  // Remove the dummy task
326  std::string dummyTaskName = GetName();
327  dummyTaskName += "_dummyTask";
328  TObjArray * tasks = mgr->GetTasks();
329  if (tasks) {
330  AliAnalysisTaskSE * dummyTask = dynamic_cast<AliAnalysisTaskSE *>(tasks->FindObject(dummyTaskName.c_str()));
331  if (!dummyTask) {
332  AliErrorStream() << "Could not remove dummy task \"" << dummyTaskName << "\" from analysis manager! Was it added?\n";
333  }
334  // Actually remove the task
335  tasks->Remove(dummyTask);
336  AliDebugStream(1) << "Removed dummy task named \"" << dummyTaskName << "\".\n";
337  }
338  else {
339  AliErrorStream() << "Could not retrieve tasks from the analysis manager.\n";
340  }
341 }
342 
352 {
353  // Determine file path
355  {
356  // Use the default if nothing is set
357  fDefaultConfigurationFilename = "$ALICE_PHYSICS/PWG/EMCAL/config/AliEmcalCorrectionConfiguration.yaml";
358  }
359 
360  // Setup and initialize configurations
361  // default is added first so that it will be checked last.
362  // Default file
363  int returnValue = fYAMLConfig.AddConfiguration(fDefaultConfigurationFilename, "default");
364  if (returnValue >= 0) {
365  AliInfoStream() << "Using default EMCal corrections configuration located at \"" << fDefaultConfigurationFilename << "\"\n";
366  }
367  else {
368  AliFatal(TString::Format("Default file located at \"%s\" does not exist!", fDefaultConfigurationFilename.c_str()));
369  }
370 
371  // User file
373  if (returnValue >= 0) {
374  AliInfoStream() << "Using user EMCal corrections configuration located at \"" << fUserConfigurationFilename << "\"\n";
375  }
376  else {
377  AliInfoStream() << "User file at \"" << fUserConfigurationFilename << "\" does not exist! All settings will be from the default file!\n";
378  }
379 
380  // Initialize
382 
383  // Note that it is initialized properly so that the analysis can proceed
385 }
386 
397 void AliEmcalCorrectionTask::DetermineComponentsToExecute(std::vector <std::string> & correctionComponents)
398 {
399  std::vector <std::string> executionOrder;
400  // executionOrder determines the order of tasks to execute, but it doesn't name the particular tasks
401  fYAMLConfig.GetProperty("executionOrder", executionOrder, true);
402 
403  // Possible components to create from both the user and default configurations
404  // Use set so that the possible components are not repeated
405  std::set <std::string> possibleComponents;
406  if (fYAMLConfig.DoesConfigurationExist("user")) {
407  for (const auto node : fYAMLConfig.GetConfiguration("user").second) {
408  possibleComponents.insert(node.first.as<std::string>());
409  }
410  }
411  for (const auto node : fYAMLConfig.GetConfiguration("default").second) {
412  possibleComponents.insert(node.first.as<std::string>());
413  }
414 
415  // Determine the correction names associated with the correction task
416  std::string expectedComponentName = "";
417  bool foundSuffixComponent = false;
418  bool foundComponent = false;
419  bool componentEnabled = true;
420 
421  // Execution order determines the order that corrections should be added to our execution list
422  for (auto & execName : executionOrder)
423  {
424  // Construct the expected component name with the suffix
425  expectedComponentName = TString::Format("%s_%s", execName.c_str(), fSuffix.c_str()).Data();
426  foundComponent = false;
427  componentEnabled = false;
428 
429  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
430  if (foundComponent)
431  {
432  // Check if the component is enabled
433  fYAMLConfig.GetProperty({expectedComponentName, "enabled"}, componentEnabled, true);
434  // If enabled, then store the name so that it can be executed
435  if (componentEnabled == true) {
436  foundSuffixComponent = true;
437  correctionComponents.push_back(expectedComponentName);
438  }
439  else {
440  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
441  }
442 
443  continue;
444  }
445  else
446  {
447  // Look for the normal component
448  expectedComponentName = execName;
449  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
450  // Check if it is enabled
451  fYAMLConfig.GetProperty({expectedComponentName, "enabled"}, componentEnabled, true);
452 
453  if (componentEnabled == true) {
454  if (foundSuffixComponent == true) {
455  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()));
456  }
457  else {
458  // Take the normal component and store it to be executed
459  correctionComponents.push_back(expectedComponentName);
460  }
461  }
462  else {
463  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
464  }
465  }
466  }
467 
468  // Need to append "AliEmcalCorrection" to allow the tasks to be found!
469  AliDebug(2, "Found EMCal Correction Components: ");
470  for (auto & component : correctionComponents)
471  {
472  component = "AliEmcalCorrection" + component;
473  AliDebug(2, TString::Format("%s", component.c_str()) );
474  }
475 }
476 
490 {
491  // Names of properties for a particular component in the user and default configurations
492  std::set <std::string> userPropertyNames;
493  std::set <std::string> defaultPropertyNames;
494  // Notes whether a match was found between user and default properties
495  bool foundMatch = false;
496  std::string tempComponentName = "";
497 
498  // Loop over all components
499  for (const auto componentName : fOrderedComponentsToExecute)
500  {
501  // Reset for each loop
502  userPropertyNames.clear();
503  defaultPropertyNames.clear();
504  // We need to remove "AliEmcalCorrection" so that the correction will be found in the configuration
505  std::string prefix = "AliEmcalCorrection";
506  tempComponentName = componentName.substr(componentName.find(prefix) + prefix.length());
507 
508  AliDebugStream(2) << "Checking component " << componentName << " for unmatched user settings" << std::endl;
509 
510  // Get the user property names
511  GetPropertyNamesFromNode("user", tempComponentName, userPropertyNames, false);
512 
513  // Get the same from default
514  // Not required here because the default configuration may not have the specialized component
515  GetPropertyNamesFromNode("default", tempComponentName, defaultPropertyNames, false);
516 
517  // We need to check the base correction as well to fill out the options
518  if (tempComponentName.find("_") != std::string::npos) {
519  // Get the base user component
520  GetPropertyNamesFromNode("user", tempComponentName.substr(0, tempComponentName.find("_")), userPropertyNames, false);
521 
522  // Required here because the default must have the base component!
523  GetPropertyNamesFromNode("default", tempComponentName.substr(0, tempComponentName.find("_")), defaultPropertyNames, true);
524  }
525 
526  // Check each property defined in the user file for a match to the properties in the default file
527  for (auto userPropertyName : userPropertyNames)
528  {
529  AliDebugStream(2) << "Checking property " << userPropertyName << std::endl;
530  foundMatch = false;
531  for (auto defaultPropertyName : defaultPropertyNames)
532  {
533  if (userPropertyName == defaultPropertyName) {
534  AliDebugStream(2) << "Found match of " << userPropertyName << " with " << defaultPropertyName << std::endl;
535  foundMatch = true;
536  }
537  }
538  if (foundMatch == false) {
539  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()));
540  }
541  }
542  }
543 }
544 
552 {
553  // Iterate over the ordered components list and create the components
554  AliEmcalCorrectionComponent * component = 0;
555  for (auto componentName : fOrderedComponentsToExecute)
556  {
557  std::string noPrefixComponentName = componentName.substr(0, componentName.find("_" + fSuffix));
558  component = AliEmcalCorrectionComponentFactory::createInstance(noPrefixComponentName);
559  if (!component)
560  {
561  AliFatal(TString::Format("Failed to create requested component %s!", componentName.c_str()));
562  }
563 
564  // For setting names of tasks to differentiate between tasks of the same class
565  component->SetName(componentName.c_str());
566  component->SetTitle(componentName.c_str());
567 
568  // Initialize the %YAML configurations in each component
569  component->SetYAMLConfiguration(fYAMLConfig);
570 
571  // configure needed fields for components to properly initialize
572  component->SetIsESD(fIsEsd);
573 
574  // Add the require containers to the component
575  // Cells must be set during UserExec() because we need to add them as a pointer
578 
579  // Initialize each component
580  bool initialized = component->Initialize();
581 
582  if (component && initialized)
583  {
584  AliInfo(TString::Format("Successfully added correction task: %s", componentName.c_str()));
585  fCorrectionComponents.push_back(component);
586  }
587  }
588 }
589 
605 {
606  // Get container node
607  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
608 
609  // Determine which containers we need based on which are requested by the enabled correction tasks
610  std::set <std::string> requestedContainers;
611  std::vector <std::string> componentRequest;
612  for ( const auto & componentName : fOrderedComponentsToExecute )
613  {
614  componentRequest.clear();
615  // Not required because not all components will have all kinds of containers
616  std::string selectionName = "AliEmcalCorrection";
617  // Expliecitly initialize as a vector to avoid ambiguity.
618  fYAMLConfig.GetProperty(std::vector<std::string>{componentName.substr(componentName.find(selectionName) + selectionName.length()), inputObjectName + "Names"}, componentRequest, false);
619  for ( auto & req : componentRequest )
620  {
621  AliDebugStream(3) << "Component " << componentName << " requested container name " << req << std::endl;
622  requestedContainers.insert(req);
623  }
624  }
625 
626  AliDebugStream(2) << inputObjectName << " Containers requested by components: " << std::endl;
627  for (auto & str : requestedContainers) {
628  AliDebugStream(2) << "\t" << str << std::endl;;
629  }
630 
631  // Create all requested containers
632  AliDebug(2, TString::Format("Setting up requested containers!"));
633  SetupContainersFromInputNodes(inputObjectType, requestedContainers);
634 }
635 
645 {
646  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
647  // Need to be of the form "clusterContainersNames"
648  inputObjectName = inputObjectName + "Names";
649 
650  std::vector <std::string> inputObjects;
651  // Property is not required, because not all components need Clusters or Tracks
652  // Expliecitly initialize as a vector to avoid ambiguity.
653  fYAMLConfig.GetProperty(std::vector<std::string>{component->GetName(), inputObjectName.c_str()}, inputObjects, false);
654 
655  //AliDebugStream(4) << "inputObjects.size(): " << inputObjects.size() << std::endl;
656 
657  // If it is not found, then there will be nothing to iterate over, so we don't need to explicitly check the return value
658  for (auto const & str : inputObjects)
659  {
660  // 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()!
661  if (inputObjectType == AliEmcalContainerUtils::kCluster)
662  {
663  AliEmcalContainer * cont = GetClusterContainer(str.c_str());
664  AliDebugStream(2) << "Adding cluster container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
665 
666  if (checkObjectExists && !cont) {
667  AliError(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
668  }
669  component->AdoptClusterContainer(GetClusterContainer(str.c_str()));
670 
671  // Check that we are using the standard input event
672  if (!(cont->GetIsEmbedding())) {
673  component->SetUsingInputEvent(true);
674  }
675  }
676  else if (inputObjectType == AliEmcalContainerUtils::kTrack)
677  {
678  AliEmcalContainer * cont = GetParticleContainer(str.c_str());
679  AliDebugStream(2) << "Adding particle container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
680 
681  if (checkObjectExists && !cont) {
682  AliFatal(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
683  }
684  component->AdoptParticleContainer(GetParticleContainer(str.c_str()));
685 
686  // Check that we are using the standard input event
687  if (!(cont->GetIsEmbedding())) {
688  component->SetUsingInputEvent(true);
689  }
690  }
691  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells)
692  {
693  // NOTE: This operates different than the others. This should be executed during run time rather than during initialization!
694  if (inputObjects.size() > 1) {
695  AliFatal(TString::Format("Component %s requested more than one cell branch, but this is not supported! Check the configuration!", component->GetName()));
696  }
697 
698  // If we've made it here, this must be at least one entry
700  AliDebugStream(2) << "Adding calo cells \"" << cellCont->GetName() << "\" of branch name \"" << cellCont->GetBranchName() << "\" to component " << component->GetName() << std::endl;
701 
702  if (!(cellCont->GetCells())) {
703  // Attempt to re-initialize the cells.
704  // NOTE: This may not succeed. Adding the container may need to be repeated after the
705  // object is created
707  }
708 
709  if (checkObjectExists && !(cellCont->GetCells())) {
710  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()));
711  }
712 
713  // Set the calo cells (may be null)
714  component->SetCaloCells(cellCont->GetCells());
715 
716  // It is possible that the cells pointer is null because it may not be created yet. For example,
717  // when combining cells. Thus, we must first check whether the pointer is available before checking
718  // for the number of cells. This could potentially decrease the amount of debug information, but this
719  // should rarely be an issue.
720  if (component->GetCaloCells()) {
721  AliDebugStream(3) << "Component GetNumberOfCells(): " << component->GetCaloCells()->GetNumberOfCells() << std::endl;
722  }
723 
724  // Check that we are using the standard input event
725  if (!(cellCont->GetIsEmbedding())) {
726  component->SetUsingInputEvent(true);
727  }
728  }
729  }
730 }
731 
738 void AliEmcalCorrectionTask::SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, std::set <std::string> & requestedContainers)
739 {
740  // Our node contains all of the objects that we will want to create.
741  for(auto & containerName : requestedContainers)
742  {
743  // The section is the container name
744  //std::string containerName = it->first.as<std::string>();
745  // Skip if the particle or cluster container already exists
746  if (GetParticleContainer(containerName.c_str()) || GetClusterContainer(containerName.c_str())) {
747  continue;
748  }
749 
750  AliDebug(2, TString::Format("Processing container %s of inputType %d", containerName.c_str(), inputObjectType));
751  if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
752  SetupContainer(inputObjectType, containerName);
753  }
754  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
755  SetupCellsInfo(containerName);
756  }
757  }
758 }
759 
768 void AliEmcalCorrectionTask::SetupCellsInfo(std::string containerName)
769 {
770  // Define cell info
772 
773  // Set properties
774  // Cells (object) name
775  cellObj->SetName(containerName);
776  // Branch name
777  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(AliEmcalContainerUtils::kCaloCells), containerName};
778  std::string tempString = "";
779  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "branchName", tempString, true);
780  if (tempString == "usedefault") {
782  }
783  cellObj->SetBranchName(tempString);
784 
785  // IsEmbedding
786  bool tempBool = false;
787  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "embedding", tempBool, false);
788  cellObj->SetIsEmbedding(tempBool);
789 
790  // Add to the array to keep track of it
791  fCellCollArray.push_back(cellObj);
792 }
793 
809 void AliEmcalCorrectionTask::SetupContainer(const AliEmcalContainerUtils::InputObject_t inputObjectType, const std::string containerName)
810 {
811  // Create container
812  AliDebugStream(2) << "Adding container" << std::endl;
813  AliEmcalContainer * cont = AddContainer(inputObjectType, containerName);
814  AliDebugStream(2) << "Added container" << std::endl;
815 
816  // Set the container properties
817  //
818  // TODO: Consider if this can be converted to a map to function pointers. There are a number of details
819  // which can make it a bit complicated. Those details include inheritance, pointing to member
820  // functions, etc. It should all be possible, but may not be worth all of the extra work and code.
821  // Example ccode:
822  // SetValueInContainer(inputObjectPropertiesPath, "minPt", &cont::SetMinPt, tempDouble, false);
823  // SetValueInContainer(inputObjectPropertiesPath, "minE", &cont::SetMinE, tempDouble, false);
824  // std::function may be easier?
825  // See: https://isocpp.org/wiki/faq/pointers-to-members
828  // type void (AliEmcalContainer::*EmcalContainerFn)(double val);
829  // // Potential map?
830  // std::map<std::string, EmcalContainerFn> EmcalContFunctionMap;
831  // EmcalContFunctionMap["minPt"] = &AliEmcalContainer::SetMinPt;
832  // EmcalContFunctionMap["minE"] = &AliEmcalContainer::SetMinE;
833  // // Define functions (use map?)
834  // EmcalContainerFn minPt = &AliEmcalContainer::SetMinPt;
835  // EmcalContainerFn minE = &AliEmcalContainer::SetMinE;
836  // // Example invocation
837  // (cont->*minPt)(tempDouble);
838 
839  // Path to the various properties
840  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(inputObjectType), containerName};
841 
842  // Temporary variables to store requested properties
843  std::string tempString = "";
844  Double_t tempDouble = 0;
845  bool tempBool = false;
846 
847  // AliEmcalContainer properties
848  // Min Pt
849  bool result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minPt", tempDouble, false);
850  if (result) {
851  AliDebugStream(2) << cont->GetName() << ": Setting minPt of " << tempDouble << std::endl;
852  cont->SetMinPt(tempDouble);
853  }
854  // Min E
855  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minE", tempDouble, false);
856  if (result) {
857  AliDebugStream(2) << cont->GetName() << ": Setting minE of " << tempDouble << std::endl;
858  cont->SetMinE(tempDouble);
859  }
860  // Eta min, max
861  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minEta", tempDouble, false);
862  if (result) {
863  // Only continue checking if the min is there, since we must set both together
864  Double_t tempDouble2 = 0;
865  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "maxEta", tempDouble, false);
866  if (result) {
867  AliDebugStream(2) << cont->GetName() << ": Setting eta limits of " << tempDouble << " to " << tempDouble2 << std::endl;
868  cont->SetEtaLimits(tempDouble, tempDouble2);
869  }
870  }
871  // Phi min, max
872  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minPhi", tempDouble, false);
873  if (result) {
874  // Only continue checking if the min is there, since we must set both together
875  Double_t tempDouble2 = 0;
876  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "maxPhi", tempDouble, false);
877  if (result) {
878  AliDebugStream(2) << cont->GetName() << ": Setting phi limits of " << tempDouble << " to " << tempDouble2 << std::endl;
879  cont->SetPhiLimits(tempDouble, tempDouble2);
880  }
881  }
882  // Embedded
883  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "embedding", tempBool, false);
884  if (result) {
885  AliDebugStream(2) << cont->GetName() << ": Setting embedding to " << (tempBool ? "enabled" : "disabled") << std::endl;
886  cont->SetIsEmbedding(tempBool);
887  }
888 
889  // Cluster specific properties
890  AliClusterContainer * clusterContainer = dynamic_cast<AliClusterContainer *>(cont);
891  if (clusterContainer) {
892  // Default energy
893  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "defaultClusterEnergy", tempString, false);
894  if (result) {
895  // Need to get the enumeration
896  AliVCluster::VCluUserDefEnergy_t clusterEnergyType = AliClusterContainer::fgkClusterEnergyTypeMap.at(tempString);
897  AliDebugStream(2) << clusterContainer->GetName() << ": Setting cluster energy type to " << clusterEnergyType << std::endl;
898  clusterContainer->SetDefaultClusterEnergy(clusterEnergyType);
899  }
900 
901  // NonLinCorrEnergyCut
902  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "clusNonLinCorrEnergyCut", tempDouble, false);
903  if (result) {
904  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusNonLinCorrEnergyCut of " << tempDouble << std::endl;
905  clusterContainer->SetClusNonLinCorrEnergyCut(tempDouble);
906  }
907 
908  // HadCorrEnergyCut
909  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "clusHadCorrEnergyCut", tempDouble, false);
910  if (result) {
911  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusHadCorrEnergyCut of " << tempDouble << std::endl;
912  clusterContainer->SetClusHadCorrEnergyCut(tempDouble);
913  }
914 
915  // SetIncludePHOS
916  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "includePHOS", tempBool, false);
917  if (result) {
918  AliDebugStream(2) << clusterContainer->GetName() << ": Setting Include PHOS to " << (tempBool ? "enabled" : "disabled") << std::endl;
919  clusterContainer->SetIncludePHOS(tempBool);
920  }
921  }
922 
923  // Track specific
924  AliTrackContainer * trackContainer = dynamic_cast<AliTrackContainer *>(cont);
925  if (trackContainer) {
926  // Track selection
927  // AOD Filter bits as a sequence
928  std::vector <UInt_t> filterBitsVector;
929  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "aodFilterBits", filterBitsVector, false);
930  if (result){
931  UInt_t filterBits = 0;
932  for (int filterBit : filterBitsVector) {
933  filterBits += filterBit;
934  }
935  AliDebugStream(2) << trackContainer->GetName() << ": Setting filterBits of " << filterBits << std::endl;
936  trackContainer->SetAODFilterBits(filterBits);
937  }
938 
939  // SetTrackFilterType enum
940  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "trackFilterType", tempString, false);
941  if (result) {
942  // Need to get the enumeration
944  AliDebugStream(2) << trackContainer->GetName() << ": Setting trackFilterType of " << trackFilterType << " (" << tempString << ")\n";
945  trackContainer->SetTrackFilterType(trackFilterType);
946  }
947 
948  // Track cuts period
949  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "trackCutsPeriod", tempString, false);
950  if (result) {
951  // Need to get the enumeration
952  AliDebugStream(2) << trackContainer->GetName() << ": Setting track cuts period to " << tempString << std::endl;
953  trackContainer->SetTrackCutsPeriod(tempString.c_str());
954  }
955  }
956 }
957 
973 AliEmcalContainer * AliEmcalCorrectionTask::AddContainer(const AliEmcalContainerUtils::InputObject_t contType, const std::string containerName)
974 {
975  // Determine the type of branch to request
976  std::string containerBranch = "";
978  AliFatal("Must specify type of container when requesting branch.");
979  }
980 
981  // Path to the various properties
982  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(contType), containerName};
983 
984  // Retrieve branch name
985  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "branchName", containerBranch, true);
986  // Should be unnecessary, since the user can only do this if done explicitly.
987  /*if (containerBranch == "")
988  {
989  AliFatal(TString::Format("Request %i container, but the container branch is empty!", contType));
990  }*/
991 
992  // Determine proper name if using "usedefault" pattern
993  if (containerBranch == "usedefault") {
994  containerBranch = AliEmcalContainerUtils::DetermineUseDefaultName(contType, fIsEsd);
995  }
996 
997  // Create containers and set them to the name of the component
998  AliEmcalContainer * cont = 0;
999  if (contType == AliEmcalContainerUtils::kCluster)
1000  {
1001  cont = new AliClusterContainer(containerBranch.c_str());
1002  AdoptClusterContainer(dynamic_cast<AliClusterContainer *>(cont));
1003  }
1004  else if (contType == AliEmcalContainerUtils::kTrack)
1005  {
1006  if (containerBranch == "mcparticles") {
1007  cont = new AliMCParticleContainer(containerBranch.c_str());
1008  }
1009  else {
1010  cont = new AliTrackContainer(containerBranch.c_str());
1011  }
1012  AdoptParticleContainer(dynamic_cast<AliParticleContainer *>(cont));
1013  }
1014  cont->SetName(containerName.c_str());
1015 
1016  return cont;
1017 }
1018 
1028 {
1029  // Check that the configuration is initialized
1030  if (fConfigurationInitialized != true)
1031  {
1032  AliFatal("YAML configuration must be initialized before running (ie. the AddTask, run macro or wagon)!");
1033  }
1034 
1035  // %YAML Objects cannot be streamed, so we need to reinitialize them here.
1037 
1038  if (fForceBeamType == kpp)
1039  fNcentBins = 1;
1040 
1041  // Allow for output files
1042  OpenFile(1);
1043  fOutput = new TList();
1044  fOutput->SetOwner();
1045 
1047 
1048  PostData(1, fOutput);
1049 }
1050 
1058 {
1059  // Run the initialization for all derived classes.
1060  for (auto component : fCorrectionComponents)
1061  {
1062  // Set cent bins (usually used for hist creation)
1063  // It cannot be set until now because it can be changed after initialization
1064  // For instance, by SetForceBeamType()
1065  component->SetNcentralityBins(fNcentBins);
1066 
1067  component->UserCreateOutputObjects();
1068 
1069  if (component->GetOutputList() != 0)
1070  {
1071  // Adds a list to the list -- this doesn't work for some unknown reason
1072  //fOutput->Add(component->GetOutputList());
1073 
1074  // iterate through lists for each component, and fill in output
1075  TList* t = new TList();
1076  t->SetName(component->GetName());
1077  fOutput->AddLast(t);
1078  t = (TList*)fOutput->Last();
1079  TIter next(component->GetOutputList());
1080  while (TObject *obj = next()){
1081  t->Add(obj);
1082  }
1083 
1084  AliDebug(1, TString::Format("Added output list from task %s to output.", component->GetName()));
1085  }
1086  }
1087 }
1088 
1094 {
1095  // Recycle embedded events which do not pass the internal event selection in the embedding helper
1097  auto embeddingHelper = AliAnalysisTaskEmcalEmbeddingHelper::GetInstance();
1098  if (embeddingHelper && embeddingHelper->EmbeddedEventUsed() == false) {
1099  AliDebugStream(4) << "Embedding helper rejected the internal event. Skipping this event.\n";
1100  return;
1101  }
1102  }
1103 
1104  // Initialize the event if not initialized
1105  if (!fEventInitialized)
1106  ExecOnce();
1107 
1108  // Only continue if we are initialized successfully
1109  if (!fEventInitialized)
1110  return;
1111 
1112  // Get the objects for each event
1113  if (!RetrieveEventObjects())
1114  return;
1115 
1116  // Call run for each correction
1117  if (!Run())
1118  return;
1119 }
1120 
1132 {
1133  if (!InputEvent()) {
1134  AliError("Could not retrieve event! Returning!");
1135  return;
1136  }
1137 
1138  // This warning was extracted out from the cell components
1139  if (dynamic_cast<AliAODEvent*>(InputEvent())) {
1140  AliWarning("=============================================================");
1141  AliWarning("=== Running on AOD is not equivalent to running on ESD! ===");
1142  AliWarning("=============================================================");
1143  }
1144 
1145  if (fNeedEmcalGeom) {
1146  fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(InputEvent()->GetRunNumber());
1147  if (!fGeom) {
1148  AliFatal("Can not get EMCal geometry instance. If you do not need the EMCal geometry, disable it by setting task->SetNeedEmcalGeometry(kFALSE).");
1149  return;
1150  }
1151  }
1152 
1153  // Load all requested track branches - each container knows name already
1154  for (Int_t i =0; i<fParticleCollArray.GetEntriesFast(); i++) {
1155  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
1157  cont->SetArray(InputEvent());
1158  }
1159 
1160  // Load all requested cluster branches - each container knows name already
1161  for (Int_t i =0; i<fClusterCollArray.GetEntriesFast(); i++) {
1162  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
1164  cont->SetArray(InputEvent());
1165  }
1166 
1167  // Determine the proper pointer for each cell object and save them to the cell container
1168  // At this point, they should all be created
1169  for (auto cellObj : fCellCollArray)
1170  {
1172  }
1173 
1174  fEventInitialized = kTRUE;
1175 
1176  // Print warning to the user that the rest of the configuration information is available in the generation log
1177  // when the Analysis Manager was created. Using cout to be certain that it is shown on the train!
1178  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";
1179 
1180  // Setup the components
1182 }
1183 
1189 {
1190  // Run the initialization for all derived classes.
1191  for (auto component : fCorrectionComponents)
1192  {
1193  // Setup geometry
1194  component->SetEMCALGeometry(fGeom);
1195 
1196  // Add the requested cells to the component
1198 
1199  // Set the input events. This is redundant to where it is set during Run(), but the events need to be
1200  // available to components, and they are only called one extra time.
1201  component->SetInputEvent(InputEvent());
1202  component->SetMCEvent(MCEvent());
1203 
1204  // Component ExecOnce()
1205  component->ExecOnce();
1206 
1207  // If the cells were created during ExecOnce(), then we need to re-initialize the pointer to ensure
1208  // that it is not null!
1209  if (!(component->GetCaloCells())) {
1210  AliDebugStream(2) << "Re-initializing cells for component " << component->GetName() << std::endl;
1212  }
1213  }
1214 }
1215 
1221 {
1222  fVertex[0] = 0;
1223  fVertex[1] = 0;
1224  fVertex[2] = 0;
1225  fNVertCont = 0;
1226 
1227  const AliVVertex *vert = InputEvent()->GetPrimaryVertex();
1228  if (vert) {
1229  vert->GetXYZ(fVertex);
1230  fNVertCont = vert->GetNContributors();
1231  }
1232 
1233  fBeamType = GetBeamType();
1234 
1235  if (fBeamType == kAA || fBeamType == kpA ) {
1237  AliMultSelection *MultSelection = static_cast<AliMultSelection*>(InputEvent()->FindListObject("MultSelection"));
1238  if (MultSelection) {
1239  fCent = MultSelection->GetMultiplicityPercentile(fCentEst.Data());
1240  }
1241  else {
1242  AliWarning("Could not retrieve centrality information! Assuming 99");
1243  }
1244  }
1245  else { // old centrality estimation < 2015
1246  AliCentrality *aliCent = InputEvent()->GetCentrality();
1247  if (aliCent) {
1248  fCent = aliCent->GetCentralityPercentile(fCentEst.Data());
1249  }
1250  else {
1251  AliWarning("Could not retrieve centrality information! Assuming 99");
1252  }
1253  }
1254 
1255  if (fNcentBins==4) {
1256  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1257  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1258  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1259  else if (fCent >= 50 && fCent <= 100) fCentBin = 3;
1260  else {
1261  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1262  fCentBin = fNcentBins-1;
1263  }
1264  }
1265  else if (fNcentBins==5) { // for PbPb 2015
1266  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1267  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1268  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1269  else if (fCent >= 50 && fCent <= 90) fCentBin = 3;
1270  else if (fCent > 90) {
1271  fCent = 99;
1272  fCentBin = 4;
1273  }
1274  else {
1275  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1276  fCentBin = fNcentBins-1;
1277  }
1278  }
1279  else {
1280  Double_t centWidth = (fMaxCent-fMinCent)/(Double_t)fNcentBins;
1281  if(centWidth>0.) {
1282  fCentBin = TMath::FloorNint(fCent/centWidth);
1283  }
1284  else {
1285  fCentBin = 0;
1286  }
1287  if (fCentBin>=fNcentBins) {
1288  AliWarning(Form("fCentBin too large: cent = %f fCentBin = %d. Assuming 99", fCent, fCentBin));
1289  fCentBin = fNcentBins-1;
1290  }
1291  }
1292  }
1293  else {
1294  fCent = 99;
1295  fCentBin = 0;
1296  }
1297 
1298  AliEmcalContainer* cont = 0;
1299 
1300  TIter nextPartColl(&fParticleCollArray);
1301  while ((cont = static_cast<AliEmcalContainer*>(nextPartColl()))) cont->NextEvent(InputEvent());
1302 
1303  TIter nextClusColl(&fClusterCollArray);
1304  while ((cont = static_cast<AliEmcalContainer*>(nextClusColl()))) cont->NextEvent(InputEvent());
1305 
1306  return kTRUE;
1307 }
1308 
1314 {
1315  // Run the initialization for all derived classes.
1316  for (auto component : fCorrectionComponents)
1317  {
1318  component->SetInputEvent(InputEvent());
1319  component->SetMCEvent(MCEvent());
1320  component->SetCentralityBin(fCentBin);
1321  component->SetCentrality(fCent);
1322  component->SetVertex(fVertex);
1323 
1324  component->Run();
1325  }
1326 
1327  PostData(1, fOutput);
1328 
1329  return kTRUE;
1330 }
1331 
1336 {
1337  // Run the initialization for all derived classes.
1338  for (auto component : fCorrectionComponents)
1339  {
1340  component->UserNotify();
1341  }
1342 
1343  return kTRUE;
1344 }
1345 
1352 std::ostream & AliEmcalCorrectionTask::PrintConfiguration(std::ostream & in, bool userConfig) const
1353 {
1354  std::string configurationName = userConfig ? "user" : "default";
1355  if (fYAMLConfig.DoesConfigurationExist(configurationName)) {
1356  auto configPair = fYAMLConfig.GetConfiguration(configurationName);
1357  if (configPair.second.IsNull() == true) {
1358  AliWarning(TString::Format("%s configuration is empty!", configPair.first.c_str()));
1359  }
1360  in << configPair.second;
1361  }
1362  else {
1363  in << "Configuration \"" << configurationName << "\" does not exist!\n";
1364  }
1365 
1366  return in;
1367 }
1368 
1376 bool AliEmcalCorrectionTask::WriteConfigurationFile(std::string filename, bool userConfig) const
1377 {
1378  return fYAMLConfig.WriteConfiguration(filename, userConfig ? "user" : "default");
1379 }
1380 
1390 {
1391  // Setup
1392  // It's important to reinitialize the configuration so the %YAML nodes are defined!
1394  std::string tempConfigName = "tempConfig";
1395  fYAMLConfig.AddConfiguration(filename, tempConfigName);
1396 
1397  // Compare
1398  bool returnValue = fYAMLConfig.CompareConfigurations(tempConfigName, userConfig ? "user" : "default");
1399 
1400  // Cleanup
1401  fYAMLConfig.RemoveConfiguration(tempConfigName);
1402 
1403  return returnValue;
1404 }
1405 
1413 {
1414  AliDebugStream(2) << "Retrieving cells object " << cellContainer->GetName() << std::endl;
1415  // Check for embedding and return object
1416  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cellContainer->GetIsEmbedding());
1417 
1418  cellContainer->SetCells(dynamic_cast<AliVCaloCells *>(event->FindListObject(cellContainer->GetBranchName().c_str())));
1419 }
1420 
1431 {
1432  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cont->GetIsEmbedding());
1433 
1434  TClonesArray * array = dynamic_cast<TClonesArray *>(event->FindListObject(cont->GetArrayName()));
1435  if (!array) {
1436  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()));
1437  array = new TClonesArray(AliEmcalContainerUtils::DetermineUseDefaultName(objectType, fIsEsd, true).c_str());
1438  array->SetName(cont->GetArrayName());
1439  event->AddObject(array);
1440  }
1441 }
1442 
1451 {
1452  // Get container node
1453  std::string inputObjectName = "";
1454  if (inputObjectType == AliEmcalContainerUtils::kCluster) {
1455  inputObjectName = "clusterContainers";
1456  }
1457  else if (inputObjectType == AliEmcalContainerUtils::kTrack) {
1458  inputObjectName = "trackContainers";
1459  }
1460  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1461  inputObjectName = "cells";
1462  }
1463  else {
1464  AliFatal(TString::Format("Unrecognized input object type %d", inputObjectType));
1465  }
1466 
1467  return inputObjectName;
1468 }
1469 
1481 bool AliEmcalCorrectionTask::CheckPossibleNamesForComponentName(std::string & name, std::set <std::string> & possibleComponents)
1482 {
1483  bool foundComponent = false;
1484  for (auto & possibleComponent : possibleComponents)
1485  {
1486  if (possibleComponent == name) {
1487  foundComponent = true;
1488  break;
1489  }
1490  }
1491 
1492  return foundComponent;
1493 }
1494 
1502 {
1503  if (fForceBeamType != kNA)
1504  return fForceBeamType;
1505 
1506  AliESDEvent *esd = dynamic_cast<AliESDEvent*>(InputEvent());
1507  if (esd) {
1508  const AliESDRun *run = esd->GetESDRun();
1509  TString beamType = run->GetBeamType();
1510  if (beamType == "p-p")
1511  return kpp;
1512  else if (beamType == "A-A")
1513  return kAA;
1514  else if (beamType == "p-A")
1515  return kpA;
1516  else
1517  return kNA;
1518  } else {
1519  Int_t runNumber = InputEvent()->GetRunNumber();
1520  // All run number ranges taken from the RCT
1521  if ((runNumber >= 136833 && runNumber <= 139517) || // LHC10h
1522  (runNumber >= 167693 && runNumber <= 170593) || // LHC11h
1523  (runNumber >= 244824 && runNumber <= 246994)) { // LHC15o
1524  return kAA;
1525  } else if ((runNumber >= 188356 && runNumber <= 188366) || // LHC12g
1526  (runNumber >= 195164 && runNumber <= 197388) || // LHC13b-f
1527  (runNumber >= 265015 && runNumber <= 267166)) { // LHC16q-t
1528  return kpA;
1529  } else {
1530  return kpp;
1531  }
1532  }
1533 }
1534 
1539 {
1540  if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1541  stream << "Cells info: " << std::endl;
1542  for (auto cellInfo : fCellCollArray) {
1543  stream << "\tName: " << cellInfo->GetName() << "\tBranch: " << cellInfo->GetBranchName() << "\tIsEmbedding: " << std::boolalpha << cellInfo->GetIsEmbedding() << std::endl;
1544  }
1545  }
1546  else if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
1547  stream << (inputObjectType == AliEmcalContainerUtils::kCluster ? "Cluster" : "Track") << " container info: " << std::endl;
1548  AliEmcalContainer * cont = 0;
1549  for (auto containerInfo : (inputObjectType == AliEmcalContainerUtils::kCluster ? fClusterCollArray : fParticleCollArray) ) {
1550  cont = static_cast<AliEmcalContainer *>(containerInfo);
1551  stream << "\tName: " << cont->GetName() << "\tBranch: " << cont->GetArrayName() << "\tTitle: " << cont->GetTitle() << "\tIsEmbedding: " << std::boolalpha << cont->GetIsEmbedding() << std::endl;
1552  }
1553  }
1554  else {
1555  AliErrorStream() << "Unrecognized input object type " << inputObjectType << std::endl;
1556  }
1557 }
1558 
1572 void AliEmcalCorrectionTask::GetPropertyNamesFromNode(const std::string configurationName, const std::string componentName, std::set <std::string> & propertyNames, const bool nodeRequired)
1573 {
1574  bool retrievedPropertyNames = false;
1575  if (fYAMLConfig.DoesConfigurationExist(configurationName)) {
1576  AliDebugStream(3) << "Looking for nodes in component \"" << componentName << "\" in the \"" << configurationName << "\" configuration\n";
1577  auto configPair = fYAMLConfig.GetConfiguration(configurationName);
1578  if (configPair.second[componentName])
1579  {
1580  for (auto propertyName : configPair.second[componentName])
1581  {
1582  AliDebugStream(4) << "Node property name " << propertyName.first.as<std::string>() << "\n";
1583  propertyNames.insert(propertyName.first.as<std::string>());
1584  }
1585  retrievedPropertyNames = true;
1586  }
1587  }
1588 
1589  if (retrievedPropertyNames == false && nodeRequired) {
1590  std::stringstream message;
1591  message << "Failed to retrieve required property \""
1592  << componentName << "\" from the \"" << configurationName << "\" configuration!" << std::endl;
1593  AliFatal(message.str().c_str());
1594  }
1595 }
1596 
1606 {
1607  AliEmcalCorrectionComponent * returnComponent = nullptr;
1608  for (auto component : fCorrectionComponents)
1609  {
1610  if (name == component->GetName()) {
1611  returnComponent = component;
1612  break;
1613  }
1614  }
1615  return returnComponent;
1616 }
1617 
1625 AliEmcalCorrectionCellContainer * AliEmcalCorrectionTask::GetCellContainer(const std::string & cellsContainerName) const
1626 {
1627  for (auto cellContainer : fCellCollArray)
1628  {
1629  if (cellContainer->GetName() == cellsContainerName) {
1630  return cellContainer;
1631  }
1632  }
1633 
1634  return 0;
1635 }
1636 
1638 {
1639  // Get the pointer to the existing analysis manager via the static access method.
1640  //==============================================================================
1641  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1642  if (!mgr)
1643  {
1644  ::Error("AddTaskEmcalCorrectionTask", "No analysis manager to connect to.");
1645  return nullptr;
1646  }
1647 
1648  // Check the analysis type using the event handlers connected to the analysis manager.
1649  //==============================================================================
1650  AliVEventHandler* handler = mgr->GetInputEventHandler();
1651  if (!handler)
1652  {
1653  ::Error("AddTaskEmcalCorrectionTask", "This task requires an input event handler");
1654  return nullptr;
1655  }
1656 
1657  TString name = "AliEmcalCorrectionTask";
1658  if (suffix != "") {
1659  name += TString::Format("_%s", suffix.Data());
1660  }
1661 
1662  AliEmcalCorrectionTask* mgrTask = static_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.Data()));
1663  if (mgrTask) return mgrTask;
1664 
1665  // Create the task that manages the corrections
1666  AliEmcalCorrectionTask* correctionTask = new AliEmcalCorrectionTask(name.Data());
1667 
1668  //-------------------------------------------------------
1669  // Final settings, pass to manager and set the containers
1670  //-------------------------------------------------------
1671 
1672  mgr->AddTask(correctionTask);
1673 
1674  // Create containers for input/output
1675  AliAnalysisDataContainer* cInput = mgr->GetCommonInputContainer();
1676 
1677  TString outputContainerName(name);
1678  outputContainerName += "_histos";
1679 
1680  AliAnalysisDataContainer * cOutput = mgr->CreateContainer(outputContainerName.Data(),
1681  TList::Class(),
1682  AliAnalysisManager::kOutputContainer,
1683  Form("%s", AliAnalysisManager::GetCommonFileName()));
1684 
1685  mgr->ConnectInput(correctionTask, 0, cInput);
1686  mgr->ConnectOutput(correctionTask, 1, cOutput);
1687 
1688  //TObjArray* cnt = mgr->GetContainers();
1689 
1690  return correctionTask;
1691 }
1692 
1694 {
1695  // Get the pointer to the existing analysis manager via the static access method.
1696  //==============================================================================
1697  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1698  if (!mgr)
1699  {
1700  ::Error("ConfigureEmcalCorrectionTaskOnLEGOTrain", "No analysis manager to connect to.");
1701  return nullptr;
1702  }
1703 
1704  // Find the correction task
1705  AliEmcalCorrectionTask * correctionTask = nullptr;
1706  const std::string taskName = "AliEmcalCorrectionTask";
1707  std::string foundTaskName = "";
1708  bool taskFound = false;
1709  std::vector<std::string> namesToSearch = {taskName};
1710 
1711  // Determine if the suffix name should be searched for.
1712  // If a suffix is given, it will be looked for first, followed by the generically named task.
1713  // This way, a user's configuration can be uniquely identified in the case of multiple correction tasks, but
1714  // if there is only one correction task without a suffix, this method will still fall back to that one and
1715  // return a correction task to be configured.
1716  if (suffix != "")
1717  {
1718  std::string suffixName = taskName;
1719  suffixName += "_";
1720  suffixName += suffix.Data();
1721  namesToSearch.insert(namesToSearch.begin(), suffixName);
1722  }
1723 
1724  // Attempt to retrieve the task from the analysis manager
1725  for (auto name : namesToSearch)
1726  {
1727  correctionTask = dynamic_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.c_str()));
1728  if (correctionTask != nullptr) {
1729  taskFound = true;
1730  foundTaskName = name;
1731  break;
1732  }
1733  }
1734 
1735  // Fatal if we can't find the task
1736  if (taskFound == false) {
1737  AliFatalClassF("Could not find correction task, checking for both the suffix \"%s\" and the main task. Did you remember to create it?", suffix.Data());
1738  }
1739 
1740  AliInfoClassStream() << "Found correction task named \"" << foundTaskName <<"\" to configure.\n";
1741 
1742  // AliAnalysisTaskCfg will require a task to be returned, so we add a dummy task to the analysis manager,
1743  // which will be removed when the user calls Initialize(true) on the correction task.
1744  std::string dummyTaskName = foundTaskName + "_dummyTask";
1745  mgr->AddTask(new AliAnalysisTaskSE(dummyTaskName.c_str()));
1746 
1747  return correctionTask;
1748 }
1749 
1755 std::string AliEmcalCorrectionTask::toString(bool includeYAMLConfigurationInfo) const
1756 {
1757  std::stringstream tempSS;
1758 
1759  // Show the correction components
1760  tempSS << "Correction components:\n";
1761  for (auto component : fOrderedComponentsToExecute) {
1762  tempSS << "\t" << component << "\n";
1763  }
1764  // Input objects
1765  tempSS << "\nInput objects:\n";
1769 
1770  if (includeYAMLConfigurationInfo == true) {
1771  tempSS << "\nUser Configuration:\n";
1772  PrintConfiguration(tempSS, true);
1773  tempSS << "\n\nDefault Configuration:\n";
1774  PrintConfiguration(tempSS);
1775  tempSS << "\n";
1776  }
1777 
1778  return tempSS.str();
1779 }
1780 
1787 std::ostream & AliEmcalCorrectionTask::Print(std::ostream & in) const {
1788  in << toString();
1789  return in;
1790 }
1791 
1799 std::ostream & operator<<(std::ostream & in, const AliEmcalCorrectionTask & myTask)
1800 {
1801  std::ostream & result = myTask.Print(in);
1802  return result;
1803 }
1804 
1812 {
1813  std::string temp(opt);
1814  bool includeYAMLConfig = false;
1815  if (temp == "YAML") {
1816  includeYAMLConfig = true;
1817  }
1818  Printf("%s", toString(includeYAMLConfig).c_str());
1819 }
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
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
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
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
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)
static const AliAnalysisTaskEmcalEmbeddingHelper * GetInstance()
BeamType fForceBeamType
forced beam type