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 **************************************************************************/
21 #include <TGeoManager.h>
22 #include <TGeoGlobalMagField.h>
26 #include "AliESDEvent.h"
27 #include "AliESDMuonTrack.h"
28 #include "AliCDBManager.h"
29 #include "AliGRPManager.h"
30 #include "AliGRPObject.h"
31 #include "AliCDBStorage.h"
32 #include "AliGeomManager.h"
36 #include "AliAnalysisManager.h"
37 #include "AliInputEventHandler.h"
38 #include "AliAnalysisTaskMuonRefit.h"
41 #include "AliMUONCDB.h"
42 #include "AliMUONConstants.h"
43 #include "AliMUONRecoParam.h"
44 #include "AliMUONESDInterface.h"
45 #include "AliMUONRefitter.h"
46 #include "AliMUONTrack.h"
47 #include "AliMUONTrackParam.h"
48 #include "AliMUONTrackExtrap.h"
49 #include "AliMUONVCluster.h"
50 #include "AliMUONVDigit.h"
51 #include "AliMUONVDigitStore.h"
52 #include "AliMUONVTrackStore.h"
53 #include "AliMUONLocalTrigger.h"
54 #include "AliMUONTriggerTrack.h"
55 #include "AliMUONVTriggerStore.h"
56 #include "AliMUONVTriggerTrackStore.h"
57 #include "AliMUONGeometryTransformer.h"
58 #include "AliMUONTriggerCircuit.h"
59 #include "AliMUONTrackHitPattern.h"
60 #include "AliMUONVTrackReconstructor.h"
62 // MUON mapping includes
63 #include "AliMpSegmentation.h"
64 #include "AliMpVSegmentation.h"
65 #include "AliMpConstants.h"
66 #include "AliMpDDLStore.h"
67 #include "AliMpManuStore.h"
69 #include "AliMpDetElement.h"
70 #include "AliMpCathodType.h"
73 #define SafeDelete(x) if (x != NULL) { delete x; x = NULL; }
76 ClassImp(AliAnalysisTaskMuonRefit)
78 //________________________________________________________________________
79 AliAnalysisTaskMuonRefit::AliAnalysisTaskMuonRefit() :
82 fImproveTracks(kFALSE),
84 fSigmaCutForTrigger(-1.),
88 fOldGeoTransformer(NULL),
89 fNewGeoTransformer(NULL),
91 fRemoveMonoCathCl(kFALSE),
92 fCheckAllPads(kFALSE),
93 fTagBadTracks(kFALSE),
94 fKeepOldParam(kFALSE),
95 fTriggerCircuit(NULL),
98 fTrackHitPattern(NULL)
100 /// Default constructor
101 for (Int_t i = 0; i < 10; i++) ResetClusterResolution(i, -1., -1.);
104 //________________________________________________________________________
105 AliAnalysisTaskMuonRefit::AliAnalysisTaskMuonRefit(const char *name) :
106 AliAnalysisTaskSE(name),
107 fDefaultStorage("raw://"),
108 fImproveTracks(kFALSE),
110 fSigmaCutForTrigger(-1.),
112 fOldAlignStorage(""),
113 fNewAlignStorage(""),
114 fOldGeoTransformer(NULL),
115 fNewGeoTransformer(NULL),
117 fRemoveMonoCathCl(kFALSE),
118 fCheckAllPads(kFALSE),
119 fTagBadTracks(kFALSE),
120 fKeepOldParam(kFALSE),
121 fTriggerCircuit(NULL),
124 fTrackHitPattern(NULL)
127 fBranchNames = "ESD:AliESDRun.,AliESDHeader.,MuonTracks,MuonClusters,MuonPads";
128 for (Int_t i = 0; i < 10; i++) ResetClusterResolution(i, -1., -1.);
131 //________________________________________________________________________
132 AliAnalysisTaskMuonRefit::~AliAnalysisTaskMuonRefit()
135 SafeDelete(fOldGeoTransformer);
136 SafeDelete(fNewGeoTransformer);
137 SafeDelete(fTriggerCircuit);
138 SafeDelete(fESDInterface);
139 SafeDelete(fRefitter);
140 SafeDelete(fTrackHitPattern);
143 //___________________________________________________________________________
144 void AliAnalysisTaskMuonRefit::UserCreateOutputObjects()
148 //________________________________________________________________________
149 void AliAnalysisTaskMuonRefit::UserExec(Option_t *)
153 // check if refitter properly created (i.e. OCDB data properly loaded)
154 if (!fRefitter) AliFatal("Problem occur while loading OCDB objects");
156 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
161 Int_t nTracks = (Int_t)esd->GetNumberOfMuonTracks();
162 if (nTracks < 1) return;
165 oldGhosts.SetOwner(kFALSE);
166 UInt_t firstGhostId = 0xFFFFFFFF - 1;
168 TList esdTracksToRemove;
169 esdTracksToRemove.SetOwner(kFALSE);
171 // load the current event
172 fESDInterface->LoadEvent(*esd, kFALSE);
174 // remove clusters from ESD (keep digits as they will not change, just eventually not used anymore)
175 esd->FindListObject("MuonClusters")->Clear("C");
178 Int_t firstClusterIndex = 0;
179 AliMUONVCluster* cluster = 0x0;
180 TIter nextCluster(fESDInterface->CreateClusterIterator());
181 while ((cluster = static_cast<AliMUONVCluster*>(nextCluster()))) {
182 Int_t clIndex = cluster->GetClusterIndex(cluster->GetUniqueID());
183 if (clIndex >= firstClusterIndex) firstClusterIndex = clIndex+1;
184 ModifyCluster(*cluster);
187 // to do not mix with old clusters in case we re-clusterize
188 fRefitter->SetFirstClusterIndex(firstClusterIndex);
190 // refit the tracks from clusters
191 AliMUONVTrackStore* newTrackStore = fRefitter->ReconstructFromClusters();
193 // reset the trigger part
194 TIter nextNewTrack(newTrackStore->CreateIterator());
195 AliMUONTrack *newTrack = 0x0;
196 while ((newTrack = static_cast<AliMUONTrack*>(nextNewTrack()))) {
197 newTrack->SetMatchTrigger(0);
198 newTrack->SetLocalTrigger(0,0,0,0,0,0,0);
199 newTrack->SetChi2MatchTrigger(0.);
200 newTrack->SetHitsPatternInTrigCh(0);
201 newTrack->SetHitsPatternInTrigChTrk(0);
204 // reconstruct trigger tracks
205 AliMUONVTriggerStore *trigStore = fESDInterface->GetTriggers();
206 AliMUONVTriggerTrackStore *trigTrackStore = AliMUONESDInterface::NewTriggerTrackStore();
207 if (!trigTrackStore) return;
208 AliMUONVTrackReconstructor* tracker = AliMUONESDInterface::GetTracker();
209 tracker->EventReconstructTrigger(*fTriggerCircuit, *trigStore, *trigTrackStore);
211 // recover the hit pattern for all trigger tracks
212 TClonesArray *esdTracks = (TClonesArray*) esd->FindListObject("MuonTracks");
213 for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
214 AliESDMuonTrack* esdTrack = (AliESDMuonTrack*) esdTracks->UncheckedAt(iTrack);
215 if (!esdTrack->ContainTriggerData()) continue;
216 // use the UniqueID of the local trigger in case several tracks match the same trigger
217 AliMUONLocalTrigger *locTrg = fESDInterface->FindLocalTrigger(esdTrack->LoCircuit());
218 AliMUONTriggerTrack *trigTrack = (AliMUONTriggerTrack*) trigTrackStore->FindObject(locTrg->GetUniqueID());
219 trigTrack->SetHitsPatternInTrigCh(esdTrack->GetHitsPatternInTrigCh());
222 // match tracker/trigger tracks
223 const Int_t kFirstTrigCh = AliMUONConstants::NTrackingCh();
224 const Float_t kZFilterOut = AliMUONConstants::MuonFilterZEnd();
225 const Float_t kFilterThickness = kZFilterOut-AliMUONConstants::MuonFilterZBeg();
226 nextNewTrack.Reset();
227 while ((newTrack = static_cast<AliMUONTrack*>(nextNewTrack()))) {
228 AliMUONTrackParam trackParam(*((AliMUONTrackParam*) (newTrack->GetTrackParamAtCluster()->Last())));
229 AliMUONTrackExtrap::ExtrapToZCov(&trackParam, kZFilterOut);
230 AliMUONTrackExtrap::AddMCSEffect(&trackParam, kFilterThickness, AliMUONConstants::MuonFilterX0());
231 AliMUONTrackExtrap::ExtrapToZCov(&trackParam, AliMUONConstants::DefaultChamberZ(kFirstTrigCh));
232 AliMUONTriggerTrack *matchedTriggerTrack = fTrackHitPattern->MatchTriggerTrack(newTrack, trackParam, *trigTrackStore, *trigStore);
233 if ( matchedTriggerTrack ) newTrack->SetHitsPatternInTrigCh(matchedTriggerTrack->GetHitsPatternInTrigCh());
236 // loop over the list of ESD tracks
237 for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
240 AliESDMuonTrack* esdTrack = (AliESDMuonTrack*) esdTracks->UncheckedAt(iTrack);
242 // keep the memory of old ghosts to concerve their Id if their are still ghosts after refitting
243 // and remember to remove them before adding the new ghosts
244 if (!esdTrack->ContainTrackerData()) {
245 AliMUONLocalTrigger *locTrg = (esdTrack->ContainTriggerData()) ? fESDInterface->FindLocalTrigger(esdTrack->LoCircuit()) : 0x0;
246 if (locTrg && !locTrg->IsNull()) oldGhosts.AddLast(locTrg);
247 if (esdTrack->GetUniqueID() <= firstGhostId) firstGhostId = esdTrack->GetUniqueID()-1;
248 esdTracksToRemove.AddLast(esdTrack);
252 // Find the corresponding re-fitted MUON track
253 newTrack = (AliMUONTrack*) newTrackStore->FindObject(esdTrack->GetUniqueID());
255 // replace the content of the current ESD track or remove it
256 if (newTrack && (!fImproveTracks || newTrack->IsImproved())) {
258 // eventually tag the tracks which do not match the trigger while they were before
259 Bool_t noLongerMatched = (fTagBadTracks && esdTrack->ContainTriggerData() && newTrack->GetMatchTrigger() <= 0);
261 // find the corresponding trigger info and eventually restore the old one
262 AliMUONLocalTrigger *locTrg = 0x0;
263 if (newTrack->GetMatchTrigger() > 0) locTrg = fESDInterface->FindLocalTrigger(newTrack->LoCircuit());
264 else if (noLongerMatched && !fKeepOldParam) {
265 locTrg = fESDInterface->FindLocalTrigger(esdTrack->LoCircuit());
266 newTrack->SetMatchTrigger(esdTrack->GetMatchTrigger());
267 newTrack->SetChi2MatchTrigger(esdTrack->GetChi2MatchTrigger());
268 newTrack->SetHitsPatternInTrigCh(esdTrack->GetHitsPatternInTrigCh());
269 newTrack->SetHitsPatternInTrigChTrk(esdTrack->GetHitsPatternInTrigChTrk());
270 newTrack->SetLocalTrigger(esdTrack->LoCircuit(), esdTrack->LoStripX(), esdTrack->LoStripY(),
271 esdTrack->LoDev(), esdTrack->LoLpt(), esdTrack->LoHpt(),
272 esdTrack->GetTriggerWithoutChamber());
274 if (locTrg && locTrg->IsNull()) locTrg = 0x0;
276 // fill the new track/cluster info
277 if (!(noLongerMatched && fKeepOldParam)) {
279 // fill the track info
280 Double_t vertex[3] = {esdTrack->GetNonBendingCoor(), esdTrack->GetBendingCoor(), esdTrack->GetZ()};
281 AliMUONESDInterface::MUONToESD(*newTrack, *esdTrack, vertex, locTrg);
283 // add the clusters if not already there
284 for (Int_t i = 0; i < newTrack->GetNClusters(); i++) {
285 AliMUONVCluster *cl = static_cast<AliMUONTrackParam*>(newTrack->GetTrackParamAtCluster()->UncheckedAt(i))->GetClusterPtr();
286 if (esd->FindMuonCluster(cl->GetUniqueID())) continue;
287 AliESDMuonCluster *esdCl = esd->NewMuonCluster();
288 AliMUONESDInterface::MUONToESD(*cl, *esdCl, kTRUE);
293 // restore the old clusters if not already done
294 for (Int_t i = 0; i < esdTrack->GetNClusters(); i++) {
295 UInt_t clId = esdTrack->GetClusterId(i);
296 if (esd->FindMuonCluster(clId)) continue;
297 AliMUONVCluster *cl = fESDInterface->FindCluster(esdTrack->GetUniqueID(), clId);
299 AliESDMuonCluster *esdCl = esd->NewMuonCluster();
300 AliMUONESDInterface::MUONToESD(*cl, *esdCl, kTRUE);
305 // eventually tag the trigger part as bad
306 esdTrack->ResetBit(BIT(20));
307 if (noLongerMatched) esdTrack->SetBit(BIT(21));
308 else esdTrack->ResetBit(BIT(21));
312 // simply tag it or remember to remove that track (cannot remove it now as it will create a hole which
313 // will eventually produce a crash in parallel track loop (AliESDEvent::MoveMuonObjects()))
315 esdTrack->SetBit(BIT(20));
316 if (esdTrack->ContainTriggerData()) esdTrack->SetBit(BIT(21));
317 else esdTrack->ResetBit(BIT(21));
319 else esdTracksToRemove.AddLast(esdTrack);
326 delete newTrackStore;
328 // remove tracks to remove and compress the array of ESD tracks
329 TIter nextTrackToRemove(&esdTracksToRemove);
330 AliESDMuonTrack* esdTrack = 0x0;
331 while ((esdTrack = static_cast<AliESDMuonTrack*>(nextTrackToRemove()))) esdTracks->Remove(esdTrack);
332 esdTracks->Compress();
334 // add new ghosts (ignoring tracks marked as bad or no longer matched)
335 TIter nextGhost(trigStore->CreateIterator());
336 AliMUONLocalTrigger *locTrg = 0x0;
337 while ((locTrg = static_cast<AliMUONLocalTrigger*>(nextGhost()))) {
338 Bool_t alreadyThere = kFALSE;
339 for (Int_t iTrack = 0; iTrack < esdTracks->GetEntriesFast(); iTrack++) {
340 esdTrack = (AliESDMuonTrack*) esdTracks->UncheckedAt(iTrack);
341 alreadyThere = (esdTrack->LoCircuit() == locTrg->LoCircuit() && !esdTrack->TestBit(BIT(21)));
342 if (alreadyThere) break;
345 UInt_t ghostId = oldGhosts.Contains(locTrg) ? locTrg->GetUniqueID() : firstGhostId--;
346 AliMUONTriggerTrack *trigTrack = (AliMUONTriggerTrack*) trigTrackStore->FindObject(locTrg->GetUniqueID());
347 AliMUONESDInterface::MUONToESD(*locTrg, *esd, ghostId, trigTrack);
353 //________________________________________________________________________
354 void AliAnalysisTaskMuonRefit::NotifyRun()
356 /// load necessary data from OCDB and create the refitter
359 if (fRefitter) return;
362 AliCDBManager* cdbm = AliCDBManager::Instance();
363 if (cdbm->IsDefaultStorageSet()) printf("MuonRefit: CDB default storage already set!\n");
365 cdbm->SetDefaultStorage(fDefaultStorage.Data());
366 if (fOldAlignStorage != "none" && !fOldAlignStorage.IsNull())
367 cdbm->SetSpecificStorage("MUON/Align/Data",fOldAlignStorage.Data());
369 if (cdbm->GetRun() > -1) printf("MuonRefit: run number already set!\n");
370 else cdbm->SetRun(fCurrentRunNumber);
372 // load magnetic field or create it for track extrapolation
373 if (!TGeoGlobalMagField::Instance()->GetField()) {
374 if (!fField.IsNull()) {
375 if (!SetMagField()) return;
376 } else if (!AliMUONCDB::LoadField()) return;
380 if (!AliMpDDLStore::Instance(kFALSE) || !AliMpManuStore::Instance(kFALSE)) {
381 if (!AliMUONCDB::LoadMapping()) return;
384 // load recoParam for refitting
385 AliMUONRecoParam* recoParam = AliMUONCDB::LoadRecoParam();
386 if (!recoParam) return;
387 if (!AliMUONESDInterface::GetTracker()) AliMUONESDInterface::ResetTracker(recoParam);
389 if (fImproveTracks) {
390 if (fSigmaCut > 0.) recoParam->ImproveTracks(kTRUE, fSigmaCut);
391 else recoParam->ImproveTracks(kTRUE);
392 } else recoParam->ImproveTracks(kFALSE);
394 if (fSigmaCutForTrigger > 0.) recoParam->SetSigmaCutForTrigger(fSigmaCutForTrigger);
395 else fSigmaCutForTrigger = recoParam->GetSigmaCutForTrigger();
397 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) {
398 if (fClusterResNB[i] < 0.) fClusterResNB[i] = recoParam->GetDefaultNonBendingReso(i);
399 if (fClusterResB[i] < 0.) fClusterResB[i] = recoParam->GetDefaultBendingReso(i);
402 // load geometry for track extrapolation to vertex and mono-cathod cluster finding
403 if (!AliGeomManager::GetGeometry()) {
407 // get original geometry transformer
408 AliGeomManager::LoadGeometry();
409 if (!AliGeomManager::GetGeometry()) return;
410 if (fOldAlignStorage != "none" && !AliGeomManager::ApplyAlignObjsFromCDB("MUON")) return;
411 fOldGeoTransformer = new AliMUONGeometryTransformer();
412 fOldGeoTransformer->LoadGeometryData();
414 // load the new geometry
415 if (cdbm->GetEntryCache()->Contains("GRP/Geometry/Data")) cdbm->UnloadFromCache("GRP/Geometry/Data");
416 AliGeomManager::GetGeometry()->UnlockGeometry();
417 AliGeomManager::LoadGeometry();
418 if (!AliGeomManager::GetGeometry()) return;
419 if (cdbm->GetEntryCache()->Contains("MUON/Align/Data")) cdbm->UnloadFromCache("MUON/Align/Data");
420 if (!fNewAlignStorage.IsNull()) cdbm->SetSpecificStorage("MUON/Align/Data",fNewAlignStorage.Data());
422 // recover default storage full name (raw:// cannot be used to set specific storage)
423 TString defaultStorage(cdbm->GetDefaultStorage()->GetType());
424 if (defaultStorage == "alien") defaultStorage += Form("://folder=%s", cdbm->GetDefaultStorage()->GetBaseFolder().Data());
425 else defaultStorage += Form("://%s", cdbm->GetDefaultStorage()->GetBaseFolder().Data());
426 cdbm->SetSpecificStorage("MUON/Align/Data",defaultStorage.Data());
428 if (!AliGeomManager::ApplyAlignObjsFromCDB("MUON")) return;
432 AliGeomManager::LoadGeometry();
433 if (!AliGeomManager::GetGeometry()) return;
434 if (!AliGeomManager::ApplyAlignObjsFromCDB("MUON")) return;
438 } else fReAlign = kFALSE; // disable the realignment if the geometry was already loaded
440 fNewGeoTransformer = new AliMUONGeometryTransformer();
441 fNewGeoTransformer->LoadGeometryData();
443 fTriggerCircuit = new AliMUONTriggerCircuit(fNewGeoTransformer);
445 fESDInterface = new AliMUONESDInterface();
447 fRefitter = new AliMUONRefitter(recoParam);
448 fRefitter->Connect(fESDInterface);
450 AliMUONVDigitStore *digitStore = AliMUONESDInterface::NewDigitStore();
451 fTrackHitPattern = new AliMUONTrackHitPattern(recoParam, *fNewGeoTransformer, *digitStore, 0x0);
452 delete digitStore; // assume the digitStore is never used when we use AliMUONTrackHitPattern
455 //________________________________________________________________________
456 void AliAnalysisTaskMuonRefit::Terminate(Option_t *)
460 //________________________________________________________________________
461 void AliAnalysisTaskMuonRefit::ModifyCluster(AliMUONVCluster& cl)
463 /// Reset the cluster resolution to the one given to the task and change
464 /// the cluster position according to the new alignment parameters if required
466 Double_t gX,gY,gZ,lX,lY,lZ;
468 // change their resolution
469 cl.SetErrXY(fClusterResNB[cl.GetChamberId()], fClusterResB[cl.GetChamberId()]);
471 // change their position
476 fOldGeoTransformer->Global2Local(cl.GetDetElemId(),gX,gY,gZ,lX,lY,lZ);
477 fNewGeoTransformer->Local2Global(cl.GetDetElemId(),lX,lY,lZ,gX,gY,gZ);
481 // "remove" mono-cathod clusters on stations 3-4-5 if required
482 // (to be done after moving clusters to the new position)
483 if (fRemoveMonoCathCl && cl.GetChamberId() > 3) {
484 Bool_t hasBending, hasNonBending;
485 if (fCheckAllPads) CheckPads(&cl, hasBending, hasNonBending);
486 else CheckPadsBelow(&cl, hasBending, hasNonBending);
487 if (!hasNonBending) cl.SetErrXY(10., cl.GetErrY());
488 if (!hasBending) cl.SetErrXY(cl.GetErrX(), 10.);
493 //________________________________________________________________________
494 void AliAnalysisTaskMuonRefit::CheckPads(AliMUONVCluster *cl, Bool_t &hasBending, Bool_t &hasNonBending) const
496 /// Check that this cluster contains pads on both cathods
500 hasNonBending = kFALSE;
502 // loop over digits contained in the cluster
503 for (Int_t iDigit = 0; iDigit < cl->GetNDigits(); iDigit++) {
505 Int_t manuId = AliMUONVDigit::ManuId(cl->GetDigitId(iDigit));
507 // check the location of the manu the digit belongs to
509 if (manuId & AliMpConstants::ManuMask(AliMp::kNonBendingPlane)) hasNonBending = kTRUE;
510 else hasBending = kTRUE;
517 //________________________________________________________________________
518 void AliAnalysisTaskMuonRefit::CheckPadsBelow(AliMUONVCluster *cl, Bool_t &hasBending, Bool_t &hasNonBending) const
520 /// Check that this cluster contains pads on both cathods just under its position
524 hasNonBending = kFALSE;
526 // get the cathod corresponding to the bending/non-bending plane
527 Int_t deId = cl->GetDetElemId();
528 AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(deId, kFALSE);
530 AliMp::CathodType cath1 = de->GetCathodType(AliMp::kBendingPlane);
531 AliMp::CathodType cath2 = de->GetCathodType(AliMp::kNonBendingPlane);
533 // get the corresponding segmentation
534 const AliMpVSegmentation* seg1 = AliMpSegmentation::Instance()->GetMpSegmentation(deId, cath1);
535 const AliMpVSegmentation* seg2 = AliMpSegmentation::Instance()->GetMpSegmentation(deId, cath2);
536 if (!seg1 || !seg2) return;
538 // get local coordinate of the cluster
540 Double_t gX = cl->GetX();
541 Double_t gY = cl->GetY();
542 Double_t gZ = cl->GetZ();
543 fNewGeoTransformer->Global2Local(deId,gX,gY,gZ,lX,lY,lZ);
545 // find pads below the cluster
546 AliMpPad pad1 = seg1->PadByPosition(lX, lY, kFALSE);
547 AliMpPad pad2 = seg2->PadByPosition(lX, lY, kFALSE);
549 // build their ID if pads are valid
550 UInt_t padId1 = (pad1.IsValid()) ? AliMUONVDigit::BuildUniqueID(deId, pad1.GetManuId(), pad1.GetManuChannel(), cath1) : 0;
551 UInt_t padId2 = (pad2.IsValid()) ? AliMUONVDigit::BuildUniqueID(deId, pad2.GetManuId(), pad2.GetManuChannel(), cath2) : 0;
553 // check if the cluster contains these pads
554 for (Int_t iDigit = 0; iDigit < cl->GetNDigits(); iDigit++) {
556 UInt_t digitId = cl->GetDigitId(iDigit);
558 if (digitId == padId1) {
561 if (hasNonBending) break;
563 } else if (digitId == padId2) {
565 hasNonBending = kTRUE;
566 if (hasBending) break;
574 //________________________________________________________________________
575 Bool_t AliAnalysisTaskMuonRefit::SetMagField() const
577 // Dealing with the magnetic field map assuming nominal current
578 // Construct the mag field map from the data in GRP and the given field map
579 // Set the global mag field instance
581 if (TGeoGlobalMagField::Instance()->IsLocked()) delete TGeoGlobalMagField::Instance();
583 AliGRPManager grpMan;
584 if (!grpMan.ReadGRPEntry()) {
585 AliError("failed to load GRP Data from OCDB");
589 const AliGRPObject *grpData = grpMan.GetGRPData();
591 AliError("GRP Data is not loaded");
595 Char_t l3Polarity = grpData->GetL3Polarity();
596 if (l3Polarity == AliGRPObject::GetInvalidChar()) {
597 AliError("GRP/GRP/Data entry: missing value for the L3 polarity !");
601 Char_t diPolarity = grpData->GetDipolePolarity();
602 if (diPolarity == AliGRPObject::GetInvalidChar()) {
603 AliError("GRP/GRP/Data entry: missing value for the dipole polarity !");
607 TString beamType = grpData->GetBeamType();
608 if (beamType==AliGRPObject::GetInvalidString()) {
609 AliError("GRP/GRP/Data entry: missing value for the beam type !");
613 Float_t beamEnergy = grpData->GetBeamEnergy();
614 if (beamEnergy==AliGRPObject::GetInvalidFloat()) {
615 AliError("GRP/GRP/Data entry: missing value for the beam energy !");
619 AliMagF::BeamType_t btype = AliMagF::kNoBeamField;
620 TString btypestr = beamType;
622 TPRegexp protonBeam("(proton|p)\\s*-?\\s*\\1");
623 TPRegexp ionBeam("(lead|pb|ion|a|A)\\s*-?\\s*\\1");
624 TPRegexp protonionBeam("(proton|p)\\s*-?\\s*(lead|pb|ion|a|A)");
625 TPRegexp ionprotonBeam("(lead|pb|ion|a|A)\\s*-?\\s*(proton|p)");
626 if (btypestr.Contains(ionBeam)) btype = AliMagF::kBeamTypeAA;
627 else if (btypestr.Contains(protonBeam)) btype = AliMagF::kBeamTypepp;
628 else if (btypestr.Contains(protonionBeam)) btype = AliMagF::kBeamTypepA;
629 else if (btypestr.Contains(ionprotonBeam)) btype = AliMagF::kBeamTypeAp;
630 else AliInfoGeneral("AliMagF",Form("Assume no LHC magnet field for the beam type %s !",beamType.Data()));
632 TGeoGlobalMagField::Instance()->SetField(new AliMagF("fld", "fld", l3Polarity ? -1:1, diPolarity ? -1:1,
633 AliMagF::k5kG, btype, beamEnergy, 2, 15., fField.Data()));
634 TGeoGlobalMagField::Instance()->Lock();
635 AliInfo("Running with the B field constructed out of GRP and custom field map !");