AliPhysics  cc1c0ba (cc1c0ba)
 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 
18 #include "AliVEventHandler.h"
19 #include "AliEMCALGeometry.h"
20 #include "AliVCaloCells.h"
21 #include "AliVCluster.h"
22 #include "AliLog.h"
23 #include "AliMultSelection.h"
24 #include "AliCentrality.h"
25 #include "AliESDEvent.h"
26 #include "AliAnalysisManager.h"
27 #include "AliAODEvent.h"
28 
30 ClassImp(AliEmcalCorrectionTask);
32 
36 
37 const std::map <std::string, AliVCluster::VCluUserDefEnergy_t> AliEmcalCorrectionTask::fgkClusterEnergyTypeMap = {
38  {"kNonLinCorr", AliVCluster::kNonLinCorr },
39  {"kHadCorr", AliVCluster::kHadCorr },
40  {"kUserDefEnergy1", AliVCluster::kUserDefEnergy1 },
41  {"kUserDefEnergy2", AliVCluster::kUserDefEnergy2 }
42 };
43 
44 const std::map <std::string, AliEmcalTrackSelection::ETrackFilterType_t> AliEmcalCorrectionTask::fgkTrackFilterTypeMap = {
45  {"kNoTrackFilter", AliEmcalTrackSelection::kNoTrackFilter },
46  {"kCustomTrackFilter", AliEmcalTrackSelection::kCustomTrackFilter },
47  {"kHybridTracks", AliEmcalTrackSelection::kHybridTracks },
48  {"kTPCOnlyTracks", AliEmcalTrackSelection::kTPCOnlyTracks }
49 };
50 
55  AliAnalysisTaskSE("AliEmcalCorrectionTask"),
56  fYAMLConfig(),
57  fSuffix(""),
58  fUserConfigurationFilename(""),
59  fDefaultConfigurationFilename(""),
60  fOrderedComponentsToExecute(),
61  fCorrectionComponents(),
62  fConfigurationInitialized(false),
63  fIsEsd(false),
64  fEventInitialized(false),
65  fCent(0),
66  fCentBin(-1),
67  fMinCent(-999),
68  fMaxCent(-999),
69  fNcentBins(4),
70  fCentEst("V0M"),
71  fUseNewCentralityEstimation(kFALSE),
72  fVertex{0},
73  fNVertCont(0),
74  fBeamType(kNA),
75  fForceBeamType(kNA),
76  fNeedEmcalGeom(kTRUE),
77  fGeom(0),
78  fParticleCollArray(),
79  fClusterCollArray(),
80  fCellCollArray(),
81  fOutput(0)
82 {
83  // Default constructor
84  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
85 
86  fParticleCollArray.SetOwner(kTRUE);
87  fClusterCollArray.SetOwner(kTRUE);
88 }
89 
100  AliAnalysisTaskSE(name),
101  fYAMLConfig(),
102  fSuffix(""),
103  fUserConfigurationFilename(""),
104  fDefaultConfigurationFilename(""),
105  fOrderedComponentsToExecute(),
106  fCorrectionComponents(),
107  fConfigurationInitialized(false),
108  fIsEsd(false),
109  fEventInitialized(false),
110  fCent(0),
111  fCentBin(-1),
112  fMinCent(-999),
113  fMaxCent(-999),
114  fNcentBins(4),
115  fCentEst("V0M"),
116  fUseNewCentralityEstimation(kFALSE),
117  fVertex{0},
118  fNVertCont(0),
119  fBeamType(kNA),
120  fForceBeamType(kNA),
121  fNeedEmcalGeom(kTRUE),
122  fGeom(0),
123  fParticleCollArray(),
124  fClusterCollArray(),
125  fCellCollArray(),
126  fOutput(0)
127 {
128  // Standard constructor
129  AliDebug(3, Form("%s", __PRETTY_FUNCTION__));
130 
131  fParticleCollArray.SetOwner(kTRUE);
132  fClusterCollArray.SetOwner(kTRUE);
133 
134  DefineInput(0, TChain::Class());
135  DefineOutput(1, TList::Class());
136 }
137 
146  fYAMLConfig(task.fYAMLConfig),
147  fSuffix(task.fSuffix),
148  fUserConfigurationFilename(task.fUserConfigurationFilename),
149  fDefaultConfigurationFilename(task.fDefaultConfigurationFilename),
150  fOrderedComponentsToExecute(task.fOrderedComponentsToExecute),
151  fCorrectionComponents(task.fCorrectionComponents), // TODO: These should be copied!
152  fConfigurationInitialized(task.fConfigurationInitialized),
153  fIsEsd(task.fIsEsd),
154  fEventInitialized(task.fEventInitialized),
155  fCent(task.fCent),
156  fCentBin(task.fCentBin),
157  fMinCent(task.fMinCent),
158  fMaxCent(task.fMaxCent),
159  fNcentBins(task.fNcentBins),
160  fCentEst(task.fCentEst),
161  fUseNewCentralityEstimation(task.fUseNewCentralityEstimation),
162  fVertex{0.},
163  fNVertCont(task.fNVertCont),
164  fBeamType(task.fBeamType),
165  fForceBeamType(task.fForceBeamType),
166  fNeedEmcalGeom(task.fNeedEmcalGeom),
167  fGeom(task.fGeom),
168  fParticleCollArray(*(static_cast<TObjArray *>(task.fParticleCollArray.Clone()))),
169  fClusterCollArray(*(static_cast<TObjArray *>(task.fClusterCollArray.Clone()))),
170  fOutput(task.fOutput) // TODO: More care is needed here!
171 {
172  // Vertex position
173  std::copy(std::begin(task.fVertex), std::end(task.fVertex), std::begin(fVertex));
174 
175  // Cell Collections
176  for (auto cellCont : task.fCellCollArray)
177  {
178  fCellCollArray.push_back(new AliEmcalCorrectionCellContainer(*cellCont));
179  }
180 }
181 
187 {
188  swap(*this, other);
189 }
190 
196 {
197  swap(*this, other);
198 
199  return *this;
200 }
201 
206 {
207  using std::swap;
208 
209  swap(first.fYAMLConfig, second.fYAMLConfig);
210  swap(first.fSuffix, second.fSuffix);
216  swap(first.fIsEsd, second.fIsEsd);
218  swap(first.fCent, second.fCent);
219  swap(first.fCentBin, second.fCentBin);
220  swap(first.fMinCent, second.fMinCent);
221  swap(first.fMaxCent, second.fMaxCent);
222  swap(first.fNcentBins, second.fNcentBins);
223  swap(first.fCentEst, second.fCentEst);
225  swap(first.fVertex, second.fVertex);
226  swap(first.fNVertCont, second.fNVertCont);
227  swap(first.fBeamType, second.fBeamType);
228  swap(first.fForceBeamType, second.fForceBeamType);
229  swap(first.fNeedEmcalGeom, second.fNeedEmcalGeom);
230  swap(first.fGeom, second.fGeom);
233  swap(first.fCellCollArray, second.fCellCollArray);
234  swap(first.fOutput, second.fOutput);
235 }
236 
242 {
243  // Destructor
244 }
245 
246 void AliEmcalCorrectionTask::Initialize(bool removeDummyTask)
247 {
248  // Determine file type
249  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
250  if (mgr) {
251  AliVEventHandler *evhand = mgr->GetInputEventHandler();
252  if (evhand) {
253  if (evhand->InheritsFrom("AliESDInputHandler")) {
254  fIsEsd = true;
255  }
256  else {
257  fIsEsd = false;
258  }
259  }
260  else {
261  AliError("Event handler not found!");
262  }
263  }
264  else {
265  AliError("Analysis manager not found!");
266  }
267 
268  // Determine the suffix of the correction task
269  std::string tempName = GetName();
270  std::size_t foundSuffix = tempName.find("_");
271  if (foundSuffix != std::string::npos) {
272  // +1 to skip "_"
273  fSuffix = tempName.substr(foundSuffix + 1).c_str();
274  }
275 
276  if (fSuffix != "") {
277  AliInfoStream() << "Initializing correction task with suffix \"" << fSuffix << "\"" << std::endl;
278  }
279 
280  // Initialize YAML configuration
282  // Check that the configuration is initialized
283  if (fConfigurationInitialized != true)
284  {
285  AliFatal("YAML configuration must be initialized before running (ie. in the run macro or wagon)!");
286  }
287 
288  // Determine component execution order
290 
291  // Check for user defined settings that are not in the default file
293 
294  // Setup input objects
295  // Setup Cells
296  // Cannot do this entirely yet because we need input objects
299  // Create cluster input objects
302  // Create track input objects
305 
306  // Initialize components
308 
309  if (removeDummyTask == true) {
310  RemoveDummyTask();
311  }
312 
313  // Print the results of the initialization
314  // Print outside of the ALICE Log system to ensure that it is always available!
315  std::cout << GetName() << " Settings:\n" << *this;
316 }
317 
323 {
324  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
325  if (!mgr)
326  {
327  AliErrorStream() << "No analysis manager to connect to.\n";
328  return;
329  }
330 
331  // Remove the dummy task
332  std::string dummyTaskName = GetName();
333  dummyTaskName += "_dummyTask";
334  TObjArray * tasks = mgr->GetTasks();
335  if (tasks) {
336  AliAnalysisTaskSE * dummyTask = dynamic_cast<AliAnalysisTaskSE *>(tasks->FindObject(dummyTaskName.c_str()));
337  if (!dummyTask) {
338  AliErrorStream() << "Could not remove dummy task \"" << dummyTaskName << "\" from analysis manager! Was it added?\n";
339  }
340  // Actually remove the task
341  tasks->Remove(dummyTask);
342  }
343  else {
344  AliErrorStream() << "Could not retrieve tasks from the analysis manager.\n";
345  }
346 }
347 
357 {
358  // Determine file path
360  {
361  // Use the default if nothing is set
362  fDefaultConfigurationFilename = "$ALICE_PHYSICS/PWG/EMCAL/config/AliEmcalCorrectionConfiguration.yaml";
363  }
364 
365  // Setup and initialize configurations
366  // user is added first so that it will be checked first.
367  // User file
368  bool returnValue = fYAMLConfig.AddConfiguration(fUserConfigurationFilename, "user");
369  if (returnValue) {
370  AliInfoStream() << "Using user EMCal corrections configuration located at \"" << fUserConfigurationFilename << "\"\n";
371  }
372  else {
373  AliInfoStream() << "User file at \"" << fUserConfigurationFilename << "\" does not exist! All settings will be from the default file!";
374  }
375 
376  // Default file
378  if (returnValue) {
379  AliInfoStream() << "Using default EMCal corrections configuration located at \"" << fDefaultConfigurationFilename << "\"\n";
380  }
381  else {
382  AliFatal(TString::Format("Default file located at \"%s\" does not exist!", fDefaultConfigurationFilename.c_str()));
383  }
384 
385  // Initialize
387 
388  // Note that it is initialized properly so that the analysis can proceed
390 }
391 
402 void AliEmcalCorrectionTask::DetermineComponentsToExecute(std::vector <std::string> & correctionComponents)
403 {
404  std::vector <std::string> executionOrder;
405  // executionOrder determines the order of tasks to execute, but it doesn't name the particular tasks
406  fYAMLConfig.GetProperty("executionOrder", executionOrder, true);
407 
408  // Possible components to create from both the user and default configurations
409  // Use set so that the possible components are not repeated
410  std::set <std::string> possibleComponents;
411  for (auto node : fYAMLConfig.GetConfiguration("user").second) {
412  possibleComponents.insert(node.first.as<std::string>());
413  }
414  for (auto node : fYAMLConfig.GetConfiguration("default").second) {
415  possibleComponents.insert(node.first.as<std::string>());
416  }
417 
418  // Determine the correction names associated with the correction task
419  std::string expectedComponentName = "";
420  bool foundSuffixComponent = false;
421  bool foundComponent = false;
422  bool componentEnabled = true;
423 
424  // Execution order determines the order that corrections should be added to our execution list
425  for (auto & execName : executionOrder)
426  {
427  // Construct the expected component name with the suffix
428  expectedComponentName = TString::Format("%s_%s", execName.c_str(), fSuffix.c_str()).Data();
429  foundComponent = false;
430  componentEnabled = false;
431 
432  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
433  if (foundComponent)
434  {
435  // Check if the component is enabled
436  fYAMLConfig.GetProperty({expectedComponentName, "enabled"}, componentEnabled, true);
437  // If enabled, then store the name so that it can be executed
438  if (componentEnabled == true) {
439  foundSuffixComponent = true;
440  correctionComponents.push_back(expectedComponentName);
441  }
442  else {
443  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
444  }
445 
446  continue;
447  }
448  else
449  {
450  // Look for the normal component
451  expectedComponentName = execName;
452  foundComponent = CheckPossibleNamesForComponentName(expectedComponentName, possibleComponents);
453  // Check if it is enabled
454  fYAMLConfig.GetProperty({expectedComponentName, "enabled"}, componentEnabled, true);
455 
456  if (componentEnabled == true) {
457  if (foundSuffixComponent == true) {
458  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()));
459  }
460  else {
461  // Take the normal component and store it to be executed
462  correctionComponents.push_back(expectedComponentName);
463  }
464  }
465  else {
466  AliInfo(TString::Format("Component %s is disabled and will not be run!", expectedComponentName.c_str()));
467  }
468  }
469  }
470 
471  // Need to append "AliEmcalCorrection" to allow the tasks to be found!
472  AliDebug(2, "Found EMCal Correction Components: ");
473  for (auto & component : correctionComponents)
474  {
475  component = "AliEmcalCorrection" + component;
476  AliDebug(2, TString::Format("%s", component.c_str()) );
477  }
478 }
479 
493 {
494  // Names of properties for a particular component in the user and default configurations
495  std::set <std::string> userPropertyNames;
496  std::set <std::string> defaultPropertyNames;
497  // Notes whether a match was found between user and default properties
498  bool foundMatch = false;
499  std::string tempComponentName = "";
500 
501  // Loop over all components
502  for (const auto componentName : fOrderedComponentsToExecute)
503  {
504  // Reset for each loop
505  userPropertyNames.clear();
506  defaultPropertyNames.clear();
507  // We need to remove "AliEmcalCorrection" so that the correction will be found in the configuration
508  std::string prefix = "AliEmcalCorrection";
509  tempComponentName = componentName.substr(componentName.find(prefix) + prefix.length());
510 
511  AliDebugStream(2) << "Checking component " << componentName << " for unmatched user settings" << std::endl;
512 
513  // Get the user property names
514  GetPropertyNamesFromNode("user", tempComponentName, userPropertyNames, false);
515 
516  // Get the same from default
517  // Not required here because the default configuration may not have the specialized component
518  GetPropertyNamesFromNode("default", tempComponentName, defaultPropertyNames, false);
519 
520  // We need to check the base correction as well to fill out the options
521  if (tempComponentName.find("_") != std::string::npos) {
522  // Get the base user component
523  GetPropertyNamesFromNode("user", tempComponentName.substr(0, tempComponentName.find("_")), userPropertyNames, false);
524 
525  // Required here because the default must have the base component!
526  GetPropertyNamesFromNode("default", tempComponentName.substr(0, tempComponentName.find("_")), defaultPropertyNames, true);
527  }
528 
529  // Check each property defined in the user file for a match to the properties in the default file
530  for (auto userPropertyName : userPropertyNames)
531  {
532  AliDebugStream(2) << "Checking property " << userPropertyName << std::endl;
533  foundMatch = false;
534  for (auto defaultPropertyName : defaultPropertyNames)
535  {
536  if (userPropertyName == defaultPropertyName) {
537  AliDebugStream(2) << "Found match of " << userPropertyName << " with " << defaultPropertyName << std::endl;
538  foundMatch = true;
539  }
540  }
541  if (foundMatch == false) {
542  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()));
543  }
544  }
545  }
546 }
547 
555 {
556  // Iterate over the ordered components list and create the components
557  AliEmcalCorrectionComponent * component = 0;
558  for (auto componentName : fOrderedComponentsToExecute)
559  {
560  std::string noPrefixComponentName = componentName.substr(0, componentName.find("_" + fSuffix));
561  component = AliEmcalCorrectionComponentFactory::createInstance(noPrefixComponentName);
562  if (!component)
563  {
564  AliFatal(TString::Format("Failed to create requested component %s!", componentName.c_str()));
565  }
566 
567  // For setting names of tasks to differentiate between tasks of the same class
568  component->SetName(componentName.c_str());
569  component->SetTitle(componentName.c_str());
570 
571  // Initialize the YAML configurations in each component
572  component->SetYAMLConfiguration(fYAMLConfig);
573 
574  // configure needed fields for components to properly initialize
575  component->SetIsESD(fIsEsd);
576 
577  // Add the require containers to the component
578  // Cells must be set during UserExec() because we need to add them as a pointer
581 
582  // Initialize each component
583  bool initialized = component->Initialize();
584 
585  if (component && initialized)
586  {
587  AliInfo(TString::Format("Successfully added correction task: %s", componentName.c_str()));
588  fCorrectionComponents.push_back(component);
589  }
590  }
591 }
592 
608 {
609  // Get container node
610  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
611 
612  // Determine which containers we need based on which are requested by the enabled correction tasks
613  std::set <std::string> requestedContainers;
614  std::vector <std::string> componentRequest;
615  for ( const auto & componentName : fOrderedComponentsToExecute )
616  {
617  componentRequest.clear();
618  // Not required because not all components will have all kinds of containers
619  std::string selectionName = "AliEmcalCorrection";
620  // Expliecitly initialize as a vector to avoid ambiguity.
621  fYAMLConfig.GetProperty(std::vector<std::string>{componentName.substr(componentName.find(selectionName) + selectionName.length()), inputObjectName + "Names"}, componentRequest, false);
622  for ( auto & req : componentRequest )
623  {
624  AliDebugStream(3) << "Component " << componentName << " requested container name " << req << std::endl;
625  requestedContainers.insert(req);
626  }
627  }
628 
629  AliDebugStream(2) << inputObjectName << " Containers requested by components: " << std::endl;
630  for (auto & str : requestedContainers) {
631  AliDebugStream(2) << "\t" << str << std::endl;;
632  }
633 
634  // Create all requested containers
635  AliDebug(2, TString::Format("Setting up requested containers!"));
636  SetupContainersFromInputNodes(inputObjectType, requestedContainers);
637 }
638 
648 {
649  std::string inputObjectName = GetInputFieldNameFromInputObjectType(inputObjectType);
650  // Need to be of the form "clusterContainersNames"
651  inputObjectName = inputObjectName + "Names";
652 
653  std::vector <std::string> inputObjects;
654  // Property is not required, because not all components need Clusters or Tracks
655  // Expliecitly initialize as a vector to avoid ambiguity.
656  fYAMLConfig.GetProperty(std::vector<std::string>{component->GetName(), inputObjectName.c_str()}, inputObjects, false);
657 
658  //AliDebugStream(4) << "inputObjects.size(): " << inputObjects.size() << std::endl;
659 
660  // If it is not found, then there will be nothing to iterate over, so we don't need to explicitly check the return value
661  for (auto const & str : inputObjects)
662  {
663  // 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()!
664  if (inputObjectType == AliEmcalContainerUtils::kCluster)
665  {
666  AliEmcalContainer * cont = GetClusterContainer(str.c_str());
667  AliDebugStream(2) << "Adding cluster container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
668 
669  if (checkObjectExists && !cont) {
670  AliError(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
671  }
672  component->AdoptClusterContainer(GetClusterContainer(str.c_str()));
673 
674  // Check that we are using the standard input event
675  if (!(cont->GetIsEmbedding())) {
676  component->SetUsingInputEvent(true);
677  }
678  }
679  else if (inputObjectType == AliEmcalContainerUtils::kTrack)
680  {
681  AliEmcalContainer * cont = GetParticleContainer(str.c_str());
682  AliDebugStream(2) << "Adding particle container " << str << " of array " << cont->GetArrayName() << " to component " << component->GetName() << std::endl;
683 
684  if (checkObjectExists && !cont) {
685  AliFatal(TString::Format("%s: Unable to retrieve input object \"%s\" because it is null. Please check your configuration!", GetName(), str.c_str()));
686  }
687  component->AdoptParticleContainer(GetParticleContainer(str.c_str()));
688 
689  // Check that we are using the standard input event
690  if (!(cont->GetIsEmbedding())) {
691  component->SetUsingInputEvent(true);
692  }
693  }
694  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells)
695  {
696  // NOTE: This operates different than the others. This should be executed during run time rather than during initialization!
697  if (inputObjects.size() > 1) {
698  AliFatal(TString::Format("Component %s requested more than one cell branch, but this is not supported! Check the configuration!", component->GetName()));
699  }
700 
701  // If we've made it here, this must be at least one entry
703  AliDebugStream(2) << "Adding calo cells \"" << cellCont->GetName() << "\" of branch name \"" << cellCont->GetBranchName() << "\" to component " << component->GetName() << std::endl;
704 
705  if (!(cellCont->GetCells())) {
706  // Attempt to re-initialize the cells.
707  // NOTE: This may not succeed. Adding the container may need to be repeated after the
708  // object is created
710  }
711 
712  if (checkObjectExists && !(cellCont->GetCells())) {
713  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()));
714  }
715 
716  // Set the calo cells (may be null)
717  component->SetCaloCells(cellCont->GetCells());
718 
719  // It is possible that the cells pointer is null because it may not be created yet. For example,
720  // when combining cells. Thus, we must first check whether the pointer is available before checking
721  // for the number of cells. This could potentially decrease the amount of debug information, but this
722  // should rarely be an issue.
723  if (component->GetCaloCells()) {
724  AliDebugStream(3) << "Component GetNumberOfCells: " << component->GetCaloCells()->GetNumberOfCells() << std::endl;
725  }
726 
727  // Check that we are using the standard input event
728  if (!(cellCont->GetIsEmbedding())) {
729  component->SetUsingInputEvent(true);
730  }
731  }
732  }
733 }
734 
741 void AliEmcalCorrectionTask::SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, std::set <std::string> & requestedContainers)
742 {
743  // Our node contains all of the objects that we will want to create.
744  for(auto & containerName : requestedContainers)
745  {
746  // The section is the container name
747  //std::string containerName = it->first.as<std::string>();
748  // Skip if the particle or cluster container already exists
749  if (GetParticleContainer(containerName.c_str()) || GetClusterContainer(containerName.c_str())) {
750  continue;
751  }
752 
753  AliDebug(2, TString::Format("Processing container %s of inputType %d", containerName.c_str(), inputObjectType));
754  if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
755  SetupContainer(inputObjectType, containerName);
756  }
757  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
758  SetupCellsInfo(containerName);
759  }
760  }
761 }
762 
771 void AliEmcalCorrectionTask::SetupCellsInfo(std::string containerName)
772 {
773  // Define cell info
775 
776  // Set properties
777  // Cells (object) name
778  cellObj->SetName(containerName);
779  // Branch name
780  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(AliEmcalContainerUtils::kCaloCells), containerName};
781  std::string tempString = "";
782  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "branchName", tempString, true);
783  if (tempString == "usedefault") {
785  }
786  cellObj->SetBranchName(tempString);
787 
788  // IsEmbedding
789  bool tempBool = false;
790  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "embedding", tempBool, false);
791  cellObj->SetIsEmbedding(tempBool);
792 
793  // Add to the array to keep track of it
794  fCellCollArray.push_back(cellObj);
795 }
796 
812 void AliEmcalCorrectionTask::SetupContainer(const AliEmcalContainerUtils::InputObject_t inputObjectType, const std::string containerName)
813 {
814  // Create container
815  AliDebugStream(2) << "Adding container" << std::endl;
816  AliEmcalContainer * cont = AddContainer(inputObjectType, containerName);
817  AliDebugStream(2) << "Added container" << std::endl;
818 
819  // Set the container properties
820  //
821  // TODO: Consider if this can be converted to a map to function pointers. There are a number of details
822  // which can make it a bit complicated. Those details include inheritance, pointing to member
823  // functions, etc. It should all be possible, but may not be worth all of the extra work and code.
824  // Example ccode:
825  // SetValueInContainer(inputObjectPropertiesPath, "minPt", &cont::SetMinPt, tempDouble, false);
826  // SetValueInContainer(inputObjectPropertiesPath, "minE", &cont::SetMinE, tempDouble, false);
827  // std::function may be easier?
828  // See: https://isocpp.org/wiki/faq/pointers-to-members
831  // type void (AliEmcalContainer::*EmcalContainerFn)(double val);
832  // // Potential map?
833  // std::map<std::string, EmcalContainerFn> EmcalContFunctionMap;
834  // EmcalContFunctionMap["minPt"] = &AliEmcalContainer::SetMinPt;
835  // EmcalContFunctionMap["minE"] = &AliEmcalContainer::SetMinE;
836  // // Define functions (use map?)
837  // EmcalContainerFn minPt = &AliEmcalContainer::SetMinPt;
838  // EmcalContainerFn minE = &AliEmcalContainer::SetMinE;
839  // // Example invocation
840  // (cont->*minPt)(tempDouble);
841 
842  // Path to the various properties
843  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(inputObjectType), containerName};
844 
845  // Temporary variables to store requested properties
846  std::string tempString = "";
847  Double_t tempDouble = 0;
848  bool tempBool = false;
849 
850  // AliEmcalContainer properties
851  // Min Pt
852  bool result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minPt", tempDouble, false);
853  if (result) {
854  AliDebugStream(2) << cont->GetName() << ": Setting minPt of " << tempDouble << std::endl;
855  cont->SetMinPt(tempDouble);
856  }
857  // Min E
858  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minE", tempDouble, false);
859  if (result) {
860  AliDebugStream(2) << cont->GetName() << ": Setting minE of " << tempDouble << std::endl;
861  cont->SetMinE(tempDouble);
862  }
863  // Eta min, max
864  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minEta", tempDouble, false);
865  if (result) {
866  // Only continue checking if the min is there, since we must set both together
867  Double_t tempDouble2 = 0;
868  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "maxEta", tempDouble, false);
869  if (result) {
870  AliDebugStream(2) << cont->GetName() << ": Setting eta limits of " << tempDouble << " to " << tempDouble2 << std::endl;
871  cont->SetEtaLimits(tempDouble, tempDouble2);
872  }
873  }
874  // Phi min, max
875  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "minPhi", tempDouble, false);
876  if (result) {
877  // Only continue checking if the min is there, since we must set both together
878  Double_t tempDouble2 = 0;
879  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "maxPhi", tempDouble, false);
880  if (result) {
881  AliDebugStream(2) << cont->GetName() << ": Setting phi limits of " << tempDouble << " to " << tempDouble2 << std::endl;
882  cont->SetPhiLimits(tempDouble, tempDouble2);
883  }
884  }
885  // Embedded
886  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "embedding", tempBool, false);
887  if (result) {
888  AliDebugStream(2) << cont->GetName() << ": Setting embedding to " << (tempBool ? "enabled" : "disabled") << std::endl;
889  cont->SetIsEmbedding(tempBool);
890  }
891 
892  // Cluster specific properties
893  AliClusterContainer * clusterContainer = dynamic_cast<AliClusterContainer *>(cont);
894  if (clusterContainer) {
895  // Default energy
896  // Probably not needed for the corrections
897  /*result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "defaultClusterEnergy", tempString, false);
898  if (result) {
899  // Need to get the enumeration
900  AliVCluster::VCluUserDefEnergy_t clusterEnergyType = fgkClusterEnergyTypeMap.at(tempString);
901  AliDebugStream(2) << clusterContainer->GetName() << ": Setting cluster energy type to " << clusterEnergyType << std::endl;
902  clusterContainer->SetDefaultClusterEnergy(clusterEnergyType);
903  }*/
904 
905  // NonLinCorrEnergyCut
906  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "clusNonLinCorrEnergyCut", tempDouble, false);
907  if (result) {
908  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusNonLinCorrEnergyCut of " << tempDouble << std::endl;
909  clusterContainer->SetClusNonLinCorrEnergyCut(tempDouble);
910  }
911 
912  // HadCorrEnergyCut
913  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "clusHadCorrEnergyCut", tempDouble, false);
914  if (result) {
915  AliDebugStream(2) << clusterContainer->GetName() << ": Setting clusHadCorrEnergyCut of " << tempDouble << std::endl;
916  clusterContainer->SetClusHadCorrEnergyCut(tempDouble);
917  }
918 
919  // SetIncludePHOS
920  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "includePHOS", tempBool, false);
921  if (result) {
922  AliDebugStream(2) << clusterContainer->GetName() << ": Setting Include PHOS to " << (tempBool ? "enabled" : "disabled") << std::endl;
923  clusterContainer->SetIncludePHOS(tempBool);
924  }
925  }
926 
927  // Track specific
928  AliTrackContainer * trackContainer = dynamic_cast<AliTrackContainer *>(cont);
929  if (trackContainer) {
930  // Track selection
931  // AOD Filter bits as a sequence
932  std::vector <UInt_t> filterBitsVector;
933  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "aodFilterBits", filterBitsVector, false);
934  if (result){
935  UInt_t filterBits = 0;
936  for (int filterBit : filterBitsVector) {
937  filterBits += filterBit;
938  }
939  AliDebugStream(2) << trackContainer->GetName() << ": Setting filterBits of " << filterBits << std::endl;
940  trackContainer->SetAODFilterBits(filterBits);
941  }
942 
943  // SetTrackFilterType enum
944  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "trackFilterType", tempString, false);
945  if (result) {
946  // Need to get the enumeration
947  AliEmcalTrackSelection::ETrackFilterType_t trackFilterType = fgkTrackFilterTypeMap.at(tempString);
948  AliDebugStream(2) << trackContainer->GetName() << ": Setting trackFilterType of " << trackFilterType << std::endl;
949  trackContainer->SetTrackFilterType(trackFilterType);
950  }
951 
952  // Track cuts period
953  result = fYAMLConfig.GetProperty(inputObjectPropertiesPath, "trackCutsPeriod", tempString, false);
954  if (result) {
955  // Need to get the enumeration
956  AliDebugStream(2) << trackContainer->GetName() << ": Setting track cuts period to " << tempString << std::endl;
957  trackContainer->SetTrackCutsPeriod(tempString.c_str());
958  }
959  }
960 }
961 
977 AliEmcalContainer * AliEmcalCorrectionTask::AddContainer(const AliEmcalContainerUtils::InputObject_t contType, const std::string containerName)
978 {
979  // Determine the type of branch to request
980  std::string containerBranch = "";
982  AliFatal("Must specify type of container when requesting branch.");
983  }
984 
985  // Path to the various properties
986  std::vector <std::string> inputObjectPropertiesPath = {"inputObjects", GetInputFieldNameFromInputObjectType(contType), containerName};
987 
988  // Retrieve branch name
989  fYAMLConfig.GetProperty(inputObjectPropertiesPath, "branchName", containerBranch, true);
990  // Should be unnecessary, since the user can only do this if done explicitly.
991  /*if (containerBranch == "")
992  {
993  AliFatal(TString::Format("Request %i container, but the container branch is empty!", contType));
994  }*/
995 
996  // Determine proper name if using "usedefault" pattern
997  if (containerBranch == "usedefault") {
998  containerBranch = AliEmcalContainerUtils::DetermineUseDefaultName(contType, fIsEsd);
999  }
1000 
1001  // Create containers and set them to the name of the component
1002  AliEmcalContainer * cont = 0;
1003  if (contType == AliEmcalContainerUtils::kCluster)
1004  {
1005  cont = new AliClusterContainer(containerBranch.c_str());
1006  AdoptClusterContainer(dynamic_cast<AliClusterContainer *>(cont));
1007  }
1008  else if (contType == AliEmcalContainerUtils::kTrack)
1009  {
1010  if (containerBranch == "mcparticles") {
1011  cont = new AliMCParticleContainer(containerBranch.c_str());
1012  }
1013  else {
1014  cont = new AliTrackContainer(containerBranch.c_str());
1015  }
1016  AdoptParticleContainer(dynamic_cast<AliParticleContainer *>(cont));
1017  }
1018  cont->SetName(containerName.c_str());
1019 
1020  return cont;
1021 }
1022 
1032 {
1033  // Check that the configuration is initialized
1034  if (fConfigurationInitialized != true)
1035  {
1036  AliFatal("YAML configuration must be initialized before running (ie. the AddTask, run macro or wagon)!");
1037  }
1038 
1039  // YAML Objects cannot be streamed, so we need to reinitialize them here.
1041 
1042  if (fForceBeamType == kpp)
1043  fNcentBins = 1;
1044 
1045  // Allow for output files
1046  OpenFile(1);
1047  fOutput = new TList();
1048  fOutput->SetOwner();
1049 
1051 
1052  PostData(1, fOutput);
1053 }
1054 
1062 {
1063  // Run the initialization for all derived classes.
1064  for (auto component : fCorrectionComponents)
1065  {
1066  // Set cent bins (usually used for hist creation)
1067  // It cannot be set until now because it can be changed after initialization
1068  // For instance, by SetForceBeamType()
1069  component->SetNcentralityBins(fNcentBins);
1070 
1071  component->UserCreateOutputObjects();
1072 
1073  if (component->GetOutputList() != 0)
1074  {
1075  // Adds a list to the list -- this doesn't work for some unknown reason
1076  //fOutput->Add(component->GetOutputList());
1077 
1078  // iterate through lists for each component, and fill in output
1079  TList* t = new TList();
1080  t->SetName(component->GetName());
1081  fOutput->AddLast(t);
1082  t = (TList*)fOutput->Last();
1083  TIter next(component->GetOutputList());
1084  while (TObject *obj = next()){
1085  t->Add(obj);
1086  }
1087 
1088  AliDebug(1, TString::Format("Added output list from task %s to output.", component->GetName()));
1089  }
1090  }
1091 }
1092 
1098 {
1099  // Initialize the event if not initialized
1100  if (!fEventInitialized)
1101  ExecOnce();
1102 
1103  // Only continue if we are initialized successfully
1104  if (!fEventInitialized)
1105  return;
1106 
1107  // Get the objects for each event
1108  if (!RetrieveEventObjects())
1109  return;
1110 
1111  // Call run for each correction
1112  if (!Run())
1113  return;
1114 }
1115 
1127 {
1128  if (!InputEvent()) {
1129  AliError("Could not retrieve event! Returning!");
1130  return;
1131  }
1132 
1133  // This warning was extracted out from the cell components
1134  if (dynamic_cast<AliAODEvent*>(InputEvent())) {
1135  AliWarning("=============================================================");
1136  AliWarning("=== Running on AOD is not equivalent to running on ESD! ===");
1137  AliWarning("=============================================================");
1138  }
1139 
1140  if (fNeedEmcalGeom) {
1141  fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(InputEvent()->GetRunNumber());
1142  if (!fGeom) {
1143  AliFatal("Can not get EMCal geometry instance. If you do not need the EMCal geometry, disable it by setting task->SetNeedEmcalGeometry(kFALSE).");
1144  return;
1145  }
1146  }
1147 
1148  // Load all requested track branches - each container knows name already
1149  for (Int_t i =0; i<fParticleCollArray.GetEntriesFast(); i++) {
1150  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
1152  cont->SetArray(InputEvent());
1153  }
1154 
1155  // Load all requested cluster branches - each container knows name already
1156  for (Int_t i =0; i<fClusterCollArray.GetEntriesFast(); i++) {
1157  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
1159  cont->SetArray(InputEvent());
1160  }
1161 
1162  // Determine the proper pointer for each cell object and save them to the cell container
1163  // At this point, they should all be created
1164  for (auto cellObj : fCellCollArray)
1165  {
1167  }
1168 
1169  fEventInitialized = kTRUE;
1170 
1171  // Print warning to the user that the rest of the configuration information is available in the generation log
1172  // when the Analysis Manager was created. Using cout to be certain that it is shown on the train!
1173  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";
1174 
1175  // Setup the components
1177 }
1178 
1184 {
1185  // Run the initialization for all derived classes.
1186  for (auto component : fCorrectionComponents)
1187  {
1188  // Setup geometry
1189  component->SetEMCALGeometry(fGeom);
1190 
1191  // Add the requested cells to the component
1193 
1194  // Set the input events. This is redundant to where it is set during Run(), but the events need to be
1195  // available to components, and they are only called one extra time.
1196  component->SetInputEvent(InputEvent());
1197  component->SetMCEvent(MCEvent());
1198 
1199  // Component ExecOnce()
1200  component->ExecOnce();
1201 
1202  // If the cells were created during ExecOnce(), then we need to re-initialize the pointer to ensure
1203  // that it is not null!
1204  if (!(component->GetCaloCells())) {
1205  AliDebugStream(2) << "Re-initializing cells for component " << component->GetName() << std::endl;
1207  }
1208  }
1209 }
1210 
1216 {
1217  fVertex[0] = 0;
1218  fVertex[1] = 0;
1219  fVertex[2] = 0;
1220  fNVertCont = 0;
1221 
1222  const AliVVertex *vert = InputEvent()->GetPrimaryVertex();
1223  if (vert) {
1224  vert->GetXYZ(fVertex);
1225  fNVertCont = vert->GetNContributors();
1226  }
1227 
1228  fBeamType = GetBeamType();
1229 
1230  if (fBeamType == kAA || fBeamType == kpA ) {
1232  AliMultSelection *MultSelection = static_cast<AliMultSelection*>(InputEvent()->FindListObject("MultSelection"));
1233  if (MultSelection) {
1234  fCent = MultSelection->GetMultiplicityPercentile(fCentEst.Data());
1235  }
1236  else {
1237  AliWarning("Could not retrieve centrality information! Assuming 99");
1238  }
1239  }
1240  else { // old centrality estimation < 2015
1241  AliCentrality *aliCent = InputEvent()->GetCentrality();
1242  if (aliCent) {
1243  fCent = aliCent->GetCentralityPercentile(fCentEst.Data());
1244  }
1245  else {
1246  AliWarning("Could not retrieve centrality information! Assuming 99");
1247  }
1248  }
1249 
1250  if (fNcentBins==4) {
1251  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1252  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1253  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1254  else if (fCent >= 50 && fCent <= 100) fCentBin = 3;
1255  else {
1256  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1257  fCentBin = fNcentBins-1;
1258  }
1259  }
1260  else if (fNcentBins==5) { // for PbPb 2015
1261  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1262  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1263  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1264  else if (fCent >= 50 && fCent <= 90) fCentBin = 3;
1265  else if (fCent > 90) {
1266  fCent = 99;
1267  fCentBin = 4;
1268  }
1269  else {
1270  AliWarning(Form("Negative centrality: %f. Assuming 99", fCent));
1271  fCentBin = fNcentBins-1;
1272  }
1273  }
1274  else {
1275  Double_t centWidth = (fMaxCent-fMinCent)/(Double_t)fNcentBins;
1276  if(centWidth>0.) {
1277  fCentBin = TMath::FloorNint(fCent/centWidth);
1278  }
1279  else {
1280  fCentBin = 0;
1281  }
1282  if (fCentBin>=fNcentBins) {
1283  AliWarning(Form("fCentBin too large: cent = %f fCentBin = %d. Assuming 99", fCent, fCentBin));
1284  fCentBin = fNcentBins-1;
1285  }
1286  }
1287  }
1288  else {
1289  fCent = 99;
1290  fCentBin = 0;
1291  }
1292 
1293  AliEmcalContainer* cont = 0;
1294 
1295  TIter nextPartColl(&fParticleCollArray);
1296  while ((cont = static_cast<AliEmcalContainer*>(nextPartColl()))) cont->NextEvent(InputEvent());
1297 
1298  TIter nextClusColl(&fClusterCollArray);
1299  while ((cont = static_cast<AliEmcalContainer*>(nextClusColl()))) cont->NextEvent(InputEvent());
1300 
1301  return kTRUE;
1302 }
1303 
1309 {
1310  // Run the initialization for all derived classes.
1311  for (auto component : fCorrectionComponents)
1312  {
1313  component->SetInputEvent(InputEvent());
1314  component->SetMCEvent(MCEvent());
1315  component->SetCentralityBin(fCentBin);
1316  component->SetCentrality(fCent);
1317  component->SetVertex(fVertex);
1318 
1319  component->Run();
1320  }
1321 
1322  PostData(1, fOutput);
1323 
1324  return kTRUE;
1325 }
1326 
1331 {
1332  // Run the initialization for all derived classes.
1333  for (auto component : fCorrectionComponents)
1334  {
1335  component->UserNotify();
1336  }
1337 
1338  return kTRUE;
1339 }
1340 
1347 std::ostream & AliEmcalCorrectionTask::PrintConfigurationString(std::ostream & in, bool userConfig) const
1348 {
1349  auto configPair = fYAMLConfig.GetConfiguration(userConfig ? "user" : "default");
1350  if (configPair.second.IsNull() == true) {
1351  AliWarning(TString::Format("%s configuration is empty!", configPair.first.c_str()));
1352  }
1353  in << configPair.second;
1354 
1355  return in;
1356 }
1357 
1365 bool AliEmcalCorrectionTask::WriteConfigurationFile(std::string filename, bool userConfig) const
1366 {
1367  bool returnValue = false;
1368  if (filename != "")
1369  {
1370  if (fConfigurationInitialized == true)
1371  {
1372  std::ofstream outFile(filename);
1373  PrintConfigurationString(outFile, userConfig);
1374  outFile.close();
1375 
1376  returnValue = true;
1377  }
1378  else
1379  {
1380  AliError(TString::Format("Configuration not properly initialized! Cannot print %s configuration!", userConfig ? "user" : "default"));
1381  }
1382 
1383  }
1384  else
1385  {
1386  AliError("Please pass a valid filename instead of empty quotes!");
1387  }
1388  return returnValue;
1389 }
1390 
1398 bool AliEmcalCorrectionTask::CompareToStoredConfiguration(std::string filename, bool userConfig) const
1399 {
1400  bool returnValue = false;
1401  if (filename != "")
1402  {
1403  if (fConfigurationInitialized == true)
1404  {
1405  // Generate YAML nodes for the comparison
1406  YAML::Node passedNode = YAML::LoadFile(filename);
1407  auto configPair = fYAMLConfig.GetConfiguration(userConfig ? "user" : "default");
1408 
1409  // Need to stream the configuration back to a string to remove the comments
1410  // since they are not preserved in the YAML node.
1411  std::stringstream passedNodeSS;
1412  passedNodeSS << passedNode;
1413  std::stringstream comparisonNodeSS;
1414  comparisonNodeSS << configPair.second;
1415 
1416  // Compare the nodes. Make the comparison as strings, as the YAML nodes do _not_ match,
1417  // despite the strings matching. In fact, the YAML nodes will _not_ match even if they
1418  // are generated from the same string....
1419  if (passedNodeSS.str() == comparisonNodeSS.str()) {
1420  returnValue = true;
1421  }
1422  else {
1423  AliWarningStream() << "Passed YAML config:\n" << passedNode << "\n\nStored YAML config:\n" << configPair.second << "\nPassed config located in file \"" << filename << "\" is not the same as the stored " << configPair.first << "configuration file! YAML configurations printed above.\n";
1424  }
1425  }
1426  else
1427  {
1428  AliError(TString::Format("Configuration not properly initialized! Cannot compare %s configuration!", userConfig ? "user" : "default"));
1429  }
1430  }
1431  else
1432  {
1433  AliError("Please pass a valid filename instead of empty quotes!");
1434  }
1435  return returnValue;
1436 }
1437 
1445 {
1446  AliDebugStream(2) << "Retrieving cells object " << cellContainer->GetName() << std::endl;
1447  // Check for embedding and return object
1448  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cellContainer->GetIsEmbedding());
1449 
1450  cellContainer->SetCells(dynamic_cast<AliVCaloCells *>(event->FindListObject(cellContainer->GetBranchName().c_str())));
1451 }
1452 
1463 {
1464  AliVEvent * event = AliEmcalContainerUtils::GetEvent(InputEvent(), cont->GetIsEmbedding());
1465 
1466  TClonesArray * array = dynamic_cast<TClonesArray *>(event->FindListObject(cont->GetArrayName()));
1467  if (!array) {
1468  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()));
1469  array = new TClonesArray(AliEmcalContainerUtils::DetermineUseDefaultName(objectType, fIsEsd, true).c_str());
1470  array->SetName(cont->GetArrayName());
1471  event->AddObject(array);
1472  }
1473 }
1474 
1483 {
1484  // Get container node
1485  std::string inputObjectName = "";
1486  if (inputObjectType == AliEmcalContainerUtils::kCluster) {
1487  inputObjectName = "clusterContainers";
1488  }
1489  else if (inputObjectType == AliEmcalContainerUtils::kTrack) {
1490  inputObjectName = "trackContainers";
1491  }
1492  else if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1493  inputObjectName = "cells";
1494  }
1495  else {
1496  AliFatal(TString::Format("Unrecognized input object type %d", inputObjectType));
1497  }
1498 
1499  return inputObjectName;
1500 }
1501 
1513 bool AliEmcalCorrectionTask::CheckPossibleNamesForComponentName(std::string & name, std::set <std::string> & possibleComponents)
1514 {
1515  bool foundComponent = false;
1516  for (auto & possibleComponent : possibleComponents)
1517  {
1518  if (possibleComponent == name) {
1519  foundComponent = true;
1520  break;
1521  }
1522  }
1523 
1524  return foundComponent;
1525 }
1526 
1534 {
1535  if (fForceBeamType != kNA)
1536  return fForceBeamType;
1537 
1538  AliESDEvent *esd = dynamic_cast<AliESDEvent*>(InputEvent());
1539  if (esd) {
1540  const AliESDRun *run = esd->GetESDRun();
1541  TString beamType = run->GetBeamType();
1542  if (beamType == "p-p")
1543  return kpp;
1544  else if (beamType == "A-A")
1545  return kAA;
1546  else if (beamType == "p-A")
1547  return kpA;
1548  else
1549  return kNA;
1550  } else {
1551  Int_t runNumber = InputEvent()->GetRunNumber();
1552  // All run number ranges taken from the RCT
1553  if ((runNumber >= 136833 && runNumber <= 139517) || // LHC10h
1554  (runNumber >= 167693 && runNumber <= 170593) || // LHC11h
1555  (runNumber >= 244824 && runNumber <= 246994)) { // LHC15o
1556  return kAA;
1557  } else if ((runNumber >= 188356 && runNumber <= 188366) || // LHC12g
1558  (runNumber >= 195164 && runNumber <= 197388) || // LHC13b-f
1559  (runNumber >= 265015 && runNumber <= 267166)) { // LHC16q-t
1560  return kpA;
1561  } else {
1562  return kpp;
1563  }
1564  }
1565 }
1566 
1571 {
1572  if (inputObjectType == AliEmcalContainerUtils::kCaloCells) {
1573  stream << "Cells info: " << std::endl;
1574  for (auto cellInfo : fCellCollArray) {
1575  stream << "\tName: " << cellInfo->GetName() << "\tBranch: " << cellInfo->GetBranchName() << "\tIsEmbedding: " << std::boolalpha << cellInfo->GetIsEmbedding() << std::endl;
1576  }
1577  }
1578  else if (inputObjectType == AliEmcalContainerUtils::kCluster || inputObjectType == AliEmcalContainerUtils::kTrack) {
1579  stream << (inputObjectType == AliEmcalContainerUtils::kCluster ? "Cluster" : "Track") << " container info: " << std::endl;
1580  AliEmcalContainer * cont = 0;
1581  for (auto containerInfo : (inputObjectType == AliEmcalContainerUtils::kCluster ? fClusterCollArray : fParticleCollArray) ) {
1582  cont = static_cast<AliEmcalContainer *>(containerInfo);
1583  stream << "\tName: " << cont->GetName() << "\tBranch: " << cont->GetArrayName() << "\tTitle: " << cont->GetTitle() << "\tIsEmbedding: " << std::boolalpha << cont->GetIsEmbedding() << std::endl;
1584  }
1585  }
1586  else {
1587  AliErrorStream() << "Unrecognized input object type " << inputObjectType << std::endl;
1588  }
1589 }
1590 
1603 void AliEmcalCorrectionTask::GetPropertyNamesFromNode(const std::string configurationName, const std::string componentName, std::set <std::string> & propertyNames, const bool nodeRequired)
1604 {
1605  auto configPair = fYAMLConfig.GetConfiguration(configurationName);
1606  if (configPair.second[componentName])
1607  {
1608  for (auto propertyName : configPair.second[componentName])
1609  {
1610  propertyNames.insert(propertyName.first.as<std::string>());
1611  }
1612  }
1613  else {
1614  if (nodeRequired) {
1615  std::stringstream message;
1616  message << "Failed to retrieve required property \""
1617  << componentName << "\" from the \"" << configurationName << "\" configuration!" << std::endl;
1618  AliFatal(message.str().c_str());
1619  }
1620  }
1621 }
1622 
1630 AliEmcalCorrectionCellContainer * AliEmcalCorrectionTask::GetCellContainer(const std::string & cellsContainerName) const
1631 {
1632  for (auto cellContainer : fCellCollArray)
1633  {
1634  if (cellContainer->GetName() == cellsContainerName) {
1635  return cellContainer;
1636  }
1637  }
1638 
1639  return 0;
1640 }
1641 
1643 {
1644  // Get the pointer to the existing analysis manager via the static access method.
1645  //==============================================================================
1646  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1647  if (!mgr)
1648  {
1649  ::Error("AddTaskEmcalCorrectionTask", "No analysis manager to connect to.");
1650  return nullptr;
1651  }
1652 
1653  // Check the analysis type using the event handlers connected to the analysis manager.
1654  //==============================================================================
1655  AliVEventHandler* handler = mgr->GetInputEventHandler();
1656  if (!handler)
1657  {
1658  ::Error("AddTaskEmcalCorrectionTask", "This task requires an input event handler");
1659  return nullptr;
1660  }
1661 
1662  TString name = "AliEmcalCorrectionTask";
1663  if (suffix != "") {
1664  name += TString::Format("_%s", suffix.Data());
1665  }
1666 
1667  AliEmcalCorrectionTask* mgrTask = static_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.Data()));
1668  if (mgrTask) return mgrTask;
1669 
1670  // Create the task that manages the corrections
1671  AliEmcalCorrectionTask* correctionTask = new AliEmcalCorrectionTask(name.Data());
1672 
1673  //-------------------------------------------------------
1674  // Final settings, pass to manager and set the containers
1675  //-------------------------------------------------------
1676 
1677  mgr->AddTask(correctionTask);
1678 
1679  // Create containers for input/output
1680  AliAnalysisDataContainer* cInput = mgr->GetCommonInputContainer();
1681 
1682  TString outputContainerName(name);
1683  outputContainerName += "_histos";
1684 
1685  AliAnalysisDataContainer * cOutput = mgr->CreateContainer(outputContainerName.Data(),
1686  TList::Class(),
1687  AliAnalysisManager::kOutputContainer,
1688  Form("%s", AliAnalysisManager::GetCommonFileName()));
1689 
1690  mgr->ConnectInput(correctionTask, 0, cInput);
1691  mgr->ConnectOutput(correctionTask, 1, cOutput);
1692 
1693  //TObjArray* cnt = mgr->GetContainers();
1694 
1695  return correctionTask;
1696 }
1697 
1699 {
1700  // Get the pointer to the existing analysis manager via the static access method.
1701  //==============================================================================
1702  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1703  if (!mgr)
1704  {
1705  ::Error("ConfigureEmcalCorrectionTaskOnLEGOTrain", "No analysis manager to connect to.");
1706  return nullptr;
1707  }
1708 
1709  // Find the correction task
1710  AliEmcalCorrectionTask * correctionTask = nullptr;
1711  const std::string taskName = "AliEmcalCorrectionTask";
1712  std::string foundTaskName = "";
1713  bool taskFound = false;
1714  std::vector<std::string> namesToSearch = {taskName};
1715 
1716  // Determine if the suffix name should be searched for.
1717  // If a suffix is given, it will be looked for first, followed by the generically named task.
1718  // This way, a user's configuration can be uniquely identified in the case of multiple correction tasks, but
1719  // if there is only one correction task without a suffix, this method will still fall back to that one and
1720  // return a correction task to be configured.
1721  if (suffix != "")
1722  {
1723  std::string suffixName = taskName;
1724  suffixName += "_";
1725  suffixName += suffix.Data();
1726  namesToSearch.insert(namesToSearch.begin(), suffixName);
1727  }
1728 
1729  // Attempt to retrieve the task from the analysis manager
1730  for (auto name : namesToSearch)
1731  {
1732  correctionTask = dynamic_cast<AliEmcalCorrectionTask *>(mgr->GetTask(name.c_str()));
1733  if (correctionTask != nullptr) {
1734  taskFound = true;
1735  foundTaskName = name;
1736  break;
1737  }
1738  }
1739 
1740  // Fatal if we can't find the task
1741  if (taskFound == false) {
1742  AliFatalClassF("Could not find correction task, checking for both the suffix \"%s\" and the main task. Did you remember to create it?", suffix.Data());
1743  }
1744 
1745  AliInfoClassStream() << "Found correction task named \"" << foundTaskName <<"\" to configure.\n";
1746 
1747  // AliAnalysisTaskCfg will require a task to be returned, so we add a dummy task to the analysis manager,
1748  // which will be removed when the user calls Initialize(true) on the correction task.
1749  std::string dummyTaskName = foundTaskName + "_dummyTask";
1750  mgr->AddTask(new AliAnalysisTaskSE(dummyTaskName.c_str()));
1751 
1752  return correctionTask;
1753 }
1754 
1760 std::string AliEmcalCorrectionTask::toString(bool includeYAMLConfigurationInfo) const
1761 {
1762  std::stringstream tempSS;
1763 
1764  // Show the correction components
1765  tempSS << "Correction components:\n";
1766  for (auto component : fOrderedComponentsToExecute) {
1767  tempSS << "\t" << component << "\n";
1768  }
1769  // Input objects
1770  tempSS << "\nInput objects:\n";
1774 
1775  if (includeYAMLConfigurationInfo == true) {
1776  tempSS << "\nUser Configuration:\n";
1777  PrintConfigurationString(tempSS, true);
1778  tempSS << "\n\nDefault Configuration:\n";
1779  PrintConfigurationString(tempSS);
1780  tempSS << "\n";
1781  }
1782 
1783  return tempSS.str();
1784 }
1785 
1792 std::ostream & AliEmcalCorrectionTask::Print(std::ostream & in) const {
1793  in << toString();
1794  return in;
1795 }
1796 
1804 std::ostream & operator<<(std::ostream & in, const AliEmcalCorrectionTask & myTask)
1805 {
1806  std::ostream & result = myTask.Print(in);
1807  return result;
1808 }
1809 
1817 {
1818  std::string temp(opt);
1819  bool includeYAMLConfig = false;
1820  if (temp == "YAML") {
1821  includeYAMLConfig = true;
1822  }
1823  Printf("%s", toString(includeYAMLConfig).c_str());
1824 }
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 specialized components)
void PrintRequestedContainersInformation(AliEmcalContainerUtils::InputObject_t inputObjectType, std::ostream &stream) const
Steering task for the EMCal correction framework.
AliEMCALGeometry * fGeom
! Emcal geometry
const char * filename
Definition: TestFCM.C:1
static const std::map< std::string, AliVCluster::VCluUserDefEnergy_t > fgkClusterEnergyTypeMap
Relates string to the cluster energy enumeration for YAML configuration.
static const AliVEvent * GetEvent(const AliVEvent *inputEvent, bool isEmbedding=false)
void SetTrackCutsPeriod(const char *period)
static AliEmcalCorrectionTask * ConfigureEmcalCorrectionTaskOnLEGOTrain(TString suffix)
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)
void SetupContainer(const AliEmcalContainerUtils::InputObject_t inputObjectType, const std::string containerName)
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.
std::string GetInputFieldNameFromInputObjectType(AliEmcalContainerUtils::InputObject_t inputObjectType)
static std::string DetermineUseDefaultName(InputObject_t objType, bool esdMode, bool returnObjectType=false)
void AdoptClusterContainer(AliClusterContainer *cont)
void UserExec(Option_t *option)
AliEmcalCorrectionTask & operator=(AliEmcalCorrectionTask other)
Double_t fMaxCent
max centrality for event selection
Double_t fVertex[3]
! Event vertex
AliEmcalContainer * AddContainer(const AliEmcalContainerUtils::InputObject_t contType, const std::string containerName)
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.
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.
void SetupCellsInfo(std::string containerName)
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.
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
void GetPropertyNamesFromNode(const std::string configurationName, const std::string componentName, std::set< std::string > &propertyNames, const bool nodeRequired)
InputObject_t
Type of input object to be created
AliClusterContainer * GetClusterContainer(Int_t i=0) const
unsigned int UInt_t
Definition: External.C:33
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)
bool GetProperty(std::vector< std::string > propertyPath, const std::string &propertyName, T &property, const bool requiredProperty) const
void SetIncludePHOS(Bool_t b)
friend std::ostream & operator<<(std::ostream &in, const AliEmcalCorrectionTask &myTask)
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
AliYAMLConfiguration fYAMLConfig
Handles configuration from YAML.
std::string fDefaultConfigurationFilename
! Default YAML configuration filename
bool AddConfiguration(std::string configurationFilename, std::string configurationName="")
TObjArray fParticleCollArray
Particle/track collection array.
TObjArray fClusterCollArray
Cluster collection array.
ETrackFilterType_t
Pre-defined track filters.
void AdoptParticleContainer(AliParticleContainer *cont)
void SetIsEmbedding(bool isEmbedded)
Set to true if the cells are located in the event that is being embedded.
void SetCaloCells(AliVCaloCells *cells)
const std::pair< std::string, YAML::Node > & GetConfiguration(const int i) const
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 Print(Option_t *opt="") const
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
void SetupContainersFromInputNodes(AliEmcalContainerUtils::InputObject_t inputObjectType, std::set< std::string > &requestedContainers)
Double_t fMinCent
min centrality for event selection
std::vector< AliEmcalCorrectionCellContainer * > fCellCollArray
Cells collection array.
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)
void Initialize(bool removeDummyTask=false)
void SetYAMLConfiguration(AliYAMLConfiguration config)
Set YAML Configuration.
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)
BeamType fForceBeamType
forced beam type