From 916f1e76c5ffee7c7ed6214b883f65b4b6df3adf Mon Sep 17 00:00:00 2001 From: gconesab Date: Fri, 19 Feb 2010 17:54:11 +0000 Subject: [PATCH] New Trigger Emulation and Trigger access from data (Rachid Guernane) libEMCALbase.pkg, EMCALbaseLinkDef.h: add raw digit and STU raw stream decoder libEMCALrec.pkg: include VZERO needed by trigger processor libEMCALsim.pkg, EMCALsimLinkDef.h: add trigger classes AliEMCALReconstructor* : invoque trigger processor (Rachid) AliEMCALDigitizer.*: create trigger digits from tower digits (Rachid) AliEMCALGeoUtils.*: add trigger mapping (Rachid) AliEMCALRawUtils.*:modify Raw2Digits method to access FALTRO data (Rachid) AliEMCALTriggerTRU.* TRU class AliEMCALTriggerSTU.*: STU class AliEMCALTriggerSTURawStream.*: STU data decoder AliEMCALTriggerElectronics.*: Trigger processor AliEMCALRawDigit.*: Elementary digit closest to raw data content AliEMCALTriggerData.*: Trigger data for persistency AliEMCALTriggerPatch.*: Object created by trigger algorithms (L0, L1) AliEMCALTriggerBoard.*: Trigger electronic device base class --- EMCAL/AliEMCALDigitizer.cxx | 217 +++++++++++- EMCAL/AliEMCALDigitizer.h | 6 +- EMCAL/AliEMCALGeoUtils.cxx | 93 ++++++ EMCAL/AliEMCALGeoUtils.h | 5 + EMCAL/AliEMCALRawDigit.cxx | 127 ++++++++ EMCAL/AliEMCALRawDigit.h | 50 +++ EMCAL/AliEMCALRawUtils.cxx | 94 +++++- EMCAL/AliEMCALRawUtils.h | 4 +- EMCAL/AliEMCALReconstructor.cxx | 53 ++- EMCAL/AliEMCALReconstructor.h | 6 +- EMCAL/AliEMCALShishKebabTrd1Module.cxx | 2 +- EMCAL/AliEMCALTriggerBoard.cxx | 173 ++++++++++ EMCAL/AliEMCALTriggerBoard.h | 68 ++++ EMCAL/AliEMCALTriggerData.cxx | 149 +++++++++ EMCAL/AliEMCALTriggerData.h | 103 ++++++ EMCAL/AliEMCALTriggerElectronics.cxx | 218 +++++++++++++ EMCAL/AliEMCALTriggerElectronics.h | 48 +++ EMCAL/AliEMCALTriggerPatch.cxx | 114 +++++++ EMCAL/AliEMCALTriggerPatch.h | 43 +++ EMCAL/AliEMCALTriggerSTU.cxx | 347 ++++++++++++++++++++ EMCAL/AliEMCALTriggerSTU.h | 47 +++ EMCAL/AliEMCALTriggerSTURawStream.cxx | 349 ++++++++++++++++++++ EMCAL/AliEMCALTriggerSTURawStream.h | 65 ++++ EMCAL/AliEMCALTriggerTRU.cxx | 435 +++++++++++++++++++++++++ EMCAL/AliEMCALTriggerTRU.h | 48 +++ EMCAL/EMCALbaseLinkDef.h | 3 + EMCAL/EMCALsimLinkDef.h | 7 + EMCAL/libEMCALbase.pkg | 5 +- EMCAL/libEMCALrec.pkg | 3 +- EMCAL/libEMCALsim.pkg | 12 +- 30 files changed, 2869 insertions(+), 25 deletions(-) create mode 100644 EMCAL/AliEMCALRawDigit.cxx create mode 100644 EMCAL/AliEMCALRawDigit.h create mode 100644 EMCAL/AliEMCALTriggerBoard.cxx create mode 100644 EMCAL/AliEMCALTriggerBoard.h create mode 100644 EMCAL/AliEMCALTriggerData.cxx create mode 100644 EMCAL/AliEMCALTriggerData.h create mode 100644 EMCAL/AliEMCALTriggerElectronics.cxx create mode 100644 EMCAL/AliEMCALTriggerElectronics.h create mode 100644 EMCAL/AliEMCALTriggerPatch.cxx create mode 100644 EMCAL/AliEMCALTriggerPatch.h create mode 100644 EMCAL/AliEMCALTriggerSTU.cxx create mode 100644 EMCAL/AliEMCALTriggerSTU.h create mode 100644 EMCAL/AliEMCALTriggerSTURawStream.cxx create mode 100644 EMCAL/AliEMCALTriggerSTURawStream.h create mode 100644 EMCAL/AliEMCALTriggerTRU.cxx create mode 100644 EMCAL/AliEMCALTriggerTRU.h diff --git a/EMCAL/AliEMCALDigitizer.cxx b/EMCAL/AliEMCALDigitizer.cxx index 72522590fb8..2c1c0f885f8 100644 --- a/EMCAL/AliEMCALDigitizer.cxx +++ b/EMCAL/AliEMCALDigitizer.cxx @@ -66,6 +66,7 @@ #include #include #include +#include #include // --- AliRoot header files --- @@ -84,6 +85,44 @@ #include "AliEMCALTick.h" #include "AliEMCALCalibData.h" #include "AliEMCALSimParam.h" +#include "AliEMCALRawDigit.h" + +namespace +{ + Double_t HeavisideTheta(Double_t x) + { + Double_t signal = 0.; + + if (x > 0.) signal = 1.; + + return signal; + } + + Double_t AnalogFastORFunction(Double_t *x, Double_t *par) + { + Double_t v0 = par[0]; + Double_t t0 = par[1]; + Double_t tr = par[2]; + + Double_t R1 = 1000.; + Double_t C1 = 33e-12; + Double_t R2 = 1800; + Double_t C2 = 22e-12; + + Double_t t = x[0]; + + return (((0.8*(-((TMath::Power(C1,2)*C2*TMath::Power(TMath::E(),(-t + t0)/(C1*R1))* + TMath::Power(R1,2)*R2)/(C1*R1 - C2*R2)) + + C1*C2*R1*R2*(1 - (C2*TMath::Power(TMath::E(),(-t + t0)/(C2*R2))*R2)/(-(C1*R1) + C2*R2)))*v0* + HeavisideTheta(t - t0))/tr + - (0.8*(C1*C2*R1*R2 - + (TMath::Power(C1,2)*C2*TMath::Power(TMath::E(),(-1.*t + t0 + 1.25*tr)/(C1*R1))* + TMath::Power(R1,2)*R2)/(C1*R1 - C2*R2) + + (C1*TMath::Power(C2,2)*TMath::Power(TMath::E(),(-1.*t + t0 + 1.25*tr)/(C2*R2))* + R1*TMath::Power(R2,2))/(C1*R1 - C2*R2))*v0* + HeavisideTheta(t - t0 - 1.25*tr))/tr)/(C2*R1)); + } +} ClassImp(AliEMCALDigitizer) @@ -540,6 +579,8 @@ void AliEMCALDigitizer::Exec(Option_t *option) Int_t nEvents = fLastEvent - fFirstEvent + 1; Int_t ievent; + TClonesArray* digitsTRG = new TClonesArray("AliEMCALRawDigit", 32 * 96); + TClonesArray* digitsTMP = new TClonesArray("AliEMCALDigit", 32 * 96); rl->LoadSDigits("EMCAL"); for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++) { @@ -548,6 +589,21 @@ void AliEMCALDigitizer::Exec(Option_t *option) Digitize(ievent) ; //Add prepared SDigits to digits and add the noise WriteDigits() ; + + //Trigger Digits + //------------------------------------- + Digits2FastOR(digitsTMP, digitsTRG); + + WriteDigits(digitsTRG); + + emcalLoader->WriteDigits( "OVERWRITE"); + emcalLoader->WriteDigitizer("OVERWRITE"); + + Unload(); + + digitsTRG->Clear(); + digitsTMP->Clear(); + //------------------------------------- if(strstr(option,"deb")) PrintDigits(option); @@ -566,6 +622,137 @@ void AliEMCALDigitizer::Exec(Option_t *option) } } +//____________________________________________________________________________ +void AliEMCALDigitizer::Digits2FastOR(TClonesArray* digitsTMP, TClonesArray* digitsTRG) +{ + // FEE digits afterburner to produce TRG digits + // we are only interested in the FEE digit deposited energy + // to be converted later into a voltage value + + // push the FEE digit to its associated FastOR (numbered from 0:95) + // TRU is in charge of summing module digits + + AliRunLoader *runLoader = AliRunLoader::Instance(); + + AliRun* run = runLoader->GetAliRun(); + + AliEMCALLoader *emcalLoader = dynamic_cast(runLoader->GetDetectorLoader("EMCAL")); + + AliEMCALGeometry* geom = dynamic_cast(run->GetDetector("EMCAL"))->GetGeometry(); + + // build FOR from simulated digits + // and xfer to the corresponding TRU input (mapping) + + TClonesArray* digits = emcalLoader->Digits(); + + TIter NextDigit(digits); + while (AliEMCALDigit* digit = (AliEMCALDigit*)NextDigit()) + { + Int_t id = digit->GetId(); + + Int_t iSupMod, nModule, nIphi, nIeta, iphi, ieta, iphim, ietam; + + geom->GetCellIndex( id, iSupMod, nModule, nIphi, nIeta ); + geom->GetModulePhiEtaIndexInSModule( iSupMod, nModule, iphim, ietam ); + geom->GetCellPhiEtaIndexInSModule( iSupMod, nModule, nIphi, nIeta, iphi, ieta); + + // identify to which TRU this FEE digit belong + Int_t itru = (iSupMod < 11) ? iphim / 4 + 3 * iSupMod : 31; + + //--------- + // + // FIXME: bad numbering solution to deal w/ the last 2 SM which have only 1 TRU each + // using the AliEMCALGeometry official numbering + // only 1 TRU/SM in SM 10 & SM 11 + // + //--------- + if ((itru == 31 && iphim < 2) || (itru == 30 && iphim > 5)) continue; + + // to be compliant with %4 per TRU + if (itru == 31) iphim -= 2; + + Int_t trgid; + Bool_t isOK = geom->GetAbsFastORIndexFromPositionInTRU(itru, ietam, iphim % 4, trgid); + + AliDebug(2,Form("trigger digit id: %d itru: %d isOK: %d\n",trgid,itru,isOK)); + + if (isOK) + { + AliEMCALDigit* d = static_cast(digitsTMP->At(trgid)); + + if (!d) + { + new((*digitsTMP)[trgid]) AliEMCALDigit(*digit); + d = (AliEMCALDigit*)digitsTMP->At(trgid); + d->SetId(trgid); + } + else + { + *d = *d + *digit; + } + } + } + + Int_t nSamples = 32; + Int_t timeSamples[nSamples]; + + NextDigit = TIter(digitsTMP); + while (AliEMCALDigit* digit = (AliEMCALDigit*)NextDigit()) + { + if (digit) + { + Int_t id = digit->GetId(); + Float_t time = digit->GetTime(); + + Double_t depositedEnergy = 0.; + for (Int_t j = 1; j <= digit->GetNprimary(); j++) depositedEnergy += digit->GetDEPrimary(j); + + // FIXME: Check digit time! + if (depositedEnergy) + { + DigitalFastOR(time, depositedEnergy, timeSamples, nSamples); + + for (Int_t j=0;jGetEntriesFast()]) AliEMCALRawDigit(id, timeSamples, nSamples); + } + } + } +} + +//____________________________________________________________________________ +void AliEMCALDigitizer::DigitalFastOR( Double_t time, Double_t dE, Int_t timeSamples[], Int_t nSamples ) +{ + // parameters: + // id: 0..95 + const Int_t reso = 11; // 11-bit resolution ADC + const Double_t vFSR = 1; // Full scale input voltage range + const Double_t Ne = 125; // signal of the APD per MeV of energy deposit in a tower: 125 photo-e-/MeV @ M=30 + const Double_t vA = .136e-6; // CSP output range: 0.136uV/e- + const Double_t rise = 40e-9; // rise time (10-90%) of the FastOR signal before shaping + + const Double_t kTimeBinWidth = 25E-9; // sampling frequency (40MHz) + + Double_t vV = 1000. * dE * Ne * vA; // GeV 2 MeV + + TF1 signalF("signal", AnalogFastORFunction, 0, nSamples * kTimeBinWidth, 3); + signalF.SetParameter( 0, vV ); + signalF.SetParameter( 1, time ); // FIXME: when does the signal arrive? Might account for cable lengths + signalF.SetParameter( 2, rise ); + + for (Int_t iTime=0; iTimeBranch("EMCAL","TClonesArray",&digits,bufferSize); //digitsBranch->SetTitle(fEventFolderName); treeD->Fill() ; - +/* emcalLoader->WriteDigits("OVERWRITE"); emcalLoader->WriteDigitizer("OVERWRITE"); Unload() ; +*/ +} +//__________________________________________________________________ +void AliEMCALDigitizer::WriteDigits(TClonesArray* digits, const char* branchName) +{ + // + AliEMCALLoader *emcalLoader = dynamic_cast(AliRunLoader::Instance()->GetDetectorLoader("EMCAL")); + + TTree* treeD = emcalLoader->TreeD(); + if (!treeD) + { + emcalLoader->MakeDigitsContainer(); + treeD = emcalLoader->TreeD(); + } + + // -- create Digits branch + Int_t bufferSize = 32000; + + if (TBranch* triggerBranch = treeD->GetBranch(branchName)) + { + triggerBranch->SetAddress(&digits); + } + else + { + treeD->Branch(branchName,"TClonesArray",&digits,bufferSize); + } + + treeD->Fill(); } //__________________________________________________________________ diff --git a/EMCAL/AliEMCALDigitizer.h b/EMCAL/AliEMCALDigitizer.h index 4f7c506d17c..716933aa37f 100644 --- a/EMCAL/AliEMCALDigitizer.h +++ b/EMCAL/AliEMCALDigitizer.h @@ -82,13 +82,17 @@ private: void PrintDigits(Option_t * option) ; void Unload() ; void WriteDigits() ; // Writes Digits the current event + void WriteDigits(TClonesArray* digits, const char* branchName = "EMTRG"); // Float_t TimeOfNoise(void) ; // Calculate time signal generated by noise //Calculate the time of crossing of the threshold by front edge //Float_t FrontEdgeTime(TClonesArray * ticks) ; Int_t DigitizeEnergy(Float_t energy, Int_t AbsId) ; - + void Digits2FastOR(TClonesArray*digitsTMP, TClonesArray* digitsTRG); + void DigitalFastOR(Double_t time, Double_t dE, Int_t timeSamples[], Int_t nSamples); + + private: Bool_t fDefaultInit; //! Says if the task was created by defaut ctor (only parameters are initialized) diff --git a/EMCAL/AliEMCALGeoUtils.cxx b/EMCAL/AliEMCALGeoUtils.cxx index 8266fe95a2f..f15ea1e588f 100644 --- a/EMCAL/AliEMCALGeoUtils.cxx +++ b/EMCAL/AliEMCALGeoUtils.cxx @@ -977,6 +977,99 @@ Int_t AliEMCALGeoUtils::GetAbsTRUNumberFromNumberInSm(const Int_t row, const Int return itru; } +//________________________________________________________________________________________________ +Bool_t AliEMCALGeoUtils::GetAbsFastORIndexFromTRU(const Int_t iTRU, const Int_t iADC, Int_t& id) const +{ + if (iTRU > 31 || iTRU < 0 || iADC > 95 || iADC < 0) + { + AliError("TRU out of range!"); + return kFALSE; + } + + id = iADC + iTRU * 96; + + return kTRUE; +} + +//________________________________________________________________________________________________ +Bool_t AliEMCALGeoUtils::GetTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, Int_t& iADC) const +{ + if (id > 3071 || id < 0) + { + AliError("Id out of range!"); + return kFALSE; + } + + iTRU = id / 96; + iADC = id % 96; + + return kTRUE; +} + +//________________________________________________________________________________________________ +Bool_t AliEMCALGeoUtils::GetPositionInTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, Int_t& iEta, Int_t& iPhi) const +{ + Int_t iADC; + + Bool_t isOK = GetTRUFromAbsFastORIndex(id, iTRU, iADC); + + if (!isOK) return kFALSE; + + Int_t x = iADC / 4; + Int_t y = iADC % 4; + + if ( int( iTRU / 3 ) % 2 ) // C side + { + iEta = 23 - x; + iPhi = y; + } + else // A side + { + iEta = x; + iPhi = 3 - y; + } + + return kTRUE; +} + +//________________________________________________________________________________________________ +Bool_t AliEMCALGeoUtils::GetPositionInSMFromAbsFastORIndex(const Int_t id, Int_t& iSM, Int_t& iEta, Int_t& iPhi) const +{ + Int_t iTRU; + Bool_t isOK = GetPositionInTRUFromAbsFastORIndex(id, iTRU, iEta, iPhi); + + if (!isOK) return kFALSE; + + iSM = iTRU / 3; + + if ( int( iTRU / 3 ) % 2 ) // C side + { + iPhi = iPhi + 4 * ( 2 - ( iTRU % 3 ) ); + } + else // A side + { + iPhi = iPhi + 4 * ( iTRU % 3 ); + } + + return kTRUE; +} + +//________________________________________________________________________________________________ +Bool_t AliEMCALGeoUtils::GetAbsFastORIndexFromPositionInTRU(const Int_t iTRU, const Int_t iEta, const Int_t iPhi, Int_t& id) const +{ + if (iTRU < 0 || iTRU > 31 || iEta < 0 || iEta > 23 || iPhi < 0 || iPhi > 3) return kFALSE; + + if ( int( iTRU / 3 ) % 2 ) // C side + { + id = iPhi + 4 * ( 23 - iEta ) + iTRU * 96; + } + else + { + id = (3 - iPhi) + 4 * iEta + iTRU * 96; + } + + return kTRUE; +} //____________________________________________________________________________ const TGeoHMatrix * AliEMCALGeoUtils::GetMatrixForSuperModule(Int_t smod) const { diff --git a/EMCAL/AliEMCALGeoUtils.h b/EMCAL/AliEMCALGeoUtils.h index 8cac92cd4ac..a9e0b588aea 100644 --- a/EMCAL/AliEMCALGeoUtils.h +++ b/EMCAL/AliEMCALGeoUtils.h @@ -126,6 +126,11 @@ public: void GetModulePhiEtaIndexInSModuleFromTRUIndex( Int_t itru, Int_t iphitru, Int_t ietatru, Int_t &ietaSM, Int_t &iphiSM) const; Int_t GetAbsTRUNumberFromNumberInSm(const Int_t row, const Int_t col, const Int_t sm) const ; + Bool_t GetAbsFastORIndexFromTRU(const Int_t iTRU, const Int_t iADC, Int_t& id) const; + Bool_t GetAbsFastORIndexFromPositionInTRU(const Int_t iTRU, const Int_t iEta, const Int_t iPhi, Int_t& id) const; + Bool_t GetTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, Int_t& iADC) const; + Bool_t GetPositionInTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, Int_t& iEta, Int_t& iPhi) const; + Bool_t GetPositionInSMFromAbsFastORIndex(const Int_t id, Int_t& iSM, Int_t& iEta, Int_t& iPhi) const; diff --git a/EMCAL/AliEMCALRawDigit.cxx b/EMCAL/AliEMCALRawDigit.cxx new file mode 100644 index 00000000000..a7a8910a489 --- /dev/null +++ b/EMCAL/AliEMCALRawDigit.cxx @@ -0,0 +1,127 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + +// --- ROOT system --- +#include +#include + +// --- Standard library --- + +// --- AliRoot header files --- + +#include "AliEMCALRawDigit.h" + +ClassImp(AliEMCALRawDigit) + +//____________________________________________________________________________ +AliEMCALRawDigit::AliEMCALRawDigit() : TObject(), +fId(-1), +fNSamples(0), +fSamples(0x0) +{ + // default ctor +} + +//____________________________________________________________________________ +AliEMCALRawDigit::AliEMCALRawDigit(Int_t id, Int_t timeSamples[], Int_t nSamples) : TObject(), +fId(id), +fNSamples(nSamples), +fSamples(0x0) +{ + // + fSamples = new Int_t[fNSamples] ; + for (Int_t i=0; i < fNSamples; i++) fSamples[i] = timeSamples[i]; +} + +//____________________________________________________________________________ +AliEMCALRawDigit::AliEMCALRawDigit(const AliEMCALRawDigit& digit) : TObject(),//AliDigitNew(digit), +fId(digit.fId), +fNSamples(digit.fNSamples), +fSamples(0x0) + +{ + // Copy ctor + // Data members of the base class (AliNewDigit) + +// fAmp = digit.fAmp; +// fIndexInList = digit.fIndexInList; + fSamples = new Int_t[fNSamples]; + for (Int_t i=0; i < digit.fNSamples; i++) fSamples[i] = digit.fSamples[i]; +} + +//____________________________________________________________________________ +AliEMCALRawDigit::~AliEMCALRawDigit() +{ + // Delete array of time samples + delete [] fSamples; +} + +//____________________________________________________________________________ +Bool_t AliEMCALRawDigit::GetTimeSample(const Int_t iSample, Int_t& timeBin, Int_t& amp) const +{ + if (iSample > fNSamples || iSample < 0) return kFALSE; + + amp = fSamples[iSample] & 0xFFF; + timeBin = (fSamples[iSample] >> 12) & 0xFF; + + return kTRUE; +} + +//____________________________________________________________________________ +void AliEMCALRawDigit::Print(const Option_t* /*opt*/) const +{ + printf("===\nDigit id: %4d / %d Time Samples: \n",fId,fNSamples); + for (Int_t i=0; i < fNSamples; i++) + { + Int_t timeBin, amp; + GetTimeSample(i, timeBin, amp); + printf("(%d,%d) ",timeBin,amp); + } + + printf("\n"); +} + +//____________________________________________________________________________ +Int_t AliEMCALRawDigit::Compare(const TObject* obj) const +{ + // Compares two digits with respect to its Id + // to sort according increasing Id + + Int_t rv; + + AliEMCALRawDigit* digit = (AliEMCALRawDigit *)obj; + + Int_t iddiff = fId - digit->GetId(); + + if ( iddiff > 0 ) + rv = 1; + else if ( iddiff < 0 ) + rv = -1; + else + rv = 0; + + return rv; +} + +//____________________________________________________________________________ +Bool_t AliEMCALRawDigit::operator==(AliEMCALRawDigit const & digit) const +{ + // Two digits are equal if they have the same Id + + if(fId == digit.fId) + return kTRUE; + else + return kFALSE; +} diff --git a/EMCAL/AliEMCALRawDigit.h b/EMCAL/AliEMCALRawDigit.h new file mode 100644 index 00000000000..04c50c1f512 --- /dev/null +++ b/EMCAL/AliEMCALRawDigit.h @@ -0,0 +1,50 @@ +#ifndef ALIEMCALRAWDIGIT_H +#define ALIEMCALRAWDIGIT_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id: AliEMCALRawDigit.h 17335 2007-03-10 03:40:17Z mvl $ */ + +// --- ROOT system --- + +#include "TObject.h" + +// --- Standard library --- + +// --- AliRoot header files --- +//#include "AliDigitNew.h" + +class AliEMCALRawDigit : public TObject +{ +// friend ostream& operator<<(ostream& , const AliEMCALRawDigit&); + +public: + + AliEMCALRawDigit(); + AliEMCALRawDigit(Int_t id, Int_t timeSamples[], Int_t nSamples); + AliEMCALRawDigit(const AliEMCALRawDigit& digit); + + virtual ~AliEMCALRawDigit(); + + Bool_t operator==(const AliEMCALRawDigit &rValue) const; + const AliEMCALRawDigit& operator = (const AliEMCALRawDigit&) {return *this;} + + Int_t Compare(const TObject* obj) const; + Bool_t IsSortable() const {return kTRUE;} + void SetId(Int_t id) {fId = id;} + Int_t GetId() const {return fId;} + + Int_t GetNSamples() const {return fNSamples;} + Bool_t GetTimeSample(const Int_t iSample, Int_t& timeBin, Int_t& amp) const; + virtual void Print(const Option_t* opt) const; + +private: + + Int_t fId; //Absolute id + Int_t fNSamples; //Number of time samples + Int_t* fSamples; //[fNSamples] + + ClassDef(AliEMCALRawDigit,1) // Digit in EMCAL +}; +#endif + diff --git a/EMCAL/AliEMCALRawUtils.cxx b/EMCAL/AliEMCALRawUtils.cxx index edc4f5c7d17..a53b33b1a95 100644 --- a/EMCAL/AliEMCALRawUtils.cxx +++ b/EMCAL/AliEMCALRawUtils.cxx @@ -47,6 +47,7 @@ class AliCaloAltroMapping; #include "AliEMCALGeometry.h" class AliEMCALDigitizer; #include "AliEMCALDigit.h" +#include "AliEMCALRawDigit.h" #include "AliEMCAL.h" #include "AliCaloCalibPedestal.h" #include "AliCaloFastAltroFitv0.h" @@ -69,7 +70,7 @@ Double_t AliEMCALRawUtils::fgTimeTrigger = 1.5E-6 ; // 15 time bins ~ 1.5 muse // some digitization constants Int_t AliEMCALRawUtils::fgThreshold = 1; Int_t AliEMCALRawUtils::fgDDLPerSuperModule = 2; // 2 ddls per SuperModule -Int_t AliEMCALRawUtils::fgPedestalValue = 0; // pedestal value for digits2raw +Int_t AliEMCALRawUtils::fgPedestalValue = 0; // pedestal value for digits2raw, default generate ZS data Double_t AliEMCALRawUtils::fgFEENoise = 3.; // 3 ADC channels of noise (sampled) AliEMCALRawUtils::AliEMCALRawUtils(fitAlgorithm fitAlgo) @@ -100,8 +101,7 @@ AliEMCALRawUtils::AliEMCALRawUtils(fitAlgorithm fitAlgo) //To make sure we match with the geometry in a simulation file, //let's try to get it first. If not, take the default geometry AliRunLoader *rl = AliRunLoader::Instance(); - if(!rl) AliError("Cannot find RunLoader!"); - if (rl->GetAliRun() && rl->GetAliRun()->GetDetector("EMCAL")) { + if (rl && rl->GetAliRun() && rl->GetAliRun()->GetDetector("EMCAL")) { fGeom = dynamic_cast(rl->GetAliRun()->GetDetector("EMCAL"))->GetGeometry(); } else { AliInfo(Form("Using default geometry in raw reco")); @@ -309,7 +309,7 @@ void AliEMCALRawUtils::Digits2Raw() } //____________________________________________________________________________ -void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr, const AliCaloCalibPedestal* pedbadmap) +void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr, const AliCaloCalibPedestal* pedbadmap, TClonesArray *digitsTRG) { // convert raw data of the current event to digits @@ -339,15 +339,29 @@ void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr, // start loop over input stream while (in.NextDDL()) { + +// if ( in.GetDDLNumber() != 0 && in.GetDDLNumber() != 2 ) continue; + while (in.NextChannel()) { +/* + Int_t hhwAdd = in.GetHWAddress(); + UShort_t iiBranch = ( hhwAdd >> 11 ) & 0x1; // 0/1 + UShort_t iiFEC = ( hhwAdd >> 7 ) & 0xF; + UShort_t iiChip = ( hhwAdd >> 4 ) & 0x7; + UShort_t iiChannel = hhwAdd & 0xF; + + if ( !( iiBranch == 0 && iiFEC == 1 && iiChip == 3 && ( iiChannel >= 8 && iiChannel <= 15 ) ) && !( iiBranch == 1 && iiFEC == 0 && in.GetColumn() == 0 ) ) continue; +*/ + //Check if the signal is high or low gain and then do the fit, //if it is from TRU or LEDMon do not fit caloFlag = in.GetCaloFlag(); - if (caloFlag != 0 && caloFlag != 1) continue; - - //Do not fit bad channels - if(fRemoveBadChannels && pedbadmap->IsBadChannel(in.GetModule(),in.GetColumn(),in.GetRow())) { +// if (caloFlag != 0 && caloFlag != 1) continue; + if (caloFlag > 2) continue; // Work with ALTRO and FALTRO + + //Do not fit bad channels of ALTRO + if(caloFlag < 2 && fRemoveBadChannels && pedbadmap->IsBadChannel(in.GetModule(),in.GetColumn(),in.GetRow())) { //printf("Tower from SM %d, column %d, row %d is BAD!!! Skip \n", in.GetModule(),in.GetColumn(),in.GetRow()); continue; } @@ -357,9 +371,12 @@ void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr, bunchlist.push_back( AliCaloBunchInfo(in.GetStartTimeBin(), in.GetBunchLength(), in.GetSignals() ) ); } // loop over bunches - Float_t time = 0; - Float_t amp = 0; - + + if ( caloFlag < 2 ){ // ALTRO + + Float_t time = 0; + Float_t amp = 0; + if ( fFittingAlgorithm == kFastFit || fFittingAlgorithm == kNeuralNet || fFittingAlgorithm == kLMS || fFittingAlgorithm == kPeakFinder || fFittingAlgorithm == kCrude) { // all functionality to determine amp and time etc is encapsulated inside the Evaluate call for these methods AliCaloFitResults fitResults = fRawAnalyzer->Evaluate( bunchlist, in.GetAltroCFG1(), in.GetAltroCFG2()); @@ -429,12 +446,60 @@ void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr, AddDigit(digitsArr, id, lowGain, TMath::Nint(amp), time); } + }//ALTRO + else + {// Fake ALTRO + // if (maxTimeBin && gSig->GetN() > maxTimeBin + 10) gSig->Set(maxTimeBin + 10); // set actual max size of TGraph + + Int_t hwAdd = in.GetHWAddress(); + UShort_t iRCU = in.GetDDLNumber() % 2; // 0/1 + UShort_t iBranch = ( hwAdd >> 11 ) & 0x1; // 0/1 + + // Now find TRU number + Int_t itru = 3 * in.GetModule() + ( (iRCU << 1) | iBranch ) - 1; + + AliDebug(1,Form("Found TRG digit in TRU: %2d ADC: %2d",itru,in.GetColumn())); + + Int_t idtrg; + + Bool_t isOK = fGeom->GetAbsFastORIndexFromTRU(itru, in.GetColumn(), idtrg); + + Int_t timeSamples[256]; for (Int_t j=0;j<256;j++) timeSamples[j] = 0; + Int_t nSamples = 0; + + for (std::vector::iterator itVectorData = bunchlist.begin(); itVectorData != bunchlist.end(); itVectorData++) + { + AliCaloBunchInfo bunch = *(itVectorData); + + const UShort_t* sig = bunch.GetData(); + Int_t startBin = bunch.GetStartBin(); + + for (Int_t iS = 0; iS < bunch.GetLength(); iS++) + { + Int_t time = startBin--; + Int_t amp = sig[iS]; + + if ( amp ) timeSamples[nSamples++] = ( ( time << 12 ) & 0xFF000 ) | ( amp & 0xFFF ); + } + } + + if (nSamples && isOK) AddDigit(digitsTRG, idtrg, timeSamples, nSamples); + }//Fake ALTRO } // end while over channel } //end while over DDL's, of input stream return ; } +//____________________________________________________________________________ +void AliEMCALRawUtils::AddDigit(TClonesArray *digitsArr, Int_t id, Int_t timeSamples[], Int_t nSamples) +{ + new((*digitsArr)[digitsArr->GetEntriesFast()]) AliEMCALRawDigit(id, timeSamples, nSamples); + + // Int_t idx = digitsArr->GetEntriesFast()-1; + // AliEMCALRawDigit* d = (AliEMCALRawDigit*)digitsArr->At(idx); +} + //____________________________________________________________________________ void AliEMCALRawUtils::AddDigit(TClonesArray *digitsArr, Int_t id, Int_t lowGain, Int_t amp, Float_t time) { // @@ -713,8 +778,8 @@ Bool_t AliEMCALRawUtils::RawSampledResponse(const Double_t dtime, const Double_t Double_t signal=0.0, noise=0.0; for (Int_t iTime = 0; iTime < GetRawFormatTimeBins(); iTime++) { - signal = signalF.Eval(iTime) ; - + signal = signalF.Eval(iTime) ; + // Next lines commeted for the moment but in principle it is not necessary to add // extra noise since noise already added at the digits level. @@ -749,7 +814,8 @@ Bool_t AliEMCALRawUtils::RawSampledResponse(const Double_t dtime, const Double_t void AliEMCALRawUtils::SetFittingAlgorithm(Int_t fitAlgo) { //Set fitting algorithm and initialize it if this same algorithm was not set before. - + //printf("**** Set Algorithm , number %d ****\n",fitAlgo); + if(fitAlgo == fFittingAlgorithm && fRawAnalyzer) { //Do nothing, this same algorithm already set before. //printf("**** Algorithm already set before, number %d, %s ****\n",fitAlgo, fRawAnalyzer->GetName()); diff --git a/EMCAL/AliEMCALRawUtils.h b/EMCAL/AliEMCALRawUtils.h index 7a17da7dc12..68d3f133909 100644 --- a/EMCAL/AliEMCALRawUtils.h +++ b/EMCAL/AliEMCALRawUtils.h @@ -40,9 +40,11 @@ class AliEMCALRawUtils : public TObject { AliEMCALRawUtils& operator =(const AliEMCALRawUtils& rawUtils); void Digits2Raw(); - void Raw2Digits(AliRawReader *reader, TClonesArray *digitsArr, const AliCaloCalibPedestal* pedbadmap); + void Raw2Digits(AliRawReader *reader, TClonesArray *digitsArr, const AliCaloCalibPedestal* pedbadmap, + TClonesArray *digitsTRG=0x0); void AddDigit(TClonesArray *digitsArr, Int_t id, Int_t lowGain, Int_t amp, Float_t time); + void AddDigit(TClonesArray *digitsArr, Int_t id, Int_t timeSamples[], Int_t nSamples); // Signal shape parameters Double_t GetRawFormatHighLowGainFactor() const { return fHighLowGainFactor ;} diff --git a/EMCAL/AliEMCALReconstructor.cxx b/EMCAL/AliEMCALReconstructor.cxx index 3c907f7c5e7..e4c41b88a46 100644 --- a/EMCAL/AliEMCALReconstructor.cxx +++ b/EMCAL/AliEMCALReconstructor.cxx @@ -58,6 +58,9 @@ #include "AliCDBManager.h" #include "AliRunLoader.h" #include "AliRun.h" +#include "AliEMCALTriggerData.h" +#include "AliEMCALTriggerElectronics.h" +#include "AliVZEROLoader.h" ClassImp(AliEMCALReconstructor) @@ -65,6 +68,7 @@ const AliEMCALRecParam* AliEMCALReconstructor::fgkRecParam = 0; // EMCAL rec. p AliEMCALRawUtils* AliEMCALReconstructor::fgRawUtils = 0; // EMCAL raw utilities class AliEMCALClusterizer* AliEMCALReconstructor::fgClusterizer = 0; // EMCAL clusterizer class TClonesArray* AliEMCALReconstructor::fgDigitsArr = 0; // shoud read just once at event +AliEMCALTriggerElectronics* AliEMCALReconstructor::fgTriggerProcessor = 0x0; //____________________________________________________________________________ AliEMCALReconstructor::AliEMCALReconstructor() : fDebug(kFALSE), fList(0), fGeom(0),fCalibData(0),fPedestalData(0) @@ -111,6 +115,7 @@ AliEMCALReconstructor::AliEMCALReconstructor() if(!fGeom) AliFatal(Form("Could not get geometry!")); + fgTriggerProcessor = new AliEMCALTriggerElectronics(); } //____________________________________________________________________________ @@ -120,7 +125,8 @@ AliEMCALReconstructor::~AliEMCALReconstructor() delete fGeom; delete fgRawUtils; delete fgClusterizer; - + delete fgTriggerProcessor; + AliCodeTimer::Instance()->Print(); } @@ -145,6 +151,40 @@ void AliEMCALReconstructor::Reconstruct(TTree* digitsTree, TTree* clustersTree) ReadDigitsArrayFromTree(digitsTree); fgClusterizer->InitParameters(); fgClusterizer->SetOutput(clustersTree); + + AliEMCALTriggerData* trgData = new AliEMCALTriggerData(); + + Int_t bufferSize = 32000; + + if (TBranch* triggerBranch = clustersTree->GetBranch("EMTRG")) + triggerBranch->SetAddress(&trgData); + else + clustersTree->Branch("EMTRG","AliEMCALTriggerData",&trgData,bufferSize); + + AliVZEROLoader* vzeroLoader = dynamic_cast(AliRunLoader::Instance()->GetDetectorLoader("VZERO")); + + TTree* treeV0 = 0x0; + + if (vzeroLoader) + { + vzeroLoader->LoadDigits("READ"); + treeV0 = vzeroLoader->TreeD(); + } + + TClonesArray *trgDigits = new TClonesArray("AliEMCALRawDigit",1000); + TBranch *branchdig = digitsTree->GetBranch("EMTRG"); + if (!branchdig) + { + AliError("Can't get the branch with the EMCAL trigger digits !"); + return; + } + + branchdig->SetAddress(&trgDigits); + branchdig->GetEntry(0); + + fgTriggerProcessor->Digits2Trigger(trgDigits, treeV0, trgData); + + trgDigits->Delete(); if(fgDigitsArr && fgDigitsArr->GetEntries()) { @@ -159,6 +199,9 @@ void AliEMCALReconstructor::Reconstruct(TTree* digitsTree, TTree* clustersTree) } + clustersTree->Fill(); + + delete trgData; } //____________________________________________________________________________ @@ -172,8 +215,11 @@ void AliEMCALReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digits rawReader->Reset() ; TClonesArray *digitsArr = new TClonesArray("AliEMCALDigit",200); + TClonesArray *digitsTrg = new TClonesArray("AliEMCALRawDigit", 200); + Int_t bufsize = 32000; digitsTree->Branch("EMCAL", &digitsArr, bufsize); + digitsTree->Branch("EMTRG", &digitsTrg, bufsize); //must be done here because, in constructor, option is not yet known fgRawUtils->SetOption(GetOption()); @@ -186,11 +232,13 @@ void AliEMCALReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digits fgRawUtils->SetRemoveBadChannels(GetRecParam()->GetRemoveBadChannels()); fgRawUtils->SetFittingAlgorithm(GetRecParam()->GetFittingAlgorithm()); - fgRawUtils->Raw2Digits(rawReader,digitsArr,fPedestalData); + fgRawUtils->Raw2Digits(rawReader,digitsArr,fPedestalData,digitsTrg); digitsTree->Fill(); digitsArr->Delete(); + digitsTrg->Delete(); delete digitsArr; + delete digitsTrg; } @@ -514,3 +562,4 @@ void AliEMCALReconstructor::ReadDigitsArrayFromTree(TTree *digitsTree) const branch->GetEntry(0); } + diff --git a/EMCAL/AliEMCALReconstructor.h b/EMCAL/AliEMCALReconstructor.h index 8b491f9294b..36d9ef7f6b4 100644 --- a/EMCAL/AliEMCALReconstructor.h +++ b/EMCAL/AliEMCALReconstructor.h @@ -39,6 +39,7 @@ class AliEMCALRawUtils; class AliEMCALGeometry; class AliEMCALCalibData ; class AliCaloCalibPedestal ; +class AliEMCALTriggerElectronics; // --- Standard library --- @@ -98,8 +99,11 @@ private: AliEMCALCalibData * fCalibData ; //! Calibration database if aval AliCaloCalibPedestal * fPedestalData ; //! Tower status database if aval - ClassDef(AliEMCALReconstructor,8) // Reconstruction algorithm class (Base Class) + static AliEMCALTriggerElectronics* fgTriggerProcessor; + + ClassDef(AliEMCALReconstructor,9) // Reconstruction algorithm class (Base Class) }; #endif // ALIEMCALRECONSTRUCTOR_H + diff --git a/EMCAL/AliEMCALShishKebabTrd1Module.cxx b/EMCAL/AliEMCALShishKebabTrd1Module.cxx index a1839de41a6..6759ef872fb 100644 --- a/EMCAL/AliEMCALShishKebabTrd1Module.cxx +++ b/EMCAL/AliEMCALShishKebabTrd1Module.cxx @@ -66,7 +66,7 @@ AliEMCALShishKebabTrd1Module::AliEMCALShishKebabTrd1Module(Double_t theta, AliEM } } else Warning("AliEMCALShishKebabTrd1Module(theta)","You should call this constractor just once !!"); DefineName(fTheta); - AliInfo(Form("AliEMCALShishKebabTrd1Module - first module: theta %1.4f geometry %s",fTheta,g->GetName())); + AliDebug(1,Form("AliEMCALShishKebabTrd1Module - first module: theta %1.4f geometry %s",fTheta,g->GetName())); } //_____________________________________________________________________________ diff --git a/EMCAL/AliEMCALTriggerBoard.cxx b/EMCAL/AliEMCALTriggerBoard.cxx new file mode 100644 index 00000000000..8a6c7074cb6 --- /dev/null +++ b/EMCAL/AliEMCALTriggerBoard.cxx @@ -0,0 +1,173 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + +/* + + +EMCal trigger board super class +run the sliding window algorithm +Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 +*/ + +#include "AliEMCALTriggerBoard.h" +#include "AliEMCALTriggerPatch.h" + +#include + +#include + +ClassImp(AliEMCALTriggerBoard) + +//_______________ +AliEMCALTriggerBoard::AliEMCALTriggerBoard() : TObject(), +fRegion(0x0), +fMap(0x0), +fRegionSize(0x0), +fSubRegionSize(0x0), +fPatchSize(0x0), +fPatches( new TClonesArray("AliEMCALTriggerPatch",10) ) +{ + +} + +//_______________ +AliEMCALTriggerBoard::AliEMCALTriggerBoard(const AliEMCALCalibData */*calibData*/, const TVector2& RS) : TObject(), +fRegion(0x0), +fMap(0x0), +fRegionSize( new TVector2( RS ) ), +fSubRegionSize( new TVector2() ), +fPatchSize( new TVector2() ), +fPatches( new TClonesArray("AliEMCALTriggerPatch",10) ) +{ + fRegion = (int**)malloc( (int)fRegionSize->X() * sizeof( int* ) ); + + if (!fRegion) printf("Error: malloc could not allocate %d bytes for fRegion\n", + int(fRegionSize->X() * sizeof( int* ))); + + fMap = (int**)malloc( (int)fRegionSize->X() * sizeof( int* ) ); + + if (!fMap) printf("Error: malloc could not allocate %d bytes for fMap\n", + int(fRegionSize->X() * sizeof( int* ))); + + for (Int_t i=0;iX();i++) + { + fRegion[i] = (int*)malloc( (int)fRegionSize->Y() * sizeof( int ) ); + + if (!fRegion[i]) printf("Error: malloc could not allocate %d bytes for fRegion[%d]\n", + i,int(fRegionSize->Y() * sizeof( int ))); + + fMap[i] = (int*)malloc( (int)fRegionSize->Y() * sizeof( int ) ); + + if (!fMap[i]) printf("Error: malloc could not allocate %d bytes for fMap[%d]\n", + i,int(fRegionSize->Y() * sizeof( int ))); + } + + // Initialize region matrix + ZeroRegion(); + + for (int i=0; iX(); ++i) + for (int j=0; jY(); ++j) fMap[i][j] = 0; +} + +//_______________ +AliEMCALTriggerBoard::~AliEMCALTriggerBoard() +{ + for (Int_t i=0;iX();i++) + { + if (fRegion[i]) {delete fRegion[i]; fRegion[i] = 0;} + if ( fMap[i]) {delete fMap[i]; fMap[i] = 0;} + } + + delete [] fRegion; fRegion = 0x0; + delete [] fMap; fMap = 0x0; + + fPatches->Delete(); +} + +//_______________ +void AliEMCALTriggerBoard::ZeroRegion() +{ + // + for (Int_t i=0;iX());i++) for (Int_t j=0;jY());j++) fRegion[i][j] = 0; +} + +//_______________ +void AliEMCALTriggerBoard::SlidingWindow( L1TriggerType_t /*type*/, Int_t thres ) +{ + // + Int_t ipatch = 0; + + for (Int_t i=0; i<=int(fRegionSize->X()-fPatchSize->X()*fSubRegionSize->X()); i+=int(fSubRegionSize->X())) + { + for (Int_t j=0; j<=int(fRegionSize->Y()-fPatchSize->Y()*fSubRegionSize->Y()); j+=int(fSubRegionSize->Y())) + { + ipatch++; + + Int_t sum = 0; + + for (Int_t k=0; kX()*fSubRegionSize->X()); k++) + { + for (Int_t l=0; lY()*fSubRegionSize->Y()); l++) + { + sum += fRegion[i+k][j+l]; + } + } + + if ( sum > thres ) + { + //if ( type == kJet ) sum /= 4; // truncate patch sum for jet case + + new((*fPatches)[fPatches->GetLast()+1]) + AliEMCALTriggerPatch( int(i/fSubRegionSize->X()), int(j/fSubRegionSize->Y()), int(sum) ); + } + } + } +} + +//__________ +void AliEMCALTriggerBoard::Scan() +{ + // + cout << " "; + for (Int_t i=0; iX()); i++) printf("%8d ",i); + cout << "\n"; + for (Int_t i=0; iX())-5; i++) printf("-------"); + cout << "\n"; + + for (Int_t i=0; iY()); i++) + { + if (i && !(i%12)) + { + for (Int_t j=0; jX())-5; j++) printf("-------"); + cout << endl; + } + + printf("%3d |",i); + for (Int_t j=0; jX()); j++) + { + printf("%2d/%5d ", fMap[j][i], fRegion[j][i]); + } + cout << endl; + } +} + +//__________ +void AliEMCALTriggerBoard::Reset() +{ + // + fPatches->Delete(); + ZeroRegion(); +} + diff --git a/EMCAL/AliEMCALTriggerBoard.h b/EMCAL/AliEMCALTriggerBoard.h new file mode 100644 index 00000000000..3b5921e174e --- /dev/null +++ b/EMCAL/AliEMCALTriggerBoard.h @@ -0,0 +1,68 @@ +#ifndef ALIEMCALTRIGGERBOARD_H +#define ALIEMCALTRIGGERBOARD_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* +EMCal trigger board super class +run the sliding window algorithm +Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 +*/ + +#include "TVector2.h" + +class TClonesArray; +class AliEMCALCalibData; + +typedef enum { kGamma, kJet } L1TriggerType_t; + +class AliEMCALTriggerBoard : public TObject +{ + +public: + AliEMCALTriggerBoard(); + AliEMCALTriggerBoard(const AliEMCALCalibData *calibData, const TVector2& RegionSize); + virtual ~AliEMCALTriggerBoard(); + + virtual void SlidingWindow(L1TriggerType_t type, Int_t Threshold); + + virtual void ZeroRegion(); + + virtual void Scan(); + virtual void Reset(); + + virtual void PatchSize(TVector2& Size) const {Size = *fPatchSize;} + virtual TVector2* PatchSize( ) const { return fPatchSize;} + virtual void RegionSize(TVector2& Size) const {Size = *fRegionSize;} + virtual TVector2* RegionSize( ) const { return fRegionSize;} + virtual void SubRegionSize(TVector2& Size) const {Size = *fSubRegionSize;} + virtual TVector2* SubRegionSize( ) const { return fSubRegionSize;} + + virtual const TClonesArray& Patches() const {return *fPatches;} + + virtual void SetRegionSize(const TVector2& Size) { *fRegionSize = Size;} + virtual void SetPatchSize(const TVector2& Size) { *fPatchSize = Size;} + virtual void SetSubRegionSize(const TVector2& Size) { *fSubRegionSize = Size;} + + virtual Int_t** Region() {return fRegion;} + virtual Int_t** Map() {return fMap;} + virtual void Map(Int_t arr[][64], const TVector2& Size) {for (Int_t i=0;iGetEntriesFast(); + + fL0NPatches[i] = new_size; + + Int_t size = 0; + for (Int_t j=0;j<=i;j++) size += fL0NPatches[j]; + + fL0Patches->Expand( size ); + + for (Int_t j=0;j( patches.At(j) ); + new((*fL0Patches)[old_size+j]) AliEMCALTriggerPatch( *p ); + } +} + +//_____________ +void AliEMCALTriggerData::SetL1GammaPatches(const TClonesArray& patches) +{ + Int_t size = patches.GetEntriesFast(); + fL1GammaPatches->Expand( size ); + + for (Int_t j=0;j( patches.At(j) ); + new((*fL1GammaPatches)[j]) AliEMCALTriggerPatch( *p ); + } +} + +//_____________ +void AliEMCALTriggerData::SetL1JetPatches(const TClonesArray& patches) +{ + Int_t size = patches.GetEntriesFast(); + + fL1JetPatches->Expand( size ); + + for (Int_t j=0;j( patches.At(j) ); + new((*fL1JetPatches)[j]) AliEMCALTriggerPatch( *p ); + } +} + +//_____________ +void AliEMCALTriggerData::SetL1Region(Int_t**& region) +{ + // + for (Int_t i=0;i<48;i++) + for (Int_t j=0;j<64;j++) + { + fL1Region[i][j] = region[i][j]; + } +} + +//_____________ +void AliEMCALTriggerData::SetL1V0(const Int_t*& arr) +{ + for (Int_t i=0;i<2;i++) fL1V0[i] = arr[i]; +} + +//_____________ +void AliEMCALTriggerData::Scan() const +{ + // + printf("L0:\n"); + for (Int_t i=0;i<32;i++) printf("\tFound %2d patches in TRU %2d\n",fL0NPatches[i],i); + + printf("L1:\n"); + printf("\tRegion of size.....................(%2d,%2d)\n",int(fL1RegionSize.X()),int(fL1RegionSize.Y())); + printf("\tGamma sub-region size..............(%2d,%2d)\n",int(fL1GammaSubRegionSize.X()),int(fL1GammaSubRegionSize.Y())); + printf("\tJet sub-region size................(%2d,%2d)\n",int(fL1JetSubRegionSize.X()),int(fL1JetSubRegionSize.Y())); + printf("\tFound %4d gamma patches of size...(%2d,%2d)\n",fL1GammaPatches->GetEntriesFast(),int(fL1GammaPatchSize.X()),int(fL1GammaPatchSize.Y())); + printf("\tFound %4d jet patches of size.....(%2d,%2d)\n",fL1JetPatches->GetEntriesFast(),int(fL1JetPatchSize.X()),int(fL1JetPatchSize.Y())); +} + +//_____________ +void AliEMCALTriggerData::Reset() +{ + // + if (fL0Patches) fL0Patches->Delete(); + if (fL1GammaPatches) fL1GammaPatches->Delete(); + if (fL1JetPatches) fL1JetPatches->Delete(); + + for (Int_t i=0;i<32;i++) fL0NPatches[i] = 0; + for (Int_t i=0;i<48;i++) for (Int_t j=0;j<64;j++) fL1Region[i][j] = 0; + fL1V0[0] = fL1V0[1] = 0; +} + + + diff --git a/EMCAL/AliEMCALTriggerData.h b/EMCAL/AliEMCALTriggerData.h new file mode 100644 index 00000000000..8fd162803fa --- /dev/null +++ b/EMCAL/AliEMCALTriggerData.h @@ -0,0 +1,103 @@ +#ifndef ALIEMCALTRIGGERDATA_H +#define ALIEMCALTRIGGERDATA_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* +EMCal trigger data container +for persistency of produced data presently stored in TTreeD +Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 +*/ + +#include +#include + +//#include +//#include + +#include + +class AliEMCALTriggerData : public TObject +{ + +public: + AliEMCALTriggerData(); + virtual ~AliEMCALTriggerData(); + + virtual void SetL0Patches(Int_t i, const TClonesArray& patches); + virtual void SetL0RegionSize( TVector2 size ) { fL0RegionSize = size; } + virtual void SetL0SubRegionSize( TVector2 size ) { fL0SubRegionSize = size; } + virtual void SetL0PatchSize( TVector2 size ) { fL0PatchSize = size; } + virtual void SetL0Peaks(Int_t v, Int_t arr[96][2] ) { for (Int_t i=0;i<96;i++) for (Int_t j=0;j<2;j++) fL0Peaks[v][i][j] = arr[i][j]; } + + virtual void SetL1GammaPatches(const TClonesArray& patches); + virtual void SetL1JetPatches(const TClonesArray& patches); + + virtual void SetL1Region(Int_t**& region); + virtual void SetL1V0(const Int_t*& arr); + + virtual void SetL1RegionSize( TVector2 size ) { fL1RegionSize = size; } + virtual void SetL1GammaPatchSize( TVector2 size ) { fL1GammaPatchSize = size; } + virtual void SetL1GammaSubRegionSize( TVector2 size ) { fL1GammaSubRegionSize = size; } + virtual void SetL1JetPatchSize( TVector2 size ) { fL1JetPatchSize = size; } + virtual void SetL1JetSubRegionSize( TVector2 size ) { fL1JetSubRegionSize = size; } + + virtual void L0Patches( TClonesArray& patches ) const { patches = *fL0Patches; } + virtual TClonesArray* L0Patches( ) const { return fL0Patches; } + virtual void L0RegionSize( TVector2 size ) const { size = fL0RegionSize; } + virtual TVector2 L0RegionSize( ) const { return fL0RegionSize; } + virtual void L0PatchSize( TVector2 size ) const { size = fL0PatchSize; } + virtual TVector2 L0PatchSize( ) const { return fL0PatchSize; } + virtual void L0SubRegionSize( TVector2 size ) const { size = fL0SubRegionSize; } + virtual TVector2 L0SubRegionSize( ) const { return fL0SubRegionSize; } + virtual void L0NPatches( Int_t arr[32] ) const { for (Int_t i=0;i<32;i++) arr[i] = fL0NPatches[i]; } + virtual void L0Peaks( Int_t arr[32][96][2] ) const { + for (Int_t i=0;i<32;i++) for (Int_t j=0;j<96;j++) for (Int_t k=0;k<2;k++) arr[i][j][k] = fL0Peaks[i][j][k]; } + + virtual void L1GammaPatches( TClonesArray& patches ) const { patches = *fL1GammaPatches; } + virtual TClonesArray* L1GammaPatches( ) const { return fL1GammaPatches; } + virtual void L1JetPatches( TClonesArray& patches ) const { patches = *fL1JetPatches; } + virtual TClonesArray* L1JetPatches( ) const { return fL1JetPatches; } + virtual void L1Region( Int_t arr[][64] ) const { for (Int_t i=0;i<48;i++) for (Int_t j=0;j<64;j++) { arr[i][j] = fL1Region[i][j]; } } + virtual Int_t* L1V0( ) { return &fL1V0[0]; } + virtual void L1RegionSize( TVector2& size ) const { size = fL1RegionSize; } + virtual TVector2 L1RegionSize( ) const { return fL1RegionSize; } + virtual void L1GammaPatchSize( TVector2& size ) const { size = fL1GammaPatchSize; } + virtual TVector2 L1GammaPatchSize( ) const { return fL1GammaPatchSize; } + virtual void L1GammaSubRegionSize( TVector2& size ) const { size = fL1GammaSubRegionSize; } + virtual TVector2 L1GammaSubRegionSize( ) const { return fL1GammaSubRegionSize; } + virtual void L1JetPatchSize( TVector2& size ) const { size = fL1JetPatchSize; } + virtual TVector2 L1JetPatchSize( ) const { return fL1JetPatchSize; } + virtual void L1JetSubRegionSize( TVector2& size ) const { size = fL1JetSubRegionSize; } + virtual TVector2 L1JetSubRegionSize( ) const { return fL1JetSubRegionSize; } + + virtual void Scan() const; + + virtual void Reset(); + +private: + + AliEMCALTriggerData(const AliEMCALTriggerData& rhs); // NOT implemented + AliEMCALTriggerData& operator=(const AliEMCALTriggerData& rhs); // NOT implemented + + TClonesArray* fL0Patches; // array of patches + Int_t fL0NPatches[32]; + TVector2 fL0RegionSize; // region size in units of fast or + TVector2 fL0SubRegionSize; // subregion size in units of fast or + TVector2 fL0PatchSize; // patch size in units of subregion + Int_t fL0Peaks[32][96][2]; // max & pos of the max for ADC channels + + TClonesArray* fL1GammaPatches; // array of patches + TClonesArray* fL1JetPatches; // array of patches + Int_t fL1Region[48][64]; // STU FastOR 48-by-124 + Int_t fL1V0[2]; // V0A V0C multiplicity estimates + TVector2 fL1RegionSize; // region size in units of fast or + TVector2 fL1GammaPatchSize; // patch size in units of subregion + TVector2 fL1GammaSubRegionSize; // subregion size in units of fast or + TVector2 fL1JetPatchSize; // patch size in units of subregion + TVector2 fL1JetSubRegionSize; // subregion size in units of fast or + + ClassDef(AliEMCALTriggerData,1) +}; + +#endif diff --git a/EMCAL/AliEMCALTriggerElectronics.cxx b/EMCAL/AliEMCALTriggerElectronics.cxx new file mode 100644 index 00000000000..e78c6b010b6 --- /dev/null +++ b/EMCAL/AliEMCALTriggerElectronics.cxx @@ -0,0 +1,218 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + +/* + + +EMCal trigger electronics manager L0/L1 +can handle both simulated digits and raw data +Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 +*/ + +#include "AliEMCALTriggerElectronics.h" +#include "AliEMCALTriggerTRU.h" +#include "AliEMCALTriggerSTU.h" +#include "AliEMCALGeometry.h" +#include "AliRunLoader.h" +#include "AliEMCAL.h" +#include "AliRun.h" +#include "AliEMCALTriggerData.h" +#include "AliEMCALDigit.h" +#include "AliCaloRawStreamV3.h" +//#include "AliVZERORawStream.h" +#include "AliEMCALTriggerSTURawStream.h" +#include "AliEMCALDigit.h" +#include "AliEMCALRawDigit.h" + +#include +#include +//#include + +namespace +{ + const Int_t kNTRU = 32; +} + +ClassImp(AliEMCALTriggerElectronics) + +//__________________ +AliEMCALTriggerElectronics::AliEMCALTriggerElectronics(AliEMCALCalibData *calibData) : TObject(), +fTRU(new TClonesArray("AliEMCALTriggerTRU",32)), +fSTU(0x0) +{ + TVector2 rSize; + + rSize.Set( 24., 4. ); + + // 32 TRUs + for (Int_t i=0;iBuildMap( i, + (static_cast(fTRU->At(i)))->Map(), + (static_cast(fTRU->At(i)))->RegionSize() + ); +} + +//________________ +AliEMCALTriggerElectronics::~AliEMCALTriggerElectronics() +{ + // + fTRU->Delete(); + delete fSTU; +} + +//__________________ +void AliEMCALTriggerElectronics::Digits2Trigger(const TClonesArray* digits, const TTree* treeV0, AliEMCALTriggerData* data) +{ + // + AliEMCALGeometry* geom = 0x0; + + AliRunLoader *rl = AliRunLoader::Instance(); + if (rl->GetAliRun() && rl->GetAliRun()->GetDetector("EMCAL")) + geom = dynamic_cast(rl->GetAliRun()->GetDetector("EMCAL"))->GetGeometry(); + else + geom = AliEMCALGeometry::GetInstance(AliEMCALGeometry::GetDefaultGeometryName()); + + if (!geom) AliError("Cannot access geometry!"); + + TIter NextDigit(digits); + while (AliEMCALRawDigit* digit = (AliEMCALRawDigit*)NextDigit()) + { + if ( digit ) + { + Int_t id = digit->GetId(); + +// digit->Print(); + + Int_t iTRU, iADC; + Bool_t isOK1 = geom->GetTRUFromAbsFastORIndex(id, iTRU, iADC); + + for (Int_t i = 0; i < digit->GetNSamples(); i++) + { + Int_t time, amp; + Bool_t isOK2 = digit->GetTimeSample(i, time, amp); + + if (isOK1 && isOK2 && amp) (static_cast(fTRU->At(iTRU)))->SetADC(iADC, time, amp); + } + } + } + /* + for (Int_t i=0; i============\n",i); + (static_cast(fTRU->At(i)))->Scan(); + } + */ + Int_t iL0 = 0; + + // At this point all FastOR are available for digitization + // digitization is done in the TRU and produces time samples + // Now run the trigger algo & consecutively write trigger outputs in TreeD dedicated branch + + for (Int_t i=0; i============\n",i)); + + AliEMCALTriggerTRU *iTRU = static_cast(fTRU->At(i)); + + iL0 += iTRU->L0v1(); + + Int_t vL0Peaks[96][2]; iTRU->Peaks( vL0Peaks ); + + data->SetL0Patches( i , iTRU->Patches() ); + data->SetL0Peaks( i , vL0Peaks ); + + if ( !i ) // do it once since identical for all TRU + { + data->SetL0RegionSize( *iTRU->RegionSize() ); + data->SetL0SubRegionSize( *iTRU->SubRegionSize() ); + data->SetL0PatchSize( *iTRU->PatchSize() ); + } + + // if ( i == 31 ) i = 35; + // + // if ( ( i / 3 ) % 2 ) { + // TRU->Print( 15 - 2 + ( i - int( i / 3 ) * 3 ) - 3 * ( (i / 3) / 2 ) , runLoader->GetEventNumber() ); + // printf("print data of TRU: from %2d to %2d\n",i,15 - 2 + ( i - int( i / 3 ) * 3 ) - 3 * ( (i / 3) / 2)); + // } + // else + // { + // TRU->Print( 31 - i % 3 - 3 * ( (i / 3) / 2 ) , runLoader->GetEventNumber() ); + // printf("print data of TRU: from %2d to %2d\n",i,31 - i % 3 - 3 * ( (i / 3) / 2 )); + // } + } + + // A L0 has been issued, run L1 + if ( iL0 ) + { + for (Int_t i=0; iFetchFOR( i, + (static_cast(fTRU->At(i)))->Region(), + (static_cast(fTRU->At(i)))->RegionSize() + ); + +// fSTU->Scan(); + + TTree* tr = const_cast(treeV0); + if ( tr ) fSTU->V0Multiplicity( *tr ); + + TVector2 size; + + size.Set( 1. , 1. ); + fSTU->SetSubRegionSize( size ); data->SetL1GammaSubRegionSize( size ); + + size.Set( 2. , 2. ); + fSTU->SetPatchSize( size ); data->SetL1GammaPatchSize( size ); + + fSTU->L1( kGamma ); + + data->SetL1GammaPatches( fSTU->Patches() ); + + fSTU->Reset(); + + size.Set( 4. , 4. ); + fSTU->SetSubRegionSize( size ); data->SetL1JetSubRegionSize( size ); + + size.Set( 2. , 2. ); + fSTU->SetPatchSize( size ); data->SetL1JetPatchSize( size ); + + fSTU->L1( kJet ); + + data->SetL1JetPatches( fSTU->Patches() ); + data->SetL1RegionSize( *fSTU->RegionSize() ); + + Int_t** region = fSTU->Region(); + data->SetL1Region( region ); + const Int_t* mv0 = fSTU->V0(); + data->SetL1V0( mv0 ); + } + + // Now reset the electronics for a fresh start with next event + Reset(); +} + +//__________________ +void AliEMCALTriggerElectronics::Reset() +{ + // + TIter NextTRU(fTRU); + while ( AliEMCALTriggerTRU *TRU = (AliEMCALTriggerTRU*)NextTRU() ) TRU->Reset(); + + fSTU->Reset(); +} diff --git a/EMCAL/AliEMCALTriggerElectronics.h b/EMCAL/AliEMCALTriggerElectronics.h new file mode 100644 index 00000000000..445f04acc43 --- /dev/null +++ b/EMCAL/AliEMCALTriggerElectronics.h @@ -0,0 +1,48 @@ +#ifndef ALIEMCALTRIGGERELECTRONICS_H +#define ALIEMCALTRIGGERELECTRONICS_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* +EMCal trigger electronics manager L0/L1 +can handle both simulated digits and raw data +Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 +*/ + +#ifndef ROOT_TObject +# include "TObject.h" +#endif +#include "TClonesArray.h" + +class AliRawReader; +class AliEMCALCalibData; +class TTree; +class AliEMCALTriggerData; +class AliEMCALTriggerSTU; +class AliESDVZERO; +class AliEMCALTriggerTRU; + +class AliEMCALTriggerElectronics : public TObject +{ +public: + AliEMCALTriggerElectronics(AliEMCALCalibData* calibData = 0x0); // ctor + virtual ~AliEMCALTriggerElectronics(); // dtor + + virtual void Digits2Trigger(const TClonesArray* digits, const TTree* treeV0, AliEMCALTriggerData* data); + virtual void Reset(); + + virtual AliEMCALTriggerTRU* GetTRU( Int_t iTRU ) {return (AliEMCALTriggerTRU*)fTRU->At(iTRU);} + virtual AliEMCALTriggerSTU* GetSTU( ) {return fSTU;} + +private: + + AliEMCALTriggerElectronics(const AliEMCALTriggerElectronics& other); // Not implemented + AliEMCALTriggerElectronics& operator=(const AliEMCALTriggerElectronics& other); // Not implemented + + TClonesArray* fTRU; // 32 TRU + AliEMCALTriggerSTU* fSTU; // 1 STU + + ClassDef(AliEMCALTriggerElectronics,1) +}; + +#endif diff --git a/EMCAL/AliEMCALTriggerPatch.cxx b/EMCAL/AliEMCALTriggerPatch.cxx new file mode 100644 index 00000000000..d4802688281 --- /dev/null +++ b/EMCAL/AliEMCALTriggerPatch.cxx @@ -0,0 +1,114 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + +/* + + + +Patch object implementation: one patch is made of subregions (Olivier's nomenclature) +Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 +*/ + +#include "AliEMCALTriggerPatch.h" +#include "AliRunLoader.h" +#include "AliRun.h" +#include "AliEMCALGeometry.h" +#include "AliEMCAL.h" + +#include "TArrayI.h" + +ClassImp(AliEMCALTriggerPatch) + +//____________ +AliEMCALTriggerPatch::AliEMCALTriggerPatch() : TObject(), +fPosition(0x0), +fSum(0) +{ + // Default constructor +} + +//____________ +AliEMCALTriggerPatch::AliEMCALTriggerPatch( Int_t i, Int_t j, Int_t k ) : TObject(), +fPosition(new TVector2( i , j )), +fSum(k) +{ +} + +//____________ + +//____________________________________________________________________ +AliEMCALTriggerPatch::AliEMCALTriggerPatch(const AliEMCALTriggerPatch& other) : TObject(other), +fPosition( new TVector2(*other.fPosition) ), +fSum( other.fSum ) +{ + // Copy ctor +} + +//____________ +AliEMCALTriggerPatch::~AliEMCALTriggerPatch() +{ + if (fPosition) delete fPosition; +} + +//____________ +void AliEMCALTriggerPatch::Print(const Option_t*) const +{ + printf("]> Patch at (%2d , %2d) w/ sum %3d\n", + (int)fPosition->X(),(int)fPosition->Y(),fSum); +} + +//________________ +void AliEMCALTriggerPatch::GetAbsCellIdsFromPatchPosition( TVector2& pSize, TVector2& sSize, TArrayI& absid ) +{ + AliRunLoader* runLoader = AliRunLoader::Instance(); + AliEMCALGeometry* geom = dynamic_cast(runLoader->GetAliRun()->GetDetector("EMCAL"))->GetGeometry(); + + Int_t nTowersinpatch = pSize.X() * pSize.Y() * sSize.X() * sSize.Y() * 4; + + absid.Set( nTowersinpatch ); + + // fPosition: patch position in the STU region + Int_t ix = ( fPosition->X() + pSize.X() ) * sSize.X(); + Int_t iy = ( fPosition->Y() + pSize.Y() ) * sSize.Y(); + + Int_t it = 0; + + for (Int_t i=fPosition->X() * sSize.X(); iY() * sSize.Y(); jGetCellPhiEtaIndexInSModule(nSupMod, nModule, k, l, iphi, ieta); + + absid.SetAt( geom->GetAbsCellIdFromCellIndexes(nSupMod, iphi, ieta) , it++ ); + } + } + } + } +} diff --git a/EMCAL/AliEMCALTriggerPatch.h b/EMCAL/AliEMCALTriggerPatch.h new file mode 100644 index 00000000000..0f532fd49a9 --- /dev/null +++ b/EMCAL/AliEMCALTriggerPatch.h @@ -0,0 +1,43 @@ +#ifndef ALIEMCALTRIGGERPATCH_H +#define ALIEMCALTRIGGERPATCH_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* + +Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 +*/ + +#ifndef ROOT_TObject +# include "TObject.h" +#endif + +#include "TVector2.h" + +class TArrayI; + +class AliEMCALTriggerPatch : public TObject { + +public: + AliEMCALTriggerPatch(); // default ctor + AliEMCALTriggerPatch(const AliEMCALTriggerPatch& other); // copy ctor + AliEMCALTriggerPatch(Int_t i, Int_t j, Int_t e); + virtual ~AliEMCALTriggerPatch(); + + void Position(TVector2& pos) const {pos = *fPosition;} + TVector2* Position( ) const {return fPosition;} + Int_t Sum() const {return fSum;} // in ADC counts + void Print(const Option_t*) const; + void GetAbsCellIdsFromPatchPosition(TVector2& psize, TVector2& ssize, TArrayI& absid); + +private: + + AliEMCALTriggerPatch& operator=(const AliEMCALTriggerPatch& other); // Not implemented + + TVector2* fPosition; + Int_t fSum; + + ClassDef(AliEMCALTriggerPatch,1) +}; + +#endif diff --git a/EMCAL/AliEMCALTriggerSTU.cxx b/EMCAL/AliEMCALTriggerSTU.cxx new file mode 100644 index 00000000000..60a395f3b49 --- /dev/null +++ b/EMCAL/AliEMCALTriggerSTU.cxx @@ -0,0 +1,347 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + +/* + + + + +Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 +*/ + +#include "AliEMCALTriggerSTU.h" +#include "AliCDBManager.h" +#include "AliCDBEntry.h" +#include "AliEMCALCalibData.h" +#include "AliVZEROCalibData.h" +#include "AliVZEROdigit.h" +#include "AliEMCALTriggerPatch.h" +#include "AliESDVZERO.h" +#include "AliLog.h" + +#include +#include +#include +#include +#include + +#include +#include + +ClassImp(AliEMCALTriggerSTU) + +//_______________ +AliEMCALTriggerSTU::AliEMCALTriggerSTU() : AliEMCALTriggerBoard() +{ + // + fV0M[0] = fV0M[1] = 0; +} + +//_______________ +AliEMCALTriggerSTU::AliEMCALTriggerSTU(AliEMCALCalibData *calibData, const TVector2& RS) : +AliEMCALTriggerBoard(calibData, RS) +{ + // + fV0M[0] = fV0M[1] = 0; +} + +//_______________ +AliEMCALTriggerSTU::~AliEMCALTriggerSTU() +{ + // +} + +//_______________ +void AliEMCALTriggerSTU::BuildMap( Int_t iTRU, Int_t** M, const TVector2* rSize ) +{ + // + if ( iTRU == 31 ) iTRU = 35; + + Int_t i2y = iTRU / 3 / 2; + + if ( ( iTRU / 3 ) % 2 ) // odd (z<0) C side + { + Int_t i1y = 2 - ( iTRU - int( iTRU / 3 ) * 3 ); // 0 1 2 w/ increasing phi + + for (Int_t i=0; iX(); i++) + for (Int_t j=0; jY(); j++) fMap[24+i][j + i1y * 4 + i2y * 12] = M[i][j]; + } + else // A side + { + Int_t i1y = iTRU - int( iTRU / 3 ) * 3; + + for (Int_t i=0; iX(); i++) + for (Int_t j=0; jY(); j++) fMap[ i][j + i1y * 4 + i2y * 12] = M[i][j]; + } +} + +//_______________ +void AliEMCALTriggerSTU::L1( L1TriggerType_t type ) +{ + // + SlidingWindow( type, int(ThresholdFromV0( type )) ); +} + +//________________ +void AliEMCALTriggerSTU::PrintADC( L1TriggerType_t type, TVector2& pos, TVector2& idx ) +{ + // + Int_t ix = ( pos.X() + fPatchSize->X() ) * fSubRegionSize->X(); + Int_t iy = ( pos.Y() + fPatchSize->Y() ) * fSubRegionSize->Y(); + + TString subRegionADC[] = {"0->15", "16->31", "32->47", "48->63", "64->79", "80->95"}; + + switch ( type ) + { + case kGamma: + { + Int_t iTRU = ( (ix-1) < 24 ) ? 31 - int(pos.Y() / 4) : 15 - int(pos.Y() / 4); + + printf("TRU #%d row #%d col #%d fastor: ",iTRU,int(idx.Y()),int(idx.X())); + + for (Int_t i=pos.X() * fSubRegionSize->X();iY();jX();iY();j> 3) << "_" << subRegionADC[(vPair[i] & 0x7)]; + } + + cout << endl; + if (vPair) delete[] vPair; + } + break; + default: + AliError("AliEMCALTriggerSTU::PrintADC(): Undefined trigger type, pls check!"); + } +} + +//________________ +void AliEMCALTriggerSTU::V0Multiplicity( TTree& treeV0 ) +{ + // + AliCDBManager *man = AliCDBManager::Instance(); + AliCDBEntry *entry = man->Get("VZERO/Calib/Data"); + AliVZEROCalibData *calibdata = (AliVZEROCalibData*)entry->GetObject(); + + TClonesArray* digitsArray = 0x0; + treeV0.SetBranchAddress("VZERODigit",&digitsArray); + + Float_t mult[64]; + Short_t adc[64]; + + for (Int_t i=0; i<64; i++) + { + adc[i] = 0; + mult[i] = 0.0; + } + + Int_t nEntries = (Int_t)treeV0.GetEntries(); + + for (Int_t e=0; eGetEntriesFast(); + + for (Int_t d=0; dAt(d); + Int_t pmNumber = digit->PMNumber(); + + if (adc[pmNumber] > (int(1.0/calibdata->GetMIPperADC(pmNumber)) /2) ) + mult[pmNumber] += float(adc[pmNumber])*calibdata->GetMIPperADC(pmNumber); + } + } + + // 0..31 V0C + // 32..63 V0A + for (Int_t j=0; j<32; j++) + { + fV0M[0] += short(mult[j ]+0.5); + fV0M[1] += short(mult[j+32]+0.5); + } +} + +//________________ +void AliEMCALTriggerSTU::FetchFOR( Int_t iTRU, Int_t **R, const TVector2* rSize ) +{ + // L1 triggers run over the whole EMCal surface + // STU builds its own fRegion aggregating TRU fRegion into one + + // STU I from TRUs O in Olivier's coordinate system + + if ( iTRU == 31 ) iTRU = 35; + + Int_t i2y = iTRU / 3 / 2; + + if ( ( iTRU / 3 ) % 2 ) // C side odd (z<0) + { + Int_t i1y = 2 - ( iTRU - int( iTRU / 3 ) * 3 ); // 0 1 2 w/ increasing phi + + for (Int_t i=0; iX(); i++) // 0:23 0:4 + for (Int_t j=0; jY(); j++) fRegion[24+i][j + i1y * 4 + i2y * 12] = R[i][j]; + } + else // A side + { + Int_t i1y = iTRU - int( iTRU / 3 ) * 3; + + for (Int_t i=0; iX(); i++) + for (Int_t j=0; jY(); j++) fRegion[ i][j + i1y * 4 + i2y * 12] = R[i][j]; + } +} + +//___________ +void AliEMCALTriggerSTU::PatchGenerator(const TClonesArray* lpos, Int_t val) +{ + ZeroRegion(); + + Int_t vTRU[32][24][4] ;//= {0}; + + for (Int_t i = 0; i < 32; i++) + for (Int_t j = 0; j < 24; j++) + for (Int_t k = 0; k < 4; k++) vTRU[i][j][k]=0; + + + AliWarning("AliEMCALTriggerSTU::PatchGenerator(): STU region has been reset!"); + + // Fill the patch FOR at 'pos' w/ value 'val' + + TIter NextPosition( lpos ); + + while ( TVector2 *pos = (TVector2*)NextPosition() ) + { + pos->Print(); + for (Int_t i=pos->X()*fSubRegionSize->X(); iX()+fPatchSize->X())*fSubRegionSize->X()); i++) + for (Int_t j=pos->Y()*fSubRegionSize->Y(); jY()+fPatchSize->Y())*fSubRegionSize->Y()); j++) + fRegion[i][j] = val; + } + + for (Int_t i=0; i<2; i++) + { + for (Int_t j=0; j<16; j++) + { + Int_t iTRU = ( !i ) ? 31 - j : 15 - j; + + for (Int_t i1=24*i; i1<24*(i+1); i1++) + { + for (Int_t j1=4*j; j1<4*(j+1); j1++) + { + vTRU[iTRU][i1%24][j1%4] = fRegion[i1][j1]; + } + } + } + } + + gSystem->Exec(Form("mkdir -p GP")); + + for (Int_t i=0; i<32; i++) + { + std::ofstream outfile(Form("GP/data_TRU%d.txt",i),std::ios::trunc); + + for (Int_t j=0;j<96;j++) + { + Int_t ietam, iphim; + + if ( int(i / 16) ) + { + ietam = j/4; + iphim = 3 - j%4; + } + else + { + ietam = 23 - j/4; + iphim = j%4; + } + + outfile << vTRU[i][ietam][iphim] << endl; + } + + outfile.close(); + } +} + +//___________ +Float_t AliEMCALTriggerSTU::ThresholdFromV0( L1TriggerType_t type ) +{ + // Compute threshold FIXME: need an access to the OCDB + // to get f(V0) parameters depending on trigger type + + switch ( type ) + { + case kGamma: + break; + case kJet: +// return 15.; + break; + default: + AliError("AliEMCALTriggerSTU::ThresholdFromV0(): Undefined trigger type, pls check!"); + } + + return 0.; +} + +//__________ +void AliEMCALTriggerSTU::Reset() +{ + fPatches->Delete(); +} diff --git a/EMCAL/AliEMCALTriggerSTU.h b/EMCAL/AliEMCALTriggerSTU.h new file mode 100644 index 00000000000..ea1f10aca4b --- /dev/null +++ b/EMCAL/AliEMCALTriggerSTU.h @@ -0,0 +1,47 @@ +#ifndef ALIEMCALTRIGGERSTU_H +#define ALIEMCALTRIGGERSTU_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* + + +Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 +*/ + +#include + +class TTree; + +class AliEMCALTriggerSTU : public AliEMCALTriggerBoard +{ +public: + + AliEMCALTriggerSTU(); + AliEMCALTriggerSTU(AliEMCALCalibData *calibData, const TVector2& rsize); + virtual ~AliEMCALTriggerSTU(); + + virtual void FetchFOR(Int_t i, Int_t** Region, const TVector2* rSize); + virtual void BuildMap(Int_t i, Int_t** Map, const TVector2* rSize); + virtual void PrintADC(L1TriggerType_t type, TVector2& pos, TVector2& idx); + virtual void L1(L1TriggerType_t type);//, TTree& treeV0); + virtual void PatchGenerator(const TClonesArray* lpos, Int_t val); + virtual const Int_t* V0() const {return fV0M;} + virtual void SetV0Multiplicity(Int_t M[], Int_t n) { for (Int_t i=0;iReset(); + fRawReader->Select("EMCAL",44); +} + +//_____________________________________________________________________________ +AliEMCALTriggerSTURawStream::~AliEMCALTriggerSTURawStream() +{ + // destructor +} + +//_____________________________________________________________________________ +void AliEMCALTriggerSTURawStream::Reset() +{ + // + if (fRawReader) fRawReader->Reset(); +} + +//_____________________________________________________________________________ +Bool_t AliEMCALTriggerSTURawStream::ReadPayLoad() +{ + // STU data decoder from Olivier Bourrion LPSC CNRS-IN2P3 + // bourrion@lpsc.in2p3.fr + + UInt_t word32[1772]; // 32b words + + Int_t iword = 0; + + UInt_t w32; + while (fRawReader->ReadNextInt(w32)) word32[iword++] = w32; + + if (iword < kPayLoadSize) + { + AliError(Form("STU raw data size is too small: %d word32 only!", iword)); + return kFALSE; + } + else if (iword > kPayLoadSize ) + { + AliLog::Message(AliLog::kInfo, "TRU raw data in the STU payload enabled","EMCAL","AliEMCALTriggerSTURawStream","ReadPayLoad()","AliEMCALTriggerSTURawStream.cxx",104); + } + + fL0 = 0; + + fL1JetThreshold = ((word32[0]>>16) & 0xFFF); + fL1GammaThreshold = (word32[0] & 0xFFF); + + for (Int_t jet_row=0; jet_row<11; jet_row++) + { + UInt_t currentrow = word32[1+jet_row]; + + for (Int_t jet_col=0; jet_col<15; jet_col++) + { + if (currentrow & (1 << jet_col)) + { + fNL1JetPatch++; + fL1JetPatchIndex = (UShort_t*)realloc(fL1JetPatchIndex, fNL1JetPatch * sizeof(UShort_t)); + if (fL1JetPatchIndex == NULL) {AliError("Error (re)allocating L1 jet patch memory");} + + fL1JetPatchIndex[fNL1JetPatch-1] = ((jet_row << 8) & 0xFF00) | (jet_col & 0xFF); + } + } + } + + ////////////////////////////////////////////////////////// + // index des L0 // + ////////////////////////////////////////////////////////// + // FIXME: still not interpreted to be done with Jiri + + unsigned short TRU_L0_indexes[32][6]; + + // extraction from stream + for (Int_t index=0;index<6;index++) + { + for (Int_t tru_num=0;tru_num<16;tru_num++) + { + TRU_L0_indexes[2*tru_num ][index] = ( word32[12+index*16+tru_num] & 0xFFFF); + TRU_L0_indexes[2*tru_num+1][index] = ((word32[12+index*16+tru_num]>>16) & 0xFFFF); + } + } + + for (Int_t tru_num=0;tru_num<32;tru_num++) + { + for (Int_t index=0;index<6;index++) + { + for (Int_t bit_num=0;bit_num<12;bit_num++) + { + if ((TRU_L0_indexes[tru_num][index] & (1 << bit_num))) + { + fL0 = 1; + + Int_t idx = 12 * index + bit_num; + + Int_t col = idx / 3; + Int_t row = idx % 3; + + fNL0GammaPatch++; + fL0GammaPatchIndex = (UShort_t*)realloc(fL0GammaPatchIndex, fNL0GammaPatch * sizeof(UShort_t)); + + if (fL0GammaPatchIndex == NULL) {AliError("Error (re)allocating L0 gamma patch memory");} + + fL0GammaPatchIndex[fNL0GammaPatch-1] = (((row << 10) & 0xC00) | ((col << 5) & 0x3E0) | (tru_num & 0x1F)); + } + } + } + } + + ////////////////////////////////////////////////////////// + // index des L1 gamma // + ////////////////////////////////////////////////////////// + + unsigned short TRU_L1_indexes[32][8]; + + // extraction from stream + for (Int_t index=0;index<8;index++) + { + for (Int_t tru_num=0;tru_num<16;tru_num++) + { + TRU_L1_indexes[2*tru_num ][index] = ( word32[108+index*16+tru_num] & 0xFFFF); + TRU_L1_indexes[2*tru_num+1][index] = ((word32[108+index*16+tru_num]>>16) & 0xFFFF); + } + } + + // interpretation + int gammacolnum; + short indexcopy; + + for (Int_t tru_num=0;tru_num<32;tru_num++) + { + for (Int_t index=0;index<8;index++) + { + for (Int_t bit_num=0; bit_num<12; bit_num++) + { + if ((TRU_L1_indexes[tru_num][index] & (1<>16) & 0xFFFF); + } + } + + for (Int_t tru_num=16;tru_num<32;tru_num++) // A side + { + for (Int_t index=0;index<96;index++) + { + fADC[tru_num][index] = fADC[tru_num][95-index]; + } + } + + return kFALSE; +} + +//_____________________________________________________________________________ +Bool_t AliEMCALTriggerSTURawStream::GetL0GammaPatch(const Int_t i, Int_t& tru, Int_t& col, Int_t& row) const +{ + // + if (i > fNL0GammaPatch) return kFALSE; + + tru = fL0GammaPatchIndex[i] & 0x1F; + col = (fL0GammaPatchIndex[i] & 0x3E0) >> 5; + row = (fL0GammaPatchIndex[i] & 0xC00) >> 10; + + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliEMCALTriggerSTURawStream::GetL1GammaPatch(const Int_t i, Int_t& tru, Int_t& col, Int_t& row) const +{ + // + if (i > fNL1GammaPatch) return kFALSE; + + tru = fL1GammaPatchIndex[i] & 0x1F; + col = (fL1GammaPatchIndex[i] & 0x3E0) >> 5; + row = (fL1GammaPatchIndex[i] & 0xC00) >> 10; + + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliEMCALTriggerSTURawStream::GetL1JetPatch(const Int_t i, Int_t& col, Int_t& row) const +{ + // + if (i > fNL1JetPatch) return kFALSE; + + col = fL1JetPatchIndex[i] & 0xFF; + row = (fL1JetPatchIndex[i] & 0xFF00) >> 8; + + return kTRUE; +} + +//_____________________________________________________________________________ +void AliEMCALTriggerSTURawStream::GetADC(Int_t iTRU, UInt_t ADC[]) +{ + // + for (Int_t i=0; i<96; i++) ADC[i] = fADC[iTRU][i]; +} + +//_____________________________________________________________________________ +void AliEMCALTriggerSTURawStream::Dump(const Option_t *option) const +{ + // + TString op = option; + + cout << "Jet Threshold: " << fL1JetThreshold << " Gamma threshold: " << fL1GammaThreshold << endl; + + Int_t itru, col, row; + + Bool_t isOK; + + if (op.Contains("L0") || op.Contains("ALL")) + { + for (Int_t i=0;i Found L0 gamma in TRU #" << setw(2) << itru + << " at: ( col: " << setw(2) << col << " , row: " << setw(2) << row << " )" << endl; + } + } + + if (op.Contains("L1") || op.Contains("ALL")) + { + for (Int_t i=0;i Found L1 gamma in TRU #" << setw(2) << itru + << " at: ( col: " << setw(2) << col << " , row: " << setw(2) << row << " )" << endl; + } + + for (Int_t i=0;i Found L1 jet at: ( col: " << setw(2) << col << " , row: " << setw(2) << row << " )" << endl; + } + } + + if (op.Contains("ADC") || op.Contains("ALL")) + { + for (Int_t i=0;i<32;i++) + { + cout << "--------\n"; + cout << "TRU #" << setw(2) << i << ":"; + for (Int_t j=0;j<96;j++) + { + TBits xadc(12); xadc.Set(12,&fADC[i][j]); + if ((j%4)==0) cout << endl; + //cout << setw(2) << j << ": " << xadc << " "; + printf("%2d: %3x / ",j,fADC[i][j]); + } + cout << "\n"; + } + } +} diff --git a/EMCAL/AliEMCALTriggerSTURawStream.h b/EMCAL/AliEMCALTriggerSTURawStream.h new file mode 100644 index 00000000000..5f0157f19f7 --- /dev/null +++ b/EMCAL/AliEMCALTriggerSTURawStream.h @@ -0,0 +1,65 @@ +#ifndef ALIEMCALTRIGGERSTURAWSTREAM_H +#define ALIEMCALTRIGGERSTURAWSTREAM_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* + + +Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 +*/ + +#include +#include + +class AliRawReader; + +class AliEMCALTriggerSTURawStream: public TObject +{ + public: + AliEMCALTriggerSTURawStream(); + AliEMCALTriggerSTURawStream(AliRawReader* rawReader); + virtual ~AliEMCALTriggerSTURawStream(); + + virtual void Reset(); + virtual Bool_t ReadPayLoad(); + virtual void Dump(const Option_t *option = "ALL") const; + + virtual void GetADC(Int_t iTRU, UInt_t ADC[]); + virtual UInt_t GetL1JetThreshold() const {return fL1JetThreshold;} + virtual UInt_t GetL1GammaThreshold() const {return fL1GammaThreshold;} + + virtual Int_t GetNL0GammaPatch() const {return fNL0GammaPatch;} + virtual Int_t GetNL1GammaPatch() const {return fNL1GammaPatch;} + virtual Int_t GetNL1JetPatch() const {return fNL1JetPatch;} + + virtual Bool_t GetL0GammaPatch(const Int_t i, Int_t& x, Int_t& y, Int_t& z) const; + virtual Bool_t GetL1GammaPatch(const Int_t i, Int_t& x, Int_t& y, Int_t& z) const; + virtual Bool_t GetL1JetPatch(const Int_t i, Int_t& x, Int_t& y) const; + + virtual UInt_t L0() {return fL0;} + +private: + + AliEMCALTriggerSTURawStream(const AliEMCALTriggerSTURawStream& rhs); + AliEMCALTriggerSTURawStream& operator = (const AliEMCALTriggerSTURawStream& rhs); + + AliRawReader* fRawReader; // object for reading the raw data + + UInt_t fL1JetThreshold; + UInt_t fL1GammaThreshold; + UShort_t* fL0GammaPatchIndex; // [fNL0GammaPatch] + UShort_t* fL1GammaPatchIndex; // [fNL1GammaPatch] + UShort_t* fL1JetPatchIndex; // [fNL1JetPatch] + + Int_t fNL0GammaPatch; + Int_t fNL1JetPatch; + Int_t fNL1GammaPatch; + + UInt_t fADC[32][96]; + UInt_t fL0; + + ClassDef(AliEMCALTriggerSTURawStream,1) // class for reading EMCAL STU DDL raw data +}; + +#endif diff --git a/EMCAL/AliEMCALTriggerTRU.cxx b/EMCAL/AliEMCALTriggerTRU.cxx new file mode 100644 index 00000000000..3730bf95f36 --- /dev/null +++ b/EMCAL/AliEMCALTriggerTRU.cxx @@ -0,0 +1,435 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + +/* + + + + +Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 +*/ + + +#include "AliEMCALTriggerTRU.h" +#include "AliEMCALTriggerPatch.h" +#include "AliEMCALDigit.h" +#include "AliEMCALTriggerSTU.h" +#include "AliEMCALCalibData.h" +#include "AliLog.h" + +#include +#include +#include +#include +#include + +namespace +{ + const Int_t kTimeBins = 64; // number of sampling bins of the FastOR signal + const Int_t kTimeWindowSize = 4; // + const Int_t kNup = 2; // + const Int_t kNdown = 1; // +} + +ClassImp(AliEMCALTriggerTRU) + +//________________ +AliEMCALTriggerTRU::AliEMCALTriggerTRU() : AliEMCALTriggerBoard()//, +//fDigits( 0x0 ) +{ + // + for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0; +} + +//________________ +AliEMCALTriggerTRU::AliEMCALTriggerTRU(AliEMCALCalibData *calibData, const TVector2& rSize, Int_t mapType) : +AliEMCALTriggerBoard(calibData, rSize) +{ + // + for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0; + + // FIXME: use of class AliEMCALTriggerParam to get size + TVector2 size; + + size.Set( 1. , 1. ); + SetSubRegionSize( size ); // 1 by 1 FOR + + size.Set( 2. , 2. ); + SetPatchSize( size ); // 2 by 2 subregions + + for (Int_t ietam=0;ietam<24;ietam++) + { + for (Int_t iphim=0;iphim<4;iphim++) + { + // idx: 0..95 since iphim: 0..11 ietam: 0..23 + Int_t idx = ( !mapType ) ? ( 3 - iphim ) + ietam * 4 : iphim + (23 - ietam) * 4; + + // Build a matrix used to get TRU digit id (ADC channel) from (eta,phi)|SM + fMap[ietam][iphim] = idx; // [0..11][0..3] namely [eta][phi] in SM + } + } +} + +//________________ +AliEMCALTriggerTRU::~AliEMCALTriggerTRU() +{ + // delete TRU digits only used as transient containers + // to compute FastOR from energy deposit + +} + +//________________ +void AliEMCALTriggerTRU::Peaks(Int_t arr[96][2]) +{ + // Return max time bin & max value for all channels + for (Int_t i=0;i<96;i++) + { + arr[i][0] = arr[i][1] = 0; + + Int_t max = 0, pos = 0; + for (Int_t j=0;j<256;j++) + { + if (fADC[i][j]>max) + { + max = fADC[i][j]; + pos = j; + } + } + + arr[i][0] = max; + arr[i][1] = pos; + } +} + +//________________ +void AliEMCALTriggerTRU::ShowFastOR(Int_t iTimeWindow, Int_t iChannel) +{ + // + Int_t iChanF, iChanL; + + if (iChannel != -1) iChanF = iChanL = iChannel; + else + { + iChanF = 0; + iChanL = 96; + } + + for (Int_t i=iChanF;i thres) + // fill a matrix to support sliding window + // compute the time sum for all the FastOR of a given TRU + // and then move the space window + + Int_t sum[96][3] ;//= { 0 }; + for(Int_t i = 0; i < 96 ; i++) + for(Int_t j = 0; j < 3 ; j++) sum[i][j] = 0; + + // Sliding window algorithm + for (Int_t i=0; i<=(kTimeBins-kTimeWindowSize); i++) + { + for(Int_t j=0; jX(); j++) + { + for (Int_t k=0; kY(); k++) + { + for (Int_t l=i; l>2; // truncate time sum + } + } + + // Threshold + // FIXME: for now consider just one threshold for all patches, should consider one per patch? + // return the list of patches above threshold + // Should probably be checked out from OCDB + + Int_t vL0Threshold = 0; + + SlidingWindow( kGamma, vL0Threshold ); + + Int_t nP = 0; + + for (Int_t j=0; jGetEntriesFast(); j++) + { + AliEMCALTriggerPatch *p = (AliEMCALTriggerPatch*)fPatches->At( j ); + + TVector2 v; + p->Position(v); + + Int_t idx = fMap[int(v.X())][int(v.Y())]; + + if ( i>2 ) + { + // Now check the '2 up/1 down' on each patch + if ( sum[idx][1]>sum[idx][0] && sum[idx][2]<=sum[idx][1] ) nP++; + + sum[idx][0] = sum[idx][1]; + sum[idx][1] = sum[idx][2]; + sum[idx][2] = p->Sum(); + } + else + { + sum[idx][i] = p->Sum(); + } + } + + if ( !nP ) + fPatches->Delete(); + else + break; // Stop the algo when at least one patch is found ( thres & max ) + + ZeroRegion(); // Clear fRegion for this time window before computing the next one + + } + + return fPatches->GetEntriesFast(); +} + +//________________ +Int_t AliEMCALTriggerTRU::L0v1() +{ + // Mimick the TRU L0 'virtual' since not yet released algo + + // L0 issuing condition is: (2 up & 1 down) AND (time sum > thres) + // fill a matrix to support sliding window + // compute the time sum for all the FastOR of a given TRU + // and then move the space window + + AliDebug(1,"=== Running TRU L0 v1 version ==="); + + // Time sliding window algorithm + for (Int_t i=0; i<=(kTimeBins-kTimeWindowSize); i++) + { + AliDebug(1,Form("----------- Time window: %d\n",i)); + + for (Int_t j=0; jX(); j++) + { + for (Int_t k=0; kY(); k++) + { + for (Int_t l=i; l 4) fRegion[j][k] = fRegion[j][k] >> 1; // truncate time sum to fit 14b + } + } + + // Threshold + // FIXME: for now consider just one threshold for all patches, should consider one per patch? + // ANSWE: both solutions will be implemented in the TRU + // return the list of patches above threshold + // Should probably be checked out from OCDB + + Int_t vL0Threshold = 0; + + SlidingWindow( kGamma, vL0Threshold ); + +// for(Int_t j=0; jX(); j++) +// for (Int_t k=0; kY(); k++) fRegion[j][k] = fRegion[j][k]>>2; // go to 12b before shipping to STU + + Int_t nP = 0; + + for (Int_t j=0; jGetEntriesFast(); j++) + { + AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)fPatches->At( j ); + + if ( AliDebugLevel() ) p->Print(""); + + TVector2 v; + p->Position(v); + + Int_t sizeX = fPatchSize->X() * fSubRegionSize->X(); + Int_t sizeY = fPatchSize->Y() * fSubRegionSize->Y(); + + const Int_t psize = sizeX * sizeY; // Number of FastOR in the patch + + Int_t idx[psize]; + + Int_t aPeaks = 0; + + for (Int_t xx=0;xxX())+xx][int(v.Y()*fSubRegionSize->Y())+yy]; // Get current patch FastOR ADC channels + + if (fRegion[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]) aPeaks++; + + if ( AliDebugLevel() ) ShowFastOR(i,idx[xx*sizeY+yy]); + } + } + + Int_t nPeaks = 0; + + for (Int_t k=i;k<=i+kTimeWindowSize-(kNup+kNdown);k++) + { + // Now check the 'kNup up / kNdown down' on each FastOR of the patch + PeakFinder( idx , psize , k , kNup , kNdown , nPeaks ); + } + + if (nPeaks == aPeaks) + { + if ( AliDebugLevel() ) + { + printf("\t----- Valid patch (all FastOR have crossed a maximum)\n"); + + for (Int_t xx=0;xxDelete(); + else + { + AliDebug(1,Form("==========[ Found %4d valid patches out of %4d ]==========\n",nP,fPatches->GetEntriesFast())); + break; // Stop the algo when at least one patch is found ( thres & max ) + } + + ZeroRegion(); // Clear fRegion for this time window before computing the next one + } + + return fPatches->GetEntriesFast(); +} + + +//________________ +Int_t AliEMCALTriggerTRU::L0v2() +{ + // Activity trigger + + // Sliding window algorithm + + for(Int_t j=0; jX(); j++) + { + for (Int_t k=0; kY(); k++) + { + Int_t max = 0; + for (Int_t l=0; l max) max = fADC[fMap[j][k]][l]; + } + + if (max>4) fRegion[j][k] = max; + } + } + + Int_t vL0Threshold = 0; + + SlidingWindow( kGamma, vL0Threshold ); + + return fPatches->GetEntriesFast(); +} + + +//________________ +void AliEMCALTriggerTRU::SetADC( Int_t channel, Int_t bin, Int_t sig ) +{ + // + if (channel>95) AliError("TRU has 96 ADC channels only!"); + fADC[channel][bin] = sig; +} + +//________________ +void AliEMCALTriggerTRU::PeakFinder( const Int_t idx[], Int_t nfastor, Int_t start, Int_t nup, Int_t ndown, Int_t& nPeaks ) +{ + // + for (Int_t i=0;i fADC[idx[i]][j-1] && fADC[idx[i]][j-1] ) ? 1 : 0; + for (Int_t j=start+nup;jExec(Form("mkdir -p Event%d",iEvent)); + + ofstream outfile(Form("Event%d/data_TRU%d.txt",iEvent,iTRU),ios_base::trunc); + + for (Int_t i=0;i<96;i++) + { + Int_t ietam = 23 - i/4; + + Int_t iphim = 3 - i%4; + + outfile << fRegion[ietam][iphim] << endl; + } + + outfile.close(); +} + +/* +//________________ +void AliEMCALTriggerTRU::Scan() +{ + // + for (Int_t i=0;i<96;i++) + { + Int_t ietam = 23 - i/4; + + Int_t iphim = 3 - i%4; + + printf("ADC: %2d fRegion[%2d][%2d]: %4d\n",i,ietam,iphim,fRegion[ietam][iphim]); + } +} +*/ +//________________ +void AliEMCALTriggerTRU::Reset() +{ + // + fPatches->Delete(); + + ZeroRegion(); + + for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0; +} + diff --git a/EMCAL/AliEMCALTriggerTRU.h b/EMCAL/AliEMCALTriggerTRU.h new file mode 100644 index 00000000000..71600cd7ee7 --- /dev/null +++ b/EMCAL/AliEMCALTriggerTRU.h @@ -0,0 +1,48 @@ +#ifndef ALIEMCALTRIGGERTRU_H +#define ALIEMCALTRIGGERTRU_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* + + +Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3 +*/ + +#include + +class AliEMCALTriggerSTU; +class AliEMCALDigit; +class AliEMCALCalibData; + +class AliEMCALTriggerTRU : public AliEMCALTriggerBoard +{ +public: + + AliEMCALTriggerTRU(); + AliEMCALTriggerTRU(AliEMCALCalibData *calibData, const TVector2& rSize, Int_t mapType); + virtual ~AliEMCALTriggerTRU(); + + virtual Int_t L0v0(); // space sum has reached a max + virtual Int_t L0v1(); // one of the 4 FastOR in the patch has reached a max + virtual Int_t L0v2(); // activity trigger + + virtual void PeakFinder(const Int_t idx[], Int_t nfastor, Int_t start, Int_t nup, Int_t ndown, Int_t& npeaks); + virtual void SetADC(Int_t channel, Int_t bin, Int_t sig ); + + virtual void SaveRegionADC(Int_t iTRU, Int_t iEvent); +// virtual void Scan(); + virtual void Reset(); + virtual void Peaks(Int_t arr[96][2]); + virtual void ShowFastOR(Int_t timewindow, Int_t chan = -1); + +private: + AliEMCALTriggerTRU(const AliEMCALTriggerTRU& rhs); + AliEMCALTriggerTRU& operator=(const AliEMCALTriggerTRU& rhs); + + Int_t fADC[96][256]; //! FIXME: Check the maximum number of samples + + ClassDef(AliEMCALTriggerTRU,1) +}; + +#endif diff --git a/EMCAL/EMCALbaseLinkDef.h b/EMCAL/EMCALbaseLinkDef.h index 4285f674d31..17003ab909c 100644 --- a/EMCAL/EMCALbaseLinkDef.h +++ b/EMCAL/EMCALbaseLinkDef.h @@ -41,6 +41,9 @@ #pragma link C++ class AliEMCALSuperModuleCalibReference+; #pragma link C++ class AliEMCALCalibMapAPDVal+; #pragma link C++ class AliEMCALSuperModuleCalibMapAPD+; +#pragma link C++ class AliEMCALRawDigit+; +#pragma link C++ class AliEMCALTriggerSTURawStream+; // #pragma link C++ class AliEMCALShishKebabTrd1Module+; #endif + diff --git a/EMCAL/EMCALsimLinkDef.h b/EMCAL/EMCALsimLinkDef.h index ed5c57dc8cb..4d44ab03a8d 100644 --- a/EMCAL/EMCALsimLinkDef.h +++ b/EMCAL/EMCALsimLinkDef.h @@ -13,5 +13,12 @@ #pragma link C++ class AliEMCALDigitizer+; #pragma link C++ class AliEMCALRawUtils+; #pragma link C++ class AliEMCALQADataMakerSim+; +#pragma link C++ class AliEMCALTriggerBoard+; +#pragma link C++ class AliEMCALTriggerPatch+; +#pragma link C++ class AliEMCALTriggerSTU+; +#pragma link C++ class AliEMCALTriggerTRU+; +#pragma link C++ class AliEMCALTriggerData+; +#pragma link C++ class AliEMCALTriggerElectronics+; #endif + diff --git a/EMCAL/libEMCALbase.pkg b/EMCAL/libEMCALbase.pkg index b97705054d1..ebb53cdfa0e 100644 --- a/EMCAL/libEMCALbase.pkg +++ b/EMCAL/libEMCALbase.pkg @@ -30,7 +30,9 @@ AliEMCALBiasAPD.cxx \ AliEMCALCalibAbs.cxx \ AliEMCALCalibReference.cxx \ AliEMCALCalibMapAPD.cxx \ -SMcalib/AliEMCALCCUSBRawStream.cxx +SMcalib/AliEMCALCCUSBRawStream.cxx \ +AliEMCALRawDigit.cxx \ +AliEMCALTriggerSTURawStream.cxx # AliEMCALShishKebabTrd1Module.cxx \ @@ -47,3 +49,4 @@ PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) \ -lRAWDatarec -lRAWDatabase \ -L$(ROOTLIBDIR) -lVMC -lGeom -lMinuit endif + diff --git a/EMCAL/libEMCALrec.pkg b/EMCAL/libEMCALrec.pkg index 7a764a03cf0..a7e85848d18 100644 --- a/EMCAL/libEMCALrec.pkg +++ b/EMCAL/libEMCALrec.pkg @@ -26,10 +26,11 @@ CINTHDRS:= $(HDRS) AliEMCALGeometry.h AliEMCALGeoUtils.h DHDR:=EMCALrecLinkDef.h # have to tune -EINCLUDE:=PYTHIA6 RAW EVGEN THijing +EINCLUDE:=PYTHIA6 RAW EVGEN THijing VZERO ifeq (win32gcc,$(ALICE_TARGET)) PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) \ -lEMCALUtils -lEMCALbase -lEMCALsim -lSTEER -lESD -lCDB -lSTEERBase \ -L$(ROOTLIBDIR) -lMinuit endif + diff --git a/EMCAL/libEMCALsim.pkg b/EMCAL/libEMCALsim.pkg index 14ebe15503a..797e0c5b759 100644 --- a/EMCAL/libEMCALsim.pkg +++ b/EMCAL/libEMCALsim.pkg @@ -11,13 +11,19 @@ AliEMCALDigitizer.cxx \ AliEMCALTick.cxx \ AliEMCALRawUtils.cxx \ AliEMCALTrigger.cxx \ -AliEMCALQADataMakerSim.cxx +AliEMCALQADataMakerSim.cxx \ +AliEMCALTriggerBoard.cxx \ +AliEMCALTriggerPatch.cxx \ +AliEMCALTriggerSTU.cxx \ +AliEMCALTriggerTRU.cxx \ +AliEMCALTriggerData.cxx \ +AliEMCALTriggerElectronics.cxx HDRS= $(SRCS:.cxx=.h) DHDR:=EMCALsimLinkDef.h # have to tune -EINCLUDE:=PYTHIA6 RAW EVGEN THijing +EINCLUDE:=PYTHIA6 RAW EVGEN THijing VZERO ifeq (win32gcc,$(ALICE_TARGET)) PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) \ @@ -25,3 +31,5 @@ PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) \ -lRAWDatarec -lRAWDatasim -lRAWDatabase \ -L$(ROOTLIBDIR) -lVMC -lGeom endif + + -- 2.39.3