alignment within train of the analysis (calibration?) framework.
- AliMUONReAlignTask and AddTaskMuonReAlign: New AliAnalysisTask to realign the muon
spectrometer and generate a muon clusterInfo tree for monitoring within train of the
analysis (calibration?) framework.
(Javier)
--- /dev/null
+/// \ingroup macros
+/// \file AddTaskMuonAlignment.C
+/// \brief Macro to add an AliMUONAlignmentTask to an analysis train
+///
+/// \author Javier Castillo, CEA/Saclay - Irfu/SPhN
+
+AliMUONAlignmentTask *AddTaskMuonAlignment()
+{
+/// Creates a filter task and adds it to the analysis manager.
+
+ // Get the pointer to the existing analysis manager via the static access method.
+ //==============================================================================
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) {
+ ::Error("AddTaskMuonAlignment", "No analysis manager to connect to.");
+ return NULL;
+ }
+
+ // This task requires an ESD input handler.
+ // Check this using the analysis manager.
+ //===============================================================================
+ TString type = mgr->GetInputEventHandler()->GetDataType();
+ if (!type.Contains("ESD")) {
+ ::Error("AddTaskMuonAlignment", "ESD filtering task needs the manager to have an ESD input handler.");
+ return NULL;
+ }
+
+ // Create the task, add it to the manager and configure it.
+ //===========================================================================
+ // Muons
+ AliMUONAlignmentTask *muonalign = new AliMUONAlignmentTask("Muon alignment");
+ mgr->AddTask(muonalign);
+
+// // Cuts on primary tracks
+// AliESDtrackCuts* esdTrackCutsL = new AliESDtrackCuts("AliESDtrackCuts", "Standard");
+// esdTrackCutsL->SetMinNClustersTPC(50);
+
+// AliAnalysisFilter* trackFilter = new AliAnalysisFilter("trackFilter");
+// trackFilter->AddCuts(esdTrackCutsL);
+
+// muonalign->SetTrackFilter(trackFilter);
+
+
+ // Create ONLY the output containers for the data produced by the task.
+ // Get and connect other common input/output containers via the manager as below
+ //==============================================================================
+ AliAnalysisDataContainer *listOut = mgr->CreateContainer("output", TList::Class(), AliAnalysisManager::kOutputContainer, "measShifts.root");
+ mgr->ConnectInput (muonalign, 0, mgr->GetCommonInputContainer());
+ mgr->ConnectOutput (muonalign, 0, listOut);
+ return muonalign;
+}
--- /dev/null
+/// \ingroup macros
+/// \file AddTaskMuonReAlign.C
+/// \brief Macro to add an AliMUONReAlignTask to an analysis train
+///
+/// \author Javier Castillo, CEA/Saclay - Irfu/SPhN
+
+AliMUONReAlignTask *AddTaskMuonReAlign()
+{
+/// Creates a filter task and adds it to the analysis manager.
+
+ // Get the pointer to the existing analysis manager via the static access method.
+ //==============================================================================
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) {
+ ::Error("AddTaskMuonReAlign", "No analysis manager to connect to.");
+ return NULL;
+ }
+
+ // This task requires an ESD input handler.
+ // Check this using the analysis manager.
+ //===============================================================================
+ TString type = mgr->GetInputEventHandler()->GetDataType();
+ if (!type.Contains("ESD")) {
+ ::Error("AddTaskMuonReAlign", "ESD filtering task needs the manager to have an ESD input handler.");
+ return NULL;
+ }
+
+ // Create the task, add it to the manager and configure it.
+ //===========================================================================
+ // Muons
+ AliMUONReAlignTask *muonrealign = new AliMUONReAlignTask("Muon realign");
+ mgr->AddTask(muonrealign);
+
+// // Cuts on primary tracks
+// AliESDtrackCuts* esdTrackCutsL = new AliESDtrackCuts("AliESDtrackCuts", "Standard");
+// esdTrackCutsL->SetMinNClustersTPC(50);
+
+// AliAnalysisFilter* trackFilter = new AliAnalysisFilter("trackFilter");
+// trackFilter->AddCuts(esdTrackCutsL);
+
+// muonalign->SetTrackFilter(trackFilter);
+
+
+
+ // Create ONLY the output containers for the data produced by the task.
+ // Get and connect other common input/output containers via the manager as below
+ //==============================================================================
+ AliAnalysisDataContainer *treeOut = mgr->CreateContainer("output", TTree::Class(), AliAnalysisManager::kOutputContainer, "clusterInfo.root");
+ mgr->ConnectInput (muonrealign, 0, mgr->GetCommonInputContainer());
+ mgr->ConnectOutput (muonrealign, 0, treeOut);
+ return muonrealign;
+}
--- /dev/null
+//-----------------------------------------------------------------------------
+/// \class AliMUONAlignmentTask
+/// AliAnalysisTask to align the MUON spectrometer.
+/// The Task reads as input ESDs and feeds the MUONTracks to AliMUONAlignment.
+/// The alignment itself is performed by AliMillepede.
+/// A OCDB entry is written with the alignment parameters.
+/// A list of graph are written to monitor the alignment parameters.
+///
+/// \author Javier Castillo, CEA/Saclay - Irfu/SPhN
+//-----------------------------------------------------------------------------
+
+#include <fstream>
+
+#include <TString.h>
+#include <TError.h>
+#include <TGraphErrors.h>
+#include <TTree.h>
+#include <TChain.h>
+#include <TClonesArray.h>
+#include <TGeoGlobalMagField.h>
+#include <Riostream.h>
+
+#include "AliAnalysisTask.h"
+#include "AliAnalysisManager.h"
+#include "AliESDInputHandler.h"
+#include "AliESDEvent.h"
+#include "AliESDMuonTrack.h"
+#include "AliMagF.h"
+#include "AliCDBManager.h"
+#include "AliCDBMetaData.h"
+#include "AliCDBId.h"
+#include "AliGeomManager.h"
+
+#include "AliMpCDB.h"
+#include "AliMUONAlignment.h"
+#include "AliMUONTrack.h"
+#include "AliMUONTrackExtrap.h"
+#include "AliMUONTrackParam.h"
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONESDInterface.h"
+
+#include "AliMUONAlignmentTask.h"
+
+///\cond CLASSIMP
+ClassImp(AliMUONAlignmentTask)
+///\endcond
+
+// //________________________________________________________________________
+// AliMUONAlignmentTask::AliMUONAlignmentTask(const char *name)
+// : AliAnalysisTask(name, ""),
+// fESD(0x0),
+// fAlign(0x0),
+// fGeoFilename(""),
+// fTransform(0x0),
+// fTrackTot(0),
+// fTrackOk(0),
+// fMSDEx(0x0),
+// fMSDEy(0x0),
+// fMSDEz(0x0),
+// fMSDEp(0x0),
+// fList(0x0)
+// {
+// /// Default Constructor
+// // Define input and output slots here
+// // Input slot #0 works with a TChain
+// DefineInput(0, TChain::Class());
+// // Output slot #0 writes NTuple/histos into a TList
+// DefineOutput(0, TList::Class());
+
+// // initialize parameters ...
+// for(Int_t k=0;k<4*156;k++) {
+// fParameters[k]=0.;
+// fErrors[k]=0.;
+// fPulls[k]=0.;
+// }
+
+// fAlign = new AliMUONAlignment();
+// fTransform = new AliMUONGeometryTransformer();
+// }
+
+//________________________________________________________________________
+AliMUONAlignmentTask::AliMUONAlignmentTask(const char *name, const char *geofilename)
+ : AliAnalysisTask(name, ""),
+ fESD(0x0),
+ fAlign(0x0),
+ fGeoFilename(geofilename),
+ fTransform(0x0),
+ fTrackTot(0),
+ fTrackOk(0),
+ fMSDEx(0x0),
+ fMSDEy(0x0),
+ fMSDEz(0x0),
+ fMSDEp(0x0),
+ fList(0x0)
+{
+ /// Default Constructor
+ // Define input and output slots here
+ // Input slot #0 works with a TChain
+ DefineInput(0, TChain::Class());
+ // Output slot #0 writes NTuple/histos into a TList
+ DefineOutput(0, TList::Class());
+
+ // initialize parameters ...
+ for(Int_t k=0;k<4*156;k++) {
+ fParameters[k]=0.;
+ fErrors[k]=0.;
+ fPulls[k]=0.;
+ }
+
+ fAlign = new AliMUONAlignment();
+ fTransform = new AliMUONGeometryTransformer();
+}
+
+
+//________________________________________________________________________
+AliMUONAlignmentTask::AliMUONAlignmentTask(const AliMUONAlignmentTask& obj)
+ : AliAnalysisTask(obj),
+ fESD(0x0),
+ fAlign(0x0),
+ fGeoFilename(""),
+ fTransform(0x0),
+ fTrackTot(0),
+ fTrackOk(0),
+ fMSDEx(0x0),
+ fMSDEy(0x0),
+ fMSDEz(0x0),
+ fMSDEp(0x0),
+ fList(0x0)
+{
+ /// Copy constructor
+ fESD = obj.fESD;
+ fAlign = obj.fAlign;
+ fGeoFilename = obj.fGeoFilename;
+ fTransform = obj.fTransform;
+ fTrackTot = obj.fTrackTot;
+ fTrackOk = obj.fTrackOk;
+ fMSDEx = obj.fMSDEx;
+ fMSDEy = obj.fMSDEy;
+ fMSDEz = obj.fMSDEz;
+ fMSDEp = obj.fMSDEp;
+ fList = obj.fList;
+}
+
+//________________________________________________________________________
+AliMUONAlignmentTask& AliMUONAlignmentTask::operator=(const AliMUONAlignmentTask& other)
+{
+ /// Assignment
+ AliAnalysisTask::operator=(other);
+ fESD = other.fESD;
+ fAlign = other.fAlign;
+ fGeoFilename = other.fGeoFilename;
+ fTransform = other.fTransform;
+ fTrackTot = other.fTrackTot;
+ fTrackOk = other.fTrackOk;
+ fMSDEx = other.fMSDEx;
+ fMSDEy = other.fMSDEy;
+ fMSDEz = other.fMSDEz;
+ fMSDEp = other.fMSDEp;
+ fList = other.fList;
+
+ return *this;
+}
+
+//________________________________________________________________________
+AliMUONAlignmentTask::~AliMUONAlignmentTask()
+{
+ /// Destructor
+ if (fAlign) delete fAlign;
+ if (fTransform) delete fTransform;
+}
+
+//________________________________________________________________________
+void AliMUONAlignmentTask::LocalInit()
+{
+ /// Local initialization, called once per task on the client machine
+ /// where the analysis train is assembled
+ AliMpCDB::LoadMpSegmentation();
+
+ // Import TGeo geometry (needed by AliMUONTrackExtrap::ExtrapToVertex)
+ if ( ! AliGeomManager::GetGeometry() ) {
+ AliGeomManager::LoadGeometry(fGeoFilename.Data());
+ if (! AliGeomManager::GetGeometry() ) {
+ Error("MUONAlignment", "getting geometry from file %s failed", fGeoFilename.Data());
+ return;
+ }
+ }
+
+ // set mag field
+ // waiting for mag field in CDB
+ if (!TGeoGlobalMagField::Instance()->GetField()) {
+ printf("Loading field map...\n");
+ AliMagF* field = new AliMagF("Maps","Maps",2,0.,0., 10.,AliMagF::k5kG);
+ TGeoGlobalMagField::Instance()->SetField(field);
+ }
+ // set the magnetic field for track extrapolations
+ AliMUONTrackExtrap::SetField();
+
+ // Set initial values here, good guess may help convergence
+ // St 1
+ // Int_t iPar = 0;
+ // fParameters[iPar++] = 0.010300 ; fParameters[iPar++] = 0.010600 ; fParameters[iPar++] = 0.000396 ;
+
+
+ fAlign->InitGlobalParameters(fParameters);
+
+
+ fTransform->LoadGeometryData();
+ fAlign->SetGeometryTransformer(fTransform);
+
+ // Do alignment with magnetic field off
+ fAlign->SetBFieldOn(kFALSE);
+
+ // Set tracking station to use
+ // Bool_t bStOnOff[5] = {kTRUE,kTRUE,kTRUE,kTRUE,kTRUE};
+ Bool_t bChOnOff[10] = {kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kFALSE,kTRUE,kTRUE,kTRUE,kTRUE};
+
+ // Set degrees of freedom to align (see AliMUONAlignment)
+ fAlign->AllowVariations(bChOnOff);
+
+ // Fix parameters or add constraints here
+ // for (Int_t iSt=0; iSt<5; iSt++)
+ // if (!bStOnOff[iSt]) fAlign->FixStation(iSt+1);
+ for (Int_t iCh=0; iCh<10; iCh++)
+ if (!bChOnOff[iCh]) fAlign->FixChamber(iCh+1);
+
+ // Left and right sides of the detector are independent, one can choose to align
+ // only one side
+ Bool_t bSpecLROnOff[2] = {kTRUE,kTRUE};
+ fAlign->FixHalfSpectrometer(bChOnOff,bSpecLROnOff);
+
+ fAlign->SetChOnOff(bChOnOff);
+ fAlign->SetSpecLROnOff(bChOnOff);
+
+ // Here we can fix some detection elements
+ fAlign->FixDetElem(908);
+ fAlign->FixDetElem(1020);
+
+ // Set predifined global constrains: X, Y, P, XvsZ, YvsZ, PvsZ, XvsY, YvsY, PvsY
+// Bool_t bVarXYT[9] = {kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE};
+// Bool_t bDetTLBR[4] = {kFALSE,kTRUE,kFALSE,kTRUE};
+ // fAlign->AddConstraints(bChOnOff,bVarXYT,bDetTLBR,bSpecLROnOff);
+
+}
+
+//________________________________________________________________________
+void AliMUONAlignmentTask::ConnectInputData(Option_t *)
+{
+ /// Connect ESD here. Called on each input data change.
+
+ // Connect ESD here
+ TTree* esdTree = dynamic_cast<TTree*> (GetInputData(0));
+ if (!esdTree) {
+ Printf("ERROR: Could not read chain from input slot 0");
+ }
+ else {
+ AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+ if (!esdH) {
+ Printf("ERROR: Could not get ESDInputHandler");
+ }
+ else {
+ fESD = esdH->GetEvent();
+ }
+ }
+}
+
+//________________________________________________________________________
+void AliMUONAlignmentTask::CreateOutputObjects()
+{
+ /// Executed once on each worker (machine actually running the analysis code)
+ //
+ // This method has to be called INSIDE the user redefined CreateOutputObjects
+ // method, before creating each object corresponding to the output containers
+ // that are to be written to a file. This need to be done in general for the big output
+ // objects that may not fit memory during processing.
+ // OpenFile(0);
+
+ // Creating graphs
+ fMSDEx = new TGraphErrors(156);
+ fMSDEy = new TGraphErrors(156);
+ fMSDEz = new TGraphErrors(156);
+ fMSDEp = new TGraphErrors(156);
+
+ // Add Ntuples to the list
+ fList = new TList();
+ fList->Add(fMSDEx);
+ fList->Add(fMSDEy);
+ fList->Add(fMSDEz);
+ fList->Add(fMSDEp);
+}
+
+//________________________________________________________________________
+void AliMUONAlignmentTask::Exec(Option_t *)
+{
+ /// Main loop, called for each event
+ if (!fESD) {
+ Printf("ERROR: fESD not available");
+ return;
+ }
+
+ Double_t trackParams[8] = {0.,0.,0.,0.,0.,0.,0.,0.};
+
+
+
+ Int_t nTracks = Int_t(fESD->GetNumberOfMuonTracks());
+ // if (!event%100) cout << " there are " << nTracks << " tracks in event " << event << endl;
+ for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
+ AliESDMuonTrack* esdTrack = fESD->GetMuonTrack(iTrack);
+ if (!esdTrack->ClustersStored()) continue;
+ Double_t invBenMom = esdTrack->GetInverseBendingMomentum();
+// fInvBenMom->Fill(invBenMom);
+// fBenMom->Fill(1./invBenMom);
+ if (TMath::Abs(invBenMom)<=1.04) {
+ AliMUONTrack track;
+ AliMUONESDInterface::ESDToMUON(*esdTrack, track);
+ fAlign->ProcessTrack(&track);
+ fAlign->LocalFit(fTrackOk++,trackParams,0);
+ }
+ fTrackTot++;
+ }
+
+ // Post final data. Write histo list to a file with option "RECREATE"
+ PostData(0,fList);
+}
+
+//________________________________________________________________________
+void AliMUONAlignmentTask::Terminate(const Option_t*)
+{
+ /// Called once per task on the client machine at the end of the analysis.
+
+ cout << "Processed " << fTrackTot << " Tracks." << endl;
+ // Perform global fit
+ fAlign->GlobalFit(fParameters,fErrors,fPulls);
+
+ cout << "Done with GlobalFit " << endl;
+
+ // Update pointers reading them from the output slot
+ fList = (TList*)GetOutputData(0);
+ fMSDEx = (TGraphErrors*)fList->At(0);
+ fMSDEy = (TGraphErrors*)fList->At(1);
+ fMSDEz = (TGraphErrors*)fList->At(2);
+ fMSDEp = (TGraphErrors*)fList->At(3);
+
+ // Store results
+ Double_t DEid[156] = {0};
+ Double_t MSDEx[156] = {0};
+ Double_t MSDEy[156] = {0};
+ Double_t MSDEz[156] = {0};
+ Double_t MSDEp[156] = {0};
+ Double_t DEidErr[156] = {0};
+ Double_t MSDExErr[156] = {0};
+ Double_t MSDEyErr[156] = {0};
+ Double_t MSDEzErr[156] = {0};
+ Double_t MSDEpErr[156] = {0};
+ Int_t lNDetElem = 4*2+4*2+18*2+26*2+26*2;
+ Int_t lNDetElemCh[10] = {4,4,4,4,18,18,26,26,26,26};
+ // Int_t lSNDetElemCh[10] = {4,8,12,16,34,52,78,104,130,156};
+ Int_t idOffset = 0; // 400
+ Int_t lSDetElemCh = 0;
+ for(Int_t iDE=0; iDE<lNDetElem; iDE++){
+ DEidErr[iDE] = 0.;
+ DEid[iDE] = idOffset+100;
+ DEid[iDE] += iDE;
+ lSDetElemCh = 0;
+ for(Int_t iCh=0; iCh<9; iCh++){
+ lSDetElemCh += lNDetElemCh[iCh];
+ if (iDE>=lSDetElemCh) {
+ DEid[iDE] += 100;
+ DEid[iDE] -= lNDetElemCh[iCh];
+ }
+ }
+ MSDEx[iDE]=fParameters[3*iDE+0];
+ MSDEy[iDE]=fParameters[3*iDE+1];
+ MSDEz[iDE]=fParameters[3*iDE+3];
+ MSDEp[iDE]=fParameters[3*iDE+2];
+ MSDExErr[iDE]=(Double_t)fAlign->GetParError(3*iDE+0);
+ MSDEyErr[iDE]=(Double_t)fAlign->GetParError(3*iDE+1);
+ MSDEzErr[iDE]=(Double_t)fAlign->GetParError(3*iDE+3);
+ MSDEpErr[iDE]=(Double_t)fAlign->GetParError(3*iDE+2);
+ fMSDEx->SetPoint(iDE,DEid[iDE],fParameters[3*iDE+0]);
+ fMSDEx->SetPoint(iDE,DEidErr[iDE],(Double_t)fAlign->GetParError(3*iDE+0));
+ fMSDEy->SetPoint(iDE,DEid[iDE],fParameters[3*iDE+1]);
+ fMSDEy->SetPoint(iDE,DEidErr[iDE],(Double_t)fAlign->GetParError(3*iDE+1));
+ fMSDEp->SetPoint(iDE,DEid[iDE],fParameters[3*iDE+2]);
+ fMSDEp->SetPoint(iDE,DEidErr[iDE],(Double_t)fAlign->GetParError(3*iDE+2));
+ fMSDEz->SetPoint(iDE,DEid[iDE],fParameters[3*iDE+3]);
+ fMSDEz->SetPoint(iDE,DEidErr[iDE],(Double_t)fAlign->GetParError(3*iDE+3));
+ }
+
+ // Post final data. Write histo list to a file with option "RECREATE"
+ PostData(0,fList);
+
+
+ // Re Align
+ AliMUONGeometryTransformer *newTransform = fAlign->ReAlign(fTransform,fParameters,true);
+ newTransform->WriteTransformations("transform2ReAlign.dat");
+
+ // Generate realigned data in local cdb
+ const TClonesArray* array = newTransform->GetMisAlignmentData();
+
+ // 100 mum residual resolution for chamber misalignments?
+ fAlign->SetAlignmentResolution(array,-1,0.01,0.01,0.004,0.003);
+
+ // CDB manager
+ AliCDBManager* cdbManager = AliCDBManager::Instance();
+ cdbManager->SetDefaultStorage("local://ReAlignCDB");
+
+ AliCDBMetaData* cdbData = new AliCDBMetaData();
+ cdbData->SetResponsible("Dimuon Offline project");
+ cdbData->SetComment("MUON alignment objects with residual misalignment");
+ AliCDBId id("MUON/Align/Data", 0, AliCDBRunRange::Infinity());
+ cdbManager->Put(const_cast<TClonesArray*>(array), id, cdbData);
+
+}
+
--- /dev/null
+#ifndef ALIMUONALIGNMENTTASK_H
+#define ALIMUONALIGNMENTTASK_H
+
+/// \ingroup ""
+/// \class AliMUONAlignmentTask
+/// \brief Task to align the muon spectrometer
+///
+// Author Javier Castillo, CEA/Saclay - Irfu/SPhN
+
+class TList;
+class TGraphErrors;
+class AliESDEvent;
+class AliMUONAlignment;
+class AliMUONGeoemetryTransformer;
+
+#include "AliAnalysisTask.h"
+
+class AliMUONAlignmentTask : public AliAnalysisTask {
+ public:
+ // AliMUONAlignmentTask(const char *name = "AliMUONAlignmentTask");
+ AliMUONAlignmentTask(const char *name = "AliMUONAlignmentTask", const char *geofilename = "geometry.root");
+ AliMUONAlignmentTask(const AliMUONAlignmentTask& obj);
+ AliMUONAlignmentTask& operator=(const AliMUONAlignmentTask& other);
+ virtual ~AliMUONAlignmentTask();
+
+ virtual void LocalInit();
+ virtual void ConnectInputData(Option_t *);
+ virtual void CreateOutputObjects();
+ virtual void Exec(Option_t *option);
+ virtual void Terminate(const Option_t*);
+
+ private:
+ AliESDEvent *fESD; //!< ESD object
+
+ AliMUONAlignment *fAlign; ///< The MUON alignment object
+ TString fGeoFilename; ///< Geometry file name
+ AliMUONGeometryTransformer *fTransform; ///< MUON geometry transformer
+
+ Int_t fTrackTot; ///< Number of track read
+ Int_t fTrackOk; ///< Number of track read
+
+ Double_t fParameters[4*156]; ///< Array of alignment parameters
+ Double_t fErrors[4*156]; ///< Array of alignment parameters errors
+ Double_t fPulls[4*156]; ///< Array of alignment parameters pulls
+
+ TGraphErrors *fMSDEx ; ///< Graph of translations along x
+ TGraphErrors *fMSDEy ; ///< Graph of translations along y
+ TGraphErrors *fMSDEz ; ///< Graph of translations along z
+ TGraphErrors *fMSDEp; ///< Graph of rotation about z
+
+ TList *fList; ///< list of graphs
+
+ ClassDef(AliMUONAlignmentTask, 1); // example of analysis
+};
+
+#endif
+
--- /dev/null
+//-----------------------------------------------------------------------------
+/// \class AliMUONReAlignTask
+/// AliAnalysisTask to realign the MUON spectrometer.
+/// The Task reads as input ESDs moves the clusters of a MUONTrack acoording
+/// to the re aligned geometry taken from a misalignment file in the OCDB
+/// and refit the track. Then it produces a AliMUONClusterInfo object for each
+/// cluster. The output is a TTree of AliMUONClusterInfo
+///
+/// \author Javier Castillo, CEA/Saclay - Irfu/SPhN
+//-----------------------------------------------------------------------------
+
+#include <fstream>
+
+#include <TString.h>
+#include <TError.h>
+#include <TTree.h>
+#include <TChain.h>
+#include <TClonesArray.h>
+#include <TRandom.h>
+#include <TGeoGlobalMagField.h>
+#include <TGeoManager.h>
+#include <Riostream.h>
+
+#include "AliAnalysisTask.h"
+#include "AliAnalysisManager.h"
+#include "AliESDInputHandler.h"
+#include "AliESDEvent.h"
+#include "AliESDMuonTrack.h"
+#include "AliMagF.h"
+#include "AliCDBManager.h"
+#include "AliGeomManager.h"
+
+#include "AliMpConstants.h"
+#include "AliMpCDB.h"
+#include "AliMpSegmentation.h"
+#include "AliMpVSegmentation.h"
+#include "AliMpPad.h"
+#include "AliMUONCalibrationData.h"
+#include "AliMUONVCalibParam.h"
+#include "AliMUONPadInfo.h"
+#include "AliMUONClusterInfo.h"
+#include "AliMUONRecoParam.h"
+#include "AliMUONESDInterface.h"
+#include "AliMUONRefitter.h"
+#include "AliMUONRecoParam.h"
+#include "AliMUONVDigit.h"
+#include "AliMUONVCluster.h"
+#include "AliMUONTrack.h"
+#include "AliMUONVTrackStore.h"
+#include "AliMUONVDigitStore.h"
+#include "AliMUONTrackParam.h"
+#include "AliMUONTrackExtrap.h"
+#include "AliMUONGeometryTransformer.h"
+
+#include "AliMUONReAlignTask.h"
+
+///\cond CLASSIMP
+ClassImp(AliMUONReAlignTask)
+///\endcond
+
+//________________________________________________________________________
+AliMUONReAlignTask::AliMUONReAlignTask(const char *name, const char *geofilename, const char *defaultocdb, const char *misalignocdb)
+ : AliAnalysisTask(name, ""),
+ fESD(0x0),
+ fClusterInfoTree(0x0),
+ fClusterInfo(0x0),
+ fESDInterface(0x0),
+ fRefitter(0x0),
+ fRecoParam(0x0),
+ fGeoFilename(geofilename),
+ fMisAlignOCDB(misalignocdb),
+ fDefaultOCDB(defaultocdb),
+ fGeoTransformer(0x0),
+ fNewGeoTransformer(0x0),
+ fGainStore(0x0),
+ fPedStore(0x0),
+ fPrintLevel(0),
+ fLastRun(-1)
+{
+ /// Default Constructor
+ // Define input and output slots here
+ // Input slot #0 works with a TChain
+ DefineInput(0, TChain::Class());
+ // Output slot #0 writes a TTree
+ DefineOutput(0, TTree::Class());
+
+ fClusterInfo = new AliMUONClusterInfo();
+ fESDInterface = new AliMUONESDInterface();
+ fGeoTransformer = new AliMUONGeometryTransformer();
+ fNewGeoTransformer = new AliMUONGeometryTransformer();
+}
+
+//________________________________________________________________________
+AliMUONReAlignTask::AliMUONReAlignTask(const AliMUONReAlignTask& obj)
+ : AliAnalysisTask(obj),
+ fESD(0x0),
+ fClusterInfoTree(0x0),
+ fClusterInfo(0x0),
+ fESDInterface(0x0),
+ fRefitter(0x0),
+ fRecoParam(0x0),
+ fGeoFilename(""),
+ fMisAlignOCDB(""),
+ fDefaultOCDB(""),
+ fGeoTransformer(0x0),
+ fNewGeoTransformer(0x0),
+ fGainStore(0x0),
+ fPedStore(0x0),
+ fPrintLevel(0),
+ fLastRun(-1)
+{
+ /// Copy constructor
+ fESD = obj.fESD;
+ fClusterInfoTree = obj.fClusterInfoTree;
+ fClusterInfo = obj.fClusterInfo;
+ fESDInterface = obj.fESDInterface;
+ fRefitter = obj.fRefitter;
+ fRecoParam = obj.fRecoParam;
+ fGeoFilename = obj.fGeoFilename;
+ fMisAlignOCDB = obj.fMisAlignOCDB;
+ fDefaultOCDB = obj.fDefaultOCDB;
+ fGeoTransformer = obj.fGeoTransformer;
+ fNewGeoTransformer = obj.fNewGeoTransformer;
+ fGainStore = obj.fGainStore;
+ fPedStore = obj.fPedStore;
+ fPrintLevel = obj.fPrintLevel;
+ fLastRun = obj.fLastRun;
+}
+
+//________________________________________________________________________________
+AliMUONReAlignTask& AliMUONReAlignTask::operator=(const AliMUONReAlignTask& other)
+{
+ /// Assignment
+ AliAnalysisTask::operator=(other);
+ fESD = other.fESD;
+ fClusterInfoTree = other.fClusterInfoTree;
+ fClusterInfo = other.fClusterInfo;
+ fESDInterface = other.fESDInterface;
+ fRefitter = other.fRefitter;
+ fRecoParam = other.fRecoParam;
+ fGeoFilename = other.fGeoFilename;
+ fMisAlignOCDB = other.fMisAlignOCDB;
+ fDefaultOCDB = other.fDefaultOCDB;
+ fGeoTransformer = other.fGeoTransformer;
+ fNewGeoTransformer = other.fNewGeoTransformer;
+ fGainStore = other.fGainStore;
+ fPedStore = other.fPedStore;
+ fPrintLevel = other.fPrintLevel;
+ fLastRun = other.fLastRun;
+
+ return *this;
+}
+
+
+//________________________________________________________________________
+AliMUONReAlignTask::~AliMUONReAlignTask()
+{
+ /// Destructor
+ if (fESDInterface) delete fESDInterface;
+ if (fGeoTransformer) delete fGeoTransformer;
+ if (fNewGeoTransformer) delete fNewGeoTransformer;
+}
+
+//________________________________________________________________________
+void AliMUONReAlignTask::LocalInit()
+{
+ /// Local initialization, called once per task on the client machine
+ /// where the analysis train is assembled
+ AliMpCDB::LoadMpSegmentation();
+
+ // prepare the refitting
+ gRandom->SetSeed(0);
+ Prepare(fGeoFilename.Data(),fDefaultOCDB.Data(),fMisAlignOCDB.Data());
+
+ fRefitter = new AliMUONRefitter(fRecoParam);
+ fRefitter->Connect(fESDInterface);
+
+ // Original geotransformer
+ fGeoTransformer->LoadGeometryData();
+ // Apply mis alignments
+ AliGeomManager::ApplyAlignObjsFromCDB("MUON");
+ // New geotransformer
+ fNewGeoTransformer->LoadGeometryData();
+
+}
+
+//________________________________________________________________________
+void AliMUONReAlignTask::ConnectInputData(Option_t *)
+{
+ /// Connect ESD here. Called on each input data change.
+ // Connect ESD here
+ TTree* esdTree = dynamic_cast<TTree*> (GetInputData(0));
+ if (!esdTree) {
+ Printf("ERROR: Could not read chain from input slot 0");
+ }
+ else {
+ AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+ if (!esdH) {
+ Printf("ERROR: Could not get ESDInputHandler");
+ }
+ else {
+ fESD = esdH->GetEvent();
+ }
+ }
+}
+
+//________________________________________________________________________
+void AliMUONReAlignTask::CreateOutputObjects()
+{
+ /// Executed once on each worker (machine actually running the analysis code)
+ //
+ // This method has to be called INSIDE the user redefined CreateOutputObjects
+ // method, before creating each object corresponding to the output containers
+ // that are to be written to a file. This need to be done in general for the big output
+ // objects that may not fit memory during processing.
+ OpenFile(0);
+
+ fClusterInfoTree = new TTree("clusterInfoTree","clusterInfoTree");
+ fClusterInfoTree->Branch("clusterInfo", &fClusterInfo, 32000, 99);
+
+}
+
+//________________________________________________________________________
+void AliMUONReAlignTask::Exec(Option_t *)
+{
+ /// Main loop, called for each event
+ if (!fESD) {
+ Printf("ERROR: fESD not available");
+ return;
+ }
+
+ // Prepare Gain and Pedestal store
+ if (!fGainStore || fLastRun!=fESD->GetRunNumber()){
+ fGainStore = AliMUONCalibrationData::CreateGains(fESD->GetRunNumber());
+ fLastRun = fESD->GetRunNumber();
+ }
+ if (!fPedStore || fLastRun!=fESD->GetRunNumber()){
+ fPedStore = AliMUONCalibrationData::CreatePedestals(fESD->GetRunNumber());
+ fLastRun = fESD->GetRunNumber();
+ }
+
+ AliMUONPadInfo padInfo;
+
+ Int_t nTracks = (Int_t)fESD->GetNumberOfMuonTracks();
+ if (nTracks < 1) return;
+
+ // load the current event
+ fESDInterface->LoadEvent(*fESD);
+ AliMUONVDigitStore* digitStore = fESDInterface->GetDigits();
+
+ Double_t lX = 0.;
+ Double_t lY = 0.;
+ Double_t lZ = 0.;
+ Double_t gX = 0.;
+ Double_t gY = 0.;
+ Double_t gZ = 0.;
+ // loop over cluster to modify their position
+ AliMUONVCluster *cluster;
+ TIter next(fESDInterface->CreateClusterIterator());
+ while ((cluster = static_cast<AliMUONVCluster*>(next()))) {
+ // cout << "Original cluster" << endl;
+ // cluster->Print();
+ gX = cluster->GetX();
+ gY = cluster->GetY();
+ gZ = cluster->GetZ();
+ fGeoTransformer->Global2Local(cluster->GetDetElemId(),gX,gY,gZ,lX,lY,lZ);
+ fNewGeoTransformer->Local2Global(cluster->GetDetElemId(),lX,lY,lZ,gX,gY,gZ);
+ cluster->SetXYZ(gX,gY,gZ);
+ // cout << "Aligned cluster" << endl;
+ // cluster->Print();
+ }
+
+ // refit the tracks from digits
+ AliMUONVTrackStore* newTrackStore = fRefitter->ReconstructFromClusters();
+
+ //----------------------------------------------//
+ // ------ fill new ESD and print results ------ //
+ //----------------------------------------------//
+ // loop over the list of ESD tracks
+ TClonesArray *esdTracks = (TClonesArray*) fESD->FindListObject("MuonTracks");
+ for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
+ // get the ESD track
+ AliESDMuonTrack* esdTrack = (AliESDMuonTrack*) esdTracks->UncheckedAt(iTrack);
+
+ // skip ghost tracks (leave them unchanged in the new ESD file)
+ if (!esdTrack->ContainTrackerData()) continue;
+
+ // get the corresponding MUON track
+ AliMUONTrack* track = fESDInterface->FindTrack(esdTrack->GetUniqueID());
+
+ // Find the corresponding re-fitted MUON track
+ AliMUONTrack* newTrack = (AliMUONTrack*) newTrackStore->FindObject(esdTrack->GetUniqueID());
+
+// // replace the content of the current ESD track or remove it if the refitting has failed
+// if (newTrack) {
+// Double_t vertex[3] = {esdTrack->GetNonBendingCoor(), esdTrack->GetBendingCoor(), esdTrack->GetZ()};
+// AliMUONESDInterface::MUONToESD(*newTrack, *esdTrack, vertex, esdInterface.GetDigits());
+// } else {
+// esdTracks->Remove(esdTrack);
+// }
+
+ // print initial and re-fitted track parameters at first cluster if any
+ if (fPrintLevel>0) {
+ cout<<" ----------------track #"<<iTrack+1<<"----------------"<<endl;
+ cout<<"before refit:"<<endl;
+ AliMUONTrackParam *param = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First();
+ param->Print("FULL");
+ if (fPrintLevel>1) param->GetCovariances().Print();
+ if (!newTrack) continue;
+ cout<<"after refit:"<<endl;
+ param = (AliMUONTrackParam*) newTrack->GetTrackParamAtCluster()->First();
+ param->Print("FULL");
+ if (fPrintLevel>1) param->GetCovariances().Print();
+ cout<<" ----------------------------------------"<<endl;
+ }
+
+ // Cluster Info part
+ UInt_t muonClusterMap = BuildClusterMap(*newTrack);
+
+ // loop over clusters
+ AliMUONTrackParam* trackParam = static_cast<AliMUONTrackParam*>(newTrack->GetTrackParamAtCluster()->First());
+ while (trackParam) {
+ fClusterInfo->Clear("C");
+
+ // fill cluster info
+ cluster = trackParam->GetClusterPtr();
+ fClusterInfo->SetRunId(fESD->GetRunNumber());
+ fClusterInfo->SetEventId(fESD->GetEventNumberInFile());
+ fClusterInfo->SetZ(cluster->GetZ());
+ fClusterInfo->SetClusterId(cluster->GetUniqueID());
+ fClusterInfo->SetClusterXY(cluster->GetX(), cluster->GetY());
+ fClusterInfo->SetClusterXYErr(cluster->GetErrX(), cluster->GetErrY());
+ fClusterInfo->SetClusterChi2(cluster->GetChi2());
+ fClusterInfo->SetClusterCharge(cluster->GetCharge());
+
+ // fill track info
+ fClusterInfo->SetTrackId(newTrack->GetUniqueID());
+ fClusterInfo->SetTrackXY(trackParam->GetNonBendingCoor(), trackParam->GetBendingCoor());
+ fClusterInfo->SetTrackThetaXY(TMath::ATan(trackParam->GetNonBendingSlope()), TMath::ATan(trackParam->GetBendingSlope()));
+ fClusterInfo->SetTrackP(trackParam->P());
+ const TMatrixD paramCov = trackParam->GetCovariances();
+ fClusterInfo->SetTrackXYErr(TMath::Sqrt(paramCov(0,0)), TMath::Sqrt(paramCov(2,2)));
+ fClusterInfo->SetTrackChi2(newTrack->GetNormalizedChi2());
+ fClusterInfo->SetTrackCharge((Short_t)trackParam->GetCharge());
+ fClusterInfo->SetTrackNHits(newTrack->GetNClusters());
+ fClusterInfo->SetTrackChamberHitMap(muonClusterMap);
+
+ // fill pad info if available
+ for (Int_t i=0; i<cluster->GetNDigits(); i++) {
+ AliMUONVDigit* digit = digitStore->FindObject(cluster->GetDigitId(i));
+ if (!digit) continue;
+
+ // pad location
+ const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->
+ GetMpSegmentation(digit->DetElemId(),AliMp::GetCathodType(digit->Cathode()));
+ AliMpPad pad = seg->PadByIndices(digit->PadX(), digit->PadY());
+
+ // calibration parameters
+ AliMUONVCalibParam* ped = fPedStore ? static_cast<AliMUONVCalibParam*>(fPedStore->FindObject(digit->DetElemId(), digit->ManuId())) : 0x0;
+ AliMUONVCalibParam* gain = fGainStore ? static_cast<AliMUONVCalibParam*>(fGainStore->FindObject(digit->DetElemId(), digit->ManuId())) : 0x0;
+ Int_t manuChannel = digit->ManuChannel();
+ Int_t planeType = 0;
+ if ( digit->ManuId() & AliMpConstants::ManuMask(AliMp::kNonBendingPlane)) {
+ planeType = 1;
+ }
+
+ // fill pad info
+ padInfo.SetPadId(digit->GetUniqueID());
+ padInfo.SetPadPlaneType(planeType);
+ padInfo.SetPadXY(pad.GetPositionX(), pad.GetPositionY());
+ padInfo.SetPadDimXY(pad.GetDimensionX(), pad.GetDimensionY());
+ padInfo.SetPadCharge((Double_t)digit->Charge());
+ padInfo.SetPadADC(digit->ADC());
+ padInfo.SetSaturated(digit->IsSaturated());
+ padInfo.SetCalibrated(digit->IsCalibrated());
+ padInfo.SetPedestal(ped->ValueAsFloatFast(manuChannel,0), ped->ValueAsFloatFast(manuChannel,1));
+ padInfo.SetGain(gain->ValueAsFloatFast(manuChannel,0), gain->ValueAsFloatFast(manuChannel,1),
+ gain->ValueAsFloatFast(manuChannel,2), gain->ValueAsFloatFast(manuChannel,3));
+
+ fClusterInfo->AddPad(padInfo);
+ }
+
+ // fill cluster info tree
+ fClusterInfoTree->Fill();
+ trackParam = static_cast<AliMUONTrackParam*>(track->GetTrackParamAtCluster()->After(trackParam));
+ }
+ }
+ // free memory
+ delete newTrackStore;
+
+
+ // Post final data. Write histo list to a file with option "RECREATE"
+ PostData(0,fClusterInfoTree);
+}
+
+//________________________________________________________________________
+void AliMUONReAlignTask::Terminate(const Option_t*)
+{
+ /// Called once per task on the client machine at the end of the analysis.
+
+}
+
+//-----------------------------------------------------------------------
+void AliMUONReAlignTask::Prepare(const char* geoFilename, const char* defaultOCDB, const char* misAlignOCDB)
+{
+ /// Set the geometry, the magnetic field, the mapping and the reconstruction parameters
+
+ // Import TGeo geometry (needed by AliMUONTrackExtrap::ExtrapToVertex)
+ if (!gGeoManager) {
+ AliGeomManager::LoadGeometry(geoFilename);
+ if (!gGeoManager) {
+ Error("AliMUONReAlignTask", "getting geometry from file %s failed", "generated/galice.root");
+ return;
+ }
+ }
+
+ // set mag field
+ printf("Loading field map...\n");
+ AliMagF* field = new AliMagF("Maps","Maps",2,0.,0., 10.,AliMagF::k5kG);
+ TGeoGlobalMagField::Instance()->SetField(field);
+ TGeoGlobalMagField::Instance()->Lock();
+
+ // Load mapping
+ AliCDBManager* man = AliCDBManager::Instance();
+ man->SetDefaultStorage(defaultOCDB);
+ man->SetSpecificStorage("MUON/Align/Data",misAlignOCDB);
+ man->Print();
+ man->SetRun(0);
+ if ( ! AliMpCDB::LoadDDLStore() ) {
+ Error("MUONRefit","Could not access mapping from OCDB !");
+ exit(-1);
+ }
+
+ // Load initial reconstruction parameters from OCDB
+ // reconstruction parameters
+ fRecoParam = AliMUONRecoParam::GetCosmicParam();
+
+ // digit selection
+ fRecoParam->SetPadGoodnessMask(0x400BE80);
+// TString caliboption = caliboption1;
+// if ( calib == 2 ) caliboption = caliboption2;
+// fRecoParam->SetCalibrationMode("NOGAIN"caliboption.Data());
+ fRecoParam->SetCalibrationMode("NOGAIN");
+
+ // chamber resolution (incuding misalignment)
+ for (Int_t iCh=0; iCh<10; iCh++) {
+ fRecoParam->SetDefaultNonBendingReso(iCh,0.4);
+ fRecoParam->SetDefaultBendingReso(iCh,0.4);
+ }
+ fRecoParam->SetMaxNonBendingDistanceToTrack(10.);
+ fRecoParam->SetMaxBendingDistanceToTrack(10.);
+
+ // cut on (non)bending slopes
+ //fRecoParam->SetMaxNonBendingSlope(0.6);
+ //fRecoParam->SetMaxBendingSlope(0.6);
+
+ // tracking algorithm
+ // fRecoParam->MakeMoreTrackCandidates(kTRUE);
+ fRecoParam->RequestStation(0, kFALSE);
+ fRecoParam->RequestStation(2, kFALSE);
+// fRecoParam->RequestStation(3, kFALSE);
+// fRecoParam->RequestStation(4, kFALSE);
+ fRecoParam->SetSigmaCutForTracking(7.);
+ fRecoParam->ImproveTracks(kTRUE, 7.);
+ Info("MUONRefit", "\n initial recontruction parameters:");
+ fRecoParam->Print("FULL");
+
+ AliMUONESDInterface::ResetTracker(fRecoParam);
+}
+
+//-----------------------------------------------------------------------
+UInt_t AliMUONReAlignTask::BuildClusterMap(AliMUONTrack &track)
+{
+ /// Build the map of clusters in tracking chambers
+
+ UInt_t muonClusterMap = 0;
+
+ AliMUONTrackParam* trackParam = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->First());
+ while (trackParam) {
+
+ muonClusterMap |= BIT(trackParam->GetClusterPtr()->GetChamberId());
+
+ trackParam = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->After(trackParam));
+ }
+
+ return muonClusterMap;
+
+}
--- /dev/null
+#ifndef ALIMUONREALIGNTASK_H
+#define ALIMUONREALIGNTASK_H
+
+/// \ingroup ""
+/// \class AliMUONReAlignTask
+/// \brief Task to refit ESD tracks with relaigned geometry
+///
+// Author Javier Castillo, CEA/Saclay - Irfu/SPhN
+
+class TTree;
+class TString;
+class AliESDEvent;
+class AliMUONClusterInfo;
+class AliMUONESDInterface;
+class AliMUONRefitter;
+class AliMUONRecoParam;
+class AliMUONGeoemetryTransformer;
+class AliMUONVStore;
+
+#include "AliAnalysisTask.h"
+
+class AliMUONReAlignTask : public AliAnalysisTask {
+ public:
+ AliMUONReAlignTask(const char *name = "AliMUONReAlignTask", const char *geofilename = "geometry.root", const char *defaultocdb = "local://$ALICE_ROOT/OCDB", const char *misalignocdb = "local://ReAlignOCDB");
+ AliMUONReAlignTask(const AliMUONReAlignTask& obj);
+ AliMUONReAlignTask& operator=(const AliMUONReAlignTask& other);
+ virtual ~AliMUONReAlignTask();
+
+ virtual void LocalInit();
+ virtual void ConnectInputData(Option_t *);
+ virtual void CreateOutputObjects();
+ virtual void Exec(Option_t *option);
+ virtual void Terminate(const Option_t*);
+
+ /// Set geoemetry file name
+ void SetGeoFilename(const char* geoFilename) {fGeoFilename = geoFilename;}
+ /// Set mis align ocdb
+ void SetMisAlignOCDB(const char* misalignOCDB) {fMisAlignOCDB = misalignOCDB;}
+ /// Set default ocdb
+ void SetDefaultOCDB(const char* defaultOCDB) {fDefaultOCDB = defaultOCDB;}
+ void Prepare(const char* geoFilename, const char* defaultOCDB, const char* misalignOCDB);
+ UInt_t BuildClusterMap(AliMUONTrack &track);
+
+ private:
+ AliESDEvent *fESD; ///< ESD object
+ TTree *fClusterInfoTree; ///< ClusterInfo tree
+ AliMUONClusterInfo *fClusterInfo; ///< ClusterInfo object
+ AliMUONESDInterface *fESDInterface; //!< MUONESDInterface
+ AliMUONRefitter *fRefitter; //!< The refitter class
+ AliMUONRecoParam *fRecoParam; //!< Parameters for reconstruction
+ TString fGeoFilename; ///< Geometry file name
+ TString fMisAlignOCDB; ///< OCDB with misalignment file
+ TString fDefaultOCDB; ///< Default OCDB
+ AliMUONGeometryTransformer *fGeoTransformer; //!< Original geometry
+ AliMUONGeometryTransformer *fNewGeoTransformer; //!< Aligned geometry
+ AliMUONVStore *fGainStore; ///< Store for gains
+ AliMUONVStore *fPedStore; ///< Store for pedestals
+ Int_t fPrintLevel; //!< Print information
+ Int_t fLastRun; //!< Last run number
+
+ ClassDef(AliMUONReAlignTask, 1); // example of analysis
+};
+
+#endif
+
#pragma link C++ class AliMUONTriggerTrack+;
#pragma link C++ class AliMUONRecoTrack+;
#pragma link C++ class AliMUONAlignment+;
+#pragma link C++ class AliMUONAlignmentTask+;
+#pragma link C++ class AliMUONReAlignTask+;
#pragma link C++ class AliMUONVClusterFinder+;
#pragma link C++ class AliMUONPad+;
#pragma link C++ class AliMUONCluster+;
AliMUONRecoTrack.cxx \
AliMUONDigitCalibrator.cxx \
AliMUONAlignment.cxx \
+ AliMUONAlignmentTask.cxx \
+ AliMUONReAlignTask.cxx \
AliMUONVClusterFinder.cxx \
AliMUONPreClusterFinder.cxx \
AliMUONPreClusterFinderV2.cxx \