AliPhysics  96866e8 (96866e8)
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  // user is added first so that it will be checked first.
362  // User file
363  int returnValue = fYAMLConfig.AddConfiguration(fUserConfigurationFilename, "user");
364  if (returnValue >= 0) {
365  AliInfoStream() << "Using user EMCal corrections configuration located at \"" << fUserConfigurationFilename << "\"\n";
366  }
367  else {
368  AliInfoStream() << "User file at \"" << fUserConfigurationFilename << "\" does not exist! All settings will be from the default file!\n";
369  }
370 
371  // Default file
373  if (returnValue >= 0) {
374  AliInfoStream() << "Using default EMCal corrections configuration located at \"" << fDefaultConfigurationFilename << "\"\n";
375  }
376  else {
377  AliFatal(TString::Format("Default file located at \"%s\" does not exist!", fDefaultConfigurationFilename.c_str()));
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  // Probably not needed for the corrections
894  /*result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "defaultClusterEnergy", tempString, false);
895  if (result) {
896  // Need to get the enumeration
897  AliVCluster::VCluUserDefEnergy_t clusterEnergyType = AliClusterContainer::fgkClusterEnergyTypeMap.at(tempString);
898  AliDebugStream(2) << clusterContainer->GetName() << ": Setting cluster energy type to " << clusterEnergyType << std::endl;
899  clusterContainer->SetDefaultClusterEnergy(clusterEnergyType);
900  }*/
901 
902  // NonLinCorrEnergyCut
903  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "clusNonLinCorrEnergyCut", tempDouble, false);
904  if (result) {
905  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusNonLinCorrEnergyCut of " << tempDouble << std::endl;
906  clusterContainer->SetClusNonLinCorrEnergyCut(tempDouble);
907  }
908 
909  // HadCorrEnergyCut
910  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "clusHadCorrEnergyCut", tempDouble, false);
911  if (result) {
912  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusHadCorrEnergyCut of " << tempDouble << std::endl;
913  clusterContainer->SetClusHadCorrEnergyCut(tempDouble);
914  }
915 
916  // SetIncludePHOS
917  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "includePHOS", tempBool, false);
918  if (result) {
919  AliDebugStream(2) << clusterContainer->GetName() << ": Setting Include PHOS to " << (tempBool ? "enabled" : "disabled") << std::endl;
920  clusterContainer->SetIncludePHOS(tempBool);
921  }
922  }
923 
924  // Track specific
925  AliTrackContainer * trackContainer = dynamic_cast<AliTrackContainer *>(cont);
926  if (trackContainer) {
927  // Track selection
928  // AOD Filter bits as a sequence
929  std::vector <UInt_t> filterBitsVector;
930  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "aodFilterBits", filterBitsVector, false);
931  if (result){
932  UInt_t filterBits = 0;
933  for (int filterBit : filterBitsVector) {
934  filterBits += filterBit;
935  }
936  AliDebugStream(2) << trackContainer->GetName() << ": Setting filterBits of " << filterBits << std::endl;
937  trackContainer->SetAODFilterBits(filterBits);
938  }
939 
940  // SetTrackFilterType enum
941  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "trackFilterType", tempString, false);
942  if (result) {
943  // Need to get the enumeration
945  AliDebugStream(2) << trackContainer->GetName() << ": Setting trackFilterType of " << trackFilterType << " (" << tempString << ")\n";
946  trackContainer->SetTrackFilterType(trackFilterType);
947  }
948 
949  // Track cuts period
950  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "trackCutsPeriod", tempString, false);
951  if (result) {
952  // Need to get the enumeration
953  AliDebugStream(2) << trackContainer->GetName() << ": Setting track cuts period to " << tempString << std::endl;
954  trackContainer->SetTrackCutsPeriod(tempString.c_str());
955  }
956  }
957 }
958 
974 AliEmcalContainer * AliEmcalCorrectionTask::AddContainer(const AliEmcalContainerUtils::InputObject_t contType, const std::string containerName)
975 {
976  // Determine the type of branch to request
977  std::string containerBranch = "";
979  AliFatal("Must specify type of container when requesting branch.");
980  }
981 
982  // Path to the various properties
983  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(contType), containerName};
984 
985  // Retrieve branch name
986  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "branchName", containerBranch, true);
987  // Should be unnecessary, since the user can only do this if done explicitly.
988  /*if (containerBranch == "")
989  {
990  AliFatal(TString::Format("Request %i container, but the container branch is empty!", contType));
991  }*/
992 
993  // Determine proper name if using "usedefault" pattern
994  if (containerBranch == "usedefault") {
995  containerBranch = AliEmcalContainerUtils::DetermineUseDefaultName(contType, fIsEsd);
996  }
997 
998  // Create containers and set them to the name of the component
999  AliEmcalContainer * cont = 0;
1000  if (contType == AliEmcalContainerUtils::kCluster)
1001  {
1002  cont = new AliClusterContainer(containerBranch.c_str());
1003  AdoptClusterContainer(dynamic_cast<AliClusterContainer *>(cont));
1004  }
1005  else if (contType == AliEmcalContainerUtils::kTrack)
1006  {
1007  if (containerBranch == "mcparticles") {
1008  cont = new AliMCParticleContainer(containerBranch.c_str());
1009  }
1010  else {
1011  cont = new AliTrackContainer(containerBranch.c_str());
1012  }
1013  AdoptParticleContainer(dynamic_cast<AliParticleContainer *>(cont));
1014  }
1015  cont->SetName(containerName.c_str());
1016 
1017  return cont;
1018 }
1019 
1029 {
1030  // Check that the configuration is initialized
1031  if (fConfigurationInitialized != true)
1032  {
1033  AliFatal("YAML configuration must be initialized before running (ie. the AddTask, run macro or wagon)!");
1034  }
1035 
1036  // %YAML Objects cannot be streamed, so we need to reinitialize them here.
1038 
1039  if (fForceBeamType == kpp)
1040  fNcentBins = 1;
1041 
1042  // Allow for output files
1043  OpenFile(1);
1044  fOutput = new TList();
1045  fOutput->SetOwner();
1046 
1048 
1049  PostData(1, fOutput);
1050 }
1051 
1059 {
1060  // Run the initialization for all derived classes.
1061  for (auto component : fCorrectionComponents)
1062  {
1063  // Set cent bins (usually used for hist creation)
1064  // It cannot be set until now because it can be changed after initialization
1065  // For instance, by SetForceBeamType()
1066  component->SetNcentralityBins(fNcentBins);
1067 
1068  component->UserCreateOutputObjects();
1069 
1070  if (component->GetOutputList() != 0)
1071  {
1072  // Adds a list to the list -- this doesn't work for some unknown reason
1073  //fOutput->Add(component->GetOutputList());
1074 
1075  // iterate through lists for each component, and fill in output
1076  TList* t = new TList();
1077  t->SetName(component->GetName());
1078  fOutput->AddLast(t);
1079  t = (TList*)fOutput->Last();
1080  TIter next(component->GetOutputList());
1081  while (TObject *obj = next()){
1082  t->Add(obj);
1083  }
1084 
1085  AliDebug(1, TString::Format("Added output list from task %s to output.", component->GetName()));
1086  }
1087  }
1088 }
1089 
1095 {
1096  // Recycle embedded events which do not pass the internal event selection in the embedding helper
1098  auto embeddingHelper = AliAnalysisTaskEmcalEmbeddingHelper::GetInstance();
1099  if (embeddingHelper && embeddingHelper->EmbeddedEventUsed() == false) {
1100  AliDebugStream(4) << "Embedding helper rejected the internal event. Skipping this event.\n";
1101  return;
1102  }
1103  }
1104 
1105  // Initialize the event if not initialized
1106  if (!fEventInitialized)
1107  ExecOnce();
1108 
1109  // Only continue if we are initialized successfully
1110  if (!fEventInitialized)
1111  return;
1112 
1113  // Get the objects for each event
1114  if (!RetrieveEventObjects())
1115  return;
1116 
1117  // Call run for each correction
1118  if (!Run())
1119  return;
1120 }
1121 
1133 {
1134  if (!InputEvent()) {
1135  AliError("Could not retrieve event! Returning!");
1136  return;
1137  }
1138 
1139  // This warning was extracted out from the cell components
1140  if (dynamic_cast<AliAODEvent*>(InputEvent())) {
1141  AliWarning("=============================================================");
1142  AliWarning("=== Running on AOD is not equivalent to running on ESD! ===");
1143  AliWarning("=============================================================");
1144  }
1145 
1146  if (fNeedEmcalGeom) {
1147  fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(InputEvent()->GetRunNumber());
1148  if (!fGeom) {
1149  AliFatal("Can not get EMCal geometry instance. If you do not need the EMCal geometry, disable it by setting task->SetNeedEmcalGeometry(kFALSE).");
1150  return;
1151  }
1152  }
1153 
1154  // Load all requested track branches - each container knows name already
1155  for (Int_t i =0; i<fParticleCollArray.GetEntriesFast(); i++) {
1156  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
1158  cont->SetArray(InputEvent());
1159  }
1160 
1161  // Load all requested cluster branches - each container knows name already
1162  for (Int_t i =0; i<fClusterCollArray.GetEntriesFast(); i++) {
1163  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
1165  cont->SetArray(InputEvent());
1166  }
1167 
1168  // Determine the proper pointer for each cell object and save them to the cell container
1169  // At this point, they should all be created
1170  for (auto cellObj : fCellCollArray)
1171  {
1173  }
1174 
1175  fEventInitialized = kTRUE;
1176 
1177  // Print warning to the user that the rest of the configuration information is available in the generation log
1178  // when the Analysis Manager was created. Using cout to be certain that it is shown on the train!
1179  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";
1180 
1181  // Setup the components
1183 }
1184 
1190 {
1191  // Run the initialization for all derived classes.
1192  for (auto component : fCorrectionComponents)
1193  {
1194  // Setup geometry
1195  component->SetEMCALGeometry(fGeom);
1196 
1197  // Add the requested cells to the component
1199 
1200  // Set the input events. This is redundant to where it is set during Run(), but the events need to be
1201  // available to components, and they are only called one extra time.
1202  component->SetInputEvent(InputEvent());
1203  component->SetMCEvent(MCEvent());
1204 
1205  // Component ExecOnce()
1206  component->ExecOnce();
1207 
1208  // If the cells were created during ExecOnce(), then we need to re-initialize the pointer to ensure
1209  // that it is not null!
1210  if (!(component->GetCaloCells())) {
1211  AliDebugStream(2) << "Re-initializing cells for component " << component->GetName() << std::endl;
1213  }
1214  }
1215 }
1216 
1222 {
1223  fVertex[0] = 0;
1224  fVertex[1] = 0;
1225  fVertex[2] = 0;
1226  fNVertCont = 0;
1227 
1228  const AliVVertex *vert = InputEvent()->GetPrimaryVertex();
1229  if (vert) {
1230  vert->GetXYZ(fVertex);
1231  fNVertCont = vert->GetNContributors();
1232  }
1233 
1234  fBeamType = GetBeamType();
1235 
1236  if (fBeamType == kAA || fBeamType == kpA ) {
1238  AliMultSelection *MultSelection = static_cast<AliMultSelection*>(InputEvent()->FindListObject("MultSelection"));
1239  if (MultSelection) {
1240  fCent = MultSelection->GetMultiplicityPercentile(fCentEst.Data());
1241  }
1242  else {
1243  AliWarning("Could not retrieve centrality information! Assuming 99");
1244  }
1245  }
1246  else { // old centrality estimation < 2015
1247  AliCentrality *aliCent = InputEvent()->GetCentrality();
1248  if (aliCent) {
1249  fCent = aliCent->GetCentralityPercentile(fCentEst.Data());
1250  }
1251  else {
1252  AliWarning("Could not retrieve centrality information! Assuming 99");
1253  }
1254  }
1255 
1256  if (fNcentBins==4) {
1257  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1258  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1259  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1260  else if (fCent >= 50 && fCent <= 100) fCentBin = 3;
1261  else {
1262  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1263  fCentBin = fNcentBins-1;
1264  }
1265  }
1266  else if (fNcentBins==5) { // for PbPb 2015
1267  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1268  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1269  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1270  else if (fCent >= 50 && fCent <= 90) fCentBin = 3;
1271  else if (fCent > 90) {
1272  fCent = 99;
1273  fCentBin = 4;
1274  }
1275  else {
1276  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1277  fCentBin = fNcentBins-1;
1278  }
1279  }
1280  else {
1281  Double_t centWidth = (fMaxCent-fMinCent)/(Double_t)fNcentBins;
1282  if(centWidth>0.) {
1283  fCentBin = TMath::FloorNint(fCent/centWidth);
1284  }
1285  else {
1286  fCentBin = 0;
1287  }
1288  if (fCentBin>=fNcentBins) {
1289  AliWarning(Form("fCentBin too large: cent = %f fCentBin = %d. Assuming 99", fCent, fCentBin));
1290  fCentBin = fNcentBins-1;
1291  }
1292  }
1293  }
1294  else {
1295  fCent = 99;
1296  fCentBin = 0;
1297  }
1298 
1299  AliEmcalContainer* cont = 0;
1300 
1301  TIter nextPartColl(&fParticleCollArray);
1302  while ((cont = static_cast<AliEmcalContainer*>(nextPartColl()))) cont->NextEvent(InputEvent());
1303 
1304  TIter nextClusColl(&fClusterCollArray);
1305  while ((cont = static_cast<AliEmcalContainer*>(nextClusColl()))) cont->NextEvent(InputEvent());
1306 
1307  return kTRUE;
1308 }
1309 
1315 {
1316  // Run the initialization for all derived classes.
1317  for (auto component : fCorrectionComponents)
1318  {
1319  component->SetInputEvent(InputEvent());
1320  component->SetMCEvent(MCEvent());
1321  component->SetCentralityBin(fCentBin);
1322  component->SetCentrality(fCent);
1323  component->SetVertex(fVertex);
1324 
1325  component->Run();
1326  }
1327 
1328  PostData(1, fOutput);
1329 
1330  return kTRUE;
1331 }
1332 
1337 {
1338  // Run the initialization for all derived classes.
1339  for (auto component : fCorrectionComponents)
1340  {
1341  component->UserNotify();
1342  }
1343 
1344  return kTRUE;
1345 }
1346 
1353 std::ostream & AliEmcalCorrectionTask::PrintConfiguration(std::ostream & in, bool userConfig) const
1354 {
1355  std::string configurationName = userConfig ? "user" : "default";
1356  if (fYAMLConfig.DoesConfigurationExist(configurationName)) {
1357  auto configPair = fYAMLConfig.GetConfiguration(configurationName);
1358  if (configPair.second.IsNull() == true) {
1359  AliWarning(TString::Format("%s configuration is empty!", configPair.first.c_str()));
1360  }
1361  in << configPair.second;
1362  }
1363  else {
1364  in << "Configuration \"" << configurationName << "\" does not exist!\n";
1365  }
1366 
1367  return in;
1368 }
1369 
1377 bool AliEmcalCorrectionTask::WriteConfigurationFile(std::string filename, bool userConfig) const
1378 {
1379  return fYAMLConfig.WriteConfiguration(filename, userConfig ? "user" : "default");
1380 }
1381 
1391 {
1392  // Setup
1393  // It's important to reinitialize the configuration so the %YAML nodes are defined!
1395  std::string tempConfigName = "tempConfig";
1396  fYAMLConfig.AddConfiguration(filename, tempConfigName);
1397 
1398  // Compare
1399  bool returnValue = fYAMLConfig.CompareConfigurations(tempConfigName, userConfig ? "user" : "default");
1400 
1401  // Cleanup
1402  fYAMLConfig.RemoveConfiguration(tempConfigName);
1403 
1404  return returnValue;
1405 }
1406 
1414 {
1415  AliDebugStream(2) << "Retrieving cells object " << cellContainer->GetName() << std::endl;
1416  // Check for embedding and return object
1417  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cellContainer->GetIsEmbedding());
1418 
1419  cellContainer->SetCells(dynamic_cast<AliVCaloCells *>(event->FindListObject(cellContainer->GetBranchName().c_str())));
1420 }
1421 
1432 {
1433  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cont->GetIsEmbedding());
1434 
1435  TClonesArray * array = dynamic_cast<TClonesArray *>(event->FindListObject(cont->GetArrayName()));
1436  if (!array) {
1437  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()));
1438  array = new TClonesArray(AliEmcalContainerUtils::DetermineUseDefaultName(objectType, fIsEsd, true).c_str());
1439  array->SetName(cont->GetArrayName());
1440  event->AddObject(array);
1441  }
1442 }
1443 
1452 {
1453  // Get container node
1454  std::string inputObjectName = "";
1455  if (inputObjectType == AliEmcalContainerUtils::kCluster) {
1456  inputObjectName = "clusterContainers";
1457  }
1458  else if (inputObjectType == AliEmcalContainerUtils::kTrack) {
1459  inputObjectName = "trackContainers";
1460  }
1461  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1462  inputObjectName = "cells";
1463  }
1464  else {
1465  AliFatal(TString::Format("Unrecognized input object type %d", inputObjectType));
1466  }
1467 
1468  return inputObjectName;
1469 }
1470 
1482 bool AliEmcalCorrectionTask::CheckPossibleNamesForComponentName(std::string & name, std::set <std::string> & possibleComponents)
1483 {
1484  bool foundComponent = false;
1485  for (auto & possibleComponent : possibleComponents)
1486  {
1487  if (possibleComponent == name) {
1488  foundComponent = true;
1489  break;
1490  }
1491  }
1492 
1493  return foundComponent;
1494 }
1495 
1503 {
1504  if (fForceBeamType != kNA)
1505  return fForceBeamType;
1506 
1507  AliESDEvent *esd = dynamic_cast<AliESDEvent*>(InputEvent());
1508  if (esd) {
1509  const AliESDRun *run = esd->GetESDRun();
1510  TString beamType = run->GetBeamType();
1511  if (beamType == "p-p")
1512  return kpp;
1513  else if (beamType == "A-A")
1514  return kAA;
1515  else if (beamType == "p-A")
1516  return kpA;
1517  else
1518  return kNA;
1519  } else {
1520  Int_t runNumber = InputEvent()->GetRunNumber();
1521  // All run number ranges taken from the RCT
1522  if ((runNumber >= 136833 && runNumber <= 139517) || // LHC10h
1523  (runNumber >= 167693 && runNumber <= 170593) || // LHC11h
1524  (runNumber >= 244824 && runNumber <= 246994)) { // LHC15o
1525  return kAA;
1526  } else if ((runNumber >= 188356 && runNumber <= 188366) || // LHC12g
1527  (runNumber >= 195164 && runNumber <= 197388) || // LHC13b-f
1528  (runNumber >= 265015 && runNumber <= 267166)) { // LHC16q-t
1529  return kpA;
1530  } else {
1531  return kpp;
1532  }
1533  }
1534 }
1535 
1540 {
1541  if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1542  stream << "Cells info: " << std::endl;
1543  for (auto cellInfo : fCellCollArray) {
1544  stream << "\tName: " << cellInfo->GetName() << "\tBranch: " << cellInfo->GetBranchName() << "\tIsEmbedding: " << std::boolalpha << cellInfo->GetIsEmbedding() << std::endl;
1545  }
1546  }
1547  else if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
1548  stream << (inputObjectType == AliEmcalContainerUtils::kCluster ? "Cluster" : "Track") << " container info: " << std::endl;
1549  AliEmcalContainer * cont = 0;
1550  for (auto containerInfo : (inputObjectType == AliEmcalContainerUtils::kCluster ? fClusterCollArray : fParticleCollArray) ) {
1551  cont = static_cast<AliEmcalContainer *>(containerInfo);
1552  stream << "\tName: " << cont->GetName() << "\tBranch: " << cont->GetArrayName() << "\tTitle: " << cont->GetTitle() << "\tIsEmbedding: " << std::boolalpha << cont->GetIsEmbedding() << std::endl;
1553  }
1554  }
1555  else {
1556  AliErrorStream() << "Unrecognized input object type " << inputObjectType << std::endl;
1557  }
1558 }
1559 
1573 void AliEmcalCorrectionTask::GetPropertyNamesFromNode(const std::string configurationName, const std::string componentName, std::set <std::string> & propertyNames, const bool nodeRequired)
1574 {
1575  bool retrievedPropertyNames = false;
1576  if (fYAMLConfig.DoesConfigurationExist(configurationName)) {
1577  AliDebugStream(3) << "Looking for nodes in component \"" << componentName << "\" in the \"" << configurationName << "\" configuration\n";
1578  auto configPair = fYAMLConfig.GetConfiguration(configurationName);
1579  if (configPair.second[componentName])
1580  {
1581  for (auto propertyName : configPair.second[componentName])
1582  {
1583  AliDebugStream(4) << "Node property name " << propertyName.first.as<std::string>() << "\n";
1584  propertyNames.insert(propertyName.first.as<std::string>());
1585  }
1586  retrievedPropertyNames = true;
1587  }
1588  }
1589 
1590  if (retrievedPropertyNames == false && nodeRequired) {
1591  std::stringstream message;
1592  message << "Failed to retrieve required property \""
1593  << componentName << "\" from the \"" << configurationName << "\" configuration!" << std::endl;
1594  AliFatal(message.str().c_str());
1595  }
1596 }
1597 
1607 {
1608  AliEmcalCorrectionComponent * returnComponent = nullptr;
1609  for (auto component : fCorrectionComponents)
1610  {
1611  if (name == component->GetName()) {
1612  returnComponent = component;
1613  break;
1614  }
1615  }
1616  return returnComponent;
1617 }
1618 
1626 AliEmcalCorrectionCellContainer * AliEmcalCorrectionTask::GetCellContainer(const std::string & cellsContainerName) const
1627 {
1628  for (auto cellContainer : fCellCollArray)
1629  {
1630  if (cellContainer->GetName() == cellsContainerName) {
1631  return cellContainer;
1632  }
1633  }
1634 
1635  return 0;
1636 }
1637 
1639 {
1640  // Get the pointer to the existing analysis manager via the static access method.
1641  //==============================================================================
1642  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1643  if (!mgr)
1644  {
1645  ::Error("AddTaskEmcalCorrectionTask", "No analysis manager to connect to.");
1646  return nullptr;
1647  }
1648 
1649  // Check the analysis type using the event handlers connected to the analysis manager.
1650  //==============================================================================
1651  AliVEventHandler* handler = mgr->GetInputEventHandler();
1652  if (!handler)
1653  {
1654  ::Error("AddTaskEmcalCorrectionTask", "This task requires an input event handler");
1655  return nullptr;
1656  }
1657 
1658  TString name = "AliEmcalCorrectionTask";
1659  if (suffix != "") {
1660  name += TString::Format("_%s", suffix.Data());
1661  }
1662 
1663  AliEmcalCorrectionTask* mgrTask = static_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.Data()));
1664  if (mgrTask) return mgrTask;
1665 
1666  // Create the task that manages the corrections
1667  AliEmcalCorrectionTask* correctionTask = new AliEmcalCorrectionTask(name.Data());
1668 
1669  //-------------------------------------------------------
1670  // Final settings, pass to manager and set the containers
1671  //-------------------------------------------------------
1672 
1673  mgr->AddTask(correctionTask);
1674 
1675  // Create containers for input/output
1676  AliAnalysisDataContainer* cInput = mgr->GetCommonInputContainer();
1677 
1678  TString outputContainerName(name);
1679  outputContainerName += "_histos";
1680 
1681  AliAnalysisDataContainer * cOutput = mgr->CreateContainer(outputContainerName.Data(),
1682  TList::Class(),
1683  AliAnalysisManager::kOutputContainer,
1684  Form("%s", AliAnalysisManager::GetCommonFileName()));
1685 
1686  mgr->ConnectInput(correctionTask, 0, cInput);
1687  mgr->ConnectOutput(correctionTask, 1, cOutput);
1688 
1689  //TObjArray* cnt = mgr->GetContainers();
1690 
1691  return correctionTask;
1692 }
1693 
1695 {
1696  // Get the pointer to the existing analysis manager via the static access method.
1697  //==============================================================================
1698  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1699  if (!mgr)
1700  {
1701  ::Error("ConfigureEmcalCorrectionTaskOnLEGOTrain", "No analysis manager to connect to.");
1702  return nullptr;
1703  }
1704 
1705  // Find the correction task
1706  AliEmcalCorrectionTask * correctionTask = nullptr;
1707  const std::string taskName = "AliEmcalCorrectionTask";
1708  std::string foundTaskName = "";
1709  bool taskFound = false;
1710  std::vector<std::string> namesToSearch = {taskName};
1711 
1712  // Determine if the suffix name should be searched for.
1713  // If a suffix is given, it will be looked for first, followed by the generically named task.
1714  // This way, a user's configuration can be uniquely identified in the case of multiple correction tasks, but
1715  // if there is only one correction task without a suffix, this method will still fall back to that one and
1716  // return a correction task to be configured.
1717  if (suffix != "")
1718  {
1719  std::string suffixName = taskName;
1720  suffixName += "_";
1721  suffixName += suffix.Data();
1722  namesToSearch.insert(namesToSearch.begin(), suffixName);
1723  }
1724 
1725  // Attempt to retrieve the task from the analysis manager
1726  for (auto name : namesToSearch)
1727  {
1728  correctionTask = dynamic_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.c_str()));
1729  if (correctionTask != nullptr) {
1730  taskFound = true;
1731  foundTaskName = name;
1732  break;
1733  }
1734  }
1735 
1736  // Fatal if we can't find the task
1737  if (taskFound == false) {
1738  AliFatalClassF("Could not find correction task, checking for both the suffix \"%s\" and the main task. Did you remember to create it?", suffix.Data());
1739  }
1740 
1741  AliInfoClassStream() << "Found correction task named \"" << foundTaskName <<"\" to configure.\n";
1742 
1743  // AliAnalysisTaskCfg will require a task to be returned, so we add a dummy task to the analysis manager,
1744  // which will be removed when the user calls Initialize(true) on the correction task.
1745  std::string dummyTaskName = foundTaskName + "_dummyTask";
1746  mgr->AddTask(new AliAnalysisTaskSE(dummyTaskName.c_str()));
1747 
1748  return correctionTask;
1749 }
1750 
1756 std::string AliEmcalCorrectionTask::toString(bool includeYAMLConfigurationInfo) const
1757 {
1758  std::stringstream tempSS;
1759 
1760  // Show the correction components
1761  tempSS << "Correction components:\n";
1762  for (auto component : fOrderedComponentsToExecute) {
1763  tempSS << "\t" << component << "\n";
1764  }
1765  // Input objects
1766  tempSS << "\nInput objects:\n";
1770 
1771  if (includeYAMLConfigurationInfo == true) {
1772  tempSS << "\nUser Configuration:\n";
1773  PrintConfiguration(tempSS, true);
1774  tempSS << "\n\nDefault Configuration:\n";
1775  PrintConfiguration(tempSS);
1776  tempSS << "\n";
1777  }
1778 
1779  return tempSS.str();
1780 }
1781 
1788 std::ostream & AliEmcalCorrectionTask::Print(std::ostream & in) const {
1789  in << toString();
1790  return in;
1791 }
1792 
1800 std::ostream & operator<<(std::ostream & in, const AliEmcalCorrectionTask & myTask)
1801 {
1802  std::ostream & result = myTask.Print(in);
1803  return result;
1804 }
1805 
1813 {
1814  std::string temp(opt);
1815  bool includeYAMLConfig = false;
1816  if (temp == "YAML") {
1817  includeYAMLConfig = true;
1818  }
1819  Printf("%s", toString(includeYAMLConfig).c_str());
1820 }
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
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