ROOT logo
/// \ingroup macros
/// \file AddTaskMuonAlignment.C
/// \brief Macro to add an AliMUONAlignmentTask to an analysis train
///
/// \author Javier Castillo, CEA/Saclay - Irfu/SPhN
/// \author Hugo Pereira Da Costa, CEA/Saclay - Irfu/SPhN

/**
AliMUONAlignmentTask calculates alignment correction for the muon spectrometer
based on reconstructed tracks, either with or without magnetic field. It uses AliMillePede2
internally for alignment, and AliMillePedeRecords for storing the derivatives.

The task has two ways of operation

1/ Full mode:
This corresponds to flags: readRecords = kFALSE, doAlignment = kTRUE, writeRecords = kFALSE
- reads tracks from an ESD,
- calculates all derivatives needed to minimize both the tracks
  and the alignment parameters
- fill and invert the (large) matrix corresponding to the global chisquare minimization
- write the resulting alignment parameters, on top of the initiali geometry, in a new CDB

Note that writeRecords can also be set to kTRUE. This will output all derivatives to a special
branch in an AOD for re-running the alignment with no need to process the tracks (see below)

2/ Split mode:
The task must run twice.
First pass with flags: readRecords = kFALSE, writeRecords = kTRUE, doAlignment = kFALSE
This
- reads tracks from an ESD,
- calculates all derivatives needed to minimize both the tracks
  and the alignment parameters
- stores them in a special branch of the output AOD, named "records",
  and containing a TClonesArray of objects typed "AliMillePedeRecord"

Second pass with flags: readRecords = kTRUE, doAlignment = kTRUE
- reads the AliMillePedeRecords stored in the AOD (or a collection of AODs)
- fill and invert the (large) matrix corresponding to the global chisquare minimization
- write the resulting alignment parameters, on top of the initiali geometry, in a new CDB

The split mode is usefull for running on the grid:
- the first pass can be done with multiple jobs (one per ESD chunk) in parallel.
- the second pass must be done one on all created AODs, in a single shot, possibly locally

When performing the alignment (doAlignment=kTRUE), one can "fix", "group", or "constrain"
detector's alignment parameters in order to ease the inversion.

One can redo the second pass as many times as needed, changing these "fixed/group/constrained" parameters,
without re-processing the ESD tracks.
*/

#include "AliAnalysisManager.h"
#include "AliMUONAlignmentTask.h"
#include "AliVEventHandler.h"

AliMUONAlignmentTask *AddTaskMuonAlignment(
  TString oldAlignmentOCDB,
  TString newAlignmentOCDB,
  Bool_t doAlignment = kTRUE,
  Bool_t writeRecords = kTRUE,
  Bool_t readRecords = kFALSE
 )
{

  /// Creates a Muon Alignment task and adds it to the analysis manager.

  // Get the pointer to the existing analysis manager via the static access method.
  AliAnalysisManager *analysisManager = AliAnalysisManager::GetAnalysisManager();
  if( !analysisManager )
  {
    ::Error("AddTaskMuonAlignment", "No analysis manager to connect to.");
    return NULL;
  }

  // get input event handler and check type
  TString type = analysisManager->GetInputEventHandler()->GetDataType();
  if( readRecords )
  {

    // when reading records, AOD are required
    if (!type.Contains( "AOD" ) )
    {
      Error("AddTaskMuonRefit", "AOD input handler needed!");
      return NULL;
    }

  } else {

    // ESDs are required otherwise
    if( !type.Contains( "ESD" ) )
    {
      Error("AddTaskMuonRefit", "AOD input handler needed!");
      return NULL;
    }

  }

  // Create the task, add it to the manager and configure it.
  AliMUONAlignmentTask *muonAlign = new AliMUONAlignmentTask( "AliMUONAlignmentTask" );
  muonAlign->SetOldAlignStorage( oldAlignmentOCDB );
  muonAlign->SetNewAlignStorage( newAlignmentOCDB );
  muonAlign->SetLoadOCDBOnce( kTRUE );
  muonAlign->SetReadRecords( readRecords );
  muonAlign->SetDoAlignment( doAlignment );
  muonAlign->SetWriteRecords( writeRecords );
  muonAlign->SetMergeAlignmentCDBs( kTRUE );

  analysisManager->AddTask(muonAlign);

  // connect input
  analysisManager->ConnectInput(muonAlign,  0, analysisManager->GetCommonInputContainer());

  // when writting records, also connect output
  if( writeRecords )
  { analysisManager->ConnectOutput(muonAlign,  0, analysisManager->GetCommonOutputContainer()); }

  // return created task
  return muonAlign;

}
 AddTaskMuonAlignment.C:1
 AddTaskMuonAlignment.C:2
 AddTaskMuonAlignment.C:3
 AddTaskMuonAlignment.C:4
 AddTaskMuonAlignment.C:5
 AddTaskMuonAlignment.C:6
 AddTaskMuonAlignment.C:7
 AddTaskMuonAlignment.C:8
 AddTaskMuonAlignment.C:9
 AddTaskMuonAlignment.C:10
 AddTaskMuonAlignment.C:11
 AddTaskMuonAlignment.C:12
 AddTaskMuonAlignment.C:13
 AddTaskMuonAlignment.C:14
 AddTaskMuonAlignment.C:15
 AddTaskMuonAlignment.C:16
 AddTaskMuonAlignment.C:17
 AddTaskMuonAlignment.C:18
 AddTaskMuonAlignment.C:19
 AddTaskMuonAlignment.C:20
 AddTaskMuonAlignment.C:21
 AddTaskMuonAlignment.C:22
 AddTaskMuonAlignment.C:23
 AddTaskMuonAlignment.C:24
 AddTaskMuonAlignment.C:25
 AddTaskMuonAlignment.C:26
 AddTaskMuonAlignment.C:27
 AddTaskMuonAlignment.C:28
 AddTaskMuonAlignment.C:29
 AddTaskMuonAlignment.C:30
 AddTaskMuonAlignment.C:31
 AddTaskMuonAlignment.C:32
 AddTaskMuonAlignment.C:33
 AddTaskMuonAlignment.C:34
 AddTaskMuonAlignment.C:35
 AddTaskMuonAlignment.C:36
 AddTaskMuonAlignment.C:37
 AddTaskMuonAlignment.C:38
 AddTaskMuonAlignment.C:39
 AddTaskMuonAlignment.C:40
 AddTaskMuonAlignment.C:41
 AddTaskMuonAlignment.C:42
 AddTaskMuonAlignment.C:43
 AddTaskMuonAlignment.C:44
 AddTaskMuonAlignment.C:45
 AddTaskMuonAlignment.C:46
 AddTaskMuonAlignment.C:47
 AddTaskMuonAlignment.C:48
 AddTaskMuonAlignment.C:49
 AddTaskMuonAlignment.C:50
 AddTaskMuonAlignment.C:51
 AddTaskMuonAlignment.C:52
 AddTaskMuonAlignment.C:53
 AddTaskMuonAlignment.C:54
 AddTaskMuonAlignment.C:55
 AddTaskMuonAlignment.C:56
 AddTaskMuonAlignment.C:57
 AddTaskMuonAlignment.C:58
 AddTaskMuonAlignment.C:59
 AddTaskMuonAlignment.C:60
 AddTaskMuonAlignment.C:61
 AddTaskMuonAlignment.C:62
 AddTaskMuonAlignment.C:63
 AddTaskMuonAlignment.C:64
 AddTaskMuonAlignment.C:65
 AddTaskMuonAlignment.C:66
 AddTaskMuonAlignment.C:67
 AddTaskMuonAlignment.C:68
 AddTaskMuonAlignment.C:69
 AddTaskMuonAlignment.C:70
 AddTaskMuonAlignment.C:71
 AddTaskMuonAlignment.C:72
 AddTaskMuonAlignment.C:73
 AddTaskMuonAlignment.C:74
 AddTaskMuonAlignment.C:75
 AddTaskMuonAlignment.C:76
 AddTaskMuonAlignment.C:77
 AddTaskMuonAlignment.C:78
 AddTaskMuonAlignment.C:79
 AddTaskMuonAlignment.C:80
 AddTaskMuonAlignment.C:81
 AddTaskMuonAlignment.C:82
 AddTaskMuonAlignment.C:83
 AddTaskMuonAlignment.C:84
 AddTaskMuonAlignment.C:85
 AddTaskMuonAlignment.C:86
 AddTaskMuonAlignment.C:87
 AddTaskMuonAlignment.C:88
 AddTaskMuonAlignment.C:89
 AddTaskMuonAlignment.C:90
 AddTaskMuonAlignment.C:91
 AddTaskMuonAlignment.C:92
 AddTaskMuonAlignment.C:93
 AddTaskMuonAlignment.C:94
 AddTaskMuonAlignment.C:95
 AddTaskMuonAlignment.C:96
 AddTaskMuonAlignment.C:97
 AddTaskMuonAlignment.C:98
 AddTaskMuonAlignment.C:99
 AddTaskMuonAlignment.C:100
 AddTaskMuonAlignment.C:101
 AddTaskMuonAlignment.C:102
 AddTaskMuonAlignment.C:103
 AddTaskMuonAlignment.C:104
 AddTaskMuonAlignment.C:105
 AddTaskMuonAlignment.C:106
 AddTaskMuonAlignment.C:107
 AddTaskMuonAlignment.C:108
 AddTaskMuonAlignment.C:109
 AddTaskMuonAlignment.C:110
 AddTaskMuonAlignment.C:111
 AddTaskMuonAlignment.C:112
 AddTaskMuonAlignment.C:113
 AddTaskMuonAlignment.C:114
 AddTaskMuonAlignment.C:115
 AddTaskMuonAlignment.C:116
 AddTaskMuonAlignment.C:117
 AddTaskMuonAlignment.C:118
 AddTaskMuonAlignment.C:119
 AddTaskMuonAlignment.C:120
 AddTaskMuonAlignment.C:121