//----------------------------------------------------------------------------- // Dec 17 2000 P.Murat: simple ROOT-parsable description of CalTower //----------------------------------------------------------------------------- #ifndef TCalTower_hh #define TCalTower_hh #include #include "TMath.h" #include "TObject.h" #include "CalorGeometry/CalConstants.hh" #include "CalorGeometry/CalParameters.hh" class TCalTower : public TObject { public: // number of data words enum { kNDataWords = 16 }; protected: // approximate values of theta for the // centers of the towers [in degrees] static Int_t fgInitialized; static double fgTheta [TOWER_NETA ]; static double fgEta [TOWER_NETA+1]; static double fgThetaMP[NMPSIDE][NMPTOW]; static double fgEtaMP [NMPSIDE][NMPTOW]; static double fgPhiMP [NMPSIDE][NMPTOW]; //----------------------------------------------------------------------------- // data members: 16 shorts // custom streamer doesn't write out TObject // next step: obsolete streamer for TCalTower, use Streamer for TCalDataBlock // instead (this is in progress) // to save more space one could also write out just RAW data.. // may be suppressed at 50 MeV or so //----------------------------------------------------------------------------- protected: Short_t fCode; // val_code&0xff + 1 byte - see .cc Short_t fEtaPhi; // (ieta << 8)+iphi Short_t fHadTdc[2]; // hadron TDC times (packed) Short_t fEmPmt [4]; // ADC counts in each EM channel Short_t fHadPmt[4]; // ADC counts in each HAD channel Short_t fHadEnergy; // hadron energy Short_t fEmEnergy; // EM energy Short_t fHadCOGPhi; // hadron center-of-gravity phi [0,1) Short_t fEmCOGPhi; // em center-of-gravity phi [0,1) //----------------------------------------------------------------------------- public: // ****** constructors and destructor TCalTower(); virtual ~TCalTower(); // ****** initialization static void InitStaticVariables(); //----------------------------------------------------------------------------- // static methods //----------------------------------------------------------------------------- static Int_t IPhi (int TowerKey) { return (TowerKey ) & 0x3f ; } static Int_t IEta (int TowerKey) { return (TowerKey >> 8) & 0x3f ; } static Int_t ValidCode(int TowerKey) { return (TowerKey >> 16) & 0xffff; } // Do not use these accessors for MiniPlug static Double_t Theta (Int_t I) { return fgTheta[I]; } static Double_t Eta (Int_t I) { return fgEta [I]; } // Use these - only for MiniPlug Double_t ThetaMP (Int_t Ieta, Int_t Iphi) { return fgThetaMP[MPISide(Ieta)][MPITow(Ieta, Iphi)]; } Double_t EtaMP (Int_t Ieta, Int_t Iphi) { return fgEtaMP [MPISide(Ieta)][MPITow(Ieta, Iphi)]; } Double_t PhiMP (Int_t Ieta, Int_t Iphi) { return fgPhiMP [MPISide(Ieta)][MPITow(Ieta, Iphi)]; } static Int_t IEta (Float_t DetEta); static Float_t DEtaNorm (Float_t DetEta); //----------------------------------------------------------------------------- // accessors //----------------------------------------------------------------------------- Short_t* Data () { return &fCode; } Int_t Type () const { return TOWER_TYPE[IEta()]; } Float_t HadEnergy() const { Int_t i = (fHadEnergy >> 14) & 0x2; Float_t e = ((fHadEnergy & 0x7fff) << i)*0.005-0.1; return e; } Float_t EmEnergy() const { Int_t i = (fEmEnergy >> 14) & 0x2; Float_t e = ((fEmEnergy & 0x7fff) << i)*0.005-0.1; return e; } Float_t Energy () const { return EmEnergy()+HadEnergy(); } Int_t ValidCode () const { return (fCode ) & 0xff; } Int_t EtaPhi () const { return fEtaPhi; } Int_t IEta () const { return (fEtaPhi >> 8) & 0xff; } Int_t IPhi () const { return (fEtaPhi ) & 0xff; } Int_t IsCentral () const { return (IEta() >= 16) && (IEta() <= 35); } Float_t Theta () const { if (IEta() >= 4 && IEta() <= 47) return fgTheta [IEta()]; else return fgThetaMP[MPISide()][MPITow()]; } Float_t Phi () const { if (IEta() >= 4 && IEta() <= 47) return 2*TMath::Pi()*(IPhi()+0.5)/TOWER_PHI_SEG[Type()]; else return fgPhiMP[MPISide()][MPITow()]; } Float_t Eta () const { Float_t theta = Theta()*TMath::Pi()/180.; Float_t eta = TMath::Log(fabs(TMath::Tan(theta/2))); return (theta < 0) ? eta : -eta; } Float_t HadCOGPhi () const { return UShort_t(fHadCOGPhi)*0.00002; } Float_t EmCOGPhi () const { return UShort_t(fEmCOGPhi) *0.00002; } Int_t NEmPmt () const { return CAL_N_EM_PMT [Type()]; } Int_t NHadPmt () const { return CAL_N_HAD_PMT [Type()]; } Int_t NEmCompartments () const { return CAL_N_EM_COMPARTMENTS [Type()]; } Int_t NHadCompartments() const { return CAL_N_HAD_COMPARTMENTS[Type()]; } // approximate "detector" Et (Z at 0) // projective geometry is assumed Float_t Et () const { return Energy()*fabs(sin(Theta()*TMath::Pi()/180.));} Int_t EmPmt (int i) const { return (Int_t) ((UShort_t) fEmPmt [i]); } Int_t HadPmt(int i) const { return (Int_t) ((UShort_t) fHadPmt[i]); } // for the central: // HadTdc[0] is CHA time, // HadTdc[1] is WHA time // for the moment times are not // defined for the rest Int_t HadTdc(Int_t i) const { return fHadTdc[i]; } Int_t MPISide(int ieta = -1) const { // return MP side (0-1) for a given ieta,iphi if (ieta == -1) ieta = IEta(); if (ieta >=0 && ieta <= 3 ) return 0; if (ieta >= 47 && ieta <= 51) return 1; return -1; } Int_t MPITow (int ieta = -1 , int iphi = -1) const ; // the phototube energy asymmetry for central towers Float_t EmAsym() { if(IsCentral()==false || (EmPmt(0) + EmPmt(1))<=0 ) return 0.0; return float(EmPmt(1) - EmPmt(0))/float(EmPmt(0) + EmPmt(1)); } Float_t HadAsym() { if(IsCentral()==false || (HadPmt(0) + HadPmt(1))<=0 ) return 0.0; return float(HadPmt(1) - HadPmt(0))/float(HadPmt(0) + HadPmt(1)); } //----------------------------------------------------------------------------- // modifiers //----------------------------------------------------------------------------- void SetValidCode(UChar_t code) { fCode = code; } void SetEtaPhi (Int_t ieta, Int_t iphi) { fEtaPhi = ((ieta & 0xff) << 8) + (iphi & 0xff); } void SetEmPmt (Int_t i, UShort_t adc) { fEmPmt [i] = (Short_t) adc; } void SetHadPmt(Int_t i, UShort_t adc) { fHadPmt[i] = (Short_t) adc; } void SetNTdcHits(Short_t n0, Short_t n1) { fCode = (fCode & 0xff) | ((n1&0xf) << 12) | ((n0&0xf) << 8); } int NTdcHits(Int_t I) { return (fCode >> (8+4*I)) & 0xf; } void SetHadTdc(Short_t t0, Short_t t1) { fHadTdc[0] = t0; fHadTdc[1] = t1; } void SetEmCOGPhi(Float_t Phi) { fEmCOGPhi = Short_t(int(floor(Phi/0.00002+0.5))); } void SetHadCOGPhi(Float_t Phi) { fHadCOGPhi = Short_t(int(floor(Phi/0.00002+0.5))); } void SetHadEnergy(Float_t E) { Int_t e = Int_t(floor((E+0.1)/0.005 + 0.5)); Int_t bit = 0; if (e > 0x7fff) { bit = 1; e = (e >> 2); } if (e > 0x7fff) e = 0x7fff; fHadEnergy = e | (bit << 15); } void SetEmEnergy(Float_t E) { Int_t e = Int_t(floor((E+0.1)/0.005 + 0.5)); Int_t bit = 0; if (e > 0x7fff) { bit = 1; e = (e >> 2); } if (e > 0x7fff) e = 0x7fff; fEmEnergy = e | (bit << 15); } // ****** schema evolution void ReadV1(TBuffer &R__b); // ****** overloaded methods of // TObject void Clear(Option_t* opt = ""); void Print(Option_t* opt = "") const; ClassDef (TCalTower,2) }; #endif