AliPhysics  b81c3d2 (b81c3d2)
 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 
21 #include "AliVEventHandler.h"
22 #include "AliEMCALGeometry.h"
23 #include "AliVCaloCells.h"
24 #include "AliVCluster.h"
25 #include "AliLog.h"
26 #include "AliMultSelection.h"
27 #include "AliCentrality.h"
28 #include "AliESDEvent.h"
29 #include "AliAnalysisManager.h"
30 #include "AliAODEvent.h"
31 
33 
37 
41 
42 const std::map <std::string, AliVCluster::VCluUserDefEnergy_t> AliEmcalCorrectionTask::fgkClusterEnergyTypeMap = {
43  {"kNonLinCorr", AliVCluster::kNonLinCorr },
44  {"kHadCorr", AliVCluster::kHadCorr },
45  {"kUserDefEnergy1", AliVCluster::kUserDefEnergy1 },
46  {"kUserDefEnergy2", AliVCluster::kUserDefEnergy2 }
47 };
48 
49 const std::map <std::string, AliEmcalTrackSelection::ETrackFilterType_t> AliEmcalCorrectionTask::fgkTrackFilterTypeMap = {
50  {"kNoTrackFilter", AliEmcalTrackSelection::kNoTrackFilter },
51  {"kCustomTrackFilter", AliEmcalTrackSelection::kCustomTrackFilter },
52  {"kHybridTracks", AliEmcalTrackSelection::kHybridTracks },
53  {"kTPCOnlyTracks", AliEmcalTrackSelection::kTPCOnlyTracks }
54 };
55 
60  AliAnalysisTaskSE("AliEmcalCorrectionTask"),
61  fSuffix(""),
62  fUserConfiguration(),
63  fUserConfigurationFilename(""),
64  fUserConfigurationString(""),
65  fDefaultConfiguration(),
66  fDefaultConfigurationFilename(""),
67  fDefaultConfigurationString(""),
68  fCorrectionComponents(),
69  fIsEsd(false),
70  fForceBeamType(kNA),
71  fConfigurationInitialized(false),
72  fOrderedComponentsToExecute(),
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  fNeedEmcalGeom(kTRUE),
85  fGeom(0),
86  fParticleCollArray(),
87  fClusterCollArray(),
88  fCellCollArray(),
89  fOutput(0)
90 {
91  // Default constructor
92  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
93 
94  fParticleCollArray.SetOwner(kTRUE);
95  fClusterCollArray.SetOwner(kTRUE);
96 }
97 
108  AliAnalysisTaskSE(name),
109  fSuffix(""),
110  fUserConfiguration(),
111  fUserConfigurationFilename(""),
112  fUserConfigurationString(""),
113  fDefaultConfiguration(),
114  fDefaultConfigurationFilename(""),
115  fDefaultConfigurationString(""),
116  fCorrectionComponents(),
117  fIsEsd(false),
118  fForceBeamType(kNA),
119  fConfigurationInitialized(false),
120  fOrderedComponentsToExecute(),
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  fNeedEmcalGeom(kTRUE),
133  fGeom(0),
134  fParticleCollArray(),
135  fClusterCollArray(),
136  fCellCollArray(),
137  fOutput(0)
138 {
139  // Standard constructor
140  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
141 
142  fParticleCollArray.SetOwner(kTRUE);
143  fClusterCollArray.SetOwner(kTRUE);
144 
145  DefineInput(0, TChain::Class());
146  DefineOutput(1, TList::Class());
147 }
148 
157  fUserConfiguration(task.fUserConfiguration),
158  fDefaultConfiguration(task.fDefaultConfiguration),
159  fSuffix(task.fSuffix),
160  fUserConfigurationString(task.fUserConfigurationString),
161  fDefaultConfigurationString(task.fDefaultConfigurationString),
162  fUserConfigurationFilename(task.fUserConfigurationFilename),
163  fDefaultConfigurationFilename(task.fDefaultConfigurationFilename),
164  fOrderedComponentsToExecute(task.fOrderedComponentsToExecute),
165  fCorrectionComponents(task.fCorrectionComponents), // TODO: These should be copied!
166  fConfigurationInitialized(task.fConfigurationInitialized),
167  fIsEsd(task.fIsEsd),
168  fEventInitialized(task.fEventInitialized),
169  fCent(task.fCent),
170  fCentBin(task.fCentBin),
171  fMinCent(task.fMinCent),
172  fMaxCent(task.fMaxCent),
173  fNcentBins(task.fNcentBins),
174  fCentEst(task.fCentEst),
175  fUseNewCentralityEstimation(task.fUseNewCentralityEstimation),
176  fVertex{0.},
177  fNVertCont(task.fNVertCont),
178  fBeamType(task.fBeamType),
179  fForceBeamType(task.fForceBeamType),
180  fNeedEmcalGeom(task.fNeedEmcalGeom),
181  fGeom(task.fGeom),
182  fParticleCollArray(*(static_cast<TObjArray *>(task.fParticleCollArray.Clone()))),
183  fClusterCollArray(*(static_cast<TObjArray *>(task.fClusterCollArray.Clone()))),
184  fOutput(task.fOutput) // TODO: More care is needed here!
185 {
186  // Vertex position
187  std::copy(std::begin(task.fVertex), std::end(task.fVertex), std::begin(fVertex));
188 
189  // Cell Collections
190  for (auto cellCont : task.fCellCollArray)
191  {
192  fCellCollArray.push_back(new AliEmcalCorrectionCellContainer(*cellCont));
193  }
194 }
195 
201 {
202  swap(*this, other);
203 }
204 
210 {
211  swap(*this, other);
212 
213  return *this;
214 }
215 
220 {
221  using std::swap;
222 
225  swap(first.fSuffix, second.fSuffix);
233  swap(first.fIsEsd, second.fIsEsd);
235  swap(first.fCent, second.fCent);
236  swap(first.fCentBin, second.fCentBin);
237  swap(first.fMinCent, second.fMinCent);
238  swap(first.fMaxCent, second.fMaxCent);
239  swap(first.fNcentBins, second.fNcentBins);
240  swap(first.fCentEst, second.fCentEst);
242  swap(first.fVertex, second.fVertex);
243  swap(first.fNVertCont, second.fNVertCont);
244  swap(first.fBeamType, second.fBeamType);
245  swap(first.fForceBeamType, second.fForceBeamType);
246  swap(first.fNeedEmcalGeom, second.fNeedEmcalGeom);
247  swap(first.fGeom, second.fGeom);
250  swap(first.fCellCollArray, second.fCellCollArray);
251  swap(first.fOutput, second.fOutput);
252 }
253 
259 {
260  // Destructor
261 }
262 
272 {
273  // Determine file type
274  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
275  if (mgr) {
276  AliVEventHandler *evhand = mgr->GetInputEventHandler();
277  if (evhand) {
278  if (evhand->InheritsFrom("AliESDInputHandler")) {
279  fIsEsd = true;
280  }
281  else {
282  fIsEsd = false;
283  }
284  }
285  else {
286  AliError("Event handler not found!");
287  }
288  }
289  else {
290  AliError("Analysis manager not found!");
291  }
292 
293  // Determine the suffix of the correction task
294  std::string tempName = GetName();
295  std::size_t foundSuffix = tempName.find("_");
296  if (foundSuffix != std::string::npos) {
297  // +1 to skip "_"
298  fSuffix = tempName.substr(foundSuffix + 1).c_str();
299  }
300 
301  if (fSuffix != "") {
302  AliInfoStream() << "Initializing correction task with suffix \"" << fSuffix << "\"" << std::endl;
303  }
304 
305  // Initialize YAML configuration
307  // Check that the configuration is initialized
308  if (fConfigurationInitialized != true)
309  {
310  AliFatal("YAML configuration must be initialized before running (ie. in the run macro or wagon)!");
311  }
312 
313  // Determine component execution order
315 
316  // Check for user defined settings that are not in the default file
318 
319  // Setup input objects
320  // Setup Cells
321  // Cannot do this entirely yet because we need input objects
324  // Create cluster input objects
327  // Create track input objects
330 
331  // Initialize components
333 
334  // Print the results of the initialization
335  // Print outside of the ALICE Log system to ensure that it is always available!
336  std::cout << GetName() << " Settings:\n" << *this;
337 }
338 
348 {
349  // Determine file path
351  {
352  // Use the default if nothing is set
353  fDefaultConfigurationFilename = "$ALICE_PHYSICS/PWG/EMCAL/config/AliEmcalCorrectionConfiguration.yaml";
354  }
355 
356  // Setup the YAML files
357  // Default
359 
361  {
362  AliInfo(TString::Format("Using default EMCal corrections configuration located at %s", fDefaultConfigurationFilename.c_str()));
363 
365  // Check for valid file
366  if (fDefaultConfiguration.IsNull() == true)
367  {
368  AliFatal(TString::Format("Could not open the default configuration file \"%s\"!", fDefaultConfigurationFilename.c_str()));
369  }
370  }
371  else
372  {
373  AliFatal(TString::Format("Default file located at \"%s\" does not exist!", fDefaultConfigurationFilename.c_str()));
374  }
375 
376  // User
378 
380  {
381  AliInfo(TString::Format("Using user EMCal corrections configuration located at %s", fUserConfigurationFilename.c_str()));
382 
384  }
385  else
386  {
387  AliInfo(TString::Format("User file at \"%s\" does not exist! All settings will be from the default file!", fUserConfigurationFilename.c_str()));
388  }
389 
390  // Save configuration into strings so that they can be streamed
391  // Need the stringstream because YAML implements streamers
392  std::stringstream tempConfiguration;
393  tempConfiguration << fUserConfiguration;
394  fUserConfigurationString = tempConfiguration.str();
395  tempConfiguration.str("");
396  tempConfiguration << fDefaultConfiguration;
397  fDefaultConfigurationString = tempConfiguration.str();
398 
399  //AliInfo(TString::Format("User configuration: %s", fUserConfigurationString.c_str()));
400  //AliInfo(TString::Format("Default configuration: %s", fDefaultConfigurationString.c_str()));
401 
402  // Note that it is initialized properly so that the analysis can proceed
404 }
405 
416 void AliEmcalCorrectionTask::DetermineComponentsToExecute(std::vector <std::string> & correctionComponents)
417 {
418  std::vector <std::string> executionOrder;
419  // executionOrder determines the order of tasks to execute, but it doesn't name the particular tasks
421 
422  // Possible components to create from both the user and default configurations
423  // Use set so that the possible components are not repeated
424  std::set <std::string> possibleComponents;
425  for (auto node : fUserConfiguration) {
426  possibleComponents.insert(node.first.as<std::string>());
427  }
428  for (auto node : fDefaultConfiguration) {
429  possibleComponents.insert(node.first.as<std::string>());
430  }
431 
432  // Determine the correction names associated with the correction task
433  std::string expectedComponentName = "";
434  bool foundSuffixComponent = false;
435  bool foundComponent = false;
436  bool componentEnabled = true;
437 
438  // Execution order determines the order that corrections should be added to our execution list
439  for (auto & execName : executionOrder)
440  {
441  // Construct the expected component name with the suffix
442  expectedComponentName = TString::Format("%s_%s", execName.c_str(), fSuffix.c_str()).Data();
443  foundComponent = false;
444  componentEnabled = false;
445 
446  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
447  if (foundComponent)
448  {
449  // Check if the component is enabled
450  AliEmcalCorrectionComponent::GetProperty("enabled", componentEnabled, fUserConfiguration, fDefaultConfiguration, true, expectedComponentName);
451  // If enabled, then store the name so that it can be executed
452  if (componentEnabled == true) {
453  foundSuffixComponent = true;
454  correctionComponents.push_back(expectedComponentName);
455  }
456  else {
457  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
458  }
459 
460  continue;
461  }
462  else
463  {
464  // Look for the normal component
465  expectedComponentName = execName;
466  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
467  // Check if it is enabled
468  AliEmcalCorrectionComponent::GetProperty("enabled", componentEnabled, fUserConfiguration, fDefaultConfiguration, true, expectedComponentName);
469 
470  if (componentEnabled == true) {
471  if (foundSuffixComponent == true) {
472  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()));
473  }
474  else {
475  // Take the normal component and store it to be executed
476  correctionComponents.push_back(expectedComponentName);
477  }
478  }
479  else {
480  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
481  }
482  }
483  }
484 
485  // Need to append "AliEmcalCorrection" to allow the tasks to be found!
486  AliDebug(2, "Found EMCal Correction Components: ");
487  for (auto & component : correctionComponents)
488  {
489  component = "AliEmcalCorrection" + component;
490  AliDebug(2, TString::Format("%s", component.c_str()) );
491  }
492 }
493 
507 {
508  // Names of properties for a particular component in the user and default configurations
509  std::set <std::string> userPropertyNames;
510  std::set <std::string> defaultPropertyNames;
511  // Notes whether a match was found between user and default properties
512  bool foundMatch = false;
513  std::string tempComponentName = "";
514 
515  // Loop over all components
516  for (const auto componentName : fOrderedComponentsToExecute)
517  {
518  // Reset for each loop
519  userPropertyNames.clear();
520  defaultPropertyNames.clear();
521  // We need to remove "AliEmcalCorrection" so that the correction will be found in the configuration
522  // "AliEmcalCorrection" is 18 characters
523  tempComponentName = componentName.substr(componentName.find("AliEmcalCorrection")+18);
524 
525  AliDebugStream(2) << "Checking component " << componentName << " for unmatched user settings" << std::endl;
526 
527  // Get the user property names
528  GetPropertyNamesFromNode(tempComponentName, fUserConfiguration, userPropertyNames, false);
529 
530  // Get the same from default
531  // Not required here because the default configuration may not have the specialized component
532  GetPropertyNamesFromNode(tempComponentName, fDefaultConfiguration, defaultPropertyNames, false);
533 
534  // We need to check the base correction as well to fill out the options
535  if (tempComponentName.find("_") != std::string::npos) {
536  // Get the base user component
537  GetPropertyNamesFromNode(tempComponentName.substr(0, tempComponentName.find("_")), fUserConfiguration, userPropertyNames, false);
538 
539  // Required here because the default must have the base component!
540  GetPropertyNamesFromNode(tempComponentName.substr(0, tempComponentName.find("_")), fDefaultConfiguration, defaultPropertyNames, true);
541  }
542 
543  // Check each property defined in the user file for a match to the properties in the default file
544  for (auto userPropertyName : userPropertyNames)
545  {
546  AliDebugStream(2) << "Checking property " << userPropertyName << std::endl;
547  foundMatch = false;
548  for (auto defaultPropertyName : defaultPropertyNames)
549  {
550  if (userPropertyName == defaultPropertyName) {
551  AliDebugStream(2) << "Found match of " << userPropertyName << " with " << defaultPropertyName << std::endl;
552  foundMatch = true;
553  }
554  }
555  if (foundMatch == false) {
556  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()));
557  }
558  }
559  }
560 }
561 
569 {
570  // Iterate over the ordered components list and create the components
571  AliEmcalCorrectionComponent * component = 0;
572  for (auto componentName : fOrderedComponentsToExecute)
573  {
574  std::string noPrefixComponentName = componentName.substr(0, componentName.find("_" + fSuffix));
575  component = AliEmcalCorrectionComponentFactory::createInstance(noPrefixComponentName);
576  if (!component)
577  {
578  AliFatal(TString::Format("Failed to create requested component %s!", componentName.c_str()));
579  }
580 
581  // For setting names of tasks to differentiate between tasks of the same class
582  component->SetName(componentName.c_str());
583  component->SetTitle(componentName.c_str());
584 
585  // Initialize the YAML configurations in each component
588 
589  // configure needed fields for components to properly initialize
590  component->SetIsESD(fIsEsd);
591 
592  // Add the require containers to the component
593  // Cells must be set during UserExec() because we need to add them as a pointer
596 
597  // Initialize each component
598  component->Initialize();
599 
600  if (component)
601  {
602  AliInfo(TString::Format("Successfully added correction task: %s", componentName.c_str()));
603  fCorrectionComponents.push_back(component);
604  }
605  }
606 }
607 
623 {
624  // Get container node
625  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
626 
627  // Get the user and default input nodes for the object type
628  YAML::Node userInputObjectNode;
629  YAML::Node defaultInputObjectNode;
630  GetNodeForInputObjects(userInputObjectNode, fUserConfiguration, inputObjectName, false);
631  GetNodeForInputObjects(defaultInputObjectNode, fDefaultConfiguration, inputObjectName, true);
632 
633  AliDebugStream(3) << "userInputObjectNode: " << userInputObjectNode << std::endl;
634  AliDebugStream(3) << "defaultInputObjectNode: " << defaultInputObjectNode << std::endl;
635 
636  // Determine which containers we need based on which are requested by the enabled correction tasks
637  std::set <std::string> requestedContainers;
638  std::vector <std::string> componentRequest;
639  for ( const auto & componentName : fOrderedComponentsToExecute )
640  {
641  componentRequest.clear();
642  // Not required because not all components will have all kinds of containers
643  // "AliEmcalCorrection" is 18 characters
644  AliEmcalCorrectionComponent::GetProperty(inputObjectName + "Names", componentRequest, fUserConfiguration, fDefaultConfiguration, false, componentName.substr(componentName.find("AliEmcalCorrection")+18));
645  for ( auto & req : componentRequest )
646  {
647  AliDebugStream(3) << "Component " << componentName << " requested container name " << req << std::endl;
648  requestedContainers.insert(req);
649  }
650  }
651 
652  AliDebugStream(2) << inputObjectName << " Containers requested by components: " << std::endl;
653  for (auto & str : requestedContainers) {
654  AliDebugStream(2) << "\t" << str << std::endl;;
655  }
656 
657  // Create all requested containers
658  AliDebug(2, TString::Format("Setting up requested containers!"));
659  SetupContainersFromInputNodes(inputObjectType, userInputObjectNode, defaultInputObjectNode, requestedContainers);
660 }
661 
670 {
671  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
672  // Need to be of the form "clusterContainersNames"
673  inputObjectName = inputObjectName + "Names";
674 
675  std::vector <std::string> inputObjects;
676  // Not required, because not all components need Clusters or Tracks
677  AliEmcalCorrectionComponent::GetProperty(inputObjectName.c_str(), inputObjects, fUserConfiguration, fDefaultConfiguration, false, component->GetName());
678 
679  //AliDebugStream(4) << "inputObjects.size(): " << inputObjects.size() << std::endl;
680 
681  // If it is not found, then there will be nothing to iterate over, so we don't need to explicitly check the return value
682  for (auto const & str : inputObjects)
683  {
684  // 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()!
685  if (inputObjectType == AliEmcalContainerUtils::kCluster)
686  {
687  AliEmcalContainer * cont = GetClusterContainer(str.c_str());
688  AliDebugStream(2) << "Adding cluster container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
689 
690  if (checkObjectExists && !cont) {
691  AliError(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
692  }
693  component->AdoptClusterContainer(GetClusterContainer(str.c_str()));
694  }
695  else if (inputObjectType == AliEmcalContainerUtils::kTrack)
696  {
697  AliEmcalContainer * cont = GetParticleContainer(str.c_str());
698  AliDebugStream(2) << "Adding particle container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
699 
700  if (checkObjectExists && !cont) {
701  AliFatal(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
702  }
703  component->AdoptParticleContainer(GetParticleContainer(str.c_str()));
704  }
705  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells)
706  {
707  // NOTE: This operates different than the others. This should be executed during run time rather than during initialization!
708  if (inputObjects.size() > 1) {
709  AliFatal(TString::Format("Component %s requested more than one cell branch, but this is not supported! Check the configuration!", component->GetName()));
710  }
711 
712  // If we've made it here, this must be at least one entry
714  AliDebugStream(2) << "Adding calo cells \"" << cellCont->GetName() << "\" of branch name \"" << cellCont->GetBranchName() << "\" to component " << component->GetName() << std::endl;
715 
716  if (!(cellCont->GetCells())) {
717  // Attempt to re-initialize the cells.
718  // NOTE: This may not succeed. Adding the container may need to be repeated after the
719  // object is created
721  }
722 
723  if (checkObjectExists && !(cellCont->GetCells())) {
724  AliFatal(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
725  }
726 
727  // Set the calo cells (may be null)
728  component->SetCaloCells(cellCont->GetCells());
729 
730  // It is possible that the cells pointer is null because it may not be created yet. For example,
731  // when combining cells. Thus, we must first check whether the pointer is available before checking
732  // for the number of cells. This could potentially decrease the amount of debug information, but this
733  // should rarely be an issue.
734  if (component->GetCaloCells()) {
735  AliDebugStream(3) << "Component GetNumberOfCells: " << component->GetCaloCells()->GetNumberOfCells() << std::endl;
736  }
737  }
738  }
739 }
740 
749 void AliEmcalCorrectionTask::SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, YAML::Node & userInputObjectNode, YAML::Node & defaultInputObjectNode, std::set <std::string> & requestedContainers)
750 {
751  // Our node contains all of the objects that we will want to create.
752  for(auto & containerName : requestedContainers)
753  {
754  // The section is the container name
755  //std::string containerName = it->first.as<std::string>();
756  // Skip if the particle or cluster container already exists
757  if (GetParticleContainer(containerName.c_str()) || GetClusterContainer(containerName.c_str())) {
758  continue;
759  }
760 
761  AliDebug(2, TString::Format("Processing container %s of inputType %d", containerName.c_str(), inputObjectType));
762  if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
763  SetupContainer(inputObjectType, containerName, userInputObjectNode, defaultInputObjectNode);
764  }
765  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
766  SetupCellsInfo(containerName, userInputObjectNode, defaultInputObjectNode);
767  }
768  }
769 }
770 
781 void AliEmcalCorrectionTask::SetupCellsInfo(std::string containerName, YAML::Node & userNode, YAML::Node & defaultNode)
782 {
783  // Define cell info
785 
786  AliDebugStream(2) << "User: " << std::endl << userNode << std::endl << "default: " << std::endl << defaultNode << std::endl;
787 
788  // Set properties
789  // Cells (object) name
790  cellObj->SetName(containerName);
791  // Branch name
792  std::string tempString = "";
793  AliEmcalCorrectionComponent::GetProperty("branchName", tempString, userNode, defaultNode, true, containerName);
794  if (tempString == "usedefault") {
796  }
797  cellObj->SetBranchName(tempString);
798 
799  // IsEmbedding
800  bool tempBool = false;
801  AliEmcalCorrectionComponent::GetProperty("embedding", tempBool, userNode, defaultNode, false, containerName);
802  cellObj->SetIsEmbedding(tempBool);
803 
804  // Add to the array to keep track of it
805  fCellCollArray.push_back(cellObj);
806 }
807 
825 void AliEmcalCorrectionTask::SetupContainer(AliEmcalContainerUtils::InputObject_t inputObjectType, std::string containerName, YAML::Node & userNode, YAML::Node & defaultNode)
826 {
827  // Create container
828  AliDebugStream(2) << "Adding container" << std::endl;
829  AliEmcalContainer * cont = AddContainer(inputObjectType, containerName, userNode, defaultNode);
830  AliDebugStream(2) << "Added container" << std::endl;
831 
832  // Set the container properties
833  //
834  // TODO: Consider if this can be converted to a map to function pointers. There are a number of details
835  // which can make it a bit complicated. Those details include inheritance, pointing to member
836  // functions, etc. It should all be possible, but may not be worth all of the extra work and code.
837  // Example ccode:
838  // SetValueInContainer("minPt", &cont::SetMinPt, tempDouble, userNode, defaultNode);
839  // SetValueInContainer("minE", &cont::SetMinE, tempDouble, userNode, defaultNode);
840 
841  // Temporary variables to store requested properties
842  std::string tempString = "";
843  Double_t tempDouble = 0;
844  bool tempBool = false;
845 
846  // AliEmcalContainer properties
847  // Min Pt
848  bool result = AliEmcalCorrectionComponent::GetProperty("minPt", tempDouble, userNode, defaultNode, false, containerName);
849  if (result) {
850  AliDebugStream(2) << cont->GetName() << ": Setting minPt of " << tempDouble << std::endl;
851  cont->SetMinPt(tempDouble);
852  }
853  // Min E
854  result = AliEmcalCorrectionComponent::GetProperty("minE", tempDouble, userNode, defaultNode, false, containerName);
855  if (result) {
856  AliDebugStream(2) << cont->GetName() << ": Setting minE of " << tempDouble << std::endl;
857  cont->SetMinE(tempDouble);
858  }
859  // Eta min, max
860  result = AliEmcalCorrectionComponent::GetProperty("minEta", tempDouble, userNode, defaultNode, false, containerName);
861  if (result) {
862  // Only continue checking if the min is there, since we must set both together
863  Double_t tempDouble2 = 0;
864  result = AliEmcalCorrectionComponent::GetProperty("maxEta", tempDouble, userNode, defaultNode, false, containerName);
865  if (result) {
866  AliDebugStream(2) << cont->GetName() << ": Setting eta limits of " << tempDouble << " to " << tempDouble2 << std::endl;
867  cont->SetEtaLimits(tempDouble, tempDouble2);
868  }
869  }
870  // Phi min, max
871  result = AliEmcalCorrectionComponent::GetProperty("minPhi", tempDouble, userNode, defaultNode, false, containerName);
872  if (result) {
873  // Only continue checking if the min is there, since we must set both together
874  Double_t tempDouble2 = 0;
875  result = AliEmcalCorrectionComponent::GetProperty("maxPhi", tempDouble, userNode, defaultNode, false, containerName);
876  if (result) {
877  AliDebugStream(2) << cont->GetName() << ": Setting phi limits of " << tempDouble << " to " << tempDouble2 << std::endl;
878  cont->SetPhiLimits(tempDouble, tempDouble2);
879  }
880  }
881  // Embedded
882  result = AliEmcalCorrectionComponent::GetProperty("IsEmbedded", tempBool, userNode, defaultNode, false, containerName);
883  if (result) {
884  AliDebugStream(2) << cont->GetName() << ": Setting embedding to " << (tempBool ? "enabled" : "disabled") << std::endl;
885  cont->SetIsEmbedding(tempBool);
886  }
887 
888  // Cluster specific properties
889  AliClusterContainer * clusterContainer = dynamic_cast<AliClusterContainer *>(cont);
890  if (clusterContainer) {
891  // Default energy
892  // Probably not needed for the corrections
893  /*result = AliEmcalCorrectionComponent::GetProperty("defaultClusterEnergy", tempString, userNode, defaultNode, false, containerName);
894  if (result) {
895  // Need to get the enumeration
896  AliVCluster::VCluUserDefEnergy_t clusterEnergyType = fgkClusterEnergyTypeMap.at(tempString);
897  AliDebugStream(2) << clusterContainer->GetName() << ": Setting cluster energy type to " << clusterEnergyType << std::endl;
898  clusterContainer->SetDefaultClusterEnergy(clusterEnergyType);
899  }*/
900 
901  // NonLinCorrEnergyCut
902  result = AliEmcalCorrectionComponent::GetProperty("clusNonLinCorrEnergyCut", tempDouble, userNode, defaultNode, false, containerName);
903  if (result) {
904  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusNonLinCorrEnergyCut of " << tempDouble << std::endl;
905  clusterContainer->SetClusNonLinCorrEnergyCut(tempDouble);
906  }
907 
908  // HadCorrEnergyCut
909  result = AliEmcalCorrectionComponent::GetProperty("clusHadCorrEnergyCut", tempDouble, userNode, defaultNode, false, containerName);
910  if (result) {
911  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusHadCorrEnergyCut of " << tempDouble << std::endl;
912  clusterContainer->SetClusHadCorrEnergyCut(tempDouble);
913  }
914 
915  // SetIncludePHOS
916  result = AliEmcalCorrectionComponent::GetProperty("includePHOS", tempBool, userNode, defaultNode, false, containerName);
917  if (result) {
918  AliDebugStream(2) << clusterContainer->GetName() << ": Setting Include PHOS to " << (tempBool ? "enabled" : "disabled") << std::endl;
919  clusterContainer->SetIncludePHOS(tempBool);
920  }
921  }
922 
923  // Track specific
924  AliTrackContainer * trackContainer = dynamic_cast<AliTrackContainer *>(cont);
925  if (trackContainer) {
926  // Track selection
927  // AOD Filter bits as a sequence
928  std::vector <UInt_t> filterBitsVector;
929  result = AliEmcalCorrectionComponent::GetProperty("aodFilterBits", filterBitsVector, userNode, defaultNode, false, containerName);
930  if (result){
931  UInt_t filterBits = 0;
932  for (int filterBit : filterBitsVector) {
933  filterBits += filterBit;
934  }
935  AliDebugStream(2) << trackContainer->GetName() << ": Setting filterBits of " << filterBits << std::endl;
936  trackContainer->SetAODFilterBits(filterBits);
937  }
938 
939  // SetTrackFilterType enum
940  result = AliEmcalCorrectionComponent::GetProperty("trackFilterType", tempString, userNode, defaultNode, false, containerName);
941  if (result) {
942  // Need to get the enumeration
943  AliEmcalTrackSelection::ETrackFilterType_t trackFilterType = fgkTrackFilterTypeMap.at(tempString);
944  AliDebugStream(2) << trackContainer->GetName() << ": Setting trackFilterType of " << trackFilterType << std::endl;
945  trackContainer->SetTrackFilterType(trackFilterType);
946  }
947 
948  // Track cuts period
949  result = AliEmcalCorrectionComponent::GetProperty("trackCutsPeriod", tempString, userNode, defaultNode, false, containerName);
950  if (result) {
951  // Need to get the enumeration
952  AliDebugStream(2) << trackContainer->GetName() << ": Setting track cuts period to " << tempString << std::endl;
953  trackContainer->SetTrackCutsPeriod(tempString.c_str());
954  }
955  }
956 }
957 
975 AliEmcalContainer * AliEmcalCorrectionTask::AddContainer(AliEmcalContainerUtils::InputObject_t contType, std::string & containerName, YAML::Node & userNode, YAML::Node & defaultNode)
976 {
977  // Determine the type of branch to request
978  std::string containerBranch = "";
980  AliFatal("Must specify type of container when requesting branch.");
981  }
982 
983  // Retrieve branch name
984  // YAML::Node() is just an empty node
985  AliDebugStream(2) << "User Node: " << userNode << std::endl;
986  AliDebugStream(2) << "Default Node: " << defaultNode << std::endl;
987  AliEmcalCorrectionComponent::GetProperty("branchName", containerBranch, userNode, defaultNode, true, containerName);
988  // Should be unnecessary, since the user can only do this if done explicitly.
989  /*if (containerBranch == "")
990  {
991  AliFatal(TString::Format("Request %i container, but the container branch is empty!", contType));
992  }*/
993 
994  // Determine proper name if using "usedefault" pattern
995  if (containerBranch == "usedefault") {
996  containerBranch = AliEmcalContainerUtils::DetermineUseDefaultName(contType, fIsEsd);
997  }
998 
999  // Create containers and set them to the name of the component
1000  AliEmcalContainer * cont = 0;
1001  if (contType == AliEmcalContainerUtils::kCluster)
1002  {
1003  cont = new AliClusterContainer(containerBranch.c_str());
1004  AdoptClusterContainer(dynamic_cast<AliClusterContainer *>(cont));
1005  }
1006  else if (contType == AliEmcalContainerUtils::kTrack)
1007  {
1008  if (containerBranch == "mcparticles") {
1009  cont = new AliMCParticleContainer(containerBranch.c_str());
1010  }
1011  else {
1012  cont = new AliTrackContainer(containerBranch.c_str());
1013  }
1014  AdoptParticleContainer(dynamic_cast<AliParticleContainer *>(cont));
1015  }
1016  cont->SetName(containerName.c_str());
1017 
1018  return cont;
1019 }
1020 
1030 {
1031  // Check that the configuration is initialized
1032  if (fConfigurationInitialized != true)
1033  {
1034  AliFatal("YAML configuration must be initialized before running (ie. the AddTask, run macro or wagon)!");
1035  }
1036 
1037  // Show the configurations info this is available
1038  AliDebugStream(4) << "User configuration string: " << fUserConfigurationString << std::endl;
1039  AliDebugStream(4) << "User configuration: " << fUserConfiguration << std::endl;
1040  AliDebugStream(4) << "Default configuration string: " << fDefaultConfigurationString << std::endl;
1041  AliDebugStream(4) << "Default configuration: " << fDefaultConfiguration << std::endl;
1042 
1043  // YAML Objects cannot be streamed, so we need to reinitialize them here.
1044  // They need reinitialize if they are null
1045  if (fUserConfiguration.IsNull() == true && fUserConfigurationString != "")
1046  {
1047  AliInfo("Reinitializing user configuration from string. Expected if running on grid!");
1049  }
1050  if (fDefaultConfiguration.IsNull() == true)
1051  {
1052  AliInfo("Reinitializing default configuration from string. Expected if running on grid!");
1054  }
1055 
1056  // Debug to check that the configuration has been (re)initiailzied has been completed correctly
1057  AliDebugStream(4) << "(Re)initialized user configuration: " << fUserConfigurationString << std::endl;
1058  AliDebugStream(4) << "(Re)initialized user configuration: " << fUserConfiguration << std::endl;
1059  AliDebugStream(4) << "(Re)initialized default configuration: " << fDefaultConfigurationString << std::endl;
1060  AliDebugStream(4) << "(Re)initialized default configuration: " << fDefaultConfiguration << std::endl;
1061 
1062  if (fForceBeamType == kpp)
1063  fNcentBins = 1;
1064 
1065  // Allow for output files
1066  OpenFile(1);
1067  fOutput = new TList();
1068  fOutput->SetOwner();
1069 
1071 
1072  PostData(1, fOutput);
1073 }
1074 
1082 {
1083  // Run the initialization for all derived classes.
1084  for (auto component : fCorrectionComponents)
1085  {
1086  // Set cent bins (usually used for hist creation)
1087  // It cannot be set until now because it can be changed after initialization
1088  // For instance, by SetForceBeamType()
1089  component->SetNcentralityBins(fNcentBins);
1090 
1091  component->UserCreateOutputObjects();
1092 
1093  if (component->GetOutputList() != 0)
1094  {
1095  // Adds a list to the list -- this doesn't work for some unknown reason
1096  //fOutput->Add(component->GetOutputList());
1097 
1098  // iterate through lists for each component, and fill in output
1099  TList* t = new TList();
1100  t->SetName(component->GetName());
1101  fOutput->AddLast(t);
1102  t = (TList*)fOutput->Last();
1103  TIter next(component->GetOutputList());
1104  while (TObject *obj = next()){
1105  t->Add(obj);
1106  }
1107 
1108  AliDebug(1, TString::Format("Added output list from task %s to output.", component->GetName()));
1109  }
1110  }
1111 }
1112 
1118 {
1119  // Initialize the event if not initialized
1120  if (!fEventInitialized)
1121  ExecOnce();
1122 
1123  // Only continue if we are initialized successfully
1124  if (!fEventInitialized)
1125  return;
1126 
1127  // Get the objects for each event
1128  if (!RetrieveEventObjects())
1129  return;
1130 
1131  // Call run for each correction
1132  if (!Run())
1133  return;
1134 }
1135 
1147 {
1148  if (!InputEvent()) {
1149  AliError("Could not retrieve event! Returning!");
1150  return;
1151  }
1152 
1153  // This warning was extracted out from the cell components
1154  if (dynamic_cast<AliAODEvent*>(InputEvent())) {
1155  AliWarning("=============================================================");
1156  AliWarning("=== Running on AOD is not equivalent to running on ESD! ===");
1157  AliWarning("=============================================================");
1158  }
1159 
1160  if (fNeedEmcalGeom) {
1161  fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(InputEvent()->GetRunNumber());
1162  if (!fGeom) {
1163  AliFatal("Can not get EMCal geometry instance. If you do not need the EMCal geometry, disable it by setting task->SetNeedEmcalGeometry(kFALSE).");
1164  return;
1165  }
1166  }
1167 
1168  // Load all requested track branches - each container knows name already
1169  for (Int_t i =0; i<fParticleCollArray.GetEntriesFast(); i++) {
1170  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
1172  cont->SetArray(InputEvent());
1173  }
1174 
1175  // Load all requested cluster branches - each container knows name already
1176  for (Int_t i =0; i<fClusterCollArray.GetEntriesFast(); i++) {
1177  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
1179  cont->SetArray(InputEvent());
1180  }
1181 
1182  // Determine the proper pointer for each cell object and save them to the cell container
1183  // At this point, they should all be created
1184  for (auto cellObj : fCellCollArray)
1185  {
1187  }
1188 
1189  fEventInitialized = kTRUE;
1190 
1191  // Print warning to the user that the rest of the configuration information is available in the generation log
1192  // when the Analysis Manager was created. Using cout to be certain that it is shown on the train!
1193  std::cout << "=== NOTE: Additional EMCal Corrections configuration information can be found when the Analysis Manager is configured. For a run macro, see above, while for a LEGO train, see the generation.log ===\n";
1194 
1195  // Setup the components
1197 }
1198 
1204 {
1205  // Run the initialization for all derived classes.
1206  for (auto component : fCorrectionComponents)
1207  {
1208  // Setup geometry
1209  component->SetEMCALGeometry(fGeom);
1210 
1211  // Set the input events. This is redundant to where it is set during Run(), but the events need to be
1212  // available to components, and they are only called one extra time.
1213  component->SetEvent(InputEvent());
1214  component->SetMCEvent(MCEvent());
1215 
1216  // Add the requested cells to the component
1218 
1219  // Component ExecOnce()
1220  component->ExecOnce();
1221 
1222  // If the cells were created during ExecOnce(), then we need to re-initialize the pointer to ensure
1223  // that it is not null!
1224  if (!(component->GetCaloCells())) {
1225  AliDebugStream(2) << "Re-initializing cells for component " << component->GetName() << std::endl;
1227  }
1228  }
1229 }
1230 
1236 {
1237  fVertex[0] = 0;
1238  fVertex[1] = 0;
1239  fVertex[2] = 0;
1240  fNVertCont = 0;
1241 
1242  const AliVVertex *vert = InputEvent()->GetPrimaryVertex();
1243  if (vert) {
1244  vert->GetXYZ(fVertex);
1245  fNVertCont = vert->GetNContributors();
1246  }
1247 
1248  fBeamType = GetBeamType();
1249 
1250  if (fBeamType == kAA || fBeamType == kpA ) {
1252  AliMultSelection *MultSelection = static_cast<AliMultSelection*>(InputEvent()->FindListObject("MultSelection"));
1253  if (MultSelection) {
1254  fCent = MultSelection->GetMultiplicityPercentile(fCentEst.Data());
1255  }
1256  else {
1257  AliWarning("Could not retrieve centrality information! Assuming 99");
1258  }
1259  }
1260  else { // old centrality estimation < 2015
1261  AliCentrality *aliCent = InputEvent()->GetCentrality();
1262  if (aliCent) {
1263  fCent = aliCent->GetCentralityPercentile(fCentEst.Data());
1264  }
1265  else {
1266  AliWarning("Could not retrieve centrality information! Assuming 99");
1267  }
1268  }
1269 
1270  if (fNcentBins==4) {
1271  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1272  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1273  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1274  else if (fCent >= 50 && fCent <= 100) fCentBin = 3;
1275  else {
1276  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1277  fCentBin = fNcentBins-1;
1278  }
1279  }
1280  else if (fNcentBins==5) { // for PbPb 2015
1281  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1282  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1283  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1284  else if (fCent >= 50 && fCent <= 90) fCentBin = 3;
1285  else if (fCent > 90) {
1286  fCent = 99;
1287  fCentBin = 4;
1288  }
1289  else {
1290  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1291  fCentBin = fNcentBins-1;
1292  }
1293  }
1294  else {
1295  Double_t centWidth = (fMaxCent-fMinCent)/(Double_t)fNcentBins;
1296  if(centWidth>0.) {
1297  fCentBin = TMath::FloorNint(fCent/centWidth);
1298  }
1299  else {
1300  fCentBin = 0;
1301  }
1302  if (fCentBin>=fNcentBins) {
1303  AliWarning(Form("fCentBin too large: cent = %f fCentBin = %d. Assuming 99", fCent, fCentBin));
1304  fCentBin = fNcentBins-1;
1305  }
1306  }
1307  }
1308  else {
1309  fCent = 99;
1310  fCentBin = 0;
1311  }
1312 
1313  AliEmcalContainer* cont = 0;
1314 
1315  TIter nextPartColl(&fParticleCollArray);
1316  while ((cont = static_cast<AliEmcalContainer*>(nextPartColl()))) cont->NextEvent();
1317 
1318  TIter nextClusColl(&fClusterCollArray);
1319  while ((cont = static_cast<AliEmcalContainer*>(nextClusColl()))) cont->NextEvent();
1320 
1321  return kTRUE;
1322 }
1323 
1329 {
1330  // Run the initialization for all derived classes.
1331  for (auto component : fCorrectionComponents)
1332  {
1333  component->SetEvent(InputEvent());
1334  component->SetMCEvent(MCEvent());
1335  component->SetCentralityBin(fCentBin);
1336  component->SetCentrality(fCent);
1337 
1338  component->Run();
1339  }
1340 
1341  PostData(1, fOutput);
1342 
1343  return kTRUE;
1344 }
1345 
1350 {
1351  // Run the initialization for all derived classes.
1352  for (auto component : fCorrectionComponents)
1353  {
1354  component->UserNotify();
1355  }
1356 
1357  return kTRUE;
1358 }
1359 
1366 std::ostream & AliEmcalCorrectionTask::PrintConfigurationString(std::ostream & in, bool userConfig) const
1367 {
1368  std::string stringToWrite = userConfig ? fUserConfigurationString : fDefaultConfigurationString;
1369  if (stringToWrite == "") {
1370  AliWarning(TString::Format("%s configuration is empty!", userConfig ? "User" : "Default"));
1371  }
1372  in << stringToWrite;
1373 
1374  return in;
1375 }
1376 
1384 bool AliEmcalCorrectionTask::WriteConfigurationFile(std::string filename, bool userConfig) const
1385 {
1386  bool returnValue = false;
1387  if (filename != "")
1388  {
1389  if (fConfigurationInitialized == true)
1390  {
1391  std::ofstream outFile(filename);
1392  PrintConfigurationString(outFile, userConfig);
1393  outFile.close();
1394 
1395  returnValue = true;
1396  }
1397  else
1398  {
1399  AliError(TString::Format("Configuration not properly initialized! Cannot print %s configuration!", userConfig ? "user" : "default"));
1400  }
1401 
1402  }
1403  else
1404  {
1405  AliError("Please pass a valid filename instead of empty quotes!");
1406  }
1407  return returnValue;
1408 }
1409 
1417 bool AliEmcalCorrectionTask::CompareToStoredConfiguration(std::string filename, bool userConfig) const
1418 {
1419  bool returnValue = false;
1420  if (filename != "")
1421  {
1422  if (fConfigurationInitialized == true)
1423  {
1424  // Generate YAML nodes for the comparison
1425  YAML::Node passedNode = YAML::LoadFile(filename);
1426  YAML::Node comparisonNode = YAML::Load(userConfig ? fUserConfigurationString : fDefaultConfigurationString);
1427 
1428  // Need to stream the configuration back to a string to remove the comments
1429  // since they are not preserved in the YAML node.
1430  std::stringstream passedNodeSS;
1431  passedNodeSS << passedNode;
1432 
1433  // Compare the nodes. Make the comparison as strings, as the YAML nodes do _not_ match, despite the strings matching.
1434  // In fact, the YAML nodes will _not_ match even if they are generated from the same string....
1435  if (passedNodeSS.str() == (userConfig ? fUserConfigurationString : fDefaultConfigurationString)) {
1436  returnValue = true;
1437  }
1438  else {
1439  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";
1440  }
1441  }
1442  else
1443  {
1444  AliError(TString::Format("Configuration not properly initialized! Cannot compare %s configuration!", userConfig ? "user" : "default"));
1445  }
1446 
1447  }
1448  else
1449  {
1450  AliError("Please pass a valid filename instead of empty quotes!");
1451  }
1452  return returnValue;
1453 }
1454 
1463 inline bool AliEmcalCorrectionTask::DoesFileExist(const std::string & filename)
1464 {
1465  std::ifstream inFile(filename);
1466  return inFile.good();
1467 }
1468 
1478 {
1479  if (filename != "")
1480  {
1481  // Handle if in AliPhysics and includes $ALICE_PHYSICS
1482  filename = gSystem->ExpandPathName(filename.c_str());
1483 
1484  // Handle grid
1485  if(filename.find("alien://") != std::string::npos)
1486  {
1487  AliDebug(2, TString::Format("Opening file \"%s\" on the grid!", filename.c_str()));
1488  // Initialize alien connection if needed
1489  if (!gGrid) {
1490  TGrid::Connect("alien://");
1491  }
1492 
1493  // Determine the local filename and copy file to local directory
1494  std::string localFilename = gSystem->BaseName(filename.c_str());
1495  // Ensures that the default and user files do not conflict if both are taken from the grid and have the same filename
1496  if (userFile == true) {
1497  localFilename = "user" + localFilename;
1498  }
1499  TFile::Cp(filename.c_str(), localFilename.c_str());
1500 
1501  // yaml-cpp should only open the local file
1502  filename = localFilename;
1503  }
1504  }
1505 }
1506 
1514 {
1515  AliDebugStream(2) << "Retrieving cells object " << cellContainer->GetName() << std::endl;
1516  // Check for embedding and return object
1517  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cellContainer->GetIsEmbedding());
1518 
1519  cellContainer->SetCells(dynamic_cast<AliVCaloCells *>(event->FindListObject(cellContainer->GetBranchName().c_str())));
1520 }
1521 
1532 {
1533  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cont->GetIsEmbedding());
1534 
1535  TClonesArray * array = dynamic_cast<TClonesArray *>(event->FindListObject(cont->GetArrayName()));
1536  if (!array) {
1537  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()));
1538  array = new TClonesArray(AliEmcalContainerUtils::DetermineUseDefaultName(objectType, fIsEsd, true).c_str());
1539  array->SetName(cont->GetArrayName());
1540  event->AddObject(array);
1541  }
1542 }
1543 
1552 {
1553  // Get container node
1554  std::string inputObjectName = "";
1555  if (inputObjectType == AliEmcalContainerUtils::kCluster) {
1556  inputObjectName = "clusterContainers";
1557  }
1558  else if (inputObjectType == AliEmcalContainerUtils::kTrack) {
1559  inputObjectName = "trackContainers";
1560  }
1561  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1562  inputObjectName = "cells";
1563  }
1564  else {
1565  AliFatal(TString::Format("Unrecognized input object type %d", inputObjectType));
1566  }
1567 
1568  return inputObjectName;
1569 }
1570 
1582 bool AliEmcalCorrectionTask::CheckPossibleNamesForComponentName(std::string & name, std::set <std::string> & possibleComponents)
1583 {
1584  bool foundComponent = false;
1585  for (auto & possibleComponent : possibleComponents)
1586  {
1587  if (possibleComponent == name) {
1588  foundComponent = true;
1589  break;
1590  }
1591  }
1592 
1593  return foundComponent;
1594 }
1595 
1603 {
1604  if (fForceBeamType != kNA)
1605  return fForceBeamType;
1606 
1607  AliESDEvent *esd = dynamic_cast<AliESDEvent*>(InputEvent());
1608  if (esd) {
1609  const AliESDRun *run = esd->GetESDRun();
1610  TString beamType = run->GetBeamType();
1611  if (beamType == "p-p")
1612  return kpp;
1613  else if (beamType == "A-A")
1614  return kAA;
1615  else if (beamType == "p-A")
1616  return kpA;
1617  else
1618  return kNA;
1619  } else {
1620  Int_t runNumber = InputEvent()->GetRunNumber();
1621  // All run number ranges taken from the RCT
1622  if ((runNumber >= 136833 && runNumber <= 139517) || // LHC10h
1623  (runNumber >= 167693 && runNumber <= 170593) || // LHC11h
1624  (runNumber >= 244824 && runNumber <= 246994)) { // LHC15o
1625  return kAA;
1626  } else if ((runNumber >= 188356 && runNumber <= 188366) || // LHC12g
1627  (runNumber >= 195164 && runNumber <= 197388) || // LHC13b-f
1628  (runNumber >= 265015 && runNumber <= 267166)) { // LHC16q-t
1629  return kpA;
1630  } else {
1631  return kpp;
1632  }
1633  }
1634 }
1635 
1640 {
1641  if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1642  stream << "Cells info: " << std::endl;
1643  for (auto cellInfo : fCellCollArray) {
1644  stream << "\tName: " << cellInfo->GetName() << "\tBranch: " << cellInfo->GetBranchName() << "\tIsEmbedding: " << std::boolalpha << cellInfo->GetIsEmbedding() << std::endl;
1645  }
1646  }
1647  else if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
1648  stream << (inputObjectType == AliEmcalContainerUtils::kCluster ? "Cluster" : "Track") << " container info: " << std::endl;
1649  AliEmcalContainer * cont = 0;
1650  for (auto containerInfo : (inputObjectType == AliEmcalContainerUtils::kCluster ? fClusterCollArray : fParticleCollArray) ) {
1651  cont = static_cast<AliEmcalContainer *>(containerInfo);
1652  stream << "\tName: " << cont->GetName() << "\tBranch: " << cont->GetArrayName() << "\tTitle: " << cont->GetTitle() << "\tIsEmbedding:" << std::boolalpha << cont->GetIsEmbedding() << std::endl;
1653  }
1654  }
1655  else {
1656  AliErrorStream() << "Unrecognized input object type " << inputObjectType << std::endl;
1657  }
1658 }
1659 
1669 void AliEmcalCorrectionTask::GetNodeForInputObjects(YAML::Node & inputNode, YAML::Node & nodeToRetrieveFrom, std::string & inputObjectName, bool requiredProperty)
1670 {
1671  // Get the user input node
1672  AliEmcalCorrectionComponent::GetProperty(inputObjectName.c_str(), inputNode, YAML::Node(), nodeToRetrieveFrom, requiredProperty, "inputObjects");
1673 
1674  // Get the user shared node and add it back to the user node so that shared parameters are available
1675  if (nodeToRetrieveFrom["sharedParameters"]) {
1676  inputNode["sharedParameters"] = nodeToRetrieveFrom["sharedParameters"];
1677  }
1678 }
1679 
1690 void AliEmcalCorrectionTask::GetPropertyNamesFromNode(const std::string & componentName, const YAML::Node & node, std::set <std::string> & propertyNames, const bool nodeRequired)
1691 {
1692  YAML::Node tempNode;
1693  AliEmcalCorrectionComponent::GetProperty(componentName, tempNode, YAML::Node(), node, nodeRequired, "");
1694  for (auto propertyName : tempNode)
1695  {
1696  propertyNames.insert(propertyName.first.as<std::string>());
1697  }
1698 }
1699 
1707 AliEmcalCorrectionCellContainer * AliEmcalCorrectionTask::GetCellContainer(const std::string & cellsContainerName) const
1708 {
1709  for (auto cellContainer : fCellCollArray)
1710  {
1711  if (cellContainer->GetName() == cellsContainerName) {
1712  return cellContainer;
1713  }
1714  }
1715 
1716  return 0;
1717 }
1718 
1720 {
1721  // Get the pointer to the existing analysis manager via the static access method.
1722  //==============================================================================
1723  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1724  if (!mgr)
1725  {
1726  ::Error("AddTaskEmcalCorrectionTask", "No analysis manager to connect to.");
1727  return 0;
1728  }
1729 
1730  // Check the analysis type using the event handlers connected to the analysis manager.
1731  //==============================================================================
1732  AliVEventHandler* handler = mgr->GetInputEventHandler();
1733  if (!handler)
1734  {
1735  ::Error("AddTaskEmcalCorrectionTask", "This task requires an input event handler");
1736  return 0;
1737  }
1738 
1739  TString name = "AliEmcalCorrectionTask";
1740  if (suffix != "") {
1741  name += TString::Format("_%s", suffix.Data());
1742  }
1743 
1744  AliEmcalCorrectionTask* mgrTask = static_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.Data()));
1745  if (mgrTask) return mgrTask;
1746 
1747  // Create the task that manages the corrections
1748  AliEmcalCorrectionTask* correctionTask = new AliEmcalCorrectionTask(name.Data());
1749 
1750  //-------------------------------------------------------
1751  // Final settings, pass to manager and set the containers
1752  //-------------------------------------------------------
1753 
1754  mgr->AddTask(correctionTask);
1755 
1756  // Create containers for input/output
1757  AliAnalysisDataContainer* cInput = mgr->GetCommonInputContainer();
1758 
1759  TString outputContainerName(name);
1760  outputContainerName += "_histos";
1761 
1762  AliAnalysisDataContainer * cOutput = mgr->CreateContainer(outputContainerName.Data(),
1763  TList::Class(),
1764  AliAnalysisManager::kOutputContainer,
1765  Form("%s", AliAnalysisManager::GetCommonFileName()));
1766 
1767  mgr->ConnectInput(correctionTask, 0, cInput);
1768  mgr->ConnectOutput(correctionTask, 1, cOutput);
1769 
1770  //TObjArray* cnt = mgr->GetContainers();
1771 
1772  return correctionTask;
1773 }
1774 
1780 std::string AliEmcalCorrectionTask::toString(bool includeYAMLConfigurationInfo) const
1781 {
1782  std::stringstream tempSS;
1783 
1784  // Show the correction components
1785  tempSS << "Correction components:\n";
1786  for (auto component : fOrderedComponentsToExecute) {
1787  tempSS << "\t" << component << "\n";
1788  }
1789  // Input objects
1790  tempSS << "\nInput objects:\n";
1794 
1795  if (includeYAMLConfigurationInfo == true) {
1796  tempSS << "\nUser Configuration:\n";
1797  PrintConfigurationString(tempSS, true);
1798  tempSS << "\n\nDefault Configuration:\n";
1799  PrintConfigurationString(tempSS);
1800  tempSS << "\n";
1801  }
1802 
1803  return tempSS.str();
1804 }
1805 
1812 std::ostream & AliEmcalCorrectionTask::Print(std::ostream & in) const {
1813  in << toString();
1814  return in;
1815 }
1816 
1824 std::ostream & operator<<(std::ostream & in, const AliEmcalCorrectionTask & myTask)
1825 {
1826  std::ostream & result = myTask.Print(in);
1827  return result;
1828 }
1829 
1837 {
1838  std::string temp(opt);
1839  bool includeYAMLConfig = false;
1840  if (temp == "YAML") {
1841  includeYAMLConfig = true;
1842  }
1843  Printf("%s", toString(includeYAMLConfig).c_str());
1844 }
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
return jsonbuilder str().c_str()
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)
ClassImp(AliAnalysisTaskCRC) AliAnalysisTaskCRC
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