ALIROOT-5433 Transition to CDHv3 in HLT
[u/mrichter/AliRoot.git] / HLT / TPCLib / comp / AliHLTTPCDataCompressionIDMap.cxx
1 //**************************************************************************
2 //* This file is property of and copyright by the ALICE HLT Project        * 
3 //* ALICE Experiment at CERN, All rights reserved.                         *
4 //*                                                                        *
5 //* Primary Authors: Sergey Gorbunov                                       *
6 //*                  for The ALICE HLT Project.                            *
7 //*                                                                        *
8 //* Permission to use, copy, modify and distribute this software and its   *
9 //* documentation strictly for non-commercial purposes is hereby granted   *
10 //* without fee, provided that the above copyright notice appears in all   *
11 //* copies and that both the copyright notice and this permission notice   *
12 //* appear in the supporting documentation. The authors make no claims     *
13 //* about the suitability of this software for any purpose. It is          *
14 //* provided "as is" without express or implied warranty.                  *
15 //**************************************************************************
16
17 // @file   AliHLTTPCDataCompressionIDMap.cxx
18 // @author Sergey Gorbunov
19 // @date   2013-14-05
20 // @brief  Map HLT cluster ID to offline index (sector,row,number) after HLT compression
21
22 #include "AliHLTTPCDataCompressionIDMap.h"
23 #include "AliHLTTPCTransform.h"
24 #include "AliHLTTPCDefinitions.h"
25 #include "AliHLTTPCSpacePointData.h"
26 #include "AliHLTTPCRawCluster.h"
27 #include "AliHLTComponent.h"
28
29 #include <vector>
30 #include <algorithm>
31 #include "Riostream.h"
32
33 using namespace std;
34
35 /** ROOT macro for the implementation of ROOT specific class methods */
36 ClassImp(AliHLTTPCDataCompressionIDMap)
37
38 const UInt_t AliHLTTPCDataCompressionIDMap::fkNSlices = 36;
39 const UInt_t AliHLTTPCDataCompressionIDMap::fkNPatches = 6;
40 const UInt_t AliHLTTPCDataCompressionIDMap::fkNPatchesTotal = fkNSlices*fkNPatches;
41
42 AliHLTTPCDataCompressionIDMap::AliHLTTPCDataCompressionIDMap() 
43 :
44   fPatchClusterBlocks(NULL),
45   fInternalMemory(NULL),  
46   fIDMap(NULL),
47   fPatchFirstID(NULL),  
48   fPatchAllHltIDsPresent(NULL)
49 {  
50   //
51   // Default constructor 
52   //
53   fPatchClusterBlocks = new const AliHLTComponentBlockData* [fkNPatchesTotal];
54   fPatchFirstID = new AliHLTUInt32_t [fkNPatchesTotal+1];
55   fPatchAllHltIDsPresent = new Bool_t [fkNPatchesTotal];
56
57   if( !fPatchClusterBlocks || !fPatchFirstID || !fPatchAllHltIDsPresent ){
58     HLTError("Can not allocate memory block of %d bytes!!", fkNPatchesTotal*(sizeof(AliHLTUInt32_t) + sizeof( Bool_t) + sizeof(AliHLTComponentBlockData*)));
59   }
60
61   for( unsigned int i=0; i<fkNPatchesTotal; i++ ) fPatchClusterBlocks[i] = NULL;
62   for( unsigned int i=0; i<=fkNPatchesTotal; i++ ) fPatchFirstID[i] = 0;
63   for( unsigned int i=0; i<fkNPatchesTotal; i++ ) fPatchAllHltIDsPresent[i] = kFALSE;
64 }
65
66
67 AliHLTTPCDataCompressionIDMap::~AliHLTTPCDataCompressionIDMap()
68 {
69   //
70   // Default destructor.
71   //  
72   delete fInternalMemory;
73   delete[] fPatchAllHltIDsPresent;
74   delete[] fPatchFirstID;
75   delete[] fPatchClusterBlocks;
76 }
77
78 void AliHLTTPCDataCompressionIDMap::StartFilling()
79 {
80   //
81   // Start filling of IDs
82   //
83
84   delete fInternalMemory;
85   fInternalMemory = new std::vector< AliIDMapEntry >;
86   if( !fInternalMemory ){
87     HLTError("Can not allocate ID map, no memory left!!!");
88   }
89   fIDMap = NULL;
90   for( unsigned int i=0; i<fkNPatchesTotal; i++ ) fPatchClusterBlocks[i] = NULL;
91   for( unsigned int i=0; i<=fkNPatchesTotal; i++ ) fPatchFirstID[i] = 0;
92   for( unsigned int i=0; i<fkNPatchesTotal; i++ ) fPatchAllHltIDsPresent[i] = kFALSE;
93 }
94
95 void AliHLTTPCDataCompressionIDMap::SetClusterBlock( const AliHLTComponentBlockData* block)
96 {
97   //
98   // Set pointer to HLT clustrers 
99   //
100   UInt_t minSlice     = AliHLTTPCDefinitions::GetMinSliceNr(*block); 
101   UInt_t minPartition = AliHLTTPCDefinitions::GetMinPatchNr(*block);
102   UInt_t maxSlice     = AliHLTTPCDefinitions::GetMaxSliceNr(*block); 
103   UInt_t maxPartition = AliHLTTPCDefinitions::GetMaxPatchNr(*block);
104   if( maxSlice!=minSlice || maxPartition!=minPartition ){
105     HLTError("Unexpected input block (slices %d-%d, patches %d-%d): only one TPC partition per block is expected", minSlice, maxSlice, minPartition, maxPartition );
106     return ;
107   }
108
109   if( minSlice>= fkNSlices || minPartition >= fkNPatches ){
110     HLTError("Wrong Slice/Patch number of input block: slice %d, patch %d", minSlice, minPartition );
111     return ;
112   }
113
114   UInt_t iSlicePatch = minSlice*fkNPatches + minPartition;
115   fPatchClusterBlocks[iSlicePatch] = block;
116 }
117
118 void AliHLTTPCDataCompressionIDMap::FillHLTID( AliHLTUInt32_t hltID)
119 {
120   //
121   // fill cluster HLT ID
122   //
123
124   if( fIDMap || !fInternalMemory ){
125     HLTError("Internal error: FillHLTID() called before StartFilling()");
126     return;
127   }
128
129   UInt_t slice = (UInt_t) AliHLTTPCSpacePointData::GetSlice(hltID);
130   UInt_t patch = (UInt_t) AliHLTTPCSpacePointData::GetPatch(hltID);
131   UInt_t number = (UInt_t) AliHLTTPCSpacePointData::GetNumber(hltID);
132   UInt_t slicepatch = (UInt_t) ( slice*fkNPatches + patch );
133
134   if( slice>= fkNSlices || patch >= fkNPatches ){
135     HLTError("Wrong Slice/Patch number of input cluster ID: slice %d, patch %d", slice, patch);
136     return ;
137   }
138   
139   if( !fPatchClusterBlocks[slicepatch] ){
140     HLTError("Cluster block is not set for slice %d, patch %d", slice, patch);
141   }
142
143   const AliHLTTPCRawClusterData *data = reinterpret_cast<const AliHLTTPCRawClusterData*>(fPatchClusterBlocks[slicepatch]->fPtr);
144   if( !data ){
145     HLTError("no data found in datablock slice %d, patch %d",slice,patch);
146     return;
147   }
148
149   if( number>=data->fCount ){
150     HLTError("cluster number %d is outside of data block length %d",number,data->fCount);
151     return;
152   }
153   
154   Int_t sliceRow = data->fClusters[number].GetPadRow();
155   sliceRow+=AliHLTTPCTransform::GetFirstRow(patch);
156
157   Int_t sector=0, row=0;
158   Bool_t ok = AliHLTTPCTransform::Slice2Sector( slice, sliceRow, sector, row);  
159   if( !ok ) {
160     HLTError("Can not transform HLT slice %d, row %d to offline numeration",slice,sliceRow);
161     return;
162   }
163  
164   AliHLTUInt32_t usec = ( (AliHLTUInt32_t) sector )&0x7F;
165   AliHLTUInt32_t urow = ( (AliHLTUInt32_t) row )&0x7F;
166  
167   AliIDMapEntry entry;
168   entry.fOfflineID = (usec<<24) + (urow<<16);
169   entry.fHltID = hltID;  
170
171   fInternalMemory->push_back(entry);
172 }
173
174
175 void AliHLTTPCDataCompressionIDMap::EndFilling()
176 {
177   //
178   // End filling of HLT IDs
179   //
180   
181   if( fIDMap || !fInternalMemory ){
182     HLTError("Internal error: EndFilling() called before StartFilling()");
183     return;
184   }
185  
186   for( unsigned int i=0; i<fkNPatchesTotal; i++ ) fPatchClusterBlocks[i] = NULL;
187
188   const int nSec = AliHLTTPCTransform::GetNSector();
189   int nRows = AliHLTTPCTransform::GetNRowUp1() + AliHLTTPCTransform::GetNRowUp2();
190   if( nRows < AliHLTTPCTransform::GetNRowLow() ) nRows = AliHLTTPCTransform::GetNRowLow();
191   
192   int nRowsTotal = nSec*nRows;
193   AliHLTUInt32_t  *nRowClusters = new AliHLTUInt32_t  [nRowsTotal];
194   if( !nRowClusters ){
195     HLTError("Cannot allocate memory block of %d bytes", nRowsTotal*sizeof(AliHLTUInt32_t) );
196     return;
197   }
198   
199   for( int i=0; i<nRowsTotal; i++ ) nRowClusters[i] = 0;
200
201   for( unsigned int i=0; i<fInternalMemory->size(); i++){
202     AliIDMapEntry &entry = fInternalMemory->at(i);
203     int sec = entry.fOfflineID >> 24;
204     int row = (entry.fOfflineID >> 16 )&0x7F;
205     int secrow = sec*nRows+row;
206     if( sec>=nSec || row>=nRows ){
207       delete[] nRowClusters;
208       HLTError("Wrong numeration: sector %d, row %d", sec, row);
209       return;
210     }
211     entry.fOfflineID = ( entry.fOfflineID&0xFFFF0000 ) + ( nRowClusters[secrow]&0x0000FFFF );
212     nRowClusters[secrow]++;
213   }
214   delete[] nRowClusters;
215
216   std::sort(fInternalMemory->begin(), fInternalMemory->end(), CompareIDs );
217
218   fIDMap = &fInternalMemory->at(0); 
219
220   SetPatchIndices( fInternalMemory->size() );
221 }
222
223 void AliHLTTPCDataCompressionIDMap::SetPatchIndices(UInt_t nIDs)
224 {
225   //
226   // Set pach indices
227   //
228   if( !fIDMap ) return;
229   for( unsigned int i=0; i<fkNPatchesTotal; i++ ) fPatchAllHltIDsPresent[i] = kTRUE;
230
231   UInt_t currentPatch = 0;
232   UInt_t nPatchClusters=0;
233   fPatchFirstID[0]=0;
234   int nOK=0;
235   for( unsigned int i=0; i<nIDs; i++ ){
236     const AliIDMapEntry &entry = fIDMap[i];
237     UInt_t slice = AliHLTTPCSpacePointData::GetSlice(entry.fHltID);
238     UInt_t patch = AliHLTTPCSpacePointData::GetPatch(entry.fHltID);
239     UInt_t number = AliHLTTPCSpacePointData::GetNumber(entry.fHltID);
240     UInt_t slicepatch = slice*fkNPatches + patch;
241
242     if( slice>= fkNSlices || patch >= fkNPatches || slicepatch < currentPatch ){
243       HLTWarning("Corrupted cluster ID block: wrong numeration: slice %d, patch %d", slice, patch );
244       break;
245     }        
246     if( slicepatch>currentPatch ){
247       for(UInt_t j = currentPatch+1; j<=slicepatch; j++) fPatchFirstID[j]=i;
248       currentPatch = slicepatch;
249       nPatchClusters=0;
250     }
251     if( number!= nPatchClusters ) {
252       if( fPatchAllHltIDsPresent[slicepatch] ){
253         HLTDebug("Non-continious cluster numeration for slice %d, patch %d", slice, patch);
254       }
255       fPatchAllHltIDsPresent[slicepatch]=kFALSE;
256     }
257     nPatchClusters++;
258     nOK++;
259   }
260   
261   for( UInt_t j = currentPatch+1; j<=fkNPatchesTotal; j++) fPatchFirstID[j] = nOK;
262
263 }
264
265
266 Bool_t AliHLTTPCDataCompressionIDMap::GetOfflineID( AliHLTUInt32_t hltID, Int_t &sector, Int_t &row, UInt_t &ind )
267 {
268   //
269   // Get cluster ID
270   //
271
272   AliHLTUInt32_t offlineID = 0;
273   if( !GetOfflineID(hltID, offlineID) ){
274     sector = 0;
275     row = 0;
276     ind = 0;
277     return 0;
278   }
279   sector = offlineID >> 24;
280   row = (offlineID >>16 )&0x7F;
281   ind = offlineID &0x0000FFFF;
282   return 1;
283 }
284
285 Bool_t AliHLTTPCDataCompressionIDMap::GetOfflineID( AliHLTUInt32_t hltID, AliHLTUInt32_t &offlineID )
286 {
287   //
288   // Get cluster ID
289   //
290
291   offlineID = 0;
292
293   UInt_t slice = AliHLTTPCSpacePointData::GetSlice(hltID);
294   UInt_t patch = AliHLTTPCSpacePointData::GetPatch(hltID);
295   UInt_t number = AliHLTTPCSpacePointData::GetNumber(hltID);
296   UInt_t slicepatch = slice*fkNPatches + patch;
297   if( !fIDMap || slice>= fkNSlices || patch >= fkNPatches ){
298     HLTWarning("Wrong HLT ID: slice %d, patch %d", slice, patch);
299     return 0;
300   }
301   const AliIDMapEntry *entry = NULL;
302
303   if( fPatchAllHltIDsPresent[slicepatch] ){
304     // look at cluster position 
305     if( fPatchFirstID[slicepatch]+number<fPatchFirstID[slicepatch+1] ){
306       entry = fIDMap + fPatchFirstID[slicepatch]+number;
307     }
308   } else { 
309     // do search
310     const AliIDMapEntry *pEnd = fIDMap+fPatchFirstID[fkNPatchesTotal];
311     AliIDMapEntry tmp;
312     tmp.fHltID = hltID;
313     tmp.fOfflineID = 0;
314     entry = std::lower_bound(fIDMap, pEnd, tmp, CompareIDs );
315     if( entry==pEnd || entry->fHltID!=hltID ){
316       entry = NULL;
317     }
318   }
319  
320   if( !entry ){
321     HLTWarning("Cluster ID is not present in the map: slice %d, patch %d, cluster %d", slice, patch, number);
322     return 0;
323   }
324   
325   offlineID = entry->fOfflineID;
326   return 1;
327 }
328
329
330 void AliHLTTPCDataCompressionIDMap::SetIDMap( const AliHLTUInt8_t *data, AliHLTUInt32_t sizeBytes )
331 {
332   //
333   // Set cluster ID map from input bufer
334   //
335
336   delete fInternalMemory;
337   fInternalMemory = 0;
338   
339   fIDMap = reinterpret_cast< const AliIDMapEntry * > (data);  
340   if( !fIDMap ) return;
341   int nIDs = sizeBytes / sizeof( AliIDMapEntry );
342   SetPatchIndices( nIDs );
343 }
344
345 int AliHLTTPCDataCompressionIDMap::WriteIDMap( AliHLTUInt8_t* output, AliHLTUInt32_t& sizeBytes )
346 {
347   //
348   // Write cluster ID map to output buffer
349   //
350   AliHLTUInt32_t maxSize = sizeBytes;
351   sizeBytes = 0;
352   if( !fIDMap ) return sizeBytes;
353   int nIDs = fPatchFirstID[fkNPatchesTotal];
354   AliHLTUInt32_t size =  nIDs * sizeof(AliIDMapEntry);
355   if( size > maxSize ) return sizeBytes;
356   sizeBytes = size;
357   memcpy( output, (const void*)fIDMap, sizeBytes);
358   return sizeBytes;
359 }
360