1 /**************************************************************************
2 * Copyright(c) 1998-1999, 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 **************************************************************************/
20 //-------------------------------------------------------
21 // Implementation of the TPC pulser calibration
23 // Origin: Jens Wiechula, Marian Ivanov J.Wiechula@gsi.de, Marian.Ivanov@cern.ch
26 //-------------------------------------------------------
34 #include <TObjArray.h>
44 #include <TDirectory.h>
49 #include "AliRawReader.h"
50 #include "AliRawReaderRoot.h"
51 #include "AliRawReaderDate.h"
52 #include "AliRawEventHeaderBase.h"
53 #include "AliTPCRawStream.h"
54 #include "AliTPCcalibDB.h"
55 #include "AliTPCCalROC.h"
56 #include "AliTPCCalPad.h"
57 #include "AliTPCROC.h"
58 #include "AliTPCParam.h"
59 #include "AliTPCCalibCE.h"
60 #include "AliMathBase.h"
61 #include "TTreeStream.h"
65 ClassImp(AliTPCCalibCE) /*FOLD00*/
67 AliTPCCalibCE::AliTPCCalibCE() : /*FOLD00*/
82 fROC(AliTPCROC::Instance()),
83 fParam(new AliTPCParam),
91 fCalRocArrayOutliers(72),
96 fParamArrayEvent(1000),
97 fParamArrayEventPol1(72),
98 fParamArrayEventPol2(72),
99 fTMeanArrayEvent(1000),
100 fQMeanArrayEvent(1000),
107 fPadTimesArrayEvent(72),
109 fPadRMSArrayEvent(72),
110 fPadPedestalArrayEvent(72),
120 fVTime0OffsetCounter(72),
129 // AliTPCSignal default constructor
131 // fHTime0 = new TH1F("hTime0Event","hTime0Event",(fLastTimeBin-fFirstTimeBin)*10,fFirstTimeBin,fLastTimeBin);
133 //_____________________________________________________________________
134 AliTPCCalibCE::AliTPCCalibCE(const AliTPCCalibCE &sig) :
136 fFirstTimeBin(sig.fFirstTimeBin),
137 fLastTimeBin(sig.fLastTimeBin),
138 fNbinsT0(sig.fNbinsT0),
139 fXminT0(sig.fXminT0),
140 fXmaxT0(sig.fXmaxT0),
141 fNbinsQ(sig.fNbinsQ),
144 fNbinsRMS(sig.fNbinsRMS),
145 fXminRMS(sig.fXminRMS),
146 fXmaxRMS(sig.fXmaxRMS),
148 fOldRCUformat(kTRUE),
149 fROC(AliTPCROC::Instance()),
150 fParam(new AliTPCParam),
158 fCalRocArrayOutliers(72),
163 fParamArrayEvent(1000),
164 fParamArrayEventPol1(72),
165 fParamArrayEventPol2(72),
166 fTMeanArrayEvent(1000),
167 fQMeanArrayEvent(1000),
170 fNevents(sig.fNevents),
174 fPadTimesArrayEvent(72),
176 fPadRMSArrayEvent(72),
177 fPadPedestalArrayEvent(72),
187 fVTime0OffsetCounter(72),
193 fDebugLevel(sig.fDebugLevel)
196 // AliTPCSignal default constructor
199 for (Int_t iSec = 0; iSec < 72; iSec++){
200 const AliTPCCalROC *calQ = (AliTPCCalROC*)sig.fCalRocArrayQ.UncheckedAt(iSec);
201 const AliTPCCalROC *calT0 = (AliTPCCalROC*)sig.fCalRocArrayT0.UncheckedAt(iSec);
202 const AliTPCCalROC *calRMS = (AliTPCCalROC*)sig.fCalRocArrayRMS.UncheckedAt(iSec);
203 const AliTPCCalROC *calOut = (AliTPCCalROC*)sig.fCalRocArrayOutliers.UncheckedAt(iSec);
205 const TH2S *hQ = (TH2S*)sig.fHistoQArray.UncheckedAt(iSec);
206 const TH2S *hT0 = (TH2S*)sig.fHistoT0Array.UncheckedAt(iSec);
207 const TH2S *hRMS = (TH2S*)sig.fHistoRMSArray.UncheckedAt(iSec);
209 if ( calQ != 0x0 ) fCalRocArrayQ.AddAt(new AliTPCCalROC(*calQ), iSec);
210 if ( calT0 != 0x0 ) fCalRocArrayT0.AddAt(new AliTPCCalROC(*calT0), iSec);
211 if ( calRMS != 0x0 ) fCalRocArrayRMS.AddAt(new AliTPCCalROC(*calRMS), iSec);
212 if ( calOut != 0x0 ) fCalRocArrayOutliers.AddAt(new AliTPCCalROC(*calOut), iSec);
215 TH2S *hNew = new TH2S(*hQ);
216 hNew->SetDirectory(0);
217 fHistoQArray.AddAt(hNew,iSec);
220 TH2S *hNew = new TH2S(*hT0);
221 hNew->SetDirectory(0);
222 fHistoQArray.AddAt(hNew,iSec);
225 TH2S *hNew = new TH2S(*hRMS);
226 hNew->SetDirectory(0);
227 fHistoQArray.AddAt(hNew,iSec);
230 for (Int_t iEvent=0; iEvent<sig.fParamArrayEvent.GetSize(); iEvent++)
231 fParamArrayEvent.AddAtAndExpand(sig.fParamArrayEvent.At(iEvent),iEvent);
232 Int_t nrows = sig.fVEventTime.GetNrows();
233 fVEventTime.ResizeTo(nrows);
234 for (Int_t iEvent=0; iEvent<nrows; iEvent++)
235 fVEventTime[iEvent] = sig.fVEventTime[iEvent];
237 // fHTime0 = new TH1F("hTime0Event","hTime0Event",(fLastTimeBin-fFirstTimeBin)*10,fFirstTimeBin,fLastTimeBin);
239 //_____________________________________________________________________
240 AliTPCCalibCE& AliTPCCalibCE::operator = (const AliTPCCalibCE &source)
243 // assignment operator
245 if (&source == this) return *this;
246 new (this) AliTPCCalibCE(source);
250 //_____________________________________________________________________
251 AliTPCCalibCE::~AliTPCCalibCE()
257 fCalRocArrayT0.Delete();
258 fCalRocArrayQ.Delete();
259 fCalRocArrayRMS.Delete();
261 fHistoQArray.Delete();
262 fHistoT0Array.Delete();
263 fHistoRMSArray.Delete();
265 fPadTimesArrayEvent.Delete();
266 fPadQArrayEvent.Delete();
267 fPadRMSArrayEvent.Delete();
268 fPadPedestalArrayEvent.Delete();
270 if ( fDebugStreamer) delete fDebugStreamer;
271 // if ( fHTime0 ) delete fHTime0;
275 //_____________________________________________________________________
276 Int_t AliTPCCalibCE::Update(const Int_t icsector, /*FOLD00*/
279 const Int_t icTimeBin,
280 const Float_t csignal)
283 // Signal filling methode on the fly pedestal and Time offset correction if necessary.
284 // no extra analysis necessary. Assumes knowledge of the signal shape!
285 // assumes that it is looped over consecutive time bins of one pad
287 if ( (icTimeBin>fLastTimeBin) || (icTimeBin<fFirstTimeBin) ) return 0;
289 Int_t iChannel = fROC->GetRowIndexes(icsector)[icRow]+icPad; // global pad position in sector
291 //init first pad and sector in this event
292 if ( fCurrentChannel == -1 ) {
293 fCurrentChannel = iChannel;
294 fCurrentSector = icsector;
298 //process last pad if we change to a new one
299 if ( iChannel != fCurrentChannel ){
301 fCurrentChannel = iChannel;
302 fCurrentSector = icsector;
306 //fill signals for current pad
307 fPadSignal.GetMatrixArray()[icTimeBin]=csignal;
308 if ( csignal > fMaxPadSignal ){
309 fMaxPadSignal = csignal;
310 fMaxTimeBin = icTimeBin;
314 //_____________________________________________________________________
315 void AliTPCCalibCE::FindPedestal(Float_t part)
318 // find pedestal and noise for the current pad. Use either database or
319 // truncated mean with part*100%
321 Bool_t noPedestal = kTRUE;;
322 if (fPedestalTPC&&fPadNoiseTPC){
323 //use pedestal database
324 //only load new pedestals if the sector has changed
325 if ( fCurrentSector!=fLastSector ){
326 fPedestalROC = fPedestalTPC->GetCalROC(fCurrentSector);
327 fPadNoiseROC = fPadNoiseTPC->GetCalROC(fCurrentSector);
328 fLastSector=fCurrentSector;
331 if ( fPedestalROC&&fPadNoiseROC ){
332 fPadPedestal = fPedestalROC->GetValue(fCurrentChannel);
333 fPadNoise = fPadNoiseROC->GetValue(fCurrentChannel);
339 //if we are not running with pedestal database, or for the current sector there is no information
340 //available, calculate the pedestal and noise on the fly
342 const Int_t kPedMax = 100; //maximum pedestal value
351 UShort_t histo[kPedMax];
352 memset(histo,0,kPedMax*sizeof(UShort_t));
354 for (Int_t i=fFirstTimeBin; i<=fLastTimeBin; i++){
355 padSignal = fPadSignal.GetMatrixArray()[i];
356 if (padSignal<=0) continue;
357 if (padSignal>max && i>10) {
361 if (padSignal>kPedMax-1) continue;
362 histo[int(padSignal+0.5)]++;
366 for (Int_t i=1; i<kPedMax; i++){
367 if (count1<count0*0.5) median=i;
372 Float_t count=histo[median] ,mean=histo[median]*median, rms=histo[median]*median*median ;
374 for (Int_t idelta=1; idelta<10; idelta++){
375 if (median-idelta<=0) continue;
376 if (median+idelta>kPedMax) continue;
377 if (count<part*count1){
378 count+=histo[median-idelta];
379 mean +=histo[median-idelta]*(median-idelta);
380 rms +=histo[median-idelta]*(median-idelta)*(median-idelta);
381 count+=histo[median+idelta];
382 mean +=histo[median+idelta]*(median+idelta);
383 rms +=histo[median+idelta]*(median+idelta)*(median+idelta);
390 rms = TMath::Sqrt(TMath::Abs(rms/count-mean*mean));
396 //_____________________________________________________________________
397 void AliTPCCalibCE::FindCESignal(TVectorD ¶m, Float_t &qSum, const TVectorF maxima)
400 // Find position, signal width and height of the CE signal (last signal)
401 // param[0] = Qmax, param[1] = mean time, param[2] = rms;
402 // maxima: array of local maxima of the pad signal use the one closest to the mean CE position
405 Float_t ceQmax =0, ceQsum=0, ceTime=0, ceRMS=0;
407 Float_t ceSumThreshold = 8.*fPadNoise; // threshold for the signal sum
408 const Int_t kCemin = 4; // range for the analysis of the ce signal +- channels from the peak
409 const Int_t kCemax = 7;
411 Float_t minDist = 25; //initial minimum distance betweek roc mean ce signal and pad ce signal
413 // find maximum closest to the sector mean from the last event
414 for ( Int_t imax=0; imax<maxima.GetNrows(); imax++){
415 Float_t tmean = (*((TVectorF*)(fTMeanArrayEvent[fTMeanArrayEvent.GetLast()])))[fCurrentSector];
416 if ( TMath::Abs( tmean-maxima[imax] ) < minDist ) {
417 minDist = tmean-maxima[imax];
418 cemaxpos = (Int_t)maxima[imax];
423 ceQmax = fPadSignal.GetMatrixArray()[cemaxpos]-fPadPedestal;
424 for (Int_t i=cemaxpos-kCemin; i<cemaxpos+kCemax; i++){
425 Float_t signal = fPadSignal.GetMatrixArray()[i]-fPadPedestal;
426 if ( (i>fFirstTimeBin) && (i<fLastTimeBin) && (signal>0) ){
427 ceTime+=signal*(i+0.5);
428 ceRMS +=signal*(i+0.5)*(i+0.5);
433 if (ceQmax&&ceQsum>ceSumThreshold) {
435 ceRMS = TMath::Sqrt(TMath::Abs(ceRMS/ceQsum-ceTime*ceTime));
436 fVTime0Offset.GetMatrixArray()[fCurrentSector]+=ceTime; // mean time for each sector
437 fVTime0OffsetCounter.GetMatrixArray()[fCurrentSector]++;
439 //Normalise Q to pad area of irocs
440 Float_t norm = fParam->GetPadPitchWidth(fCurrentSector)*fParam->GetPadPitchLength(fCurrentSector,fCurrentRow);
443 fVMeanQ.GetMatrixArray()[fCurrentSector]+=ceQsum;
444 fVMeanQCounter.GetMatrixArray()[fCurrentSector]++;
456 //_____________________________________________________________________
457 Bool_t AliTPCCalibCE::IsPeak(Int_t pos, Int_t tminus, Int_t tplus)
460 // Check if 'pos' is a Maximum. Consider 'tminus' timebins before
461 // and 'tplus' timebins after 'pos'
463 for (Int_t iTime = pos; iTime>pos-tminus; iTime--)
464 if ( fPadSignal[iTime-1] >= fPadSignal[iTime] ) return kFALSE;
465 for (Int_t iTime = pos, iTime2=pos; iTime<pos+tplus; iTime++,iTime2++){
466 if ( (iTime==pos) && (fPadSignal[iTime+1]==fPadSignal[iTime]) ) // allow two timebins with same adc value
468 if ( fPadSignal[iTime2+1] >= fPadSignal[iTime2] ) return kFALSE;
472 //_____________________________________________________________________
473 void AliTPCCalibCE::FindLocalMaxima(TVectorF &maxima)
476 // Find local maxima on the pad signal and Histogram them
478 Float_t ceThreshold = 5.*fPadNoise; // threshold for the signal
482 for (Int_t i=fLastTimeBin-tplus-1; i>=fFirstTimeBin+tminus; i--){
483 if ( (fPadSignal[i]-fPadPedestal)>ceThreshold && IsPeak(i,tminus,tplus) ){
484 maxima.GetMatrixArray()[count++]=i;
485 GetHistoTmean(fCurrentSector,kTRUE)->Fill(i);
489 //_____________________________________________________________________
490 void AliTPCCalibCE::ProcessPad() /*FOLD00*/
493 // Process data of current pad
498 FindLocalMaxima(maxima);
499 if ( (fNevents == 0) || (fOldRunNumber!=fRunNumber) ) return; // return because we don't have Time0 info for the CE yet
505 FindCESignal(param, Qsum, maxima);
507 Double_t meanT = param[1];
508 Double_t sigmaT = param[2];
510 //Fill Event T0 counter
511 (*GetPadTimesEvent(fCurrentSector,kTRUE)).GetMatrixArray()[fCurrentChannel] = meanT;
514 GetHistoQ(fCurrentSector,kTRUE)->Fill( TMath::Sqrt(Qsum), fCurrentChannel );
517 GetHistoRMS(fCurrentSector,kTRUE)->Fill( sigmaT, fCurrentChannel );
520 //Fill debugging info
521 if ( fDebugLevel>0 ){
522 (*GetPadPedestalEvent(fCurrentSector,kTRUE)).GetMatrixArray()[fCurrentChannel]=fPadPedestal;
523 (*GetPadRMSEvent(fCurrentSector,kTRUE)).GetMatrixArray()[fCurrentChannel]=sigmaT;
524 (*GetPadQEvent(fCurrentSector,kTRUE)).GetMatrixArray()[fCurrentChannel]=Qsum;
529 //_____________________________________________________________________
530 void AliTPCCalibCE::EndEvent() /*FOLD00*/
533 // Process data of current pad
534 // The Functions 'SetTimeStamp' and 'SetRunNumber' should be called
535 // before the EndEvent function to set the event timestamp and number!!!
536 // This is automatically done if the ProcessEvent(AliRawReader *rawReader)
537 // function was called
540 //check if last pad has allready been processed, if not do so
541 if ( fMaxTimeBin>-1 ) ProcessPad();
545 TVectorF vMeanTime(72);
547 AliTPCCalROC calIroc(0);
548 AliTPCCalROC calOroc(36);
550 //find mean time0 offset for side A and C
551 Double_t time0Side[2]; //time0 for side A:0 and C:0
552 Double_t time0SideCount[2]; //time0 counter for side A:0 and C:0
553 time0Side[0]=0;time0Side[1]=0;time0SideCount[0]=0;time0SideCount[1]=0;
554 for ( Int_t iSec = 0; iSec<72; iSec++ ){
555 time0Side[(iSec/18)%2] += fVTime0Offset.GetMatrixArray()[iSec];
556 time0SideCount[(iSec/18)%2] += fVTime0OffsetCounter.GetMatrixArray()[iSec];
558 if ( time0SideCount[0] >0 )
559 time0Side[0]/=time0SideCount[0];
560 if ( time0SideCount[1] >0 )
561 time0Side[1]/=time0SideCount[1];
562 // end find time0 offset
564 //loop over all ROCs, fill CE Time histogram corrected for the mean Time0 of each ROC
565 for ( Int_t iSec = 0; iSec<72; iSec++ ){
567 //find median and then calculate the mean around it
568 TH1S *hMeanT = GetHistoTmean(iSec);
569 if ( !hMeanT ) continue;
570 Double_t entries = hMeanT->GetEntries();
572 Short_t *arr = hMeanT->GetArray()+1;
574 for ( ibin=0; ibin<hMeanT->GetNbinsX(); ibin++){
576 if ( sum>=(entries/2) ) break;
579 Int_t firstBin = fFirstTimeBin+ibin-delta;
580 Int_t lastBin = fFirstTimeBin+ibin+delta;
581 if ( firstBin<fFirstTimeBin ) firstBin=fFirstTimeBin;
582 if ( lastBin>fLastTimeBin ) lastBin =fLastTimeBin;
583 Float_t median =AliMathBase::GetCOG(arr+ibin-delta,2*delta,firstBin,lastBin);
584 vMeanTime.GetMatrixArray()[iSec]=median;
587 TVectorF *vTimes = GetPadTimesEvent(iSec);
588 if ( !vTimes ) continue;
589 AliTPCCalROC calIrocOutliers(0);
590 AliTPCCalROC calOrocOutliers(36);
592 // calculate mean Q of the sector
594 if ( fVMeanQCounter.GetMatrixArray()[iSec]>0 ) meanQ=fVMeanQ.GetMatrixArray()[iSec]/fVMeanQCounter.GetMatrixArray()[iSec];
595 vMeanQ.GetMatrixArray()[iSec]=meanQ;
597 for ( UInt_t iChannel=0; iChannel<fROC->GetNChannels(iSec); iChannel++ ){
598 Float_t Time = (*vTimes).GetMatrixArray()[iChannel];
600 //set values for temporary roc calibration class
602 calIroc.SetValue(iChannel, Time);
603 if ( Time == 0 ) calIrocOutliers.SetValue(iChannel,1);
606 calOroc.SetValue(iChannel, Time);
607 if ( Time == 0 ) calOrocOutliers.SetValue(iChannel,1);
610 if ( (fNevents>0) && (fOldRunNumber==fRunNumber) )
611 GetHistoT0(iSec,kTRUE)->Fill( Time-time0Side[(iSec/18)%2],iChannel );
615 //------------------------------- Debug start ------------------------------
616 if ( fDebugLevel>0 ){
617 if ( !fDebugStreamer ) {
619 TDirectory *backup = gDirectory;
620 fDebugStreamer = new TTreeSRedirector("debugCalibCE.root");
621 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
628 Float_t Q = (*GetPadQEvent(iSec))[iChannel];
629 Float_t RMS = (*GetPadRMSEvent(iSec))[iChannel];
631 UInt_t channel=iChannel;
634 while ( channel > (fROC->GetRowIndexes(sector)[row]+fROC->GetNPads(sector,row)-1) ) row++;
635 pad = channel-fROC->GetRowIndexes(sector)[row];
636 padc = pad-(fROC->GetNPads(sector,row)/2);
638 // TH1F *h1 = new TH1F(Form("hSignalD%d.%d.%d",sector,row,pad),
639 // Form("hSignalD%d.%d.%d",sector,row,pad),
640 // fLastTimeBin-fFirstTimeBin,
641 // fFirstTimeBin,fLastTimeBin);
642 // h1->SetDirectory(0);
644 // for (Int_t i=fFirstTimeBin; i<fLastTimeBin+1; i++)
645 // h1->Fill(i,fPadSignal(i));
648 if (fVTime0OffsetCounter.GetMatrixArray()[iSec]>0)
649 T0Sec = fVTime0Offset.GetMatrixArray()[iSec]/fVTime0OffsetCounter.GetMatrixArray()[iSec];
650 Double_t T0Side = time0Side[(iSec/18)%2];
651 (*fDebugStreamer) << "DataPad" <<
652 "Event=" << fNevents <<
653 "EventNumber=" << fRunNumber <<
654 "TimeStamp=" << fTimeStamp <<
655 "Sector="<< sector <<
659 "PadSec="<< channel <<
660 "Time0Sec=" << T0Sec <<
661 "Time0Side=" << T0Side <<
672 //----------------------------- Debug end ------------------------------
676 TVectorD paramPol1(3);
677 TVectorD paramPol2(6);
678 TMatrixD matPol1(3,3);
679 TMatrixD matPol2(6,6);
683 if ( (fNevents>0) && (fOldRunNumber==fRunNumber) ){
685 calIroc.GlobalFit(&calIrocOutliers,0,paramPol1,matPol1,chi2Pol1,0);
686 calIroc.GlobalFit(&calIrocOutliers,0,paramPol2,matPol2,chi2Pol2,1);
688 calOroc.GlobalFit(&calOrocOutliers,0,paramPol1,matPol1,chi2Pol1,0);
689 calOroc.GlobalFit(&calOrocOutliers,0,paramPol2,matPol2,chi2Pol2,1);
692 GetParamArrayPol1(iSec,kTRUE)->AddAtAndExpand(new TVectorD(paramPol1), fNevents);
693 GetParamArrayPol2(iSec,kTRUE)->AddAtAndExpand(new TVectorD(paramPol2), fNevents);
695 // printf("events: %d -- size: %d\n",fNevents,GetParamArrayPol1(iSec)->GetSize());
697 //------------------------------- Debug start ------------------------------
698 if ( fDebugLevel>0 ){
699 if ( !fDebugStreamer ) {
701 TDirectory *backup = gDirectory;
702 fDebugStreamer = new TTreeSRedirector("debugCalibCE.root");
703 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
705 (*fDebugStreamer) << "DataRoc" <<
706 "Event=" << fEvent <<
707 "EventNumber=" << fRunNumber <<
708 "TimeStamp=" << fTimeStamp <<
710 "hMeanT.=" << hMeanT <<
711 "median=" << median <<
712 "paramPol1.=" << ¶mPol1 <<
713 "paramPol2.=" << ¶mPol2 <<
714 "matPol1.=" << &matPol1 <<
715 "matPol2.=" << &matPol2 <<
716 "chi2Pol1=" << chi2Pol1 <<
717 "chi2Pol2=" << chi2Pol2 <<
720 //------------------------------- Debug end ------------------------------
723 /* AliMathBase::FitGaus(fHTime0->GetArray()+1,
724 fHTime0->GetNbinsX(),
725 fHTime0->GetXaxis()->GetXmin(),
726 fHTime0->GetXaxis()->GetXmax(),
730 // fParamArrayEvent.AddAtAndExpand(new TVectorD(param),fNevents);
731 fTMeanArrayEvent.AddAtAndExpand(new TVectorF(vMeanTime),fNevents);
732 fQMeanArrayEvent.AddAtAndExpand(new TVectorF(vMeanQ),fNevents);
733 if ( fVEventTime.GetNrows() < fNevents ) {
734 fVEventTime.ResizeTo((Int_t)(fVEventTime.GetNrows()+1000));
735 fVEventNumber.ResizeTo((Int_t)(fVEventNumber.GetNrows()+1000));
737 fVEventTime[fNevents] = fTimeStamp;
738 fVEventNumber[fNevents] = fRunNumber;
741 fOldRunNumber = fRunNumber;
744 //_____________________________________________________________________
745 Bool_t AliTPCCalibCE::ProcessEvent(AliTPCRawStream *rawStream) /*FOLD00*/
748 // Event Processing loop - AliTPCRawStream
749 // The Function 'SetTimeStamp' should be called for each event to set the event time stamp!!!
752 rawStream->SetOldRCUFormat(fOldRCUformat);
756 Bool_t withInput = kFALSE;
758 while (rawStream->Next()) {
760 Int_t isector = rawStream->GetSector(); // current sector
761 Int_t iRow = rawStream->GetRow(); // current row
762 Int_t iPad = rawStream->GetPad(); // current pad
763 Int_t iTimeBin = rawStream->GetTime(); // current time bin
764 Float_t signal = rawStream->GetSignal(); // current ADC signal
766 Update(isector,iRow,iPad,iTimeBin,signal);
776 //_____________________________________________________________________
777 Bool_t AliTPCCalibCE::ProcessEvent(AliRawReader *rawReader)
780 // Event processing loop - AliRawReader
784 AliTPCRawStream rawStream(rawReader);
785 AliRawEventHeaderBase* eventHeader = (AliRawEventHeaderBase*)rawReader->GetEventHeader();
787 fTimeStamp = eventHeader->Get("Timestamp");
788 fRunNumber = eventHeader->Get("RunNb");
792 rawReader->Select("TPC");
794 return ProcessEvent(&rawStream);
796 //_____________________________________________________________________
797 Bool_t AliTPCCalibCE::ProcessEvent(eventHeaderStruct *event)
800 // Event processing loop - date event
802 AliRawReader *rawReader = new AliRawReaderDate((void*)event);
803 Bool_t result=ProcessEvent(rawReader);
808 //_____________________________________________________________________
809 TH2S* AliTPCCalibCE::GetHisto(Int_t sector, TObjArray *arr, /*FOLD00*/
810 Int_t nbinsY, Float_t ymin, Float_t ymax,
811 Char_t *type, Bool_t force)
814 // return pointer to TH2S histogram of 'type'
815 // if force is true create a new histogram if it doesn't exist allready
817 if ( !force || arr->UncheckedAt(sector) )
818 return (TH2S*)arr->UncheckedAt(sector);
820 // if we are forced and histogram doesn't yes exist create it
821 Char_t name[255], title[255];
823 sprintf(name,"hCalib%s%.2d",type,sector);
824 sprintf(title,"%s calibration histogram sector %.2d",type,sector);
826 // new histogram with Q calib information. One value for each pad!
827 TH2S* hist = new TH2S(name,title,
829 fROC->GetNChannels(sector),0,fROC->GetNChannels(sector));
830 hist->SetDirectory(0);
831 arr->AddAt(hist,sector);
834 //_____________________________________________________________________
835 TH2S* AliTPCCalibCE::GetHistoT0(Int_t sector, Bool_t force) /*FOLD00*/
838 // return pointer to T0 histogram
839 // if force is true create a new histogram if it doesn't exist allready
841 TObjArray *arr = &fHistoT0Array;
842 return GetHisto(sector, arr, fNbinsT0, fXminT0, fXmaxT0, "T0", force);
844 //_____________________________________________________________________
845 TH2S* AliTPCCalibCE::GetHistoQ(Int_t sector, Bool_t force) /*FOLD00*/
848 // return pointer to Q histogram
849 // if force is true create a new histogram if it doesn't exist allready
851 TObjArray *arr = &fHistoQArray;
852 return GetHisto(sector, arr, fNbinsQ, fXminQ, fXmaxQ, "Q", force);
854 //_____________________________________________________________________
855 TH2S* AliTPCCalibCE::GetHistoRMS(Int_t sector, Bool_t force) /*FOLD00*/
858 // return pointer to Q histogram
859 // if force is true create a new histogram if it doesn't exist allready
861 TObjArray *arr = &fHistoRMSArray;
862 return GetHisto(sector, arr, fNbinsRMS, fXminRMS, fXmaxRMS, "RMS", force);
864 //_____________________________________________________________________
865 TH1S* AliTPCCalibCE::GetHisto(Int_t sector, TObjArray *arr,
866 Char_t *type, Bool_t force)
869 // return pointer to TH1S histogram
870 // if force is true create a new histogram if it doesn't exist allready
872 if ( !force || arr->UncheckedAt(sector) )
873 return (TH1S*)arr->UncheckedAt(sector);
875 // if we are forced and histogram doesn't yes exist create it
876 Char_t name[255], title[255];
878 sprintf(name,"hCalib%s%.2d",type,sector);
879 sprintf(title,"%s calibration histogram sector %.2d",type,sector);
881 // new histogram with Q calib information. One value for each pad!
882 TH1S* hist = new TH1S(name,title,
883 fLastTimeBin-fFirstTimeBin,fFirstTimeBin,fLastTimeBin);
884 hist->SetDirectory(0);
885 arr->AddAt(hist,sector);
888 //_____________________________________________________________________
889 TH1S* AliTPCCalibCE::GetHistoTmean(Int_t sector, Bool_t force)
892 // return pointer to Q histogram
893 // if force is true create a new histogram if it doesn't exist allready
895 TObjArray *arr = &fHistoTmean;
896 return GetHisto(sector, arr, "LastTmean", force);
898 //_____________________________________________________________________
899 TVectorF* AliTPCCalibCE::GetPadInfoEvent(Int_t sector, TObjArray *arr, Bool_t force) /*FOLD00*/
902 // return pointer to Pad Info from 'arr' for the current event and sector
903 // if force is true create it if it doesn't exist allready
905 if ( !force || arr->UncheckedAt(sector) )
906 return (TVectorF*)arr->UncheckedAt(sector);
908 TVectorF *vect = new TVectorF(fROC->GetNChannels(sector));
909 arr->AddAt(vect,sector);
912 //_____________________________________________________________________
913 TVectorF* AliTPCCalibCE::GetPadTimesEvent(Int_t sector, Bool_t force) /*FOLD00*/
916 // return pointer to Pad Times Array for the current event and sector
917 // if force is true create it if it doesn't exist allready
919 TObjArray *arr = &fPadTimesArrayEvent;
920 return GetPadInfoEvent(sector,arr,force);
922 //_____________________________________________________________________
923 TVectorF* AliTPCCalibCE::GetPadQEvent(Int_t sector, Bool_t force) /*FOLD00*/
926 // return pointer to Pad Q Array for the current event and sector
927 // if force is true create it if it doesn't exist allready
928 // for debugging purposes only
931 TObjArray *arr = &fPadQArrayEvent;
932 return GetPadInfoEvent(sector,arr,force);
934 //_____________________________________________________________________
935 TVectorF* AliTPCCalibCE::GetPadRMSEvent(Int_t sector, Bool_t force) /*FOLD00*/
938 // return pointer to Pad RMS Array for the current event and sector
939 // if force is true create it if it doesn't exist allready
940 // for debugging purposes only
942 TObjArray *arr = &fPadRMSArrayEvent;
943 return GetPadInfoEvent(sector,arr,force);
945 //_____________________________________________________________________
946 TVectorF* AliTPCCalibCE::GetPadPedestalEvent(Int_t sector, Bool_t force) /*FOLD00*/
949 // return pointer to Pad RMS Array for the current event and sector
950 // if force is true create it if it doesn't exist allready
951 // for debugging purposes only
953 TObjArray *arr = &fPadPedestalArrayEvent;
954 return GetPadInfoEvent(sector,arr,force);
956 //_____________________________________________________________________
957 AliTPCCalROC* AliTPCCalibCE::GetCalRoc(Int_t sector, TObjArray* arr, Bool_t force) /*FOLD00*/
960 // return pointer to ROC Calibration
961 // if force is true create a new histogram if it doesn't exist allready
963 if ( !force || arr->UncheckedAt(sector) )
964 return (AliTPCCalROC*)arr->UncheckedAt(sector);
966 // if we are forced and histogram doesn't yes exist create it
968 // new AliTPCCalROC for T0 information. One value for each pad!
969 AliTPCCalROC *croc = new AliTPCCalROC(sector);
971 for ( UInt_t iChannel = 0; iChannel<croc->GetNchannels(); iChannel++){
972 croc->SetValue(iChannel, 0);
974 arr->AddAt(croc,sector);
977 //_____________________________________________________________________
978 AliTPCCalROC* AliTPCCalibCE::GetCalRocT0(Int_t sector, Bool_t force) /*FOLD00*/
981 // return pointer to Carge ROC Calibration
982 // if force is true create a new histogram if it doesn't exist allready
984 TObjArray *arr = &fCalRocArrayT0;
985 return GetCalRoc(sector, arr, force);
987 //_____________________________________________________________________
988 AliTPCCalROC* AliTPCCalibCE::GetCalRocQ(Int_t sector, Bool_t force) /*FOLD00*/
991 // return pointer to T0 ROC Calibration
992 // if force is true create a new histogram if it doesn't exist allready
994 TObjArray *arr = &fCalRocArrayQ;
995 return GetCalRoc(sector, arr, force);
997 //_____________________________________________________________________
998 AliTPCCalROC* AliTPCCalibCE::GetCalRocRMS(Int_t sector, Bool_t force) /*FOLD00*/
1001 // return pointer to signal width ROC Calibration
1002 // if force is true create a new histogram if it doesn't exist allready
1004 TObjArray *arr = &fCalRocArrayRMS;
1005 return GetCalRoc(sector, arr, force);
1007 //_____________________________________________________________________
1008 AliTPCCalROC* AliTPCCalibCE::GetCalRocOutliers(Int_t sector, Bool_t force)
1011 // return pointer to Outliers
1012 // if force is true create a new histogram if it doesn't exist allready
1014 TObjArray *arr = &fCalRocArrayOutliers;
1015 return GetCalRoc(sector, arr, force);
1017 //_____________________________________________________________________
1018 TObjArray* AliTPCCalibCE::GetParamArray(Int_t sector, TObjArray* arr, Bool_t force)
1021 // return pointer to TObjArray of fit parameters
1022 // if force is true create a new histogram if it doesn't exist allready
1024 if ( !force || arr->UncheckedAt(sector) )
1025 return (TObjArray*)arr->UncheckedAt(sector);
1027 // if we are forced and array doesn't yes exist create it
1029 // new TObjArray for parameters
1030 TObjArray *newArr = new TObjArray;
1031 arr->AddAt(newArr,sector);
1034 //_____________________________________________________________________
1035 TObjArray* AliTPCCalibCE::GetParamArrayPol1(Int_t sector, Bool_t force)
1038 // return pointer to TObjArray of fit parameters from plane fit
1039 // if force is true create a new histogram if it doesn't exist allready
1041 TObjArray *arr = &fParamArrayEventPol1;
1042 return GetParamArray(sector, arr, force);
1044 //_____________________________________________________________________
1045 TObjArray* AliTPCCalibCE::GetParamArrayPol2(Int_t sector, Bool_t force)
1048 // return pointer to TObjArray of fit parameters from parabola fit
1049 // if force is true create a new histogram if it doesn't exist allready
1051 TObjArray *arr = &fParamArrayEventPol2;
1052 return GetParamArray(sector, arr, force);
1054 //_____________________________________________________________________
1055 void AliTPCCalibCE::ResetEvent() /*FOLD00*/
1058 // Reset global counters -- Should be called before each event is processed
1067 fPadTimesArrayEvent.Delete();
1068 fPadQArrayEvent.Delete();
1069 fPadRMSArrayEvent.Delete();
1070 fPadPedestalArrayEvent.Delete();
1072 for ( Int_t i=0; i<72; i++ ){
1073 fVTime0Offset.GetMatrixArray()[i]=0;
1074 fVTime0OffsetCounter.GetMatrixArray()[i]=0;
1075 fVMeanQ.GetMatrixArray()[i]=0;
1076 fVMeanQCounter.GetMatrixArray()[i]=0;
1079 //_____________________________________________________________________
1080 void AliTPCCalibCE::ResetPad() /*FOLD00*/
1083 // Reset pad infos -- Should be called after a pad has been processed
1085 for (Int_t i=fFirstTimeBin; i<fLastTimeBin+1; i++)
1086 fPadSignal.GetMatrixArray()[i] = 0;
1092 //_____________________________________________________________________
1093 TGraph *AliTPCCalibCE::MakeGraphTimeCE(Int_t sector, Int_t xVariable, Int_t fitType, Int_t fitParameter) /*FOLD00*/
1096 // Make graph from fit parameters of pol1 or pol2 fit
1097 // xVariable: 0-run time, 1-run number, 2-internal event counter
1098 // fitType: 0-pol1 fit, 1-pol2 fit, 2-mean time, 2-mean Q
1099 // fitParameter: fit parameter ( 0-2 for pol1, 0-5 for pol2, 0 for mean time )
1102 Double_t *x = new Double_t[fNevents];
1103 Double_t *y = new Double_t[fNevents];
1105 TVectorD *xVar = 0x0;
1106 TObjArray *aType = 0x0;
1110 if ( (sector<0) || (sector>71) ) return 0x0;
1111 if ( (xVariable<0) || (xVariable>2) ) return 0x0;
1112 if ( (fitType<0) || (fitType>3) ) return 0x0;
1114 if ( (fitParameter<0) || (fitParameter>2) ) return 0x0;
1115 aType = &fParamArrayEventPol1;
1116 if ( aType->At(sector)==0x0 ) return 0x0;
1118 else if ( fitType==1 ){
1119 if ( (fitParameter<0) || (fitParameter>5) ) return 0x0;
1120 aType = &fParamArrayEventPol2;
1121 if ( aType->At(sector)==0x0 ) return 0x0;
1125 if ( xVariable == 0 ) xVar = &fVEventTime;
1126 if ( xVariable == 1 ) xVar = &fVEventNumber;
1127 if ( xVariable == 2 ) {
1128 xVar = new TVectorD(fNevents);
1129 for ( Int_t i=0;i<fNevents; i++) (*xVar)[i]=i;
1132 for (Int_t ievent =0; ievent<fNevents; ievent++){
1134 TObjArray *events = (TObjArray*)(aType->At(sector));
1135 if ( events->GetSize()<=ievent ) break;
1136 TVectorD *v = (TVectorD*)(events->At(ievent));
1137 if ( v!=0x0 ) { x[npoints]=(*xVar)[ievent]; y[npoints]=(*v)[fitParameter]; npoints++;}
1138 } else if (fitType == 2) {
1139 Double_t yValue=(*((TVectorF*)(fTMeanArrayEvent[ievent])))[sector];
1140 if ( yValue>0 ) { x[npoints]=(*xVar)[ievent]; y[npoints]=yValue;npoints++;}
1141 }else if (fitType == 3) {
1142 Double_t yValue=(*((TVectorF*)(fQMeanArrayEvent[ievent])))[sector];
1143 if ( yValue>0 ) { x[npoints]=(*xVar)[ievent]; y[npoints]=yValue;npoints++;}
1147 TGraph *gr = new TGraph(npoints);
1148 //sort xVariable increasing
1149 Int_t *sortIndex = new Int_t[npoints];
1150 TMath::Sort(npoints,x,sortIndex);
1151 for (Int_t i=0;i<npoints;i++){
1152 gr->SetPoint(i,x[sortIndex[i]],y[sortIndex[i]]);
1156 if ( xVariable == 2 ) delete xVar;
1162 //_____________________________________________________________________
1163 void AliTPCCalibCE::Analyse()
1166 // Calculate calibration constants
1170 TVectorD paramT0(3);
1171 TVectorD paramRMS(3);
1172 TMatrixD dummy(3,3);
1174 for (Int_t iSec=0; iSec<72; iSec++){
1175 TH2S *hT0 = GetHistoT0(iSec);
1176 if (!hT0 ) continue;
1178 AliTPCCalROC *rocQ = GetCalRocQ (iSec,kTRUE);
1179 AliTPCCalROC *rocT0 = GetCalRocT0 (iSec,kTRUE);
1180 AliTPCCalROC *rocRMS = GetCalRocRMS(iSec,kTRUE);
1181 AliTPCCalROC *rocOut = GetCalRocOutliers(iSec,kTRUE);
1183 TH2S *hQ = GetHistoQ(iSec);
1184 TH2S *hRMS = GetHistoRMS(iSec);
1186 Short_t *array_hQ = hQ->GetArray();
1187 Short_t *array_hT0 = hT0->GetArray();
1188 Short_t *array_hRMS = hRMS->GetArray();
1190 UInt_t nChannels = fROC->GetNChannels(iSec);
1198 for (UInt_t iChannel=0; iChannel<nChannels; iChannel++){
1201 Float_t cogTime0 = -1000;
1202 Float_t cogQ = -1000;
1203 Float_t cogRMS = -1000;
1207 Int_t offsetQ = (fNbinsQ+2)*(iChannel+1)+1;
1208 Int_t offsetT0 = (fNbinsT0+2)*(iChannel+1)+1;
1209 Int_t offsetRMS = (fNbinsRMS+2)*(iChannel+1)+1;
1212 AliMathBase::FitGaus(array_hQ+offsetQ,fNbinsQ,fXminQ,fXmaxQ,¶mQ,&dummy);
1213 AliMathBase::FitGaus(array_hT0+offsetT0,fNbinsT0,fXminT0,fXmaxT0,¶mT0,&dummy);
1214 AliMathBase::FitGaus(array_hRMS+offsetRMS,fNbinsRMS,fXminRMS,fXmaxRMS,¶mRMS,&dummy);
1216 cogTime0 = paramT0[1];
1217 cogRMS = paramRMS[1];
1219 cogQ = AliMathBase::GetCOG(array_hQ+offsetQ,fNbinsQ,fXminQ,fXmaxQ);
1220 cogTime0 = AliMathBase::GetCOG(array_hT0+offsetT0,fNbinsT0,fXminT0,fXmaxT0);
1221 cogRMS = AliMathBase::GetCOG(array_hRMS+offsetRMS,fNbinsRMS,fXminRMS,fXmaxRMS);
1226 if ( (cogQ < ??) && (cogTime0 > ??) && (cogTime0<??) && ( cogRMS>??) ){
1233 rocQ->SetValue(iChannel, cogQ*cogQ);
1234 rocT0->SetValue(iChannel, cogTime0);
1235 rocRMS->SetValue(iChannel, cogRMS);
1236 rocOut->SetValue(iChannel, cogOut);
1240 if ( fDebugLevel > 0 ){
1241 if ( !fDebugStreamer ) {
1243 TDirectory *backup = gDirectory;
1244 fDebugStreamer = new TTreeSRedirector("debugCalibCEAnalysis.root");
1245 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
1248 while ( iChannel > (fROC->GetRowIndexes(iSec)[row]+fROC->GetNPads(iSec,row)-1) ) row++;
1249 pad = iChannel-fROC->GetRowIndexes(iSec)[row];
1250 padc = pad-(fROC->GetNPads(iSec,row)/2);
1252 (*fDebugStreamer) << "DataEnd" <<
1253 "Sector=" << iSec <<
1257 "PadSec=" << iChannel <<
1259 "T0=" << cogTime0 <<
1268 fDebugStreamer->GetFile()->Write();
1269 // delete fDebugStreamer;
1270 // fDebugStreamer = 0x0;
1272 //_____________________________________________________________________
1273 void AliTPCCalibCE::DumpToFile(const Char_t *filename, const Char_t *dir, Bool_t append)
1276 // Write class to file
1285 option = "recreate";
1287 TDirectory *backup = gDirectory;
1288 TFile f(filename,option.Data());
1290 if ( !sDir.IsNull() ){
1291 f.mkdir(sDir.Data());
1297 if ( backup ) backup->cd();