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