LCOV - code coverage report
Current view: top level - AD/ADrec - AliADReconstructor.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 365 0.3 %
Date: 2016-06-14 17:26:59 Functions: 1 18 5.6 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, 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             : /* $Id: AliADReconstructor.cxx 20956 2007-09-26 14:22:18Z mrodrigu $ */
      17             : //////////////////////////////////////////////////////////////////////////////
      18             : //                                                                          //
      19             : //  Class for AD reconstruction                                         //
      20             : //////////////////////////////////////////////////////////////////////////////
      21             : #include <algorithm>
      22             : 
      23             : #include <TParameter.h>
      24             : #include <TGeoManager.h>
      25             : #include <TGeoMatrix.h>
      26             : #include <TGeoPhysicalNode.h>
      27             : 
      28             : #include <TF1.h>
      29             : 
      30             : #include <AliGeomManager.h>
      31             : 
      32             : #include "AliRawReader.h"
      33             : #include "AliGRPObject.h"
      34             : #include "AliCDBManager.h"
      35             : #include "AliCDBStorage.h"
      36             : #include "AliCDBEntry.h"
      37             : #include "AliESDEvent.h"
      38             : #include "AliRunInfo.h"
      39             : #include "AliCTPTimeParams.h"
      40             : #include "AliLHCClockPhase.h"
      41             : #include "TSpline.h"
      42             : 
      43             : #include "AliADReconstructor.h"
      44             : #include "AliADdigit.h"
      45             : #include "AliESDAD.h"
      46             : #include "AliESDADfriend.h"
      47             : #include "AliADConst.h"
      48             : #include "AliADCalibData.h"
      49             : #include "AliADRawStream.h"
      50             : #include "AliADDecision.h"
      51             : 
      52          16 : ClassImp(AliADReconstructor);
      53             : 
      54             : //_____________________________________________________________________________
      55             : AliADReconstructor::AliADReconstructor()
      56           0 :   : AliReconstructor()
      57           0 :   , fESDAD(NULL)
      58           0 :   , fESD(NULL)
      59           0 :   , fESDADfriend(NULL)
      60           0 :   , fCalibData(NULL)
      61           0 :   , fDigitsArray(NULL)
      62           0 :   , fSaturationCorrection(NULL)
      63           0 :   , fCollisionMode(0)
      64           0 :   , fBeamEnergy(0.)
      65           0 :   , fCorrectForSaturation(kTRUE)
      66           0 : {  
      67             :   // Default constructor  
      68             : 
      69             :   // Get calibration data
      70           0 :   fCalibData = GetCalibData();
      71             : 
      72             :   //Get time slewing
      73           0 :   GetTimeSlewingSplines();
      74             : 
      75           0 :   AliCDBManager *man = AliCDBManager::Instance();
      76             :   AliCDBEntry *entry = NULL;
      77             : 
      78             :   // Now get the CTP L0->L1 delay
      79           0 :   entry = man->Get("GRP/CTP/CTPtiming");
      80           0 :   if (!entry) AliFatal("CTP timing parameters are not found in OCDB !");
      81           0 :   AliCTPTimeParams *ctpParams = dynamic_cast<AliCTPTimeParams*>(entry->GetObject());
      82           0 :   Float_t l1Delay = (Float_t)ctpParams->GetDelayL1L0()*25.0;
      83             : 
      84           0 :   entry = man->Get("GRP/CTP/TimeAlign");
      85           0 :   if (!entry) AliFatal("CTP time-alignment is not found in OCDB !");
      86           0 :   AliCTPTimeParams *ctpTimeAlign = dynamic_cast<AliCTPTimeParams*>(entry->GetObject());
      87           0 :   l1Delay += ((Float_t)ctpTimeAlign->GetDelayL1L0()*25.0);
      88             : 
      89           0 :   entry = man->Get("AD/Calib/TimeDelays");
      90           0 :   if (!entry) AliFatal("AD time delays are not found in OCDB !");
      91           0 :   TH1F *TimeDelays = dynamic_cast<TH1F*>(entry->GetObject());
      92             : 
      93           0 :   entry = man->Get("GRP/Calib/LHCClockPhase");
      94           0 :   if (!entry) AliFatal("LHC clock-phase shift is not found in OCDB !");
      95           0 :   AliLHCClockPhase *phase = dynamic_cast<AliLHCClockPhase*>(entry->GetObject());
      96             : 
      97           0 :   for (Int_t i=0; i<16; ++i) {
      98           0 :     const Int_t board = AliADCalibData::GetBoardNumber(i); 
      99           0 :     fHptdcOffset[i] = (((Float_t)fCalibData->GetRollOver(board)-
     100           0 :                         (Float_t)fCalibData->GetTriggerCountOffset(board))*25.0
     101           0 :                        +fCalibData->GetTimeOffset(i)
     102           0 :                        -l1Delay
     103           0 :                        -phase->GetMeanPhase()
     104           0 :                        -TimeDelays->GetBinContent(i+1)
     105           0 :                        -kADOffset);
     106             :   }
     107             :    
     108           0 :   const Float_t zADC1 = TMath::Abs(GetZPosition("AD/ADC1"));  // outer 
     109           0 :   const Float_t zADC2 = TMath::Abs(GetZPosition("AD/ADC2"));  // inner
     110           0 :   const Float_t zADA1 = TMath::Abs(GetZPosition("AD/ADA1"));  // inner
     111           0 :   const Float_t zADA2 = TMath::Abs(GetZPosition("AD/ADA2"));  // outer
     112             : 
     113             :   // distance in time units from nominal vertex to AD
     114           0 :   fLayerDist[0] = zADC1/TMath::Ccgs()*1e9;
     115           0 :   fLayerDist[1] = zADC2/TMath::Ccgs()*1e9;
     116           0 :   fLayerDist[2] = zADA1/TMath::Ccgs()*1e9;
     117           0 :   fLayerDist[3] = zADA2/TMath::Ccgs()*1e9; 
     118           0 : }
     119             : //________________________________________________________________________________
     120             : void AliADReconstructor::SetOption(Option_t* opt)
     121             : {
     122           0 :   TObjArray *oa = TString(opt).Tokenize(" ");
     123           0 :   for (Int_t i=0, n=oa->GetEntries(); i<n; ++i) {
     124           0 :     const TString s = oa->At(i)->GetName();
     125           0 :     if (s.Contains("SaturationCorrection")) {
     126           0 :       fCorrectForSaturation = !s.Contains("-");
     127           0 :     }
     128           0 :   }
     129           0 :   delete oa;
     130           0 :   AliInfo(Form("opt='%s'  fCorrectForSaturation: %s", opt, fCorrectForSaturation ? "ON" : "OFF"));
     131           0 : }
     132             : //________________________________________________________________________________
     133             : Double_t AliADReconstructor::GetZPosition(const char* symname)
     134             : {
     135             :   // Get the global z coordinate of the given AD alignable volume
     136             :   //
     137             :   Double_t *tr;
     138           0 :   TGeoPNEntry *pne = gGeoManager->GetAlignableEntry(symname);
     139           0 :   if (!pne) {
     140           0 :     AliFatalClass(Form("TGeoPNEntry with symbolic name %s does not exist!", symname));
     141           0 :     return 0;
     142             :   }
     143             : 
     144           0 :   TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
     145           0 :   if (NULL != pnode) {
     146           0 :     TGeoHMatrix* hm = pnode->GetMatrix();
     147           0 :     tr = hm->GetTranslation();
     148           0 :   } else {
     149           0 :     const char* path = pne->GetTitle();
     150           0 :     if (!gGeoManager->cd(path)) {
     151           0 :       AliFatalClass(Form("Volume path %s not valid!", path));
     152           0 :       return 0;
     153             :     }
     154           0 :     tr = gGeoManager->GetCurrentMatrix()->GetTranslation();
     155           0 :   }
     156           0 :   return tr[2];
     157           0 : }
     158             : 
     159             : 
     160             : //_____________________________________________________________________________
     161             : AliADReconstructor& AliADReconstructor::operator = (const AliADReconstructor&)
     162             : {
     163             :   // assignment operator
     164           0 :   Fatal("operator =",  "assignment operator not implemented");
     165           0 :   return *this;
     166             : }
     167             : 
     168             : //_____________________________________________________________________________
     169             : AliADReconstructor::~AliADReconstructor()
     170           0 : {
     171             :   // destructor
     172           0 :   delete fESDAD;
     173           0 :   delete fESDADfriend;
     174           0 :   delete fDigitsArray;
     175           0 : }
     176             : 
     177             : //_____________________________________________________________________________
     178             : void AliADReconstructor::Init()
     179             : {
     180             :   // initializer
     181           0 :   SetOption(GetOption());
     182             : 
     183           0 :   fESDAD        = new AliESDAD;
     184           0 :   fESDADfriend  = new AliESDADfriend;
     185             : 
     186           0 :   if (fCorrectForSaturation) {
     187           0 :     AliCDBEntry *entry = AliCDBManager::Instance()->Get("AD/Calib/Saturation");
     188           0 :     if (!entry) AliFatal("AD/Calib/Saturation is not found in OCDB !");
     189           0 :     fSaturationCorrection = dynamic_cast<TTree*>(entry->GetObject());
     190           0 :   }
     191           0 : }
     192             : 
     193             : UShort_t MakeTriggerFlags(Bool_t UBA, Bool_t UBC,
     194             :                           Bool_t UGA, Bool_t UGC) {
     195             :   UShort_t flags = 0;
     196           0 :   flags |= (1<< 0)*(UBA && UBC);
     197           0 :   flags |= (1<< 1)*(UBA || UBC);
     198           0 :   flags |= (1<< 2)*(UGA && UBC);
     199           0 :   flags |= (1<< 3)*UGA;
     200           0 :   flags |= (1<< 4)*(UGC && UBA);
     201           0 :   flags |= (1<< 5)*UGC;
     202             :   //CTA1 and CTC1
     203             :   //CTA1 or CTC1
     204             :   //CTA2 and CTC2
     205             :   //CTA2 or CTC2 
     206             :   //MTA and MTC
     207             :   //MTA or MTC
     208           0 :   flags |= (1<<12)*UBA;
     209           0 :   flags |= (1<<13)*UBC;
     210           0 :   flags |= (1<<14)*(UGA || UGC);
     211           0 :   flags |= (1<<15)*((UGA && UBC) || (UGC && UBA));
     212           0 :   return flags;
     213             : }
     214             : 
     215             : //_____________________________________________________________________________
     216             : void AliADReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digitsTree) const
     217             : {
     218             :   // converts RAW to digits 
     219           0 :   if (NULL == digitsTree) {
     220           0 :     AliError("No digits tree!");
     221           0 :     return;
     222             :   }
     223             : 
     224           0 :   if (NULL == fDigitsArray)
     225           0 :     fDigitsArray = new TClonesArray("AliADdigit", 16);
     226           0 :   digitsTree->Branch("ADDigit", &fDigitsArray);
     227             : 
     228           0 :   rawReader->Reset();
     229           0 :   AliADRawStream rawStream(rawReader);
     230           0 :   if (rawStream.Next()) {   
     231           0 :     Bool_t aBBflag[16];
     232           0 :     Bool_t aBGflag[16];
     233             :     
     234           0 :     for (Int_t iChannel=0; iChannel<16; ++iChannel) { // iChannel -> online channel number
     235           0 :       const Int_t offlineCh = kOfflineChannel[iChannel];
     236             :       // ADC charge samples
     237           0 :       Short_t chargeADC[kADNClocks] = { 0 };
     238             : //       aBBflag[offlineCh] = kFALSE;
     239             : //       aBGflag[offlineCh] = kFALSE;
     240           0 :       for (Int_t iClock=0; iClock<kADNClocks; ++iClock) {
     241           0 :         chargeADC[iClock]  = rawStream.GetPedestal(iChannel, iClock);
     242             : //      if (rawStream.GetBBFlag(iChannel, iClock)) aBBflag[offlineCh]=kTRUE;
     243             : //      if (rawStream.GetBGFlag(iChannel, iClock)) aBGflag[offlineCh]=kTRUE;
     244             :       }
     245             :       // Integrator flag
     246           0 :       const Bool_t integrator = rawStream.GetIntegratorFlag(iChannel, kADNClocks/2);
     247           0 :       const Bool_t BBflag     = rawStream.GetBBFlag(iChannel, kADNClocks/2); 
     248           0 :       const Bool_t BGflag     = rawStream.GetBGFlag(iChannel, kADNClocks/2);
     249           0 :       aBBflag[offlineCh] = BBflag;
     250           0 :       aBGflag[offlineCh] = BGflag;
     251             :    
     252             :       // HPTDC data (leading time and width)
     253           0 :       const Int_t   board     = AliADCalibData::GetBoardNumber(offlineCh);
     254           0 :       const Float_t time      = rawStream.GetTime(iChannel)  * fCalibData->GetTimeResolution(board);
     255           0 :       const Float_t width     = rawStream.GetWidth(iChannel) * fCalibData->GetWidthResolution(board);
     256             :       // Add a digit
     257           0 :       if(!fCalibData->IsChannelDead(offlineCh)){
     258           0 :       new ((*fDigitsArray)[fDigitsArray->GetEntriesFast()])
     259           0 :         AliADdigit(offlineCh, time, width,integrator, chargeADC, BBflag, BGflag);
     260             :       }
     261             :       
     262           0 :       fESDADfriend->SetBBScalers(offlineCh, rawStream.GetBBScalers(iChannel));
     263           0 :       fESDADfriend->SetBGScalers(offlineCh, rawStream.GetBGScalers(iChannel));
     264           0 :       for (Int_t iEv=0; iEv<kADNClocks; ++iEv) {
     265           0 :         fESDADfriend->SetBBFlag(offlineCh, iEv, rawStream.GetBBFlag(iChannel, iEv));
     266           0 :         fESDADfriend->SetBGFlag(offlineCh, iEv, rawStream.GetBGFlag(iChannel, iEv));
     267             :       }
     268           0 :     }
     269             :     //BC Unmasked triggers
     270             :     Int_t pBBmulADA = 0;
     271             :     Int_t pBBmulADC = 0;
     272             :     Int_t pBGmulADA = 0;
     273             :     Int_t pBGmulADC = 0;
     274             :   
     275           0 :     for (Int_t iChannel=0; iChannel<4; ++iChannel) {//Loop over pairs of pads
     276             :     //Enable time is used to turn off the coincidence 
     277           0 :       pBBmulADC += ((!fCalibData->GetEnableTiming(iChannel+ 0) || aBBflag[iChannel+ 0]) && (!fCalibData->GetEnableTiming(iChannel+ 4) || aBBflag[iChannel+ 4]));
     278           0 :       pBGmulADC += ((!fCalibData->GetEnableTiming(iChannel+ 0) || aBGflag[iChannel+ 0]) && (!fCalibData->GetEnableTiming(iChannel+ 4) || aBGflag[iChannel+ 4]));
     279             :       
     280           0 :       pBBmulADA += ((!fCalibData->GetEnableTiming(iChannel+ 8) || aBBflag[iChannel+ 8]) && (!fCalibData->GetEnableTiming(iChannel+12) || aBBflag[iChannel+12]));
     281           0 :       pBGmulADA += ((!fCalibData->GetEnableTiming(iChannel+ 8) || aBGflag[iChannel+ 8]) && (!fCalibData->GetEnableTiming(iChannel+12) || aBGflag[iChannel+12]));
     282             :     }
     283             :     
     284           0 :     const Bool_t UBA = (pBBmulADA >= fCalibData->GetBBAThreshold());
     285           0 :     const Bool_t UBC = (pBBmulADC >= fCalibData->GetBBCThreshold());
     286           0 :     const Bool_t UGA = (pBGmulADA >= fCalibData->GetBGAThreshold());
     287           0 :     const Bool_t UGC = (pBGmulADC >= fCalibData->GetBGCThreshold());
     288             : 
     289           0 :     const UShort_t fTrigger = MakeTriggerFlags(UBA, UBC,
     290           0 :                                                UGA, UGC);
     291             :     
     292           0 :     fESDADfriend->SetTriggerInputs(fTrigger);
     293           0 :     fESDADfriend->SetTriggerInputsMask(rawStream.GetTriggerInputsMask());
     294             :   
     295           0 :     for (Int_t iScaler=0; iScaler<AliESDADfriend::kNScalers; ++iScaler) {
     296           0 :       fESDADfriend->SetTriggerScalers(iScaler, rawStream.GetTriggerScalers(iScaler));
     297             :     }
     298           0 :     digitsTree->Fill();
     299           0 :   }
     300             : 
     301           0 :   fDigitsArray->Clear();
     302           0 : }
     303             : 
     304             : //_____________________________________________________________________________
     305             : void AliADReconstructor::FillESD(TTree* digitsTree, TTree* /*clustersTree*/,AliESDEvent* esd) const
     306             : {
     307           0 :   printf("Running AD Reconstruction \n");
     308             : 
     309           0 :   if (!digitsTree) {
     310           0 :       AliError("No digits tree!");
     311           0 :       return;
     312             :   }
     313             : 
     314           0 :   TBranch* digitBranch = digitsTree->GetBranch("ADDigit");
     315           0 :   digitBranch->SetAddress(&fDigitsArray);
     316             : 
     317           0 :   Float_t   mult[16];
     318           0 :   Float_t    adc[16];
     319           0 :   Float_t   tail[16];
     320           0 :   Float_t   tailComplement[16];
     321           0 :   Float_t   time[16];
     322           0 :   Float_t  width[16];
     323           0 :   Bool_t aBBflag[16];
     324           0 :   Bool_t aBGflag[16];
     325           0 :   Float_t   adcTrigger[16];
     326             :   
     327           0 :   for (Int_t i=0; i<16; i++){
     328           0 :     adc[i]            = 0.0f;
     329           0 :     tail[i]           = 0.0f;
     330           0 :     tailComplement[i] = 0.0f;
     331           0 :     mult[i]           = 0.0f;
     332           0 :     time[i]           = kInvalidTime;
     333           0 :     width[i]          = 0.0f;
     334           0 :     aBBflag[i]        = kFALSE;
     335           0 :     aBGflag[i]        = kFALSE;
     336           0 :     adcTrigger[i]     = 0.0f;
     337             :   }
     338             :   
     339           0 :   TClonesArray *f_Int0 = new TClonesArray;
     340           0 :   TClonesArray *f_Int1 = new TClonesArray;
     341           0 :   Int_t chOffline=0, chOnline=0;
     342           0 :   Float_t extrapolationThresholds[kADNClocks];
     343           0 :   Bool_t  doExtrapolation[kADNClocks];
     344           0 :   for (Int_t i=0; i<kADNClocks; ++i) {
     345           0 :     extrapolationThresholds[i] = -999.0f;
     346           0 :     doExtrapolation[i]         = kFALSE;
     347             :   }
     348           0 :   Float_t chargeEqualizationFactor = 1.0f;
     349           0 :   if (fCorrectForSaturation) {
     350           0 :     fSaturationCorrection->SetBranchAddress("f_Int0",                   &f_Int0);
     351           0 :     fSaturationCorrection->SetBranchAddress("f_Int1",                   &f_Int1);
     352           0 :     fSaturationCorrection->SetBranchAddress("chOffline",                &chOffline);
     353           0 :     fSaturationCorrection->SetBranchAddress("chOnline",                 &chOnline);
     354           0 :     fSaturationCorrection->SetBranchAddress("extrapolationThresholds",  &extrapolationThresholds);
     355           0 :     fSaturationCorrection->SetBranchAddress("doExtrapolation",          &doExtrapolation);
     356           0 :     fSaturationCorrection->SetBranchAddress("chargeEqualizationFactor", &chargeEqualizationFactor);
     357           0 :   }
     358             :   Bool_t correctedForSaturation = kFALSE;
     359             : 
     360           0 :   for (Long64_t e=0, n=digitsTree->GetEntries(); e<n; ++e) {
     361           0 :     digitsTree->GetEvent(e);
     362             :     
     363           0 :     for (Int_t d=0, m=fDigitsArray->GetEntriesFast(); d<m; ++d) {    
     364           0 :       const AliADdigit* digit    = dynamic_cast<const AliADdigit*>(fDigitsArray->At(d));
     365           0 :       const Int_t       pmNumber = digit->PMNumber();
     366             :       
     367             :       // Pedestal retrieval and suppression
     368           0 :       Bool_t  integrator = digit->Integrator();
     369             :       Float_t maxadc     = 0.0f;
     370             :       Int_t   imax       = -1;
     371           0 :       Float_t adcPedSub[kADNClocks] = { 0 };
     372           0 :       for (Int_t iClock=0; iClock<kADNClocks; ++iClock) {
     373           0 :         const Short_t charge      = digit->ChargeADC(iClock);
     374           0 :         const Bool_t  iIntegrator = ((iClock%2) == 0 ? integrator : !integrator);
     375             : 
     376           0 :         const Int_t k = pmNumber + 16*iIntegrator;
     377           0 :         adcPedSub[iClock] = static_cast<Float_t>(charge) - fCalibData->GetPedestal(k);
     378           0 :         if(adcPedSub[iClock] <= GetRecoParam()->GetNSigmaPed()*fCalibData->GetSigma(k)) {
     379           0 :           adcPedSub[iClock] = 0;
     380           0 :           continue;
     381             :         }
     382             :         
     383           0 :         if (iClock < GetRecoParam()->GetStartClock() ||
     384           0 :             iClock > GetRecoParam()->GetEndClock()) continue;
     385             : 
     386           0 :         if (adcPedSub[iClock] > maxadc) {
     387             :           maxadc = adcPedSub[iClock];
     388             :           imax   = iClock;
     389           0 :         }
     390           0 :       }
     391             : 
     392             :       // start and end BCs for charge integration
     393           0 :       const Int_t start = TMath::Max( 0, imax - GetRecoParam()->GetNPreClocks());
     394           0 :       const Int_t end   = TMath::Min(20, imax + GetRecoParam()->GetNPostClocks());
     395             : 
     396             :       // start and end BCs for tail charge integration
     397           0 :       const Int_t tailBegin = GetRecoParam()->GetTailBegin();
     398           0 :       const Int_t tailEnd   = GetRecoParam()->GetTailEnd();
     399             : 
     400             :       // integrated charge without saturation correction
     401           0 :       adc[pmNumber] = 0.0f;
     402           0 :       for (Int_t iClock=start; iClock<=end; ++iClock)
     403           0 :         adc[pmNumber] += adcPedSub[iClock];
     404             :       
     405             :       // HPTDC leading time and width
     406             :       // Correction for slewing and various time delays
     407           0 :       time[pmNumber]    = CorrectLeadingTime(pmNumber, digit->Time(), adc[pmNumber]);
     408           0 :       width[pmNumber]   = digit->Width();
     409           0 :       aBBflag[pmNumber] = digit->GetBBflag();
     410           0 :       aBGflag[pmNumber] = digit->GetBGflag();
     411             : 
     412           0 :       if (imax != -1) {
     413             :         const Float_t threshold = 20.0f;
     414             :         Bool_t isPileUp = kFALSE;
     415           0 :         for (Int_t bc=13; bc<kADNClocks-1 && !isPileUp; ++bc)
     416           0 :           isPileUp |= (adcPedSub[bc+1] > adcPedSub[bc] + threshold);
     417             :     
     418             :          
     419           0 :         for (Int_t iClock=tailBegin; iClock<=tailEnd; ++iClock)
     420           0 :           tail[pmNumber] += adcPedSub[iClock];
     421             : 
     422           0 :         adcTrigger[pmNumber] = adcPedSub[10];
     423             : 
     424           0 :         for (Int_t iClock=end+1; iClock<kADNClocks; ++iClock)
     425           0 :           tailComplement[pmNumber] += adcPedSub[iClock];
     426             : 
     427           0 :         if (fCorrectForSaturation) {
     428           0 :           f_Int0->Clear();
     429           0 :           f_Int1->Clear();
     430           0 :           fSaturationCorrection->GetEntry(pmNumber);
     431           0 :         }
     432             : 
     433           0 :         AliDebug(3, Form("pmNumber=%d offlineCh=%d onlineCh=%d isPileUp=%d", pmNumber, chOffline, chOnline, isPileUp));
     434           0 :         adc[pmNumber] = 0.0f;
     435           0 :         for (Int_t iClock=start; iClock<=end; ++iClock) {
     436           0 :           const Bool_t iIntegrator = ((iClock%2) == 0 ? integrator : !integrator);
     437             :           
     438           0 :           const TF1* fExtrapolation = (doExtrapolation[iClock]
     439           0 :                                        ? static_cast<const TF1*>(iIntegrator
     440           0 :                                                                  ? f_Int1->At(iClock)
     441           0 :                                                                  : f_Int0->At(iClock))
     442             :                                        : NULL);
     443           0 :           correctedForSaturation  |= doExtrapolation[iClock];
     444           0 :           if (doExtrapolation[iClock]) {
     445           0 :             AliDebug(3, Form("Ch%02d bc%02d %d tail=%6.1f thr=%6.1f adc=%6.1f adcCorr=%7.1f",
     446             :                              pmNumber, iClock, doExtrapolation[iClock], tail[pmNumber], extrapolationThresholds[iClock],
     447             :                              adcPedSub[iClock], fExtrapolation->Eval(tail[pmNumber])));
     448             :           }
     449             : 
     450           0 :           adc[pmNumber] += chargeEqualizationFactor*((doExtrapolation[iClock] && tail[pmNumber] > extrapolationThresholds[iClock])
     451           0 :                                                      ? fExtrapolation->Eval(tail[pmNumber])
     452           0 :                                                      : adcPedSub[iClock]
     453             :                                                      );
     454             :         }
     455             :         // if the tail charge is biased by after-pulses/pileup it's sign is reversed
     456             :         // (this implies also that the correction for ADC saturation is biased)
     457           0 :         if (isPileUp)
     458           0 :           tail[pmNumber] *= -1;
     459           0 :       }
     460             : 
     461           0 :       AliDebug(3, Form("ADreco: GetRecoParam()->GetNPreClocks()=%d, GetRecoParam()->GetNPostClocks()=%d imax=%d maxadc=%.1f adc[%2d]=%.1f tail[%2d]=%.1f tailC=%.1f",
     462             :                        GetRecoParam()->GetNPreClocks(),
     463             :                        GetRecoParam()->GetNPostClocks(),
     464             :                        imax,
     465             :                        maxadc,
     466             :                        pmNumber,
     467             :                        adc[pmNumber],
     468             :                        pmNumber,
     469             :                        tail[pmNumber],
     470             :                        tailComplement[pmNumber]));
     471             :       
     472             :       // MIP multiplicity
     473           0 :       const Float_t adcPerMIP = const_cast<AliADCalibData*>(fCalibData)->GetADCperMIP(pmNumber);
     474           0 :       mult[pmNumber] = (adcPerMIP != 0 ? adc[pmNumber]/adcPerMIP : 0.0f);
     475             :       
     476           0 :       if (adc[pmNumber] > 0) {
     477           0 :         AliDebug(1, Form("PM = %d ADC = %.2f (%.2f) TDC %.2f (%.2f)   Int %d (%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d)    %.2f %.2f   %.2f %.2f    %d %d",
     478             :                          pmNumber,  adc[pmNumber],
     479             :                          digit->ChargeADC(11)+digit->ChargeADC(10)+digit->ChargeADC(9)+digit->ChargeADC(8)+
     480             :                          digit->ChargeADC(7)+digit->ChargeADC(6)+digit->ChargeADC(5)+digit->ChargeADC(4)-
     481             :                          4.*fCalibData->GetPedestal(pmNumber)-4.*fCalibData->GetPedestal(pmNumber+16),
     482             :                          digit->Time(), time[pmNumber],
     483             :                          integrator,
     484             :                          digit->ChargeADC(0), digit->ChargeADC(1), digit->ChargeADC(2), digit->ChargeADC(3), digit->ChargeADC(4), digit->ChargeADC(5), digit->ChargeADC(6), digit->ChargeADC(7),
     485             :                          digit->ChargeADC(8), digit->ChargeADC(9), digit->ChargeADC(10),
     486             :                          digit->ChargeADC(11), digit->ChargeADC(12),
     487             :                          digit->ChargeADC(13), digit->ChargeADC(14), digit->ChargeADC(15), digit->ChargeADC(16), digit->ChargeADC(17), digit->ChargeADC(18), digit->ChargeADC(19), digit->ChargeADC(20),
     488             :                          fCalibData->GetPedestal(pmNumber), fCalibData->GetSigma(pmNumber),
     489             :                          fCalibData->GetPedestal(pmNumber+16), fCalibData->GetSigma(pmNumber+16),
     490             :                          aBBflag[pmNumber], aBGflag[pmNumber]));
     491             :       };
     492             :       
     493             :       // Fill ESD friend object
     494           0 :       for (Int_t iEv=0; iEv < kADNClocks; ++iEv) {
     495           0 :         fESDADfriend->SetPedestal      (pmNumber, iEv, static_cast<Float_t>(digit->ChargeADC(iEv)));
     496           0 :         fESDADfriend->SetIntegratorFlag(pmNumber, iEv, ((iEv%2) == 0 ? integrator : !integrator));
     497             :       }
     498           0 :       fESDADfriend->SetTime (pmNumber, digit->Time());
     499           0 :       fESDADfriend->SetWidth(pmNumber, digit->Width());      
     500           0 :     } // end of loop over digits
     501             :   } // end of loop over events in digits tree
     502             : 
     503           0 :   if (fCorrectForSaturation)
     504           0 :     fSaturationCorrection->ResetBranchAddresses();
     505             :   
     506           0 :   fESDAD->SetBit(AliESDAD::kCorrectedLeadingTime,   kTRUE);
     507           0 :   fESDAD->SetBit(AliESDAD::kCorrectedForSaturation, correctedForSaturation);
     508           0 :   fESDAD->SetMultiplicity(mult);
     509           0 :   fESDAD->SetADC(adc);
     510           0 :   fESDAD->SetTime(time);
     511           0 :   fESDAD->SetWidth(width);
     512           0 :   fESDAD->SetBBFlag(aBBflag);
     513           0 :   fESDAD->SetBGFlag(aBGflag);
     514           0 :   fESDAD->SetADCTail(tail);
     515           0 :   fESDAD->SetADCTrigger(adcTrigger);
     516             :   
     517             :   // Fill BB and BG flags for all channel in 21 clocks (called past-future flags)
     518           0 :   for (Int_t i=0; i<16; ++i) {
     519           0 :     for (Int_t iClock=0; iClock<kADNClocks; ++iClock) {
     520           0 :       fESDAD->SetPFBBFlag(i, iClock, fESDADfriend->GetBBFlag(i, iClock));
     521           0 :       fESDAD->SetPFBGFlag(i, iClock, fESDADfriend->GetBGFlag(i, iClock));
     522             :     }
     523             :   }
     524           0 :   fESDAD->SetBit(AliESDAD::kPastFutureFlagsFilled, kTRUE);
     525             :    
     526             :   Int_t pBBmulADA = 0;
     527             :   Int_t pBBmulADC = 0;
     528             :   Int_t pBGmulADA = 0;
     529             :   Int_t pBGmulADC = 0;
     530             :   
     531           0 :   for (Int_t iChannel=0; iChannel<4; ++iChannel) {//Loop over pairs of pads
     532             :     //Enable time is used to turn off the coincidence 
     533           0 :     pBBmulADC += ((!fCalibData->GetEnableTiming(iChannel+ 0) || aBBflag[iChannel+ 0]) && (!fCalibData->GetEnableTiming(iChannel+ 4) || aBBflag[iChannel+ 4]));
     534           0 :     pBGmulADC += ((!fCalibData->GetEnableTiming(iChannel+ 0) || aBGflag[iChannel+ 0]) && (!fCalibData->GetEnableTiming(iChannel+ 4) || aBGflag[iChannel+ 4]));
     535             : 
     536           0 :     pBBmulADA += ((!fCalibData->GetEnableTiming(iChannel+ 8) || aBBflag[iChannel+ 8]) && (!fCalibData->GetEnableTiming(iChannel+12) || aBBflag[iChannel+12]));
     537           0 :     pBGmulADA += ((!fCalibData->GetEnableTiming(iChannel+ 8) || aBGflag[iChannel+ 8]) && (!fCalibData->GetEnableTiming(iChannel+12) || aBGflag[iChannel+12]));
     538             :   }
     539             :         
     540           0 :   const Bool_t UBA = (pBBmulADA >= fCalibData->GetBBAThreshold());
     541           0 :   const Bool_t UBC = (pBBmulADC >= fCalibData->GetBBCThreshold());
     542           0 :   const Bool_t UGA = (pBGmulADA >= fCalibData->GetBGAThreshold());
     543           0 :   const Bool_t UGC = (pBGmulADC >= fCalibData->GetBGCThreshold());
     544             : 
     545           0 :   const UShort_t fTrigger = MakeTriggerFlags(UBA, UBC,
     546           0 :                                              UGA, UGC);
     547             : 
     548           0 :   fESDAD->SetTriggerBits(fTrigger);
     549           0 :   fESDAD->SetBit(AliESDAD::kOnlineBitsFilled,kTRUE);
     550             : 
     551             :   // now fill the AD decision
     552           0 :   AliADDecision offlineDecision;
     553           0 :   offlineDecision.SetRecoParam(GetRecoParam());
     554           0 :   offlineDecision.FillDecisions(fESDAD);
     555             :   
     556           0 :   if (NULL != esd) { 
     557           0 :     AliDebug(1, Form("Writing AD data to ESD tree"));
     558           0 :     esd->SetADData(fESDAD);
     559             :     
     560           0 :     AliESDfriend *fr = dynamic_cast<AliESDfriend*>(esd->FindListObject("AliESDfriend"));
     561           0 :     if (NULL != fr) {
     562           0 :       AliDebug(1, Form("Writing AD friend data to ESD tree"));
     563           0 :       fr->SetADfriend(fESDADfriend);
     564             :     }
     565           0 :   }
     566             :   
     567           0 :   fDigitsArray->Clear();
     568           0 : }
     569             : 
     570             : //_____________________________________________________________________________
     571             : const AliADCalibData* AliADReconstructor::GetCalibData() const
     572             : {
     573           0 :   AliCDBManager *man = AliCDBManager::Instance();
     574           0 :   AliCDBEntry *entry = man->Get("AD/Calib/Data");
     575             :   const AliADCalibData *calibdata = NULL;
     576             : 
     577           0 :   if (NULL != entry)
     578           0 :     calibdata = dynamic_cast<const AliADCalibData*>(entry->GetObject());
     579           0 :   if (NULL == calibdata)
     580           0 :     AliFatal("No calibration data from calibration database !");
     581             : 
     582           0 :   return calibdata;
     583           0 : }
     584             : 
     585             : //_____________________________________________________________________________
     586             : void AliADReconstructor::GetTimeSlewingSplines()
     587             : {
     588           0 :   AliCDBManager *man = AliCDBManager::Instance();
     589           0 :   AliCDBEntry *entry = man->Get("AD/Calib/TimeSlewing");  
     590             :   TList *fListSplines = NULL;
     591             : 
     592           0 :   if (NULL != entry)
     593           0 :     fListSplines = dynamic_cast<TList*>(entry->GetObject());
     594           0 :   if (NULL == fListSplines)
     595           0 :     AliFatal("No time slewing correction from calibration database !");
     596             :   
     597           0 :   for (Int_t i=0; i<16; ++i)
     598           0 :     fTimeSlewingSpline[i] = dynamic_cast<TSpline3*>(fListSplines->At(i));
     599           0 : }
     600             : 
     601             : //_____________________________________________________________________________
     602             : AliCDBStorage* AliADReconstructor::SetStorage(const char *uri) 
     603             : {
     604             :   // Sets the storage  
     605             :   Bool_t deleteManager = kFALSE;  
     606           0 :   AliCDBManager *manager = AliCDBManager::Instance();
     607           0 :   AliCDBStorage *defstorage = manager->GetDefaultStorage();
     608             :   
     609           0 :   if(!defstorage || !(defstorage->Contains("AD"))) { 
     610           0 :      AliWarning("No default storage set or default storage doesn't contain AD!");
     611           0 :      manager->SetDefaultStorage(uri);
     612             :      deleteManager = kTRUE;
     613           0 :   }
     614             :  
     615           0 :   AliCDBStorage *storage = manager->GetDefaultStorage();
     616           0 :   if(deleteManager) {
     617           0 :      AliCDBManager::Instance()->UnsetDefaultStorage();
     618             :      defstorage = 0;   // the storage is killed by AliCDBManager::Instance()->Destroy()
     619           0 :   }
     620             : 
     621           0 :   return storage; 
     622             : }
     623             : 
     624             : //____________________________________________________________________________
     625             : void AliADReconstructor::GetCollisionMode()
     626             : {
     627             :   // Retrieval of collision mode 
     628           0 :   const TString beamType = GetRunInfo()->GetBeamType();
     629           0 :   if (beamType == AliGRPObject::GetInvalidString()) {
     630           0 :     AliError("AD cannot retrieve beam type");
     631           0 :     return;
     632             :   }
     633           0 :   if((beamType.CompareTo("P-P") ==0) ||
     634           0 :      (beamType.CompareTo("p-p") ==0)) {
     635           0 :     fCollisionMode = 0;
     636           0 :   } else if ((beamType.CompareTo("Pb-Pb") == 0)  ||
     637           0 :              (beamType.CompareTo("A-A") == 0)) {
     638           0 :     fCollisionMode = 1;
     639           0 :   }
     640             :     
     641           0 :   fBeamEnergy = GetRunInfo()->GetBeamEnergy();
     642           0 :   if (fBeamEnergy == AliGRPObject::GetInvalidFloat()) {
     643           0 :     AliError("Missing value for the beam energy ! Using 0");
     644           0 :     fBeamEnergy = 0.;
     645           0 :   }
     646             :   
     647           0 :   AliDebug(1, Form("\n ++++++ Beam type and collision mode retrieved as %s %d @ %1.3f GeV ++++++\n\n", beamType.Data(), fCollisionMode, fBeamEnergy));
     648           0 : }
     649             : //____________________________________________________________________________
     650             : Float_t AliADReconstructor::CorrectLeadingTime(Int_t i, Float_t time, Float_t adc) const
     651             : {
     652             :   // Correct the leading time
     653             :   // for slewing effect and
     654             :   // misalignment of the channels
     655           0 :   if (time < 1e-6)
     656           0 :     return kInvalidTime;
     657             : 
     658             :   // In case of pathological signals
     659           0 :   if (adc < 1.0)
     660           0 :     return time;
     661             : 
     662             :   // Slewing and offset correction
     663           0 :   const Int_t board = AliADCalibData::GetBoardNumber(i);
     664           0 :   time -= fTimeSlewingSpline[i]->Eval(TMath::Log10(1/adc))*fCalibData->GetTimeResolution(board);
     665           0 :   time += fLayerDist[i/4];
     666             :   
     667             :   // Channel alignment and general offset subtraction
     668             :   //time -= fHptdcOffset[i];
     669             :   return time;
     670           0 : }

Generated by: LCOV version 1.11