3 // Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
4 //*-- Copyright © ASV
13 #include "AliL3Compress.h"
14 #include "AliL3TrackArray.h"
15 #include "AliL3ModelTrack.h"
16 #include "AliL3Transform.h"
17 #include "AliL3MemHandler.h"
20 //_____________________________________________________________
24 // Class for compressing and uncompressing data.
26 ClassImp(AliL3Compress)
28 AliL3Compress::AliL3Compress()
31 SetBitNumbers(7,7,10,4);
38 AliL3Compress::AliL3Compress(Int_t slice,Int_t patch,Int_t pad,Int_t time,Int_t charge,Int_t shape)
42 SetBitNumbers(pad,time,charge,shape);
48 AliL3Compress::~AliL3Compress()
58 void AliL3Compress::SetBitNumbers(Int_t pad,Int_t time,Int_t charge,Int_t shape)
62 fNumChargeBits=charge;
66 void AliL3Compress::WriteFile(AliL3TrackArray *tracks,Char_t *filename)
68 FILE *file = fopen(filename,"w");
69 Short_t ntracks = tracks->GetNTracks();
70 //cout<<"Writing "<<ntracks<<" tracks to file"<<endl;
73 AliL3ClusterModel *clusters=0;
74 AliL3TrackModel *model=0;
75 for(Int_t i=0; i<ntracks; i++)
77 AliL3ModelTrack *track = (AliL3ModelTrack*)tracks->GetCheckedTrack(i);
81 model = track->GetModel();
82 if(model->fNClusters==0) continue;
83 clusters = track->GetClusters();
84 //cout<<"Writing "<<(int)model->fNClusters<<" clusters"<<endl;
85 if(fwrite(model,sizeof(AliL3TrackModel),1,file)!=1) break;
86 //cout<<"Writing "<<(int)model->fNClusters<<" clusters to file"<<endl;
87 if(fwrite(clusters,model->fNClusters*sizeof(AliL3ClusterModel),1,file)!=1) break;
92 cout<<"Wrote "<<count<<" tracks "<<endl;
96 void AliL3Compress::ReadFile(Char_t *filename)
98 FILE *file = fopen(filename,"r");
101 cerr<<"Cannot open file "<<filename<<endl;
107 fTracks = new AliL3TrackArray("AliL3ModelTrack");
109 cout<<"Reading file "<<filename<<endl;
112 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->NextTrack();
113 track->Init(fSlice,fPatch);
114 AliL3TrackModel *model = track->GetModel();
115 AliL3ClusterModel *clusters = track->GetClusters();
116 //cout<<"Reading model "<<(int)model<<endl;
117 if(fread(model,sizeof(AliL3TrackModel),1,file)!=1) break;
118 //cout<<"Reading clusters "<<(int)clusters<<endl;
119 if(fread(clusters,(model->fNClusters)*sizeof(AliL3ClusterModel),1,file)!=1) break;
120 //cout<<"Filling track"<<endl;
125 fTracks->RemoveLast();
126 cout<<"Read "<<fTracks->GetNTracks()<<" tracks from file"<<endl;
130 void AliL3Compress::CompressFile(Char_t *infile,Char_t *outfile)
133 BIT_FILE *output = OpenOutputBitFile(outfile);
134 FILE *input = fopen(infile,"r");
136 AliL3TrackModel track;
137 AliL3ClusterModel cluster;
141 Int_t timeo,pado,chargeo,shapeo;
142 timeo=pado=chargeo=shapeo=0;
145 if(fread(&track,sizeof(AliL3TrackModel),1,input)!=1) break;
147 if(output->mask != 0x80) //Write the current byte to file.
149 if(putc(output->rack,output->file )!=output->rack)
150 cerr<<"AliL3Compress::ComressFile : Error writing to bitfile"<<endl;
155 //Write track parameters:
156 fwrite(&track,sizeof(AliL3TrackModel),1,output->file);
157 for(Int_t i=0; i<track.fNClusters; i++)
159 if(fread(&cluster,sizeof(AliL3ClusterModel),1,input)!=1) break;
162 temp = (Int_t)cluster.fPresent;
163 OutputBit(output,temp);
166 //Write time information:
167 temp = (Int_t)cluster.fDTime;
172 power = 1<<fNumTimeBits;
178 OutputBits(output,abs(temp),fNumTimeBits);
180 //Write pad information:
181 temp = (Int_t)cluster.fDPad;
186 power = 1<<fNumPadBits;
192 OutputBits(output,abs(temp),fNumPadBits);
194 //Write charge information:
195 temp = (Int_t)cluster.fDCharge;
200 power = 1<<fNumChargeBits;
206 OutputBits(output,abs(temp),fNumChargeBits);
208 //Write shape information:
209 temp = (Int_t)cluster.fDSigmaY2;
210 power = 1<<fNumShapeBits;
211 if(abs(temp) >= power)
216 OutputBits(output,abs(temp),fNumShapeBits);
218 temp = (Int_t)cluster.fDSigmaZ2;
219 if(abs(temp) >= power)
224 OutputBits(output,abs(temp),fNumShapeBits);
229 CloseOutputBitFile(output);
231 cout<<endl<<"There was following number of overflows: "<<endl
233 <<"Time "<<timeo<<endl
234 <<"Charge "<<chargeo<<endl
235 <<"Shape "<<shapeo<<endl;
238 void AliL3Compress::ExpandFile(Char_t *infile,Char_t *outfile)
240 BIT_FILE *input = OpenInputBitFile(infile);
241 FILE *output = fopen(outfile,"w");
243 AliL3TrackModel trackmodel;
244 AliL3ClusterModel *clusters=0;
247 clusters = new AliL3ClusterModel[(NumRows[fPatch])];
248 while(!feof(input->file))
250 input->mask=0x80;//make sure we read a new byte from file.
252 //Read and write track:
253 if(fread(&trackmodel,sizeof(AliL3TrackModel),1,input->file)!=1) break;
254 fwrite(&trackmodel,sizeof(AliL3TrackModel),1,output);
256 for(Int_t i=0; i<NumRows[fPatch]; i++)
261 temp = InputBit(input);
264 clusters[i].fPresent=kFALSE;
267 clusters[i].fPresent=kTRUE;
269 //Read time information:
270 sign=InputBit(input);
271 temp = InputBits(input,fNumTimeBits);
274 clusters[i].fDTime = temp;
276 //Read pad information:
277 sign=InputBit(input);
278 temp = InputBits(input,fNumPadBits);
281 clusters[i].fDPad = temp;
283 //Read charge information:
284 sign = InputBit(input);
285 temp=InputBits(input,fNumChargeBits);
288 clusters[i].fDCharge = temp;
290 //Read shape information:
291 temp = InputBits(input,fNumShapeBits);
292 clusters[i].fDSigmaY2 = temp;
294 temp = InputBits(input,fNumShapeBits);
295 clusters[i].fDSigmaZ2 = temp;
300 fwrite(clusters,(trackmodel.fNClusters)*sizeof(AliL3ClusterModel),1,output);
306 CloseInputBitFile(input);
309 void AliL3Compress::CreateDigitArray(Int_t maxnumber)
313 fMaxDigits=maxnumber;
314 if(fDigits) delete [] fDigits;
315 fDigits = new AliL3RandomDigitData[maxnumber];
316 if(fDPt) delete [] fDPt;
317 fDPt = new AliL3RandomDigitData*[maxnumber];
320 void AliL3Compress::RestoreData(Char_t *uncompfile)
323 //Read the uncompressed file:
324 ReadFile(uncompfile);
326 CreateDigitArray(100000);
328 Float_t pad,time,sigmaY2,sigmaZ2;
330 for(Int_t j=NRows[fPatch][0]; j<=NRows[fPatch][1]; j++)
332 for(Int_t i=0; i<fTracks->GetNTracks(); i++)
334 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
336 if(!track->GetPad(j,pad) ||
337 !track->GetTime(j,time) ||
338 !track->GetClusterCharge(j,charge) ||
339 !track->GetXYWidth(j,sigmaY2) ||
340 !track->GetZWidth(j,sigmaZ2))
343 CreateDigits(j,pad,time,charge,sigmaY2,sigmaZ2);
347 QSort(fDPt,0,fNDigits);
350 void AliL3Compress::PrintDigits()
352 Int_t pad,time,charge,row;
353 for(Int_t i=0; i<fNDigits; i++)
357 time = fDPt[i]->fTime;
358 charge = fDPt[i]->fCharge;
359 if(i>0 && row != fDPt[i-1]->fRow)
360 cout<<"---Padrow "<<row<<"---"<<endl;
361 cout<<"Pad "<<pad<<" time "<<time<<" charge "<<charge<<endl;
365 void AliL3Compress::WriteRestoredData(Char_t *remainfile,Char_t *restoredfile)
367 //Get the remaining raw data array:
368 AliL3MemHandler *mem = new AliL3MemHandler();
369 mem->SetBinaryInput(remainfile);
371 AliL3DigitRowData *origRow = mem->CompBinary2Memory(numdigits);
372 mem->CloseBinaryInput();
374 //Allocate memory for the merged data:
375 UInt_t size = mem->GetAllocatedSize() + fNDigits*sizeof(AliL3DigitData);
376 Byte_t *data = new Byte_t[size];
378 AliL3DigitRowData *tempRow = (AliL3DigitRowData*)data;
380 Int_t ndigits,action,charge;
382 for(Int_t i=NRows[fPatch][0]; i<=NRows[fPatch][1]; i++)
386 AliL3DigitData *origDig = origRow->fDigitData;
387 AliL3DigitData *tempDig = tempRow->fDigitData;
391 for(UInt_t j=0; j<origRow->fNDigit; j++)
393 pad = origDig[j].fPad;
394 time = origDig[j].fTime;
395 charge = origDig[j].fCharge;
396 while((action=ComparePoints(i,pad,time)) == 1)
398 tempDig[ndigits].fPad = fDPt[fNUsed]->fPad;
399 tempDig[ndigits].fTime = fDPt[fNUsed]->fTime;
400 tempDig[ndigits].fCharge = fDPt[fNUsed]->fCharge;
406 tempDig[ndigits].fPad = pad;
407 tempDig[ndigits].fTime = time;
408 tempDig[ndigits].fCharge = charge;
412 if(fNUsed >= fNDigits) break;
413 if(fDPt[fNUsed]->fRow != i) //we are on a new row
415 tempDig[ndigits].fPad = fDPt[fNUsed]->fPad;
416 tempDig[ndigits].fTime = fDPt[fNUsed]->fTime;
417 tempDig[ndigits].fCharge = fDPt[fNUsed]->fCharge;
421 tempRow->fNDigit = ndigits;
422 Int_t size = sizeof(AliL3DigitData)*tempRow->fNDigit + sizeof(AliL3DigitRowData);
423 Byte_t *byte_pt = (Byte_t*)tempRow;
425 tempRow = (AliL3DigitRowData*)byte_pt;
426 mem->UpdateRowPointer(origRow);
430 mem->SetBinaryOutput(restoredfile);
431 mem->Memory2CompBinary((UInt_t)NumRows[fPatch],(AliL3DigitRowData*)data);
432 mem->CloseBinaryOutput();
438 void AliL3Compress::CreateDigits(Int_t row,Float_t pad,Float_t time,Int_t charge,Float_t sigmaY2,Float_t sigmaZ2)
440 //Create raw data out of the cluster.
442 AliL3Transform *tr = new AliL3Transform();
443 TRandom *random = new TRandom();
446 TH1F *hist1 = new TH1F("hist1","",tr->GetNPads(row),0,tr->GetNPads(row)-1);
447 TH1F *hist2 = new TH1F("hist2","",tr->GetNTimeBins(),0,tr->GetNTimeBins()-1);
448 TH2F *hist3 = new TH2F("hist3","",tr->GetNPads(row),0,tr->GetNPads(row)-1,tr->GetNTimeBins(),0,tr->GetNTimeBins()-1);
450 //Convert back the sigmas:
453 padw = tr->GetPadPitchWidthLow();
455 padw = tr->GetPadPitchWidthUp();
456 timew = tr->GetZWidth();
459 sigmaY2 = sigmaY2/2.07;
460 sigmaY2 = sigmaY2/0.108;
461 sigmaY2 = sigmaY2/(padw*padw);
462 sigmaY2 = sigmaY2 - 1./12;
465 sigmaZ2 = sigmaZ2/1.77;
466 sigmaZ2 = sigmaZ2/0.169;
467 sigmaZ2 = sigmaZ2/(timew*timew);
468 sigmaZ2 = sigmaZ2 - 1./12;
470 if(sigmaY2 <= 0 || sigmaZ2 <= 0)
472 cerr<<"AliL3Compress::CreateDigits() : Wrong sigmas : "<<sigmaY2<<" "<<sigmaZ2<<endl;
476 //Create the distributions in pad and time:
477 for(Int_t i=0; i<entries; i++)
479 hist1->Fill(random->Gaus(pad,sqrt(sigmaY2)));
480 hist2->Fill(random->Gaus(time,sqrt(sigmaZ2)));
483 //Create the cluster:
485 Double_t content1,content2,dpad,dtime;
486 for(Int_t i=0; i<hist1->GetEntries(); i++)
488 bin1 = hist1->GetBin(i);
489 content1 = hist1->GetBinContent(bin1);
490 if((Int_t)content1==0) continue;
491 content1 = charge*content1/entries;
492 dpad = hist1->GetBinCenter(bin1);
493 for(Int_t j=0; j<hist2->GetEntries(); j++)
495 bin2 = hist2->GetBin(j);
496 content2 = hist2->GetBinContent(bin2);
497 if((Int_t)content2==0) continue;
498 content2 = content1*content2/entries;
499 dtime = hist2->GetBinCenter(bin2);
500 hist3->Fill(dpad,dtime,content2);
504 //Fill it into the digit array:
505 for(Int_t i=0; i<hist3->GetNbinsX(); i++)
507 for(Int_t j=0; j<hist3->GetNbinsY(); j++)
509 bin1 = hist3->GetBin(i,j);
510 content1 = hist3->GetBinContent(bin1);
511 if((Int_t)content1 < 3) continue;
514 if(fNDigits >= fMaxDigits)
516 cerr<<"AliL3Compress::CreateDigits() : Array index out of range : "<<fNDigits<<endl;
519 fDigits[fNDigits].fCharge=(Int_t)content1;
520 fDigits[fNDigits].fRow = row;
521 fDigits[fNDigits].fPad = (Int_t)hist3->GetXaxis()->GetBinCenter(i);
522 fDigits[fNDigits].fTime = (Int_t)hist3->GetYaxis()->GetBinCenter(j);
523 fDPt[fNDigits] = &fDigits[fNDigits];
535 void AliL3Compress::QSort(AliL3RandomDigitData **a, Int_t first, Int_t last)
538 // Sort array of AliL3RandomDigitData pointers using a quicksort algorithm.
539 // Uses CompareDigits() to compare objects.
542 static AliL3RandomDigitData *tmp;
543 static int i; // "static" to save stack space
546 while (last - first > 1) {
550 while (++i < last && CompareDigits(a[i], a[first]) < 0)
552 while (--j > first && CompareDigits(a[j], a[first]) > 0)
568 if (j - first < last - (j + 1)) {
570 first = j + 1; // QSort(j + 1, last);
572 QSort(a, j + 1, last);
573 last = j; // QSort(first, j);