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: U. Frankenfeld, A. Vestbo, C. Loizides *
8 //* Matthias Richter <Matthias.Richter@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 AliHLTTPCMemHandler.cxx
21 // @author U. Frankenfeld, A. Vestbo, C. Loizides, maintained by
24 // @brief input interface base class for the TPC tracking code before
25 // migration to the HLT component framework
28 #include "AliHLTTPCDigitData.h"
29 #include "AliHLTTPCLogging.h"
30 #include "AliHLTTPCTransform.h"
31 #include "AliHLTTPCSpacePointData.h"
32 #include "AliHLTTPCMemHandler.h"
37 ClassImp(AliHLTTPCMemHandler)
39 AliHLTTPCMemHandler::AliHLTTPCMemHandler()
63 AliHLTTPCMemHandler::~AliHLTTPCMemHandler()
67 if(fRandomDigits) delete [] fRandomDigits;
68 if(fDPt) delete [] fDPt;
71 void AliHLTTPCMemHandler::Init(Int_t s,Int_t p, Int_t *r)
81 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Init","sector coordinates")
82 <<"Invalid slice no " << s <<ENDLOG;
90 fRowMin=AliHLTTPCTransform::GetFirstRow(p);
91 fRowMax=AliHLTTPCTransform::GetLastRow(p);
96 void AliHLTTPCMemHandler::ResetROI()
98 //Resets the Look-up table for Region of Interest mode.
99 for(Int_t i=fRowMin; i<=fRowMax; i++)
101 fEtaMinTimeBin[i] = 0;
102 fEtaMaxTimeBin[i] = AliHLTTPCTransform::GetNTimeBins()-1;
106 void AliHLTTPCMemHandler::SetROI(const Float_t *eta,Int_t */*slice*/)
108 // Init the Look-up table for the Region of Interest mode.
109 // Here you can specify a certain etaregion, - all data
110 // outside this region will be discarded:
111 // eta[0] = mimium eta
112 // eta[1] = maximum eta
113 // slice[0] = mimumum slice
114 // slice[1] = maximum slice
117 if(TMath::Abs(eta[1])<.00001)
119 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetROI","Eta Values")
120 <<"Bad ROI parameters."<<ENDLOG;
121 for(Int_t i=fRowMin; i<=fRowMax; i++)
129 for(Int_t i=fRowMin; i<=fRowMax; i++)
134 Float_t thetamax = 2*atan(exp(-1.*eta[1]));
136 xyz[0] = AliHLTTPCTransform::Row2X(i);
138 xyz[2] = xyz[0]/tan(thetamax);
139 AliHLTTPCTransform::Slice2Sector(fSlice,i,sector,row);
140 AliHLTTPCTransform::Local2Raw(xyz,sector,row);
142 fEtaMinTimeBin[i] = (Int_t)xyz[2];
144 if(TMath::Abs(eta[0])<.00001)
145 fEtaMaxTimeBin[i] = 445;
148 Float_t thetamin = 2*atan(exp(-1.*eta[0]));
149 xyz[0] = AliHLTTPCTransform::Row2X(i);
150 xyz[1] = AliHLTTPCTransform::GetMaxY(i);
151 Float_t radii = sqrt(pow(xyz[0],2) + pow(xyz[1],2));
152 xyz[2] = radii/tan(thetamin);
153 AliHLTTPCTransform::Local2Raw(xyz,sector,row);
154 fEtaMaxTimeBin[i] = (Int_t)xyz[2];
160 Bool_t AliHLTTPCMemHandler::SetBinaryInput(char *name)
162 //Set the input binary file.
163 fInBinary = fopen(name,"r");
165 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryInput","File Open")
166 <<"Error opening file "<<name<<ENDLOG;
172 Bool_t AliHLTTPCMemHandler::SetBinaryInput(FILE *file)
174 //Set the input binary file.
177 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryInput","File Open")
178 <<"Pointer to File = 0x0 "<<ENDLOG;
184 void AliHLTTPCMemHandler::CloseBinaryInput()
186 //Close the input file.
188 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CloseBinaryInput","File Close")
189 <<"Nothing to Close"<<ENDLOG;
196 Bool_t AliHLTTPCMemHandler::SetBinaryOutput(char *name)
198 //Set the binary output file.
199 fOutBinary = fopen(name,"w");
201 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryOutput","File Open")
202 <<"Pointer to File = 0x0 "<<ENDLOG;
208 Bool_t AliHLTTPCMemHandler::SetBinaryOutput(FILE *file)
210 //Set the binary output file.
213 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryOutput","File Open")
214 <<"Pointer to File = 0x0 "<<ENDLOG;
220 void AliHLTTPCMemHandler::CloseBinaryOutput()
224 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CloseBinaryOutPut","File Close")
225 <<"Nothing to Close"<<ENDLOG;
232 UInt_t AliHLTTPCMemHandler::GetFileSize()
234 //Returns the file size in bytes of the input file.
236 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetFileSize","File")
237 <<"No Input File"<<ENDLOG;
240 fseek(fInBinary,0,SEEK_END);
241 long size=ftell(fInBinary);
243 if (size<0) return 0;
247 Byte_t *AliHLTTPCMemHandler::Allocate()
250 return Allocate(GetFileSize());
253 Byte_t *AliHLTTPCMemHandler::Allocate(UInt_t size)
255 //Allocate memory of size in bytes.
257 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Allocate","Memory")
258 <<"Delete Memory"<<ENDLOG;
261 fPt = new Byte_t[size];
264 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Allocate","Memory")
265 <<AliHLTTPCLog::kDec<<"Allocate "<<size<<" Bytes of Memory"<<ENDLOG;
269 void AliHLTTPCMemHandler::Free()
271 //Clear the memory, if allocated.
273 // LOG(AliHLTTPCLog::kInformational,"AliHLTTPCMemHandler::Free","Memory")
274 // <<"No Memory allocated - can't Free"<<ENDLOG;
282 ///////////////////////////////////////// Random
283 void AliHLTTPCMemHandler::SetRandomSeed()
285 //If you are adding random data to the original data.
287 SetRandomSeed(time(tp));
290 void AliHLTTPCMemHandler::SetRandomCluster(Int_t maxnumber)
292 //If you are adding random data to the original data.
295 fNRandom = maxnumber;
297 if(fRandomDigits) delete [] fRandomDigits;
298 fRandomDigits = new AliHLTTPCRandomDigitData[fNRandom*9];
299 if(fDPt) delete [] fDPt;
300 fDPt = new AliHLTTPCRandomDigitData *[fNRandom*9];
303 void AliHLTTPCMemHandler::QSort(AliHLTTPCRandomDigitData **a, Int_t first, Int_t last)
306 // Sort array of AliHLTTPCRandomDigitData pointers using a quicksort algorithm.
307 // Uses CompareDigits() to compare objects.
310 static AliHLTTPCRandomDigitData *tmp;
311 static int i; // "static" to save stack space
314 while (last - first > 1) {
318 while (++i < last && CompareDigits(a[i], a[first]) < 0)
320 while (--j > first && CompareDigits(a[j], a[first]) > 0)
337 if (j - first < last - (j + 1)) {
339 first = j + 1; // QSort(j + 1, last);
341 QSort(a, j + 1, last);
342 last = j; // QSort(first, j);
347 UInt_t AliHLTTPCMemHandler::GetRandomSize() const
351 for(Int_t r=fRowMin;r<=fRowMax;r++){
352 Int_t npad=AliHLTTPCTransform::GetNPads(r);
353 nrandom += Int_t (fNGenerate * ((Double_t) npad/141.));
355 return 9 * nrandom * sizeof(AliHLTTPCDigitData);
358 void AliHLTTPCMemHandler::DigitizePoint(Int_t row, Int_t pad,
359 Int_t time,Int_t charge)
361 //Making one single random cluster.
362 for(Int_t j=-1;j<2;j++){
363 for(Int_t k=-1;k<2;k++){
364 Int_t dcharge = charge;
367 if(dcharge<10) continue;
368 Int_t dpad = j + pad;
369 Int_t dtime = k + time;
371 if(dpad<0||dpad>=AliHLTTPCTransform::GetNPads(row)) continue;
372 if(dtime<0||dtime>=AliHLTTPCTransform::GetNTimeBins()) continue;
374 fRandomDigits[fNDigits].fCharge = dcharge;
375 fRandomDigits[fNDigits].fRow = row;
376 fRandomDigits[fNDigits].fPad = dpad;
377 fRandomDigits[fNDigits].fTime = dtime;
378 fDPt[fNDigits] = &fRandomDigits[fNDigits];
384 ///////////////////////////////////////// Digit IO
385 Bool_t AliHLTTPCMemHandler::Memory2BinaryFile(UInt_t nrow,AliHLTTPCDigitRowData *data)
387 //Write data to the outputfile as is. No run-length encoding is done.
390 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","File")
391 <<"No Output File"<<ENDLOG;
395 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","Memory")
396 <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
400 AliHLTTPCDigitRowData *rowPt = data;
402 for(UInt_t i=0;i<nrow;i++){
403 Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit
404 + sizeof(AliHLTTPCDigitRowData);
406 fwrite(rowPt,size,1,fOutBinary);
407 Byte_t *bytePt =(Byte_t *) rowPt;
409 rowPt = (AliHLTTPCDigitRowData *) bytePt;
411 LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Memory2Binary","Memory")
412 <<AliHLTTPCLog::kDec<<"Wrote "<<outsize<<" Bytes to Memory ("
413 <<nrow<<" Rows)"<<ENDLOG;
417 void AliHLTTPCMemHandler::AddData(AliHLTTPCDigitData *data,UInt_t & ndata,
418 UInt_t /*row*/,UShort_t pad,UShort_t time,UShort_t charge) const
421 data[ndata].fPad = pad;
422 data[ndata].fTime = time;
423 data[ndata].fCharge = charge;
427 void AliHLTTPCMemHandler::AddRandom(AliHLTTPCDigitData *data, UInt_t & ndata)
429 //add some random data
430 data[ndata].fPad = fDPt[fNUsed]->fPad;
431 data[ndata].fTime = fDPt[fNUsed]->fTime;
432 data[ndata].fCharge = fDPt[fNUsed]->fCharge;
437 void AliHLTTPCMemHandler::MergeDataRandom(AliHLTTPCDigitData *data, UInt_t & ndata,
438 UInt_t row, UShort_t pad, UShort_t time, UShort_t charge)
441 data[ndata].fPad = pad;
442 data[ndata].fTime = time;
443 data[ndata].fCharge = charge;
444 while(ComparePoints(row,pad,time)==0){
445 Int_t ch = data[ndata].fCharge + fDPt[fNUsed]->fCharge;
446 if(charge>=AliHLTTPCTransform::GetADCSat()) ch = AliHLTTPCTransform::GetADCSat();
447 data[ndata].fCharge = ch;
453 void AliHLTTPCMemHandler::AddDataRandom(AliHLTTPCDigitData *data, UInt_t & ndata,
454 UInt_t row, UShort_t pad, UShort_t time, UShort_t charge)
458 while((action=ComparePoints(row,pad,time))==1){
459 AddRandom(data,ndata);
462 MergeDataRandom(data,ndata,row,pad,time,charge);
465 AddData(data,ndata,row,pad,time,charge);
469 void AliHLTTPCMemHandler::Write(UInt_t *comp, UInt_t & index,
470 UInt_t & subindex, UShort_t value) const
472 //write compressed data
473 UInt_t shift[3] = {0,10,20};
474 if(subindex==0) comp[index] =0; //clean up memory
475 comp[index] |= (value&0x03ff)<<shift[subindex];
483 UShort_t AliHLTTPCMemHandler::Read(UInt_t *comp, UInt_t & index, UInt_t & subindex) const
485 //read compressed data
486 UInt_t shift[3] = {0,10,20};
487 UShort_t value = (comp[index]>>shift[subindex])&0x03ff;
497 UShort_t AliHLTTPCMemHandler::Test(const UInt_t *comp,
498 UInt_t index, UInt_t subindex) const
501 UInt_t shift[3] = {0,10,20};
502 return (comp[index]>>shift[subindex])&0x03ff;
505 Int_t AliHLTTPCMemHandler::Memory2CompMemory(UInt_t nrow,
506 AliHLTTPCDigitRowData *data,UInt_t *comp)
508 //Performs run-length encoding on data stored in memory pointed to by data.
509 //The compressed data is written to comp.
511 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2CompMemory","Memory")
512 <<"Pointer to compressed data = 0x0 "<<ENDLOG;
516 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2CompMemory","Memory")
517 <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
520 AliHLTTPCDigitRowData *rowPt = data;
524 for(UInt_t i=0;i<nrow;i++){
525 UShort_t value = rowPt->fRow;
526 Write(comp,index,subindex,value);
530 for(Int_t d=0;d<200;d++) ddd[d]=0;
531 for(UInt_t dig=0;dig<rowPt->fNDigit;dig++){
532 if(rowPt->fDigitData[dig].fPad <200){
533 ddd[rowPt->fDigitData[dig].fPad]++;
536 for(Int_t d=0;d<200;d++){
542 Write(comp,index,subindex,npad);
544 for(UShort_t pad=0;pad <= maxpad;pad++){
545 if(digit>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad != pad)
547 Write(comp,index,subindex,pad);
548 // write zero if time != 0
549 if(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
550 if(rowPt->fDigitData[digit].fTime>0){
551 Write(comp,index,subindex,0);
552 Write(comp,index,subindex,rowPt->fDigitData[digit].fTime);
555 while(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
556 UShort_t charge = rowPt->fDigitData[digit].fCharge;
560 Write(comp,index,subindex,charge);
561 if(digit+1<rowPt->fNDigit&&rowPt->fDigitData[digit+1].fPad == pad){
562 if(rowPt->fDigitData[digit].fTime +1 !=
563 rowPt->fDigitData[digit+1].fTime){
564 Write(comp,index,subindex,0);
565 UShort_t nzero = rowPt->fDigitData[digit+1].fTime -
566 (rowPt->fDigitData[digit].fTime +1);
567 Write(comp,index,subindex,nzero);
572 Write(comp,index,subindex,0);
573 Write(comp,index,subindex,0);
576 Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit+
577 sizeof(AliHLTTPCDigitRowData);
578 Byte_t *bytePt =(Byte_t *) rowPt;
580 rowPt = (AliHLTTPCDigitRowData *) bytePt;
583 Write(comp,index,subindex,0);
584 return index * sizeof(UInt_t);
587 UInt_t AliHLTTPCMemHandler::GetCompMemorySize(UInt_t nrow,AliHLTTPCDigitRowData *data) const
589 //Return the size of RLE data, after compressing data.
592 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetCompMemorySize","Memory")
593 <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
596 AliHLTTPCDigitRowData *rowPt = data;
599 for(UInt_t i=0;i<nrow;i++){
604 for(Int_t d=0;d<200;d++) ddd[d]=0;
605 for(UInt_t dig=0;dig<rowPt->fNDigit;dig++){
606 if(rowPt->fDigitData[dig].fPad <200){
607 ddd[rowPt->fDigitData[dig].fPad]++;
610 for(Int_t d=0;d<200;d++){
618 for(UShort_t pad=0;pad <= maxpad;pad++){
619 if(digit>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad != pad)
622 // write zero if time != 0
623 if(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
624 if(rowPt->fDigitData[digit].fTime>0){
629 while(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
631 if(digit+1<rowPt->fNDigit&&rowPt->fDigitData[digit+1].fPad == pad){
632 if(rowPt->fDigitData[digit].fTime +1 !=
633 rowPt->fDigitData[digit+1].fTime){
644 Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit+
645 sizeof(AliHLTTPCDigitRowData);
646 Byte_t *bytePt =(Byte_t *) rowPt;
648 rowPt = (AliHLTTPCDigitRowData *) bytePt;
652 return (index/3) * sizeof(UInt_t);
655 UInt_t AliHLTTPCMemHandler::GetMemorySize(UInt_t nrow,UInt_t *comp) const
659 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetMemorySize","Memory")
660 <<"Pointer to compressed data = 0x0 "<<ENDLOG;
668 for(UInt_t i=0;i<nrow;i++){
670 Read(comp,index,subindex);
671 UShort_t npad = Read(comp,index,subindex);
672 for(UShort_t p=0;p<npad;p++){
673 Read(comp,index,subindex);
674 if(Test(comp,index,subindex)==0){
675 Read(comp,index,subindex);
676 if(Read(comp,index,subindex)== 0) continue;
679 while(Read(comp,index,subindex)!=0) ndigit++;
680 if(Read(comp,index,subindex)==0) break;
683 Int_t size = sizeof(AliHLTTPCDigitData) * ndigit+
684 sizeof(AliHLTTPCDigitRowData);
691 UInt_t AliHLTTPCMemHandler::GetNRow(UInt_t *comp,UInt_t size)
695 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetNRow","Memory")
696 <<"Pointer to compressed data = 0x0 "<<ENDLOG;
703 while(index<size-1){ //don't start with last word
706 Read(comp,index,subindex);
707 UShort_t npad = Read(comp,index,subindex);
708 for(UShort_t p=0;p<npad;p++){
709 Read(comp,index,subindex);
710 if(Test(comp,index,subindex)==0){
711 Read(comp,index,subindex);
712 if(Read(comp,index,subindex)==0)continue;
715 while(Read(comp,index,subindex)!=0) ndigit++;
716 if(Read(comp,index,subindex)==0) break;
720 if(index==size-1){ //last word
722 if(Read(comp,index,subindex)!=0) nrow++;
728 Bool_t AliHLTTPCMemHandler::CompMemory2CompBinary(UInt_t nrow,UInt_t *comp,
731 //Write the RLE data in comp to the output file.
734 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2CompBinary","File")
735 <<"No Output File"<<ENDLOG;
739 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2CompBinary","Memory")
740 <<"Pointer to compressed data = 0x0 "<<ENDLOG;
744 size=GetMemorySize(nrow,comp);
746 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2CompBinary","Memory")
747 <<"Memory size = 0 "<<ENDLOG;
750 UInt_t length = size/sizeof(UInt_t);
751 fwrite(&length,sizeof(UInt_t),1,fOutBinary);
752 fwrite(comp,size,1,fOutBinary);
757 Bool_t AliHLTTPCMemHandler::Memory2CompBinary(UInt_t nrow,AliHLTTPCDigitRowData *data)
759 //Perform RLE on the data, and write it to the output file.
761 AliHLTTPCMemHandler * handler = new AliHLTTPCMemHandler();
762 UInt_t size = GetCompMemorySize(nrow,data);
763 UInt_t *comp =(UInt_t *)handler->Allocate(size);
764 Memory2CompMemory(nrow,data,comp);
765 CompMemory2CompBinary(nrow,comp,size);
772 ///////////////////////////////////////// Point IO
773 Bool_t AliHLTTPCMemHandler::Memory2Binary(UInt_t npoint,AliHLTTPCSpacePointData *data)
775 //Writing spacepoints stored in data to the outputfile.
777 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","File")
778 <<"No Output File"<<ENDLOG;
782 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","Memory")
783 <<"Pointer to AliHLTTPCSpacePointData = 0x0 "<<ENDLOG;
786 UInt_t size = npoint*sizeof(AliHLTTPCSpacePointData);
787 fwrite(data,size,1,fOutBinary);
792 Bool_t AliHLTTPCMemHandler::Transform(UInt_t npoint,AliHLTTPCSpacePointData *data,Int_t slice)
794 //Transform the space points in data, to global coordinates in slice.
796 LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Transform","Memory")
797 <<"Pointer to AliHLTTPCSpacePointData = 0x0 "<<ENDLOG;
801 for(UInt_t i=0;i<npoint;i++){
806 AliHLTTPCTransform::Local2Global(xyz,slice);
814 void AliHLTTPCMemHandler::UpdateRowPointer(AliHLTTPCDigitRowData *&tempPt)
816 //Update the data pointer to the next padrow in memory.
818 Byte_t *tmp = (Byte_t*)tempPt;
819 Int_t size = sizeof(AliHLTTPCDigitRowData) + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
821 tempPt = (AliHLTTPCDigitRowData*)tmp;
824 Int_t AliHLTTPCMemHandler::ComparePoints(UInt_t /*row*/,UShort_t pad,UShort_t time) const
827 if(fNUsed>=fNDigits) return -2;
829 if(pad==fDPt[fNUsed]->fPad&&time==fDPt[fNUsed]->fTime) return 0;
831 if(pad<fDPt[fNUsed]->fPad) return -1;
832 if(pad==fDPt[fNUsed]->fPad&&time<fDPt[fNUsed]->fTime) return -1;
837 Int_t AliHLTTPCMemHandler::CompareDigits(const AliHLTTPCRandomDigitData *a,const AliHLTTPCRandomDigitData *b) const
840 if(a->fPad==b->fPad && a->fTime == b->fTime) return 0;
842 if(a->fPad<b->fPad) return -1;
843 if(a->fPad==b->fPad && a->fTime<b->fTime) return -1;