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 **************************************************************************/
16 /* $Id: AliTRDgtuTMU.cxx 28397 2008-09-02 09:33:00Z cblume $ */
18 ////////////////////////////////////////////////////////////////////////////
20 // Track Matching Unit (TMU) simulation //
22 // Author: J. Klein (Jochen.Klein@cern.ch) //
24 ////////////////////////////////////////////////////////////////////////////
31 #include "AliESDEvent.h"
32 #include "AliESDTrdTrack.h"
35 #include "AliTRDgeometry.h"
36 #include "AliTRDpadPlane.h"
38 #include "AliTRDgtuParam.h"
39 #include "AliTRDgtuTMU.h"
40 #include "AliTRDtrackGTU.h"
42 ClassImp(AliTRDgtuTMU)
44 AliTRDgtuTMU::AliTRDgtuTMU(Int_t stack, Int_t sector) :
47 fTrackletsPostInput(0x0),
48 fZChannelTracklets(0x0),
54 // constructor which initializes the position information of the TMU
56 fGtuParam = AliTRDgtuParam::Instance();
58 // store tracklets per link
59 fTracklets = new TObjArray*[fGtuParam->GetNLinks()];
60 for (Int_t iLink = 0; iLink < fGtuParam->GetNLinks(); iLink++) {
61 fTracklets[iLink] = new TObjArray();
64 // tracklets after input units per layer
65 fTrackletsPostInput = new TObjArray*[fGtuParam->GetNLayers()];
66 fZChannelTracklets = new TList*[fGtuParam->GetNLayers()];
67 for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
68 fZChannelTracklets[layer] = new TList[fGtuParam->GetNZChannels()];
69 fTrackletsPostInput[layer] = new TObjArray();
72 fTracks = new TList*[fGtuParam->GetNZChannels()];
73 for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
74 fTracks[zch] = new TList[fGtuParam->GetNRefLayers()];
83 AliTRDgtuTMU::~AliTRDgtuTMU()
87 for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
88 delete [] fTracks[zch];
91 for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
92 delete [] fZChannelTracklets[layer];
93 delete fTrackletsPostInput[layer];
95 delete [] fZChannelTracklets;
96 delete [] fTrackletsPostInput;
98 for (Int_t iLink = 0; iLink < fGtuParam->GetNLinks(); iLink++) {
99 delete fTracklets[iLink];
101 delete [] fTracklets;
104 Bool_t AliTRDgtuTMU::SetSector(Int_t sector)
108 if (sector > -1 && sector < fGtuParam->GetGeo()->Nsector() ) {
113 AliError(Form("Invalid sector given: %i", sector));
117 Bool_t AliTRDgtuTMU::SetStack(Int_t stack)
119 // Set the stack (necessary for tracking)
121 if (stack > -1 && stack < fGtuParam->GetGeo()->Nstack() ) {
126 AliError(Form("Invalid stack given: %i", stack));
130 Bool_t AliTRDgtuTMU::Reset()
134 for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
135 for (Int_t reflayeridx = 0; reflayeridx < fGtuParam->GetNRefLayers(); reflayeridx++) {
136 fTracks[zch][reflayeridx].Clear();
140 // delete all added tracklets
141 for (Int_t iLink = 0; iLink < fGtuParam->GetNLinks(); iLink++) {
142 fTracklets[iLink]->Clear();
144 for (Int_t layer = 0; layer < fGtuParam->GetNLinks()/2; layer++) {
145 fTrackletsPostInput[layer]->Clear();
146 for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++)
147 fZChannelTracklets[layer][zch].Clear();
156 Bool_t AliTRDgtuTMU::AddTracklet(AliTRDtrackletGTU *tracklet, Int_t link)
158 // add a tracklet on the given link
160 fTracklets[link]->Add(tracklet);
165 Bool_t AliTRDgtuTMU::RunTMU(TList *ListOfTracks, AliESDEvent *esd, Int_t outLabel)
167 // performs the analysis as in a TMU module of the GTU, i. e.
169 // calculation of track parameteres (pt, deflection, ???)
171 if (fStack < 0 || fSector < 0) {
172 AliError("No valid stack/sector set for this TMU! No tracking!");
176 // ----- Input units -----
177 AliDebug(1,"--------- Running Input units ----------");
178 for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
179 if (!RunInputUnit(layer)) {
180 AliError(Form("Input unit in layer %i failed", layer));
185 // ----- Z-channel units -----
186 AliDebug(1,"--------- Running Z-channel units ----------");
187 for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
188 if (!RunZChannelUnit(layer)) {
189 AliError(Form("Z-Channel unit in layer %i failed", layer));
194 // ----- track finding -----
195 AliDebug(1,"--------- Running tracking units ----------");
196 for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
197 if (!RunTrackFinder(zch, ListOfTracks)) {
198 AliError(Form("Track Finder in z-channel %i failed", zch));
203 // ----- Track Merging -----
204 if (!RunTrackMerging(ListOfTracks)) {
205 AliError("Track merging failed");
209 // ----- track reconstruction -----
210 if (!RunTrackReconstruction(ListOfTracks)) {
211 AliError("Track reconstruction failed");
215 // ----- label calculation and ESD storage -----
216 TIter next(ListOfTracks);
217 while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) next()) {
221 trk->SetLabel(outLabel);
223 AliESDTrdTrack *trdtrack = trk->CreateTrdTrack();
224 esd->AddTrdTrack(trdtrack);
232 Bool_t AliTRDgtuTMU::RunInputUnit(Int_t layer)
234 // precalculations for the tracking and reconstruction
236 Int_t iTrkl0 = 0; // A-side tracklet
237 Int_t iTrkl1 = 0; // B-side tracklet
239 Int_t nTracklets = 0;
240 while ((!fGtuParam->GetLimitNoTracklets() ||
241 (nTracklets < fGtuParam->GetMaxNoTracklets())) &&
242 ((iTrkl0 < fTracklets[2*layer + 0]->GetEntriesFast()) ||
243 (iTrkl1 < fTracklets[2*layer + 1]->GetEntriesFast()))) {
244 if (iTrkl1 >= fTracklets[2*layer + 1]->GetEntriesFast()) {
245 fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 0]->At(iTrkl0));
249 if (iTrkl0 >= fTracklets[2*layer + 0]->GetEntriesFast()) {
250 fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 1]->At(iTrkl1));
254 if (((AliTRDtrackletGTU*) fTracklets[2*layer + 1]->At(iTrkl1))->GetZbin() <
255 ((AliTRDtrackletGTU*) fTracklets[2*layer + 0]->At(iTrkl0))->GetZbin()) {
256 fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 1]->At(iTrkl1));
261 fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 0]->At(iTrkl0));
269 TIter next(fTrackletsPostInput[layer]);
271 while ( AliTRDtrackletGTU *trk = (AliTRDtrackletGTU*) next() ) {
272 trk->SetIndex(fTrackletsPostInput[layer]->IndexOf(trk));
274 Int_t alpha = (trk->GetYbin() >> fGtuParam->GetBitExcessY()) * fGtuParam->GetCiAlpha(layer);
275 alpha = ( 2 * trk->GetdY() - (alpha >> fGtuParam->GetBitExcessAlpha()) + 1 ) >> 1;
276 // wrapping projected alpha as in hardware
277 if ((alpha < -64) || (alpha > 63))
278 AliDebug(1, Form("alpha out of range: %i", alpha));
279 alpha = alpha & 0x7f;
281 trk->SetAlpha(0xffffffc0 | alpha);
283 trk->SetAlpha(alpha);
285 Int_t yproj = trk->GetdY() * (fGtuParam->GetCiYProj(layer));
286 yproj = ( ( ( (yproj >> fGtuParam->GetBitExcessYProj()) + trk->GetYbin() ) >> 2) + 1) >> 1;
287 trk->SetYProj(yproj);
289 trk->SetYPrime(trk->GetYbin() + fGtuParam->GetYt(fStack, layer, trk->GetZbin()));
291 AliDebug(10, Form("0x%08x: idx: %3i, z: %2i, y: %5i, dy: %3i, y': %5i, y_proj: %5i, alpha: %3i, pid: %3i, c: %5i, yt: %5i",
292 trk->GetTrackletWord(), trk->GetIndex(), trk->GetZbin(), trk->GetYbin(), trk->GetdY(), trk->GetYPrime(),
293 trk->GetYProj(), trk->GetAlpha(), trk->GetPID(),
294 fGtuParam->GetCiYProj(layer), fGtuParam->GetYt(fStack, layer, trk->GetZbin()) ));
299 Bool_t AliTRDgtuTMU::RunZChannelUnit(Int_t layer)
301 // run the z-channel unit
303 TIter next(fTrackletsPostInput[layer]);
305 while (AliTRDtrackletGTU *trk = (AliTRDtrackletGTU*) next()) {
306 for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
307 if (fGtuParam->IsInZChannel(fStack, layer, zch, trk->GetZbin()) ) {
308 trk->SetSubChannel(zch, fGtuParam->GetZSubchannel(fStack, layer, zch, trk->GetZbin()) );
310 TIter nexttrkl(&fZChannelTracklets[layer][zch], kIterBackward);
311 AliTRDtrackletGTU *t = 0x0;
312 while ((t = (AliTRDtrackletGTU*) nexttrkl.Next())) {
313 if (t->GetSubChannel(zch) < trk->GetSubChannel(zch) ||
314 ((t->GetSubChannel(zch) == trk->GetSubChannel(zch)) && (t->GetYProj() < trk->GetYProj())) ) {
319 fZChannelTracklets[layer][zch].AddAfter(t, trk);
321 fZChannelTracklets[layer][zch].AddFirst(trk);
324 AliDebug(10, Form("stack %d, layer %2d: 0x%08x Z(2..0)=%i/%i/%i",
325 fStack, layer, trk->GetTrackletWord(),
326 fGtuParam->IsInZChannel(fStack, layer, 2, trk->GetZbin()) ? trk->GetSubChannel(2) : -1,
327 fGtuParam->IsInZChannel(fStack, layer, 1, trk->GetZbin()) ? trk->GetSubChannel(1) : -1,
328 fGtuParam->IsInZChannel(fStack, layer, 0, trk->GetZbin()) ? trk->GetSubChannel(0) : -1
334 Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
336 // run the track finding
338 Int_t *notr = new Int_t[fGtuParam->GetNLayers()];
339 Int_t *ptrA = new Int_t[fGtuParam->GetNLayers()];
340 Int_t *ptrB = new Int_t[fGtuParam->GetNLayers()];
342 Bool_t *bHitA = new Bool_t[fGtuParam->GetNLayers()];
343 Bool_t *bHitB = new Bool_t[fGtuParam->GetNLayers()];
344 Bool_t *bAligned = new Bool_t[fGtuParam->GetNLayers()];
345 Bool_t *bAlignedA = new Bool_t[fGtuParam->GetNLayers()];
346 Bool_t *bAlignedB = new Bool_t[fGtuParam->GetNLayers()];
347 Bool_t *bDone = new Bool_t[fGtuParam->GetNLayers()];
350 Int_t *inc = new Int_t[fGtuParam->GetNLayers()];
351 Int_t *incprime = new Int_t[fGtuParam->GetNLayers()];
353 // ----- signals within current layer -----
364 AliTRDtrackletGTU *trkRA = 0x0; // reference tracklet A
365 AliTRDtrackletGTU *trkRB = 0x0; // reference tracklet B
366 AliTRDtrackletGTU *trkA = 0x0; // tracklet A in current layer
367 AliTRDtrackletGTU *trkB = 0x0; // tracklet B in current layer
369 AliTRDtrackletGTU *trkEnd = new AliTRDtrackletGTU();
370 for (Int_t i = 0; i < fGtuParam->GetNZChannels(); i++)
371 trkEnd->SetSubChannel(i, 7);
376 for (Int_t refLayerIdx = 0; refLayerIdx < fGtuParam->GetNRefLayers(); refLayerIdx++) {
377 Int_t reflayer = fGtuParam->GetRefLayer(refLayerIdx);
378 AliDebug(5,Form("Tracking for z-channel: %i, reflayer: %i", zch, reflayer));
380 ready = kFALSE; // ready if all channels done
382 // for (Int_t iLayer = 0; iLayer < fGtuParam->GetNLayers(); iLayer++) {
383 // for (Int_t iTrkl = 0; iTrkl < fZChannelTracklets[iLayer][zch].GetEntries(); iTrkl++) {
384 // printf("%4i/%4i(%i,%i) ",
385 // ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetYProj(),
386 // ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetAlpha(),
387 // ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetIndex(),
388 // ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetSubChannel(zch)
394 for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
395 notr[layer] = fZChannelTracklets[layer][zch].GetEntries();
396 ptrA[layer] = 0; // notr[layer] > 0 ? 0 : -1;
397 ptrB[layer] = 1; // notr[layer] > 1 ? 1 : -1;
399 // not necessary here
400 // bDone[layer] = (ptrB[layer] >= notr[layer] - 1); // trkB is last one
401 // bDone[layer] = (notr[layer] <= 0);
402 // ready = ready && bDone[layer];
405 AliDebug(5,Form("in layer: %i (zchannel = %i) there are: %i tracklets", layer, zch, notr[layer]));
408 if (ptrA[reflayer] < 0 && ptrB[reflayer] < 0)
412 // ----- reference tracklets -----
415 if (0 <= ptrA[reflayer] && ptrA[reflayer] < notr[reflayer])
416 trkRA = (AliTRDtrackletGTU*) fZChannelTracklets[reflayer][zch].At(ptrA[reflayer]);
418 AliDebug(10,Form("No valid tracklet in the reference at ptr: %i! Nothing done!", ptrA[reflayer]));
422 if (0 <= ptrB[reflayer] && ptrB[reflayer] < notr[reflayer])
423 trkRB = (AliTRDtrackletGTU*) fZChannelTracklets[reflayer][zch].At(ptrB[reflayer]);
425 yPlus = trkRA->GetYProj() + fGtuParam->GetDeltaY();
426 yMinus = trkRA->GetYProj() - fGtuParam->GetDeltaY();
427 alphaPlus = trkRA->GetAlpha() + fGtuParam->GetDeltaAlpha();
428 alphaMinus = trkRA->GetAlpha() - fGtuParam->GetDeltaAlpha();
430 ybPlus = trkRB->GetYProj() + fGtuParam->GetDeltaY();
431 ybMinus = trkRB->GetYProj() - fGtuParam->GetDeltaY();
433 else { // irrelevant (should be, is it?)
434 ybPlus = trkRA->GetYProj() + fGtuParam->GetDeltaY();
435 ybMinus = trkRA->GetYProj() - fGtuParam->GetDeltaY();
442 for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
443 bHitA[layer] = bHitB[layer] = bAligned[layer] = kFALSE;
444 inc[layer] = incprime[layer] = 0;
446 if (layer == reflayer) {
447 bHitA[layer] = kTRUE;
448 bAligned[layer] = kTRUE;
455 if (0 <= ptrA[layer] && ptrA[layer] < notr[layer])
456 trkA = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]);
457 if (0 <= ptrB[layer] && ptrB[layer] < notr[layer])
458 trkB = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]);
460 bAlignedA[layer] = kFALSE;
461 bAlignedB[layer] = kFALSE;
464 bHitA[layer] = ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) ) &&
465 !(trkA->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() > yPlus) ) &&
466 !(trkA->GetAlpha() < alphaMinus) &&
467 !(trkA->GetAlpha() > alphaPlus) );
468 bAlignedA[layer] = !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) );
472 bAlignedA[layer] = kTRUE;
476 bHitB[layer] = ( !(trkB->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() < yMinus) ) &&
477 !(trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > yPlus) ) &&
478 !(trkB->GetAlpha() < alphaMinus) &&
479 !(trkB->GetAlpha() > alphaPlus) );
480 bAlignedB[layer] = (trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > yPlus) );
484 bAlignedB[layer] = kTRUE;
487 bAligned[layer] = bAlignedA[layer] || bAlignedB[layer]; //???
488 // bAligned[layer] = bAlignedA[layer]; //???
490 if (bAligned[layer] && (bHitA[layer] || bHitB[layer]) )
492 else if (!bAligned[layer] )
496 if ((trkA->GetSubChannel(zch) > trkRB->GetSubChannel(zch)) || (trkA->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkA->GetYProj() > ybPlus) )
503 // pre-calculation for the layer shifting (alignment w. r. t. trkRB)
506 if ((trkA->GetSubChannel(zch) < trkRB->GetSubChannel(zch)) || (trkA->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkA->GetYProj() < ybMinus )) // could trkA be aligned for trkRB
516 if ((trkB->GetSubChannel(zch) < trkRB->GetSubChannel(zch)) || (trkB->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkB->GetYProj() < ybMinus )) // could trkB be aligned for trkRB
523 } // end of loop over layers
525 AliDebug(5,Form("logic calculation finished, Nhits: %i %s",
526 nHits, (nHits >= 4) ? "-> track found" : ""));
529 // ----- track registration -----
530 AliTRDtrackGTU *track = new AliTRDtrackGTU();
531 track->SetSector(fSector);
532 track->SetStack(fStack);
533 for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++ ) {
534 if (bHitA[layer] || layer == reflayer)
535 track->AddTracklet((AliTRDtrackletGTU* ) fZChannelTracklets[layer][zch].At(ptrA[layer]), layer );
536 else if (bHitB[layer])
537 track->AddTracklet((AliTRDtrackletGTU* ) fZChannelTracklets[layer][zch].At(ptrB[layer]), layer );
540 Bool_t registerTrack = kTRUE;
541 for (Int_t layerIdx = refLayerIdx-1; layerIdx >= 0; layerIdx--) {
542 if (track->IsTrackletInLayer(fGtuParam->GetRefLayer(layerIdx))) {
543 if ((track->GetTracklet(fGtuParam->GetRefLayer(layerIdx)))->GetSubChannel(zch) > 0) {
544 AliDebug(1,"Not registered");
545 registerTrack = kFALSE;
550 track->SetZChannel(zch);
551 track->SetRefLayerIdx(refLayerIdx);
552 fTracks[zch][refLayerIdx].Add(track);
558 if ( (nUnc != 0) && (nUnc + nHits >= 4) ) // could this position of the reference layer give some track //??? special check in case of hit?
560 else if (nWayBeyond > 2) // no track possible for both reference tracklets
565 if (inc[reflayer] != 0) // reflayer is shifted
566 for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
567 if (layer == reflayer)
569 inc[layer] = incprime[layer];
571 else { // reflayer is not shifted
572 for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
573 if (layer == reflayer || notr[layer] == 0)
578 if (0 <= ptrA[layer] && ptrA[layer] < notr[layer])
579 trkA = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]);
581 if (0 <= ptrB[layer] && ptrB[layer] < notr[layer])
582 trkB = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]);
585 if ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) ) &&
586 !(trkA->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() > yPlus ) ) ) // trkA could hit trkRA
587 // if ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) ) )
590 if ( trkB->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() < yMinus) )
592 else if ( !(trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > yPlus) ) )
595 inc[layer] = incprime[layer];
598 inc[layer] = incprime[layer];
604 for (Int_t layer = fGtuParam->GetNLayers()-1; layer >= 0; layer--) {
606 bDone[layer] = ptrB[layer] < 0 || ptrB[layer] >= notr[layer];
607 ready = ready && bDone[layer];
609 if (inc[layer] != 0 && ptrA[layer] >= notr[layer])
610 AliError(Form("Invalid increment: %i at ptrA: %i, notr: %i", inc[layer], ptrA[layer], notr[layer]));
612 // AliInfo(Form("Shifting layer: %i, notr: %i, ptrA: %i, ptrB: %i, inc: %i", layer, notr[layer], ptrA[layer], ptrB[layer], inc[layer]));
613 AliDebug(10,Form(" Layer: %i %2i(%2i, %2i, %4i, %3i)%s%s %2i(%2i, %2i, %4i, %3i)%s%s +%i %s (no: %i)",
616 (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetIndex() : -1,
617 (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetSubChannel(zch) : -1,
618 (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetYProj() : -1,
619 (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetAlpha() : -1,
620 bHitA[layer] ? "*" : " ", bAlignedA[layer] ? "+" : " ",
622 (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetIndex() : -1,
623 (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetSubChannel(zch) : -1,
624 (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetYProj() : -1,
625 (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetAlpha() : -1,
626 bHitB[layer] ? "*" : " ", bAlignedB[layer] ? "+" : " ",
627 inc[layer], bDone[layer] ? "done" : " ", notr[layer]));
628 ptrA[layer] += inc[layer];
629 ptrB[layer] += inc[layer];
633 } // end of loop over reflayer
650 Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks)
652 TList **tracksRefMerged = new TList*[fGtuParam->GetNZChannels()];
653 TList **tracksRefUnique = new TList*[fGtuParam->GetNZChannels()];
655 for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
656 tracksRefMerged[zch] = new TList;
657 tracksRefUnique[zch] = new TList;
660 TList *tracksZMergedStage0 = new TList;
661 TList *tracksZUniqueStage0 = new TList;
663 TList **tracksZSplitted = new TList*[2];
664 for (Int_t i = 0; i < 2; i++)
665 tracksZSplitted[i] = new TList;
667 TList *tracksZMergedStage1 = new TList;
669 AliTRDtrackGTU **trkInRefLayer = new AliTRDtrackGTU*[fGtuParam->GetNRefLayers()];
671 // Bool_t done = kFALSE;
673 AliTRDtrackGTU *trkStage0 = 0x0;
675 for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
676 // ----- Merging and Unification in Reflayers (seed_merger) -----
680 for (Int_t refLayerIdx = 0; refLayerIdx < fGtuParam->GetNRefLayers(); refLayerIdx++) {
681 trkInRefLayer[refLayerIdx] = (AliTRDtrackGTU*) fTracks[zch][refLayerIdx].First();
682 if (trkInRefLayer[refLayerIdx] == 0) {
685 else if (trkStage0 == 0x0 ) {
686 trkStage0 = trkInRefLayer[refLayerIdx];
687 minIdx = refLayerIdx;
690 else if ( (trkInRefLayer[refLayerIdx]->GetZSubChannel() < trkStage0->GetZSubChannel()) ||
691 ((trkInRefLayer[refLayerIdx]->GetZSubChannel() == trkStage0->GetZSubChannel()) &&
692 ((trkInRefLayer[refLayerIdx]->GetYapprox() >> 3) < (trkStage0->GetYapprox() >> 3)) ) ) {
693 minIdx = refLayerIdx;
694 trkStage0 = trkInRefLayer[refLayerIdx];
700 tracksRefMerged[zch]->Add(trkStage0);
701 fTracks[zch][minIdx].RemoveFirst();
702 } while (trkStage0 != 0);
704 Uniquifier(tracksRefMerged[zch], tracksRefUnique[zch]);
706 AliDebug(2, Form("zchannel %i", zch));
707 TIter trackRefMerged(tracksRefMerged[zch]);
708 while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackRefMerged())
709 AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, z_idx=%i",
710 AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
711 trk->GetTrackletIndex(5),
712 trk->GetTrackletIndex(4),
713 trk->GetTrackletIndex(3),
714 trk->GetTrackletIndex(2),
715 trk->GetTrackletIndex(1),
716 trk->GetTrackletIndex(0),
717 trk->GetYapprox() >> 3,
718 trk->GetZSubChannel()));
719 AliDebug(2, "uniquified:");
720 TIter trackRefUnique(tracksRefUnique[zch]);
721 while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackRefUnique())
722 AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, z_idx=%i",
723 AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
724 trk->GetTrackletIndex(5),
725 trk->GetTrackletIndex(4),
726 trk->GetTrackletIndex(3),
727 trk->GetTrackletIndex(2),
728 trk->GetTrackletIndex(1),
729 trk->GetTrackletIndex(0),
730 trk->GetYapprox() >> 3,
731 trk->GetZSubChannel()));
734 // ----- Merging in zchannels - 1st stage -----
736 if (AliTRDgtuParam::GetUseGTUmerge()) {
739 Bool_t lowerThan[3] = { kFALSE, kFALSE, kFALSE };
740 AliTRDtrackGTU *trk[3] = { 0x0, 0x0, 0x0 };
741 for (Int_t iChannel = 0; iChannel < fGtuParam->GetNZChannels(); ++iChannel)
742 trk[iChannel] = (AliTRDtrackGTU*) tracksRefUnique[iChannel]->First();
744 for (Int_t iChannel = 0; iChannel < fGtuParam->GetNZChannels(); ++iChannel) {
745 AliTRDtrackGTU *trk1 = trk[iChannel];
746 AliTRDtrackGTU *trk2 = trk[(iChannel + 1) % 3];
748 Int_t sortnum1 = (trk1->GetZChannel() + 3 * trk1->GetZSubChannel()) / 2 - 1;
749 Int_t sortnum2 = (trk2->GetZChannel() + 3 * trk2->GetZSubChannel()) / 2 - 1;
750 AliDebug(5, Form("comparing tracks %i - %i: %i - %i",
751 trk1->GetZChannel(), trk2->GetZChannel(),
752 sortnum1, sortnum2));
753 if ( (sortnum1 < sortnum2) ||
754 ((sortnum1 == sortnum2) &&
755 ((trk1->GetYapprox() >> 3) < (trk2->GetYapprox() >> 3)) ) ) {
756 lowerThan[iChannel] = kTRUE;
761 notEmpty = (trk[2] ? (1 << 2) : 0) |
762 (trk[1] ? (1 << 1) : 0) |
763 (trk[0] ? (1 << 0) : 0);
820 tracksZMergedStage0->Add(trk[pop]);
821 tracksRefUnique[pop]->RemoveFirst();
826 // there is still a difference between this implementation and
827 // the hardware algorithm, only for expert use
832 // compare tracks from all adjacent zchannels
833 // (including comparison of channels 2 and 0)
834 for (Int_t i = fGtuParam->GetNZChannels() - 1; i > -1; i--) {
836 AliTRDtrackGTU *trk = (AliTRDtrackGTU*) tracksRefUnique[zch]->First();
840 else if (trkStage0 == 0x0 ) {
846 Int_t sortnum1 = (trk->GetZChannel() + 3 * trk->GetZSubChannel()) / 2 - 1;
847 Int_t sortnum2 = (trkStage0->GetZChannel() + 3 * trkStage0->GetZSubChannel()) / 2 - 1;
848 AliDebug(5, Form("comparing tracks %i - %i: %i - %i",
849 trk->GetZChannel(), trkStage0->GetZChannel(),
850 sortnum1, sortnum2));
851 if ( (sortnum1 < sortnum2) ||
852 ((sortnum1 == sortnum2) &&
853 ((trk->GetYapprox() >> 3) < (trkStage0->GetYapprox() >> 3)) ) ) {
863 tracksZMergedStage0->Add(trkStage0);
864 tracksRefUnique[minIdx]->RemoveFirst();
865 } while (trkStage0 != 0);
868 Uniquifier(tracksZMergedStage0, tracksZUniqueStage0);
870 AliDebug(2, "stage 0:");
871 TIter trackZMergedStage0(tracksZMergedStage0);
872 while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackZMergedStage0())
873 AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
874 AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
875 trk->GetTrackletIndex(5),
876 trk->GetTrackletIndex(4),
877 trk->GetTrackletIndex(3),
878 trk->GetTrackletIndex(2),
879 trk->GetTrackletIndex(1),
880 trk->GetTrackletIndex(0),
881 trk->GetYapprox() >> 3,
883 trk->GetZSubChannel()));
885 AliDebug(2, "uniquified:");
886 TIter trackZUniqueStage0(tracksZUniqueStage0);
887 while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackZUniqueStage0())
888 AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
889 AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
890 trk->GetTrackletIndex(5),
891 trk->GetTrackletIndex(4),
892 trk->GetTrackletIndex(3),
893 trk->GetTrackletIndex(2),
894 trk->GetTrackletIndex(1),
895 trk->GetTrackletIndex(0),
896 trk->GetYapprox() >> 3,
898 trk->GetZSubChannel()));
900 // ----- Splitting in z -----
902 TIter next(tracksZUniqueStage0);
903 while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) next()) {
904 tracksZSplitted[(trk->GetZChannel() + 3 * (trk->GetZSubChannel() - 1)) % 2]->Add(trk);
907 for (Int_t i = 0; i < 2; i++) {
908 AliDebug(2, Form("split %i:", i));
909 TIter trackZSplit(tracksZSplitted[i]);
910 while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackZSplit())
911 AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
912 AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
913 trk->GetTrackletIndex(5),
914 trk->GetTrackletIndex(4),
915 trk->GetTrackletIndex(3),
916 trk->GetTrackletIndex(2),
917 trk->GetTrackletIndex(1),
918 trk->GetTrackletIndex(0),
919 trk->GetYapprox() >> 3,
921 trk->GetZSubChannel()));
924 // ----- Merging in zchanels - 2nd stage -----
929 for (Int_t i = 1; i >= 0; i--) {
930 AliTRDtrackGTU *trk = (AliTRDtrackGTU*) tracksZSplitted[i]->First();
934 else if (trkStage0 == 0x0 ) {
939 else if ( (((trk->GetZChannel() + 3 * (trk->GetZSubChannel() - 1)) / 2) < ((trkStage0->GetZChannel() + 3 * (trkStage0->GetZSubChannel() - 1)) / 2)) ||
940 ((((trk->GetZChannel() + 3 * (trk->GetZSubChannel() - 1)) / 2) == ((trkStage0->GetZChannel() + 3 * (trkStage0->GetZSubChannel() - 1)) / 2)) &&
941 ((trk->GetYapprox() >> 3) < (trkStage0->GetYapprox() >> 3)) ) ) {
950 tracksZMergedStage1->Add(trkStage0);
951 tracksZSplitted[minIdx]->RemoveFirst();
952 } while (trkStage0 != 0);
954 Uniquifier(tracksZMergedStage1, ListOfTracks);
956 AliDebug(2, "merged:");
957 TIter trackZMergedStage1(tracksZMergedStage1);
958 while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackZMergedStage1())
959 AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
960 AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
961 trk->GetTrackletIndex(5),
962 trk->GetTrackletIndex(4),
963 trk->GetTrackletIndex(3),
964 trk->GetTrackletIndex(2),
965 trk->GetTrackletIndex(1),
966 trk->GetTrackletIndex(0),
967 trk->GetYapprox() >> 3,
969 trk->GetZSubChannel()));
971 AliDebug(2, "uniquified:");
972 TIter track(ListOfTracks);
973 while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) track())
974 AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
975 AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
976 trk->GetTrackletIndex(5),
977 trk->GetTrackletIndex(4),
978 trk->GetTrackletIndex(3),
979 trk->GetTrackletIndex(2),
980 trk->GetTrackletIndex(1),
981 trk->GetTrackletIndex(0),
982 trk->GetYapprox() >> 3,
984 trk->GetZSubChannel()));
987 for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
988 delete tracksRefMerged[zch];
989 delete tracksRefUnique[zch];
991 delete [] tracksRefMerged;
992 delete [] tracksRefUnique;
995 delete tracksZMergedStage0;
996 delete tracksZUniqueStage0;
998 for (Int_t i = 0; i < 2; i++)
999 delete tracksZSplitted[i];
1000 delete [] tracksZSplitted;
1002 delete tracksZMergedStage1;
1004 delete [] trkInRefLayer;
1009 Bool_t AliTRDgtuTMU::RunTrackReconstruction(TList* ListOfTracks)
1011 // run the track reconstruction for all tracks in the list
1013 TIter next(ListOfTracks);
1014 while (AliTRDtrackGTU *track = (AliTRDtrackGTU*) next()) {
1015 CalculateTrackParams(track);
1016 CalculatePID(track);
1017 AliDebug(1, Form("track with pid = %i", track->GetPID()));
1022 Bool_t AliTRDgtuTMU::CalculatePID(AliTRDtrackGTU *track)
1024 // calculate PID for the given track
1026 AliError("No track to calculate!");
1030 if (AliTRDgtuParam::GetUseGTUconst()) {
1031 // averaging as in GTU
1032 AliDebug(1, "using GTU constants for PID calculation");
1035 // selection of coefficient for averaging
1036 switch(track->GetTrackletMask()){
1039 coeff=0x5558; // approx. 1/6
1049 coeff=0x6666; // approx. 1/5
1054 coeff=0x8000; // = 0.25
1056 coeff &= 0x1ffff; // 17-bit constant
1060 for (Int_t iLayer = 0; iLayer < fGtuParam->GetNLayers(); iLayer++) {
1061 if ((track->GetTrackletMask() >> iLayer) & 1) {
1062 sum += track->GetTracklet(iLayer)->GetPID();
1067 Float_t av = 1./i * sum;
1069 ULong64_t prod = (sum * coeff) & 0xfffffffffull;
1070 ULong64_t prodFinal = ((prod >> 17) + ((prod >> 16) & 1)) & 0xff;
1072 if (TMath::Abs((prodFinal & 0xff) - av) > 0.5)
1073 AliError(Form("problem with PID averaging (hw <-> ar): %3lli <-> %4.1f", prodFinal & 0xff, av));
1074 track->SetPID(prodFinal & 0xff);
1081 Int_t nTracklets = 0;
1083 for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
1084 if (!track->IsTrackletInLayer(layer)) {
1087 AliTRDtrackletGTU *trk = track->GetTracklet(layer);
1088 pidSum += trk->GetPID();
1093 track->SetPID(pidSum/nTracklets);
1095 AliError("Track without contributing tracklets, no PID assigned");
1101 Bool_t AliTRDgtuTMU::CalculateTrackParams(AliTRDtrackGTU *track)
1103 // calculate the track parameters
1106 AliError("No track to calculate!");
1116 AliDebug(5,Form("There are %i tracklets in this track.", track->GetNTracklets()));
1118 for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
1119 if (!track->IsTrackletInLayer(layer)) {
1122 AliTRDtrackletGTU *trk = track->GetTracklet(layer);
1124 AliError(Form("Could not get tracklet in layer %i\n", layer));
1127 AliDebug(10,Form(" layer %i trk yprime: %6i, aki: %6i", layer, trk->GetYPrime(),
1128 fGtuParam->GetAki(track->GetTrackletMask(), layer)));
1129 a += (((fGtuParam->GetAki(track->GetTrackletMask(), layer) * trk->GetYPrime()) >> 7) + 1) >> 1;
1130 b += fGtuParam->GetBki(track->GetTrackletMask(), layer) * trk->GetYPrime() * fGtuParam->GetBinWidthY();
1131 c += fGtuParam->GetCki(track->GetTrackletMask(), layer) * trk->GetYPrime() * fGtuParam->GetBinWidthY();
1137 track->SetFitParams(a << 2, b, c);
1139 fGtuParam->GetIntersectionPoints(track->GetTrackletMask(), x1, x2);
1141 AliDebug(5,Form(" Track parameters: a16 = %i, a18 = %i, b = %f, c = %f, x1 = %f, x2 = %f, pt = %f (trkl mask: %i)",
1142 a, a << 2, b, c, x1, x2, track->GetPt(), track->GetTrackletMask()));
1148 Bool_t AliTRDgtuTMU::Uniquifier(const TList *inlist, TList *outlist)
1150 // remove multiple occurences of the same track
1153 AliTRDtrackGTU *trkStage0 = 0x0;
1154 AliTRDtrackGTU *trkStage1 = 0x0;
1157 if (trkStage0 != trkStage1)
1160 trkStage0 = (AliTRDtrackGTU*) next();
1162 Bool_t tracksEqual = kFALSE;
1163 if (trkStage0 != 0 && trkStage1 != 0) {
1164 for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
1165 if (trkStage0->GetTrackletIndex(layer) != -1 && trkStage0->GetTrackletIndex(layer) == trkStage1->GetTrackletIndex(layer)) {
1166 tracksEqual = kTRUE;
1173 if (trkStage0->GetNTracklets() >= trkStage1->GetNTracklets()) {
1175 trkStage1 = trkStage0;
1179 if (trkStage1 != 0x0)
1180 outlist->Add(trkStage1);
1181 trkStage1 = trkStage0;
1184 } while (trkStage1 != 0x0);