3 /**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
5 * ALICE Experiment at CERN, All rights reserved. *
7 * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 * Kenneth Aamodt <Kenneth.aamodt@ift.uib.no> *
9 * for The ALICE HLT Project. *
11 * Permission to use, copy, modify and distribute this software and its *
12 * documentation strictly for non-commercial purposes is hereby granted *
13 * without fee, provided that the above copyright notice appears in all *
14 * copies and that both the copyright notice and this permission notice *
15 * appear in the supporting documentation. The authors make no claims *
16 * about the suitability of this software for any purpose. It is *
17 * provided "as is" without express or implied warranty. *
18 **************************************************************************/
20 /** @file AliHLTTPCPad.cxx
21 @author Matthias Richter, Kenneth Aamodt
23 @brief Container Class for TPC Pads.
26 // see header file for class documentation
28 // refer to README to build package
30 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
37 #include "AliHLTTPCPad.h"
38 #include "AliHLTStdIncludes.h"
42 #include "AliHLTTPCTransform.h"
43 #include "AliHLTTPCClusters.h"
45 //------------------------------
47 /** margin for the base line be re-avaluated */
48 #define ALIHLTPAD_BASELINE_MARGIN (2*fAverage)
50 /** ROOT macro for the implementation of ROOT specific class methods */
51 ClassImp(AliHLTTPCPad)
53 AliHLTTPCPad::AliHLTTPCPad()
56 fUsedClusterCandidates(),
74 fSignalPositionArray(NULL),
75 fSizeOfSignalPositionArray(0)
77 // see header file for class documentation
79 // refer to README to build package
81 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
82 // HLTInfo("Entering default constructor");
83 fDataSignals= new AliHLTTPCSignal_t[AliHLTTPCTransform::GetNTimeBins()];
84 memset( fDataSignals, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
86 fSignalPositionArray= new AliHLTTPCSignal_t[AliHLTTPCTransform::GetNTimeBins()];
87 memset( fSignalPositionArray, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
88 fSizeOfSignalPositionArray=0;
91 AliHLTTPCPad::AliHLTTPCPad(Int_t offset, Int_t nofBins)
94 fUsedClusterCandidates(),
112 fSignalPositionArray(NULL),
113 fSizeOfSignalPositionArray(0)
115 // see header file for class documentation
118 AliHLTTPCPad::~AliHLTTPCPad()
120 // see header file for class documentation
122 HLTWarning("event data acquisition not stopped");
126 AliHLTTPCSignal_t* pData=fDataSignals;
130 if (fSignalPositionArray) {
131 AliHLTTPCSignal_t* pData=fSignalPositionArray;
132 fSignalPositionArray=NULL;
138 Int_t AliHLTTPCPad::SetID(Int_t rowno, Int_t padno)
140 // see header file for class documentation
146 Int_t AliHLTTPCPad::StartEvent()
148 // see header file for class documentation
150 if (fpRawData==NULL) {
159 fpRawData=new AliHLTTPCSignal_t[fNofBins];
161 for (int i=0; i<fNofBins; i++) fpRawData[i]=-1;
163 HLTError("memory allocation failed");
168 HLTWarning("event data acquisition already started");
174 Int_t AliHLTTPCPad::CalculateBaseLine(Int_t reqMinCount)
176 // see header file for class documentation
178 AliHLTTPCSignal_t avBackup=fAverage;
179 //HLTDebug("reqMinCount=%d fCount=%d fTotal=%d fSum=%d fBLMax=%d fBLMin=%d", reqMinCount, fCount, fTotal, fSum, fBLMax, fBLMin);
180 if (fCount>=reqMinCount && fCount>=fTotal/2) {
181 fAverage=fCount>0?fSum/fCount:0;
183 //HLTDebug("average for current event %d (%d - %d)", fAverage, fBLMax, fBLMin);
185 if (fBLMax>ALIHLTPAD_BASELINE_MARGIN) {
187 //HLTDebug("maximum value %d exceeds margin for base line (%d) "
188 // "-> re-evaluate base line", fBLMax, ALIHLTPAD_BASELINE_MARGIN);
190 for (Int_t i=fFirstBLBin; i<fNofBins; i++)
191 if (fpRawData[i]>=0) AddBaseLineValue(i, fpRawData[i]);
192 if (fCount>0 && fCount>=reqMinCount && fCount>=fTotal/2) {
193 fAverage=fSum/fCount;
194 //HLTDebug("new average %d", fAverage);
196 // HLTDebug("baseline re-eveluation skipped because of to few "
197 // "contributing bins: total=%d, contributing=%d, req=%d"
198 // "\ndata might be already zero suppressed"
199 // , fTotal, fCount, reqMinCount);
204 HLTError("missing raw data for base line calculation");
209 // calculate average for all events
210 fAverage=((avBackup*fNofEvents)+fAverage)/(fNofEvents+1);
211 //HLTDebug("base line average for %d event(s): %d", fNofEvents+1, fAverage);
219 // HLTDebug("baseline calculation skipped because of to few contributing "
220 // "bins: total=%d, contributing=%d, required=%d \ndata might be "
221 // "already zero suppressed", fTotal, fCount, reqMinCount);
227 Int_t AliHLTTPCPad::StopEvent()
229 // see header file for class documentation
232 AliHLTTPCSignal_t* pData=fpRawData;
238 } else if (fNofBins>0) {
239 HLTError("event data acquisition not started");
245 Int_t AliHLTTPCPad::ResetHistory()
247 // see header file for class documentation
254 Int_t AliHLTTPCPad::SetThreshold(AliHLTTPCSignal_t thresh)
256 // see header file for class documentation
262 Int_t AliHLTTPCPad::AddBaseLineValue(Int_t bin, AliHLTTPCSignal_t value)
264 // see header file for class documentation
266 if (bin>=fFirstBLBin) {
267 if (fAverage<0 || value<ALIHLTPAD_BASELINE_MARGIN) {
268 // add to the current sum and count
272 // keep the maximum value for later quality control of the base
277 if (fBLMin<0 || fBLMin>value) {
278 // keep the minimum value for later quality control of the base
284 // HLTDebug("ignoring value %d (bin %d) for base line calculation "
285 // "(current average is %d)",
286 // value, bin, fAverage);
292 Int_t AliHLTTPCPad::SetRawData(Int_t bin, AliHLTTPCSignal_t value)
294 // see header file for class documentation
299 if (fpRawData[bin]<0) {
300 AddBaseLineValue(bin, value);
303 // ignore value for average calculation
304 HLTWarning("overriding content of bin %d (%d)", bin, fpRawData[bin]);
306 fpRawData[bin]=value;
308 HLTWarning("ignoring neg. raw data");
311 HLTWarning("bin %d out of range (%d)", bin, fNofBins);
314 } else if (fNofBins>0) {
315 HLTError("event cycle not started");
321 Int_t AliHLTTPCPad::Next(Int_t bZeroSuppression)
323 // see header file for class documentation
324 if (fpRawData==NULL) return 0;
325 Int_t iResult=fReadPos<fNofBins;
326 if (iResult>0 && (iResult=(++fReadPos<fNofBins))>0) {
327 if (bZeroSuppression) {
328 while ((iResult=(fReadPos<fNofBins))>0 &&
329 GetCorrectedData(fReadPos)<=0)
336 Int_t AliHLTTPCPad::Rewind(Int_t bZeroSuppression)
338 // see header file for class documentation
339 fReadPos=(bZeroSuppression>0?0:fFirstBLBin)-1;
340 return Next(bZeroSuppression);
343 AliHLTTPCSignal_t AliHLTTPCPad::GetRawData(Int_t bin) const
345 // see header file for class documentation
346 AliHLTTPCSignal_t data=0;
351 HLTWarning("requested bin %d out of range (%d)", bin, fNofBins);
353 } else if (fNofBins>0) {
354 HLTWarning("data only available within event cycle");
359 AliHLTTPCSignal_t AliHLTTPCPad::GetCorrectedData(Int_t bin) const
361 // see header file for class documentation
362 AliHLTTPCSignal_t data=GetRawData(bin)-GetBaseLine(bin);
363 AliHLTTPCSignal_t prev=0;
364 if (bin>1) prev=GetRawData(bin-1)-GetBaseLine(bin-1);
365 AliHLTTPCSignal_t succ=0;
366 if (bin+1<GetSize()) succ=GetRawData(bin+1)-GetBaseLine(bin+1);
374 // the signal is below the base-line and threshold
378 // the neighboring bins are both below base-line/threshold
379 // a real signal is always more than one bin wide because of the shaper
380 if (prev<=0 && succ<=0) data=0;
383 // the bin is inside the range of ignored bins
384 if (bin<fFirstBLBin) data=0;
385 //HLTDebug("fReadPos=%d data=%d threshold=%d raw data=%d base line=%d", fReadPos, data, fThreshold, GetRawData(bin), GetBaseLine(bin));
389 AliHLTTPCSignal_t AliHLTTPCPad::GetBaseLine(Int_t bin) const
391 // see header file for class documentation
392 AliHLTTPCSignal_t val=0;
394 // we take the minumum value as the base line if it doesn't differ from
395 // the average to much
398 const AliHLTTPCSignal_t kMaxDifference=15;
399 if ((fAverage-fBLMin)<=kMaxDifference) val=fBLMin;
400 else val>kMaxDifference?val-=kMaxDifference:0;
404 // here we should never get
406 HLTFatal("wrong base line value");
411 AliHLTTPCSignal_t AliHLTTPCPad::GetAverage() const
413 // see header file for class documentation
414 return fAverage>0?fAverage:0;
417 Float_t AliHLTTPCPad::GetOccupancy() const
419 // see header file for class documentation
421 if (fpRawData && fNofBins>0) {
422 for (Int_t i=fFirstBLBin; i<fNofBins; i++) {
423 if (GetCorrectedData(i)>0) occupancy+=1;
425 if (fNofBins-fFirstBLBin>0)
426 occupancy/=fNofBins-fFirstBLBin;
431 Float_t AliHLTTPCPad::GetAveragedOccupancy() const
433 // see header file for class documentation
435 // history is not yet implemented
436 return GetOccupancy();
438 void AliHLTTPCPad::PrintRawData()
440 // see header file for class documentation
441 for(Int_t bin=0;bin<AliHLTTPCTransform::GetNTimeBins();bin++){
442 if(GetDataSignal(bin)>0)
443 cout<<fRowNo<<"\t"<<fPadNo<<"\t"<<bin<<"\t"<<GetDataSignal(bin)<<endl;;
445 cout<<"bins: "<<AliHLTTPCTransform::GetNTimeBins()<<endl;
448 void AliHLTTPCPad::SetDataToDefault()
450 // see header file for class documentation
452 memset( fDataSignals, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
453 memset( fSignalPositionArray, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
454 fSizeOfSignalPositionArray=0;
458 void AliHLTTPCPad::SetDataSignal(Int_t bin,Int_t signal)
460 // see header file for class documentation
461 fDataSignals[bin]=signal;
462 fSignalPositionArray[fSizeOfSignalPositionArray]=bin;
463 fSizeOfSignalPositionArray++;
466 Int_t AliHLTTPCPad::GetDataSignal(Int_t bin) const
468 // see header file for class documentation
469 return fDataSignals[bin];
472 void AliHLTTPCPad::FindClusterCandidates()
474 // see header file for class documentation
478 vector<Int_t> tmpPos;
479 vector<Int_t> tmpSig;
482 for(Int_t pos=fSizeOfSignalPositionArray-2;pos>=0;pos--){
484 if(fSignalPositionArray[pos]==fSignalPositionArray[pos+1]+1){
485 seqcharge+=fDataSignals[fSignalPositionArray[pos+1]];
486 seqaverage += fSignalPositionArray[pos+1]*fDataSignals[fSignalPositionArray[pos+1]];
487 seqerror += fSignalPositionArray[pos+1]*fSignalPositionArray[pos+1]*fDataSignals[fSignalPositionArray[pos+1]];
489 tmpPos.push_back(fSignalPositionArray[pos+1]);
490 tmpSig.push_back(fDataSignals[fSignalPositionArray[pos+1]]);
492 if(fDataSignals[fSignalPositionArray[pos+1]]>fDataSignals[fSignalPositionArray[pos]]){
495 if(fDataSignals[fSignalPositionArray[pos+1]]<fDataSignals[fSignalPositionArray[pos]]&&isFalling){
497 seqmean = seqaverage/seqcharge;
499 //Calculate mean in pad direction:
500 Int_t padmean = seqcharge*fPadNo;
501 Int_t paderror = fPadNo*padmean;
502 AliHLTTPCClusters candidate;
503 candidate.fTotalCharge = seqcharge;
504 candidate.fPad = padmean;
505 candidate.fPad2 = paderror;
506 candidate.fTime = seqaverage;
507 candidate.fTime2 = seqerror;
508 candidate.fMean = seqmean;
509 candidate.fLastMergedPad = fPadNo;
510 fClusterCandidates.push_back(candidate);
511 fUsedClusterCandidates.push_back(0);
524 seqcharge+=fDataSignals[fSignalPositionArray[0]];
525 seqaverage += fSignalPositionArray[0]*fDataSignals[fSignalPositionArray[0]];
526 seqerror += fSignalPositionArray[0]*fSignalPositionArray[0]*fDataSignals[fSignalPositionArray[0]];
527 tmpPos.push_back(fSignalPositionArray[0]);
528 tmpSig.push_back(fDataSignals[fSignalPositionArray[0]]);
530 //Calculate mean of sequence:
532 seqmean = seqaverage/seqcharge;
534 //Calculate mean in pad direction:
535 Int_t padmean = seqcharge*fPadNo;
536 Int_t paderror = fPadNo*padmean;
537 AliHLTTPCClusters candidate;
538 candidate.fTotalCharge = seqcharge;
539 candidate.fPad = padmean;
540 candidate.fPad2 = paderror;
541 candidate.fTime = seqaverage;
542 candidate.fTime2 = seqerror;
543 candidate.fMean = seqmean;
544 candidate.fLastMergedPad = fPadNo;
545 fClusterCandidates.push_back(candidate);
546 fUsedClusterCandidates.push_back(0);
556 else if(seqcharge>0){
557 seqcharge+=fDataSignals[fSignalPositionArray[pos+1]];
558 seqaverage += fSignalPositionArray[pos+1]*fDataSignals[fSignalPositionArray[pos+1]];
559 seqerror += fSignalPositionArray[pos+1]*fSignalPositionArray[pos+1]*fDataSignals[fSignalPositionArray[pos+1]];
560 tmpPos.push_back(fSignalPositionArray[pos+1]);
561 tmpSig.push_back(fDataSignals[fSignalPositionArray[pos+1]]);
563 //Calculate mean of sequence:
565 seqmean = seqaverage/seqcharge;
567 //Calculate mean in pad direction:
568 Int_t padmean = seqcharge*fPadNo;
569 Int_t paderror = fPadNo*padmean;
570 AliHLTTPCClusters candidate;
571 candidate.fTotalCharge = seqcharge;
572 candidate.fPad = padmean;
573 candidate.fPad2 = paderror;
574 candidate.fTime = seqaverage;
575 candidate.fTime2 = seqerror;
576 candidate.fMean = seqmean;
577 candidate.fLastMergedPad = fPadNo;
578 fClusterCandidates.push_back(candidate);
579 fUsedClusterCandidates.push_back(0);