AliPhysics  50c46fc (50c46fc)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliEmcalCorrectionTask.cxx
Go to the documentation of this file.
1 // AliEmcalCorrectionTask
2 //
3 // Runs the cell and cluster level corrections for the EMCal
4 //
5 
8 
9 #include <vector>
10 #include <set>
11 #include <fstream>
12 #include <sstream>
13 #include <iostream>
14 #include <algorithm>
15 
16 #include <TChain.h>
17 #include <TSystem.h>
18 #include <TGrid.h>
19 #include <TFile.h>
20 #include <TUUID.h>
21 
22 #include "AliVEventHandler.h"
23 #include "AliEMCALGeometry.h"
24 #include "AliVCaloCells.h"
25 #include "AliVCluster.h"
26 #include "AliLog.h"
27 #include "AliMultSelection.h"
28 #include "AliCentrality.h"
29 #include "AliESDEvent.h"
30 #include "AliAnalysisManager.h"
31 #include "AliAODEvent.h"
32 
34 
36 ClassImp(AliEmcalCorrectionTask);
38 
42 
43 const std::map <std::string, AliVCluster::VCluUserDefEnergy_t> AliEmcalCorrectionTask::fgkClusterEnergyTypeMap = {
44  {"kNonLinCorr", AliVCluster::kNonLinCorr },
45  {"kHadCorr", AliVCluster::kHadCorr },
46  {"kUserDefEnergy1", AliVCluster::kUserDefEnergy1 },
47  {"kUserDefEnergy2", AliVCluster::kUserDefEnergy2 }
48 };
49 
50 const std::map <std::string, AliEmcalTrackSelection::ETrackFilterType_t> AliEmcalCorrectionTask::fgkTrackFilterTypeMap = {
51  {"kNoTrackFilter", AliEmcalTrackSelection::kNoTrackFilter },
52  {"kCustomTrackFilter", AliEmcalTrackSelection::kCustomTrackFilter },
53  {"kHybridTracks", AliEmcalTrackSelection::kHybridTracks },
54  {"kTPCOnlyTracks", AliEmcalTrackSelection::kTPCOnlyTracks }
55 };
56 
61  AliAnalysisTaskSE("AliEmcalCorrectionTask"),
62  fUserConfiguration(),
63  fDefaultConfiguration(),
64  fSuffix(""),
65  fUserConfigurationString(""),
66  fDefaultConfigurationString(""),
67  fUserConfigurationFilename(""),
68  fDefaultConfigurationFilename(""),
69  fOrderedComponentsToExecute(),
70  fCorrectionComponents(),
71  fConfigurationInitialized(false),
72  fIsEsd(false),
73  fEventInitialized(false),
74  fCent(0),
75  fCentBin(-1),
76  fMinCent(-999),
77  fMaxCent(-999),
78  fNcentBins(4),
79  fCentEst("V0M"),
80  fUseNewCentralityEstimation(kFALSE),
81  fVertex{0},
82  fNVertCont(0),
83  fBeamType(kNA),
84  fForceBeamType(kNA),
85  fNeedEmcalGeom(kTRUE),
86  fGeom(0),
87  fParticleCollArray(),
88  fClusterCollArray(),
89  fCellCollArray(),
90  fOutput(0)
91 {
92  // Default constructor
93  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
94 
95  fParticleCollArray.SetOwner(kTRUE);
96  fClusterCollArray.SetOwner(kTRUE);
97 }
98 
109  AliAnalysisTaskSE(name),
110  fUserConfiguration(),
111  fDefaultConfiguration(),
112  fSuffix(""),
113  fUserConfigurationString(""),
114  fDefaultConfigurationString(""),
115  fUserConfigurationFilename(""),
116  fDefaultConfigurationFilename(""),
117  fOrderedComponentsToExecute(),
118  fCorrectionComponents(),
119  fConfigurationInitialized(false),
120  fIsEsd(false),
121  fEventInitialized(false),
122  fCent(0),
123  fCentBin(-1),
124  fMinCent(-999),
125  fMaxCent(-999),
126  fNcentBins(4),
127  fCentEst("V0M"),
128  fUseNewCentralityEstimation(kFALSE),
129  fVertex{0},
130  fNVertCont(0),
131  fBeamType(kNA),
132  fForceBeamType(kNA),
133  fNeedEmcalGeom(kTRUE),
134  fGeom(0),
135  fParticleCollArray(),
136  fClusterCollArray(),
137  fCellCollArray(),
138  fOutput(0)
139 {
140  // Standard constructor
141  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
142 
143  fParticleCollArray.SetOwner(kTRUE);
144  fClusterCollArray.SetOwner(kTRUE);
145 
146  DefineInput(0, TChain::Class());
147  DefineOutput(1, TList::Class());
148 }
149 
158  fUserConfiguration(task.fUserConfiguration),
159  fDefaultConfiguration(task.fDefaultConfiguration),
160  fSuffix(task.fSuffix),
161  fUserConfigurationString(task.fUserConfigurationString),
162  fDefaultConfigurationString(task.fDefaultConfigurationString),
163  fUserConfigurationFilename(task.fUserConfigurationFilename),
164  fDefaultConfigurationFilename(task.fDefaultConfigurationFilename),
165  fOrderedComponentsToExecute(task.fOrderedComponentsToExecute),
166  fCorrectionComponents(task.fCorrectionComponents), // TODO: These should be copied!
167  fConfigurationInitialized(task.fConfigurationInitialized),
168  fIsEsd(task.fIsEsd),
169  fEventInitialized(task.fEventInitialized),
170  fCent(task.fCent),
171  fCentBin(task.fCentBin),
172  fMinCent(task.fMinCent),
173  fMaxCent(task.fMaxCent),
174  fNcentBins(task.fNcentBins),
175  fCentEst(task.fCentEst),
176  fUseNewCentralityEstimation(task.fUseNewCentralityEstimation),
177  fVertex{0.},
178  fNVertCont(task.fNVertCont),
179  fBeamType(task.fBeamType),
180  fForceBeamType(task.fForceBeamType),
181  fNeedEmcalGeom(task.fNeedEmcalGeom),
182  fGeom(task.fGeom),
183  fParticleCollArray(*(static_cast<TObjArray *>(task.fParticleCollArray.Clone()))),
184  fClusterCollArray(*(static_cast<TObjArray *>(task.fClusterCollArray.Clone()))),
185  fOutput(task.fOutput) // TODO: More care is needed here!
186 {
187  // Vertex position
188  std::copy(std::begin(task.fVertex), std::end(task.fVertex), std::begin(fVertex));
189 
190  // Cell Collections
191  for (auto cellCont : task.fCellCollArray)
192  {
193  fCellCollArray.push_back(new AliEmcalCorrectionCellContainer(*cellCont));
194  }
195 }
196 
202 {
203  swap(*this, other);
204 }
205 
211 {
212  swap(*this, other);
213 
214  return *this;
215 }
216 
221 {
222  using std::swap;
223 
226  swap(first.fSuffix, second.fSuffix);
234  swap(first.fIsEsd, second.fIsEsd);
236  swap(first.fCent, second.fCent);
237  swap(first.fCentBin, second.fCentBin);
238  swap(first.fMinCent, second.fMinCent);
239  swap(first.fMaxCent, second.fMaxCent);
240  swap(first.fNcentBins, second.fNcentBins);
241  swap(first.fCentEst, second.fCentEst);
243  swap(first.fVertex, second.fVertex);
244  swap(first.fNVertCont, second.fNVertCont);
245  swap(first.fBeamType, second.fBeamType);
246  swap(first.fForceBeamType, second.fForceBeamType);
247  swap(first.fNeedEmcalGeom, second.fNeedEmcalGeom);
248  swap(first.fGeom, second.fGeom);
251  swap(first.fCellCollArray, second.fCellCollArray);
252  swap(first.fOutput, second.fOutput);
253 }
254 
260 {
261  // Destructor
262 }
263 
273 {
274  // Determine file type
275  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
276  if (mgr) {
277  AliVEventHandler *evhand = mgr->GetInputEventHandler();
278  if (evhand) {
279  if (evhand->InheritsFrom("AliESDInputHandler")) {
280  fIsEsd = true;
281  }
282  else {
283  fIsEsd = false;
284  }
285  }
286  else {
287  AliError("Event handler not found!");
288  }
289  }
290  else {
291  AliError("Analysis manager not found!");
292  }
293 
294  // Determine the suffix of the correction task
295  std::string tempName = GetName();
296  std::size_t foundSuffix = tempName.find("_");
297  if (foundSuffix != std::string::npos) {
298  // +1 to skip "_"
299  fSuffix = tempName.substr(foundSuffix + 1).c_str();
300  }
301 
302  if (fSuffix != "") {
303  AliInfoStream() << "Initializing correction task with suffix \"" << fSuffix << "\"" << std::endl;
304  }
305 
306  // Initialize YAML configuration
308  // Check that the configuration is initialized
309  if (fConfigurationInitialized != true)
310  {
311  AliFatal("YAML configuration must be initialized before running (ie. in the run macro or wagon)!");
312  }
313 
314  // Determine component execution order
316 
317  // Check for user defined settings that are not in the default file
319 
320  // Setup input objects
321  // Setup Cells
322  // Cannot do this entirely yet because we need input objects
325  // Create cluster input objects
328  // Create track input objects
331 
332  // Initialize components
334 
335  // Print the results of the initialization
336  // Print outside of the ALICE Log system to ensure that it is always available!
337  std::cout << GetName() << " Settings:\n" << *this;
338 }
339 
349 {
350  // Determine file path
352  {
353  // Use the default if nothing is set
354  fDefaultConfigurationFilename = "$ALICE_PHYSICS/PWG/EMCAL/config/AliEmcalCorrectionConfiguration.yaml";
355  }
356 
357  // Setup the YAML files
358  // Default
360 
362  {
363  AliInfo(TString::Format("Using default EMCal corrections configuration located at %s", fDefaultConfigurationFilename.c_str()));
364 
366  // Check for valid file
367  if (fDefaultConfiguration.IsNull() == true)
368  {
369  AliFatal(TString::Format("Could not open the default configuration file \"%s\"!", fDefaultConfigurationFilename.c_str()));
370  }
371  }
372  else
373  {
374  AliFatal(TString::Format("Default file located at \"%s\" does not exist!", fDefaultConfigurationFilename.c_str()));
375  }
376 
377  // User
379 
381  {
382  AliInfo(TString::Format("Using user EMCal corrections configuration located at %s", fUserConfigurationFilename.c_str()));
383 
385  }
386  else
387  {
388  AliInfo(TString::Format("User file at \"%s\" does not exist! All settings will be from the default file!", fUserConfigurationFilename.c_str()));
389  }
390 
391  // Save configuration into strings so that they can be streamed
392  // Need the stringstream because YAML implements streamers
393  std::stringstream tempConfiguration;
394  tempConfiguration << fUserConfiguration;
395  fUserConfigurationString = tempConfiguration.str();
396  tempConfiguration.str("");
397  tempConfiguration << fDefaultConfiguration;
398  fDefaultConfigurationString = tempConfiguration.str();
399 
400  //AliInfo(TString::Format("User configuration: %s", fUserConfigurationString.c_str()));
401  //AliInfo(TString::Format("Default configuration: %s", fDefaultConfigurationString.c_str()));
402 
403  // Note that it is initialized properly so that the analysis can proceed
405 }
406 
417 void AliEmcalCorrectionTask::DetermineComponentsToExecute(std::vector <std::string> & correctionComponents)
418 {
419  std::vector <std::string> executionOrder;
420  // executionOrder determines the order of tasks to execute, but it doesn't name the particular tasks
422 
423  // Possible components to create from both the user and default configurations
424  // Use set so that the possible components are not repeated
425  std::set <std::string> possibleComponents;
426  for (auto node : fUserConfiguration) {
427  possibleComponents.insert(node.first.as<std::string>());
428  }
429  for (auto node : fDefaultConfiguration) {
430  possibleComponents.insert(node.first.as<std::string>());
431  }
432 
433  // Determine the correction names associated with the correction task
434  std::string expectedComponentName = "";
435  bool foundSuffixComponent = false;
436  bool foundComponent = false;
437  bool componentEnabled = true;
438 
439  // Execution order determines the order that corrections should be added to our execution list
440  for (auto & execName : executionOrder)
441  {
442  // Construct the expected component name with the suffix
443  expectedComponentName = TString::Format("%s_%s", execName.c_str(), fSuffix.c_str()).Data();
444  foundComponent = false;
445  componentEnabled = false;
446 
447  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
448  if (foundComponent)
449  {
450  // Check if the component is enabled
451  AliEmcalCorrectionComponent::GetProperty("enabled", componentEnabled, fUserConfiguration, fDefaultConfiguration, true, expectedComponentName);
452  // If enabled, then store the name so that it can be executed
453  if (componentEnabled == true) {
454  foundSuffixComponent = true;
455  correctionComponents.push_back(expectedComponentName);
456  }
457  else {
458  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
459  }
460 
461  continue;
462  }
463  else
464  {
465  // Look for the normal component
466  expectedComponentName = execName;
467  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
468  // Check if it is enabled
469  AliEmcalCorrectionComponent::GetProperty("enabled", componentEnabled, fUserConfiguration, fDefaultConfiguration, true, expectedComponentName);
470 
471  if (componentEnabled == true) {
472  if (foundSuffixComponent == true) {
473  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()));
474  }
475  else {
476  // Take the normal component and store it to be executed
477  correctionComponents.push_back(expectedComponentName);
478  }
479  }
480  else {
481  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
482  }
483  }
484  }
485 
486  // Need to append "AliEmcalCorrection" to allow the tasks to be found!
487  AliDebug(2, "Found EMCal Correction Components: ");
488  for (auto & component : correctionComponents)
489  {
490  component = "AliEmcalCorrection" + component;
491  AliDebug(2, TString::Format("%s", component.c_str()) );
492  }
493 }
494 
508 {
509  // Names of properties for a particular component in the user and default configurations
510  std::set <std::string> userPropertyNames;
511  std::set <std::string> defaultPropertyNames;
512  // Notes whether a match was found between user and default properties
513  bool foundMatch = false;
514  std::string tempComponentName = "";
515 
516  // Loop over all components
517  for (const auto componentName : fOrderedComponentsToExecute)
518  {
519  // Reset for each loop
520  userPropertyNames.clear();
521  defaultPropertyNames.clear();
522  // We need to remove "AliEmcalCorrection" so that the correction will be found in the configuration
523  // "AliEmcalCorrection" is 18 characters
524  tempComponentName = componentName.substr(componentName.find("AliEmcalCorrection")+18);
525 
526  AliDebugStream(2) << "Checking component " << componentName << " for unmatched user settings" << std::endl;
527 
528  // Get the user property names
529  GetPropertyNamesFromNode(tempComponentName, fUserConfiguration, userPropertyNames, false);
530 
531  // Get the same from default
532  // Not required here because the default configuration may not have the specialized component
533  GetPropertyNamesFromNode(tempComponentName, fDefaultConfiguration, defaultPropertyNames, false);
534 
535  // We need to check the base correction as well to fill out the options
536  if (tempComponentName.find("_") != std::string::npos) {
537  // Get the base user component
538  GetPropertyNamesFromNode(tempComponentName.substr(0, tempComponentName.find("_")), fUserConfiguration, userPropertyNames, false);
539 
540  // Required here because the default must have the base component!
541  GetPropertyNamesFromNode(tempComponentName.substr(0, tempComponentName.find("_")), fDefaultConfiguration, defaultPropertyNames, true);
542  }
543 
544  // Check each property defined in the user file for a match to the properties in the default file
545  for (auto userPropertyName : userPropertyNames)
546  {
547  AliDebugStream(2) << "Checking property " << userPropertyName << std::endl;
548  foundMatch = false;
549  for (auto defaultPropertyName : defaultPropertyNames)
550  {
551  if (userPropertyName == defaultPropertyName) {
552  AliDebugStream(2) << "Found match of " << userPropertyName << " with " << defaultPropertyName << std::endl;
553  foundMatch = true;
554  }
555  }
556  if (foundMatch == false) {
557  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()));
558  }
559  }
560  }
561 }
562 
570 {
571  // Iterate over the ordered components list and create the components
572  AliEmcalCorrectionComponent * component = 0;
573  for (auto componentName : fOrderedComponentsToExecute)
574  {
575  std::string noPrefixComponentName = componentName.substr(0, componentName.find("_" + fSuffix));
576  component = AliEmcalCorrectionComponentFactory::createInstance(noPrefixComponentName);
577  if (!component)
578  {
579  AliFatal(TString::Format("Failed to create requested component %s!", componentName.c_str()));
580  }
581 
582  // For setting names of tasks to differentiate between tasks of the same class
583  component->SetName(componentName.c_str());
584  component->SetTitle(componentName.c_str());
585 
586  // Initialize the YAML configurations in each component
589 
590  // configure needed fields for components to properly initialize
591  component->SetIsESD(fIsEsd);
592 
593  // Add the require containers to the component
594  // Cells must be set during UserExec() because we need to add them as a pointer
597 
598  // Initialize each component
599  bool initialized = component->Initialize();
600 
601  if (component && initialized)
602  {
603  AliInfo(TString::Format("Successfully added correction task: %s", componentName.c_str()));
604  fCorrectionComponents.push_back(component);
605  }
606  }
607 }
608 
624 {
625  // Get container node
626  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
627 
628  // Get the user and default input nodes for the object type
629  YAML::Node userInputObjectNode;
630  YAML::Node defaultInputObjectNode;
631  GetNodeForInputObjects(userInputObjectNode, fUserConfiguration, inputObjectName, false);
632  GetNodeForInputObjects(defaultInputObjectNode, fDefaultConfiguration, inputObjectName, true);
633 
634  AliDebugStream(3) << "userInputObjectNode: " << userInputObjectNode << std::endl;
635  AliDebugStream(3) << "defaultInputObjectNode: " << defaultInputObjectNode << std::endl;
636 
637  // Determine which containers we need based on which are requested by the enabled correction tasks
638  std::set <std::string> requestedContainers;
639  std::vector <std::string> componentRequest;
640  for ( const auto & componentName : fOrderedComponentsToExecute )
641  {
642  componentRequest.clear();
643  // Not required because not all components will have all kinds of containers
644  // "AliEmcalCorrection" is 18 characters
645  AliEmcalCorrectionComponent::GetProperty(inputObjectName + "Names", componentRequest, fUserConfiguration, fDefaultConfiguration, false, componentName.substr(componentName.find("AliEmcalCorrection")+18));
646  for ( auto & req : componentRequest )
647  {
648  AliDebugStream(3) << "Component " << componentName << " requested container name " << req << std::endl;
649  requestedContainers.insert(req);
650  }
651  }
652 
653  AliDebugStream(2) << inputObjectName << " Containers requested by components: " << std::endl;
654  for (auto & str : requestedContainers) {
655  AliDebugStream(2) << "\t" << str << std::endl;;
656  }
657 
658  // Create all requested containers
659  AliDebug(2, TString::Format("Setting up requested containers!"));
660  SetupContainersFromInputNodes(inputObjectType, userInputObjectNode, defaultInputObjectNode, requestedContainers);
661 }
662 
672 {
673  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
674  // Need to be of the form "clusterContainersNames"
675  inputObjectName = inputObjectName + "Names";
676 
677  std::vector <std::string> inputObjects;
678  // Not required, because not all components need Clusters or Tracks
679  AliEmcalCorrectionComponent::GetProperty(inputObjectName.c_str(), inputObjects, fUserConfiguration, fDefaultConfiguration, false, component->GetName());
680 
681  //AliDebugStream(4) << "inputObjects.size(): " << inputObjects.size() << std::endl;
682 
683  // If it is not found, then there will be nothing to iterate over, so we don't need to explicitly check the return value
684  for (auto const & str : inputObjects)
685  {
686  // 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()!
687  if (inputObjectType == AliEmcalContainerUtils::kCluster)
688  {
689  AliEmcalContainer * cont = GetClusterContainer(str.c_str());
690  AliDebugStream(2) << "Adding cluster container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
691 
692  if (checkObjectExists && !cont) {
693  AliError(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
694  }
695  component->AdoptClusterContainer(GetClusterContainer(str.c_str()));
696 
697  // Check that we are using the standard input event
698  if (!(cont->GetIsEmbedding())) {
699  component->SetUsingInputEvent(true);
700  }
701  }
702  else if (inputObjectType == AliEmcalContainerUtils::kTrack)
703  {
704  AliEmcalContainer * cont = GetParticleContainer(str.c_str());
705  AliDebugStream(2) << "Adding particle container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
706 
707  if (checkObjectExists && !cont) {
708  AliFatal(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
709  }
710  component->AdoptParticleContainer(GetParticleContainer(str.c_str()));
711 
712  // Check that we are using the standard input event
713  if (!(cont->GetIsEmbedding())) {
714  component->SetUsingInputEvent(true);
715  }
716  }
717  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells)
718  {
719  // NOTE: This operates different than the others. This should be executed during run time rather than during initialization!
720  if (inputObjects.size() > 1) {
721  AliFatal(TString::Format("Component %s requested more than one cell branch, but this is not supported! Check the configuration!", component->GetName()));
722  }
723 
724  // If we've made it here, this must be at least one entry
726  AliDebugStream(2) << "Adding calo cells \"" << cellCont->GetName() << "\" of branch name \"" << cellCont->GetBranchName() << "\" to component " << component->GetName() << std::endl;
727 
728  if (!(cellCont->GetCells())) {
729  // Attempt to re-initialize the cells.
730  // NOTE: This may not succeed. Adding the container may need to be repeated after the
731  // object is created
733  }
734 
735  if (checkObjectExists && !(cellCont->GetCells())) {
736  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()));
737  }
738 
739  // Set the calo cells (may be null)
740  component->SetCaloCells(cellCont->GetCells());
741 
742  // It is possible that the cells pointer is null because it may not be created yet. For example,
743  // when combining cells. Thus, we must first check whether the pointer is available before checking
744  // for the number of cells. This could potentially decrease the amount of debug information, but this
745  // should rarely be an issue.
746  if (component->GetCaloCells()) {
747  AliDebugStream(3) << "Component GetNumberOfCells: " << component->GetCaloCells()->GetNumberOfCells() << std::endl;
748  }
749 
750  // Check that we are using the standard input event
751  if (!(cellCont->GetIsEmbedding())) {
752  component->SetUsingInputEvent(true);
753  }
754  }
755  }
756 }
757 
766 void AliEmcalCorrectionTask::SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, YAML::Node & userInputObjectNode, YAML::Node & defaultInputObjectNode, std::set <std::string> & requestedContainers)
767 {
768  // Our node contains all of the objects that we will want to create.
769  for(auto & containerName : requestedContainers)
770  {
771  // The section is the container name
772  //std::string containerName = it->first.as<std::string>();
773  // Skip if the particle or cluster container already exists
774  if (GetParticleContainer(containerName.c_str()) || GetClusterContainer(containerName.c_str())) {
775  continue;
776  }
777 
778  AliDebug(2, TString::Format("Processing container %s of inputType %d", containerName.c_str(), inputObjectType));
779  if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
780  SetupContainer(inputObjectType, containerName, userInputObjectNode, defaultInputObjectNode);
781  }
782  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
783  SetupCellsInfo(containerName, userInputObjectNode, defaultInputObjectNode);
784  }
785  }
786 }
787 
798 void AliEmcalCorrectionTask::SetupCellsInfo(std::string containerName, YAML::Node & userNode, YAML::Node & defaultNode)
799 {
800  // Define cell info
802 
803  AliDebugStream(2) << "User: " << std::endl << userNode << std::endl << "default: " << std::endl << defaultNode << std::endl;
804 
805  // Set properties
806  // Cells (object) name
807  cellObj->SetName(containerName);
808  // Branch name
809  std::string tempString = "";
810  AliEmcalCorrectionComponent::GetProperty("branchName", tempString, userNode, defaultNode, true, containerName);
811  if (tempString == "usedefault") {
813  }
814  cellObj->SetBranchName(tempString);
815 
816  // IsEmbedding
817  bool tempBool = false;
818  AliEmcalCorrectionComponent::GetProperty("embedding", tempBool, userNode, defaultNode, false, containerName);
819  cellObj->SetIsEmbedding(tempBool);
820 
821  // Add to the array to keep track of it
822  fCellCollArray.push_back(cellObj);
823 }
824 
842 void AliEmcalCorrectionTask::SetupContainer(AliEmcalContainerUtils::InputObject_t inputObjectType, std::string containerName, YAML::Node & userNode, YAML::Node & defaultNode)
843 {
844  // Create container
845  AliDebugStream(2) << "Adding container" << std::endl;
846  AliEmcalContainer * cont = AddContainer(inputObjectType, containerName, userNode, defaultNode);
847  AliDebugStream(2) << "Added container" << std::endl;
848 
849  // Set the container properties
850  //
851  // TODO: Consider if this can be converted to a map to function pointers. There are a number of details
852  // which can make it a bit complicated. Those details include inheritance, pointing to member
853  // functions, etc. It should all be possible, but may not be worth all of the extra work and code.
854  // Example ccode:
855  // SetValueInContainer("minPt", &cont::SetMinPt, tempDouble, userNode, defaultNode);
856  // SetValueInContainer("minE", &cont::SetMinE, tempDouble, userNode, defaultNode);
857 
858  // Temporary variables to store requested properties
859  std::string tempString = "";
860  Double_t tempDouble = 0;
861  bool tempBool = false;
862 
863  // AliEmcalContainer properties
864  // Min Pt
865  bool result = AliEmcalCorrectionComponent::GetProperty("minPt", tempDouble, userNode, defaultNode, false, containerName);
866  if (result) {
867  AliDebugStream(2) << cont->GetName() << ": Setting minPt of " << tempDouble << std::endl;
868  cont->SetMinPt(tempDouble);
869  }
870  // Min E
871  result = AliEmcalCorrectionComponent::GetProperty("minE", tempDouble, userNode, defaultNode, false, containerName);
872  if (result) {
873  AliDebugStream(2) << cont->GetName() << ": Setting minE of " << tempDouble << std::endl;
874  cont->SetMinE(tempDouble);
875  }
876  // Eta min, max
877  result = AliEmcalCorrectionComponent::GetProperty("minEta", tempDouble, userNode, defaultNode, false, containerName);
878  if (result) {
879  // Only continue checking if the min is there, since we must set both together
880  Double_t tempDouble2 = 0;
881  result = AliEmcalCorrectionComponent::GetProperty("maxEta", tempDouble, userNode, defaultNode, false, containerName);
882  if (result) {
883  AliDebugStream(2) << cont->GetName() << ": Setting eta limits of " << tempDouble << " to " << tempDouble2 << std::endl;
884  cont->SetEtaLimits(tempDouble, tempDouble2);
885  }
886  }
887  // Phi min, max
888  result = AliEmcalCorrectionComponent::GetProperty("minPhi", tempDouble, userNode, defaultNode, false, containerName);
889  if (result) {
890  // Only continue checking if the min is there, since we must set both together
891  Double_t tempDouble2 = 0;
892  result = AliEmcalCorrectionComponent::GetProperty("maxPhi", tempDouble, userNode, defaultNode, false, containerName);
893  if (result) {
894  AliDebugStream(2) << cont->GetName() << ": Setting phi limits of " << tempDouble << " to " << tempDouble2 << std::endl;
895  cont->SetPhiLimits(tempDouble, tempDouble2);
896  }
897  }
898  // Embedded
899  result = AliEmcalCorrectionComponent::GetProperty("embedding", tempBool, userNode, defaultNode, false, containerName);
900  if (result) {
901  AliDebugStream(2) << cont->GetName() << ": Setting embedding to " << (tempBool ? "enabled" : "disabled") << std::endl;
902  cont->SetIsEmbedding(tempBool);
903  }
904 
905  // Cluster specific properties
906  AliClusterContainer * clusterContainer = dynamic_cast<AliClusterContainer *>(cont);
907  if (clusterContainer) {
908  // Default energy
909  // Probably not needed for the corrections
910  /*result = AliEmcalCorrectionComponent::GetProperty("defaultClusterEnergy", tempString, userNode, defaultNode, false, containerName);
911  if (result) {
912  // Need to get the enumeration
913  AliVCluster::VCluUserDefEnergy_t clusterEnergyType = fgkClusterEnergyTypeMap.at(tempString);
914  AliDebugStream(2) << clusterContainer->GetName() << ": Setting cluster energy type to " << clusterEnergyType << std::endl;
915  clusterContainer->SetDefaultClusterEnergy(clusterEnergyType);
916  }*/
917 
918  // NonLinCorrEnergyCut
919  result = AliEmcalCorrectionComponent::GetProperty("clusNonLinCorrEnergyCut", tempDouble, userNode, defaultNode, false, containerName);
920  if (result) {
921  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusNonLinCorrEnergyCut of " << tempDouble << std::endl;
922  clusterContainer->SetClusNonLinCorrEnergyCut(tempDouble);
923  }
924 
925  // HadCorrEnergyCut
926  result = AliEmcalCorrectionComponent::GetProperty("clusHadCorrEnergyCut", tempDouble, userNode, defaultNode, false, containerName);
927  if (result) {
928  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusHadCorrEnergyCut of " << tempDouble << std::endl;
929  clusterContainer->SetClusHadCorrEnergyCut(tempDouble);
930  }
931 
932  // SetIncludePHOS
933  result = AliEmcalCorrectionComponent::GetProperty("includePHOS", tempBool, userNode, defaultNode, false, containerName);
934  if (result) {
935  AliDebugStream(2) << clusterContainer->GetName() << ": Setting Include PHOS to " << (tempBool ? "enabled" : "disabled") << std::endl;
936  clusterContainer->SetIncludePHOS(tempBool);
937  }
938  }
939 
940  // Track specific
941  AliTrackContainer * trackContainer = dynamic_cast<AliTrackContainer *>(cont);
942  if (trackContainer) {
943  // Track selection
944  // AOD Filter bits as a sequence
945  std::vector <UInt_t> filterBitsVector;
946  result = AliEmcalCorrectionComponent::GetProperty("aodFilterBits", filterBitsVector, userNode, defaultNode, false, containerName);
947  if (result){
948  UInt_t filterBits = 0;
949  for (int filterBit : filterBitsVector) {
950  filterBits += filterBit;
951  }
952  AliDebugStream(2) << trackContainer->GetName() << ": Setting filterBits of " << filterBits << std::endl;
953  trackContainer->SetAODFilterBits(filterBits);
954  }
955 
956  // SetTrackFilterType enum
957  result = AliEmcalCorrectionComponent::GetProperty("trackFilterType", tempString, userNode, defaultNode, false, containerName);
958  if (result) {
959  // Need to get the enumeration
960  AliEmcalTrackSelection::ETrackFilterType_t trackFilterType = fgkTrackFilterTypeMap.at(tempString);
961  AliDebugStream(2) << trackContainer->GetName() << ": Setting trackFilterType of " << trackFilterType << std::endl;
962  trackContainer->SetTrackFilterType(trackFilterType);
963  }
964 
965  // Track cuts period
966  result = AliEmcalCorrectionComponent::GetProperty("trackCutsPeriod", tempString, userNode, defaultNode, false, containerName);
967  if (result) {
968  // Need to get the enumeration
969  AliDebugStream(2) << trackContainer->GetName() << ": Setting track cuts period to " << tempString << std::endl;
970  trackContainer->SetTrackCutsPeriod(tempString.c_str());
971  }
972  }
973 }
974 
992 AliEmcalContainer * AliEmcalCorrectionTask::AddContainer(AliEmcalContainerUtils::InputObject_t contType, std::string & containerName, YAML::Node & userNode, YAML::Node & defaultNode)
993 {
994  // Determine the type of branch to request
995  std::string containerBranch = "";
997  AliFatal("Must specify type of container when requesting branch.");
998  }
999 
1000  // Retrieve branch name
1001  // YAML::Node() is just an empty node
1002  AliDebugStream(2) << "User Node: " << userNode << std::endl;
1003  AliDebugStream(2) << "Default Node: " << defaultNode << std::endl;
1004  AliEmcalCorrectionComponent::GetProperty("branchName", containerBranch, userNode, defaultNode, true, containerName);
1005  // Should be unnecessary, since the user can only do this if done explicitly.
1006  /*if (containerBranch == "")
1007  {
1008  AliFatal(TString::Format("Request %i container, but the container branch is empty!", contType));
1009  }*/
1010 
1011  // Determine proper name if using "usedefault" pattern
1012  if (containerBranch == "usedefault") {
1013  containerBranch = AliEmcalContainerUtils::DetermineUseDefaultName(contType, fIsEsd);
1014  }
1015 
1016  // Create containers and set them to the name of the component
1017  AliEmcalContainer * cont = 0;
1018  if (contType == AliEmcalContainerUtils::kCluster)
1019  {
1020  cont = new AliClusterContainer(containerBranch.c_str());
1021  AdoptClusterContainer(dynamic_cast<AliClusterContainer *>(cont));
1022  }
1023  else if (contType == AliEmcalContainerUtils::kTrack)
1024  {
1025  if (containerBranch == "mcparticles") {
1026  cont = new AliMCParticleContainer(containerBranch.c_str());
1027  }
1028  else {
1029  cont = new AliTrackContainer(containerBranch.c_str());
1030  }
1031  AdoptParticleContainer(dynamic_cast<AliParticleContainer *>(cont));
1032  }
1033  cont->SetName(containerName.c_str());
1034 
1035  return cont;
1036 }
1037 
1047 {
1048  // Check that the configuration is initialized
1049  if (fConfigurationInitialized != true)
1050  {
1051  AliFatal("YAML configuration must be initialized before running (ie. the AddTask, run macro or wagon)!");
1052  }
1053 
1054  // Show the configurations info this is available
1055  AliDebugStream(4) << "User configuration string: " << fUserConfigurationString << std::endl;
1056  AliDebugStream(4) << "User configuration: " << fUserConfiguration << std::endl;
1057  AliDebugStream(4) << "Default configuration string: " << fDefaultConfigurationString << std::endl;
1058  AliDebugStream(4) << "Default configuration: " << fDefaultConfiguration << std::endl;
1059 
1060  // YAML Objects cannot be streamed, so we need to reinitialize them here.
1061  // They need reinitialize if they are null
1062  if (fUserConfiguration.IsNull() == true && fUserConfigurationString != "")
1063  {
1064  AliInfo("Reinitializing user configuration from string. Expected if running on grid!");
1066  }
1067  if (fDefaultConfiguration.IsNull() == true)
1068  {
1069  AliInfo("Reinitializing default configuration from string. Expected if running on grid!");
1071  }
1072 
1073  // Debug to check that the configuration has been (re)initiailzied has been completed correctly
1074  AliDebugStream(4) << "(Re)initialized user configuration: " << fUserConfigurationString << std::endl;
1075  AliDebugStream(4) << "(Re)initialized user configuration: " << fUserConfiguration << std::endl;
1076  AliDebugStream(4) << "(Re)initialized default configuration: " << fDefaultConfigurationString << std::endl;
1077  AliDebugStream(4) << "(Re)initialized default configuration: " << fDefaultConfiguration << std::endl;
1078 
1079  if (fForceBeamType == kpp)
1080  fNcentBins = 1;
1081 
1082  // Allow for output files
1083  OpenFile(1);
1084  fOutput = new TList();
1085  fOutput->SetOwner();
1086 
1088 
1089  PostData(1, fOutput);
1090 }
1091 
1099 {
1100  // Run the initialization for all derived classes.
1101  for (auto component : fCorrectionComponents)
1102  {
1103  // Set cent bins (usually used for hist creation)
1104  // It cannot be set until now because it can be changed after initialization
1105  // For instance, by SetForceBeamType()
1106  component->SetNcentralityBins(fNcentBins);
1107 
1108  component->UserCreateOutputObjects();
1109 
1110  if (component->GetOutputList() != 0)
1111  {
1112  // Adds a list to the list -- this doesn't work for some unknown reason
1113  //fOutput->Add(component->GetOutputList());
1114 
1115  // iterate through lists for each component, and fill in output
1116  TList* t = new TList();
1117  t->SetName(component->GetName());
1118  fOutput->AddLast(t);
1119  t = (TList*)fOutput->Last();
1120  TIter next(component->GetOutputList());
1121  while (TObject *obj = next()){
1122  t->Add(obj);
1123  }
1124 
1125  AliDebug(1, TString::Format("Added output list from task %s to output.", component->GetName()));
1126  }
1127  }
1128 }
1129 
1135 {
1136  // Initialize the event if not initialized
1137  if (!fEventInitialized)
1138  ExecOnce();
1139 
1140  // Only continue if we are initialized successfully
1141  if (!fEventInitialized)
1142  return;
1143 
1144  // Get the objects for each event
1145  if (!RetrieveEventObjects())
1146  return;
1147 
1148  // Call run for each correction
1149  if (!Run())
1150  return;
1151 }
1152 
1164 {
1165  if (!InputEvent()) {
1166  AliError("Could not retrieve event! Returning!");
1167  return;
1168  }
1169 
1170  // This warning was extracted out from the cell components
1171  if (dynamic_cast<AliAODEvent*>(InputEvent())) {
1172  AliWarning("=============================================================");
1173  AliWarning("=== Running on AOD is not equivalent to running on ESD! ===");
1174  AliWarning("=============================================================");
1175  }
1176 
1177  if (fNeedEmcalGeom) {
1178  fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(InputEvent()->GetRunNumber());
1179  if (!fGeom) {
1180  AliFatal("Can not get EMCal geometry instance. If you do not need the EMCal geometry, disable it by setting task->SetNeedEmcalGeometry(kFALSE).");
1181  return;
1182  }
1183  }
1184 
1185  // Load all requested track branches - each container knows name already
1186  for (Int_t i =0; i<fParticleCollArray.GetEntriesFast(); i++) {
1187  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
1189  cont->SetArray(InputEvent());
1190  }
1191 
1192  // Load all requested cluster branches - each container knows name already
1193  for (Int_t i =0; i<fClusterCollArray.GetEntriesFast(); i++) {
1194  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
1196  cont->SetArray(InputEvent());
1197  }
1198 
1199  // Determine the proper pointer for each cell object and save them to the cell container
1200  // At this point, they should all be created
1201  for (auto cellObj : fCellCollArray)
1202  {
1204  }
1205 
1206  fEventInitialized = kTRUE;
1207 
1208  // Print warning to the user that the rest of the configuration information is available in the generation log
1209  // when the Analysis Manager was created. Using cout to be certain that it is shown on the train!
1210  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";
1211 
1212  // Setup the components
1214 }
1215 
1221 {
1222  // Run the initialization for all derived classes.
1223  for (auto component : fCorrectionComponents)
1224  {
1225  // Setup geometry
1226  component->SetEMCALGeometry(fGeom);
1227 
1228  // Add the requested cells to the component
1230 
1231  // Set the input events. This is redundant to where it is set during Run(), but the events need to be
1232  // available to components, and they are only called one extra time.
1233  component->SetInputEvent(InputEvent());
1234  component->SetMCEvent(MCEvent());
1235 
1236  // Component ExecOnce()
1237  component->ExecOnce();
1238 
1239  // If the cells were created during ExecOnce(), then we need to re-initialize the pointer to ensure
1240  // that it is not null!
1241  if (!(component->GetCaloCells())) {
1242  AliDebugStream(2) << "Re-initializing cells for component " << component->GetName() << std::endl;
1244  }
1245  }
1246 }
1247 
1253 {
1254  fVertex[0] = 0;
1255  fVertex[1] = 0;
1256  fVertex[2] = 0;
1257  fNVertCont = 0;
1258 
1259  const AliVVertex *vert = InputEvent()->GetPrimaryVertex();
1260  if (vert) {
1261  vert->GetXYZ(fVertex);
1262  fNVertCont = vert->GetNContributors();
1263  }
1264 
1265  fBeamType = GetBeamType();
1266 
1267  if (fBeamType == kAA || fBeamType == kpA ) {
1269  AliMultSelection *MultSelection = static_cast<AliMultSelection*>(InputEvent()->FindListObject("MultSelection"));
1270  if (MultSelection) {
1271  fCent = MultSelection->GetMultiplicityPercentile(fCentEst.Data());
1272  }
1273  else {
1274  AliWarning("Could not retrieve centrality information! Assuming 99");
1275  }
1276  }
1277  else { // old centrality estimation < 2015
1278  AliCentrality *aliCent = InputEvent()->GetCentrality();
1279  if (aliCent) {
1280  fCent = aliCent->GetCentralityPercentile(fCentEst.Data());
1281  }
1282  else {
1283  AliWarning("Could not retrieve centrality information! Assuming 99");
1284  }
1285  }
1286 
1287  if (fNcentBins==4) {
1288  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1289  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1290  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1291  else if (fCent >= 50 && fCent <= 100) fCentBin = 3;
1292  else {
1293  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1294  fCentBin = fNcentBins-1;
1295  }
1296  }
1297  else if (fNcentBins==5) { // for PbPb 2015
1298  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1299  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1300  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1301  else if (fCent >= 50 && fCent <= 90) fCentBin = 3;
1302  else if (fCent > 90) {
1303  fCent = 99;
1304  fCentBin = 4;
1305  }
1306  else {
1307  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1308  fCentBin = fNcentBins-1;
1309  }
1310  }
1311  else {
1312  Double_t centWidth = (fMaxCent-fMinCent)/(Double_t)fNcentBins;
1313  if(centWidth>0.) {
1314  fCentBin = TMath::FloorNint(fCent/centWidth);
1315  }
1316  else {
1317  fCentBin = 0;
1318  }
1319  if (fCentBin>=fNcentBins) {
1320  AliWarning(Form("fCentBin too large: cent = %f fCentBin = %d. Assuming 99", fCent, fCentBin));
1321  fCentBin = fNcentBins-1;
1322  }
1323  }
1324  }
1325  else {
1326  fCent = 99;
1327  fCentBin = 0;
1328  }
1329 
1330  AliEmcalContainer* cont = 0;
1331 
1332  TIter nextPartColl(&fParticleCollArray);
1333  while ((cont = static_cast<AliEmcalContainer*>(nextPartColl()))) cont->NextEvent();
1334 
1335  TIter nextClusColl(&fClusterCollArray);
1336  while ((cont = static_cast<AliEmcalContainer*>(nextClusColl()))) cont->NextEvent();
1337 
1338  return kTRUE;
1339 }
1340 
1346 {
1347  // Run the initialization for all derived classes.
1348  for (auto component : fCorrectionComponents)
1349  {
1350  component->SetInputEvent(InputEvent());
1351  component->SetMCEvent(MCEvent());
1352  component->SetCentralityBin(fCentBin);
1353  component->SetCentrality(fCent);
1354  component->SetVertex(fVertex);
1355 
1356  component->Run();
1357  }
1358 
1359  PostData(1, fOutput);
1360 
1361  return kTRUE;
1362 }
1363 
1368 {
1369  // Run the initialization for all derived classes.
1370  for (auto component : fCorrectionComponents)
1371  {
1372  component->UserNotify();
1373  }
1374 
1375  return kTRUE;
1376 }
1377 
1384 std::ostream & AliEmcalCorrectionTask::PrintConfigurationString(std::ostream & in, bool userConfig) const
1385 {
1386  std::string stringToWrite = userConfig ? fUserConfigurationString : fDefaultConfigurationString;
1387  if (stringToWrite == "") {
1388  AliWarning(TString::Format("%s configuration is empty!", userConfig ? "User" : "Default"));
1389  }
1390  in << stringToWrite;
1391 
1392  return in;
1393 }
1394 
1402 bool AliEmcalCorrectionTask::WriteConfigurationFile(std::string filename, bool userConfig) const
1403 {
1404  bool returnValue = false;
1405  if (filename != "")
1406  {
1407  if (fConfigurationInitialized == true)
1408  {
1409  std::ofstream outFile(filename);
1410  PrintConfigurationString(outFile, userConfig);
1411  outFile.close();
1412 
1413  returnValue = true;
1414  }
1415  else
1416  {
1417  AliError(TString::Format("Configuration not properly initialized! Cannot print %s configuration!", userConfig ? "user" : "default"));
1418  }
1419 
1420  }
1421  else
1422  {
1423  AliError("Please pass a valid filename instead of empty quotes!");
1424  }
1425  return returnValue;
1426 }
1427 
1435 bool AliEmcalCorrectionTask::CompareToStoredConfiguration(std::string filename, bool userConfig) const
1436 {
1437  bool returnValue = false;
1438  if (filename != "")
1439  {
1440  if (fConfigurationInitialized == true)
1441  {
1442  // Generate YAML nodes for the comparison
1443  YAML::Node passedNode = YAML::LoadFile(filename);
1444  YAML::Node comparisonNode = YAML::Load(userConfig ? fUserConfigurationString : fDefaultConfigurationString);
1445 
1446  // Need to stream the configuration back to a string to remove the comments
1447  // since they are not preserved in the YAML node.
1448  std::stringstream passedNodeSS;
1449  passedNodeSS << passedNode;
1450 
1451  // Compare the nodes. Make the comparison as strings, as the YAML nodes do _not_ match, despite the strings matching.
1452  // In fact, the YAML nodes will _not_ match even if they are generated from the same string....
1453  if (passedNodeSS.str() == (userConfig ? fUserConfigurationString : fDefaultConfigurationString)) {
1454  returnValue = true;
1455  }
1456  else {
1457  AliWarningStream() << "Passed YAML config:\n" << passedNode << "\n\nStored YAML config:\n" << comparisonNode << "\nPassed config located in file \"" << filename << "\" is not the same as the stored " << (userConfig ? "user" : "default") << "configuration file! YAML configurations printed above.\n";
1458  }
1459  }
1460  else
1461  {
1462  AliError(TString::Format("Configuration not properly initialized! Cannot compare %s configuration!", userConfig ? "user" : "default"));
1463  }
1464 
1465  }
1466  else
1467  {
1468  AliError("Please pass a valid filename instead of empty quotes!");
1469  }
1470  return returnValue;
1471 }
1472 
1481 inline bool AliEmcalCorrectionTask::DoesFileExist(const std::string & filename)
1482 {
1483  std::ifstream inFile(filename);
1484  return inFile.good();
1485 }
1486 
1496 {
1497  if (filename != "")
1498  {
1499  // Handle if in AliPhysics and includes $ALICE_PHYSICS
1500  filename = gSystem->ExpandPathName(filename.c_str());
1501 
1502  // Handle grid
1503  if(filename.find("alien://") != std::string::npos)
1504  {
1505  AliDebug(2, TString::Format("Opening file \"%s\" on the grid!", filename.c_str()));
1506  // Initialize alien connection if needed
1507  if (!gGrid) {
1508  TGrid::Connect("alien://");
1509  }
1510 
1511  // Determine the local filename and copy file to local directory
1512  std::string localFilename = gSystem->BaseName(filename.c_str());
1513  // Ensures that the default and user files do not conflict if both are taken from the grid and have the same filename
1514  if (userFile == true) {
1515  localFilename = "user." + localFilename;
1516  }
1517  // Add UUID to ensure there are no conflicts if multiple correction tasks have the same configuration file name
1518  TUUID tempUUID;
1519  localFilename = "." + localFilename;
1520  localFilename = tempUUID.AsString() + localFilename;
1521 
1522  // Copy file
1523  TFile::Cp(filename.c_str(), localFilename.c_str());
1524 
1525  // yaml-cpp should only open the local file
1526  filename = localFilename;
1527  }
1528  }
1529 }
1530 
1538 {
1539  AliDebugStream(2) << "Retrieving cells object " << cellContainer->GetName() << std::endl;
1540  // Check for embedding and return object
1541  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cellContainer->GetIsEmbedding());
1542 
1543  cellContainer->SetCells(dynamic_cast<AliVCaloCells *>(event->FindListObject(cellContainer->GetBranchName().c_str())));
1544 }
1545 
1556 {
1557  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cont->GetIsEmbedding());
1558 
1559  TClonesArray * array = dynamic_cast<TClonesArray *>(event->FindListObject(cont->GetArrayName()));
1560  if (!array) {
1561  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()));
1562  array = new TClonesArray(AliEmcalContainerUtils::DetermineUseDefaultName(objectType, fIsEsd, true).c_str());
1563  array->SetName(cont->GetArrayName());
1564  event->AddObject(array);
1565  }
1566 }
1567 
1576 {
1577  // Get container node
1578  std::string inputObjectName = "";
1579  if (inputObjectType == AliEmcalContainerUtils::kCluster) {
1580  inputObjectName = "clusterContainers";
1581  }
1582  else if (inputObjectType == AliEmcalContainerUtils::kTrack) {
1583  inputObjectName = "trackContainers";
1584  }
1585  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1586  inputObjectName = "cells";
1587  }
1588  else {
1589  AliFatal(TString::Format("Unrecognized input object type %d", inputObjectType));
1590  }
1591 
1592  return inputObjectName;
1593 }
1594 
1606 bool AliEmcalCorrectionTask::CheckPossibleNamesForComponentName(std::string & name, std::set <std::string> & possibleComponents)
1607 {
1608  bool foundComponent = false;
1609  for (auto & possibleComponent : possibleComponents)
1610  {
1611  if (possibleComponent == name) {
1612  foundComponent = true;
1613  break;
1614  }
1615  }
1616 
1617  return foundComponent;
1618 }
1619 
1627 {
1628  if (fForceBeamType != kNA)
1629  return fForceBeamType;
1630 
1631  AliESDEvent *esd = dynamic_cast<AliESDEvent*>(InputEvent());
1632  if (esd) {
1633  const AliESDRun *run = esd->GetESDRun();
1634  TString beamType = run->GetBeamType();
1635  if (beamType == "p-p")
1636  return kpp;
1637  else if (beamType == "A-A")
1638  return kAA;
1639  else if (beamType == "p-A")
1640  return kpA;
1641  else
1642  return kNA;
1643  } else {
1644  Int_t runNumber = InputEvent()->GetRunNumber();
1645  // All run number ranges taken from the RCT
1646  if ((runNumber >= 136833 && runNumber <= 139517) || // LHC10h
1647  (runNumber >= 167693 && runNumber <= 170593) || // LHC11h
1648  (runNumber >= 244824 && runNumber <= 246994)) { // LHC15o
1649  return kAA;
1650  } else if ((runNumber >= 188356 && runNumber <= 188366) || // LHC12g
1651  (runNumber >= 195164 && runNumber <= 197388) || // LHC13b-f
1652  (runNumber >= 265015 && runNumber <= 267166)) { // LHC16q-t
1653  return kpA;
1654  } else {
1655  return kpp;
1656  }
1657  }
1658 }
1659 
1664 {
1665  if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1666  stream << "Cells info: " << std::endl;
1667  for (auto cellInfo : fCellCollArray) {
1668  stream << "\tName: " << cellInfo->GetName() << "\tBranch: " << cellInfo->GetBranchName() << "\tIsEmbedding: " << std::boolalpha << cellInfo->GetIsEmbedding() << std::endl;
1669  }
1670  }
1671  else if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
1672  stream << (inputObjectType == AliEmcalContainerUtils::kCluster ? "Cluster" : "Track") << " container info: " << std::endl;
1673  AliEmcalContainer * cont = 0;
1674  for (auto containerInfo : (inputObjectType == AliEmcalContainerUtils::kCluster ? fClusterCollArray : fParticleCollArray) ) {
1675  cont = static_cast<AliEmcalContainer *>(containerInfo);
1676  stream << "\tName: " << cont->GetName() << "\tBranch: " << cont->GetArrayName() << "\tTitle: " << cont->GetTitle() << "\tIsEmbedding: " << std::boolalpha << cont->GetIsEmbedding() << std::endl;
1677  }
1678  }
1679  else {
1680  AliErrorStream() << "Unrecognized input object type " << inputObjectType << std::endl;
1681  }
1682 }
1683 
1693 void AliEmcalCorrectionTask::GetNodeForInputObjects(YAML::Node & inputNode, YAML::Node & nodeToRetrieveFrom, std::string & inputObjectName, bool requiredProperty)
1694 {
1695  // Get the user input node
1696  AliEmcalCorrectionComponent::GetProperty(inputObjectName.c_str(), inputNode, YAML::Node(), nodeToRetrieveFrom, requiredProperty, "inputObjects");
1697 
1698  // Get the user shared node and add it back to the user node so that shared parameters are available
1699  if (nodeToRetrieveFrom["sharedParameters"]) {
1700  inputNode["sharedParameters"] = nodeToRetrieveFrom["sharedParameters"];
1701  }
1702 }
1703 
1714 void AliEmcalCorrectionTask::GetPropertyNamesFromNode(const std::string & componentName, const YAML::Node & node, std::set <std::string> & propertyNames, const bool nodeRequired)
1715 {
1716  YAML::Node tempNode;
1717  AliEmcalCorrectionComponent::GetProperty(componentName, tempNode, YAML::Node(), node, nodeRequired, "");
1718  for (auto propertyName : tempNode)
1719  {
1720  propertyNames.insert(propertyName.first.as<std::string>());
1721  }
1722 }
1723 
1731 AliEmcalCorrectionCellContainer * AliEmcalCorrectionTask::GetCellContainer(const std::string & cellsContainerName) const
1732 {
1733  for (auto cellContainer : fCellCollArray)
1734  {
1735  if (cellContainer->GetName() == cellsContainerName) {
1736  return cellContainer;
1737  }
1738  }
1739 
1740  return 0;
1741 }
1742 
1744 {
1745  // Get the pointer to the existing analysis manager via the static access method.
1746  //==============================================================================
1747  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1748  if (!mgr)
1749  {
1750  ::Error("AddTaskEmcalCorrectionTask", "No analysis manager to connect to.");
1751  return 0;
1752  }
1753 
1754  // Check the analysis type using the event handlers connected to the analysis manager.
1755  //==============================================================================
1756  AliVEventHandler* handler = mgr->GetInputEventHandler();
1757  if (!handler)
1758  {
1759  ::Error("AddTaskEmcalCorrectionTask", "This task requires an input event handler");
1760  return 0;
1761  }
1762 
1763  TString name = "AliEmcalCorrectionTask";
1764  if (suffix != "") {
1765  name += TString::Format("_%s", suffix.Data());
1766  }
1767 
1768  AliEmcalCorrectionTask* mgrTask = static_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.Data()));
1769  if (mgrTask) return mgrTask;
1770 
1771  // Create the task that manages the corrections
1772  AliEmcalCorrectionTask* correctionTask = new AliEmcalCorrectionTask(name.Data());
1773 
1774  //-------------------------------------------------------
1775  // Final settings, pass to manager and set the containers
1776  //-------------------------------------------------------
1777 
1778  mgr->AddTask(correctionTask);
1779 
1780  // Create containers for input/output
1781  AliAnalysisDataContainer* cInput = mgr->GetCommonInputContainer();
1782 
1783  TString outputContainerName(name);
1784  outputContainerName += "_histos";
1785 
1786  AliAnalysisDataContainer * cOutput = mgr->CreateContainer(outputContainerName.Data(),
1787  TList::Class(),
1788  AliAnalysisManager::kOutputContainer,
1789  Form("%s", AliAnalysisManager::GetCommonFileName()));
1790 
1791  mgr->ConnectInput(correctionTask, 0, cInput);
1792  mgr->ConnectOutput(correctionTask, 1, cOutput);
1793 
1794  //TObjArray* cnt = mgr->GetContainers();
1795 
1796  return correctionTask;
1797 }
1798 
1804 std::string AliEmcalCorrectionTask::toString(bool includeYAMLConfigurationInfo) const
1805 {
1806  std::stringstream tempSS;
1807 
1808  // Show the correction components
1809  tempSS << "Correction components:\n";
1810  for (auto component : fOrderedComponentsToExecute) {
1811  tempSS << "\t" << component << "\n";
1812  }
1813  // Input objects
1814  tempSS << "\nInput objects:\n";
1818 
1819  if (includeYAMLConfigurationInfo == true) {
1820  tempSS << "\nUser Configuration:\n";
1821  PrintConfigurationString(tempSS, true);
1822  tempSS << "\n\nDefault Configuration:\n";
1823  PrintConfigurationString(tempSS);
1824  tempSS << "\n";
1825  }
1826 
1827  return tempSS.str();
1828 }
1829 
1836 std::ostream & AliEmcalCorrectionTask::Print(std::ostream & in) const {
1837  in << toString();
1838  return in;
1839 }
1840 
1848 std::ostream & operator<<(std::ostream & in, const AliEmcalCorrectionTask & myTask)
1849 {
1850  std::ostream & result = myTask.Print(in);
1851  return result;
1852 }
1853 
1861 {
1862  std::string temp(opt);
1863  bool includeYAMLConfig = false;
1864  if (temp == "YAML") {
1865  includeYAMLConfig = true;
1866  }
1867  Printf("%s", toString(includeYAMLConfig).c_str());
1868 }
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 components)
void PrintRequestedContainersInformation(AliEmcalContainerUtils::InputObject_t inputObjectType, std::ostream &stream) const
Steering task for the EMCal correction framework.
AliEMCALGeometry * fGeom
! Emcal geometry
const char * filename
Definition: TestFCM.C:1
static const std::map< std::string, AliVCluster::VCluUserDefEnergy_t > fgkClusterEnergyTypeMap
Relates string to the cluster energy enumeration for YAML configuration.
void SetTrackCutsPeriod(const char *period)
static bool DoesFileExist(const std::string &filename)
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)
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.
TSystem * gSystem
std::string GetInputFieldNameFromInputObjectType(AliEmcalContainerUtils::InputObject_t inputObjectType)
static std::string DetermineUseDefaultName(InputObject_t objType, bool esdMode, bool returnObjectType=false)
void AdoptClusterContainer(AliClusterContainer *cont)
void SetupConfigurationFilePath(std::string &filename, bool userFile=false)
void UserExec(Option_t *option)
AliEmcalCorrectionTask & operator=(AliEmcalCorrectionTask other)
YAML::Node fUserConfiguration
! User YAML Configuration
Double_t fMaxCent
max centrality for event selection
Double_t fVertex[3]
! Event vertex
Declaration of class AliAnalysisTaskEmcalEmbeddingHelper.
void DetermineComponentsToExecute(std::vector< std::string > &componentsToExecute)
TList * fOutput
! Output for histograms
Wrapper around cells objects for the EMCal Correction Task.
bool fConfigurationInitialized
True if the YAML configuration files are initialized.
AliEmcalContainer * AddContainer(AliEmcalContainerUtils::InputObject_t contType, std::string &containerName, YAML::Node &userNode, YAML::Node &defaultNode)
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.
static AliVEvent * GetEvent(AliVEvent *inputEvent, bool isEmbedding=false)
void SetUserConfiguration(YAML::Node &node)
Make copy to ensure that the nodes do not point to each other (?)
bool CompareToStoredConfiguration(std::string filename, bool userConfig=false) const
AliVCaloCells * GetCells() const
Pointer to the actual CaloCells object.
bool fEventInitialized
If the event is initialized properly.
void Load()
Definition: UnfoldingHF.C:238
TString fCentEst
name of V0 centrality estimator
void SetAODFilterBits(UInt_t bits)
int Int_t
Definition: External.C:63
std::string fUserConfigurationFilename
! User YAML configruation filename
InputObject_t
Type of input object to be created
AliClusterContainer * GetClusterContainer(Int_t i=0) const
unsigned int UInt_t
Definition: External.C:33
std::string fDefaultConfigurationString
Store the default YAML configuration as a string so that it can be streamed.
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)
Bool_t fNeedEmcalGeom
whether or not the task needs the emcal geometry
static const std::map< std::string, AliEmcalTrackSelection::ETrackFilterType_t > fgkTrackFilterTypeMap
Relates string to the track filter enumeration for YAML configuration.
std::string GetBranchName() const
Get the name of the cells branch (NOT the same as the name!)
void SetCellsObjectInCellContainerBasedOnProperties(AliEmcalCorrectionCellContainer *cellContainer)
Bool_t fUseNewCentralityEstimation
Use new centrality estimation (for 2015 data)
bool GetIsEmbedding() const
True if the cells are located in the event that is being embedded.
Bool_t Data(TH1F *h, Double_t *rangefit, Bool_t writefit, Double_t &sgn, Double_t &errsgn, Double_t &bkg, Double_t &errbkg, Double_t &sgnf, Double_t &errsgnf, Double_t &sigmafit, Int_t &status)
AliEmcalCorrectionCellContainer * GetCellContainer(const std::string &cellsContainerName) const
std::string fDefaultConfigurationFilename
! Default YAML configuration filename
void GetNodeForInputObjects(YAML::Node &inputNode, YAML::Node &nodeToRetrieveFrom, std::string &inputObjectName, bool requiredProperty)
TObjArray fParticleCollArray
Particle/track collection array.
TObjArray fClusterCollArray
Cluster collection array.
void SetDefaultConfiguration(YAML::Node &node)
ETrackFilterType_t
Pre-defined track filters.
void AdoptParticleContainer(AliParticleContainer *cont)
std::ostream & operator<<(std::ostream &in, const AliEmcalCorrectionTask &myTask)
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
void SetArray(const AliVEvent *event)
Int_t GetRunNumber(TString)
Definition: PlotMuonQA.C:2235
void SetTrackFilterType(ETrackFilterType_t f)
std::string toString(bool includeYAMLConfigurationInfo=false) const
const char Option_t
Definition: External.C:48
void SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, YAML::Node &userInputObjectNode, YAML::Node &defaultInputObjectNode, std::set< std::string > &requestedContainers)
YAML::Node fDefaultConfiguration
! Default YAML Configuration
void Print(Option_t *opt="") const
void SetupCellsInfo(std::string containerName, YAML::Node &userNode, YAML::Node &defaultNode)
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
Double_t fMinCent
min centrality for event selection
std::vector< AliEmcalCorrectionCellContainer * > fCellCollArray
Cells collection array.
void SetupContainer(AliEmcalContainerUtils::InputObject_t inputObjectType, std::string containerName, YAML::Node &userNode, YAML::Node &defaultNode)
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)
std::string fUserConfigurationString
Store the user YAML configuration as a string so that it can be streamed.
void GetPropertyNamesFromNode(const std::string &componentName, const YAML::Node &node, std::set< std::string > &propertyNames, const bool nodeRequired)
std::ostream & PrintConfigurationString(std::ostream &in, bool userConfig=false) const
TList * OpenFile(const char *fname)
Definition: DrawAnaELoss.C:65
void SetClusHadCorrEnergyCut(Double_t cut)
void swap(AliEmcalCorrectionTask &first, AliEmcalCorrectionTask &second)
bool GetProperty(std::string propertyName, T &property, bool requiredProperty=true, std::string correctionName="")
Retrieve property.
BeamType fForceBeamType
forced beam type