AliPhysics  b330fab (b330fab)
 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  bool initialized = component->Initialize();
600 
601  if (component && initialized)
602  {
603  AliInfo(TString::Format("Successfully added correction task: %s", componentName.c_str()));
604  fCorrectionComponents.push_back(component);
605  }
606  }
607 }
608 
624 {
625  // Get container node
626  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
627 
628  // Get the user and default input nodes for the object type
629  YAML::Node userInputObjectNode;
630  YAML::Node defaultInputObjectNode;
631  GetNodeForInputObjects(userInputObjectNode, fUserConfiguration, inputObjectName, false);
632  GetNodeForInputObjects(defaultInputObjectNode, fDefaultConfiguration, inputObjectName, true);
633 
634  AliDebugStream(3) << "userInputObjectNode: " << userInputObjectNode << std::endl;
635  AliDebugStream(3) << "defaultInputObjectNode: " << defaultInputObjectNode << std::endl;
636 
637  // Determine which containers we need based on which are requested by the enabled correction tasks
638  std::set <std::string> requestedContainers;
639  std::vector <std::string> componentRequest;
640  for ( const auto & componentName : fOrderedComponentsToExecute )
641  {
642  componentRequest.clear();
643  // Not required because not all components will have all kinds of containers
644  // "AliEmcalCorrection" is 18 characters
645  AliEmcalCorrectionComponent::GetProperty(inputObjectName + "Names", componentRequest, fUserConfiguration, fDefaultConfiguration, false, componentName.substr(componentName.find("AliEmcalCorrection")+18));
646  for ( auto & req : componentRequest )
647  {
648  AliDebugStream(3) << "Component " << componentName << " requested container name " << req << std::endl;
649  requestedContainers.insert(req);
650  }
651  }
652 
653  AliDebugStream(2) << inputObjectName << " Containers requested by components: " << std::endl;
654  for (auto & str : requestedContainers) {
655  AliDebugStream(2) << "\t" << str << std::endl;;
656  }
657 
658  // Create all requested containers
659  AliDebug(2, TString::Format("Setting up requested containers!"));
660  SetupContainersFromInputNodes(inputObjectType, userInputObjectNode, defaultInputObjectNode, requestedContainers);
661 }
662 
672 {
673  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
674  // Need to be of the form "clusterContainersNames"
675  inputObjectName = inputObjectName + "Names";
676 
677  std::vector <std::string> inputObjects;
678  // Not required, because not all components need Clusters or Tracks
679  AliEmcalCorrectionComponent::GetProperty(inputObjectName.c_str(), inputObjects, fUserConfiguration, fDefaultConfiguration, false, component->GetName());
680 
681  //AliDebugStream(4) << "inputObjects.size(): " << inputObjects.size() << std::endl;
682 
683  // If it is not found, then there will be nothing to iterate over, so we don't need to explicitly check the return value
684  for (auto const & str : inputObjects)
685  {
686  // NOTE: The AliEmcalContainer derived objects operate differently than the cells. The containers should be added during initialization while the cells should be added during ExecOnce()!
687  if (inputObjectType == AliEmcalContainerUtils::kCluster)
688  {
689  AliEmcalContainer * cont = GetClusterContainer(str.c_str());
690  AliDebugStream(2) << "Adding cluster container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
691 
692  if (checkObjectExists && !cont) {
693  AliError(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
694  }
695  component->AdoptClusterContainer(GetClusterContainer(str.c_str()));
696 
697  // Check that we are using the standard input event
698  if (!(cont->GetIsEmbedding())) {
699  component->SetUsingInputEvent(true);
700  }
701  }
702  else if (inputObjectType == AliEmcalContainerUtils::kTrack)
703  {
704  AliEmcalContainer * cont = GetParticleContainer(str.c_str());
705  AliDebugStream(2) << "Adding particle container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
706 
707  if (checkObjectExists && !cont) {
708  AliFatal(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
709  }
710  component->AdoptParticleContainer(GetParticleContainer(str.c_str()));
711 
712  // Check that we are using the standard input event
713  if (!(cont->GetIsEmbedding())) {
714  component->SetUsingInputEvent(true);
715  }
716  }
717  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells)
718  {
719  // NOTE: This operates different than the others. This should be executed during run time rather than during initialization!
720  if (inputObjects.size() > 1) {
721  AliFatal(TString::Format("Component %s requested more than one cell branch, but this is not supported! Check the configuration!", component->GetName()));
722  }
723 
724  // If we've made it here, this must be at least one entry
726  AliDebugStream(2) << "Adding calo cells \"" << cellCont->GetName() << "\" of branch name \"" << cellCont->GetBranchName() << "\" to component " << component->GetName() << std::endl;
727 
728  if (!(cellCont->GetCells())) {
729  // Attempt to re-initialize the cells.
730  // NOTE: This may not succeed. Adding the container may need to be repeated after the
731  // object is created
733  }
734 
735  if (checkObjectExists && !(cellCont->GetCells())) {
736  AliFatal(TString::Format("%s: Unable to retrieve cells \"%s\" in input object \"%s\" because the cells are null. Please check your configuration!", GetName(), cellCont->GetBranchName().c_str(), str.c_str()));
737  }
738 
739  // Set the calo cells (may be null)
740  component->SetCaloCells(cellCont->GetCells());
741 
742  // It is possible that the cells pointer is null because it may not be created yet. For example,
743  // when combining cells. Thus, we must first check whether the pointer is available before checking
744  // for the number of cells. This could potentially decrease the amount of debug information, but this
745  // should rarely be an issue.
746  if (component->GetCaloCells()) {
747  AliDebugStream(3) << "Component GetNumberOfCells: " << component->GetCaloCells()->GetNumberOfCells() << std::endl;
748  }
749 
750  // Check that we are using the standard input event
751  if (!(cellCont->GetIsEmbedding())) {
752  component->SetUsingInputEvent(true);
753  }
754  }
755  }
756 }
757 
766 void AliEmcalCorrectionTask::SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, YAML::Node & userInputObjectNode, YAML::Node & defaultInputObjectNode, std::set <std::string> & requestedContainers)
767 {
768  // Our node contains all of the objects that we will want to create.
769  for(auto & containerName : requestedContainers)
770  {
771  // The section is the container name
772  //std::string containerName = it->first.as<std::string>();
773  // Skip if the particle or cluster container already exists
774  if (GetParticleContainer(containerName.c_str()) || GetClusterContainer(containerName.c_str())) {
775  continue;
776  }
777 
778  AliDebug(2, TString::Format("Processing container %s of inputType %d", containerName.c_str(), inputObjectType));
779  if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
780  SetupContainer(inputObjectType, containerName, userInputObjectNode, defaultInputObjectNode);
781  }
782  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
783  SetupCellsInfo(containerName, userInputObjectNode, defaultInputObjectNode);
784  }
785  }
786 }
787 
798 void AliEmcalCorrectionTask::SetupCellsInfo(std::string containerName, YAML::Node & userNode, YAML::Node & defaultNode)
799 {
800  // Define cell info
802 
803  AliDebugStream(2) << "User: " << std::endl << userNode << std::endl << "default: " << std::endl << defaultNode << std::endl;
804 
805  // Set properties
806  // Cells (object) name
807  cellObj->SetName(containerName);
808  // Branch name
809  std::string tempString = "";
810  AliEmcalCorrectionComponent::GetProperty("branchName", tempString, userNode, defaultNode, true, containerName);
811  if (tempString == "usedefault") {
813  }
814  cellObj->SetBranchName(tempString);
815 
816  // IsEmbedding
817  bool tempBool = false;
818  AliEmcalCorrectionComponent::GetProperty("embedding", tempBool, userNode, defaultNode, false, containerName);
819  cellObj->SetIsEmbedding(tempBool);
820 
821  // Add to the array to keep track of it
822  fCellCollArray.push_back(cellObj);
823 }
824 
842 void AliEmcalCorrectionTask::SetupContainer(AliEmcalContainerUtils::InputObject_t inputObjectType, std::string containerName, YAML::Node & userNode, YAML::Node & defaultNode)
843 {
844  // Create container
845  AliDebugStream(2) << "Adding container" << std::endl;
846  AliEmcalContainer * cont = AddContainer(inputObjectType, containerName, userNode, defaultNode);
847  AliDebugStream(2) << "Added container" << std::endl;
848 
849  // Set the container properties
850  //
851  // TODO: Consider if this can be converted to a map to function pointers. There are a number of details
852  // which can make it a bit complicated. Those details include inheritance, pointing to member
853  // functions, etc. It should all be possible, but may not be worth all of the extra work and code.
854  // Example ccode:
855  // SetValueInContainer("minPt", &cont::SetMinPt, tempDouble, userNode, defaultNode);
856  // SetValueInContainer("minE", &cont::SetMinE, tempDouble, userNode, defaultNode);
857 
858  // Temporary variables to store requested properties
859  std::string tempString = "";
860  Double_t tempDouble = 0;
861  bool tempBool = false;
862 
863  // AliEmcalContainer properties
864  // Min Pt
865  bool result = AliEmcalCorrectionComponent::GetProperty("minPt", tempDouble, userNode, defaultNode, false, containerName);
866  if (result) {
867  AliDebugStream(2) << cont->GetName() << ": Setting minPt of " << tempDouble << std::endl;
868  cont->SetMinPt(tempDouble);
869  }
870  // Min E
871  result = AliEmcalCorrectionComponent::GetProperty("minE", tempDouble, userNode, defaultNode, false, containerName);
872  if (result) {
873  AliDebugStream(2) << cont->GetName() << ": Setting minE of " << tempDouble << std::endl;
874  cont->SetMinE(tempDouble);
875  }
876  // Eta min, max
877  result = AliEmcalCorrectionComponent::GetProperty("minEta", tempDouble, userNode, defaultNode, false, containerName);
878  if (result) {
879  // Only continue checking if the min is there, since we must set both together
880  Double_t tempDouble2 = 0;
881  result = AliEmcalCorrectionComponent::GetProperty("maxEta", tempDouble, userNode, defaultNode, false, containerName);
882  if (result) {
883  AliDebugStream(2) << cont->GetName() << ": Setting eta limits of " << tempDouble << " to " << tempDouble2 << std::endl;
884  cont->SetEtaLimits(tempDouble, tempDouble2);
885  }
886  }
887  // Phi min, max
888  result = AliEmcalCorrectionComponent::GetProperty("minPhi", tempDouble, userNode, defaultNode, false, containerName);
889  if (result) {
890  // Only continue checking if the min is there, since we must set both together
891  Double_t tempDouble2 = 0;
892  result = AliEmcalCorrectionComponent::GetProperty("maxPhi", tempDouble, userNode, defaultNode, false, containerName);
893  if (result) {
894  AliDebugStream(2) << cont->GetName() << ": Setting phi limits of " << tempDouble << " to " << tempDouble2 << std::endl;
895  cont->SetPhiLimits(tempDouble, tempDouble2);
896  }
897  }
898  // Embedded
899  result = AliEmcalCorrectionComponent::GetProperty("embedding", tempBool, userNode, defaultNode, false, containerName);
900  if (result) {
901  AliDebugStream(2) << cont->GetName() << ": Setting embedding to " << (tempBool ? "enabled" : "disabled") << std::endl;
902  cont->SetIsEmbedding(tempBool);
903  }
904 
905  // Cluster specific properties
906  AliClusterContainer * clusterContainer = dynamic_cast<AliClusterContainer *>(cont);
907  if (clusterContainer) {
908  // Default energy
909  // Probably not needed for the corrections
910  /*result = AliEmcalCorrectionComponent::GetProperty("defaultClusterEnergy", tempString, userNode, defaultNode, false, containerName);
911  if (result) {
912  // Need to get the enumeration
913  AliVCluster::VCluUserDefEnergy_t clusterEnergyType = fgkClusterEnergyTypeMap.at(tempString);
914  AliDebugStream(2) << clusterContainer->GetName() << ": Setting cluster energy type to " << clusterEnergyType << std::endl;
915  clusterContainer->SetDefaultClusterEnergy(clusterEnergyType);
916  }*/
917 
918  // NonLinCorrEnergyCut
919  result = AliEmcalCorrectionComponent::GetProperty("clusNonLinCorrEnergyCut", tempDouble, userNode, defaultNode, false, containerName);
920  if (result) {
921  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusNonLinCorrEnergyCut of " << tempDouble << std::endl;
922  clusterContainer->SetClusNonLinCorrEnergyCut(tempDouble);
923  }
924 
925  // HadCorrEnergyCut
926  result = AliEmcalCorrectionComponent::GetProperty("clusHadCorrEnergyCut", tempDouble, userNode, defaultNode, false, containerName);
927  if (result) {
928  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusHadCorrEnergyCut of " << tempDouble << std::endl;
929  clusterContainer->SetClusHadCorrEnergyCut(tempDouble);
930  }
931 
932  // SetIncludePHOS
933  result = AliEmcalCorrectionComponent::GetProperty("includePHOS", tempBool, userNode, defaultNode, false, containerName);
934  if (result) {
935  AliDebugStream(2) << clusterContainer->GetName() << ": Setting Include PHOS to " << (tempBool ? "enabled" : "disabled") << std::endl;
936  clusterContainer->SetIncludePHOS(tempBool);
937  }
938  }
939 
940  // Track specific
941  AliTrackContainer * trackContainer = dynamic_cast<AliTrackContainer *>(cont);
942  if (trackContainer) {
943  // Track selection
944  // AOD Filter bits as a sequence
945  std::vector <UInt_t> filterBitsVector;
946  result = AliEmcalCorrectionComponent::GetProperty("aodFilterBits", filterBitsVector, userNode, defaultNode, false, containerName);
947  if (result){
948  UInt_t filterBits = 0;
949  for (int filterBit : filterBitsVector) {
950  filterBits += filterBit;
951  }
952  AliDebugStream(2) << trackContainer->GetName() << ": Setting filterBits of " << filterBits << std::endl;
953  trackContainer->SetAODFilterBits(filterBits);
954  }
955 
956  // SetTrackFilterType enum
957  result = AliEmcalCorrectionComponent::GetProperty("trackFilterType", tempString, userNode, defaultNode, false, containerName);
958  if (result) {
959  // Need to get the enumeration
960  AliEmcalTrackSelection::ETrackFilterType_t trackFilterType = fgkTrackFilterTypeMap.at(tempString);
961  AliDebugStream(2) << trackContainer->GetName() << ": Setting trackFilterType of " << trackFilterType << std::endl;
962  trackContainer->SetTrackFilterType(trackFilterType);
963  }
964 
965  // Track cuts period
966  result = AliEmcalCorrectionComponent::GetProperty("trackCutsPeriod", tempString, userNode, defaultNode, false, containerName);
967  if (result) {
968  // Need to get the enumeration
969  AliDebugStream(2) << trackContainer->GetName() << ": Setting track cuts period to " << tempString << std::endl;
970  trackContainer->SetTrackCutsPeriod(tempString.c_str());
971  }
972  }
973 }
974 
992 AliEmcalContainer * AliEmcalCorrectionTask::AddContainer(AliEmcalContainerUtils::InputObject_t contType, std::string & containerName, YAML::Node & userNode, YAML::Node & defaultNode)
993 {
994  // Determine the type of branch to request
995  std::string containerBranch = "";
997  AliFatal("Must specify type of container when requesting branch.");
998  }
999 
1000  // Retrieve branch name
1001  // YAML::Node() is just an empty node
1002  AliDebugStream(2) << "User Node: " << userNode << std::endl;
1003  AliDebugStream(2) << "Default Node: " << defaultNode << std::endl;
1004  AliEmcalCorrectionComponent::GetProperty("branchName", containerBranch, userNode, defaultNode, true, containerName);
1005  // Should be unnecessary, since the user can only do this if done explicitly.
1006  /*if (containerBranch == "")
1007  {
1008  AliFatal(TString::Format("Request %i container, but the container branch is empty!", contType));
1009  }*/
1010 
1011  // Determine proper name if using "usedefault" pattern
1012  if (containerBranch == "usedefault") {
1013  containerBranch = AliEmcalContainerUtils::DetermineUseDefaultName(contType, fIsEsd);
1014  }
1015 
1016  // Create containers and set them to the name of the component
1017  AliEmcalContainer * cont = 0;
1018  if (contType == AliEmcalContainerUtils::kCluster)
1019  {
1020  cont = new AliClusterContainer(containerBranch.c_str());
1021  AdoptClusterContainer(dynamic_cast<AliClusterContainer *>(cont));
1022  }
1023  else if (contType == AliEmcalContainerUtils::kTrack)
1024  {
1025  if (containerBranch == "mcparticles") {
1026  cont = new AliMCParticleContainer(containerBranch.c_str());
1027  }
1028  else {
1029  cont = new AliTrackContainer(containerBranch.c_str());
1030  }
1031  AdoptParticleContainer(dynamic_cast<AliParticleContainer *>(cont));
1032  }
1033  cont->SetName(containerName.c_str());
1034 
1035  return cont;
1036 }
1037 
1047 {
1048  // Check that the configuration is initialized
1049  if (fConfigurationInitialized != true)
1050  {
1051  AliFatal("YAML configuration must be initialized before running (ie. the AddTask, run macro or wagon)!");
1052  }
1053 
1054  // Show the configurations info this is available
1055  AliDebugStream(4) << "User configuration string: " << fUserConfigurationString << std::endl;
1056  AliDebugStream(4) << "User configuration: " << fUserConfiguration << std::endl;
1057  AliDebugStream(4) << "Default configuration string: " << fDefaultConfigurationString << std::endl;
1058  AliDebugStream(4) << "Default configuration: " << fDefaultConfiguration << std::endl;
1059 
1060  // YAML Objects cannot be streamed, so we need to reinitialize them here.
1061  // They need reinitialize if they are null
1062  if (fUserConfiguration.IsNull() == true && fUserConfigurationString != "")
1063  {
1064  AliInfo("Reinitializing user configuration from string. Expected if running on grid!");
1066  }
1067  if (fDefaultConfiguration.IsNull() == true)
1068  {
1069  AliInfo("Reinitializing default configuration from string. Expected if running on grid!");
1071  }
1072 
1073  // Debug to check that the configuration has been (re)initiailzied has been completed correctly
1074  AliDebugStream(4) << "(Re)initialized user configuration: " << fUserConfigurationString << std::endl;
1075  AliDebugStream(4) << "(Re)initialized user configuration: " << fUserConfiguration << std::endl;
1076  AliDebugStream(4) << "(Re)initialized default configuration: " << fDefaultConfigurationString << std::endl;
1077  AliDebugStream(4) << "(Re)initialized default configuration: " << fDefaultConfiguration << std::endl;
1078 
1079  if (fForceBeamType == kpp)
1080  fNcentBins = 1;
1081 
1082  // Allow for output files
1083  OpenFile(1);
1084  fOutput = new TList();
1085  fOutput->SetOwner();
1086 
1088 
1089  PostData(1, fOutput);
1090 }
1091 
1099 {
1100  // Run the initialization for all derived classes.
1101  for (auto component : fCorrectionComponents)
1102  {
1103  // Set cent bins (usually used for hist creation)
1104  // It cannot be set until now because it can be changed after initialization
1105  // For instance, by SetForceBeamType()
1106  component->SetNcentralityBins(fNcentBins);
1107 
1108  component->UserCreateOutputObjects();
1109 
1110  if (component->GetOutputList() != 0)
1111  {
1112  // Adds a list to the list -- this doesn't work for some unknown reason
1113  //fOutput->Add(component->GetOutputList());
1114 
1115  // iterate through lists for each component, and fill in output
1116  TList* t = new TList();
1117  t->SetName(component->GetName());
1118  fOutput->AddLast(t);
1119  t = (TList*)fOutput->Last();
1120  TIter next(component->GetOutputList());
1121  while (TObject *obj = next()){
1122  t->Add(obj);
1123  }
1124 
1125  AliDebug(1, TString::Format("Added output list from task %s to output.", component->GetName()));
1126  }
1127  }
1128 }
1129 
1135 {
1136  // Initialize the event if not initialized
1137  if (!fEventInitialized)
1138  ExecOnce();
1139 
1140  // Only continue if we are initialized successfully
1141  if (!fEventInitialized)
1142  return;
1143 
1144  // Get the objects for each event
1145  if (!RetrieveEventObjects())
1146  return;
1147 
1148  // Call run for each correction
1149  if (!Run())
1150  return;
1151 }
1152 
1164 {
1165  if (!InputEvent()) {
1166  AliError("Could not retrieve event! Returning!");
1167  return;
1168  }
1169 
1170  // This warning was extracted out from the cell components
1171  if (dynamic_cast<AliAODEvent*>(InputEvent())) {
1172  AliWarning("=============================================================");
1173  AliWarning("=== Running on AOD is not equivalent to running on ESD! ===");
1174  AliWarning("=============================================================");
1175  }
1176 
1177  if (fNeedEmcalGeom) {
1178  fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(InputEvent()->GetRunNumber());
1179  if (!fGeom) {
1180  AliFatal("Can not get EMCal geometry instance. If you do not need the EMCal geometry, disable it by setting task->SetNeedEmcalGeometry(kFALSE).");
1181  return;
1182  }
1183  }
1184 
1185  // Load all requested track branches - each container knows name already
1186  for (Int_t i =0; i<fParticleCollArray.GetEntriesFast(); i++) {
1187  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
1189  cont->SetArray(InputEvent());
1190  }
1191 
1192  // Load all requested cluster branches - each container knows name already
1193  for (Int_t i =0; i<fClusterCollArray.GetEntriesFast(); i++) {
1194  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
1196  cont->SetArray(InputEvent());
1197  }
1198 
1199  // Determine the proper pointer for each cell object and save them to the cell container
1200  // At this point, they should all be created
1201  for (auto cellObj : fCellCollArray)
1202  {
1204  }
1205 
1206  fEventInitialized = kTRUE;
1207 
1208  // Print warning to the user that the rest of the configuration information is available in the generation log
1209  // when the Analysis Manager was created. Using cout to be certain that it is shown on the train!
1210  std::cout << "=== NOTE: Additional EMCal Corrections configuration information can be found when the Analysis Manager is configured. For a run macro, see above, while for a LEGO train, see the generation.log ===\n";
1211 
1212  // Setup the components
1214 }
1215 
1221 {
1222  // Run the initialization for all derived classes.
1223  for (auto component : fCorrectionComponents)
1224  {
1225  // Setup geometry
1226  component->SetEMCALGeometry(fGeom);
1227 
1228  // Add the requested cells to the component
1230 
1231  // Set the input events. This is redundant to where it is set during Run(), but the events need to be
1232  // available to components, and they are only called one extra time.
1233  component->SetInputEvent(InputEvent());
1234  component->SetMCEvent(MCEvent());
1235 
1236  // Component ExecOnce()
1237  component->ExecOnce();
1238 
1239  // If the cells were created during ExecOnce(), then we need to re-initialize the pointer to ensure
1240  // that it is not null!
1241  if (!(component->GetCaloCells())) {
1242  AliDebugStream(2) << "Re-initializing cells for component " << component->GetName() << std::endl;
1244  }
1245  }
1246 }
1247 
1253 {
1254  fVertex[0] = 0;
1255  fVertex[1] = 0;
1256  fVertex[2] = 0;
1257  fNVertCont = 0;
1258 
1259  const AliVVertex *vert = InputEvent()->GetPrimaryVertex();
1260  if (vert) {
1261  vert->GetXYZ(fVertex);
1262  fNVertCont = vert->GetNContributors();
1263  }
1264 
1265  fBeamType = GetBeamType();
1266 
1267  if (fBeamType == kAA || fBeamType == kpA ) {
1269  AliMultSelection *MultSelection = static_cast<AliMultSelection*>(InputEvent()->FindListObject("MultSelection"));
1270  if (MultSelection) {
1271  fCent = MultSelection->GetMultiplicityPercentile(fCentEst.Data());
1272  }
1273  else {
1274  AliWarning("Could not retrieve centrality information! Assuming 99");
1275  }
1276  }
1277  else { // old centrality estimation < 2015
1278  AliCentrality *aliCent = InputEvent()->GetCentrality();
1279  if (aliCent) {
1280  fCent = aliCent->GetCentralityPercentile(fCentEst.Data());
1281  }
1282  else {
1283  AliWarning("Could not retrieve centrality information! Assuming 99");
1284  }
1285  }
1286 
1287  if (fNcentBins==4) {
1288  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1289  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1290  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1291  else if (fCent >= 50 && fCent <= 100) fCentBin = 3;
1292  else {
1293  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1294  fCentBin = fNcentBins-1;
1295  }
1296  }
1297  else if (fNcentBins==5) { // for PbPb 2015
1298  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1299  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1300  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1301  else if (fCent >= 50 && fCent <= 90) fCentBin = 3;
1302  else if (fCent > 90) {
1303  fCent = 99;
1304  fCentBin = 4;
1305  }
1306  else {
1307  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1308  fCentBin = fNcentBins-1;
1309  }
1310  }
1311  else {
1312  Double_t centWidth = (fMaxCent-fMinCent)/(Double_t)fNcentBins;
1313  if(centWidth>0.) {
1314  fCentBin = TMath::FloorNint(fCent/centWidth);
1315  }
1316  else {
1317  fCentBin = 0;
1318  }
1319  if (fCentBin>=fNcentBins) {
1320  AliWarning(Form("fCentBin too large: cent = %f fCentBin = %d. Assuming 99", fCent, fCentBin));
1321  fCentBin = fNcentBins-1;
1322  }
1323  }
1324  }
1325  else {
1326  fCent = 99;
1327  fCentBin = 0;
1328  }
1329 
1330  AliEmcalContainer* cont = 0;
1331 
1332  TIter nextPartColl(&fParticleCollArray);
1333  while ((cont = static_cast<AliEmcalContainer*>(nextPartColl()))) cont->NextEvent();
1334 
1335  TIter nextClusColl(&fClusterCollArray);
1336  while ((cont = static_cast<AliEmcalContainer*>(nextClusColl()))) cont->NextEvent();
1337 
1338  return kTRUE;
1339 }
1340 
1346 {
1347  // Run the initialization for all derived classes.
1348  for (auto component : fCorrectionComponents)
1349  {
1350  component->SetInputEvent(InputEvent());
1351  component->SetMCEvent(MCEvent());
1352  component->SetCentralityBin(fCentBin);
1353  component->SetCentrality(fCent);
1354  component->SetVertex(fVertex);
1355 
1356  component->Run();
1357  }
1358 
1359  PostData(1, fOutput);
1360 
1361  return kTRUE;
1362 }
1363 
1368 {
1369  // Run the initialization for all derived classes.
1370  for (auto component : fCorrectionComponents)
1371  {
1372  component->UserNotify();
1373  }
1374 
1375  return kTRUE;
1376 }
1377 
1384 std::ostream & AliEmcalCorrectionTask::PrintConfigurationString(std::ostream & in, bool userConfig) const
1385 {
1386  std::string stringToWrite = userConfig ? fUserConfigurationString : fDefaultConfigurationString;
1387  if (stringToWrite == "") {
1388  AliWarning(TString::Format("%s configuration is empty!", userConfig ? "User" : "Default"));
1389  }
1390  in << stringToWrite;
1391 
1392  return in;
1393 }
1394 
1402 bool AliEmcalCorrectionTask::WriteConfigurationFile(std::string filename, bool userConfig) const
1403 {
1404  bool returnValue = false;
1405  if (filename != "")
1406  {
1407  if (fConfigurationInitialized == true)
1408  {
1409  std::ofstream outFile(filename);
1410  PrintConfigurationString(outFile, userConfig);
1411  outFile.close();
1412 
1413  returnValue = true;
1414  }
1415  else
1416  {
1417  AliError(TString::Format("Configuration not properly initialized! Cannot print %s configuration!", userConfig ? "user" : "default"));
1418  }
1419 
1420  }
1421  else
1422  {
1423  AliError("Please pass a valid filename instead of empty quotes!");
1424  }
1425  return returnValue;
1426 }
1427 
1435 bool AliEmcalCorrectionTask::CompareToStoredConfiguration(std::string filename, bool userConfig) const
1436 {
1437  bool returnValue = false;
1438  if (filename != "")
1439  {
1440  if (fConfigurationInitialized == true)
1441  {
1442  // Generate YAML nodes for the comparison
1443  YAML::Node passedNode = YAML::LoadFile(filename);
1444  YAML::Node comparisonNode = YAML::Load(userConfig ? fUserConfigurationString : fDefaultConfigurationString);
1445 
1446  // Need to stream the configuration back to a string to remove the comments
1447  // since they are not preserved in the YAML node.
1448  std::stringstream passedNodeSS;
1449  passedNodeSS << passedNode;
1450 
1451  // Compare the nodes. Make the comparison as strings, as the YAML nodes do _not_ match, despite the strings matching.
1452  // In fact, the YAML nodes will _not_ match even if they are generated from the same string....
1453  if (passedNodeSS.str() == (userConfig ? fUserConfigurationString : fDefaultConfigurationString)) {
1454  returnValue = true;
1455  }
1456  else {
1457  AliWarningStream() << "Passed YAML config:\n" << passedNode << "\n\nStored YAML config:\n" << comparisonNode << "\nPassed config located in file \"" << filename << "\" is not the same as the stored " << (userConfig ? "user" : "default") << "configuration file! YAML configurations printed above.\n";
1458  }
1459  }
1460  else
1461  {
1462  AliError(TString::Format("Configuration not properly initialized! Cannot compare %s configuration!", userConfig ? "user" : "default"));
1463  }
1464 
1465  }
1466  else
1467  {
1468  AliError("Please pass a valid filename instead of empty quotes!");
1469  }
1470  return returnValue;
1471 }
1472 
1481 inline bool AliEmcalCorrectionTask::DoesFileExist(const std::string & filename)
1482 {
1483  std::ifstream inFile(filename);
1484  return inFile.good();
1485 }
1486 
1496 {
1497  if (filename != "")
1498  {
1499  // Handle if in AliPhysics and includes $ALICE_PHYSICS
1500  filename = gSystem->ExpandPathName(filename.c_str());
1501 
1502  // Handle grid
1503  if(filename.find("alien://") != std::string::npos)
1504  {
1505  AliDebug(2, TString::Format("Opening file \"%s\" on the grid!", filename.c_str()));
1506  // Initialize alien connection if needed
1507  if (!gGrid) {
1508  TGrid::Connect("alien://");
1509  }
1510 
1511  // Determine the local filename and copy file to local directory
1512  std::string localFilename = gSystem->BaseName(filename.c_str());
1513  // Ensures that the default and user files do not conflict if both are taken from the grid and have the same filename
1514  if (userFile == true) {
1515  localFilename = "user." + localFilename;
1516  }
1517  // Add UUID to ensure there are no conflicts if multiple correction tasks have the same configuration file name
1518  TUUID tempUUID;
1519  localFilename = "." + localFilename;
1520  localFilename = tempUUID.AsString() + localFilename;
1521 
1522  // Copy file
1523  TFile::Cp(filename.c_str(), localFilename.c_str());
1524 
1525  // yaml-cpp should only open the local file
1526  filename = localFilename;
1527  }
1528  }
1529 }
1530 
1538 {
1539  AliDebugStream(2) << "Retrieving cells object " << cellContainer->GetName() << std::endl;
1540  // Check for embedding and return object
1541  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cellContainer->GetIsEmbedding());
1542 
1543  cellContainer->SetCells(dynamic_cast<AliVCaloCells *>(event->FindListObject(cellContainer->GetBranchName().c_str())));
1544 }
1545 
1556 {
1557  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cont->GetIsEmbedding());
1558 
1559  TClonesArray * array = dynamic_cast<TClonesArray *>(event->FindListObject(cont->GetArrayName()));
1560  if (!array) {
1561  AliWarning(TString::Format("Container %s requested branch %s, but it does not exist! Creating it for you! Please check that this is the proper action!", cont->GetName(), cont->GetArrayName().Data()));
1562  array = new TClonesArray(AliEmcalContainerUtils::DetermineUseDefaultName(objectType, fIsEsd, true).c_str());
1563  array->SetName(cont->GetArrayName());
1564  event->AddObject(array);
1565  }
1566 }
1567 
1576 {
1577  // Get container node
1578  std::string inputObjectName = "";
1579  if (inputObjectType == AliEmcalContainerUtils::kCluster) {
1580  inputObjectName = "clusterContainers";
1581  }
1582  else if (inputObjectType == AliEmcalContainerUtils::kTrack) {
1583  inputObjectName = "trackContainers";
1584  }
1585  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1586  inputObjectName = "cells";
1587  }
1588  else {
1589  AliFatal(TString::Format("Unrecognized input object type %d", inputObjectType));
1590  }
1591 
1592  return inputObjectName;
1593 }
1594 
1606 bool AliEmcalCorrectionTask::CheckPossibleNamesForComponentName(std::string & name, std::set <std::string> & possibleComponents)
1607 {
1608  bool foundComponent = false;
1609  for (auto & possibleComponent : possibleComponents)
1610  {
1611  if (possibleComponent == name) {
1612  foundComponent = true;
1613  break;
1614  }
1615  }
1616 
1617  return foundComponent;
1618 }
1619 
1627 {
1628  if (fForceBeamType != kNA)
1629  return fForceBeamType;
1630 
1631  AliESDEvent *esd = dynamic_cast<AliESDEvent*>(InputEvent());
1632  if (esd) {
1633  const AliESDRun *run = esd->GetESDRun();
1634  TString beamType = run->GetBeamType();
1635  if (beamType == "p-p")
1636  return kpp;
1637  else if (beamType == "A-A")
1638  return kAA;
1639  else if (beamType == "p-A")
1640  return kpA;
1641  else
1642  return kNA;
1643  } else {
1644  Int_t runNumber = InputEvent()->GetRunNumber();
1645  // All run number ranges taken from the RCT
1646  if ((runNumber >= 136833 && runNumber <= 139517) || // LHC10h
1647  (runNumber >= 167693 && runNumber <= 170593) || // LHC11h
1648  (runNumber >= 244824 && runNumber <= 246994)) { // LHC15o
1649  return kAA;
1650  } else if ((runNumber >= 188356 && runNumber <= 188366) || // LHC12g
1651  (runNumber >= 195164 && runNumber <= 197388) || // LHC13b-f
1652  (runNumber >= 265015 && runNumber <= 267166)) { // LHC16q-t
1653  return kpA;
1654  } else {
1655  return kpp;
1656  }
1657  }
1658 }
1659 
1664 {
1665  if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1666  stream << "Cells info: " << std::endl;
1667  for (auto cellInfo : fCellCollArray) {
1668  stream << "\tName: " << cellInfo->GetName() << "\tBranch: " << cellInfo->GetBranchName() << "\tIsEmbedding: " << std::boolalpha << cellInfo->GetIsEmbedding() << std::endl;
1669  }
1670  }
1671  else if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
1672  stream << (inputObjectType == AliEmcalContainerUtils::kCluster ? "Cluster" : "Track") << " container info: " << std::endl;
1673  AliEmcalContainer * cont = 0;
1674  for (auto containerInfo : (inputObjectType == AliEmcalContainerUtils::kCluster ? fClusterCollArray : fParticleCollArray) ) {
1675  cont = static_cast<AliEmcalContainer *>(containerInfo);
1676  stream << "\tName: " << cont->GetName() << "\tBranch: " << cont->GetArrayName() << "\tTitle: " << cont->GetTitle() << "\tIsEmbedding: " << std::boolalpha << cont->GetIsEmbedding() << std::endl;
1677  }
1678  }
1679  else {
1680  AliErrorStream() << "Unrecognized input object type " << inputObjectType << std::endl;
1681  }
1682 }
1683 
1693 void AliEmcalCorrectionTask::GetNodeForInputObjects(YAML::Node & inputNode, YAML::Node & nodeToRetrieveFrom, std::string & inputObjectName, bool requiredProperty)
1694 {
1695  // Get the user input node
1696  AliEmcalCorrectionComponent::GetProperty(inputObjectName.c_str(), inputNode, YAML::Node(), nodeToRetrieveFrom, requiredProperty, "inputObjects");
1697 
1698  // Get the user shared node and add it back to the user node so that shared parameters are available
1699  if (nodeToRetrieveFrom["sharedParameters"]) {
1700  inputNode["sharedParameters"] = nodeToRetrieveFrom["sharedParameters"];
1701  }
1702 }
1703 
1714 void AliEmcalCorrectionTask::GetPropertyNamesFromNode(const std::string & componentName, const YAML::Node & node, std::set <std::string> & propertyNames, const bool nodeRequired)
1715 {
1716  YAML::Node tempNode;
1717  AliEmcalCorrectionComponent::GetProperty(componentName, tempNode, YAML::Node(), node, nodeRequired, "");
1718  for (auto propertyName : tempNode)
1719  {
1720  propertyNames.insert(propertyName.first.as<std::string>());
1721  }
1722 }
1723 
1731 AliEmcalCorrectionCellContainer * AliEmcalCorrectionTask::GetCellContainer(const std::string & cellsContainerName) const
1732 {
1733  for (auto cellContainer : fCellCollArray)
1734  {
1735  if (cellContainer->GetName() == cellsContainerName) {
1736  return cellContainer;
1737  }
1738  }
1739 
1740  return 0;
1741 }
1742 
1744 {
1745  // Get the pointer to the existing analysis manager via the static access method.
1746  //==============================================================================
1747  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1748  if (!mgr)
1749  {
1750  ::Error("AddTaskEmcalCorrectionTask", "No analysis manager to connect to.");
1751  return 0;
1752  }
1753 
1754  // Check the analysis type using the event handlers connected to the analysis manager.
1755  //==============================================================================
1756  AliVEventHandler* handler = mgr->GetInputEventHandler();
1757  if (!handler)
1758  {
1759  ::Error("AddTaskEmcalCorrectionTask", "This task requires an input event handler");
1760  return 0;
1761  }
1762 
1763  TString name = "AliEmcalCorrectionTask";
1764  if (suffix != "") {
1765  name += TString::Format("_%s", suffix.Data());
1766  }
1767 
1768  AliEmcalCorrectionTask* mgrTask = static_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.Data()));
1769  if (mgrTask) return mgrTask;
1770 
1771  // Create the task that manages the corrections
1772  AliEmcalCorrectionTask* correctionTask = new AliEmcalCorrectionTask(name.Data());
1773 
1774  //-------------------------------------------------------
1775  // Final settings, pass to manager and set the containers
1776  //-------------------------------------------------------
1777 
1778  mgr->AddTask(correctionTask);
1779 
1780  // Create containers for input/output
1781  AliAnalysisDataContainer* cInput = mgr->GetCommonInputContainer();
1782 
1783  TString outputContainerName(name);
1784  outputContainerName += "_histos";
1785 
1786  AliAnalysisDataContainer * cOutput = mgr->CreateContainer(outputContainerName.Data(),
1787  TList::Class(),
1788  AliAnalysisManager::kOutputContainer,
1789  Form("%s", AliAnalysisManager::GetCommonFileName()));
1790 
1791  mgr->ConnectInput(correctionTask, 0, cInput);
1792  mgr->ConnectOutput(correctionTask, 1, cOutput);
1793 
1794  //TObjArray* cnt = mgr->GetContainers();
1795 
1796  return correctionTask;
1797 }
1798 
1804 std::string AliEmcalCorrectionTask::toString(bool includeYAMLConfigurationInfo) const
1805 {
1806  std::stringstream tempSS;
1807 
1808  // Show the correction components
1809  tempSS << "Correction components:\n";
1810  for (auto component : fOrderedComponentsToExecute) {
1811  tempSS << "\t" << component << "\n";
1812  }
1813  // Input objects
1814  tempSS << "\nInput objects:\n";
1818 
1819  if (includeYAMLConfigurationInfo == true) {
1820  tempSS << "\nUser Configuration:\n";
1821  PrintConfigurationString(tempSS, true);
1822  tempSS << "\n\nDefault Configuration:\n";
1823  PrintConfigurationString(tempSS);
1824  tempSS << "\n";
1825  }
1826 
1827  return tempSS.str();
1828 }
1829 
1836 std::ostream & AliEmcalCorrectionTask::Print(std::ostream & in) const {
1837  in << toString();
1838  return in;
1839 }
1840 
1848 std::ostream & operator<<(std::ostream & in, const AliEmcalCorrectionTask & myTask)
1849 {
1850  std::ostream & result = myTask.Print(in);
1851  return result;
1852 }
1853 
1861 {
1862  std::string temp(opt);
1863  bool includeYAMLConfig = false;
1864  if (temp == "YAML") {
1865  includeYAMLConfig = true;
1866  }
1867  Printf("%s", toString(includeYAMLConfig).c_str());
1868 }
void AdoptClusterContainer(AliClusterContainer *cont)
Int_t fNcentBins
how many centrality bins
void SetBranchName(std::string branchName)
Set the name of the cells branch (NOT the same as the name!)
std::string fSuffix
Suffix of the Correction Task (used to select components)
void PrintRequestedContainersInformation(AliEmcalContainerUtils::InputObject_t inputObjectType, std::ostream &stream) const
Steering task for the EMCal correction framework.
AliEMCALGeometry * fGeom
! Emcal geometry
const char * filename
Definition: TestFCM.C:1
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
ClassImp(AliAnalysisTaskDeltaPt) AliAnalysisTaskDeltaPt
void GetNodeForInputObjects(YAML::Node &inputNode, YAML::Node &nodeToRetrieveFrom, std::string &inputObjectName, bool requiredProperty)
TObjArray fParticleCollArray
Particle/track collection array.
TObjArray fClusterCollArray
Cluster collection array.
void SetDefaultConfiguration(YAML::Node &node)
ETrackFilterType_t
Pre-defined track filters.
void AdoptParticleContainer(AliParticleContainer *cont)
std::ostream & operator<<(std::ostream &in, const AliEmcalCorrectionTask &myTask)
void SetIsEmbedding(bool isEmbedded)
Set to true if the cells are located in the event that is being embedded.
void SetCaloCells(AliVCaloCells *cells)
BeamType fBeamType
! Event beam type
void SetArray(const AliVEvent *event)
Int_t GetRunNumber(TString)
Definition: PlotMuonQA.C:2235
void SetTrackFilterType(ETrackFilterType_t f)
std::string toString(bool includeYAMLConfigurationInfo=false) const
const char Option_t
Definition: External.C:48
void SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, YAML::Node &userInputObjectNode, YAML::Node &defaultInputObjectNode, std::set< std::string > &requestedContainers)
YAML::Node fDefaultConfiguration
! Default YAML Configuration
void Print(Option_t *opt="") const
void SetupCellsInfo(std::string containerName, YAML::Node &userNode, YAML::Node &defaultNode)
Int_t fNVertCont
! Event vertex number of contributors
static AliEmcalCorrectionComponent * createInstance(std::string const &s)
Creates an instance of an object based on the name if the name is registered in the map...
void SetName(std::string name)
Set the name of the cells object (NOT the same as the branch!)
bool Bool_t
Definition: External.C:53
Int_t fCentBin
! Event centrality bin
Double_t fMinCent
min centrality for event selection
std::vector< AliEmcalCorrectionCellContainer * > fCellCollArray
Cells collection array.
void SetupContainer(AliEmcalContainerUtils::InputObject_t inputObjectType, std::string containerName, YAML::Node &userNode, YAML::Node &defaultNode)
Container structure for EMCAL clusters.
Container for MC-true particles within the EMCAL framework.
void AddContainersToComponent(AliEmcalCorrectionComponent *component, AliEmcalContainerUtils::InputObject_t inputObjectType, bool checkObjectExists=false)
std::string fUserConfigurationString
Store the user YAML configuration as a string so that it can be streamed.
void GetPropertyNamesFromNode(const std::string &componentName, const YAML::Node &node, std::set< std::string > &propertyNames, const bool nodeRequired)
std::ostream & PrintConfigurationString(std::ostream &in, bool userConfig=false) const
TList * OpenFile(const char *fname)
Definition: DrawAnaELoss.C:65
void SetClusHadCorrEnergyCut(Double_t cut)
void swap(AliEmcalCorrectionTask &first, AliEmcalCorrectionTask &second)
bool GetProperty(std::string propertyName, T &property, bool requiredProperty=true, std::string correctionName="")
Retrieve property.
BeamType fForceBeamType
forced beam type