X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=EMCAL%2FAliEMCALRawUtils.cxx;h=92cc806248e142bc8d7eefed50bce0f85b735ab8;hb=48b634ff934842fabcb6cfedda2ada1875d97b1f;hp=4e0e4f44d6863ee460e4c2049d475f0b22cc2179;hpb=8cb998bdcd1a879c577164ebdf7cc217a0a903d8;p=u%2Fmrichter%2FAliRoot.git diff --git a/EMCAL/AliEMCALRawUtils.cxx b/EMCAL/AliEMCALRawUtils.cxx index 4e0e4f44d68..92cc806248e 100644 --- a/EMCAL/AliEMCALRawUtils.cxx +++ b/EMCAL/AliEMCALRawUtils.cxx @@ -1,3 +1,4 @@ +// -*- mode: c++ -*- /************************************************************************** * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * * @@ -14,85 +15,108 @@ **************************************************************************/ /* $Id$ */ -/* History of cvs commits: - * - * $Log$ - * Revision 1.8 2007/12/05 02:30:51 jklay - * modification to read Altro mappings into AliEMCALRecParam and pass to AliEMCALRawUtils from AliEMCALReconstructor; add option to AliEMCALRawUtils to set old RCU format (for testbeam) or not - * - * Revision 1.7 2007/11/14 15:51:46 gustavo - * Take out few unnecessary prints - * - * Revision 1.6 2007/11/01 01:23:51 mvl - * Removed call to SetOldRCUFormat, which is only needed for testbeam data - * - * Revision 1.5 2007/11/01 01:20:33 mvl - * Further improvement of peak finding; more robust fit - * - * Revision 1.4 2007/10/31 17:15:24 mvl - * Fixed bug in raw data unpacking; Added pedestal to signal fit; Added logic to deal with high/low gain - * - * Revision 1.3 2007/09/27 08:36:46 mvl - * More robust setting of fit range in FitRawSignal (P. Hristov) - * - * Revision 1.2 2007/09/03 20:55:35 jklay - * EMCAL e-by-e reconstruction methods from Cvetan - * - * Revision 1.1 2007/03/17 19:56:38 mvl - * Moved signal shape routines from AliEMCAL to separate class AliEMCALRawUtils to streamline raw data reconstruction code. - * */ -//*-- Author: Marco van Leeuwen (LBL) -#include "AliEMCALRawUtils.h" -#include "TF1.h" -#include "TGraph.h" -#include "TSystem.h" +//_________________________________________________________________________ +// Utility Class for handling Raw data +// Does all transitions from Digits to Raw and vice versa, +// for simu and reconstruction +// +// Note: the current version is still simplified. Only +// one raw signal per digit is generated; either high-gain or low-gain +// Need to add concurrent high and low-gain info in the future +// No pedestal is added to the raw signal. +//*-- Author: Marco van Leeuwen (LBL) +//*-- Major refactoring by Per Thomas Hille -#include "AliLog.h" +#include "AliEMCALRawUtils.h" +#include "AliRun.h" #include "AliRunLoader.h" -#include "AliCaloAltroMapping.h" #include "AliAltroBuffer.h" #include "AliRawReader.h" -#include "AliCaloRawStream.h" +#include "AliCaloRawStreamV3.h" #include "AliDAQ.h" - #include "AliEMCALRecParam.h" #include "AliEMCALLoader.h" #include "AliEMCALGeometry.h" -#include "AliEMCALDigitizer.h" #include "AliEMCALDigit.h" - +#include "AliEMCALRawDigit.h" +#include "AliEMCAL.h" +#include "AliCaloCalibPedestal.h" +#include "AliCaloBunchInfo.h" +#include "AliCaloFitResults.h" +#include "AliEMCALTriggerRawDigitMaker.h" +#include "AliEMCALTriggerSTURawStream.h" +#include "AliEMCALTriggerData.h" +#include "AliCaloConstants.h" +#include "AliCaloRawAnalyzer.h" +#include "AliCaloRawAnalyzerFactory.h" +#include "AliEMCALRawResponse.h" + +using namespace CALO; +using namespace EMCAL; ClassImp(AliEMCALRawUtils) -// Signal shape parameters -Int_t AliEMCALRawUtils::fgOrder = 2 ; // Order of gamma function -Double_t AliEMCALRawUtils::fgTimeBinWidth = 100E-9 ; // each sample is 100 ns -Double_t AliEMCALRawUtils::fgTau = 235E-9 ; // 235 ns (from CERN testbeam; not very accurate) -Double_t AliEMCALRawUtils::fgTimeTrigger = 1.5E-6 ; // 15 time bins ~ 1.5 musec -// some digitization constants -Int_t AliEMCALRawUtils::fgThreshold = 1; -Int_t AliEMCALRawUtils::fgDDLPerSuperModule = 2; // 2 ddls per SuperModule - -AliEMCALRawUtils::AliEMCALRawUtils() - : fHighLowGainFactor(0.), fOption("") +AliEMCALRawUtils::AliEMCALRawUtils( Algo::fitAlgorithm fitAlgo) : fNoiseThreshold(3), + fNPedSamples(4), + fGeom(0), + fOption(""), + fRemoveBadChannels(kFALSE), + fFittingAlgorithm(fitAlgo), + fTimeMin(-1.), + fTimeMax(1.), + fUseFALTRO(kTRUE), + fRawAnalyzer(0), + fTriggerRawDigitMaker(0x0) { - fHighLowGainFactor = 16. ; // adjusted for a low gain range of 82 GeV (10 bits) + SetFittingAlgorithm(fitAlgo); + const TObjArray* maps = AliEMCALRecParam::GetMappings(); + if(!maps) AliFatal("Cannot retrieve ALTRO mappings!!"); + for(Int_t i = 0; i < 4; i++) + { + fMapping[i] = (AliAltroMapping*)maps->At(i); + } + + AliRunLoader *rl = AliRunLoader::Instance(); + if (rl && rl->GetAliRun()) + { + AliEMCAL * emcal = dynamic_cast(rl->GetAliRun()->GetDetector("EMCAL")); + if(emcal) + { + fGeom = emcal->GetGeometry(); + } + else + { + AliDebug(1, Form("Using default geometry in raw reco")); + fGeom = AliEMCALGeometry::GetInstance(AliEMCALGeometry::GetDefaultGeometryName()); + } + } + else + { + AliDebug(1, Form("Using default geometry in raw reco")); + fGeom = AliEMCALGeometry::GetInstance(AliEMCALGeometry::GetDefaultGeometryName()); + } + + if(!fGeom) AliFatal(Form("Could not get geometry!")); + fTriggerRawDigitMaker = new AliEMCALTriggerRawDigitMaker(); } -//____________________________________________________________________________ -AliEMCALRawUtils::~AliEMCALRawUtils() { + + +AliEMCALRawUtils::~AliEMCALRawUtils() +{ + //dtor + delete fRawAnalyzer; + delete fTriggerRawDigitMaker; } -//____________________________________________________________________________ -void AliEMCALRawUtils::Digits2Raw(AliAltroMapping **mapping) + + +void AliEMCALRawUtils::Digits2Raw() { // convert digits of the current event to raw data - - AliRunLoader *rl = AliRunLoader::GetRunLoader(); + AliRunLoader *rl = AliRunLoader::Instance(); AliEMCALLoader *loader = dynamic_cast(rl->GetDetectorLoader("EMCAL")); - - // get the digits loader->LoadDigits("EMCAL"); loader->GetEvent(); TClonesArray* digits = loader->Digits() ; @@ -101,77 +125,92 @@ void AliEMCALRawUtils::Digits2Raw(AliAltroMapping **mapping) Warning("Digits2Raw", "no digits found !"); return; } - - // get the geometry - AliEMCALGeometry* geom = AliEMCALGeometry::GetInstance(); - if (!geom) { - AliError(Form("No geometry found !")); - return; - } static const Int_t nDDL = 12*2; // 12 SM hardcoded for now. Buffers allocated dynamically, when needed, so just need an upper limit here AliAltroBuffer* buffers[nDDL]; for (Int_t i=0; i < nDDL; i++) buffers[i] = 0; - - Int_t adcValuesLow[fgkTimeBins]; - Int_t adcValuesHigh[fgkTimeBins]; - + + TArrayI adcValuesLow( TIMEBINS ); + TArrayI adcValuesHigh( TIMEBINS ); + // loop over digits (assume ordered digits) - for (Int_t iDigit = 0; iDigit < digits->GetEntries(); iDigit++) { - AliEMCALDigit* digit = dynamic_cast(digits->At(iDigit)) ; - if (digit->GetAmp() < fgThreshold) - continue; - - //get cell indices - Int_t nSM = 0; - Int_t nIphi = 0; - Int_t nIeta = 0; - Int_t iphi = 0; - Int_t ieta = 0; - Int_t nModule = 0; - geom->GetCellIndex(digit->GetId(), nSM, nModule, nIphi, nIeta); - geom->GetCellPhiEtaIndexInSModule(nSM, nModule, nIphi, nIeta,iphi, ieta) ; - - //Check which is the RCU of the cell. - Int_t iRCU = -111; - //RCU0 - if (0<=iphi&&iphi<8) iRCU=0; // first cable row - else if (8<=iphi&&iphi<16 && 0<=ieta&&ieta<24) iRCU=0; // first half; - //second cable row - //RCU1 - else if(8<=iphi&&iphi<16 && 24<=ieta&&ieta<48) iRCU=1; // second half; - //second cable row - else if(16<=iphi&&iphi<24) iRCU=1; // third cable row - - //Which DDL? - Int_t iDDL = fgDDLPerSuperModule* nSM + iRCU; - if (iDDL >= nDDL) - Fatal("Digits2Raw()","Non-existent DDL board number: %d", iDDL); - - if (buffers[iDDL] == 0) { - // open new file and write dummy header - TString fileName = AliDAQ::DdlFileName("EMCAL",iDDL); - buffers[iDDL] = new AliAltroBuffer(fileName.Data(),mapping[iRCU]); - buffers[iDDL]->WriteDataHeader(kTRUE, kFALSE); //Dummy; - } - - // out of time range signal (?) - if (digit->GetTimeR() > GetRawFormatTimeMax() ) { - AliInfo("Signal is out of time range.\n"); - buffers[iDDL]->FillBuffer((Int_t)digit->GetAmp()); - buffers[iDDL]->FillBuffer(GetRawFormatTimeBins() ); // time bin - buffers[iDDL]->FillBuffer(3); // bunch length - buffers[iDDL]->WriteTrailer(3, ieta, iphi, nSM); // trailer - // calculate the time response function - } else { - Bool_t lowgain = RawSampledResponse(digit->GetTimeR(), digit->GetAmp(), adcValuesHigh, adcValuesLow) ; - if (lowgain) - buffers[iDDL]->WriteChannel(ieta, iphi, 0, GetRawFormatTimeBins(), adcValuesLow, fgThreshold); - else - buffers[iDDL]->WriteChannel(ieta,iphi, 1, GetRawFormatTimeBins(), adcValuesHigh, fgThreshold); - } - } + for (Int_t iDigit = 0; iDigit < digits->GetEntries(); iDigit++) + { + AliEMCALDigit* digit = dynamic_cast(digits->At(iDigit)) ; + if(!digit) + { + AliFatal("NULL Digit"); + } + else + { + if (digit->GetAmplitude() < AliEMCALRawResponse::GetRawFormatThreshold() ) + { + continue; + } + //get cell indices + Int_t nSM = 0; + Int_t nIphi = 0; + Int_t nIeta = 0; + Int_t iphi = 0; + Int_t ieta = 0; + Int_t nModule = 0; + fGeom->GetCellIndex(digit->GetId(), nSM, nModule, nIphi, nIeta); + fGeom->GetCellPhiEtaIndexInSModule(nSM, nModule, nIphi, nIeta,iphi, ieta) ; + + //Check which is the RCU, 0 or 1, of the cell. + Int_t iRCU = -111; + if (0<=iphi&&iphi<8) iRCU=0; // first cable row + else if (8<=iphi&&iphi<16 && 0<=ieta&&ieta<24) iRCU=0; // first half; + else if(8<=iphi&&iphi<16 && 24<=ieta&&ieta<48) iRCU=1; // second half; + //second cable row + else if(16<=iphi&&iphi<24) iRCU=1; // third cable row + + if (nSM%2==1) iRCU = 1 - iRCU; // swap for odd=C side, to allow us to cable both sides the same + + if (iRCU<0) + Fatal("Digits2Raw()","Non-existent RCU number: %d", iRCU); + + //Which DDL? + Int_t iDDL = NRCUSPERMODULE*nSM + iRCU; + if (iDDL < 0 || iDDL >= nDDL){ + Fatal("Digits2Raw()","Non-existent DDL board number: %d", iDDL); + } + else{ + if (buffers[iDDL] == 0) + { + // open new file and write dummy header + TString fileName = AliDAQ::DdlFileName("EMCAL",iDDL); + //Select mapping file RCU0A, RCU0C, RCU1A, RCU1C + Int_t iRCUside=iRCU+(nSM%2)*2; + //iRCU=0 and even (0) SM -> RCU0A.data 0 + //iRCU=1 and even (0) SM -> RCU1A.data 1 + //iRCU=0 and odd (1) SM -> RCU0C.data 2 + //iRCU=1 and odd (1) SM -> RCU1C.data 3 + buffers[iDDL] = new AliAltroBuffer(fileName.Data(),fMapping[iRCUside]); + buffers[iDDL]->WriteDataHeader(kTRUE, kFALSE); //Dummy; + } + + // out of time range signal (?) + if (digit->GetTimeR() > TIMEBINMAX ) { + AliInfo("Signal is out of time range.\n"); + buffers[iDDL]->FillBuffer((Int_t)digit->GetAmplitude()); + buffers[iDDL]->FillBuffer( TIMEBINS ); // time bin + buffers[iDDL]->FillBuffer(3); // bunch length + buffers[iDDL]->WriteTrailer(3, ieta, iphi, nSM); // trailer + // calculate the time response function + } else { + Bool_t lowgain = AliEMCALRawResponse::RawSampledResponse(digit->GetTimeR(), digit->GetAmplitude(), + adcValuesHigh.GetArray(), adcValuesLow.GetArray()) ; + + if (lowgain) + buffers[iDDL]->WriteChannel(ieta, iphi, 0, TIMEBINS, adcValuesLow.GetArray(), AliEMCALRawResponse::GetRawFormatThreshold() ); + else + buffers[iDDL]->WriteChannel(ieta,iphi, 1, TIMEBINS, adcValuesHigh.GetArray(), AliEMCALRawResponse::GetRawFormatThreshold() ); + } + }// iDDL under the limits + }//digit exists + }//Digit loop // write headers and close files for (Int_t i=0; i < nDDL; i++) { @@ -181,306 +220,166 @@ void AliEMCALRawUtils::Digits2Raw(AliAltroMapping **mapping) delete buffers[i]; } } - mapping[0]->Delete(); - mapping[1]->Delete(); + loader->UnloadDigits(); } -//____________________________________________________________________________ -void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr, - AliAltroMapping **mapping) -{ - // convert raw data of the current event to digits - AliEMCALGeometry * geom = AliEMCALGeometry::GetInstance(); - if (!geom) { - AliError(Form("No geometry found !")); - return; - } - - digitsArr->Clear(); - - if (!digitsArr) { - Error("Raw2Digits", "no digits found !"); - return; - } - if (!reader) { - Error("Raw2Digits", "no raw reader found !"); - return; - } - - AliCaloRawStream in(reader,"EMCAL",mapping); - // Select EMCAL DDL's; - reader->Select("EMCAL"); - - TString option = GetOption(); - if (option.Contains("OldRCUFormat")) - in.SetOldRCUFormat(kTRUE); // Needed for testbeam data - else - in.SetOldRCUFormat(kFALSE); - - - //Updated fitting routine from 2007 beam test takes into account - //possibility of two peaks in data and selects first one for fitting - //Also sets some of the starting parameters based on the shape of the - //given raw signal being fit - - TF1 * signalF = new TF1("signal", RawResponseFunction, 0, GetRawFormatTimeBins(), 5); - signalF->SetParNames("amp","t0","tau","N","ped"); - signalF->SetParameter(2,2.35); // tau in units of time bin - signalF->SetParLimits(2,2,-1); - signalF->SetParameter(3,2); // order - signalF->SetParLimits(3,2,-1); - - Int_t id = -1; - Float_t time = 0. ; - Float_t amp = 0. ; - - //Graph to hold data we will fit (should be converted to an array - //later to speed up processing - TGraph * gSig = new TGraph(GetRawFormatTimeBins()); - - Int_t readOk = 1; - Int_t lowGain = 0; - - while (readOk && in.GetModule() < 0) - readOk = in.Next(); // Go to first digit - - Int_t col = 0; - Int_t row = 0; - while (readOk) { - id = geom->GetAbsCellIdFromCellIndexes(in.GetModule(), in.GetRow(), in.GetColumn()) ; - lowGain = in.IsLowGain(); - Int_t maxTime = in.GetTime(); // timebins come in reverse order - if (maxTime < 0 || maxTime >= GetRawFormatTimeBins()) { - AliWarning(Form("Invalid time bin %d",maxTime)); - maxTime = GetRawFormatTimeBins(); - } - gSig->Set(maxTime+1); - // There is some kind of zero-suppression in the raw data, - // so set up the TGraph in advance - for (Int_t i=0; i < maxTime; i++) { - gSig->SetPoint(i, i , 0); - } - - Int_t iTime = 0; - do { - if (in.GetTime() >= gSig->GetN()) { - AliWarning("Too many time bins"); - gSig->Set(in.GetTime()); - } - col = in.GetColumn(); - row = in.GetRow(); - - gSig->SetPoint(in.GetTime(), in.GetTime(), in.GetSignal()) ; - if (in.GetTime() > maxTime) - maxTime = in.GetTime(); - iTime++; - } while ((readOk = in.Next()) && !in.IsNewHWAddress()); - FitRaw(gSig, signalF, amp, time) ; - - if (amp > 0) { - AliDebug(2,Form("id %d lowGain %d amp %g", id, lowGain, amp)); - //cout << "col " << col-40 << " row " << row-8 << " lowGain " << lowGain << " amp " << amp << endl; - AddDigit(digitsArr, id, lowGain, (Int_t)amp, time); - } - - // Reset graph - for (Int_t index = 0; index < gSig->GetN(); index++) { - gSig->SetPoint(index, index, 0) ; - } - }; // EMCAL entries loop - - delete signalF ; - delete gSig; - - return ; -} - -//____________________________________________________________________________ -void AliEMCALRawUtils::AddDigit(TClonesArray *digitsArr, Int_t id, Int_t lowGain, Int_t amp, Float_t time) { - // - // Add a new digit. - // This routine checks whether a digit exists already for this tower - // and then decides whether to use the high or low gain info - // - // Called by Raw2Digits - +void AliEMCALRawUtils::AddDigit(TClonesArray *digitsArr, Int_t id, Int_t lowGain, Float_t amp, Float_t time, Float_t chi2, Int_t ndf) +{ + // comment AliEMCALDigit *digit = 0, *tmpdigit = 0; - TIter nextdigit(digitsArr); - while (digit == 0 && (tmpdigit = (AliEMCALDigit*) nextdigit())) { - if (tmpdigit->GetId() == id) - digit = tmpdigit; - } - + + while (digit == 0 && (tmpdigit = (AliEMCALDigit*) nextdigit())) + { + if (tmpdigit->GetId() == id) digit = tmpdigit; + } + if (!digit) { // no digit existed for this tower; create one + Int_t type = AliEMCALDigit::kHG; // use enum in AliEMCALDigit if (lowGain) - amp = Int_t(fHighLowGainFactor * amp); + { + amp *= HGLGFACTOR; + type = AliEMCALDigit::kLGnoHG; + } + Int_t idigit = digitsArr->GetEntries(); - new((*digitsArr)[idigit]) AliEMCALDigit( -1, -1, id, amp, time, idigit) ; - } - else { // a digit already exists, check range - // (use high gain if signal < 800, otherwise low gain) - if (lowGain) { // new digit is low gain - if (digit->GetAmp() > 800) { // use if stored digit is out of range - digit->SetAmp(Int_t(fHighLowGainFactor * amp)); - digit->SetTime(time); - } - } - else if (amp < 800) { // new digit is high gain; use if not out of range - digit->SetAmp(amp); - digit->SetTime(time); - } - } + new((*digitsArr)[idigit]) AliEMCALDigit( -1, -1, id, amp, time, type, idigit, chi2, ndf); + AliDebug(2,Form("Add digit Id %d for the first time, type %d", id, type)); + }//digit added first time + else + { // a digit already exists, check range + // (use high gain if signal < cut value, otherwise low gain) + if (lowGain) + { // new digit is low gain + if (digit->GetAmplitude() > OVERFLOWCUT ) + { // use if previously stored (HG) digit is out of range + digit->SetAmplitude( HGLGFACTOR * amp); + digit->SetTime(time); + digit->SetType(AliEMCALDigit::kLG); + AliDebug(2,Form("Add LG digit ID %d for the second time, type %d", digit->GetId(), digit->GetType())); + } + }//new low gain digit + else { // new digit is high gain + + if (amp < OVERFLOWCUT ) + { // new digit is high gain; use if not out of range + digit->SetAmplitude(amp); + digit->SetTime(time); + digit->SetType(AliEMCALDigit::kHG); + AliDebug(2,Form("Add HG digit ID %d for the second time, type %d", digit->GetId(), digit->GetType())); + } + else + { // HG out of range, just change flag value to show that HG did exist + digit->SetType(AliEMCALDigit::kLG); + AliDebug(2,Form("Change LG digit to HG, ID %d, type %d", digit->GetId(), digit->GetType())); + } + }//new high gain digit + }//digit existed replace it } -//____________________________________________________________________________ -void AliEMCALRawUtils::FitRaw(TGraph * gSig, TF1* signalF, Float_t & amp, Float_t & time) -{ - // Fits the raw signal time distribution; from AliEMCALGetter - - const Int_t kNoiseThreshold = 5; - const Int_t kNPedSamples = 5; - amp = time = 0. ; - Double_t ped = 0; - Int_t nPed = 0; - for (Int_t index = 0; index < kNPedSamples; index++) { - Double_t ttime, signal; - gSig->GetPoint(index, ttime, signal) ; - if (signal > 0) { - ped += signal; - nPed++; - } - } - - if (nPed > 0) - ped /= nPed; - else { - AliWarning("Could not determine pedestal"); - ped = 10; // put some small value as first guess - } +void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr, const AliCaloCalibPedestal* pedbadmap, TClonesArray *digitsTRG, AliEMCALTriggerData* trgData) +{ + //conversion of raw data to digits + if(digitsArr) digitsArr->Clear("C"); + if (!digitsArr) { Error("Raw2Digits", "no digits found !");return;} + if (!reader) {Error("Raw2Digits", "no raw reader found !");return;} + AliEMCALTriggerSTURawStream inSTU(reader); + AliCaloRawStreamV3 in(reader,"EMCAL",fMapping); + reader->Select("EMCAL",0,43); // 43 = AliEMCALGeoParams::fgkLastAltroDDL + fTriggerRawDigitMaker->Reset(); + fTriggerRawDigitMaker->SetIO(reader, in, inSTU, digitsTRG, trgData); + fRawAnalyzer->SetIsZeroSuppressed(true); // TMP - should use stream->IsZeroSuppressed(), or altro cfg registers later + + Int_t lowGain = 0; + Int_t caloFlag = 0; // low, high gain, or TRU, or LED ref. + + Float_t bcTimePhaseCorr = 0; // for BC-based L1 phase correction + Int_t bcMod4 = (reader->GetBCID() % 4); // LHC uses 40 MHz, EMCal uses 10 MHz clock + if (bcMod4==0 || bcMod4==1) { + bcTimePhaseCorr = -1e-7; // subtract 100 ns for certain BC values + } + + while (in.NextDDL()) + { + while (in.NextChannel()) + { + caloFlag = in.GetCaloFlag(); + if (caloFlag > 2) continue; // Work with ALTRO and FALTRO + if(caloFlag < 2 && fRemoveBadChannels && pedbadmap->IsBadChannel(in.GetModule(),in.GetColumn(),in.GetRow())) + { + continue; + } + vector bunchlist; + while (in.NextBunch()) + { + bunchlist.push_back( AliCaloBunchInfo(in.GetStartTimeBin(), in.GetBunchLength(), in.GetSignals() ) ); + } + if (bunchlist.size() == 0) continue; + if ( caloFlag < 2 ) + { // ALTRO + Int_t id = fGeom->GetAbsCellIdFromCellIndexes(in.GetModule(), in.GetRow(), in.GetColumn()) ; + lowGain = in.IsLowGain(); + fRawAnalyzer->SetL1Phase( in.GetL1Phase() ); + AliCaloFitResults res = fRawAnalyzer->Evaluate( bunchlist, in.GetAltroCFG1(), in.GetAltroCFG2()); + if(res.GetAmp() >= fNoiseThreshold ) + { + AddDigit(digitsArr, id, lowGain, res.GetAmp(), res.GetTime()+bcTimePhaseCorr, res.GetChi2(), res.GetNdf() ); + } + }//ALTRO + else if(fUseFALTRO) + {// Fake ALTRO + fTriggerRawDigitMaker->Add( bunchlist ); + }//Fake ALTRO + } // end while over channel + } //end while over DDL's, of input stream + fTriggerRawDigitMaker->PostProcess(); + TrimDigits(digitsArr); +} - Int_t max_found = 0; - Int_t i_max = 0; - Float_t max = -1; - Float_t max_fit = gSig->GetN(); - Float_t min_after_sig = 9999; - Int_t tmin_after_sig = gSig->GetN(); - Int_t n_ped_after_sig = 0; - for (Int_t i=kNPedSamples; i < gSig->GetN(); i++) { - Double_t ttime, signal; - gSig->GetPoint(i, ttime, signal) ; - if (!max_found && signal > max) { - i_max = i; - max = signal; +void AliEMCALRawUtils::TrimDigits(TClonesArray *digitsArr) +{ + AliEMCALDigit *digit = 0; + Int_t n = 0; + Int_t nDigits = digitsArr->GetEntriesFast(); + TIter nextdigit(digitsArr); + while ((digit = (AliEMCALDigit*) nextdigit())) { + if (digit->GetType() == AliEMCALDigit::kLGnoHG) { + AliDebug(1,Form("Remove digit with id %d, LGnoHG",digit->GetId())); + digitsArr->Remove(digit); } - else if ( max > ped + kNoiseThreshold ) { - max_found = 1; - min_after_sig = signal; - tmin_after_sig = i; + else if(fTimeMin > digit->GetTime() || fTimeMax < digit->GetTime()) { + digitsArr->Remove(digit); + AliDebug(1,Form("Remove digit with id %d, Bad Time %e",digit->GetId(), digit->GetTime())); } - if (max_found) { - if ( signal < min_after_sig) { - min_after_sig = signal; - tmin_after_sig = i; - } - if (i > tmin_after_sig + 5) { // Two close peaks; end fit at minimum - max_fit = tmin_after_sig; - break; - } - if ( signal < ped + kNoiseThreshold) - n_ped_after_sig++; - if (n_ped_after_sig >= 5) { // include 5 pedestal bins after peak - max_fit = i; - break; - } + else if (0 > digit->GetChi2()) { + digitsArr->Remove(digit); + AliDebug(1,Form("Remove digit with id %d, Bad Chi2 %e",digit->GetId(), digit->GetChi2())); } - } - - if ( max - ped > kNoiseThreshold ) { // else its noise - AliDebug(2,Form("Fitting max %d ped %d", max, ped)); - signalF->SetRange(0,max_fit); - - if(max-ped > 50) - signalF->SetParLimits(2,1,3); - - signalF->SetParameter(4, ped) ; - signalF->SetParameter(1, i_max); - signalF->SetParameter(0, max); - - gSig->Fit(signalF, "QROW"); // Note option 'W': equal errors on all points - amp = signalF->GetParameter(0); - time = signalF->GetParameter(1)*GetRawFormatTimeBinWidth() - fgTimeTrigger; - } - return; + else { + digit->SetIndexInList(n); + n++; + } + }//while + + digitsArr->Compress(); + AliDebug(1,Form("N Digits before trimming : %d; after array compression %d",nDigits,digitsArr->GetEntriesFast())); } -//__________________________________________________________________ -Double_t AliEMCALRawUtils::RawResponseFunction(Double_t *x, Double_t *par) -{ - // Matches version used in 2007 beam test - // - // Shape of the electronics raw reponse: - // It is a semi-gaussian, 2nd order Gamma function of the general form - // - // t' = (t - t0 + tau) / tau - // F = A * t**N * exp( N * ( 1 - t) ) for t >= 0 - // F = 0 for t < 0 - // - // parameters: - // A: par[0] // Amplitude = peak value - // t0: par[1] - // tau: par[2] - // N: par[3] - // ped: par[4] - // - Double_t signal ; - Double_t tau =par[2]; - Double_t N =par[3]; - Double_t ped = par[4]; - Double_t xx = ( x[0] - par[1] + tau ) / tau ; - if (xx <= 0) - signal = ped ; - else { - signal = ped + par[0] * TMath::Power(xx , N) * TMath::Exp(N * (1 - xx )) ; - } - return signal ; -} -//__________________________________________________________________ -Bool_t AliEMCALRawUtils::RawSampledResponse( -const Double_t dtime, const Double_t damp, Int_t * adcH, Int_t * adcL) const +void AliEMCALRawUtils::SetFittingAlgorithm(Int_t fitAlgo) { - // for a start time dtime and an amplitude damp given by digit, - // calculates the raw sampled response AliEMCAL::RawResponseFunction - - const Int_t kRawSignalOverflow = 0x3FF ; - const Int_t pedVal = 32; - Bool_t lowGain = kFALSE ; + delete fRawAnalyzer; // delete doesn't do anything if the pointer is 0x0 + fRawAnalyzer = AliCaloRawAnalyzerFactory::CreateAnalyzer( fitAlgo ); + fRawAnalyzer->SetNsampleCut(5); // requirement for fits to be done, for the new methods + fRawAnalyzer->SetOverflowCut ( OVERFLOWCUT ); + fRawAnalyzer->SetAmpCut(fNoiseThreshold); + fRawAnalyzer->SetFitArrayCut(fNoiseThreshold); +} - TF1 signalF("signal", RawResponseFunction, 0, GetRawFormatTimeMax(), 4); - signalF.SetParameter(0, pedVal) ; - signalF.SetParameter(1, damp) ; - signalF.SetParameter(2, dtime + fgTimeTrigger) ; - for (Int_t iTime = 0; iTime < GetRawFormatTimeBins(); iTime++) { - Double_t time = iTime * GetRawFormatTimeBinWidth() ; - Double_t signal = signalF.Eval(time) ; - adcH[iTime] = static_cast(signal + 0.5) ; - if ( adcH[iTime] > kRawSignalOverflow ){ // larger than 10 bits - adcH[iTime] = kRawSignalOverflow ; - lowGain = kTRUE ; - } - signal /= fHighLowGainFactor; - - adcL[iTime] = static_cast(signal + 0.5) ; - if ( adcL[iTime] > kRawSignalOverflow) // larger than 10 bits - adcL[iTime] = kRawSignalOverflow ; - } - return lowGain ; -}