AliPhysics  1168478 (1168478)
 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 
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  fSuffix(""),
63  fUserConfiguration(),
64  fUserConfigurationFilename(""),
65  fUserConfigurationString(""),
66  fDefaultConfiguration(),
67  fDefaultConfigurationFilename(""),
68  fDefaultConfigurationString(""),
69  fCorrectionComponents(),
70  fIsEsd(false),
71  fForceBeamType(kNA),
72  fConfigurationInitialized(false),
73  fOrderedComponentsToExecute(),
74  fEventInitialized(false),
75  fCent(0),
76  fCentBin(-1),
77  fMinCent(-999),
78  fMaxCent(-999),
79  fNcentBins(4),
80  fCentEst("V0M"),
81  fUseNewCentralityEstimation(kFALSE),
82  fVertex{0},
83  fNVertCont(0),
84  fBeamType(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  fSuffix(""),
111  fUserConfiguration(),
112  fUserConfigurationFilename(""),
113  fUserConfigurationString(""),
114  fDefaultConfiguration(),
115  fDefaultConfigurationFilename(""),
116  fDefaultConfigurationString(""),
117  fCorrectionComponents(),
118  fIsEsd(false),
119  fForceBeamType(kNA),
120  fConfigurationInitialized(false),
121  fOrderedComponentsToExecute(),
122  fEventInitialized(false),
123  fCent(0),
124  fCentBin(-1),
125  fMinCent(-999),
126  fMaxCent(-999),
127  fNcentBins(4),
128  fCentEst("V0M"),
129  fUseNewCentralityEstimation(kFALSE),
130  fVertex{0},
131  fNVertCont(0),
132  fBeamType(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  component->Initialize();
600 
601  if (component)
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  else if (inputObjectType == AliEmcalContainerUtils::kTrack)
698  {
699  AliEmcalContainer * cont = GetParticleContainer(str.c_str());
700  AliDebugStream(2) << "Adding particle container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
701 
702  if (checkObjectExists && !cont) {
703  AliFatal(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
704  }
705  component->AdoptParticleContainer(GetParticleContainer(str.c_str()));
706  }
707  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells)
708  {
709  // NOTE: This operates different than the others. This should be executed during run time rather than during initialization!
710  if (inputObjects.size() > 1) {
711  AliFatal(TString::Format("Component %s requested more than one cell branch, but this is not supported! Check the configuration!", component->GetName()));
712  }
713 
714  // If we've made it here, this must be at least one entry
716  AliDebugStream(2) << "Adding calo cells \"" << cellCont->GetName() << "\" of branch name \"" << cellCont->GetBranchName() << "\" to component " << component->GetName() << std::endl;
717 
718  if (!(cellCont->GetCells())) {
719  // Attempt to re-initialize the cells.
720  // NOTE: This may not succeed. Adding the container may need to be repeated after the
721  // object is created
723  }
724 
725  if (checkObjectExists && !(cellCont->GetCells())) {
726  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()));
727  }
728 
729  // Set the calo cells (may be null)
730  component->SetCaloCells(cellCont->GetCells());
731 
732  // It is possible that the cells pointer is null because it may not be created yet. For example,
733  // when combining cells. Thus, we must first check whether the pointer is available before checking
734  // for the number of cells. This could potentially decrease the amount of debug information, but this
735  // should rarely be an issue.
736  if (component->GetCaloCells()) {
737  AliDebugStream(3) << "Component GetNumberOfCells: " << component->GetCaloCells()->GetNumberOfCells() << std::endl;
738  }
739  }
740  }
741 }
742 
751 void AliEmcalCorrectionTask::SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, YAML::Node & userInputObjectNode, YAML::Node & defaultInputObjectNode, std::set <std::string> & requestedContainers)
752 {
753  // Our node contains all of the objects that we will want to create.
754  for(auto & containerName : requestedContainers)
755  {
756  // The section is the container name
757  //std::string containerName = it->first.as<std::string>();
758  // Skip if the particle or cluster container already exists
759  if (GetParticleContainer(containerName.c_str()) || GetClusterContainer(containerName.c_str())) {
760  continue;
761  }
762 
763  AliDebug(2, TString::Format("Processing container %s of inputType %d", containerName.c_str(), inputObjectType));
764  if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
765  SetupContainer(inputObjectType, containerName, userInputObjectNode, defaultInputObjectNode);
766  }
767  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
768  SetupCellsInfo(containerName, userInputObjectNode, defaultInputObjectNode);
769  }
770  }
771 }
772 
783 void AliEmcalCorrectionTask::SetupCellsInfo(std::string containerName, YAML::Node & userNode, YAML::Node & defaultNode)
784 {
785  // Define cell info
787 
788  AliDebugStream(2) << "User: " << std::endl << userNode << std::endl << "default: " << std::endl << defaultNode << std::endl;
789 
790  // Set properties
791  // Cells (object) name
792  cellObj->SetName(containerName);
793  // Branch name
794  std::string tempString = "";
795  AliEmcalCorrectionComponent::GetProperty("branchName", tempString, userNode, defaultNode, true, containerName);
796  if (tempString == "usedefault") {
798  }
799  cellObj->SetBranchName(tempString);
800 
801  // IsEmbedding
802  bool tempBool = false;
803  AliEmcalCorrectionComponent::GetProperty("embedding", tempBool, userNode, defaultNode, false, containerName);
804  cellObj->SetIsEmbedding(tempBool);
805 
806  // Add to the array to keep track of it
807  fCellCollArray.push_back(cellObj);
808 }
809 
827 void AliEmcalCorrectionTask::SetupContainer(AliEmcalContainerUtils::InputObject_t inputObjectType, std::string containerName, YAML::Node & userNode, YAML::Node & defaultNode)
828 {
829  // Create container
830  AliDebugStream(2) << "Adding container" << std::endl;
831  AliEmcalContainer * cont = AddContainer(inputObjectType, containerName, userNode, defaultNode);
832  AliDebugStream(2) << "Added container" << std::endl;
833 
834  // Set the container properties
835  //
836  // TODO: Consider if this can be converted to a map to function pointers. There are a number of details
837  // which can make it a bit complicated. Those details include inheritance, pointing to member
838  // functions, etc. It should all be possible, but may not be worth all of the extra work and code.
839  // Example ccode:
840  // SetValueInContainer("minPt", &cont::SetMinPt, tempDouble, userNode, defaultNode);
841  // SetValueInContainer("minE", &cont::SetMinE, tempDouble, userNode, defaultNode);
842 
843  // Temporary variables to store requested properties
844  std::string tempString = "";
845  Double_t tempDouble = 0;
846  bool tempBool = false;
847 
848  // AliEmcalContainer properties
849  // Min Pt
850  bool result = AliEmcalCorrectionComponent::GetProperty("minPt", tempDouble, userNode, defaultNode, false, containerName);
851  if (result) {
852  AliDebugStream(2) << cont->GetName() << ": Setting minPt of " << tempDouble << std::endl;
853  cont->SetMinPt(tempDouble);
854  }
855  // Min E
856  result = AliEmcalCorrectionComponent::GetProperty("minE", tempDouble, userNode, defaultNode, false, containerName);
857  if (result) {
858  AliDebugStream(2) << cont->GetName() << ": Setting minE of " << tempDouble << std::endl;
859  cont->SetMinE(tempDouble);
860  }
861  // Eta min, max
862  result = AliEmcalCorrectionComponent::GetProperty("minEta", tempDouble, userNode, defaultNode, false, containerName);
863  if (result) {
864  // Only continue checking if the min is there, since we must set both together
865  Double_t tempDouble2 = 0;
866  result = AliEmcalCorrectionComponent::GetProperty("maxEta", tempDouble, userNode, defaultNode, false, containerName);
867  if (result) {
868  AliDebugStream(2) << cont->GetName() << ": Setting eta limits of " << tempDouble << " to " << tempDouble2 << std::endl;
869  cont->SetEtaLimits(tempDouble, tempDouble2);
870  }
871  }
872  // Phi min, max
873  result = AliEmcalCorrectionComponent::GetProperty("minPhi", tempDouble, userNode, defaultNode, false, containerName);
874  if (result) {
875  // Only continue checking if the min is there, since we must set both together
876  Double_t tempDouble2 = 0;
877  result = AliEmcalCorrectionComponent::GetProperty("maxPhi", tempDouble, userNode, defaultNode, false, containerName);
878  if (result) {
879  AliDebugStream(2) << cont->GetName() << ": Setting phi limits of " << tempDouble << " to " << tempDouble2 << std::endl;
880  cont->SetPhiLimits(tempDouble, tempDouble2);
881  }
882  }
883  // Embedded
884  result = AliEmcalCorrectionComponent::GetProperty("embedding", tempBool, userNode, defaultNode, false, containerName);
885  if (result) {
886  AliDebugStream(2) << cont->GetName() << ": Setting embedding to " << (tempBool ? "enabled" : "disabled") << std::endl;
887  cont->SetIsEmbedding(tempBool);
888  }
889 
890  // Cluster specific properties
891  AliClusterContainer * clusterContainer = dynamic_cast<AliClusterContainer *>(cont);
892  if (clusterContainer) {
893  // Default energy
894  // Probably not needed for the corrections
895  /*result = AliEmcalCorrectionComponent::GetProperty("defaultClusterEnergy", tempString, userNode, defaultNode, false, containerName);
896  if (result) {
897  // Need to get the enumeration
898  AliVCluster::VCluUserDefEnergy_t clusterEnergyType = fgkClusterEnergyTypeMap.at(tempString);
899  AliDebugStream(2) << clusterContainer->GetName() << ": Setting cluster energy type to " << clusterEnergyType << std::endl;
900  clusterContainer->SetDefaultClusterEnergy(clusterEnergyType);
901  }*/
902 
903  // NonLinCorrEnergyCut
904  result = AliEmcalCorrectionComponent::GetProperty("clusNonLinCorrEnergyCut", tempDouble, userNode, defaultNode, false, containerName);
905  if (result) {
906  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusNonLinCorrEnergyCut of " << tempDouble << std::endl;
907  clusterContainer->SetClusNonLinCorrEnergyCut(tempDouble);
908  }
909 
910  // HadCorrEnergyCut
911  result = AliEmcalCorrectionComponent::GetProperty("clusHadCorrEnergyCut", tempDouble, userNode, defaultNode, false, containerName);
912  if (result) {
913  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusHadCorrEnergyCut of " << tempDouble << std::endl;
914  clusterContainer->SetClusHadCorrEnergyCut(tempDouble);
915  }
916 
917  // SetIncludePHOS
918  result = AliEmcalCorrectionComponent::GetProperty("includePHOS", tempBool, userNode, defaultNode, false, containerName);
919  if (result) {
920  AliDebugStream(2) << clusterContainer->GetName() << ": Setting Include PHOS to " << (tempBool ? "enabled" : "disabled") << std::endl;
921  clusterContainer->SetIncludePHOS(tempBool);
922  }
923  }
924 
925  // Track specific
926  AliTrackContainer * trackContainer = dynamic_cast<AliTrackContainer *>(cont);
927  if (trackContainer) {
928  // Track selection
929  // AOD Filter bits as a sequence
930  std::vector <UInt_t> filterBitsVector;
931  result = AliEmcalCorrectionComponent::GetProperty("aodFilterBits", filterBitsVector, userNode, defaultNode, false, containerName);
932  if (result){
933  UInt_t filterBits = 0;
934  for (int filterBit : filterBitsVector) {
935  filterBits += filterBit;
936  }
937  AliDebugStream(2) << trackContainer->GetName() << ": Setting filterBits of " << filterBits << std::endl;
938  trackContainer->SetAODFilterBits(filterBits);
939  }
940 
941  // SetTrackFilterType enum
942  result = AliEmcalCorrectionComponent::GetProperty("trackFilterType", tempString, userNode, defaultNode, false, containerName);
943  if (result) {
944  // Need to get the enumeration
945  AliEmcalTrackSelection::ETrackFilterType_t trackFilterType = fgkTrackFilterTypeMap.at(tempString);
946  AliDebugStream(2) << trackContainer->GetName() << ": Setting trackFilterType of " << trackFilterType << std::endl;
947  trackContainer->SetTrackFilterType(trackFilterType);
948  }
949 
950  // Track cuts period
951  result = AliEmcalCorrectionComponent::GetProperty("trackCutsPeriod", tempString, userNode, defaultNode, false, containerName);
952  if (result) {
953  // Need to get the enumeration
954  AliDebugStream(2) << trackContainer->GetName() << ": Setting track cuts period to " << tempString << std::endl;
955  trackContainer->SetTrackCutsPeriod(tempString.c_str());
956  }
957  }
958 }
959 
977 AliEmcalContainer * AliEmcalCorrectionTask::AddContainer(AliEmcalContainerUtils::InputObject_t contType, std::string & containerName, YAML::Node & userNode, YAML::Node & defaultNode)
978 {
979  // Determine the type of branch to request
980  std::string containerBranch = "";
982  AliFatal("Must specify type of container when requesting branch.");
983  }
984 
985  // Retrieve branch name
986  // YAML::Node() is just an empty node
987  AliDebugStream(2) << "User Node: " << userNode << std::endl;
988  AliDebugStream(2) << "Default Node: " << defaultNode << std::endl;
989  AliEmcalCorrectionComponent::GetProperty("branchName", containerBranch, userNode, defaultNode, true, containerName);
990  // Should be unnecessary, since the user can only do this if done explicitly.
991  /*if (containerBranch == "")
992  {
993  AliFatal(TString::Format("Request %i container, but the container branch is empty!", contType));
994  }*/
995 
996  // Determine proper name if using "usedefault" pattern
997  if (containerBranch == "usedefault") {
998  containerBranch = AliEmcalContainerUtils::DetermineUseDefaultName(contType, fIsEsd);
999  }
1000 
1001  // Create containers and set them to the name of the component
1002  AliEmcalContainer * cont = 0;
1003  if (contType == AliEmcalContainerUtils::kCluster)
1004  {
1005  cont = new AliClusterContainer(containerBranch.c_str());
1006  AdoptClusterContainer(dynamic_cast<AliClusterContainer *>(cont));
1007  }
1008  else if (contType == AliEmcalContainerUtils::kTrack)
1009  {
1010  if (containerBranch == "mcparticles") {
1011  cont = new AliMCParticleContainer(containerBranch.c_str());
1012  }
1013  else {
1014  cont = new AliTrackContainer(containerBranch.c_str());
1015  }
1016  AdoptParticleContainer(dynamic_cast<AliParticleContainer *>(cont));
1017  }
1018  cont->SetName(containerName.c_str());
1019 
1020  return cont;
1021 }
1022 
1032 {
1033  // Check that the configuration is initialized
1034  if (fConfigurationInitialized != true)
1035  {
1036  AliFatal("YAML configuration must be initialized before running (ie. the AddTask, run macro or wagon)!");
1037  }
1038 
1039  // Show the configurations info this is available
1040  AliDebugStream(4) << "User configuration string: " << fUserConfigurationString << std::endl;
1041  AliDebugStream(4) << "User configuration: " << fUserConfiguration << std::endl;
1042  AliDebugStream(4) << "Default configuration string: " << fDefaultConfigurationString << std::endl;
1043  AliDebugStream(4) << "Default configuration: " << fDefaultConfiguration << std::endl;
1044 
1045  // YAML Objects cannot be streamed, so we need to reinitialize them here.
1046  // They need reinitialize if they are null
1047  if (fUserConfiguration.IsNull() == true && fUserConfigurationString != "")
1048  {
1049  AliInfo("Reinitializing user configuration from string. Expected if running on grid!");
1051  }
1052  if (fDefaultConfiguration.IsNull() == true)
1053  {
1054  AliInfo("Reinitializing default configuration from string. Expected if running on grid!");
1056  }
1057 
1058  // Debug to check that the configuration has been (re)initiailzied has been completed correctly
1059  AliDebugStream(4) << "(Re)initialized user configuration: " << fUserConfigurationString << std::endl;
1060  AliDebugStream(4) << "(Re)initialized user configuration: " << fUserConfiguration << std::endl;
1061  AliDebugStream(4) << "(Re)initialized default configuration: " << fDefaultConfigurationString << std::endl;
1062  AliDebugStream(4) << "(Re)initialized default configuration: " << fDefaultConfiguration << std::endl;
1063 
1064  if (fForceBeamType == kpp)
1065  fNcentBins = 1;
1066 
1067  // Allow for output files
1068  OpenFile(1);
1069  fOutput = new TList();
1070  fOutput->SetOwner();
1071 
1073 
1074  PostData(1, fOutput);
1075 }
1076 
1084 {
1085  // Run the initialization for all derived classes.
1086  for (auto component : fCorrectionComponents)
1087  {
1088  // Set cent bins (usually used for hist creation)
1089  // It cannot be set until now because it can be changed after initialization
1090  // For instance, by SetForceBeamType()
1091  component->SetNcentralityBins(fNcentBins);
1092 
1093  component->UserCreateOutputObjects();
1094 
1095  if (component->GetOutputList() != 0)
1096  {
1097  // Adds a list to the list -- this doesn't work for some unknown reason
1098  //fOutput->Add(component->GetOutputList());
1099 
1100  // iterate through lists for each component, and fill in output
1101  TList* t = new TList();
1102  t->SetName(component->GetName());
1103  fOutput->AddLast(t);
1104  t = (TList*)fOutput->Last();
1105  TIter next(component->GetOutputList());
1106  while (TObject *obj = next()){
1107  t->Add(obj);
1108  }
1109 
1110  AliDebug(1, TString::Format("Added output list from task %s to output.", component->GetName()));
1111  }
1112  }
1113 }
1114 
1120 {
1121  // Initialize the event if not initialized
1122  if (!fEventInitialized)
1123  ExecOnce();
1124 
1125  // Only continue if we are initialized successfully
1126  if (!fEventInitialized)
1127  return;
1128 
1129  // Get the objects for each event
1130  if (!RetrieveEventObjects())
1131  return;
1132 
1133  // Call run for each correction
1134  if (!Run())
1135  return;
1136 }
1137 
1149 {
1150  if (!InputEvent()) {
1151  AliError("Could not retrieve event! Returning!");
1152  return;
1153  }
1154 
1155  // This warning was extracted out from the cell components
1156  if (dynamic_cast<AliAODEvent*>(InputEvent())) {
1157  AliWarning("=============================================================");
1158  AliWarning("=== Running on AOD is not equivalent to running on ESD! ===");
1159  AliWarning("=============================================================");
1160  }
1161 
1162  if (fNeedEmcalGeom) {
1163  fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(InputEvent()->GetRunNumber());
1164  if (!fGeom) {
1165  AliFatal("Can not get EMCal geometry instance. If you do not need the EMCal geometry, disable it by setting task->SetNeedEmcalGeometry(kFALSE).");
1166  return;
1167  }
1168  }
1169 
1170  // Load all requested track branches - each container knows name already
1171  for (Int_t i =0; i<fParticleCollArray.GetEntriesFast(); i++) {
1172  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
1174  cont->SetArray(InputEvent());
1175  }
1176 
1177  // Load all requested cluster branches - each container knows name already
1178  for (Int_t i =0; i<fClusterCollArray.GetEntriesFast(); i++) {
1179  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
1181  cont->SetArray(InputEvent());
1182  }
1183 
1184  // Determine the proper pointer for each cell object and save them to the cell container
1185  // At this point, they should all be created
1186  for (auto cellObj : fCellCollArray)
1187  {
1189  }
1190 
1191  fEventInitialized = kTRUE;
1192 
1193  // Print warning to the user that the rest of the configuration information is available in the generation log
1194  // when the Analysis Manager was created. Using cout to be certain that it is shown on the train!
1195  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";
1196 
1197  // Setup the components
1199 }
1200 
1206 {
1207  // Run the initialization for all derived classes.
1208  for (auto component : fCorrectionComponents)
1209  {
1210  // Setup geometry
1211  component->SetEMCALGeometry(fGeom);
1212 
1213  // Set the input events. This is redundant to where it is set during Run(), but the events need to be
1214  // available to components, and they are only called one extra time.
1215  component->SetEvent(InputEvent());
1216  component->SetMCEvent(MCEvent());
1217 
1218  // Add the requested cells to the component
1220 
1221  // Component ExecOnce()
1222  component->ExecOnce();
1223 
1224  // If the cells were created during ExecOnce(), then we need to re-initialize the pointer to ensure
1225  // that it is not null!
1226  if (!(component->GetCaloCells())) {
1227  AliDebugStream(2) << "Re-initializing cells for component " << component->GetName() << std::endl;
1229  }
1230  }
1231 }
1232 
1238 {
1239  fVertex[0] = 0;
1240  fVertex[1] = 0;
1241  fVertex[2] = 0;
1242  fNVertCont = 0;
1243 
1244  const AliVVertex *vert = InputEvent()->GetPrimaryVertex();
1245  if (vert) {
1246  vert->GetXYZ(fVertex);
1247  fNVertCont = vert->GetNContributors();
1248  }
1249 
1250  fBeamType = GetBeamType();
1251 
1252  if (fBeamType == kAA || fBeamType == kpA ) {
1254  AliMultSelection *MultSelection = static_cast<AliMultSelection*>(InputEvent()->FindListObject("MultSelection"));
1255  if (MultSelection) {
1256  fCent = MultSelection->GetMultiplicityPercentile(fCentEst.Data());
1257  }
1258  else {
1259  AliWarning("Could not retrieve centrality information! Assuming 99");
1260  }
1261  }
1262  else { // old centrality estimation < 2015
1263  AliCentrality *aliCent = InputEvent()->GetCentrality();
1264  if (aliCent) {
1265  fCent = aliCent->GetCentralityPercentile(fCentEst.Data());
1266  }
1267  else {
1268  AliWarning("Could not retrieve centrality information! Assuming 99");
1269  }
1270  }
1271 
1272  if (fNcentBins==4) {
1273  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1274  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1275  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1276  else if (fCent >= 50 && fCent <= 100) fCentBin = 3;
1277  else {
1278  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1279  fCentBin = fNcentBins-1;
1280  }
1281  }
1282  else if (fNcentBins==5) { // for PbPb 2015
1283  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1284  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1285  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1286  else if (fCent >= 50 && fCent <= 90) fCentBin = 3;
1287  else if (fCent > 90) {
1288  fCent = 99;
1289  fCentBin = 4;
1290  }
1291  else {
1292  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1293  fCentBin = fNcentBins-1;
1294  }
1295  }
1296  else {
1297  Double_t centWidth = (fMaxCent-fMinCent)/(Double_t)fNcentBins;
1298  if(centWidth>0.) {
1299  fCentBin = TMath::FloorNint(fCent/centWidth);
1300  }
1301  else {
1302  fCentBin = 0;
1303  }
1304  if (fCentBin>=fNcentBins) {
1305  AliWarning(Form("fCentBin too large: cent = %f fCentBin = %d. Assuming 99", fCent, fCentBin));
1306  fCentBin = fNcentBins-1;
1307  }
1308  }
1309  }
1310  else {
1311  fCent = 99;
1312  fCentBin = 0;
1313  }
1314 
1315  AliEmcalContainer* cont = 0;
1316 
1317  TIter nextPartColl(&fParticleCollArray);
1318  while ((cont = static_cast<AliEmcalContainer*>(nextPartColl()))) cont->NextEvent();
1319 
1320  TIter nextClusColl(&fClusterCollArray);
1321  while ((cont = static_cast<AliEmcalContainer*>(nextClusColl()))) cont->NextEvent();
1322 
1323  return kTRUE;
1324 }
1325 
1331 {
1332  // Run the initialization for all derived classes.
1333  for (auto component : fCorrectionComponents)
1334  {
1335  component->SetEvent(InputEvent());
1336  component->SetMCEvent(MCEvent());
1337  component->SetCentralityBin(fCentBin);
1338  component->SetCentrality(fCent);
1339 
1340  component->Run();
1341  }
1342 
1343  PostData(1, fOutput);
1344 
1345  return kTRUE;
1346 }
1347 
1352 {
1353  // Run the initialization for all derived classes.
1354  for (auto component : fCorrectionComponents)
1355  {
1356  component->UserNotify();
1357  }
1358 
1359  return kTRUE;
1360 }
1361 
1368 std::ostream & AliEmcalCorrectionTask::PrintConfigurationString(std::ostream & in, bool userConfig) const
1369 {
1370  std::string stringToWrite = userConfig ? fUserConfigurationString : fDefaultConfigurationString;
1371  if (stringToWrite == "") {
1372  AliWarning(TString::Format("%s configuration is empty!", userConfig ? "User" : "Default"));
1373  }
1374  in << stringToWrite;
1375 
1376  return in;
1377 }
1378 
1386 bool AliEmcalCorrectionTask::WriteConfigurationFile(std::string filename, bool userConfig) const
1387 {
1388  bool returnValue = false;
1389  if (filename != "")
1390  {
1391  if (fConfigurationInitialized == true)
1392  {
1393  std::ofstream outFile(filename);
1394  PrintConfigurationString(outFile, userConfig);
1395  outFile.close();
1396 
1397  returnValue = true;
1398  }
1399  else
1400  {
1401  AliError(TString::Format("Configuration not properly initialized! Cannot print %s configuration!", userConfig ? "user" : "default"));
1402  }
1403 
1404  }
1405  else
1406  {
1407  AliError("Please pass a valid filename instead of empty quotes!");
1408  }
1409  return returnValue;
1410 }
1411 
1419 bool AliEmcalCorrectionTask::CompareToStoredConfiguration(std::string filename, bool userConfig) const
1420 {
1421  bool returnValue = false;
1422  if (filename != "")
1423  {
1424  if (fConfigurationInitialized == true)
1425  {
1426  // Generate YAML nodes for the comparison
1427  YAML::Node passedNode = YAML::LoadFile(filename);
1428  YAML::Node comparisonNode = YAML::Load(userConfig ? fUserConfigurationString : fDefaultConfigurationString);
1429 
1430  // Need to stream the configuration back to a string to remove the comments
1431  // since they are not preserved in the YAML node.
1432  std::stringstream passedNodeSS;
1433  passedNodeSS << passedNode;
1434 
1435  // Compare the nodes. Make the comparison as strings, as the YAML nodes do _not_ match, despite the strings matching.
1436  // In fact, the YAML nodes will _not_ match even if they are generated from the same string....
1437  if (passedNodeSS.str() == (userConfig ? fUserConfigurationString : fDefaultConfigurationString)) {
1438  returnValue = true;
1439  }
1440  else {
1441  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";
1442  }
1443  }
1444  else
1445  {
1446  AliError(TString::Format("Configuration not properly initialized! Cannot compare %s configuration!", userConfig ? "user" : "default"));
1447  }
1448 
1449  }
1450  else
1451  {
1452  AliError("Please pass a valid filename instead of empty quotes!");
1453  }
1454  return returnValue;
1455 }
1456 
1465 inline bool AliEmcalCorrectionTask::DoesFileExist(const std::string & filename)
1466 {
1467  std::ifstream inFile(filename);
1468  return inFile.good();
1469 }
1470 
1480 {
1481  if (filename != "")
1482  {
1483  // Handle if in AliPhysics and includes $ALICE_PHYSICS
1484  filename = gSystem->ExpandPathName(filename.c_str());
1485 
1486  // Handle grid
1487  if(filename.find("alien://") != std::string::npos)
1488  {
1489  AliDebug(2, TString::Format("Opening file \"%s\" on the grid!", filename.c_str()));
1490  // Initialize alien connection if needed
1491  if (!gGrid) {
1492  TGrid::Connect("alien://");
1493  }
1494 
1495  // Determine the local filename and copy file to local directory
1496  std::string localFilename = gSystem->BaseName(filename.c_str());
1497  // Ensures that the default and user files do not conflict if both are taken from the grid and have the same filename
1498  if (userFile == true) {
1499  localFilename = "user." + localFilename;
1500  }
1501  // Add UUID to ensure there are no conflicts if multiple correction tasks have the same configuration file name
1502  TUUID tempUUID;
1503  localFilename = "." + localFilename;
1504  localFilename = tempUUID.AsString() + localFilename;
1505 
1506  // Copy file
1507  TFile::Cp(filename.c_str(), localFilename.c_str());
1508 
1509  // yaml-cpp should only open the local file
1510  filename = localFilename;
1511  }
1512  }
1513 }
1514 
1522 {
1523  AliDebugStream(2) << "Retrieving cells object " << cellContainer->GetName() << std::endl;
1524  // Check for embedding and return object
1525  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cellContainer->GetIsEmbedding());
1526 
1527  cellContainer->SetCells(dynamic_cast<AliVCaloCells *>(event->FindListObject(cellContainer->GetBranchName().c_str())));
1528 }
1529 
1540 {
1541  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cont->GetIsEmbedding());
1542 
1543  TClonesArray * array = dynamic_cast<TClonesArray *>(event->FindListObject(cont->GetArrayName()));
1544  if (!array) {
1545  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()));
1546  array = new TClonesArray(AliEmcalContainerUtils::DetermineUseDefaultName(objectType, fIsEsd, true).c_str());
1547  array->SetName(cont->GetArrayName());
1548  event->AddObject(array);
1549  }
1550 }
1551 
1560 {
1561  // Get container node
1562  std::string inputObjectName = "";
1563  if (inputObjectType == AliEmcalContainerUtils::kCluster) {
1564  inputObjectName = "clusterContainers";
1565  }
1566  else if (inputObjectType == AliEmcalContainerUtils::kTrack) {
1567  inputObjectName = "trackContainers";
1568  }
1569  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1570  inputObjectName = "cells";
1571  }
1572  else {
1573  AliFatal(TString::Format("Unrecognized input object type %d", inputObjectType));
1574  }
1575 
1576  return inputObjectName;
1577 }
1578 
1590 bool AliEmcalCorrectionTask::CheckPossibleNamesForComponentName(std::string & name, std::set <std::string> & possibleComponents)
1591 {
1592  bool foundComponent = false;
1593  for (auto & possibleComponent : possibleComponents)
1594  {
1595  if (possibleComponent == name) {
1596  foundComponent = true;
1597  break;
1598  }
1599  }
1600 
1601  return foundComponent;
1602 }
1603 
1611 {
1612  if (fForceBeamType != kNA)
1613  return fForceBeamType;
1614 
1615  AliESDEvent *esd = dynamic_cast<AliESDEvent*>(InputEvent());
1616  if (esd) {
1617  const AliESDRun *run = esd->GetESDRun();
1618  TString beamType = run->GetBeamType();
1619  if (beamType == "p-p")
1620  return kpp;
1621  else if (beamType == "A-A")
1622  return kAA;
1623  else if (beamType == "p-A")
1624  return kpA;
1625  else
1626  return kNA;
1627  } else {
1628  Int_t runNumber = InputEvent()->GetRunNumber();
1629  // All run number ranges taken from the RCT
1630  if ((runNumber >= 136833 && runNumber <= 139517) || // LHC10h
1631  (runNumber >= 167693 && runNumber <= 170593) || // LHC11h
1632  (runNumber >= 244824 && runNumber <= 246994)) { // LHC15o
1633  return kAA;
1634  } else if ((runNumber >= 188356 && runNumber <= 188366) || // LHC12g
1635  (runNumber >= 195164 && runNumber <= 197388) || // LHC13b-f
1636  (runNumber >= 265015 && runNumber <= 267166)) { // LHC16q-t
1637  return kpA;
1638  } else {
1639  return kpp;
1640  }
1641  }
1642 }
1643 
1648 {
1649  if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1650  stream << "Cells info: " << std::endl;
1651  for (auto cellInfo : fCellCollArray) {
1652  stream << "\tName: " << cellInfo->GetName() << "\tBranch: " << cellInfo->GetBranchName() << "\tIsEmbedding: " << std::boolalpha << cellInfo->GetIsEmbedding() << std::endl;
1653  }
1654  }
1655  else if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
1656  stream << (inputObjectType == AliEmcalContainerUtils::kCluster ? "Cluster" : "Track") << " container info: " << std::endl;
1657  AliEmcalContainer * cont = 0;
1658  for (auto containerInfo : (inputObjectType == AliEmcalContainerUtils::kCluster ? fClusterCollArray : fParticleCollArray) ) {
1659  cont = static_cast<AliEmcalContainer *>(containerInfo);
1660  stream << "\tName: " << cont->GetName() << "\tBranch: " << cont->GetArrayName() << "\tTitle: " << cont->GetTitle() << "\tIsEmbedding: " << std::boolalpha << cont->GetIsEmbedding() << std::endl;
1661  }
1662  }
1663  else {
1664  AliErrorStream() << "Unrecognized input object type " << inputObjectType << std::endl;
1665  }
1666 }
1667 
1677 void AliEmcalCorrectionTask::GetNodeForInputObjects(YAML::Node & inputNode, YAML::Node & nodeToRetrieveFrom, std::string & inputObjectName, bool requiredProperty)
1678 {
1679  // Get the user input node
1680  AliEmcalCorrectionComponent::GetProperty(inputObjectName.c_str(), inputNode, YAML::Node(), nodeToRetrieveFrom, requiredProperty, "inputObjects");
1681 
1682  // Get the user shared node and add it back to the user node so that shared parameters are available
1683  if (nodeToRetrieveFrom["sharedParameters"]) {
1684  inputNode["sharedParameters"] = nodeToRetrieveFrom["sharedParameters"];
1685  }
1686 }
1687 
1698 void AliEmcalCorrectionTask::GetPropertyNamesFromNode(const std::string & componentName, const YAML::Node & node, std::set <std::string> & propertyNames, const bool nodeRequired)
1699 {
1700  YAML::Node tempNode;
1701  AliEmcalCorrectionComponent::GetProperty(componentName, tempNode, YAML::Node(), node, nodeRequired, "");
1702  for (auto propertyName : tempNode)
1703  {
1704  propertyNames.insert(propertyName.first.as<std::string>());
1705  }
1706 }
1707 
1715 AliEmcalCorrectionCellContainer * AliEmcalCorrectionTask::GetCellContainer(const std::string & cellsContainerName) const
1716 {
1717  for (auto cellContainer : fCellCollArray)
1718  {
1719  if (cellContainer->GetName() == cellsContainerName) {
1720  return cellContainer;
1721  }
1722  }
1723 
1724  return 0;
1725 }
1726 
1728 {
1729  // Get the pointer to the existing analysis manager via the static access method.
1730  //==============================================================================
1731  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1732  if (!mgr)
1733  {
1734  ::Error("AddTaskEmcalCorrectionTask", "No analysis manager to connect to.");
1735  return 0;
1736  }
1737 
1738  // Check the analysis type using the event handlers connected to the analysis manager.
1739  //==============================================================================
1740  AliVEventHandler* handler = mgr->GetInputEventHandler();
1741  if (!handler)
1742  {
1743  ::Error("AddTaskEmcalCorrectionTask", "This task requires an input event handler");
1744  return 0;
1745  }
1746 
1747  TString name = "AliEmcalCorrectionTask";
1748  if (suffix != "") {
1749  name += TString::Format("_%s", suffix.Data());
1750  }
1751 
1752  AliEmcalCorrectionTask* mgrTask = static_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.Data()));
1753  if (mgrTask) return mgrTask;
1754 
1755  // Create the task that manages the corrections
1756  AliEmcalCorrectionTask* correctionTask = new AliEmcalCorrectionTask(name.Data());
1757 
1758  //-------------------------------------------------------
1759  // Final settings, pass to manager and set the containers
1760  //-------------------------------------------------------
1761 
1762  mgr->AddTask(correctionTask);
1763 
1764  // Create containers for input/output
1765  AliAnalysisDataContainer* cInput = mgr->GetCommonInputContainer();
1766 
1767  TString outputContainerName(name);
1768  outputContainerName += "_histos";
1769 
1770  AliAnalysisDataContainer * cOutput = mgr->CreateContainer(outputContainerName.Data(),
1771  TList::Class(),
1772  AliAnalysisManager::kOutputContainer,
1773  Form("%s", AliAnalysisManager::GetCommonFileName()));
1774 
1775  mgr->ConnectInput(correctionTask, 0, cInput);
1776  mgr->ConnectOutput(correctionTask, 1, cOutput);
1777 
1778  //TObjArray* cnt = mgr->GetContainers();
1779 
1780  return correctionTask;
1781 }
1782 
1788 std::string AliEmcalCorrectionTask::toString(bool includeYAMLConfigurationInfo) const
1789 {
1790  std::stringstream tempSS;
1791 
1792  // Show the correction components
1793  tempSS << "Correction components:\n";
1794  for (auto component : fOrderedComponentsToExecute) {
1795  tempSS << "\t" << component << "\n";
1796  }
1797  // Input objects
1798  tempSS << "\nInput objects:\n";
1802 
1803  if (includeYAMLConfigurationInfo == true) {
1804  tempSS << "\nUser Configuration:\n";
1805  PrintConfigurationString(tempSS, true);
1806  tempSS << "\n\nDefault Configuration:\n";
1807  PrintConfigurationString(tempSS);
1808  tempSS << "\n";
1809  }
1810 
1811  return tempSS.str();
1812 }
1813 
1820 std::ostream & AliEmcalCorrectionTask::Print(std::ostream & in) const {
1821  in << toString();
1822  return in;
1823 }
1824 
1832 std::ostream & operator<<(std::ostream & in, const AliEmcalCorrectionTask & myTask)
1833 {
1834  std::ostream & result = myTask.Print(in);
1835  return result;
1836 }
1837 
1845 {
1846  std::string temp(opt);
1847  bool includeYAMLConfig = false;
1848  if (temp == "YAML") {
1849  includeYAMLConfig = true;
1850  }
1851  Printf("%s", toString(includeYAMLConfig).c_str());
1852 }
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