1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 //-----------------------------------------------------------------------------
19 /// \class AliMUONAlignmentTask
20 /// AliAnalysisTask to align the MUON spectrometer.
21 /// The Task reads as input ESDs and feeds the MUONTracks to AliMUONAlignment.
22 /// The alignment itself is performed by AliMillepede.
23 /// A OCDB entry is written with the alignment parameters.
24 /// A list of graph are written to monitor the alignment parameters.
26 /// \author Javier Castillo, CEA/Saclay - Irfu/SPhN
27 //-----------------------------------------------------------------------------
33 #include <TGraphErrors.h>
36 #include <TClonesArray.h>
37 #include <TGeoGlobalMagField.h>
38 #include <TGeoManager.h>
39 #include <Riostream.h>
41 #include "AliAnalysisTask.h"
42 #include "AliAnalysisManager.h"
43 #include "AliESDInputHandler.h"
44 #include "AliESDEvent.h"
45 #include "AliESDMuonTrack.h"
47 #include "AliCDBManager.h"
48 #include "AliGRPManager.h"
49 #include "AliCDBMetaData.h"
51 #include "AliGeomManager.h"
54 #include "AliMUONAlignment.h"
55 #include "AliMUONTrack.h"
56 #include "AliMUONTrackExtrap.h"
57 #include "AliMUONTrackParam.h"
58 #include "AliMUONGeometryTransformer.h"
59 #include "AliMUONESDInterface.h"
61 #include "AliMUONAlignmentTask.h"
64 ClassImp(AliMUONAlignmentTask)
67 // //________________________________________________________________________
68 // AliMUONAlignmentTask::AliMUONAlignmentTask(const char *name)
69 // : AliAnalysisTask(name, ""),
82 // /// Default Constructor
83 // // Define input and output slots here
84 // // Input slot #0 works with a TChain
85 // DefineInput(0, TChain::Class());
86 // // Output slot #0 writes NTuple/histos into a TList
87 // DefineOutput(0, TList::Class());
89 // // initialize parameters ...
90 // for(Int_t k=0;k<4*156;k++) {
96 // fAlign = new AliMUONAlignment();
97 // fTransform = new AliMUONGeometryTransformer();
100 //________________________________________________________________________
101 AliMUONAlignmentTask::AliMUONAlignmentTask(const char *name, const char *geofilename, const char *defaultocdb, const char *misalignocdb)
102 : AliAnalysisTask(name, ""),
105 fGeoFilename(geofilename),
106 fMisAlignOCDB(misalignocdb),
107 fDefaultOCDB(defaultocdb),
118 /// Default Constructor
119 // Define input and output slots here
120 // Input slot #0 works with a TChain
121 DefineInput(0, TChain::Class());
122 // Output slot #0 writes NTuple/histos into a TList
123 DefineOutput(0, TList::Class());
125 // initialize parameters ...
126 for(Int_t k=0;k<4*156;k++) {
132 fAlign = new AliMUONAlignment();
133 fTransform = new AliMUONGeometryTransformer();
137 //________________________________________________________________________
138 AliMUONAlignmentTask::AliMUONAlignmentTask(const AliMUONAlignmentTask& obj)
139 : AliAnalysisTask(obj),
158 fGeoFilename = obj.fGeoFilename;
159 fTransform = obj.fTransform;
160 fTrackTot = obj.fTrackTot;
161 fTrackOk = obj.fTrackOk;
162 fLastRunNumber = obj.fLastRunNumber;
170 //________________________________________________________________________
171 AliMUONAlignmentTask& AliMUONAlignmentTask::operator=(const AliMUONAlignmentTask& other)
174 AliAnalysisTask::operator=(other);
176 fAlign = other.fAlign;
177 fGeoFilename = other.fGeoFilename;
178 fMisAlignOCDB = other.fMisAlignOCDB;
179 fDefaultOCDB = other.fDefaultOCDB;
180 fTransform = other.fTransform;
181 fTrackTot = other.fTrackTot;
182 fTrackOk = other.fTrackOk;
183 fLastRunNumber = other.fLastRunNumber;
184 fMSDEx = other.fMSDEx;
185 fMSDEy = other.fMSDEy;
186 fMSDEz = other.fMSDEz;
187 fMSDEp = other.fMSDEp;
193 //________________________________________________________________________
194 AliMUONAlignmentTask::~AliMUONAlignmentTask()
197 if (fAlign) delete fAlign;
198 if (fTransform) delete fTransform;
201 //________________________________________________________________________
202 void AliMUONAlignmentTask::LocalInit()
204 /// Local initialization, called once per task on the client machine
205 /// where the analysis train is assembled
207 // Prepare(fGeoFilename.Data(),fDefaultOCDB.Data(),fMisAlignOCDB.Data());
208 Prepare(fGeoFilename.Data(),"local://$ALICE_ROOT/OCDB",fMisAlignOCDB.Data());
211 // Set initial values here, good guess may help convergence
214 // fParameters[iPar++] = 0.010300 ; fParameters[iPar++] = 0.010600 ; fParameters[iPar++] = 0.000396 ;
217 fAlign->InitGlobalParameters(fParameters);
220 fTransform->LoadGeometryData();
221 fAlign->SetGeometryTransformer(fTransform);
223 // Do alignment with magnetic field off
224 fAlign->SetBFieldOn(kFALSE);
226 // Set tracking station to use
227 // Bool_t bStOnOff[5] = {kTRUE,kTRUE,kTRUE,kTRUE,kTRUE};
228 Bool_t bChOnOff[10] = {kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kFALSE,kTRUE,kTRUE,kTRUE,kTRUE};
230 // Set degrees of freedom to align (see AliMUONAlignment)
231 fAlign->AllowVariations(bChOnOff);
233 // Fix parameters or add constraints here
234 // for (Int_t iSt=0; iSt<5; iSt++)
235 // if (!bStOnOff[iSt]) fAlign->FixStation(iSt+1);
236 for (Int_t iCh=0; iCh<10; iCh++)
237 if (!bChOnOff[iCh]) fAlign->FixChamber(iCh+1);
239 // Left and right sides of the detector are independent, one can choose to align
241 Bool_t bSpecLROnOff[2] = {kTRUE,kTRUE};
242 fAlign->FixHalfSpectrometer(bChOnOff,bSpecLROnOff);
244 fAlign->SetChOnOff(bChOnOff);
245 fAlign->SetSpecLROnOff(bChOnOff);
247 // Here we can fix some detection elements
248 fAlign->FixDetElem(908);
249 fAlign->FixDetElem(1020);
251 // Set predifined global constrains: X, Y, P, XvsZ, YvsZ, PvsZ, XvsY, YvsY, PvsY
252 // Bool_t bVarXYT[9] = {kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE};
253 // Bool_t bDetTLBR[4] = {kFALSE,kTRUE,kFALSE,kTRUE};
254 // fAlign->AddConstraints(bChOnOff,bVarXYT,bDetTLBR,bSpecLROnOff);
258 //________________________________________________________________________
259 void AliMUONAlignmentTask::ConnectInputData(Option_t *)
261 /// Connect ESD here. Called on each input data change.
264 TTree* esdTree = dynamic_cast<TTree*> (GetInputData(0));
266 Printf("ERROR: Could not read chain from input slot 0");
269 AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
271 Printf("ERROR: Could not get ESDInputHandler");
274 fESD = esdH->GetEvent();
279 //________________________________________________________________________
280 void AliMUONAlignmentTask::CreateOutputObjects()
282 /// Executed once on each worker (machine actually running the analysis code)
284 // This method has to be called INSIDE the user redefined CreateOutputObjects
285 // method, before creating each object corresponding to the output containers
286 // that are to be written to a file. This need to be done in general for the big output
287 // objects that may not fit memory during processing.
291 fMSDEx = new TGraphErrors(156);
292 fMSDEy = new TGraphErrors(156);
293 fMSDEz = new TGraphErrors(156);
294 fMSDEp = new TGraphErrors(156);
296 // Add Ntuples to the list
304 //________________________________________________________________________
305 void AliMUONAlignmentTask::Exec(Option_t *)
307 /// Main loop, called for each event
309 Printf("ERROR: fESD not available");
313 Double_t trackParams[8] = {0.,0.,0.,0.,0.,0.,0.,0.};
314 if (fESD->GetRunNumber()!=fLastRunNumber){
315 fLastRunNumber = fESD->GetRunNumber();
316 Prepare(fGeoFilename.Data(),fDefaultOCDB.Data(),fMisAlignOCDB.Data());
319 Int_t nTracks = Int_t(fESD->GetNumberOfMuonTracks());
320 // if (!event%100) cout << " there are " << nTracks << " tracks in event " << event << endl;
321 for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
322 AliESDMuonTrack* esdTrack = fESD->GetMuonTrack(iTrack);
323 if (!esdTrack->ClustersStored()) continue;
324 Double_t invBenMom = esdTrack->GetInverseBendingMomentum();
325 // fInvBenMom->Fill(invBenMom);
326 // fBenMom->Fill(1./invBenMom);
327 if (TMath::Abs(invBenMom)<=1.04) {
329 AliMUONESDInterface::ESDToMUON(*esdTrack, track);
330 fAlign->ProcessTrack(&track);
331 fAlign->LocalFit(fTrackOk++,trackParams,0);
334 cout << "Processed " << fTrackTot << " Tracks." << endl;
337 // Post final data. Write histo list to a file with option "RECREATE"
341 //________________________________________________________________________
342 void AliMUONAlignmentTask::FinishTaskOutput()
344 /// Called once per task on the client machine at the end of the analysis.
346 cout << "Processed " << fTrackTot << " Tracks." << endl;
347 // Perform global fit
348 fAlign->GlobalFit(fParameters,fErrors,fPulls);
350 cout << "Done with GlobalFit " << endl;
352 // // Update pointers reading them from the output slot
353 // fList = (TList*)GetOutputData(0);
354 // fMSDEx = (TGraphErrors*)fList->At(0);
355 // fMSDEy = (TGraphErrors*)fList->At(1);
356 // fMSDEz = (TGraphErrors*)fList->At(2);
357 // fMSDEp = (TGraphErrors*)fList->At(3);
360 Double_t deId[156] = {0};
361 Double_t msdEx[156] = {0};
362 Double_t msdEy[156] = {0};
363 Double_t msdEz[156] = {0};
364 Double_t msdEp[156] = {0};
365 Double_t deIdErr[156] = {0};
366 Double_t msdExErr[156] = {0};
367 Double_t msdEyErr[156] = {0};
368 Double_t msdEzErr[156] = {0};
369 Double_t msdEpErr[156] = {0};
370 Int_t lNDetElem = 4*2+4*2+18*2+26*2+26*2;
371 Int_t lNDetElemCh[10] = {4,4,4,4,18,18,26,26,26,26};
372 // Int_t lSNDetElemCh[10] = {4,8,12,16,34,52,78,104,130,156};
373 Int_t idOffset = 0; // 400
374 Int_t lSDetElemCh = 0;
375 for(Int_t iDE=0; iDE<lNDetElem; iDE++){
377 deId[iDE] = idOffset+100;
380 for(Int_t iCh=0; iCh<9; iCh++){
381 lSDetElemCh += lNDetElemCh[iCh];
382 if (iDE>=lSDetElemCh) {
384 deId[iDE] -= lNDetElemCh[iCh];
387 msdEx[iDE]=fParameters[3*iDE+0];
388 msdEy[iDE]=fParameters[3*iDE+1];
389 msdEz[iDE]=fParameters[3*iDE+3];
390 msdEp[iDE]=fParameters[3*iDE+2];
391 msdExErr[iDE]=(Double_t)fAlign->GetParError(3*iDE+0);
392 msdEyErr[iDE]=(Double_t)fAlign->GetParError(3*iDE+1);
393 msdEzErr[iDE]=(Double_t)fAlign->GetParError(3*iDE+3);
394 msdEpErr[iDE]=(Double_t)fAlign->GetParError(3*iDE+2);
395 fMSDEx->SetPoint(iDE,deId[iDE],fParameters[3*iDE+0]);
396 fMSDEx->SetPoint(iDE,deIdErr[iDE],(Double_t)fAlign->GetParError(3*iDE+0));
397 fMSDEy->SetPoint(iDE,deId[iDE],fParameters[3*iDE+1]);
398 fMSDEy->SetPoint(iDE,deIdErr[iDE],(Double_t)fAlign->GetParError(3*iDE+1));
399 fMSDEp->SetPoint(iDE,deId[iDE],fParameters[3*iDE+2]);
400 fMSDEp->SetPoint(iDE,deIdErr[iDE],(Double_t)fAlign->GetParError(3*iDE+2));
401 fMSDEz->SetPoint(iDE,deId[iDE],fParameters[3*iDE+3]);
402 fMSDEz->SetPoint(iDE,deIdErr[iDE],(Double_t)fAlign->GetParError(3*iDE+3));
405 // Post final data. Write histo list to a file with option "RECREATE"
409 AliMUONGeometryTransformer *newTransform = fAlign->ReAlign(fTransform,fParameters,true);
410 newTransform->WriteTransformations("transform2ReAlign.dat");
412 // Generate realigned data in local cdb
413 const TClonesArray* array = newTransform->GetMisAlignmentData();
415 // 100 mum residual resolution for chamber misalignments?
416 fAlign->SetAlignmentResolution(array,-1,0.01,0.01,0.004,0.003);
419 AliCDBManager* cdbManager = AliCDBManager::Instance();
420 cdbManager->SetDefaultStorage(fDefaultOCDB.Data());
421 cdbManager->SetSpecificStorage("MUON/Align/Data",fMisAlignOCDB.Data());
423 AliCDBMetaData* cdbData = new AliCDBMetaData();
424 cdbData->SetResponsible("Dimuon Offline project");
425 cdbData->SetComment("MUON alignment objects with residual misalignment");
426 AliCDBId id("MUON/Align/Data", 0, AliCDBRunRange::Infinity());
427 cdbManager->Put(const_cast<TClonesArray*>(array), id, cdbData);
431 //________________________________________________________________________
432 void AliMUONAlignmentTask::Terminate(const Option_t*)
434 /// Called once per task on the client machine at the end of the analysis.
438 //-----------------------------------------------------------------------
439 void AliMUONAlignmentTask::Prepare(const char* geoFilename, const char* defaultOCDB, const char* misAlignOCDB)
441 /// Set the geometry, the magnetic field, the mapping and the reconstruction parameters
444 AliCDBManager* man = AliCDBManager::Instance();
445 man->SetDefaultStorage(defaultOCDB);
446 man->SetSpecificStorage("MUON/Align/Data",misAlignOCDB);
448 man->SetRun(fLastRunNumber);
449 if ( ! AliMpCDB::LoadDDLStore() ) {
450 Error("MUONRefit","Could not access mapping from OCDB !");
454 // Import TGeo geometry (needed by AliMUONTrackExtrap::ExtrapToVertex)
456 AliGeomManager::LoadGeometry(geoFilename);
458 Error("AliMUONReAlignTask", "getting geometry from file %s failed", "generated/galice.root");
464 if (!TGeoGlobalMagField::Instance()->GetField()) {
465 printf("Loading field map...\n");
466 AliGRPManager *grpMan = new AliGRPManager();
467 grpMan->ReadGRPEntry();
468 grpMan->SetMagField();
471 // set the magnetic field for track extrapolations
472 AliMUONTrackExtrap::SetField();