ClassImp(AliMUONDigit)
+namespace
+{
+ const UInt_t SATURATEDFLAG = 0x1;
+}
+
//_____________________________________________________________________________
AliMUONDigit::AliMUONDigit()
-: TObject(),
-fPadX(0),
-fPadY(0),
-fCathode(0),
-fSignal(0),
-fPhysics(0),
-fHit(0),
-fDetElemId(0),
+:
+TObject(),
+fDetElemId(-1),
fManuId(-1),
fManuChannel(-1),
+fSignal(0),
+fPadX(-1),
+fPadY(-1),
+fCathode(-1),
fADC(0),
-fIsSaturated(kFALSE)
+fFlags(0),
+fNtracks(0),
+fTcharges(0x0),
+fTracks(0x0),
+fPhysics(0),
+fHit(0)
{
+ //
// Default constructor
-
- for ( Int_t i=0; i<kMAXTRACKS; ++i )
- {
- fTcharges[i] = 0;
- fTracks[i] = 0;
- }
+ //
}
//_____________________________________________________________________________
AliMUONDigit::AliMUONDigit(const AliMUONDigit& digit)
- : TObject(digit)
+: TObject(digit),
+fDetElemId(-1),
+fManuId(-1),
+fManuChannel(-1),
+fSignal(0),
+fPadX(-1),
+fPadY(-1),
+fCathode(-1),
+fADC(0),
+fFlags(0),
+fNtracks(0),
+fTcharges(0x0),
+fTracks(0x0),
+fPhysics(0),
+fHit(0)
{
+ //
// copy constructor
-
+ //
(static_cast<const AliMUONDigit&>(digit)).Copy(*this);
}
-//_____________________________________________________________________________
-AliMUONDigit::~AliMUONDigit()
-{
- // Destructor
-}
-
-//_____________________________________________________________________________
-AliMUONDigit&
-AliMUONDigit::operator=(const AliMUONDigit& digit)
-{
- AliMUONDigit a(digit);
- a.Copy(*this);
- return *this;
-}
-
-//______________________________________________________________________________
-void
-AliMUONDigit::Copy(TObject& obj) const
-{
- // Copy this line to line.
-
- TObject::Copy(obj);
- AliMUONDigit& digit = static_cast<AliMUONDigit&>(obj);
- digit.fPadX = fPadX;
- digit.fPadY = fPadY;
- digit.fCathode = fCathode;
- digit.fSignal = fSignal;
- digit.fHit = fHit;
- digit.fDetElemId = fDetElemId;
- digit.fManuId = fManuId;
- digit.fManuChannel = fManuChannel;
- digit.fADC = fADC;
- digit.fIsSaturated = fIsSaturated;
-}
-
-
//_____________________________________________________________________________
AliMUONDigit::AliMUONDigit(Int_t *digits)
+: TObject(),
+fDetElemId(-1),
+fManuId(-1),
+fManuChannel(-1),
+fSignal(0),
+fPadX(-1),
+fPadY(-1),
+fCathode(-1),
+fADC(0),
+fFlags(0),
+fNtracks(0),
+fTcharges(0x0),
+fTracks(0x0),
+fPhysics(0),
+fHit(0)
+
{
//
// Creates a MUON digit object to be updated
+ // \deprecated
//
fPadX = digits[0];
fPadY = digits[1];
fManuId = -1;
fManuChannel = -1;
fADC=0;
- fIsSaturated = kFALSE;
+ fFlags = 0;
}
+
//_____________________________________________________________________________
AliMUONDigit::AliMUONDigit(Int_t *tracks, Int_t *charges, Int_t *digits)
+: TObject(),
+fDetElemId(-1),
+fManuId(-1),
+fManuChannel(-1),
+fSignal(0),
+fPadX(-1),
+fPadY(-1),
+fCathode(-1),
+fADC(0),
+fFlags(0),
+fNtracks(0),
+fTcharges(0x0),
+fTracks(0x0),
+fPhysics(0),
+fHit(0)
{
- //
- // Creates a MUON digit object
- //
+ //
+ // Creates a MUON digit object
+ //
+ // \deprecated
fPadX = digits[0];
fPadY = digits[1];
fCathode = digits[2];
fManuId = -1;
fManuChannel = -1;
fADC=0;
- for(Int_t i=0; i<kMAXTRACKS; i++) {
+
+ // For backward compatibility, which assumed 10 tracks.
+ fNtracks = 10;
+ fTcharges = new Int_t[fNtracks];
+ fTracks = new Int_t[fNtracks];
+
+ for ( Int_t i=0; i<fNtracks; ++i )
+ {
fTcharges[i] = charges[i];
fTracks[i] = tracks[i];
}
- fIsSaturated=kFALSE;
+ fFlags=0;
+}
+
+//_____________________________________________________________________________
+AliMUONDigit::~AliMUONDigit()
+{
+ //
+ // Destructor
+ //
+ delete[] fTcharges;
+ delete[] fTracks;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONDigit::AddTrack(Int_t trackNumber, Int_t trackCharge)
+{
+ //
+ // Add 1 track information to the track list we keep.
+ // The implementation below is dumb, you've been warned !
+ //
+
+ // First check if track is already there, in which
+ // case we simply increment its charge.
+ for ( Int_t i = 0; i < Ntracks(); ++i )
+ {
+ if ( Track(i) == trackNumber )
+ {
+ fTcharges[i] += trackCharge;
+ return;
+ }
+ }
+
+ // Nope. It's a brand new track. Make a new array to get space
+ // for it, copy the old array into new one, and add the track.
+ Int_t* newTracks = new Int_t[fNtracks+1];
+ Int_t* newTcharges = new Int_t[fNtracks+1];
+
+ for ( Int_t i = 0; i < fNtracks; ++i )
+ {
+ newTracks[i] = fTracks[i];
+ newTcharges[i] = fTcharges[i];
+ }
+
+ newTracks[fNtracks] = trackNumber;
+ newTcharges[fNtracks] = trackCharge;
+
+ delete[] fTracks;
+ delete[] fTcharges;
+
+ fTracks = newTracks;
+ fTcharges = newTcharges;
+
+ ++fNtracks;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONDigit::Clear(Option_t*)
+{
+ //
+ // Reset this digit, in particular the internal arrays are deleted.
+ //
+ delete[] fTracks;
+ delete[] fTcharges;
+ fTracks=0x0;
+ fTcharges=0x0;
+ fNtracks=0;
}
//_____________________________________________________________________________
Int_t AliMUONDigit::Compare(const TObject *obj) const
{
-// sort by idDE
+ //
+ // The order defined below is first by DE, then Signal, then
+ // manuId, and then manuChannel, i.e. it should be a total ordering...
+ //
- AliMUONDigit* d = (AliMUONDigit*) obj;
+ const AliMUONDigit* d = static_cast<const AliMUONDigit*>(obj);
+
+ if ( DetElemId() > d->DetElemId() )
+ {
+ return 1;
+ }
+ else if ( DetElemId() < d->DetElemId() )
+ {
+ return -1;
+ }
+ else
+ {
+ if ( Signal() > d->Signal() )
+ {
+ return 1;
+ }
+ else if ( Signal() < d->Signal() )
+ {
+ return -1;
+ }
+ else
+ {
+ if ( ManuId() < d->ManuId() )
+ {
+ return 1;
+ }
+ else if ( ManuId() > d->ManuId() )
+ {
+ return -1;
+ }
+ else
+ {
+ return ( ManuChannel() < d->ManuChannel() ) ? 1 : -1;
+ }
+ }
+ }
+}
+
+//______________________________________________________________________________
+void
+AliMUONDigit::Copy(TObject& obj) const
+{
+ //
+ // Copy this line to line.
+ //
+ TObject::Copy(obj);
+ AliMUONDigit& digit = static_cast<AliMUONDigit&>(obj);
+
+ digit.fDetElemId = fDetElemId;
+ digit.fManuId = fManuId;
+ digit.fManuChannel = fManuChannel;
+ digit.fSignal = fSignal;
+
+ digit.fPadX = fPadX;
+ digit.fPadY = fPadY;
+ digit.fCathode = fCathode;
+ digit.fADC = fADC;
+ digit.fFlags = fFlags;
+
+ digit.fNtracks = fNtracks;
+
+ delete[] digit.fTcharges;
+ delete[] digit.fTracks;
+
+ if ( fNtracks )
+ {
+ digit.fTcharges = new Int_t[fNtracks];
+ digit.fTracks = new Int_t[fNtracks];
+ }
+
+ for ( Int_t i=0; i<fNtracks; ++i )
+ {
+ digit.fTcharges[i] = fTcharges[i];
+ digit.fTracks[i] = fTracks[i];
+ }
+
+ digit.fPhysics = fPhysics;
+ digit.fHit = fHit;
+}
- return ( fDetElemId > d->DetElemId()) ? 1 : -1;
+//_____________________________________________________________________________
+Bool_t
+AliMUONDigit::IsSaturated() const
+{
+ return (fFlags & SATURATEDFLAG );
+}
+//_____________________________________________________________________________
+AliMUONDigit&
+AliMUONDigit::operator=(const AliMUONDigit& digit)
+{
+ //
+ // Assignement operator.
+ //
+ AliMUONDigit a(digit);
+ a.Copy(*this);
+ return *this;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONDigit::PatchTracks(Int_t mask)
+{
+ //
+ // Add mask to each track number.
+ //
+ for ( Int_t i = 0; i < Ntracks(); ++i )
+ {
+ fTracks[i] += mask;
+ }
}
//_____________________________________________________________________________
void
AliMUONDigit::Print(Option_t* opt) const
{
+ //
+ // Dump to screen.
+ // If opt=="tracks", info on tracks are printed too.
+ //
cout << "DetEle " << setw(5) << DetElemId()
<< " Cath " << setw(2) << Cathode()
<< " (Ix,Iy)=(" << setw(3) << PadX() << "," << setw(3) << PadY()
<< "," << setw(3) << ManuChannel() << ")"
<< " Signal=" << setw(6) << Signal()
<< " Physics=" << setw(4) << Physics();
- if ( fIsSaturated )
+ if ( IsSaturated() )
{
cout << "(S)";
}
options.ToLower();
if ( options.Contains("tracks") )
{
- cout << " Track0=" << setw(3) << Track(0)
- << " Charge0=" << setw(4) << TrackCharge(0)
- << " Track1=" << setw(3) << Track(1)
- << " Charge1=" << setw(4) << TrackCharge(1);
+ cout << " Hit " << setw(3) << Hit();
+ Int_t ntracks = Ntracks();
+ if (ntracks)
+ {
+ cout << " Tracks : " << setw(2) << ntracks;
+ for ( Int_t i = 0; i < ntracks; ++i )
+ {
+ cout << " Track(" << i << ")=" << setw(3) << Track(i)
+ << " Charge(" << i << ")=" << setw(5) << TrackCharge(i);
+ }
+ }
+ else
+ {
+ cout << " no track info.";
+ }
}
cout << endl;
}
-//_____________________________________________________________________________
-Bool_t
-AliMUONDigit::IsSaturated() const
-{
- return fIsSaturated;
-}
-
-//_____________________________________________________________________________
-Int_t
-AliMUONDigit::ManuId() const
-{
- return fManuId;
-}
-
-//_____________________________________________________________________________
-Int_t
-AliMUONDigit::ManuChannel() const
-{
- return fManuChannel;
-}
-
-//_____________________________________________________________________________
-Int_t
-AliMUONDigit::ADC() const
-{
- return fADC;
-}
-
//_____________________________________________________________________________
void
-AliMUONDigit::SetADC(Int_t adc)
+AliMUONDigit::Saturated(Bool_t value)
{
- fADC = adc;
+ if ( value )
+ {
+ fFlags |= SATURATEDFLAG;
+ }
+ else
+ {
+ fFlags ^= SATURATEDFLAG;
+ }
}
//_____________________________________________________________________________
}
//_____________________________________________________________________________
-void
-AliMUONDigit::Saturated(Bool_t saturated)
+Int_t
+AliMUONDigit::Track(Int_t i) const
{
- fIsSaturated=saturated;
+ //
+ // Return the i-th track number (if i is >=0 and < Ntracks()) or -1.
+ //
+ if ( i >= 0 && i < fNtracks )
+ {
+ return fTracks[i];
+ }
+
+ return -1;
}
+//_____________________________________________________________________________
+Int_t
+AliMUONDigit::TrackCharge(Int_t i) const
+{
+ //
+ // Return the i-th track charge (if i is >=0 and < Ntracjs()) or -1.
+ //
+ if ( i >= 0 && i < fNtracks )
+ {
+ return fTcharges[i];
+ }
+ return -1;
+}
#include <TObject.h>
-static const Int_t kMAXTRACKS=10;
-
-class AliMUONDigit : public TObject {
-
+class AliMUONDigit : public TObject
+{
public:
AliMUONDigit();
AliMUONDigit(const AliMUONDigit& rhs);
+ /// \deprecated
AliMUONDigit(Int_t *digits);
+ /// \deprecated
AliMUONDigit(Int_t *tracks, Int_t *charges, Int_t *digits);
virtual ~AliMUONDigit();
virtual Bool_t IsSortable() const {return kTRUE;}
virtual int Compare(const TObject *obj) const;
- virtual Int_t DetElemId()const {return fDetElemId;}
+ virtual Int_t DetElemId()const {return fDetElemId;}
virtual Int_t PadX() const {return fPadX;}
virtual Int_t PadY() const {return fPadY;}
virtual Int_t Cathode() const {return fCathode;}
virtual Int_t Physics() const {return fPhysics;}
- virtual Int_t Hit() const {return fHit;}
- virtual Int_t Track(Int_t i) const {return fTracks[i];}
- virtual Int_t TrackCharge(Int_t i) const {return fTcharges[i];}
+ virtual Int_t Hit() const {return fHit;}
+
+ virtual Int_t Ntracks() const { return fNtracks; }
+ virtual void AddTrack(Int_t trackNumber, Int_t trackCharge);
+ virtual Int_t Track(Int_t i) const;
+ virtual Int_t TrackCharge(Int_t i) const;
- virtual Int_t ADC() const;
- virtual Int_t ManuId() const;
- virtual Int_t ManuChannel() const;
+ virtual Int_t ADC() const { return fADC; }
+ virtual Int_t ManuId() const { return fManuId; }
+ virtual Int_t ManuChannel() const { return fManuChannel; }
virtual Bool_t IsSaturated() const;
virtual void Saturated(Bool_t saturated=kTRUE);
virtual void SetElectronics(Int_t manuId, Int_t manuChannel);
- virtual void SetADC(Int_t adc);
+ virtual void SetADC(Int_t adc) { fADC=adc; }
virtual void SetDetElemId(Int_t id) {fDetElemId = id;}
virtual void SetPadX(Int_t pad) {fPadX = pad;}
virtual void SetPadY(Int_t pad) {fPadY = pad;}
virtual void Copy(TObject& digit) const;
- private:
+ /** Delete the internal track arrays (which are dynamically allocated).
+ * This is to insure we can put those digits in e.g. TClonesArray
+ * w/o leaking memory.
+ */
+ virtual void Clear(Option_t*);
+
+ /// Add mask to the track numbers.
+ virtual void PatchTracks(Int_t mask);
+
+private:
+ Int_t fDetElemId; // Detection element ID
+ Int_t fManuId; // Id of the MANU chip.
+ Int_t fManuChannel; // Channel within the MANU chip.
+ Int_t fSignal; // Signal amplitude
+
Int_t fPadX; // Pad number along x
Int_t fPadY; // Pad number along y
Int_t fCathode; // Cathode number
+ Int_t fADC; // ADC value
+ UInt_t fFlags; // Special flags (e.g. is the signal an overflow ?)
- Int_t fSignal; // Signal amplitude
- Int_t fTcharges[kMAXTRACKS]; // charge per track making this digit (up to 10)
- Int_t fTracks[kMAXTRACKS]; // primary tracks making this digit (up to 10)
- Int_t fPhysics; // physics contribution to signal
- Int_t fHit; // hit number - temporary solution
- Int_t fDetElemId; // Detection element ID
-
- Int_t fManuId; // Id of the MANU chip.
- Int_t fManuChannel; // Channel within the MANU chip.
- Int_t fADC; // ADC value
- Bool_t fIsSaturated; // Is the signal an overflow ?
-
- ClassDef(AliMUONDigit,3) //Digits for MUON
+ Int_t fNtracks; // MC tracks making to this digit.
+ Int_t* fTcharges; //[fNtracks] charges of MC track making this digit
+ Int_t* fTracks; //[fNtracks] primary MC tracks making this digit
+ Int_t fPhysics; // MC physics contribution to signal
+ Int_t fHit; // MC hit number - temporary solution
+
+ ClassDef(AliMUONDigit,4) //Digits for MUON
};
#endif