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