LCOV - code coverage report
Current view: top level - MUON/MUONbase - AliMUONDigitCalibrator.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 85 141 60.3 %
Date: 2016-06-14 17:26:59 Functions: 11 16 68.8 %

          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$
      17             : 
      18             : #include "AliMUONDigitCalibrator.h"
      19             : 
      20             : #include "AliCDBEntry.h"
      21             : #include "AliCDBManager.h"
      22             : #include "AliLog.h"
      23             : #include "AliMUONCalibrationData.h"
      24             : #include "AliMUONConstants.h"
      25             : #include "AliMUONLogger.h"
      26             : #include "AliMUONPadStatusMaker.h"
      27             : #include "AliMUONPadStatusMapMaker.h"
      28             : #include "AliMUONRecoParam.h"
      29             : #include "AliMUONVCalibParam.h"
      30             : #include "AliMUONVDigit.h"
      31             : #include "AliMUONVDigitStore.h"
      32             : #include "AliMUONVStore.h"
      33             : #include "AliMpBusPatch.h"
      34             : #include "AliMpConstants.h"
      35             : #include "AliMpCDB.h"
      36             : #include "AliMpDDLStore.h"
      37             : #include "AliMpDEIterator.h"
      38             : #include "AliMpDetElement.h"
      39             : #include "AliMpManuStore.h"
      40             : 
      41             : //-----------------------------------------------------------------------------
      42             : /// \class AliMUONDigitCalibrator
      43             : /// Class used to calibrate digits (either real or simulated ones).
      44             : ///
      45             : /// The calibration consists of subtracting the pedestal
      46             : /// and multiplying by a constant gain, so that
      47             : /// Signal = (ADC-pedestal)*gain
      48             : ///
      49             : /// Please note also that for the moment, if a digit lies on a dead channel
      50             : /// we remove this digit from the list of digits.
      51             : /// FIXME: this has to be revisited. By using the AliMUONDigit::fFlags we
      52             : /// should in principle flag a digit as bad w/o removing it, but this 
      53             : /// then requires some changes in the cluster finder to deal with this extra
      54             : /// information correctly (e.g. to set a quality for the cluster if it contains
      55             : /// bad digits).
      56             : ///
      57             : /// \author Laurent Aphecetche
      58             : //-----------------------------------------------------------------------------
      59             : 
      60             : 
      61             : /// \cond CLASSIMP
      62          18 : ClassImp(AliMUONDigitCalibrator)
      63             : /// \endcond
      64             : 
      65             : //_____________________________________________________________________________
      66             : AliMUONDigitCalibrator::AliMUONDigitCalibrator(Int_t runNumber)
      67           0 : : TObject(),
      68           0 : fLogger(new AliMUONLogger(20000)),
      69           0 : fStatusMaker(0x0),
      70           0 : fStatusMapMaker(0x0),
      71           0 : fPedestals(0x0),
      72           0 : fNumberOfBadPads(0),
      73           0 : fNumberOfPads(0),
      74           0 : fChargeSigmaCut(0),
      75           0 : fMask(0)
      76           0 : {
      77             :   /// ctor
      78             :   
      79             :   AliMUONRecoParam* recoParam(0x0);
      80             :   
      81           0 :   AliCDBEntry* e = AliCDBManager::Instance()->Get("MUON/Calib/RecoParam",runNumber);
      82           0 :   if (e)
      83             :   {
      84           0 :     TObject* o = e->GetObject();
      85           0 :     if ( o->IsA() == TObjArray::Class() )
      86             :     {
      87           0 :       TObjArray* a = static_cast<TObjArray*>(o);
      88             : //      a->SetOwner(kTRUE); // FIXME: this should be done but somehow makes the reco crash at the end at cleaning stage... investigate why ?
      89           0 :       TIter next(a);
      90             :       AliMUONRecoParam* p;
      91           0 :       while ( ( p = static_cast<AliMUONRecoParam*>(next()) ))
      92             :       {
      93           0 :         if ( p->IsDefault()) recoParam = p;
      94             :       }
      95           0 :     }
      96             :     else
      97             :     {
      98           0 :       recoParam = static_cast<AliMUONRecoParam*>(o);
      99             :     }
     100           0 :   }
     101           0 :   if (!recoParam)
     102             :   {
     103           0 :     AliError("Cannot get the recoParam. Failing");
     104           0 :     return;
     105             :   }
     106             :   
     107             :   // OK. Now get all we need and work...
     108             :   
     109           0 :   AliMUONCalibrationData calib(runNumber);
     110             :   
     111           0 :   Ctor(calib,recoParam,kFALSE);
     112           0 : }
     113             : 
     114             : //_____________________________________________________________________________
     115             : AliMUONDigitCalibrator::AliMUONDigitCalibrator(const AliMUONCalibrationData& calib,
     116             :                                                const AliMUONRecoParam* recoParams)
     117           2 : : TObject(),
     118           6 : fLogger(new AliMUONLogger(20000)),
     119           2 : fStatusMaker(0x0),
     120           2 : fStatusMapMaker(0x0),
     121           2 : fPedestals(0x0),
     122           2 : fNumberOfBadPads(0),
     123           2 : fNumberOfPads(0),
     124           2 : fChargeSigmaCut(0),
     125           2 : fMask(0)
     126          10 : {
     127             :   /// ctor
     128             :   
     129           2 :   Ctor(calib,recoParams);
     130           4 : }
     131             : 
     132             : //_____________________________________________________________________________
     133             : AliMUONDigitCalibrator::AliMUONDigitCalibrator(const AliMUONCalibrationData& calib, int /*b*/)
     134           0 : : TObject(),
     135           0 : fLogger(new AliMUONLogger(20000)),
     136           0 : fStatusMaker(0x0),
     137           0 : fStatusMapMaker(0x0),
     138           0 : fPedestals(0x0),
     139           0 : fNumberOfBadPads(0),
     140           0 : fNumberOfPads(0),
     141           0 : fChargeSigmaCut(0),
     142           0 : fMask(0)
     143           0 : {
     144             :   /// ctor
     145             :   
     146           0 :   Ctor(calib,0x0);
     147           0 : }
     148             : 
     149             : //_____________________________________________________________________________
     150             : void
     151             : AliMUONDigitCalibrator::Ctor(const AliMUONCalibrationData& calib,
     152             :                              const AliMUONRecoParam* recoParams,
     153             :                              Bool_t deferredInitialization)
     154             : {
     155             :   /// designated ctor
     156             :   
     157             :   // Load mapping manu store
     158           2 :   if ( ! AliMpCDB::LoadManuStore() ) {
     159           0 :     AliFatal("Could not access manu store from OCDB !");
     160           0 :   }
     161             :   
     162           4 :   fStatusMaker = new AliMUONPadStatusMaker(calib);
     163             :   
     164             :   // Set default values, as loose as reasonable
     165             :   
     166           2 :   fChargeSigmaCut = 3.0;
     167             :   
     168           2 :         fMask = 0x8080; // reject pads where ped *or* hv are missing
     169             :         
     170           2 :         if ( recoParams )
     171             :         {
     172             :     // if we have reco params, we use limits and cuts from there :
     173             :     
     174           2 :     fStatusMaker->SetLimits(*recoParams);
     175             :     
     176           2 :     fMask = recoParams->PadGoodnessMask();
     177             :                 //WARNING : getting this mask wrong is a very effective way of getting
     178             :                 //no digits at all out of this class ;-)
     179             :     
     180           2 :     fChargeSigmaCut = recoParams->ChargeSigmaCut();
     181           2 :         }
     182             :   else
     183             :   {
     184           0 :     fLogger->Log("No RecoParam available");
     185           0 :     fLogger->Log(Form("SigmaCut=%e",fChargeSigmaCut));
     186             :   }
     187             :   
     188           4 :   fStatusMapMaker = new AliMUONPadStatusMapMaker(*fStatusMaker,fMask,deferredInitialization);
     189             :   
     190           2 :   fPedestals = calib.Pedestals();
     191           2 : }
     192             : 
     193             : //_____________________________________________________________________________
     194             : AliMUONDigitCalibrator::~AliMUONDigitCalibrator()
     195          12 : {
     196             :   /// dtor.
     197             :   
     198           2 :   if ( fNumberOfPads > 0 ) 
     199             :   {
     200           2 :     if ( fStatusMaker ) 
     201             :     {
     202           2 :       fStatusMaker->Report(fMask);
     203             :     }
     204             :     
     205           4 :     AliInfo("Summary of messages:");
     206             : 
     207           2 :     fLogger->Print();
     208             :     
     209          10 :     AliInfo(Form("We have seen %g pads, and rejected %g (%7.2f %%)",
     210             :                  fNumberOfPads,fNumberOfBadPads,
     211             :                  ( fNumberOfPads > 0 ) ? fNumberOfBadPads*100.0/fNumberOfPads : 0 ));
     212             :         }
     213             : 
     214           4 :   delete fStatusMaker;
     215           4 :   delete fStatusMapMaker;
     216           4 :   delete fLogger;
     217           6 : }
     218             : 
     219             : //_____________________________________________________________________________
     220             : void
     221             : AliMUONDigitCalibrator::Calibrate(AliMUONVDigitStore& digitStore)
     222             : {
     223             :   /// Calibrate the digits contained in digitStore  
     224          16 :   TIter next(digitStore.CreateTrackerIterator());
     225             :   AliMUONVDigit* digit;
     226             :   
     227           8 :   fStatusMapMaker->RefreshRejectProbabilities(); // this will do something only for simulations
     228             :   // (and only for those simulations where the reject list contain probabilities which are
     229             :   // different from zero or one)
     230             :   
     231          40 :   AliDebug(1,Form("# of digits = %d",digitStore.GetSize()));
     232             :   
     233        4264 :   while ( ( digit = static_cast<AliMUONVDigit*>(next() ) ) )
     234             :   {
     235        2832 :     if ( digit->IsCalibrated() ) 
     236             :     {
     237           0 :       fLogger->Log("ERROR : trying to calibrate a digit twice");
     238           0 :       return;
     239             :     }
     240             :     
     241        1416 :     digit->Calibrated(kTRUE);
     242        1416 :     digit->ChargeInFC(kTRUE);
     243             :     
     244             :     Float_t charge(0.0);
     245        1416 :     Int_t statusMap;
     246        1416 :     Bool_t isSaturated(kFALSE);
     247             :     
     248        1416 :     ++fNumberOfPads;
     249             :     
     250        7080 :     Bool_t ok = IsValidDigit(digit->DetElemId(),digit->ManuId(),digit->ManuChannel(),&statusMap);
     251             :     
     252        1416 :     digit->SetStatusMap(statusMap);
     253             : 
     254        1416 :     if (ok)
     255             :     {
     256        5664 :       charge = CalibrateDigit(digit->DetElemId(),digit->ManuId(),digit->ManuChannel(),
     257        2832 :                               digit->ADC(),fChargeSigmaCut,&isSaturated);
     258        1416 :     }
     259             :     else
     260             :     {
     261           0 :       ++fNumberOfBadPads;      
     262             :     }
     263             :     
     264        1416 :     digit->SetCharge(charge);
     265        1416 :     digit->Saturated(isSaturated);
     266             :     
     267        1416 :   }
     268          16 : }
     269             : 
     270             : //_____________________________________________________________________________
     271             : Float_t
     272             : AliMUONDigitCalibrator::CalibrateDigit(Int_t detElemId, Int_t manuId, Int_t manuChannel,
     273             :                                        Float_t adc, Float_t nsigmas, 
     274             :                                        Bool_t* isSaturated) const
     275             : 
     276             : {
     277             :   /// Calibrate one digit
     278             :   /// Return the digit charge, in fC
     279             :   
     280        2832 :   if ( nsigmas < 0 ) 
     281             :   {
     282           0 :     nsigmas = fChargeSigmaCut;
     283           0 :   }
     284             : 
     285        1416 :   fLogger->Log(Form("ChargeSigmaCut used = %e",nsigmas));
     286             : 
     287        1416 :   AliMUONVCalibParam* pedestal = static_cast<AliMUONVCalibParam*>
     288        1416 :   (fPedestals->FindObject(detElemId,manuId));
     289             :   
     290        1416 :   if (!pedestal)
     291             :   {
     292             :     // no pedestal -> no charge    
     293           0 :     fLogger->Log(Form("Got a null pedestal object for DE,manu=%d,%d",detElemId,manuId));        
     294           0 :     return 0.0;
     295             :   }
     296             :   
     297        1416 :   Float_t padc = adc-pedestal->ValueAsFloat(manuChannel,0);
     298             :   
     299             :         // Gain (mV/fC) = 1/(a0*capa) with a0~1.25 and capa~0.2 
     300             :   Float_t charge(0);
     301        1416 :   Float_t capa(AliMUONConstants::DefaultCapa()); // capa = 0.2 and a0 = 1.25
     302        1416 :   Float_t a0(AliMUONConstants::DefaultA0());  // is equivalent to gain = 4 mV/fC
     303        1416 :   Float_t adc2mv(AliMUONConstants::DefaultADC2MV()); // 1 ADC channel = 0.61 mV
     304             :   //
     305             :   // Note that the ChargeMax (for one pad) is roughly 4096 * 0.61 mV/channel / 4 mV/fC = 625 fC
     306             :   
     307        1416 :   if ( padc > nsigmas*pedestal->ValueAsFloat(manuChannel,1) ) 
     308             :   {
     309        1324 :     charge = a0*padc*capa*adc2mv;
     310        1324 :   }
     311             :   
     312        1416 :   if ( isSaturated ) 
     313             :   {
     314             :     const Int_t saturation(3000);
     315             :     
     316        1416 :     if ( padc >= saturation )
     317             :     {
     318           0 :       *isSaturated = kTRUE;
     319           0 :     }
     320             :     else
     321             :     {
     322        1416 :       *isSaturated = kFALSE;
     323             :     }
     324        1416 :   }
     325             :   
     326        1416 :   return ( charge > 0.0 ? charge : 0.0 );
     327        1416 : }
     328             : 
     329             : //_____________________________________________________________________________
     330             : Bool_t 
     331             : AliMUONDigitCalibrator::IsValidDigit(Int_t detElemId, Int_t manuId, Int_t manuChannel,
     332             :                                      Int_t* statusMap) const
     333             : 
     334             : {
     335             :   /// Check if a given pad is ok or not.
     336             :   
     337             :   // initialize the statusmap to dead by default
     338        4248 :   if (statusMap) *statusMap = AliMUONPadStatusMapMaker::SelfDeadMask();
     339             : 
     340             :   // First a protection against bad input parameters
     341        1416 :   AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
     342        1416 :   if (!de) return kFALSE; // not existing DE
     343        1416 :   if (!de->IsExistingChannel(manuId,manuChannel))
     344             :   {
     345             :     // non-existing (might happen when we get parity errors in read-out
     346             :     // that spoils the manuId
     347           0 :     return kFALSE;
     348             :   }
     349        1416 :   if (!de->IsConnectedChannel(manuId,manuChannel))
     350             :   {
     351             :     // existing (in read-out), but not connected channel
     352           0 :     return kFALSE;
     353             :   }
     354             :   
     355             :   // ok, now we have a valid channel number, so let's see if that pad
     356             :   // behaves or not ;-)
     357             :   
     358        1416 :   Int_t sm = StatusMap(detElemId,manuId,manuChannel);
     359             :   
     360        2832 :   if (statusMap) *statusMap = sm;
     361             :   
     362        1416 :   if ( ( sm & AliMUONPadStatusMapMaker::SelfDeadMask() ) != 0 ) 
     363             :   {
     364             :     // pad itself is bad (not testing its neighbours at this stage)
     365           0 :     return kFALSE;
     366             :   }
     367             :   
     368        1416 :   return kTRUE;
     369        1416 : }
     370             : 
     371             : //_____________________________________________________________________________
     372             : Int_t 
     373             : AliMUONDigitCalibrator::PadStatus(Int_t detElemId, Int_t manuId, Int_t manuChannel) const
     374             : {
     375             :   /// Return the status of the given pad
     376           0 :   return fStatusMaker->PadStatus(detElemId,manuId,manuChannel);
     377             : }
     378             : 
     379             : //_____________________________________________________________________________
     380             : Int_t 
     381             : AliMUONDigitCalibrator::StatusMap(Int_t detElemId, Int_t manuId, Int_t manuChannel) const
     382             : {
     383             :   /// Return the status map of the given pad
     384        2832 :   return fStatusMapMaker->StatusMap(detElemId,manuId,manuChannel);
     385             :   
     386             : }
     387             : 

Generated by: LCOV version 1.11