3 // Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
4 //*-- Copyright © ASV
6 #include "AliL3StandardIncludes.h"
11 #include "AliL3Logging.h"
12 #include "AliL3Compress.h"
13 #include "AliL3TrackArray.h"
14 #include "AliL3ModelTrack.h"
15 #include "AliL3Transform.h"
16 #include "AliL3MemHandler.h"
18 #include "AliL3FileHandler.h"
22 //_____________________________________________________________
26 // Class for compressing and uncompressing data.
28 ClassImp(AliL3Compress)
30 AliL3Compress::AliL3Compress()
33 SetBitNumbers(0,0,0,0);
40 AliL3Compress::AliL3Compress(Int_t slice,Int_t patch,Char_t *path)
44 SetBitNumbers(0,0,0,0);
48 sprintf(fPath,"%s",path);
51 AliL3Compress::~AliL3Compress()
61 void AliL3Compress::SetBitNumbers(Int_t pad,Int_t time,Int_t charge,Int_t shape)
65 fNumChargeBits=charge;
69 void AliL3Compress::WriteFile(AliL3TrackArray *tracks)
72 sprintf(fname,"%s/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
73 FILE *file = fopen(fname,"w");
74 Short_t ntracks = tracks->GetNTracks();
75 //cout<<"Writing "<<ntracks<<" tracks to file"<<endl;
78 AliL3ClusterModel *clusters=0;
79 AliL3TrackModel *model=0;
80 for(Int_t i=0; i<ntracks; i++)
82 AliL3ModelTrack *track = (AliL3ModelTrack*)tracks->GetCheckedTrack(i);
85 //Do not save useless tracks or clusters:
86 //if(track->CheckClustersQuality(2) == 0)
90 model = track->GetModel();
91 if(model->fNClusters==0) continue;
92 clusters = track->GetClusters();
93 //cout<<"Writing "<<(int)model->fNClusters<<" clusters"<<endl;
94 if(fwrite(model,sizeof(AliL3TrackModel),1,file)!=1) break;
95 //cout<<"Writing "<<(int)model->fNClusters<<" clusters to file"<<endl;
96 if(fwrite(clusters,model->fNClusters*sizeof(AliL3ClusterModel),1,file)!=1) break;
101 cout<<"Wrote "<<count<<" tracks "<<endl;
105 void AliL3Compress::ReadFile(Char_t which)
107 //Read the trackfile.
111 sprintf(fname,"%s/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
112 else if(which == 'u')
113 sprintf(fname,"%s/tracks_u_%d_%d.raw",fPath,fSlice,fPatch);
116 cerr<<"AliL3Compress::ReadFile() : Wrong option"<<endl;
120 FILE *file = fopen(fname,"r");
123 cerr<<"Cannot open file "<<fname<<endl;
129 fTracks = new AliL3TrackArray("AliL3ModelTrack");
131 //cout<<"Reading file "<<fname<<endl;
134 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->NextTrack();
135 track->Init(fSlice,fPatch);
136 AliL3TrackModel *model = track->GetModel();
137 AliL3ClusterModel *clusters = track->GetClusters();
138 //cout<<"Reading model "<<(int)model<<endl;
139 if(fread(model,sizeof(AliL3TrackModel),1,file)!=1) break;
140 //cout<<"Reading clusters "<<(int)clusters<<endl;
141 if(fread(clusters,(model->fNClusters)*sizeof(AliL3ClusterModel),1,file)!=1) break;
142 //cout<<"Filling track"<<endl;
147 fTracks->RemoveLast();
148 //cout<<"Read "<<fTracks->GetNTracks()<<" tracks from file"<<endl;
152 void AliL3Compress::CompressFile()
156 cerr<<"AliL3Compress::CompressFile() : Bitnumbers not set"<<endl;
161 sprintf(fname,"%s/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
162 BIT_FILE *output = OpenOutputBitFile(fname);
164 sprintf(fname,"%s/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
165 FILE *input = fopen(fname,"r");
168 cerr<<"AliL3Compress::CompressFile() : Error opening file: "<<fname<<endl;
172 AliL3TrackModel track;
173 AliL3ClusterModel cluster;
177 Int_t timeo,pado,chargeo,shapeo;
178 timeo=pado=chargeo=shapeo=0;
181 if(fread(&track,sizeof(AliL3TrackModel),1,input)!=1) break;
183 if(output->mask != 0x80) //Write the current byte to file.
185 //cerr<<"\nAliL3Compress::CompressFile() : Writing overhead bits!!!"<<endl;
186 if(putc(output->rack,output->file )!=output->rack)
187 cerr<<"AliL3Compress::ComressFile : Error writing to bitfile"<<endl;
192 //Write track parameters:
193 fwrite(&track,sizeof(AliL3TrackModel),1,output->file);
194 for(Int_t i=0; i<track.fNClusters; i++)
196 if(fread(&cluster,sizeof(AliL3ClusterModel),1,input)!=1) break;
199 temp = (Int_t)cluster.fPresent;
200 OutputBit(output,temp);
203 //Write time information:
204 temp = (Int_t)cluster.fDTime;
209 power = 1<<(fNumTimeBits-1);
215 OutputBits(output,abs(temp),(fNumTimeBits-1));
217 //Write pad information:
218 temp = (Int_t)cluster.fDPad;
223 power = 1<<(fNumPadBits-1);
229 OutputBits(output,abs(temp),(fNumPadBits-1));
231 //Write charge information:
232 temp = (Int_t)cluster.fDCharge;
237 power = 1<<(fNumChargeBits-1);
243 OutputBits(output,abs(temp),(fNumChargeBits-1));
245 //Write shape information:
246 temp = (Int_t)cluster.fDSigmaY2;
251 power = 1<<(fNumShapeBits-1);
252 if(abs(temp) >= power)
257 OutputBits(output,abs(temp),(fNumShapeBits-1));
259 temp = (Int_t)cluster.fDSigmaZ2;
264 power = 1<<(fNumShapeBits-1);
265 if(abs(temp) >= power)
270 OutputBits(output,abs(temp),(fNumShapeBits-1));
275 CloseOutputBitFile(output);
277 cout<<endl<<"Saturations: "<<endl
279 <<"Time "<<timeo<<endl
280 <<"Charge "<<chargeo<<endl
281 <<"Shape "<<shapeo<<endl;
284 void AliL3Compress::ExpandFile()
288 cerr<<"AliL3Compress::ExpandFile() : Bitnumbers not set"<<endl;
293 sprintf(fname,"%s/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
294 BIT_FILE *input = OpenInputBitFile(fname);
296 sprintf(fname,"%s/tracks_u_%d_%d.raw",fPath,fSlice,fPatch);
297 FILE *output = fopen(fname,"w");
300 cerr<<"AliL3Compress::ExpandFile() : Error opening file: "<<fname<<endl;
304 AliL3TrackModel trackmodel;
305 AliL3ClusterModel *clusters=0;
308 clusters = new AliL3ClusterModel[(AliL3Transform::GetNRows(fPatch))];
309 while(!feof(input->file))
311 input->mask=0x80;//make sure we read a new byte from file.
313 //Read and write track:
314 if(fread(&trackmodel,sizeof(AliL3TrackModel),1,input->file)!=1) break;
315 fwrite(&trackmodel,sizeof(AliL3TrackModel),1,output);
317 for(Int_t i=0; i<AliL3Transform::GetNRows(fPatch); i++)
322 temp = InputBit(input);
325 clusters[i].fPresent=kFALSE;
328 clusters[i].fPresent=kTRUE;
330 //Read time information:
331 sign=InputBit(input);
332 temp = InputBits(input,(fNumTimeBits-1));
335 clusters[i].fDTime = temp;
337 //Read pad information:
338 sign=InputBit(input);
339 temp = InputBits(input,(fNumPadBits-1));
342 clusters[i].fDPad = temp;
344 //Read charge information:
345 sign = InputBit(input);
346 temp=InputBits(input,(fNumChargeBits-1));
349 clusters[i].fDCharge = temp;
351 //Read shape information:
352 sign = InputBit(input);
353 temp = InputBits(input,(fNumShapeBits-1));
356 clusters[i].fDSigmaY2 = temp;
358 sign = InputBit(input);
359 temp = InputBits(input,(fNumShapeBits-1));
362 clusters[i].fDSigmaZ2 = temp;
367 fwrite(clusters,(trackmodel.fNClusters)*sizeof(AliL3ClusterModel),1,output);
373 CloseInputBitFile(input);
376 void AliL3Compress::CreateDigitArray(Int_t maxnumber)
380 fMaxDigits=maxnumber;
381 if(fDigits) delete [] fDigits;
382 fDigits = new AliL3RandomDigitData[maxnumber];
383 if(fDPt) delete [] fDPt;
384 fDPt = new AliL3RandomDigitData*[maxnumber];
387 void AliL3Compress::RestoreData(Char_t which)
390 //which == u : restore compressed data
391 //which == m : restore uncompressed data
396 CreateDigitArray(10000000);
398 Float_t pad,time,sigmaY2,sigmaZ2;
400 for(Int_t j=AliL3Transform::GetFirstRow(fPatch); j<=AliL3Transform::GetLastRow(fPatch); j++)
402 cout<<"Building clusters on row "<<j<<endl;
403 for(Int_t i=0; i<fTracks->GetNTracks(); i++)
405 AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
407 if(!track->GetPad(j,pad) ||
408 !track->GetTime(j,time) ||
409 !track->GetClusterCharge(j,charge) ||
410 !track->GetXYWidth(j,sigmaY2) ||
411 !track->GetZWidth(j,sigmaZ2))
413 npads = track->GetNPads(j);
414 CreateDigits(j,npads,pad,time,charge,sigmaY2,sigmaZ2);
418 QSort(fDPt,0,fNDigits);
421 void AliL3Compress::PrintDigits(Int_t padrow)
423 Int_t pad,time,charge,row;
424 for(Int_t i=0; i<fNDigits; i++)
428 if(row != padrow) continue;
430 time = fDPt[i]->fTime;
431 charge = fDPt[i]->fCharge;
432 if(i>0 && row != fDPt[i-1]->fRow)
433 cout<<"---Padrow "<<row<<"---"<<endl;
434 cout<<"Padrow "<<row<<" Pad "<<pad<<" time "<<time<<" charge "<<charge<<endl;
438 void AliL3Compress::WriteRestoredData()
442 //Get the remaining raw data array:
443 AliL3MemHandler *mem = new AliL3MemHandler();
444 sprintf(fname,"%s/remains_%d_%d.raw",fPath,fSlice,fPatch);
445 mem->SetBinaryInput(fname);
447 AliL3DigitRowData *origRow = mem->CompBinary2Memory(numdigits);
448 mem->CloseBinaryInput();
450 //Allocate memory for the merged data:
451 UInt_t size = mem->GetAllocatedSize() + fNDigits*sizeof(AliL3DigitData);
452 cout<<"Allocating "<<size<<" bytes for merged data array "<<endl;
453 Byte_t *data = new Byte_t[size];
455 AliL3DigitRowData *tempRow = (AliL3DigitRowData*)data;
457 Int_t ndigits,action,charge;
460 UInt_t digit_counter;
462 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
466 AliL3DigitData *origDig = origRow->fDigitData;
467 AliL3DigitData *tempDig = tempRow->fDigitData;
468 if((Int_t)origRow->fRow != i)
469 cerr<<"AliL3Compress::WriteRestoredData() : Mismatching row numbering "<<(Int_t)origRow->fRow<<" "<<i<<endl;
471 //cout<<"Writing row "<<i<<" with "<<(Int_t)origRow->fNDigit<<" old digits"<<endl;
476 while(digit_counter < origRow->fNDigit)
478 pad = origDig[digit_counter].fPad;
479 time = origDig[digit_counter].fTime;
480 charge = origDig[digit_counter].fCharge;
482 while( (action=ComparePoints(i,pad,time)) == 1)
484 tempDig[ndigits].fPad = fDPt[fNUsed]->fPad;
485 tempDig[ndigits].fTime = fDPt[fNUsed]->fTime;
486 tempDig[ndigits].fCharge = fDPt[fNUsed]->fCharge;
493 tempDig[ndigits].fPad = pad;
494 tempDig[ndigits].fTime = time;
495 tempDig[ndigits].fCharge = charge;
500 if(fNUsed >= fNDigits)
502 //cerr<<"AliL3Compress::WriteRestoredData() : Array out of range : "<<fNUsed<<" "<<fNDigits<<endl;
505 if(fDPt[fNUsed]->fRow != i) //we are on a new row
507 tempDig[ndigits].fPad = fDPt[fNUsed]->fPad;
508 tempDig[ndigits].fTime = fDPt[fNUsed]->fTime;
509 tempDig[ndigits].fCharge = fDPt[fNUsed]->fCharge;
513 //cout<<"Writing "<<ndigits<<" digits on row "<<i<<endl;
518 tempRow->fNDigit = ndigits;
519 Int_t size = sizeof(AliL3DigitData)*tempRow->fNDigit + sizeof(AliL3DigitRowData);
520 Byte_t *byte_pt = (Byte_t*)tempRow;
522 tempRow = (AliL3DigitRowData*)byte_pt;
523 mem->UpdateRowPointer(origRow);
526 if(row_counter != AliL3Transform::GetNRows(fPatch))
527 cerr<<"AliL3Compress::WriteRestoredData() : Written rows: "<<row_counter<<" total rows "<<AliL3Transform::GetNRows(fPatch)<<endl;
530 sprintf(fname,"%s/restored_%d_%d.raw",fPath,fSlice,fPatch);
531 mem->SetBinaryOutput(fname);
532 mem->Memory2CompBinary((UInt_t)AliL3Transform::GetNRows(fPatch),(AliL3DigitRowData*)data);
533 mem->CloseBinaryOutput();
540 void AliL3Compress::CreateDigits(Int_t row,Int_t npads,Float_t pad,Float_t time,Int_t charge,Float_t sigmaY2,Float_t sigmaZ2)
542 //Create raw data out of the cluster.
544 if(npads == 1)//If there was only 1 pad, the xywidth is set to zero.
547 if(sigmaY2 < 0 || sigmaZ2 <= 0)
549 cerr<<"AliL3Compress::CreateDigits() : Wrong sigmas : "<<sigmaY2<<" "<<sigmaZ2;
550 cerr<<" on row "<<row<<" pad "<<pad<<" time "<<time<<endl;
554 TRandom *random = new TRandom();
557 TH1F *hist1 = new TH1F("hist1","",AliL3Transform::GetNPads(row),0,AliL3Transform::GetNPads(row)-1);
558 TH1F *hist2 = new TH1F("hist2","",AliL3Transform::GetNTimeBins(),0,AliL3Transform::GetNTimeBins()-1);
559 TH2F *hist3 = new TH2F("hist3","",AliL3Transform::GetNPads(row),0,AliL3Transform::GetNPads(row)-1,AliL3Transform::GetNTimeBins(),0,AliL3Transform::GetNTimeBins()-1);
563 //Create the distributions in pad and time:
564 for(Int_t i=0; i<entries; i++)
566 hist1->Fill(random->Gaus(pad,sqrt(sigmaY2)));
567 hist2->Fill(random->Gaus(time,sqrt(sigmaZ2)));
570 //Create the cluster:
572 Double_t content1,content2,dpad,dtime;
573 for(Int_t i=0; i<hist1->GetEntries(); i++)
575 bin1 = hist1->GetBin(i);
576 content1 = hist1->GetBinContent(bin1);
577 if((Int_t)content1==0) continue;
578 content1 = charge*content1/entries;
579 dpad = hist1->GetBinCenter(bin1);
580 for(Int_t j=0; j<hist2->GetEntries(); j++)
582 bin2 = hist2->GetBin(j);
583 content2 = hist2->GetBinContent(bin2);
584 if((Int_t)content2==0) continue;
585 content2 = content1*content2/entries;
586 dtime = hist2->GetBinCenter(bin2);
587 hist3->Fill(dpad,dtime,content2);
592 //Fill it into the digit array:
593 for(Int_t i=0; i<hist3->GetNbinsX(); i++)
595 for(Int_t j=0; j<hist3->GetNbinsY(); j++)
597 bin1 = hist3->GetBin(i,j);
598 content1 = hist3->GetBinContent(bin1);
599 if((Int_t)content1 < 3) continue;
602 if(fNDigits >= fMaxDigits)
604 cerr<<"AliL3Compress::CreateDigits() : Array index out of range : "<<fNDigits<<endl;
607 fDigits[fNDigits].fCharge=(Int_t)content1;
608 fDigits[fNDigits].fRow = row;
609 fDigits[fNDigits].fPad = (Int_t)hist3->GetXaxis()->GetBinCenter(i);
610 fDigits[fNDigits].fTime = (Int_t)hist3->GetYaxis()->GetBinCenter(j);
611 fDPt[fNDigits] = &fDigits[fNDigits];
617 // cout<<"Small cluster "<<local_dig<<" pad "<<(Int_t)fDigits[fNDigits-1].fPad<<" time "<<(Int_t)fDigits[fNDigits-1].fTime<<endl;
625 void AliL3Compress::PrintCompRatio()
628 sprintf(fname,"%s/remains_%d_%d.raw",fPath,fSlice,fPatch);
629 AliL3MemHandler *mem = new AliL3MemHandler();
630 if(!mem->SetBinaryInput(fname))
632 cerr<<"AliL3Compress::PrintCompRatio(): Error opening file: "<<fname<<endl;
636 AliL3DigitRowData *rowPt = (AliL3DigitRowData*)mem->CompBinary2Memory(ndigits);
637 mem->CloseBinaryInput();
639 Int_t digit_counter=0;
640 for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
642 digit_counter += rowPt->fNDigit;
643 mem->UpdateRowPointer(rowPt);
647 sprintf(fname,"%s/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
648 FILE *file1 = fopen(fname,"r");
651 cerr<<"AliL3Compress::PrintCompRatio(): Error opening file: "<<fname<<endl;
654 fseek(file1,0,SEEK_END);
655 UInt_t filesize1 = (UInt_t)ftell(file1);
658 sprintf(fname,"%s/digits_%d_%d.raw",fPath,fSlice,fPatch);
659 FILE *file2 = fopen(fname,"r");
662 cerr<<"AliL3Compress::PrintCompRatio(): Error opening file: "<<fname<<endl;
665 fseek(file2,0,SEEK_END);
666 UInt_t filesize2 = (UInt_t)ftell(file2);
669 cout<<"----------------------"<<endl;
670 cout<<"Original file size : "<<filesize2<<endl;
671 cout<<"Compressed file size : "<<filesize1<<endl;
672 cout<<"Remaining digits : "<<digit_counter<<endl;
673 cout<<"Compression ratio : "<<(Float_t)(filesize1 + (10*digit_counter)/8)/(Float_t)(filesize2)<<endl;
677 void AliL3Compress::QSort(AliL3RandomDigitData **a, Int_t first, Int_t last)
680 // Sort array of AliL3RandomDigitData pointers using a quicksort algorithm.
681 // Uses CompareDigits() to compare objects.
684 static AliL3RandomDigitData *tmp;
685 static int i; // "static" to save stack space
688 while (last - first > 1) {
692 while (++i < last && CompareDigits(a[i], a[first]) < 0)
694 while (--j > first && CompareDigits(a[j], a[first]) > 0)
710 if (j - first < last - (j + 1)) {
712 first = j + 1; // QSort(j + 1, last);
714 QSort(a, j + 1, last);
715 last = j; // QSort(first, j);
720 void AliL3Compress::WriteRootFile(Char_t *newrootfile)
724 AliL3MemHandler *mem = new AliL3MemHandler();
725 sprintf(fname,"%s/restored_%d_%d.raw",fPath,fSlice,fPatch);
726 mem->SetBinaryInput(fname);
728 AliL3DigitRowData *rowPt = (AliL3DigitRowData*)mem->CompBinary2Memory(ndigits);
729 mem->CloseBinaryInput();
731 sprintf(fname,"%s/digitfile",fPath);
733 AliL3FileHandler *file = new AliL3FileHandler();
734 if(!file->SetAliInput(fname))
736 cerr<<"AliL3Compress::WriteRootFile() : Error opening file: "<<fname<<endl;
740 file->Init(fSlice,fPatch);
741 file->AliDigits2RootFile(rowPt,newrootfile);
742 file->CloseAliInput();