1 /**************************************************************************
2 * Copyright(c) 2007, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 // This class decodes the stream of ALTRO samples to extract
19 // the PHOS "digits" of current event. Uses fitting procedure
20 // to separate reasonable samples
23 // AliRawReader* rf = new AliRawReaderDate("2006run2211.raw");
24 // AliPHOSRawDecoder dc(rf);
25 // while (rf->NextEvent()) {
26 // dc.SetOldRCUFormat(kTRUE);
27 // dc.SubtractPedestals(kTRUE);
28 // while ( dc.NextDigit() ) {
29 // Int_t module = dc.GetModule();
30 // Int_t column = dc.GetColumn();
31 // Int_t row = dc.GetRow();
32 // Double_t amplitude = dc.GetEnergy();
33 // Double_t time = dc.GetTime();
34 // Bool_t IsLowGain = dc.IsLowGain();
39 // Author: Dmitri Peressounko using idea of Y.Kucheryaev
41 // --- ROOT system ---
52 // --- AliRoot header files ---
54 #include "AliPHOSRawDecoderv2.h"
55 #include "AliPHOSPulseGenerator.h"
58 ClassImp(AliPHOSRawDecoderv2)
60 //-----------------------------------------------------------------------------
61 AliPHOSRawDecoderv2::AliPHOSRawDecoderv2():AliPHOSRawDecoder(),
62 fNtimeSamples(25),fRMScut(11.)
64 //Default constructor.
73 //-----------------------------------------------------------------------------
74 AliPHOSRawDecoderv2::AliPHOSRawDecoderv2(AliRawReader* rawReader, AliAltroMapping **mapping):
75 AliPHOSRawDecoder(rawReader,mapping),
76 fNtimeSamples(25),fRMScut(11.)
78 //Construct a decoder object.
79 //Is is user responsibility to provide next raw event
80 //using AliRawReader::NextEvent().
89 //-----------------------------------------------------------------------------
90 AliPHOSRawDecoderv2::~AliPHOSRawDecoderv2()
96 //-----------------------------------------------------------------------------
97 AliPHOSRawDecoderv2::AliPHOSRawDecoderv2(const AliPHOSRawDecoderv2 &phosDecoder ):
98 AliPHOSRawDecoder(phosDecoder),
99 fNtimeSamples(25),fRMScut(11.)
102 fNtimeSamples=phosDecoder.fNtimeSamples ;
103 for(Int_t i=0; i<3;i++){
104 fLGpar[i]=phosDecoder.fLGpar[i] ;
105 fHGpar[i]=phosDecoder.fHGpar[i] ;
107 fRMScut=phosDecoder.fRMScut ;
110 //-----------------------------------------------------------------------------
111 AliPHOSRawDecoderv2& AliPHOSRawDecoderv2::operator = (const AliPHOSRawDecoderv2 &phosDecoder)
113 //Assignment operator.
115 fNtimeSamples=phosDecoder.fNtimeSamples ;
116 for(Int_t i=0; i<3;i++){
117 fLGpar[i]=phosDecoder.fLGpar[i] ;
118 fHGpar[i]=phosDecoder.fHGpar[i] ;
120 fRMScut=phosDecoder.fRMScut ;
124 //-----------------------------------------------------------------------------
125 Bool_t AliPHOSRawDecoderv2::NextDigit()
127 //Extract an energy deposited in the crystal,
128 //crystal' position (module,column,row),
129 //time and gain (high or low).
130 //First collects sample, then evaluates it and if it has
131 //reasonable shape, fits it with Gamma2 function and extracts
134 TCanvas * cs = (TCanvas*)gROOT->FindObjectAny("CSample") ;
136 cs = new TCanvas("CSample","CSample") ;
138 TH1D * h = (TH1D*)gROOT->FindObjectAny("hSample") ;
140 h=new TH1D("hSample","",200,0.,200.) ;
143 AliCaloRawStream* in = fCaloStream;
145 Int_t iBin = fSamples->GetSize();
147 Double_t pedMean = 0;
150 Double_t baseLine = 1.0;
151 const Int_t nPreSamples = 10;
154 while ( in->Next() ) {
156 // Fit the full sample
157 if(in->IsNewHWAddress() && iBin!=fSamples->GetSize()) {
159 Double_t pedestal =0. ;
162 pedestal = (Double_t)(pedMean/nPed);
166 for(Int_t i=0; i<fSamples->GetSize(); i++){
167 h->SetBinContent(i+1,fSamples->At(i)) ;
170 //calculate time and energy
173 for(Int_t i=iBin; i<fSamples->GetSize(); i++){
174 if(maxAmp<fSamples->At(i)){
176 maxAmp=fSamples->At(i) ;
179 if(maxBin==fSamples->GetSize()-1){//bad sample
184 fEnergy=Double_t(maxAmp)-pedestal ;
185 fOverflow =0 ; //look for plato on the top of sample
186 if(fEnergy>500 && //this is not fluctuation of soft sample
187 maxBin<fSamples->GetSize()-1 && fSamples->At(maxBin+1)==maxAmp){ //and there is a plato
192 // if(fRow==54 && fColumn==24){
193 // printf("fE=%f, ped=%f, row=%d, col=%d \n",fEnergy,pedestal,fRow,fColumn) ;
194 // if(fOverflow)printf(" Overflow \n") ;
195 // else printf("iBin=%d, maxBin=%d, maxAmp=%d,Amp(+1)=%d,Amp(-1)=%d \n",iBin,maxBin,maxAmp,fSamples->At(maxBin+1),fSamples->At(maxBin-1)) ;
203 return kTRUE ; //do not calculate energy and time for overflowed channels
205 if(fEnergy<baseLine){ //do not evaluate time, drop this sample
211 //else calculate time
228 for(Int_t i=iBin+1; i<fSamples->GetSize()&& cnts<fNtimeSamples; i++){
229 if(fSamples->At(i)<pedestal)
231 //Presently we do not use channels with overflow
232 // if(fOverflow && (fSamples->At(i)==maxAmp ||fSamples->At(i-1)==maxAmp)) //can not calculate time in overflow bin
234 if(fTimes->At(i)-fTimes->At(i-1)!=1) //do not use samples with non-consequtive points
236 Double_t de=fSamples->At(i)-pedestal ;
237 Double_t av = de+fSamples->At(i-1)-pedestal ;
238 if(av<=0.) //this is fluctuation around pedestal, scip
240 Double_t ds = fSamples->At(i)-fSamples->At(i-1) ;
241 Double_t ti = ds/av ; // calculate log. derivative
242 ti=a/(ti+b)-c*ti ; // and compare with parameterization
243 ti=Double_t(fTimes->At(i))-ti ;
244 Double_t wi = TMath::Abs(ds) ;
253 fQuality = tRMS/tW-fTime*fTime ;
255 //printf("t0=%f, RMS=%f, cut=%f \n",fTime,tRMS,fRMScut) ;
256 // if(tRMS>=fRMScut){ //bad sample
267 for(Int_t i=iBin+1; i<fSamples->GetSize()-1&&!isBad; i++){
268 if(fSamples->At(i)>fSamples->At(i-1)+5 && fSamples->At(i)>fSamples->At(i+1)+5) { //single jump
275 pedRMS=pedRMS/nPed-pedestal*pedestal ;
279 for(Int_t i=iBin+1; i<fSamples->GetSize()-1&&!isBad; i++){
280 if(fSamples->At(i)<pedestal-1)
287 if(fEnergy>10. && !isBad ){
288 printf("fE=%f, ped=%f, fQuality=%f, pedRMS=%f \n",fEnergy,pedestal,fQuality,pedRMS) ;
289 if(fOverflow)printf(" Overflow \n") ;
290 if(isBad)printf("bad") ;
291 // else printf("iBin=%d, maxBin=%d, maxAmp=%d,Amp(+1)=%d,Amp(-1)=%d \n",iBin,maxBin,maxAmp,fSamples->At(maxBin+1),fSamples->At(maxBin-1)) ;
299 return kTRUE ; //will scan further
302 fLowGainFlag = in->IsLowGain();
303 fModule = in->GetModule()+1;
304 fRow = in->GetRow() +1;
305 fColumn = in->GetColumn()+1;
308 // Fill array with samples
310 if(fPedSubtract && (in->GetTime() < nPreSamples)) {
311 pedMean += in->GetSignal();
312 pedRMS += in->GetSignal()*in->GetSignal();
315 fSamples->AddAt(in->GetSignal(),iBin);
316 fTimes->AddAt(in->GetTime(),iBin);