// $Id$ //************************************************************************** //* This file is property of and copyright by the ALICE HLT Project * //* ALICE Experiment at CERN, All rights reserved. * //* * //* Primary Authors: U. Frankenfeld, A. Vestbo, C. Loizides * //* Matthias Richter * //* for The ALICE HLT Project. * //* * //* Permission to use, copy, modify and distribute this software and its * //* documentation strictly for non-commercial purposes is hereby granted * //* without fee, provided that the above copyright notice appears in all * //* copies and that both the copyright notice and this permission notice * //* appear in the supporting documentation. The authors make no claims * //* about the suitability of this software for any purpose. It is * //* provided "as is" without express or implied warranty. * //************************************************************************** // @file AliHLTTPCMemHandler.cxx // @author U. Frankenfeld, A. Vestbo, C. Loizides, maintained by // Matthias Richter // @date // @brief input interface base class for the TPC tracking code before // migration to the HLT component framework #include #include "AliHLTTPCDigitData.h" #include "AliHLTTPCLogging.h" #include "AliHLTTPCTransform.h" #include "AliHLTTPCSpacePointData.h" #include "AliHLTTPCMemHandler.h" #include "TMath.h" using namespace std; ClassImp(AliHLTTPCMemHandler) AliHLTTPCMemHandler::AliHLTTPCMemHandler() : fRowMin(0), fRowMax(0), fSlice(0), fPatch(0), fInBinary(NULL), fOutBinary(NULL), fPt(NULL), fSize(0), fIsRandom(kFALSE), fNRandom(0), fNGenerate(0), fNUsed(0), fNDigits(0), fDPt(NULL), fRandomDigits(NULL), fDummy(0) { //Constructor Init(0,0); ResetROI(); } AliHLTTPCMemHandler::~AliHLTTPCMemHandler() { //Destructor if(fPt) delete[] fPt; if(fRandomDigits) delete [] fRandomDigits; if(fDPt) delete [] fDPt; } void AliHLTTPCMemHandler::Init(Int_t s,Int_t p, Int_t *r) { //init handler assert(sfgkNSlice) { fSlice=0; fPatch=0; fRowMin=0; fRowMax=0; if (r) *r=0; LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Init","sector coordinates") <<"Invalid slice no " << s < 1) { i = first; j = last; for (;;) { while (++i < last && CompareDigits(a[i], a[first]) < 0) ; while (--j > first && CompareDigits(a[j], a[first]) > 0) ; if (i >= j) break; tmp = a[i]; a[i] = a[j]; a[j] = tmp; } if (j == first) { ++first; continue; } tmp = a[first]; a[first] = a[j]; a[j] = tmp; if (j - first < last - (j + 1)) { QSort(a, first, j); first = j + 1; // QSort(j + 1, last); } else { QSort(a, j + 1, last); last = j; // QSort(first, j); } } } UInt_t AliHLTTPCMemHandler::GetRandomSize() const { //get random size Int_t nrandom = 0; for(Int_t r=fRowMin;r<=fRowMax;r++){ Int_t npad=AliHLTTPCTransform::GetNPads(r); nrandom += Int_t (fNGenerate * ((Double_t) npad/141.)); } return 9 * nrandom * sizeof(AliHLTTPCDigitData); } void AliHLTTPCMemHandler::DigitizePoint(Int_t row, Int_t pad, Int_t time,Int_t charge) { //Making one single random cluster. for(Int_t j=-1;j<2;j++){ for(Int_t k=-1;k<2;k++){ Int_t dcharge = charge; if(j) dcharge /=2; if(k) dcharge /=2; if(dcharge<10) continue; Int_t dpad = j + pad; Int_t dtime = k + time; if(dpad<0||dpad>=AliHLTTPCTransform::GetNPads(row)) continue; if(dtime<0||dtime>=AliHLTTPCTransform::GetNTimeBins()) continue; fRandomDigits[fNDigits].fCharge = dcharge; fRandomDigits[fNDigits].fRow = row; fRandomDigits[fNDigits].fPad = dpad; fRandomDigits[fNDigits].fTime = dtime; fDPt[fNDigits] = &fRandomDigits[fNDigits]; fNDigits++; } } } ///////////////////////////////////////// Digit IO Bool_t AliHLTTPCMemHandler::Memory2BinaryFile(UInt_t nrow,AliHLTTPCDigitRowData *data) { //Write data to the outputfile as is. No run-length encoding is done. if(!fOutBinary){ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","File") <<"No Output File"<fNDigit + sizeof(AliHLTTPCDigitRowData); outsize += size; fwrite(rowPt,size,1,fOutBinary); Byte_t *bytePt =(Byte_t *) rowPt; bytePt += size; rowPt = (AliHLTTPCDigitRowData *) bytePt; } LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Memory2Binary","Memory") <fPad; data[ndata].fTime = fDPt[fNUsed]->fTime; data[ndata].fCharge = fDPt[fNUsed]->fCharge; ndata++; fNUsed++; } void AliHLTTPCMemHandler::MergeDataRandom(AliHLTTPCDigitData *data, UInt_t & ndata, UInt_t row, UShort_t pad, UShort_t time, UShort_t charge) { //merge random data data[ndata].fPad = pad; data[ndata].fTime = time; data[ndata].fCharge = charge; while(ComparePoints(row,pad,time)==0){ Int_t ch = data[ndata].fCharge + fDPt[fNUsed]->fCharge; if(charge>=AliHLTTPCTransform::GetADCSat()) ch = AliHLTTPCTransform::GetADCSat(); data[ndata].fCharge = ch; fNUsed++; } ndata++; } void AliHLTTPCMemHandler::AddDataRandom(AliHLTTPCDigitData *data, UInt_t & ndata, UInt_t row, UShort_t pad, UShort_t time, UShort_t charge) { //add data random Int_t action; while((action=ComparePoints(row,pad,time))==1){ AddRandom(data,ndata); } if(action==0){ MergeDataRandom(data,ndata,row,pad,time,charge); } if(action<0){ AddData(data,ndata,row,pad,time,charge); } } void AliHLTTPCMemHandler::Write(UInt_t *comp, UInt_t & index, UInt_t & subindex, UShort_t value) const { //write compressed data UInt_t shift[3] = {0,10,20}; if(subindex==0) comp[index] =0; //clean up memory comp[index] |= (value&0x03ff)<>shift[subindex])&0x03ff; if(subindex == 2){ subindex = 0; index++; } else subindex++; return value; } UShort_t AliHLTTPCMemHandler::Test(const UInt_t *comp, UInt_t index, UInt_t subindex) const { //supi dupi test UInt_t shift[3] = {0,10,20}; return (comp[index]>>shift[subindex])&0x03ff; } Int_t AliHLTTPCMemHandler::Memory2CompMemory(UInt_t nrow, AliHLTTPCDigitRowData *data,UInt_t *comp) { //Performs run-length encoding on data stored in memory pointed to by data. //The compressed data is written to comp. if(!comp){ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2CompMemory","Memory") <<"Pointer to compressed data = 0x0 "<fRow; Write(comp,index,subindex,value); UShort_t maxpad=0; UShort_t npad=0; Int_t ddd[1000]; for(Int_t d=0;d<200;d++) ddd[d]=0; for(UInt_t dig=0;digfNDigit;dig++){ if(rowPt->fDigitData[dig].fPad <200){ ddd[rowPt->fDigitData[dig].fPad]++; } } for(Int_t d=0;d<200;d++){ if(ddd[d]){ npad++; maxpad =d; } } Write(comp,index,subindex,npad); UInt_t digit=0; for(UShort_t pad=0;pad <= maxpad;pad++){ if(digit>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad != pad) continue; Write(comp,index,subindex,pad); // write zero if time != 0 if(digitfNDigit && rowPt->fDigitData[digit].fPad == pad){ if(rowPt->fDigitData[digit].fTime>0){ Write(comp,index,subindex,0); Write(comp,index,subindex,rowPt->fDigitData[digit].fTime); } } while(digitfNDigit && rowPt->fDigitData[digit].fPad == pad){ UShort_t charge = rowPt->fDigitData[digit].fCharge; if(charge>=1023){ charge=1023; } Write(comp,index,subindex,charge); if(digit+1fNDigit&&rowPt->fDigitData[digit+1].fPad == pad){ if(rowPt->fDigitData[digit].fTime +1 != rowPt->fDigitData[digit+1].fTime){ Write(comp,index,subindex,0); UShort_t nzero = rowPt->fDigitData[digit+1].fTime - (rowPt->fDigitData[digit].fTime +1); Write(comp,index,subindex,nzero); } } digit++; } Write(comp,index,subindex,0); Write(comp,index,subindex,0); } Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit+ sizeof(AliHLTTPCDigitRowData); Byte_t *bytePt =(Byte_t *) rowPt; bytePt += size; rowPt = (AliHLTTPCDigitRowData *) bytePt; } while(subindex) Write(comp,index,subindex,0); return index * sizeof(UInt_t); } UInt_t AliHLTTPCMemHandler::GetCompMemorySize(UInt_t nrow,AliHLTTPCDigitRowData *data) const { //Return the size of RLE data, after compressing data. if(!data){ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetCompMemorySize","Memory") <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<fNDigit;dig++){ if(rowPt->fDigitData[dig].fPad <200){ ddd[rowPt->fDigitData[dig].fPad]++; } } for(Int_t d=0;d<200;d++){ if(ddd[d]){ npad++; maxpad =d; } } index++; UInt_t digit=0; for(UShort_t pad=0;pad <= maxpad;pad++){ if(digit>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad != pad) continue; index++; // write zero if time != 0 if(digitfNDigit && rowPt->fDigitData[digit].fPad == pad){ if(rowPt->fDigitData[digit].fTime>0){ index++; index++; } } while(digitfNDigit && rowPt->fDigitData[digit].fPad == pad){ index++; if(digit+1fNDigit&&rowPt->fDigitData[digit+1].fPad == pad){ if(rowPt->fDigitData[digit].fTime +1 != rowPt->fDigitData[digit+1].fTime){ index++; index++; } } digit++; } index++; index++; } Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit+ sizeof(AliHLTTPCDigitRowData); Byte_t *bytePt =(Byte_t *) rowPt; bytePt += size; rowPt = (AliHLTTPCDigitRowData *) bytePt; } while(index%3) index++; return (index/3) * sizeof(UInt_t); } UInt_t AliHLTTPCMemHandler::GetMemorySize(UInt_t nrow,UInt_t *comp) const { //get memory size if(!comp){ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetMemorySize","Memory") <<"Pointer to compressed data = 0x0 "<Allocate(size); Memory2CompMemory(nrow,data,comp); CompMemory2CompBinary(nrow,comp,size); handler->Free(); delete handler; return out; } ///////////////////////////////////////// Point IO Bool_t AliHLTTPCMemHandler::Memory2Binary(UInt_t npoint,AliHLTTPCSpacePointData *data) { //Writing spacepoints stored in data to the outputfile. if(!fOutBinary){ LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","File") <<"No Output File"<fNDigit*sizeof(AliHLTTPCDigitData); tmp += size; tempPt = (AliHLTTPCDigitRowData*)tmp; } Int_t AliHLTTPCMemHandler::ComparePoints(UInt_t /*row*/,UShort_t pad,UShort_t time) const { //compare two points if(fNUsed>=fNDigits) return -2; if(pad==fDPt[fNUsed]->fPad&&time==fDPt[fNUsed]->fTime) return 0; if(padfPad) return -1; if(pad==fDPt[fNUsed]->fPad&&timefTime) return -1; return 1; } Int_t AliHLTTPCMemHandler::CompareDigits(const AliHLTTPCRandomDigitData *a,const AliHLTTPCRandomDigitData *b) const { //compare two digits if(a->fPad==b->fPad && a->fTime == b->fTime) return 0; if(a->fPadfPad) return -1; if(a->fPad==b->fPad && a->fTimefTime) return -1; return 1; }