LCOV - code coverage report
Current view: top level - TRD/TRDbase - AliTRDonlineTrackMatching.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 267 336 79.5 %
Date: 2016-06-14 17:26:59 Functions: 17 20 85.0 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-2012, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       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             :  **************************************************************************/
      15             : 
      16             : ///////////////////////////////////////////////////////////////////////////////
      17             : //
      18             : // Track matching between TRD online tracks and ESD tracks.
      19             : //
      20             : // Author: Felix Rettig <rettig@compeng.uni-frankfurt.de>
      21             : //
      22             : ///////////////////////////////////////////////////////////////////////////////
      23             : 
      24             : #include <TH1.h>
      25             : #include <AliESDEvent.h>
      26             : #include <AliExternalTrackParam.h>
      27             : #include "AliESDtrack.h"
      28             : #include "AliESDTrdTrack.h"
      29             : #include <AliGeomManager.h>
      30             : #include "AliTRDgeometry.h"
      31             : #include "AliTRDpadPlane.h"
      32             : #include "AliTRDonlineTrackMatching.h"
      33             : 
      34             : const Float_t AliTRDonlineTrackMatching::fgkSaveInnerRadius = 290.5;
      35             : const Float_t AliTRDonlineTrackMatching::fgkSaveOuterRadius = 364.5;
      36             : 
      37             : Float_t AliTRDonlineTrackMatching::fEsdTrackCutMinTPCrows = 0.;
      38             : Float_t AliTRDonlineTrackMatching::fEsdTrackCutMinRatioRowsFindableClusters = 0.;
      39             : Float_t AliTRDonlineTrackMatching::fEsdTrackCutMaxChi2TPCclusters = 0.;
      40             : Float_t AliTRDonlineTrackMatching::fEsdTrackCutMaxChi2ITSclusters = 0.;
      41             : Float_t AliTRDonlineTrackMatching::fEsdTrackCutMaxDCAtoVertexXY = 0.;
      42             : Float_t AliTRDonlineTrackMatching::fEsdTrackCutMaxDCAtoVertexZ = 0.;
      43             : UShort_t AliTRDonlineTrackMatching::fEsdTrackCutsITSlayerMask = 0;  // similar to 2011 default cut: 0x3
      44             : Float_t AliTRDonlineTrackMatching::fEsdTrackVCutsChi2TPCconstrainedVsGlobal = 0.;
      45             : Float_t AliTRDonlineTrackMatching::fEsdTrackCutPtDCAOfs = 0.;
      46             : Float_t AliTRDonlineTrackMatching::fEsdTrackCutPtDCACoeff = 0.;
      47             : Bool_t AliTRDonlineTrackMatching::fEsdTrackCutMinimal = kFALSE;
      48             : Bool_t AliTRDonlineTrackMatching::fEsdTrackCutRequireTPCrefit = kTRUE;
      49             : Bool_t AliTRDonlineTrackMatching::fEsdTrackCutRequireITSrefit = kFALSE;
      50             : Bool_t AliTRDonlineTrackMatching::fEsdTrackCutPrim = kFALSE;
      51             : 
      52             : AliTRDonlineTrackMatching::AliTRDonlineTrackMatching() :
      53          24 :   TObject(),
      54          24 :   fTRDgeo(NULL),
      55          24 :   fMinMatchRating(0.25),
      56          24 :   fHistMatchRating(NULL)
      57         120 : {
      58             :   // default ctor
      59          24 :   SetEsdTrackDefaultCuts("minimal");
      60          48 : }
      61             : 
      62             : AliTRDonlineTrackMatching::AliTRDonlineTrackMatching(const AliTRDonlineTrackMatching &c) :
      63           0 :   TObject(c),
      64           0 :   fTRDgeo(c.fTRDgeo),
      65           0 :   fMinMatchRating(c.fMinMatchRating),
      66           0 :   fHistMatchRating(c.fHistMatchRating)
      67           0 : {
      68             :   // copy ctor
      69           0 : }
      70             : 
      71          96 : AliTRDonlineTrackMatching::~AliTRDonlineTrackMatching() {
      72             : 
      73             :   // dtor
      74             : 
      75          26 :   delete fTRDgeo;
      76          24 :   fTRDgeo = NULL;
      77          48 : }
      78             : 
      79             : Short_t AliTRDonlineTrackMatching::EstimateSector(const Double_t globalCoords[3]) {
      80             : 
      81             :   // estimates sector by phi angle in x-y plane
      82             : 
      83        7288 :   if ((TMath::Abs(globalCoords[0]) > 600) || (TMath::Abs(globalCoords[0]) > 600) || (TMath::Sqrt(globalCoords[0]*globalCoords[0] + globalCoords[1]*globalCoords[1]) < 0.01)){
      84             :     //printf("GGG %.3f/%.3f\n", globalCoords[0], globalCoords[1]);
      85           0 :     return -1;
      86             :   } else {
      87        1822 :     Double_t ang = TMath::ATan2(globalCoords[1], globalCoords[0]);
      88        1822 :     if (ang > 0){
      89             : #ifdef TRD_TM_DEBUG
      90             :       printf("       es: %.2f/%.2f  -> phi: %.2fdeg -> Sec %02d  (A)\n",
      91             :              globalCoords[0], globalCoords[1], TMath::ATan2(globalCoords[1], globalCoords[0])*180./TMath::Pi(),
      92             :              TMath::FloorNint(ang/(20./180.*TMath::Pi())));
      93             : #endif
      94        1426 :       return TMath::FloorNint(ang/(20./180.*TMath::Pi()));
      95             :     } else {
      96             : #ifdef TRD_TM_DEBUG
      97             :       printf("       es: %.2f/%.2f  -> phi: %.2fdeg -> Sec %02d  (B)\n",
      98             :              globalCoords[0], globalCoords[1], TMath::ATan2(globalCoords[1], globalCoords[0])*180./TMath::Pi(),
      99             :              17 - TMath::FloorNint(TMath::Abs(ang)/(20./180.*TMath::Pi())));
     100             : #endif
     101         396 :       return 17 - TMath::FloorNint(TMath::Abs(ang)/(20./180.*TMath::Pi()));
     102             :     }
     103             : 
     104             :   }
     105        1822 : }
     106             : 
     107             : Short_t AliTRDonlineTrackMatching::EstimateLayer(Double_t radius) {
     108             : 
     109             :   // estimates layer by radial distance (for virtual stack at phi = 0)
     110             : 
     111             :   const Float_t rBoundaries[7] = {290.80, 302.20, 315.06, 327.55, 340.3, 352.80, 364.15}; // radial border lines centered between anode plane and successing radiator
     112             :   const Short_t rLayers[7] = {-1, 0, 1, 2, 3, 4, 5};
     113       10422 :   for (UShort_t i = 0; i < 7; ++i){
     114        4300 :     if (radius < rBoundaries[i])
     115        1822 :       return rLayers[i];
     116             :   }
     117           0 :   return -2; // radius larger than outmost layer
     118        1822 : }
     119             : 
     120             : Short_t AliTRDonlineTrackMatching::EstimateLocalStack(const Double_t globalCoords[3]) {
     121             : 
     122             :   // determines stack within sector by z position
     123             : 
     124        3644 :   Double_t absZ = TMath::Abs(globalCoords[2]);
     125        1822 :   Short_t signZ = (globalCoords[2] > 0.) ? 1 : -1;
     126        1822 :   Double_t r = TMath::Sqrt(globalCoords[0]*globalCoords[0] + globalCoords[1]*globalCoords[1]);
     127        1822 :   Short_t layer = EstimateLayer(r);
     128             : 
     129             : #ifdef TRD_TM_DEBUG
     130             :   printf("EstimateLocalStack A     r: %.2f   x: %.2f/%.2f/%.2f  -> layer: %i    absZ = %.2f\n",
     131             :          r, globalCoords[0], globalCoords[1], globalCoords[2], layer, absZ);
     132             : #endif
     133             : 
     134        1822 :   if (layer < 0)
     135          34 :     return -1;
     136             : 
     137        1788 :   Double_t innerStackHalfLength = AliTRDgeometry::GetChamberLength(0, 2) / 2.;  // same for all layers
     138        1788 :   if (absZ < innerStackHalfLength)
     139        1142 :     return 2;
     140             : 
     141         646 :   Double_t outerStackLength = AliTRDgeometry::GetChamberLength(layer, 1);
     142             : 
     143         646 :   absZ -= innerStackHalfLength;
     144             : 
     145             : #ifdef TRD_TM_DEBUG
     146             :   printf("EstimateLocalStack B     r: %.2f   x: %.2f/%.2f/%.2f  -> layer: %i    absZ = %.2f    il: %.2f   ol: %.2f\n",
     147             :          r, globalCoords[0], globalCoords[1], globalCoords[2], layer, absZ, 2.*innerStackHalfLength, outerStackLength);
     148             : #endif
     149             : 
     150         646 :   if (absZ > 2.05*outerStackLength)
     151           0 :     return (signZ > 0) ? -2 : -1; // outside supermodule in z direction
     152             : 
     153        1292 :   if (absZ < outerStackLength)
     154        1190 :     return (signZ > 0) ? 1 : 3;
     155             :   else
     156         102 :     return (signZ > 0) ? 0 : 4;
     157             : 
     158        1822 : }
     159             : 
     160             : Short_t AliTRDonlineTrackMatching::EstimateStack(const Double_t globalCoords[3]) {
     161             : 
     162             :   // returns the closest TRD stack to a 3D position in global coordinates
     163             : 
     164        3644 :   Short_t sec = EstimateSector(globalCoords);
     165        1822 :   Short_t st = EstimateLocalStack(globalCoords);
     166             : #ifdef TRD_TM_DEBUG
     167             :   printf("EstimateStack sec %d  st %d\n", sec, st);
     168             : #endif
     169        3644 :   if ((sec < 0) || (st < 0))
     170          34 :     return -1;
     171             :   else
     172        1788 :     return 5*sec + st;
     173        1822 : }
     174             : 
     175             : Bool_t AliTRDonlineTrackMatching::StackToTrack(const AliExternalTrackParam *track, Short_t &stack, UShort_t &layersWithTracklet, Double_t magFieldinKiloGauss){
     176             : 
     177             :   // returns stack to track param
     178             : 
     179         260 :   stack = -1;
     180         130 :   layersWithTracklet = 0;
     181             : 
     182         130 :   UInt_t stackHits[fgkTrdStacks];
     183         130 :   Double_t x[3] = { 0. };
     184         130 :   memset(stackHits, 0, fgkTrdStacks*sizeof(UInt_t));
     185             : 
     186             : #ifdef TRD_TM_DEBUG
     187             :   printf("STACK-TO-TRACK\n");
     188             : #endif
     189             : 
     190             :   Double_t r = fgkSaveInnerRadius;
     191        7504 :   while (r < fgkSaveOuterRadius){
     192        3726 :     if (track->GetXYZAt(r, magFieldinKiloGauss, x)) {
     193        1822 :       stack = EstimateStack(x);
     194        1822 :       if (stack >= 0){
     195        1788 :         stackHits[stack]++;
     196        1788 :         if (stackHits[stack] > 16) // experimental
     197             :           break;
     198             : #ifdef TRD_TM_DEBUG
     199             :         printf(" r=%.3fcm  %.2f/%.2f  -  %d hits for stack %d  S%02d-%d   (mag=%.1f)\n",
     200             :                r, x[0], x[1], stackHits[stack], stack, stack/5, stack%5, magFieldinKiloGauss);
     201             : #endif
     202             :       }
     203             :     }
     204        3622 :     r += 1.;
     205             :   }
     206             : 
     207             :   // find stack with most hits
     208             :   UInt_t bestHits = 0;
     209       23660 :   for (UShort_t iStack = 0; iStack < fgkTrdStacks; ++iStack){
     210       11700 :     if (stackHits[iStack] == 0)
     211             :       continue;
     212             : #ifdef TRD_TM_DEBUG
     213             :     printf("  finally %d hits in stack S%02d-%d\n", stackHits[iStack], iStack/5, iStack%5);
     214             : #endif
     215         108 :     if (stackHits[iStack] > bestHits){
     216             :       bestHits = stackHits[iStack];
     217         108 :       stack = iStack;
     218         108 :     }
     219             :   }
     220             : 
     221         130 :   if (stack >= 0){
     222             : #ifdef TRD_TM_DEBUG
     223             :     printf("best stack: S%02d-%d\n", TrdLsiSec(stack), TrdLsiSi(stack));
     224             : #endif
     225         106 :     return kTRUE;
     226             :   }
     227             : 
     228          24 :   return kFALSE;
     229         130 : }
     230             : 
     231             : Bool_t AliTRDonlineTrackMatching::StackToTrack(const AliESDtrack* track, Short_t &stack, UShort_t &layersWithTracklet, Double_t magFieldinKiloGauss){
     232             : 
     233             :   // returns stack to ESD track
     234             : 
     235         390 :   if (track->GetOuterParam())
     236         260 :     return StackToTrack(track->GetOuterParam(), stack, layersWithTracklet, magFieldinKiloGauss);
     237           0 :   else if (track->GetInnerParam())
     238           0 :     return StackToTrack(track->GetInnerParam(), stack, layersWithTracklet, magFieldinKiloGauss);
     239             :   else
     240           0 :     return StackToTrack(track, stack, layersWithTracklet, magFieldinKiloGauss);
     241         130 : }
     242             : 
     243             : Bool_t AliTRDonlineTrackMatching::AcceptTrack(const AliESDtrack* esdTrack, const AliESDEvent* esdEvent){
     244             : 
     245             :   // returns result ESD track cuts
     246             : 
     247         304 :   if (!esdTrack)
     248           0 :     return kFALSE;
     249             : 
     250         152 :   UInt_t status = esdTrack->GetStatus();
     251             : 
     252         152 :   if (fEsdTrackCutMinimal){
     253           0 :     return ((status & AliESDtrack::kTPCout) > 0);
     254             :   }
     255             : 
     256             :   // require TPC fit
     257         304 :   if ((fEsdTrackCutRequireTPCrefit) && (!(status & AliESDtrack::kTPCrefit)))
     258          16 :     return kFALSE;
     259             : 
     260             :   // require ITS re-fit
     261         136 :   if ((fEsdTrackCutRequireITSrefit) && (!(status & AliESDtrack::kITSrefit)))
     262           0 :     return kFALSE;
     263             : 
     264             :   // TPC requirements
     265         136 :   Float_t nCrossedRowsTPC = esdTrack->GetTPCCrossedRows();
     266             :   Float_t ratioCrossedRowsOverFindableClustersTPC =
     267         408 :     (esdTrack->GetTPCNclsF() > 0) ? (nCrossedRowsTPC / esdTrack->GetTPCNclsF()) : 1.0;
     268             :   Float_t chi2PerClusterTPC =
     269         408 :     (esdTrack->GetTPCclusters(0) > 0) ? (esdTrack->GetTPCchi2()/Float_t(esdTrack->GetTPCclusters(0))) : 100.;
     270             : 
     271             :   if (
     272         266 :       (nCrossedRowsTPC < fEsdTrackCutMinTPCrows) ||
     273         130 :       (ratioCrossedRowsOverFindableClustersTPC < fEsdTrackCutMinRatioRowsFindableClusters) ||
     274         130 :       (chi2PerClusterTPC > fEsdTrackCutMaxChi2TPCclusters)
     275             :       )
     276           6 :     return kFALSE;
     277             : 
     278             :   // ITS requirements
     279         342 :   Float_t chi2PerClusterITS = (esdTrack->GetITSclusters(0) > 0) ? esdTrack->GetITSchi2()/Float_t(esdTrack->GetITSclusters(0)) : 1000.;
     280             :   UShort_t clustersInAnyITSlayer = kFALSE;
     281        1820 :   for (UShort_t layer = 0; layer < 6; ++layer)
     282         780 :     clustersInAnyITSlayer += (esdTrack->HasPointOnITSLayer(layer) & ((fEsdTrackCutsITSlayerMask >> layer) & 1));
     283             : 
     284         130 :   if ((fEsdTrackCutsITSlayerMask != 0) &&
     285           0 :       ((clustersInAnyITSlayer == 0) || (chi2PerClusterITS >= fEsdTrackCutMaxChi2ITSclusters))
     286             :       )
     287           0 :     return kFALSE;
     288             : 
     289             :   // geometric requirements
     290         130 :   Float_t impactPos[2], impactCov[3];
     291         130 :   esdTrack->GetImpactParameters(impactPos, impactCov);
     292             : 
     293         130 :   if (TMath::Abs(impactPos[0]) > fEsdTrackCutMaxDCAtoVertexXY)
     294           0 :     return kFALSE;
     295             : 
     296         130 :   if (TMath::Abs(impactPos[1]) > fEsdTrackCutMaxDCAtoVertexZ)
     297           0 :     return kFALSE;
     298             : 
     299         130 :   if (fEsdTrackCutPrim){
     300             :     // additional requirements for primary tracks
     301             : 
     302           0 :     const AliESDVertex* vertex = esdEvent->GetPrimaryVertexTracks();
     303           0 :     if ((!vertex) || (!vertex->GetStatus()))
     304           0 :       vertex = esdEvent->GetPrimaryVertexSPD();
     305             : 
     306             :     Float_t chi2TPCConstrainedVsGlobal =
     307           0 :       (vertex->GetStatus()) ? esdTrack->GetChi2TPCConstrainedVsGlobal(vertex) : (fEsdTrackVCutsChi2TPCconstrainedVsGlobal + 10.);
     308             : 
     309           0 :     if (chi2TPCConstrainedVsGlobal > fEsdTrackVCutsChi2TPCconstrainedVsGlobal)
     310           0 :       return kFALSE;
     311             : 
     312             :     Float_t cutDCAToVertexXYPtDep =
     313           0 :       fEsdTrackCutPtDCAOfs + fEsdTrackCutPtDCACoeff/((TMath::Abs(esdTrack->Pt()) > 0.0001) ? esdTrack->Pt() : 0.0001);
     314             : 
     315           0 :     if (TMath::Abs(impactPos[0]) >= cutDCAToVertexXYPtDep)
     316           0 :       return kFALSE;
     317             : 
     318           0 :   }
     319             : 
     320         130 :   return kTRUE;
     321         282 : }
     322             : 
     323             : Bool_t AliTRDonlineTrackMatching::ProcessEvent(AliESDEvent *esdEvent, Bool_t updateRef, Int_t label) {
     324             : 
     325             :   // performs track matching for all TRD online tracks of the ESD event
     326             : 
     327           8 :   UInt_t numTrdTracks = esdEvent->GetNumberOfTrdTracks();
     328           8 :   if (numTrdTracks <= 0)
     329           0 :     return kTRUE;
     330             : 
     331           8 :   if (!AliGeomManager::GetGeometry()){
     332           0 :     AliError("Geometry not available! Skipping TRD track matching.");
     333           0 :     return kFALSE;
     334             :   }
     335             : 
     336           8 :   if (!fTRDgeo){
     337           4 :     fTRDgeo = new AliTRDgeometry();
     338           2 :   }
     339             : 
     340             :   //
     341             :   // ESD track selection and sorting by TRD stack
     342             :   //
     343             : 
     344           8 :   UInt_t esdTracksByStack[fgkTrdStacks][fgkMaxEsdTracksPerStack];
     345           8 :   UInt_t esdTrackNumByStack[fgkTrdStacks];
     346           8 :   memset(esdTrackNumByStack, 0, fgkTrdStacks*sizeof(UInt_t));
     347             : 
     348           8 :   UInt_t numEsdTracks = esdEvent->GetNumberOfTracks();
     349             : #ifdef TRD_TM_DEBUG
     350             :   UInt_t numEsdTracksAccepted = 0;
     351             : #endif
     352           8 :   Short_t stack;
     353           8 :   UShort_t layers;
     354             :   AliESDtrack* esdTrack;
     355             : 
     356         320 :   for (UInt_t iEsdTrack = 0; iEsdTrack < numEsdTracks; ++iEsdTrack){
     357         152 :     esdTrack = esdEvent->GetTrack(iEsdTrack);
     358             : 
     359         152 :     if (!esdTrack){
     360           0 :       AliError("invalid ESD track!");
     361           0 :       continue;
     362             :     }
     363             : 
     364             :     // track filter here
     365         152 :     if (!AcceptTrack(esdTrack, esdEvent))
     366             :       continue;
     367             : #ifdef TRD_TM_DEBUG
     368             :     else
     369             :       numEsdTracksAccepted++;
     370             : #endif
     371             : 
     372             :     // assign ESD track to TRD stack
     373         130 :     if (StackToTrack(esdTrack, stack, layers, esdEvent->GetMagneticField())){
     374             : 
     375         106 :       if (stack < 0){
     376             : #ifdef TRD_TM_DEBUG
     377             :         printf("#TRACKMATCHING - invalid stack for ESD track\n");
     378             : #endif
     379             :         continue;
     380             :       }
     381             : 
     382             :       // register track in relevant stacks
     383         106 :       Int_t stacksForReg[9] = {-1, -1, -1, -1, -1, -1, -1, -1, -1};
     384         106 :       stacksForReg[0] = stack; // stack hit
     385         106 :       stacksForReg[1] = (stack + 5) % 90; // same stack in next supermodule
     386         106 :       stacksForReg[2] = (stack - 5); // same stack in previous supermodule
     387         106 :       if (stacksForReg[2] < 0)
     388          16 :         stacksForReg[2] += 90;
     389             : 
     390         212 :       switch(TrdLsiSi(stack)){
     391             :       case 0:
     392             :         // stack 0
     393           4 :         stacksForReg[3] = stack + 1; // next stack in same supermodule
     394           4 :         stacksForReg[4] =  stacksForReg[1] + 1; // next stack in next supermodule
     395           4 :         stacksForReg[5] =  stacksForReg[2] + 1; // next stack in previous supermodule
     396           4 :         break;
     397             :       case 1:
     398             :       case 2:
     399             :       case 3:
     400         100 :         stacksForReg[3] = stack + 1; // next stack in same supermodule
     401         100 :         stacksForReg[4] =  stacksForReg[1] + 1; // next stack in next supermodule
     402         100 :         stacksForReg[5] =  stacksForReg[2] + 1; // next stack in previous supermodule
     403         100 :         stacksForReg[6] = stack - 1; // previous stack in same supermodule
     404         100 :         stacksForReg[7] =  stacksForReg[1] - 1; // previous stack in next supermodule
     405         100 :         stacksForReg[8] =  stacksForReg[2] - 1; // previous stack in previous supermodule
     406         100 :         break;
     407             :       case 4:
     408           2 :         stacksForReg[3] = stack - 1; // previous stack in same supermodule
     409           2 :         stacksForReg[4] =  stacksForReg[1] - 1; // previous stack in next supermodule
     410           2 :         stacksForReg[5] =  stacksForReg[2] - 1; // previous stack in previous supermodule
     411           2 :         break;
     412             :       default:
     413             :         break;
     414             :       }
     415             : 
     416             : #ifdef TRD_TM_DEBUG
     417             :       printf("#TRACKMATCHING - assigned ESD track %d to following TRD stacks:", iEsdTrack);
     418             : #endif
     419             : 
     420             :       // register for stacks
     421        2184 :       for (UShort_t iReg = 0; iReg < 9; ++iReg){
     422         942 :         if (stacksForReg[iReg] < 0)
     423           6 :           break;
     424             : 
     425         936 :         if (stacksForReg[iReg] >= 90){
     426           0 :           AliError(Form("invalid stack for registration: %i", stacksForReg[iReg]));
     427           0 :           continue;
     428             :         }
     429             : 
     430         936 :         if (esdTrackNumByStack[stacksForReg[iReg]] < fgkMaxEsdTracksPerStack - 1)
     431         936 :           esdTracksByStack[stacksForReg[iReg]][esdTrackNumByStack[stacksForReg[iReg]]++] = iEsdTrack;
     432             : #ifdef TRD_TM_DEBUG
     433             :         else
     434             :           printf("#TRACKMATCHING - maximum number (%d) of ESD tracks per stack reached for S%02d-%d (%d tracks total). Skipping track!\n",
     435             :                  fgkMaxEsdTracksPerStack, TrdLsiSec(stacksForReg[iReg]), TrdLsiSi(stacksForReg[iReg]), numEsdTracks);
     436             :         printf(" S%02d-%d", TrdLsiSec(stacksForReg[iReg]), TrdLsiSi(stacksForReg[iReg]));
     437             : #endif
     438             :       }
     439             : #ifdef TRD_TM_DEBUG
     440             :       printf(" (ESD-ASSIGN)\n");
     441             : #endif
     442             : 
     443             : //      if (esdTrackNumByStack[stack] >= fgkMaxEsdTracksPerStack){
     444             : //#ifdef TRD_TM_DEBUG
     445             : //      printf("#TRACKMATCHING - maximum number (%d) of ESD tracks per stack reached for S%02d-%d (%d tracks total). Skipping track!\n",
     446             : //             fgkMaxEsdTracksPerStack, TrdLsiSec(stack), TrdLsiSi(stack), numEsdTracks);
     447             : //#endif
     448             : //      continue;
     449             : //      }
     450             : //
     451             : //      esdTracksByStack[stack][esdTrackNumByStack[stack]++] = iEsdTrack;
     452             : //#ifdef TRD_TM_DEBUG
     453             : //      printf("#TRACKMATCHING - assigned ESD track %d to TRD stack S%02d-%d\n",
     454             : //           iEsdTrack, TrdLsiSec(stack), TrdLsiSi(stack));
     455             : //#endif
     456         106 :     }
     457             : 
     458             :   } // loop over esd tracks
     459             : 
     460             : #ifdef TRD_TM_DEBUG
     461             :   printf("#TRACKMATCHING - %d ESD tracks accepted, %d rejected\n",
     462             :          numEsdTracksAccepted, numEsdTracks - numEsdTracksAccepted);
     463             : #endif
     464             : 
     465             :   //
     466             :   // search matching ESD track for each TRD online track
     467             :   //
     468             :   AliESDTrdTrack* trdTrack;
     469             :   Double_t trdPt;
     470             :   AliESDtrack* matchCandidate;
     471             :   AliESDtrack* matchTrack;
     472             :   Int_t matchEsdTrackIndexInStack;
     473             :   Double_t matchRating;
     474             :   Int_t matchCandidateCount;
     475           8 :   Double_t distY, distZ;
     476             : 
     477        4654 :   for (UInt_t iTrdTrack = 0; iTrdTrack < numTrdTracks; ++iTrdTrack){
     478             : 
     479        2319 :     trdTrack = esdEvent->GetTrdTrack(iTrdTrack);
     480        2319 :     if ((label != -1) &&
     481           0 :         (trdTrack->GetLabel() != label))
     482             :       continue;
     483             : 
     484        6957 :     if ((trdTrack->GetSector() < 0) || (trdTrack->GetSector() > 17) ||
     485        4638 :         (trdTrack->GetStack() < 0) || (trdTrack->GetStack() > 4))
     486             :       continue;
     487             : 
     488        2319 :     stack = TrdSecSiLsi(trdTrack->GetSector(), trdTrack->GetStack());
     489        2319 :     trdPt = (esdEvent->GetMagneticField() > 0.) ? (-1.*trdTrack->Pt()) : trdTrack->Pt();
     490             :     matchTrack = NULL;
     491             :     matchEsdTrackIndexInStack = -1;
     492             :     matchRating = 0.;
     493             :     matchCandidateCount = 0;
     494             : 
     495             : #ifdef TRD_TM_DEBUG
     496             :     printf("#TRACKMATCHING - trying to match TRD online track %d in S%02d-%d\n",
     497             :            iTrdTrack, trdTrack->GetSector(), trdTrack->GetStack());
     498             : #endif
     499             : 
     500             :     // loop over all esd tracks in the same stack and check distance
     501        6678 :     for (UInt_t iEsdTrack = 0; iEsdTrack < esdTrackNumByStack[stack]; ++iEsdTrack){
     502        1020 :       matchCandidate = esdEvent->GetTrack(esdTracksByStack[stack][iEsdTrack]);
     503             : 
     504        1020 :       if (EstimateTrackDistance(matchCandidate, trdTrack, esdEvent->GetMagneticField(), &distY, &distZ) == 0){
     505          60 :         Double_t rating = RateTrackMatch(distY, distZ, matchCandidate->GetSignedPt(), trdPt);
     506             : #ifdef TRD_TM_DEBUG
     507             :         printf("#TRACKMATCHING  S%02d-%d  trd %d - esd %d   dy: %.3f    dz: %.3f   r: %.3f    pt e: %.2f  t: %.2f   match: %d\n",
     508             :                trdTrack->GetSector(), trdTrack->GetStack(), iTrdTrack, iEsdTrack,
     509             :                distY, distZ, rating, matchCandidate->GetSignedPt(), trdPt,
     510             :                (rating >= fMinMatchRating) ? 1 : 0);
     511             : #endif
     512          60 :         if (rating > 0.){
     513             :           // possibly matching pair found
     514          14 :           matchCandidateCount++;
     515          14 :           if ((matchTrack == NULL) || (rating > matchRating)){
     516             :             // new best match
     517             :             matchTrack = matchCandidate;
     518             :             matchEsdTrackIndexInStack = iEsdTrack;
     519             :             matchRating = rating;
     520          14 :           }
     521             :         }
     522             : 
     523          60 :       } else {
     524             :         // estimation of distance failed
     525             : #ifdef TRD_TM_DEBUG
     526             :         printf("TRACKMATCHING  S%02d-%d  trd %d - esd %d   failed\n",
     527             :                trdTrack->GetSector(), trdTrack->GetStack(), iTrdTrack, iEsdTrack);
     528             : #endif
     529             :       }
     530             :     } // loop over esd tracks in same stack
     531             : 
     532        2319 :     if (fHistMatchRating){
     533           0 :       fHistMatchRating->Fill(matchRating);
     534           0 :     }
     535             : 
     536        2333 :     if ((matchTrack) && (matchRating >= fMinMatchRating)){
     537          39 :       AliDebug(1, Form("S%02d-%d  trd %d - esd %d   match!    pt:  %.2f  %.2f",
     538             :                        trdTrack->GetSector(), trdTrack->GetStack(), iTrdTrack, matchEsdTrackIndexInStack,
     539             :                        trdPt, matchTrack->GetSignedPt()));
     540             : #ifdef TRD_TM_DEBUG
     541             :       printf("#TRACKMATCHING  S%02d-%d  trd %d - esd %d   match!    pt:  %.2f  %.2f\n",
     542             :              trdTrack->GetSector(), trdTrack->GetStack(), iTrdTrack, matchEsdTrackIndexInStack,
     543             :              trdPt, matchTrack->GetSignedPt());
     544             : #endif
     545          13 :       if (updateRef)
     546          13 :         trdTrack->SetTrackMatchReference(matchTrack);
     547             :     } else {
     548        2306 :       if (updateRef)
     549        2306 :         trdTrack->SetTrackMatchReference(NULL);
     550             :     }
     551             : 
     552             :   } // loop over TRD online tracks
     553             : 
     554             :   return kTRUE;
     555          16 : }
     556             : 
     557             : Bool_t AliTRDonlineTrackMatching::TrackPlaneIntersect(AliExternalTrackParam *trk, Double_t pnt[3], Double_t norm[3], Double_t mag){
     558             : 
     559             :   // calculates the intersection point of a track param and a plane defined by point pnt and normal vector norm
     560             : 
     561             :   UInt_t its = 0;
     562             :   Double_t r = 290.;
     563             :   Double_t step = 10.;
     564             :   Int_t flag = 0;
     565             :   Double_t dist = 0, dist_prev = 0;
     566         584 :   Double_t x[3] = {0., 0., 0.};
     567             : 
     568         292 :   dist = (x[0] - pnt[0]) * norm[0] + (x[1] - pnt[1]) *norm[1] + (x[2] - pnt[2]) * norm[2];
     569             : 
     570        5544 :   while(TMath::Abs(dist) > 0.1) {
     571             : 
     572        5001 :     trk->GetXYZAt(r, mag, x);
     573             : 
     574        5001 :     if ((x[0] * x[0] + x[1] * x[1]) < 100.)  // extrapolation to radius failed
     575           0 :       return kFALSE;
     576             : 
     577             :     //distance between current track position and plane
     578        5001 :     dist_prev = TMath::Abs(dist);
     579        5001 :     dist = (x[0] - pnt[0]) * norm[0] + (x[1] - pnt[1]) * norm[1];
     580        9710 :     if ((flag) && (TMath::Abs(dist) > dist_prev)){
     581        1080 :       step /= -2.;
     582        1080 :     }
     583             :     flag=1;
     584        5001 :     r += step;
     585        5001 :     its++;
     586        9961 :     if ((r > 380.) || (r < 100.) || (its > 100) || (TMath::Abs(step) < 0.00001)){
     587             :       break;
     588             :     }
     589             :   }
     590        2336 :   for (Int_t i=0; i<3; i++)
     591         876 :     pnt[i] = x[i];
     592             : 
     593         292 :   return kTRUE;
     594         292 : }
     595             : 
     596             : Int_t AliTRDonlineTrackMatching::EstimateTrackDistance(AliESDtrack *esd_track, AliESDTrdTrack* gtu_track, Double_t mag, Double_t *ydist, Double_t *zdist){
     597             : 
     598             :   // returns an estimate for the spatial distance between TPC offline track and GTU online track
     599             : 
     600        2040 :   if ((!esd_track) || (!gtu_track))
     601           0 :     return -3;
     602             : 
     603             :   // AssertTRDGeometry();
     604        1020 :   if (!fTRDgeo)
     605           0 :     fTRDgeo = new AliTRDgeometry();
     606             : 
     607             :   Float_t diff_y = 0;
     608             :   Float_t diff_z = 0;
     609             :   Int_t nLayers = 0;
     610        1020 :   Double_t xtrkl[3];
     611        1020 :   Double_t ptrkl[3];
     612        1020 :   Double_t ptrkl2[3];
     613             :   UInt_t trklDet;
     614             :   UShort_t trklLayer;
     615             :   UInt_t stack_gtu;
     616             :   UShort_t stackInSector;
     617             : 
     618       15300 :   for (UShort_t iLayer = 0; iLayer < 6; iLayer++){
     619        6120 :     AliESDTrdTracklet* trkl = gtu_track->GetTracklet(iLayer);
     620        6120 :     if (trkl){
     621         292 :       trklDet = trkl->GetDetector();
     622         292 :       trklLayer = TrdDetLyr(trklDet);
     623         292 :       stack_gtu = TrdDetLsi(trklDet);
     624         292 :       stackInSector = TrdDetSi(trklDet);
     625             : 
     626             :       // local coordinates of the outer end point of the tracklet
     627         292 :       xtrkl[0] = AliTRDgeometry::AnodePos();
     628         292 :       xtrkl[1] = trkl->GetLocalY();
     629             : 
     630         584 :       if(stackInSector == 2){ // corrected version by Felix Muecke
     631         800 :         xtrkl[2] = fTRDgeo->GetPadPlane(trklLayer, stackInSector)->GetRowPos(trkl->GetBinZ()) -
     632         508 :           (fTRDgeo->GetPadPlane(trklLayer, stackInSector)->GetRowSize(trkl->GetBinZ()))/2. -
     633         508 :           fTRDgeo->GetPadPlane(trklLayer, stackInSector)->GetRowPos(6);
     634         216 :       } else {
     635          76 :         xtrkl[2] = fTRDgeo->GetPadPlane(trklLayer, stackInSector)->GetRowPos(trkl->GetBinZ()) -
     636          76 :           (fTRDgeo->GetPadPlane(trklLayer, stackInSector)->GetRowSize(trkl->GetBinZ()))/2. -
     637          76 :           fTRDgeo->GetPadPlane(trklLayer, stackInSector)->GetRowPos(8);
     638             :       }
     639             : 
     640             :       // old draft version
     641             :       // xtrkl[2] = fTRDgeo->GetPadPlane(trklLayer, (trklDet/6) % 5)->GetRowPos(trkl->GetBinZ()) -
     642             :       //        fTRDgeo->GetPadPlane(trklLayer, (trklDet/6) % 5)->GetRowSize(trkl->GetBinZ()) -
     643             :       //        fTRDgeo->GetPadPlane(trklLayer, (trklDet/6) % 5)->GetRowPos(8);
     644             : 
     645             :       // transform to global coordinates
     646         292 :       TGeoHMatrix *matrix = fTRDgeo->GetClusterMatrix(trklDet);
     647         292 :       if (!matrix){
     648           0 :         if ((stack_gtu != 13*5+2) && (stack_gtu != 14*5+2) && (stack_gtu != 15*5+2))
     649           0 :           AliDebug(1, Form("invalid TRD cluster matrix in EstimateTrackDistance for detector %i", trklDet));
     650           0 :         return -5;
     651             :       }
     652         292 :       matrix->LocalToMaster(xtrkl, ptrkl);
     653         292 :       fTRDgeo->RotateBack(gtu_track->GetSector() * 30, ptrkl, ptrkl2);  // ptrkl2 now contains the global position of the outer end point of the tracklet
     654             : 
     655             :       // calculate parameterization of plane representing the tracklets layer
     656         292 :       Double_t layer_zero_local[3] = {0., 0.,  0.};
     657         292 :       Double_t layer_zero_global[3], layer_zero_global2[3];
     658             : 
     659         292 :       matrix->LocalToMaster(layer_zero_local, layer_zero_global);
     660         292 :       fTRDgeo->RotateBack(trklDet, layer_zero_global, layer_zero_global2); // layer_zero_global2 points to chamber origin in global coords
     661             : 
     662         292 :       Double_t layer_ref_local[3] = {AliTRDgeometry::AnodePos(), 0.,  0.};
     663         292 :       Double_t layer_ref_global[3], layer_ref_global2[3];
     664             : 
     665         292 :       matrix->LocalToMaster(layer_ref_local, layer_ref_global);
     666         292 :       fTRDgeo->RotateBack(trklDet, layer_ref_global, layer_ref_global2); // layer_ref_global2 points to center anode pos within plane in global coords
     667             : 
     668         292 :       Double_t n0[3] = {layer_ref_global2[0]-layer_zero_global2[0],
     669         292 :                         layer_ref_global2[1]-layer_zero_global2[1],
     670         292 :                         layer_ref_global2[2]-layer_zero_global2[2]};
     671             : 
     672         292 :       Double_t n_len = TMath::Sqrt(n0[0]*n0[0] + n0[1]*n0[1] + n0[2]*n0[2]);
     673         292 :       if (n_len == 0.){ // This should never happen
     674           0 :         AliError("divison by zero in estimate_track_distance!");
     675             :         n_len = 1.;
     676           0 :       }
     677         292 :       Double_t n[3] = {n0[0]/n_len, n0[1]/n_len, n0[2]/n_len}; // normal vector of plane
     678             : 
     679         292 :       const AliExternalTrackParam *trackParam = esd_track->GetOuterParam();
     680         292 :       if (!trackParam) {
     681           0 :         trackParam = esd_track->GetInnerParam();
     682           0 :         if (!trackParam)
     683           0 :           trackParam = esd_track;
     684             :       }
     685             : 
     686         292 :       AliExternalTrackParam *outerTPC = new AliExternalTrackParam(*trackParam);
     687         292 :       Bool_t isects = TrackPlaneIntersect(outerTPC, layer_ref_global2, n, mag); // find intersection point between track and TRD layer
     688         584 :       delete outerTPC;
     689             :       outerTPC = NULL;
     690             : 
     691         292 :       if (isects == kFALSE){ // extrapolation fails, because track never reaches the TRD radius
     692           0 :         return -1;
     693             :       }
     694             : 
     695         292 :       Double_t m[2] = {ptrkl2[0] - layer_ref_global2[0], ptrkl2[1] - layer_ref_global2[1]};
     696         292 :       Double_t len_m = TMath::Sqrt(m[0]*m[0] + m[1]*m[1]);
     697         292 :       diff_y += len_m;
     698         292 :       diff_z += TMath::Abs(ptrkl2[2] - layer_ref_global2[2]);
     699         292 :       nLayers++;
     700         584 :     }
     701        6120 :   }
     702             : 
     703        1020 :   if (nLayers > 0){
     704          60 :     *ydist = diff_y / nLayers;
     705          60 :     *zdist = diff_z / nLayers;
     706          60 :     return 0;
     707             :   }
     708             :   else
     709         960 :     return -4;
     710        2040 : }
     711             : 
     712             : Double_t AliTRDonlineTrackMatching::PtDiffRel(Double_t refPt, Double_t gtuPt){
     713             : 
     714             :   // return relative pt difference
     715             : 
     716          28 :   if (TMath::Abs(refPt) > 0.000001){
     717          14 :     return (gtuPt - refPt) / refPt;
     718             :   } else
     719           0 :     return 0.;
     720          14 : }
     721             : 
     722             : 
     723             : Double_t AliTRDonlineTrackMatching::RateTrackMatch(Double_t distY, Double_t distZ, Double_t rpt, Double_t gpt){
     724             : 
     725             :   // returns a match rating derived from Y and Z distance as well as pt difference
     726             : 
     727             :   // maximum limits for spatial distance
     728         120 :   if ((distY > 5.) || (distZ > 20.))
     729          46 :     return 0.;
     730             : 
     731             :   // same pt sign required
     732          14 :   if ((rpt * gpt) < 0.)
     733           0 :     return 0.;
     734             : 
     735          14 :   Double_t rating_distY = -0.1 * distY + 1.;
     736          14 :   Double_t rating_distZ = -0.025 * distZ + 1.;
     737          14 :   Double_t rating_ptDiff = 1. - TMath::Abs(PtDiffRel(rpt, gpt));
     738             : 
     739          14 :   if (rating_ptDiff <  0.)
     740           0 :     rating_ptDiff = 0.2;
     741             : 
     742          14 :   Double_t total = rating_distY * rating_distZ * rating_ptDiff;
     743             : 
     744             : #ifdef TRD_TM_DEBUG
     745             :   if (total > 1.){
     746             :     printf("<ERROR> track match rating exceeds limit of 1.0: %.3f", total);
     747             :   }
     748             : #endif
     749             : 
     750             :   return total;
     751          60 : }
     752             : 
     753             : 
     754             : void AliTRDonlineTrackMatching::SetEsdTrackDefaultCuts(const char* cutIdent) {
     755             : 
     756          48 :   if (strcmp(cutIdent, "strict") == 0){
     757             : 
     758             : #ifdef TRD_TM_DEBUG
     759             :     printf("AliTRDonlineTrackMatching -- default track cuts selected");
     760             : #endif
     761             : 
     762           0 :     fEsdTrackCutMinimal = kFALSE;
     763           0 :     fEsdTrackCutPrim = kFALSE;
     764             : 
     765           0 :     fEsdTrackCutMinTPCrows = 70;
     766           0 :     fEsdTrackCutRequireTPCrefit = kTRUE;
     767           0 :     fEsdTrackCutMinRatioRowsFindableClusters = 0.8;
     768           0 :     fEsdTrackCutMaxChi2TPCclusters = 4.;
     769           0 :     fEsdTrackVCutsChi2TPCconstrainedVsGlobal = 36.;
     770             : 
     771           0 :     fEsdTrackCutRequireITSrefit = kFALSE;
     772           0 :     fEsdTrackCutMaxChi2ITSclusters = 36.;
     773             : 
     774           0 :     fEsdTrackCutMaxDCAtoVertexXY = 1000.;
     775           0 :     fEsdTrackCutMaxDCAtoVertexZ = 2.;
     776           0 :     fEsdTrackCutsITSlayerMask = 0x0;
     777             : 
     778           0 :     fEsdTrackCutPtDCAOfs = 0.0105;
     779           0 :     fEsdTrackCutPtDCACoeff = 0.0350;
     780          24 :   } else if (strcmp(cutIdent, "minimal") == 0){
     781             : 
     782             : #ifdef TRD_TM_DEBUG
     783             :     printf("AliTRDonlineTrackMatching -- minimal track cuts selected\n");
     784             : #endif
     785             : 
     786          24 :     fEsdTrackCutMinimal = kFALSE;
     787          24 :     fEsdTrackCutPrim = kFALSE;
     788             : 
     789          24 :     fEsdTrackCutMinTPCrows = 70;
     790          24 :     fEsdTrackCutRequireTPCrefit = kTRUE;
     791          24 :     fEsdTrackCutMinRatioRowsFindableClusters = 0.;
     792          24 :     fEsdTrackCutMaxChi2TPCclusters = 100.;
     793          24 :     fEsdTrackVCutsChi2TPCconstrainedVsGlobal = 1000.;
     794             : 
     795          24 :     fEsdTrackCutRequireITSrefit = kFALSE;
     796          24 :     fEsdTrackCutMaxChi2ITSclusters = 0.;
     797             : 
     798          24 :     fEsdTrackCutMaxDCAtoVertexXY = 1000.;
     799          24 :     fEsdTrackCutMaxDCAtoVertexZ = 1000.;
     800          24 :     fEsdTrackCutsITSlayerMask = 0x0;
     801          24 :   } else
     802           0 :     AliErrorClass("invalid cut set");
     803             : 
     804          24 : }

Generated by: LCOV version 1.11