Added new method DisIntegrate(AliMUONHit&, TList& digits) to replace the one in
authorivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 31 Jan 2006 16:45:34 +0000 (16:45 +0000)
committerivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 31 Jan 2006 16:45:34 +0000 (16:45 +0000)
AliMUONChamber (which is still there until we remove the old digitizers).
Note that those new methods rely on the new segmentations, i.e. for Trigger it
can only work with FactoryV4.
(Laurent)

MUON/AliMUONResponse.cxx
MUON/AliMUONResponse.h
MUON/AliMUONResponseTrigger.cxx
MUON/AliMUONResponseTrigger.h
MUON/AliMUONResponseV0.cxx
MUON/AliMUONResponseV0.h

index 190922c..f99c472 100644 (file)
@@ -17,6 +17,9 @@
 
 #include "AliMUONResponse.h"
 
+#include "AliLog.h"
+#include "TList.h"
+
 ClassImp(AliMUONResponse)
 
 AliMUONResponse::AliMUONResponse()
@@ -31,3 +34,11 @@ AliMUONResponse::~AliMUONResponse()
 // Destructor
 }
 
+//_____________________________________________________________________________
+void
+AliMUONResponse::DisIntegrate(const AliMUONHit&, TList& digits)
+{
+  digits.Clear();
+  AliError("Not implemented in this base class");
+}
+
index 7c4a796..50c49dd 100644 (file)
 /// \class AliMUONResponse
 /// \brief Chamber response base class
 
-#include <TObject.h>
+#ifndef ROOT_TObject
+#include "TObject.h"
+#endif
 
-class TF1;
+class AliMUONDigit;
 class AliMUONGeometrySegmentation;
+class AliMUONHit;
 class AliMUONTransientDigit;
+class TF1;
+class TList;
 
 class AliMUONResponse : public TObject 
 {
@@ -70,6 +75,10 @@ class AliMUONResponse : public TObject
     //virtual Int_t DigitResponse(Int_t )                {return kTRUE;}
     virtual Int_t DigitResponse(Int_t , 
                                 AliMUONTransientDigit* ) {return kTRUE;}
+    
+    /// Go from one hit to several digits, applying charge spreading.
+    virtual void DisIntegrate(const AliMUONHit& hit, TList& digits);
+
     // 
     ClassDef(AliMUONResponse,1) // Chamber response virtual base class 
 };
index cf3c3c3..d444bd6 100644 (file)
 
 #include "AliMUONResponseTrigger.h"
 
+#include "AliLog.h"
+#include "AliMUON.h"
+#include "AliMUONDigit.h"
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONHit.h"
+#include "AliMUONSegmentation.h"
+#include "AliMpPad.h"
+#include "AliMpPlaneType.h"
+#include "AliMpVSegmentation.h"
+#include "AliRun.h"
+#include "TList.h"
+#include "AliMUONTriggerSegmentationV2.h"
+
 ClassImp(AliMUONResponseTrigger)
 
+namespace
+{
+  Float_t TOFLIMIT = 75E-9;
+
+  AliMUON* muon()
+  {
+    return static_cast<AliMUON*>(gAlice->GetModule("MUON"));
+  }
+
+  void Global2Local(Int_t detElemId, Double_t xg, Double_t yg, Double_t zg,
+                  Double_t& xl, Double_t& yl, Double_t& zl)
+  {  
+  // ideally should be : 
+  // Double_t x,y,z;
+  // AliMUONGeometry::Global2Local(detElemId,xg,yg,zg,x,y,z);
+  // but while waiting for this geometry singleton, let's go through
+  // AliMUON still.
+  
+    const AliMUONGeometryTransformer* transformer = muon()->GetGeometryTransformer();
+    transformer->Global2Local(detElemId,xg,yg,zg,xl,yl,zl);
+  }
+
+  AliMUONSegmentation* Segmentation()
+  {
+    static AliMUONSegmentation* segmentation = muon()->GetSegmentation();
+    return segmentation;
+  }
+}
+
 //------------------------------------------------------------------   
 AliMUONResponseTrigger::AliMUONResponseTrigger()
   : AliMUONResponse()
@@ -40,6 +82,84 @@ Int_t AliMUONResponseTrigger::DigitResponse(Int_t digit,
 }
 
 
+//_____________________________________________________________________________
+void 
+AliMUONResponseTrigger::DisIntegrate(const AliMUONHit& hit, TList& digits)
+{
+  //
+  // Generate 2 digits (one on each cathode) from 1 hit, i.e. no cluster-size
+  // generation (simplest response case).
+  //
+  
+  digits.Clear();
+  
+  Float_t xhit = hit.X();
+  Float_t yhit = hit.Y();
+  Float_t zhit = 0; // FIXME : should it be hit.Z() ?
+  Int_t detElemId = hit.DetElemId();  
+  
+  Double_t x,y,z;
+  Global2Local(detElemId,xhit,yhit,zhit,x,y,z);
+  
+  Float_t tof = hit.Age();
+  Int_t twentyNano(100);
+  if (tof<TOFLIMIT)
+  {
+    twentyNano=1;
+  }
+  
+  for ( Int_t cath = 0; cath < 2; ++cath )
+  {
+    const AliMpVSegmentation* seg = Segmentation()->GetMpSegmentation(detElemId,cath);
+    
+    AliMpPad pad = seg->PadByPosition(TVector2(x,y),kFALSE);
+    Int_t ix = pad.GetIndices().GetFirst();
+    Int_t iy = pad.GetIndices().GetSecond();
+    
+    AliDebug(1,Form("xhit,yhit=%e,%e lx,ly,lz=%e,%e,%e ix,iy=%d,%d",
+                    xhit,yhit,x,y,z,ix,iy));
+    
+    if ( !pad.IsValid() )
+    {
+      AliWarning(Form("hit w/o strip %d-%d xhit,yhit=%e,%e local x,y,z "
+                      "%e,%e,%e ix,iy=%d,%d",detElemId,
+                      cath,
+                      xhit,yhit,x,y,z,ix,iy));
+      continue;
+    }
+    AliMUONDigit* d = new AliMUONDigit;
+    d->SetDetElemId(detElemId);
+    //FIXME: >> the following code to get the ixGlo and iyGlo is a bad hack 
+    // because trigger has not yet switched to local numbering of its indices !
+    // We should be able to use directly the (local) ix,iy from the pad !
+    const AliMUONTriggerSegmentationV2* old = 
+      dynamic_cast<const AliMUONTriggerSegmentationV2*>
+        (Segmentation()->GetDESegmentation(detElemId,cath));
+    if ( !old )
+    {
+      AliFatal("Got a wrong TriggerSegmentation object! Check that!");
+    }
+    Int_t ixGlo;
+    Int_t iyGlo;
+    old->ILoc2IGlo(ix,iy,ixGlo,iyGlo);
+    if ( xhit < 0 ) ixGlo = -ixGlo;
+    // << end of bad hack.
+    d->SetPadX(ixGlo);
+    d->SetPadY(iyGlo);
+    d->SetSignal(twentyNano);
+    d->AddPhysicsSignal(d->Signal());
+    d->SetCathode(cath);
+    digits.Add(d);   
+ //   AliDebug(1,Form("Adding digit DE %d Cathode %d (%d,%d) signal %d",
+//                    detElemId,cath,ixGlo,iyGlo,twentyNano));
+  }
+  
+//  StdoutToAliDebug(1,digits.Print();); 
+//  AliDebug(1,Form("Number of digits for detelem %d track %d : %d",
+//                  hit.DetElemId(),hit.Track(),digits.GetSize()));
+//   
+}
+
 
 
 
index 868cb51..67758e0 100644 (file)
@@ -24,6 +24,8 @@ class AliMUONResponseTrigger : public AliMUONResponse
   // Set the GenerCluster parameter       
   virtual Int_t SetGenerCluster(){return 0;}
 
+  virtual void DisIntegrate(const AliMUONHit& hit, TList& digits);
+  
   ClassDef(AliMUONResponseTrigger,1) // Implementation of RPC response
     
 };
index a820fcf..7f0a255 100644 (file)
 
 /* $Id$ */
 
-#include <TMath.h>
-#include <TRandom.h>
 
 #include "AliMUONResponseV0.h"
-#include "AliMUONGeometrySegmentation.h"
+
 #include "AliLog.h"
+#include "AliMUON.h"
+#include "AliMUONConstants.h"
+#include "AliMUONDigit.h"
+#include "AliMUONGeometrySegmentation.h"
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONHit.h"
+#include "AliMUONSegmentation.h"
+#include "AliMpArea.h"
+#include "AliMpDEManager.h"
+#include "AliMpPlaneType.h"
+#include "AliMpStationType.h"
+#include "AliMpVPadIterator.h"
+#include "AliMpVSegmentation.h"
+#include "AliRun.h"
+#include "Riostream.h"
+#include "TVector2.h"
+#include <TMath.h>
+#include <TRandom.h>
 
 ClassImp(AliMUONResponseV0)
        
+AliMUON* muon()
+{
+    return static_cast<AliMUON*>(gAlice->GetModule("MUON"));
+}
+
+void Global2Local(Int_t detElemId, Double_t xg, Double_t yg, Double_t zg,
+                  Double_t& xl, Double_t& yl, Double_t& zl)
+{  
+  // ideally should be : 
+  // Double_t x,y,z;
+  // AliMUONGeometry::Global2Local(detElemId,xg,yg,zg,x,y,z);
+  // but while waiting for this geometry singleton, let's go through
+  // AliMUON still.
+  
+  const AliMUONGeometryTransformer* transformer = muon()->GetGeometryTransformer();
+  transformer->Global2Local(detElemId,xg,yg,zg,xl,yl,zl);
+}
+
+AliMUONSegmentation* Segmentation()
+{
+  static AliMUONSegmentation* segmentation = muon()->GetSegmentation();
+  return segmentation;
+}
+
 //__________________________________________________________________________
 AliMUONResponseV0::AliMUONResponseV0()
-  : AliMUONResponse()
+  : AliMUONResponse(),
+  fChargeSlope(0.0),
+  fChargeSpreadX(0.0),
+  fChargeSpreadY(0.0),
+  fSigmaIntegration(0.0),
+  fMaxAdc(0),
+  fZeroSuppression(0),
+  fChargeCorrel(0.0),
+  fMathieson(new AliMUONMathieson),
+  fChargeThreshold(1e-4)
 {
-// Default constructor
-
-  fMathieson = new AliMUONMathieson();
-  fChargeCorrel = 0;
+    // Normal constructor
+    AliDebug(1,Form("Default ctor"));
 }
 
    //_________________________________________________________________________
@@ -46,6 +93,7 @@ AliMUONResponseV0::AliMUONResponseV0(const AliMUONResponseV0& rhs)
    //__________________________________________________________________________
 AliMUONResponseV0::~AliMUONResponseV0()
 {
+  AliDebug(1,"");
   delete fMathieson;
 }
 
@@ -61,6 +109,31 @@ AliMUONResponseV0& AliMUONResponseV0::operator = (const AliMUONResponseV0& rhs)
   return *this;  
 }
 
+//______________________________________________________________________________
+void
+AliMUONResponseV0::Print(Option_t*) const
+{
+  cout << " ChargeSlope=" << fChargeSlope
+    << " ChargeSpreadX,Y=" << fChargeSpreadX
+    << fChargeSpreadY
+    << " ChargeCorrelation=" << fChargeCorrel
+    << endl;
+  
+//Float_t fChargeSlope;              // Slope of the charge distribution
+//Float_t fChargeSpreadX;            // Width of the charge distribution in x
+//Float_t fChargeSpreadY;            // Width of the charge distribution in y
+//Float_t fSigmaIntegration;         // Number of sigma's used for charge distribution
+//Int_t   fMaxAdc;                   // Maximum ADC channel
+//Int_t   fSaturation;               // Pad saturation in ADC channel
+//Int_t   fZeroSuppression;          // Zero suppression threshold
+//Float_t fChargeCorrel;             // amplitude of charge correlation on 2 cathods
+//                                   // is RMS of ln(q1/q2)
+//AliMUONMathieson* fMathieson;      // pointer to mathieson fct
+//Float_t fChargeThreshold;          // Charges below this threshold are = 0  
+//
+
+}
+
   //__________________________________________________________________________
 void AliMUONResponseV0::SetSqrtKx3AndDeriveKx2Kx4(Float_t SqrtKx3)
 {
@@ -103,28 +176,144 @@ Float_t AliMUONResponseV0::IntXY(Int_t idDE, AliMUONGeometrySegmentation* segmen
 
   return fMathieson->IntXY(idDE, segmentation);
 }
+
+
   //-------------------------------------------
 Int_t  AliMUONResponseV0::DigitResponse(Int_t digit, AliMUONTransientDigit* /*where*/)
 {
+//  FIXME : AliFatal("put the pedestal adding here!");
     // add white noise and do zero-suppression and signal truncation
 //     Float_t meanNoise = gRandom->Gaus(1, 0.2);
     // correct noise for slat chambers;
     // one more field to add to AliMUONResponseV0 to allow different noises ????
-    Float_t meanNoise = gRandom->Gaus(1., 0.2);
-    Float_t noise     = gRandom->Gaus(0., meanNoise);
+//    Float_t meanNoise = gRandom->Gaus(1., 0.2);
+//    Float_t noise     = gRandom->Gaus(0., meanNoise);
+    Float_t noise     = gRandom->Gaus(0., 1.0);
     digit += TMath::Nint(noise); 
     if ( digit <= ZeroSuppression()) digit = 0;
     // if ( digit >  MaxAdc())          digit=MaxAdc();
-    if ( digit >  Saturation())          digit=Saturation();
+    if ( digit >  Saturation())          
+    {
+      digit=Saturation();
+    }
 
     return digit;
 }
 
+//_____________________________________________________________________________
+Float_t
+AliMUONResponseV0::GetAnod(Float_t x) const
+{
+  //
+  // Return wire coordinate closest to x.
+  //
+  Int_t n = Int_t(x/Pitch());
+  Float_t wire = (x>0) ? n+0.5 : n-0.5;
+  return Pitch()*wire;
+}
 
+//______________________________________________________________________________
+void 
+AliMUONResponseV0::DisIntegrate(const AliMUONHit& hit, TList& digits)
+{
+  //
+  //
+  //
+  
+  digits.Clear();
+  
+  Int_t detElemId = hit.DetElemId();
+  
+  //
+  // Width of the integration area
+  //
+  Double_t dx = SigmaIntegration()*ChargeSpreadX();
+  Double_t dy = SigmaIntegration()*ChargeSpreadY();
+  
+  // Use that (dx,dy) to specify the area upon which
+  // we will iterate to spread charge into.
+  Double_t x,y,z;
+  Global2Local(detElemId,hit.X(),hit.Y(),hit.Z(),x,y,z);
+  x = GetAnod(x);
+  TVector2 hitPosition(x,y);
+  AliMpArea area(hitPosition,TVector2(dx,dy));
+  
+  //
+  // Get pulse height from energy loss
+  Float_t qtot = IntPH(hit.Eloss());
+  
+  Float_t currentCorrel = TMath::Exp(gRandom->Gaus(0.0,ChargeCorrel()/2.0));
 
+  AliDebug(4,Form("DE=%d eloss=%e x,y,z=%e,%e,%e fCurrentCorrel=%e dx,dy=%e,%e",
+                  detElemId,hit.Eloss(),hit.X(),hit.Y(),hit.Z(),
+                  currentCorrel,dx,dy));
+      
+  AliMpStationType station = AliMpDEManager::GetStationType(detElemId);
+  
+  Int_t intOffset = 1;
+  if ( station == kStation1 || station == kStation2 )
+  {
+    intOffset = 0;
+  }
+  
+  for ( Int_t cath = 0; cath < 2; ++cath )
+  {
+    Float_t qcath = qtot * ( cath == 0 ? currentCorrel : 1.0/currentCorrel);
+    
+    AliDebug(4,Form("i=%d qtot=%e qcath=%e",cath+1,qtot,qcath));      
+    // Get an iterator to loop over pads, within the given area.
+      const AliMpVSegmentation* seg = 
+        Segmentation()->GetMpSegmentation(detElemId,cath);
+      AliMpVPadIterator* it = seg->CreateIterator(area);
+      
+      if (!it)
+      {
+        AliError(Form("Could not get iterator for detElemId %d",detElemId));
+        return;
+      }
+      
+      // Start loop over pads.
+      it->First();
+      while ( !it->IsDone() )
+      {
+        AliMpPad pad = it->CurrentItem();      
+        TVector2 lowerLeft(hitPosition-pad.Position()-pad.Dimensions());
+        TVector2 upperRight(lowerLeft + pad.Dimensions()*2.0);
+        Float_t qp = TMath::Abs(fMathieson->IntXY(lowerLeft.X(),lowerLeft.Y(),
+                                                  upperRight.X(),upperRight.Y()));
 
 
-
+        Int_t icharge = Int_t(qp*qcath);
+        
+        if ( qp > fChargeThreshold )
+        {
+          AliDebug(4,Form("ix,iy=%d,%d qp=%e",
+                          pad.GetIndices().GetFirst()+intOffset,
+                          pad.GetIndices().GetSecond()+intOffset,
+                          qp));
+          AliMUONDigit* d = new AliMUONDigit;
+          d->SetDetElemId(detElemId);
+          d->SetPadX(pad.GetIndices().GetFirst()+intOffset);
+          d->SetPadY(pad.GetIndices().GetSecond()+intOffset);
+          d->SetSignal(icharge);
+          d->AddPhysicsSignal(d->Signal());
+          d->SetCathode(cath);
+          Int_t manuId = pad.GetLocation().GetFirst();
+          Int_t manuChannel = pad.GetLocation().GetSecond();
+          AliMpPlaneType planeType = AliMpDEManager::GetPlaneType(detElemId,cath);
+          if ( planeType == kNonBendingPlane )
+          {
+            // FIXME: this should not be there, but integrated in the mapping files directly.
+            manuId |= (1<<11);
+          }
+          d->SetElectronics(manuId,manuChannel);
+          digits.Add(d);   
+        }       
+        it->Next();
+      }
+      delete it;
+  }
+}
 
 
 
index 4333caa..3ed5d43 100644 (file)
@@ -16,7 +16,7 @@
 class AliMUONResponseV0 : public AliMUONResponse
 {
  public:
-    AliMUONResponseV0();
+  AliMUONResponseV0();
     virtual ~AliMUONResponseV0();
     //
     // Configuration methods
@@ -87,7 +87,12 @@ class AliMUONResponseV0 : public AliMUONResponse
     // Noise, zero-suppression, adc saturation
     virtual Int_t DigitResponse(Int_t digit, AliMUONTransientDigit* where);
 
-    ClassDef(AliMUONResponseV0,1) // Implementation of Mathieson response
+    virtual Float_t GetAnod(Float_t x) const;
+    
+    virtual void DisIntegrate(const AliMUONHit& hit, TList& digits);
+    
+    virtual void Print(Option_t* opt="") const;
+     
  protected:
     AliMUONResponseV0(const AliMUONResponseV0& rhs);
     AliMUONResponseV0& operator = (const AliMUONResponseV0& rhs);
@@ -102,8 +107,11 @@ class AliMUONResponseV0 : public AliMUONResponse
     Float_t fChargeCorrel;             // amplitude of charge correlation on 2 cathods
                                        // is RMS of ln(q1/q2)
     AliMUONMathieson* fMathieson;      // pointer to mathieson fct
-
+    Float_t fChargeThreshold;          // Charges below this threshold are = 0  
+    
+    ClassDef(AliMUONResponseV0,2) // Implementation of detector response
 };
+
 #endif