New digitizer, not deriving from MUONDigitizer and doing decalibration of
authorivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 31 Jan 2006 16:39:43 +0000 (16:39 +0000)
committerivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 31 Jan 2006 16:39:43 +0000 (16:39 +0000)
digits.
(Laurent)

MUON/AliMUONDigitizerV3.cxx [new file with mode: 0644]
MUON/AliMUONDigitizerV3.h [new file with mode: 0644]

diff --git a/MUON/AliMUONDigitizerV3.cxx b/MUON/AliMUONDigitizerV3.cxx
new file mode 100644 (file)
index 0000000..2199cd6
--- /dev/null
@@ -0,0 +1,443 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+
+// $Id$
+
+#include "AliMUONDigitizerV3.h"
+
+#include "AliLog.h"
+#include "AliMUONCalibrationData.h"
+#include "AliMUONChamber.h"
+#include "AliMUONConstants.h"
+#include "AliMUONData.h"
+#include "AliMUONDigit.h"
+#include "AliMUONTriggerDecisionV1.h"
+//#include "AliMUONTriggerElectronics.h"
+#include "AliMUONCalibParam.h"
+#include "AliMpDEManager.h"
+#include "AliMpStationType.h"
+#include "AliRun.h"
+#include "AliRunDigitizer.h"
+#include "AliRunLoader.h"
+#include "Riostream.h"
+#include "TRandom.h"
+#include "TString.h"
+
+ClassImp(AliMUONDigitizerV3)
+
+//_____________________________________________________________________________
+AliMUONDigitizerV3::AliMUONDigitizerV3(AliRunDigitizer* manager, 
+                                       ETriggerCodeVersion triggerCodeVersion)
+: AliDigitizer(manager),
+fZeroSuppression(6),
+fSaturation(3000),
+fIsInitialized(kFALSE),
+fOutputData(0x0),
+fCalibrationData(0x0),
+fTriggerProcessor(0x0),
+fTriggerCodeVersion(triggerCodeVersion)
+{
+  AliDebug(1,Form("AliRunDigitizer=%p",fManager));
+}
+
+//_____________________________________________________________________________
+AliMUONDigitizerV3::~AliMUONDigitizerV3()
+{
+  AliDebug(1,"dtor");
+  delete fOutputData;
+  delete fCalibrationData;
+  delete fTriggerProcessor;
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONDigitizerV3::ApplyResponseToDigit(AliMUONDigit& digit)
+{
+  // For trigger digits, simply sets the digit's charge to 0 or 1.
+  //
+  // For tracking digits, starting from an ideal digit's charge, we :
+  //
+  // - add some noise (thus leading to a realistic charge)
+  // - divide by a gain (thus decalibrating the digit)
+  // - add a pedestal (thus decalibrating the digit)
+  // - sets the signal to zero if below ZeroSuppression() level (thus simulating
+  //   zero suppression).
+  //
+  
+  Int_t detElemId = digit.DetElemId();
+  AliMpStationType stationType = AliMpDEManager::GetStationType(detElemId);
+  if ( stationType == kStationTrigger )
+  {
+    if ( digit.Signal() > 0  )
+    {
+      digit.SetSignal(1);
+    }
+    else
+    {
+      digit.SetSignal(0);
+    }
+    return;    
+  }
+  
+  // The following is for tracking digits only.
+  
+  Int_t manuId = digit.ManuId();
+  Int_t manuChannel = digit.ManuChannel();
+  
+  AliMUONCalibParam* pedestal = fCalibrationData->Pedestal(detElemId,manuId,manuChannel);
+  if (!pedestal)
+  {
+    AliFatal(Form("Could not get pedestal for DE=%d manuId=%d manuChannel=%d",
+                  detElemId,manuId,manuChannel));    
+  }
+  Float_t adc_noise = gRandom->Gaus(0.0,pedestal->Sigma());
+  
+  AliMUONCalibParam* gain = fCalibrationData->Gain(detElemId,manuId,manuChannel);
+  if (!gain)
+  {
+    AliFatal(Form("Could not get gain for DE=%d manuId=%d manuChannel=%d",
+                  detElemId,manuId,manuChannel));    
+  }
+  
+  Float_t signal_noise = adc_noise*gain->Mean();
+  
+  Float_t signal = digit.Signal() + signal_noise;
+  Int_t adc;
+  
+  if ( signal > fSaturation )
+  {
+    adc = fSaturation;
+    digit.Saturated(kTRUE);
+  }
+  else
+  {
+    if ( gain->Mean() < 1E-6 )
+    {
+      AliFatal(Form("Got a too small gain %e for DE=%d manuId=%d manuChannel=%d",
+                    gain->Mean(),detElemId,manuId,manuChannel));
+    }
+    adc = TMath::Nint( signal / gain->Mean() + pedestal->Mean() );
+    
+    if ( adc <= pedestal->Mean() + 3.0*pedestal->Sigma() ) 
+    {
+      adc = 0;
+    }
+  }
+  digit.SetPhysicsSignal(TMath::Nint(signal));
+  digit.SetSignal(adc);
+  digit.SetADC(adc);
+}
+
+//_____________________________________________________________________________
+void
+AliMUONDigitizerV3::ApplyResponse()
+{
+  for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
+       {
+    TClonesArray* digits = fOutputData->Digits(ich);
+    Int_t n = digits->GetEntriesFast();
+    for ( Int_t i = 0; i < n; ++i )
+    {
+      AliMUONDigit* d = static_cast<AliMUONDigit*>(digits->UncheckedAt(i));
+      ApplyResponseToDigit(*d);
+      if ( d->Signal() <= 0 )
+      {
+        digits->RemoveAt(i);
+      }
+    }
+  }    
+  
+  for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
+       {
+    fOutputData->Digits(ich)->Compress();
+  }
+}
+
+//_____________________________________________________________________________
+void
+AliMUONDigitizerV3::AddOrUpdateDigit(TClonesArray& array, 
+                                     const AliMUONDigit& digit)
+{
+  Int_t ix = FindDigitIndex(array,digit);
+  
+  if (ix>=0)
+  {
+    AliMUONDigit* d = static_cast<AliMUONDigit*>(array.UncheckedAt(ix));
+    Bool_t ok = MergeDigits(digit,*d);
+    if (!ok)
+    {
+      AliError("Digits are not mergeable !");
+    }
+    else
+    {
+      new(array[ix]) AliMUONDigit(*d);
+    }
+  }
+  else
+  {
+    ix = array.GetLast() + 1;
+    new(array[ix]) AliMUONDigit(digit);
+  }
+  
+}
+
+//_____________________________________________________________________________
+void
+AliMUONDigitizerV3::Exec(Option_t*)
+{
+  AliDebug(1, "Running digitizer.");
+  
+  if ( fManager->GetNinputs() == 0 )
+  {
+    AliWarning("No input set. Nothing to do.");
+    return;
+  }
+  
+  if ( !fIsInitialized )
+  {
+    AliError("Not initialized. Cannot perform the work. Sorry");
+    return;
+  }
+  
+  Int_t nInputFiles = fManager->GetNinputs();
+  
+  if ( fOutputData->TreeD() == 0x0 )
+  {
+    AliDebug(1,"Calling MakeDigitsContainer");
+    fOutputData->GetLoader()->MakeDigitsContainer();
+  }
+  fOutputData->MakeBranch("D,GLT");
+  fOutputData->SetTreeAddress("D,GLT");
+  
+  // Loop over all the input files, and merge the sdigits found in those
+  // files.
+  for ( Int_t iFile = 0; iFile < nInputFiles; ++iFile )
+  {    
+    AliMUONData* inputData = GetDataAccess(fManager->GetInputFolderName(iFile));
+    if (!inputData)
+    {
+      AliFatal(Form("Could not get access to input file #%d",iFile));
+    }
+    AliDebug(1,Form("inputData=%p",inputData));
+    //FIXME: what about the fMask ???
+    inputData->GetLoader()->LoadSDigits("READ");
+    TTree* treeS = inputData->GetLoader()->TreeS();
+    AliDebug(1,Form("TreeS=%p",treeS));
+    inputData->SetTreeAddress("S");
+    inputData->GetSDigits();
+    MergeWithSDigits(*fOutputData,*inputData);
+    inputData->ResetSDigits();
+    inputData->GetLoader()->UnloadSDigits();
+    delete inputData;
+  }
+  
+  // At this point, we do have digit arrays (one per chamber) which contains 
+  // the merging of all the sdigits of the input file(s).
+  // We now massage them to apply the detector response, i.e. this
+  // is here that we do the "digitization" work.
+  
+  ApplyResponse();
+  
+  // 
+  
+  // We generate the global and local trigger decisions.
+  fTriggerProcessor->ExecuteTask();
+  
+  // Fill the output treeD
+  fOutputData->Fill("D,GLT");
+  
+  // Write to the output tree(D).
+  // Please note that as GlobalTrigger, LocalTrigger and Digits are in the same
+  // tree (=TreeD) in different branches, this WriteDigits in fact writes all of 
+  // the 3 branches.
+  fOutputData->GetLoader()->WriteDigits("OVERWRITE");
+  
+  // Finally, we clean up after ourselves.
+  fOutputData->ResetDigits();
+  fOutputData->ResetTrigger();
+  fOutputData->GetLoader()->UnloadDigits();
+}
+
+//_____________________________________________________________________________
+Int_t
+AliMUONDigitizerV3::FindDigitIndex(TClonesArray& array, const AliMUONDigit& digit)
+{
+  // FIXME: this is of course not the best implementation you can think of.
+  // Reconsider the use of hit/digit map...
+  Int_t n = array.GetEntriesFast();
+  for ( Int_t i = 0; i < n; ++i )
+  {
+    AliMUONDigit* d = static_cast<AliMUONDigit*>(array.UncheckedAt(i));
+    if ( d->DetElemId() == digit.DetElemId() &&
+         d->PadX() == digit.PadX() &&
+         d->PadY() == digit.PadY() && 
+         d->Cathode() == digit.Cathode() )
+    {
+      return i;
+    }
+  }
+  return -1;
+}
+
+//_____________________________________________________________________________
+AliMUONData* 
+AliMUONDigitizerV3::GetDataAccess(const TString& folderName)
+{
+  AliDebug(1,Form("Getting access to folder %s",folderName.Data()));
+  AliRunLoader* runLoader = AliRunLoader::GetRunLoader(folderName);
+  if (!runLoader)
+  {
+    AliError(Form("Could not get RunLoader from folder %s",folderName.Data()));
+    return 0x0;
+  }
+  AliLoader* loader = static_cast<AliLoader*>(runLoader->GetLoader("MUONLoader"));
+  if (!loader)
+  {
+    AliError(Form("Could not get MuonLoader from folder %s",folderName.Data()));
+    return 0x0;
+  }
+  AliMUONData* data = new AliMUONData(loader,"MUON","MUONDataForDigitOutput");
+  AliDebug(1,Form("AliMUONData=%p loader=%p",data,loader));
+  return data;
+}
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONDigitizerV3::Init()
+{
+  AliDebug(1,"");
+  
+  if ( fIsInitialized )
+  {
+    AliError("Object already initialized.");
+    return kFALSE;
+  }
+  
+  if (!fManager)
+  {
+    AliError("fManager is null !");
+    return kFALSE;
+  }
+  
+  fOutputData = GetDataAccess(fManager->GetOutputFolderName());
+  if (!fOutputData)
+  {
+    AliError("Can not perform digitization. I'm sorry");
+    return kFALSE;
+  }
+  AliDebug(1,Form("fOutputData=%p",fOutputData));
+  
+  AliRunLoader* runLoader = fOutputData->GetLoader()->GetRunLoader();
+  AliRun* galice = runLoader->GetAliRun();  
+  Int_t runnumber = galice->GetRunNumber();
+  
+  fCalibrationData = new AliMUONCalibrationData(runnumber);
+  
+  switch (fTriggerCodeVersion)
+  {
+    case kTriggerDecision:
+      fTriggerProcessor = new AliMUONTriggerDecisionV1(fOutputData);
+      break;
+    case kTriggerElectronics:
+      AliFatal("Implement me!");
+//      fTrigger = new AliMUONTriggerElectronics(fOutputData);
+      break;
+    default:
+      AliFatal("Unknown trigger processor type");
+      break;
+  }
+  
+  fIsInitialized = kTRUE;
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONDigitizerV3::MergeDigits(const AliMUONDigit& src, AliMUONDigit& srcAndDest)
+{
+  AliDebug(1,"Merging the following digits:");
+  StdoutToAliDebug(1,src.Print(););
+  StdoutToAliDebug(1,srcAndDest.Print(););
+  
+  Bool_t check = ( src.DetElemId() == srcAndDest.DetElemId() &&
+                   src.PadX() == srcAndDest.PadX() &&
+                   src.PadY() == srcAndDest.PadY() &&
+                   src.Cathode() == srcAndDest.Cathode() );
+  if (!check)
+  {
+    return kFALSE;
+  }
+  
+  srcAndDest.AddSignal(src.Signal());
+  srcAndDest.AddPhysicsSignal(src.Physics());
+  StdoutToAliDebug(1,cout << "result:"; srcAndDest.Print(););
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONDigitizerV3::MergeWithSDigits(AliMUONData& outputData, 
+                                     const AliMUONData& inputData)
+{
+  AliDebug(1,"");
+  
+       for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
+       {
+    TClonesArray* iDigits = inputData.SDigits(ich); 
+    TClonesArray* oDigits = outputData.Digits(ich);
+    if (!iDigits)
+    {
+      AliError(Form("Could not get sdigits for ich=%d",ich));
+      return;
+    }
+    Int_t nSDigits = iDigits->GetEntriesFast();
+    for ( Int_t k = 0; k < nSDigits; ++k )
+               {
+                       AliMUONDigit* sdigit = static_cast<AliMUONDigit*>(iDigits->UncheckedAt(k));
+      // FIXME: Merging logic should go here.
+      // For testing, only put the digit in the output.
+      if (!sdigit)
+      {
+        AliError(Form("Could not get sdigit for ich=%d and k=%d",ich,k));
+      }
+      else
+      {
+        AddOrUpdateDigit(*oDigits,*sdigit);
+      }
+               }   
+  }
+}
+
+//------------------------------------------------------------------------
+//void AliMUONDigitizerv2::FillTriggerOutput()
+//{
+//  // Derived to fill TreeD and resets the trigger array in fMUONData.
+//  
+//     AliDebug(3,"Filling trees with trigger.");
+//     fMUONData->Fill("GLT");
+//     fMUONData->ResetTrigger();
+//}
+//
+//------------------------------------------------------------------------
+//void AliMUONDigitizerv2::CreateTrigger()
+//{
+//  fMUONData->MakeBranch("GLT");
+//  fMUONData->SetTreeAddress("GLT");
+//  fTrigDec->Digits2Trigger(); 
+//  FillTriggerOutput();       
+//  
+//}
+
diff --git a/MUON/AliMUONDigitizerV3.h b/MUON/AliMUONDigitizerV3.h
new file mode 100644 (file)
index 0000000..905fb00
--- /dev/null
@@ -0,0 +1,72 @@
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice                               */
+
+// $Id$
+
+/// \ingroup sim
+/// \class AliMUONDigitizerV3
+/// \brief New digitizer, not deriving from MUONDigitizer and doing
+/// decalibration of digits
+/// 
+/// \author Laurent Aphecetche
+
+#ifndef ALIMUONDIGITIZERV3_H
+#define ALIMUONDIGITIZERV3_H
+
+#ifndef ALIDIGITIZER_H
+#include "AliDigitizer.h"
+#endif
+
+class AliMUONCalibrationData;
+class AliMUONData;
+class AliMUONDigit;
+class TClonesArray;
+class TString;
+
+class AliMUONDigitizerV3 : public AliDigitizer
+{
+public:
+  enum ETriggerCodeVersion
+  {
+    kTriggerDecision=-1,
+    kTriggerElectronics
+  };
+  
+  AliMUONDigitizerV3(AliRunDigitizer* manager=0, 
+                     ETriggerCodeVersion=kTriggerDecision);
+  virtual ~AliMUONDigitizerV3();
+
+  virtual void Exec(Option_t* opt="");
+  
+  virtual Bool_t Init();
+
+private:
+    
+  void AddOrUpdateDigit(TClonesArray& array, 
+                        const AliMUONDigit& digit);
+    
+  void ApplyResponse();
+
+  void ApplyResponseToDigit(AliMUONDigit& digit);
+
+  Int_t FindDigitIndex(TClonesArray& array, const AliMUONDigit& digit);
+
+  AliMUONData* GetDataAccess(const TString& folderName);
+
+  Bool_t MergeDigits(const AliMUONDigit& src, AliMUONDigit& srcAndDest);
+
+  void MergeWithSDigits(AliMUONData& outputData, const AliMUONData& inputData);
+  
+private:
+  Int_t fZeroSuppression;
+  Int_t fSaturation;
+  Bool_t fIsInitialized; 
+  AliMUONData* fOutputData; //!
+  AliMUONCalibrationData* fCalibrationData; //!
+  TTask* fTriggerProcessor;
+  ETriggerCodeVersion fTriggerCodeVersion;
+  
+  ClassDef(AliMUONDigitizerV3,1) // 
+};
+
+#endif