]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCHWCFSpacePointContainer.cxx
update of track model compression
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCHWCFSpacePointContainer.cxx
1 // $Id$
2
3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project        * 
5 //* ALICE Experiment at CERN, All rights reserved.                         *
6 //*                                                                        *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8 //*                  for The ALICE HLT Project.                            *
9 //*                                                                        *
10 //* Permission to use, copy, modify and distribute this software and its   *
11 //* documentation strictly for non-commercial purposes is hereby granted   *
12 //* without fee, provided that the above copyright notice appears in all   *
13 //* copies and that both the copyright notice and this permission notice   *
14 //* appear in the supporting documentation. The authors make no claims     *
15 //* about the suitability of this software for any purpose. It is          *
16 //* provided "as is" without express or implied warranty.                  *
17 //**************************************************************************
18
19 /// @file   AliHLTTPCHWCFSpacePointContainer.cxx
20 /// @author Matthias Richter
21 /// @date   2011-08-08
22 /// @brief  Helper class for handling of HLT TPC cluster data blocks from the
23 ///         HW ClusterFinder
24 /// @note   Class is a duplicate of AliHLTTPCHWCFSpacePointContainer and should
25 ///         be merged with it in a generic way
26
27 #include "AliHLTTPCHWCFSpacePointContainer.h"
28 #include "AliHLTErrorGuard.h"
29 #include "AliHLTTPCDefinitions.h"
30 #include "AliHLTTPCSpacePointData.h"
31 #include "AliHLTTPCRawCluster.h"
32 #include "AliHLTTPCTransform.h"
33 #include "AliHLTComponent.h"
34 #include "AliHLTTemplates.h"
35 #include "AliHLTDataDeflater.h"
36 #include "AliRawDataHeader.h"
37 #include "AliLog.h"
38 #include "TMath.h"
39 #include <memory>
40 #include <algorithm>
41 #include <cmath>
42 #include <iostream>
43 #include <sstream>
44 #include <iomanip>
45
46
47 /** ROOT macro for the implementation of ROOT specific class methods */
48 ClassImp(AliHLTTPCHWCFSpacePointContainer)
49
50 AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointContainer(int mode)
51   : AliHLTSpacePointContainer()
52   , fClusters()
53   , fSelections()
54   , fBlocks()
55   , fSingleBlock()
56   , fMode(mode)
57 {
58   // see header file for class documentation
59   // or
60   // refer to README to build package
61   // or
62   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
63   if (fMode&kModeSingle) {
64     fSingleBlock.SetDecoder(new AliHLTTPCHWCFData);
65     fSingleBlock.SetGrid(AllocateIndexGrid());
66   }
67 }
68
69 AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointContainer(const AliHLTTPCHWCFSpacePointContainer& c)
70   : AliHLTSpacePointContainer(c)
71   , fClusters(c.fClusters.begin(), c.fClusters.end())
72   , fSelections()
73   , fBlocks()
74   , fSingleBlock()
75   , fMode(c.fMode)
76 {
77   /// copy constructor
78 }
79
80 AliHLTTPCHWCFSpacePointContainer& AliHLTTPCHWCFSpacePointContainer::operator=(const AliHLTTPCHWCFSpacePointContainer& c)
81 {
82   /// assignment operator
83   if (&c==this) return *this;
84   AliHLTSpacePointContainer::operator=(c);
85   fClusters=c.fClusters;
86   fMode=c.fMode;
87
88   return *this;
89 }
90
91 AliHLTTPCHWCFSpacePointContainer::~AliHLTTPCHWCFSpacePointContainer()
92 {
93   // destructor
94   Clear();
95   if (fSingleBlock.GetDecoder()) delete fSingleBlock.GetDecoder();
96   if (fSingleBlock.GetGrid()) delete fSingleBlock.GetGrid();
97 }
98
99 int AliHLTTPCHWCFSpacePointContainer::AddInputBlock(const AliHLTComponentBlockData* pDesc)
100 {
101   // add input block to the collection
102   if (!pDesc) return -EINVAL;
103   int iResult=0;
104   int count=0;
105   if (pDesc->fDataType!=AliHLTTPCDefinitions::fgkHWClustersDataType) {
106     HLTWarning("ignoring data block of type %s", AliHLTComponent::DataType2Text(pDesc->fDataType).c_str());
107     return 0;
108   }
109   if (!pDesc->fPtr) return -ENODATA;
110   if (pDesc->fSize<=sizeof(AliRawDataHeader)) return 0;
111
112   AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
113   AliHLTUInt8_t part  = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
114
115   AliHLTUInt32_t decoderIndex=AliHLTTPCSpacePointData::GetID(slice, part, 0);
116
117   AliHLTUInt32_t *buffer=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr);
118   // skip the first 8 32-bit CDH words
119   buffer += 8;
120   UInt_t bufferSize32 = ((Int_t)pDesc->fSize - sizeof(AliRawDataHeader) )/sizeof(AliHLTUInt32_t);
121
122   AliHLTTPCHWCFData* pDecoder=NULL;
123   AliHLTSpacePointPropertyGrid* pGrid=NULL;
124   if (fMode&kModeSingle) {
125     pDecoder=fSingleBlock.GetDecoder();
126     pGrid=fSingleBlock.GetGrid();
127   } else {
128     if (fBlocks.find(decoderIndex)!=fBlocks.end()) {
129       HLTError("data block of slice %d partition %d already added, skipping data block", slice, part);
130       return -EEXIST;
131     }
132   }
133
134   if (!pDecoder) {
135     pDecoder=new AliHLTTPCHWCFData;
136     if (!pDecoder) return -ENOMEM;
137   }
138
139   if (pDecoder->Init(reinterpret_cast<AliHLTUInt8_t*>(buffer), bufferSize32*sizeof(AliHLTUInt32_t))<0 ||
140       (pDecoder->CheckVersion()<0 && (int)bufferSize32>pDecoder->GetRCUTrailerSize())) {
141     HLTError("data block of type %s corrupted: can not decode format",
142              AliHLTComponent::DataType2Text(pDesc->fDataType).c_str());
143     return -EBADMSG;
144   }
145
146   if (fMode&kModeSingle && !pGrid) {
147     pGrid=AllocateIndexGrid();
148     if (!pGrid) {
149       delete pDecoder;
150       return -ENOMEM;
151     }
152   }
153
154   if (fMode&kModeCreateMap) { // register immediately
155   UInt_t nofClusters=pDecoder->GetNumberOfClusters();
156
157   for (UInt_t i=0; i<nofClusters; i++) {
158     AliHLTUInt32_t clusterID=~(AliHLTUInt32_t)0;
159     // cluster ID from slice, partition and index
160     clusterID=AliHLTTPCSpacePointData::GetID(slice, part, i);
161
162     if (fClusters.find(clusterID)==fClusters.end()) {
163       // new cluster
164       fClusters[clusterID]=AliHLTTPCHWCFSpacePointProperties(pDecoder, i);
165       count++;
166     } else {
167       HLTError("cluster with ID 0x%08x already existing, skipping cluster %d of data block 0x%08x",
168                clusterID, i, pDesc->fSpecification);
169     }
170   }
171   }
172
173   if (pGrid && (iResult=PopulateAccessGrid(pGrid, pDecoder, slice, part))<0) {
174     HLTError("failed to populate access grid for block %s 0x%09x: %d",
175              AliHLTComponent::DataType2Text(pDesc->fDataType).c_str(), pDesc->fSpecification, iResult);
176     return iResult;
177   }
178
179   if (fMode&kModeSingle) {
180     fSingleBlock.SetDecoder(pDecoder);
181     fSingleBlock.SetGrid(pGrid);
182     fSingleBlock.SetId(decoderIndex);
183   } else {
184     fBlocks[decoderIndex]=AliHLTTPCHWCFSpacePointBlock(decoderIndex, pDecoder, pGrid);
185   }
186   return count;
187 }
188
189 AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* AliHLTTPCHWCFSpacePointContainer::AllocateIndexGrid()
190 {
191   // allocate index grid, one single point to define the dimensions
192   
193   // max 33 padrows, step 1 padrow
194   // max 140 pads, step 2x max delta pad
195   // max 1024 time bins, step 2x max delta time
196   return new AliHLTSpacePointPropertyGrid(33, 1.0,
197                                           140, 2*AliHLTTPCDefinitions::GetMaxClusterDeltaPad(),
198                                           1024, 2*AliHLTTPCDefinitions::GetMaxClusterDeltaTime()
199                                           );
200 }
201
202 int AliHLTTPCHWCFSpacePointContainer::PopulateAccessGrid(AliHLTSpacePointPropertyGrid* pGrid, AliHLTUInt32_t mask) const
203 {
204   // populate an access grid
205   if (!pGrid) return -EINVAL;
206
207   pGrid->Clear();
208   
209   AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(mask);
210   AliHLTUInt8_t partition  = AliHLTTPCDefinitions::GetMinPatchNr(mask);
211   AliHLTUInt32_t decoderIndex=AliHLTTPCSpacePointData::GetID(slice, partition, 0);
212   std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointBlock>::const_iterator block=fBlocks.find(decoderIndex);
213   if (block==fBlocks.end()) {
214     HLTError("can not find data block of id 0x%08x", mask);
215     return -ENOENT;
216   }
217   return PopulateAccessGrid(pGrid, block->second.GetDecoder(), slice, partition);
218 }
219
220 int AliHLTTPCHWCFSpacePointContainer::PopulateAccessGrid(AliHLTSpacePointPropertyGrid* pGrid, AliHLTTPCHWCFData* pDecoder,
221                                                          int slice, int partition) const
222 {
223   // populate an access grid
224   if (!pDecoder) return -EINVAL;
225   int iResult=0;
226
227   if (pDecoder->GetNumberOfClusters()==0) return 0;
228   AliHLTTPCHWCFData::iterator cl=pDecoder->begin();
229   for (; cl!=pDecoder->end(); ++cl) {
230     iResult=pGrid->CountSpacePoint(cl.GetPadRow(), cl.GetPad(), cl.GetTime());
231     if (iResult<0)
232       HLTError("CountSpacePoint %f %f %f failed: %d", cl.GetPadRow(), cl.GetPad(), cl.GetTime(), iResult);
233   }
234   
235   int count=0;
236   cl=pDecoder->begin();
237   for (; cl!=pDecoder->end(); ++cl, count++) {
238     AliHLTUInt32_t id=AliHLTTPCSpacePointData::GetID(slice, partition, count);
239     iResult=pGrid->AddSpacePoint(AliHLTSpacePointProperties(id), cl.GetPadRow(), cl.GetPad(), cl.GetTime());
240     if (iResult<0)
241       HLTError("AddSpacePoint 0x%08x %f %f %f failed: %d", id, cl.GetPadRow(), cl.GetPad(), cl.GetTime(), iResult);
242   }
243
244   return 0;
245 }
246
247 const AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* AliHLTTPCHWCFSpacePointContainer::GetSpacePointPropertyGrid(AliHLTUInt32_t mask) const
248 {
249   // get the access grid for a data block
250   AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(mask);
251   AliHLTUInt8_t part  = AliHLTTPCDefinitions::GetMinPatchNr(mask);
252   AliHLTUInt32_t decoderIndex=AliHLTTPCSpacePointData::GetID(slice, part, 0);
253   std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointBlock>::const_iterator block=fBlocks.find(decoderIndex);
254   if (block==fBlocks.end()) {
255     HLTError("can not find data block of id 0x%08x", mask);
256     return NULL;
257   }
258   return block->second.GetGrid();
259 }
260
261 int AliHLTTPCHWCFSpacePointContainer::SetSpacePointPropertyGrid(AliHLTUInt32_t mask, AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pGrid)
262 {
263   // set the access grid for a data block
264   AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(mask);
265   AliHLTUInt8_t part  = AliHLTTPCDefinitions::GetMinPatchNr(mask);
266   AliHLTUInt32_t decoderIndex=AliHLTTPCSpacePointData::GetID(slice, part, 0);
267   std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointBlock>::iterator block=fBlocks.find(decoderIndex);
268   if (block==fBlocks.end()) {
269     HLTError("can not find data block of id 0x%08x", mask);
270     return -ENOENT;
271   }
272   if (block->second.GetGrid()!=NULL && pGrid!=NULL && block->second.GetGrid()!=pGrid) {
273     // there is trouble ahead because this will delete the index grid instance
274     // but it might be an external pointer supposed to be deleted by someone else
275     ALIHLTERRORGUARD(1, "overriding previous instance of index grid, potential memory leak or invalid deallocation ahead");
276   }
277   block->second.SetGrid(pGrid);
278   return 0;
279 }
280
281 int AliHLTTPCHWCFSpacePointContainer::GetClusterIDs(vector<AliHLTUInt32_t>& tgt) const
282 {
283   // get array of cluster IDs
284   tgt.clear();
285   transform(fClusters.begin(), fClusters.end(), back_inserter(tgt), HLT::AliGetKey());
286   return tgt.size();
287 }
288
289 bool AliHLTTPCHWCFSpacePointContainer::Check(AliHLTUInt32_t clusterID) const
290 {
291   // check if the cluster is available
292   return fClusters.find(clusterID)!=fClusters.end();
293 }
294
295 const vector<AliHLTUInt32_t>* AliHLTTPCHWCFSpacePointContainer::GetClusterIDs(AliHLTUInt32_t mask)
296 {
297   // get array of cluster IDs filtered by mask
298   if (fSelections.find(mask)!=fSelections.end()) {
299     // return existing selection
300     return fSelections.find(mask)->second;
301   }
302   // create new collection
303   vector<AliHLTUInt32_t>* selected=new vector<AliHLTUInt32_t>;
304   if (!selected) return NULL;
305   UInt_t slice=AliHLTTPCSpacePointData::GetSlice(mask);
306   UInt_t partition=AliHLTTPCSpacePointData::GetPatch(mask);
307   //HLTInfo("creating collection 0x%08x", mask);
308
309   // the first cluster with number 0 has equal ID to mask unless
310   // the mask selects multiple partitions/slices
311   std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(mask);
312   bool bAll=false;
313   if (slice>=(unsigned)AliHLTTPCTransform::GetNSlice() ||
314       partition>=(unsigned)AliHLTTPCTransform::GetNumberOfPatches()) {
315     cl=fClusters.begin();
316     bAll=true;
317   }
318   for (; cl!=fClusters.end(); cl++) {
319     UInt_t s=AliHLTTPCSpacePointData::GetSlice(cl->first);
320     UInt_t p=AliHLTTPCSpacePointData::GetPatch(cl->first);
321     if ((slice>=(unsigned)AliHLTTPCTransform::GetNSlice() || s==slice) && 
322         (partition>=(unsigned)AliHLTTPCTransform::GetNumberOfPatches() || p==partition)) {
323       selected->push_back(cl->first);
324     } else if (!bAll) {
325       // no need to continue, we are out of the range
326       break;
327     }
328   }
329   //HLTInfo("collection 0x%08x with %d spacepoints", mask, selected->size());
330   fSelections[mask]=selected;
331   return selected;
332 }
333
334 float AliHLTTPCHWCFSpacePointContainer::GetX(AliHLTUInt32_t clusterID) const
335 {
336   // get X coordinate
337   std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(clusterID);
338   if (cl==fClusters.end() ||
339       cl->second.Decoder()==NULL) return 0.0;
340   // FIXME: understand deviation from the nominal x value
341   // there is a small deviation in the x coordinate - padrow number correlation
342   // in principle, the clusterfinder only uses the mapping to set the x parameter.
343   // now extracting the x value from the padrow no.
344   //return cl->second.Decoder()->fX;
345   int index=AliHLTTPCSpacePointData::GetNumber(cl->first);
346   return cl->second.Decoder()->GetPadRow(index);
347 }
348
349 float AliHLTTPCHWCFSpacePointContainer::GetXWidth(AliHLTUInt32_t clusterID) const
350 {
351   // get error for X coordinate
352   std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(clusterID);
353   if (cl==fClusters.end() ||
354       cl->second.Decoder()==NULL) return 0.0;
355   return 0.0; // fixed in padrow number
356 }
357
358 float AliHLTTPCHWCFSpacePointContainer::GetY(AliHLTUInt32_t clusterID) const
359 {
360   // get Y coordinate
361   std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(clusterID);
362   if (cl==fClusters.end() ||
363       cl->second.Decoder()==NULL) return 0.0;
364   int index=AliHLTTPCSpacePointData::GetNumber(cl->first);
365   return cl->second.Decoder()->GetPad(index);
366 }
367
368 float AliHLTTPCHWCFSpacePointContainer::GetYWidth(AliHLTUInt32_t clusterID) const
369 {
370   // get error for Y coordinate
371   std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(clusterID);
372   if (cl==fClusters.end() ||
373       cl->second.Decoder()==NULL) return 0.0;
374   int index=AliHLTTPCSpacePointData::GetNumber(cl->first);
375   return cl->second.Decoder()->GetSigmaY2(index);
376 }
377
378 float AliHLTTPCHWCFSpacePointContainer::GetZ(AliHLTUInt32_t clusterID) const
379 {
380   // get Z coordinate
381   std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(clusterID);
382   if (cl==fClusters.end() ||
383       cl->second.Decoder()==NULL) return 0.0;
384   int index=AliHLTTPCSpacePointData::GetNumber(cl->first);
385   return cl->second.Decoder()->GetTime(index);
386 }
387
388 float AliHLTTPCHWCFSpacePointContainer::GetZWidth(AliHLTUInt32_t clusterID) const
389 {
390   // get error for Z coordinate
391   std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(clusterID);
392   if (cl==fClusters.end() ||
393       cl->second.Decoder()==NULL) return 0.0;
394   int index=AliHLTTPCSpacePointData::GetNumber(cl->first);
395   return cl->second.Decoder()->GetSigmaZ2(index);
396 }
397
398 float AliHLTTPCHWCFSpacePointContainer::GetCharge(AliHLTUInt32_t clusterID) const
399 {
400   // get charge
401   std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(clusterID);
402   if (cl==fClusters.end() ||
403       cl->second.Decoder()==NULL) return 0.0;
404   int index=AliHLTTPCSpacePointData::GetNumber(cl->first);
405   return cl->second.Decoder()->GetCharge(index);
406 }
407
408 float AliHLTTPCHWCFSpacePointContainer::GetQMax(AliHLTUInt32_t clusterID) const
409 {
410   // get charge
411   std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(clusterID);
412   if (cl==fClusters.end() ||
413       cl->second.Decoder()==NULL) return 0.0;
414   int index=AliHLTTPCSpacePointData::GetNumber(cl->first);
415   return cl->second.Decoder()->GetQMax(index);
416 }
417
418 float AliHLTTPCHWCFSpacePointContainer::GetPhi(AliHLTUInt32_t clusterID) const
419 {
420   // get charge
421
422   // phi can be derived directly from the id, no need to search
423   // for existing cluster
424   int slice=AliHLTTPCSpacePointData::GetSlice(clusterID);
425   return ( slice + 0.5 ) * TMath::Pi() / 9.0;
426 }
427
428 void AliHLTTPCHWCFSpacePointContainer::Clear(Option_t * option)
429 {
430   // clear the object and reset pointer references
431   fClusters.clear();
432
433   for (std::map<AliHLTUInt32_t, vector<AliHLTUInt32_t>*>::iterator selection=fSelections.begin();
434        selection!=fSelections.end(); selection++) {
435     if (selection->second) delete selection->second;
436   }
437   fSelections.clear();
438
439   for (std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointBlock>::iterator block=fBlocks.begin();
440        block!=fBlocks.end(); block++) {
441     if (block->second.GetDecoder()) delete block->second.GetDecoder();
442     if (block->second.GetGrid()) delete block->second.GetGrid();
443   }
444   fBlocks.clear();
445
446   if (fSingleBlock.GetDecoder()) fSingleBlock.GetDecoder()->Reset();
447   if (fSingleBlock.GetGrid()) fSingleBlock.GetGrid()->Clear();
448
449   AliHLTSpacePointContainer::Clear(option);
450 }
451
452 void AliHLTTPCHWCFSpacePointContainer::Print(ostream& out, Option_t */*option*/) const
453 {
454   // print to stream
455   std::stringstream str;
456   str << "AliHLTTPCHWCFSpacePointContainer::Print" << endl;
457   str << "n clusters: " << fClusters.size() << endl;
458   for (std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.begin();
459        cl!=fClusters.end(); cl++) {
460     str << " 0x" << hex << setw(8) << setfill('0') << cl->first << dec << cl->second << endl;
461   }
462   out << str;
463 }
464
465 AliHLTSpacePointContainer* AliHLTTPCHWCFSpacePointContainer::SelectByMask(AliHLTUInt32_t mask, bool /*bAlloc*/) const
466 {
467   /// create a collection of clusters for a space point mask
468   std::auto_ptr<AliHLTTPCHWCFSpacePointContainer> c(new AliHLTTPCHWCFSpacePointContainer);
469   if (!c.get()) return NULL;
470
471   UInt_t slice=AliHLTTPCSpacePointData::GetSlice(mask);
472   UInt_t partition=AliHLTTPCSpacePointData::GetPatch(mask);
473   for (std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.begin();
474        cl!=fClusters.end(); cl++) {
475     UInt_t s=AliHLTTPCSpacePointData::GetSlice(cl->first);
476     UInt_t p=AliHLTTPCSpacePointData::GetPatch(cl->first);
477     if ((slice>=(unsigned)AliHLTTPCTransform::GetNSlice() || s==slice) && 
478         (partition>=(unsigned)AliHLTTPCTransform::GetNumberOfPatches() || p==partition)) {
479       c->fClusters[cl->first]=cl->second;
480     }
481   }
482   return c.release();
483 }
484
485 AliHLTSpacePointContainer* AliHLTTPCHWCFSpacePointContainer::SelectByTrack(int trackId, bool /*bAlloc*/) const
486 {
487   /// create a collection of clusters for a specific track
488   std::auto_ptr<AliHLTTPCHWCFSpacePointContainer> c(new AliHLTTPCHWCFSpacePointContainer);
489   if (!c.get()) return NULL;
490
491   HLT::copy_map_if(fClusters.begin(), fClusters.end(), c->fClusters, HLT::AliHLTUnaryPredicate<AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties, int>(&AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties::GetTrackId,trackId));
492   return c.release();
493 }
494
495 AliHLTSpacePointContainer* AliHLTTPCHWCFSpacePointContainer::SelectByMC(int mcId, bool /*bAlloc*/) const
496 {
497   /// create a collection of clusters for a specific MC track
498   std::auto_ptr<AliHLTTPCHWCFSpacePointContainer> c(new AliHLTTPCHWCFSpacePointContainer);
499   if (!c.get()) return NULL;
500
501   HLT::copy_map_if(fClusters.begin(), fClusters.end(), c->fClusters, HLT::AliHLTUnaryPredicate<AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties, int>(&AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties::GetMCId,mcId));
502   return c.release();
503 }
504
505 AliHLTSpacePointContainer* AliHLTTPCHWCFSpacePointContainer::UsedClusters(bool /*bAlloc*/) const
506 {
507   /// create a collection of all used clusters
508   std::auto_ptr<AliHLTTPCHWCFSpacePointContainer> c(new AliHLTTPCHWCFSpacePointContainer);
509   if (!c.get()) return NULL;
510
511   HLT::copy_map_if(fClusters.begin(), fClusters.end(), c->fClusters, HLT::AliHLTUnaryPredicate<AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties, bool>(&AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties::IsUsed,true));
512   return c.release();
513 }
514
515 AliHLTSpacePointContainer* AliHLTTPCHWCFSpacePointContainer::UnusedClusters(bool /*bAlloc*/) const
516 {
517   /// create a collection of all unused clusters
518   std::auto_ptr<AliHLTTPCHWCFSpacePointContainer> c(new AliHLTTPCHWCFSpacePointContainer);
519   if (!c.get()) return NULL;
520
521   HLT::copy_map_if(fClusters.begin(), fClusters.end(), c->fClusters, HLT::AliHLTUnaryPredicate<AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties, bool>(&AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties::IsUsed,false));
522   return c.release();
523 }
524
525 int AliHLTTPCHWCFSpacePointContainer::MarkUsed(const AliHLTUInt32_t* clusterIDs, int arraySize)
526 {
527   /// mark the clusters with specified IDs as used
528   if (!clusterIDs) return -EINVAL;
529   int iCount=0;
530   for (int i=0; i<arraySize; i++) {
531     if (fClusters.find(clusterIDs[i])==fClusters.end()) continue;
532     fClusters[clusterIDs[i]].MarkUsed();
533     iCount++;
534   }
535   return iCount;
536 }
537
538 int AliHLTTPCHWCFSpacePointContainer::SetTrackID(int trackID, const AliHLTUInt32_t* clusterIDs, int arraySize)
539 {
540   /// set track id for specified clusters
541   if (!clusterIDs) return -EINVAL;
542   int iCount=0;
543   for (int i=0; i<arraySize; i++) {
544     if (fClusters.find(clusterIDs[i])==fClusters.end()) continue;
545     fClusters[clusterIDs[i]].SetTrackId(trackID);
546     iCount++;
547   }
548   return iCount;
549 }
550
551 int AliHLTTPCHWCFSpacePointContainer::GetTrackID(AliHLTUInt32_t clusterID) const
552 {
553   /// get track id for specified cluster
554   map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator element=fClusters.find(clusterID);
555   if (element==fClusters.end()) return -1;
556   return element->second.GetTrackId();
557 }
558
559 int AliHLTTPCHWCFSpacePointContainer::SetMCID(int mcID, const AliHLTUInt32_t* clusterIDs, int arraySize)
560 {
561   /// set mc id for specified clusters
562   if (!clusterIDs) return -EINVAL;
563   int iCount=0;
564   for (int i=0; i<arraySize; i++) {
565     if (fClusters.find(clusterIDs[i])==fClusters.end()) continue;
566     fClusters[clusterIDs[i]].SetMCId(mcID);
567     iCount++;
568   }
569   return iCount;
570 }
571
572 int AliHLTTPCHWCFSpacePointContainer::Write(AliHLTUInt8_t* outputPtr,
573                                             AliHLTUInt32_t size,
574                                             AliHLTComponentBlockDataList&
575                                             outputBlocks,
576                                             AliHLTDataDeflater* pDeflater,
577                                             const char* option) const
578 {
579   /// write blocks to HLT component output
580   AliHLTUInt32_t offset=0;
581   if (outputBlocks.size()>0) {
582     offset=outputBlocks.back().fOffset+outputBlocks.back().fSize;
583   }
584   return Write(outputPtr, size, offset, outputBlocks, pDeflater, option);
585 }
586
587 int AliHLTTPCHWCFSpacePointContainer::Write(AliHLTUInt8_t* outputPtr,
588                                             AliHLTUInt32_t size,
589                                             AliHLTUInt32_t offset,
590                                             AliHLTComponentBlockDataList&
591                                             outputBlocks,
592                                             AliHLTDataDeflater* pDeflater,
593                                             const char* option) const
594 {
595   /// write blocks to HLT component output
596   return WriteSorted(outputPtr, size, offset, outputBlocks, pDeflater, option);
597 }
598
599 int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
600                                                   AliHLTUInt32_t size,
601                                                   AliHLTUInt32_t offset,
602                                                   AliHLTComponentBlockDataList&
603                                                   outputBlocks,
604                                                   AliHLTDataDeflater* pDeflater,
605                                                   const char* option) const
606 {
607   /// write blocks to HLT component output
608   int iResult=0;
609
610   if (fMode&kModeSingle) {
611     iResult=WriteSorted(outputPtr, size, offset, fSingleBlock.GetDecoder(), fSingleBlock.GetGrid(), fSingleBlock.GetId(), outputBlocks, pDeflater, option);
612   } else {
613     iResult=-ENOENT;
614     for (std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointBlock>::const_iterator block=fBlocks.begin();
615          block!=fBlocks.end(); block++) {
616       AliHLTTPCHWCFData* pDecoder=block->second.GetDecoder();
617       AliHLTSpacePointPropertyGrid* pGrid=block->second.GetGrid();
618       AliHLTUInt32_t mask=block->first;
619       // FIXME: have to propagate the parameter which block is currently to be written
620       // for now the index grid is only set for that one
621       if (!pGrid) continue;
622       iResult=WriteSorted(outputPtr, size, offset, pDecoder, pGrid, mask, outputBlocks, pDeflater, option);
623       break; // only one is supposed to be written
624     }
625     if (iResult==-ENOENT) {
626       HLTError("could not find the index grid of the partition to be written");
627     }
628   }
629   return iResult;
630 }
631
632 int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
633                                                   AliHLTUInt32_t size,
634                                                   AliHLTUInt32_t offset,
635                                                   AliHLTTPCHWCFData* pDecoder,
636                                                   AliHLTSpacePointPropertyGrid* pGrid,
637                                                   AliHLTUInt32_t mask,
638                                                   AliHLTComponentBlockDataList&
639                                                   outputBlocks,
640                                                   AliHLTDataDeflater* pDeflater,
641                                                   const char* /*option*/) const
642 {
643   /// write blocks to HLT component output
644   if (!outputPtr || !pDecoder || !pGrid) return -EINVAL;
645   if (pDecoder->GetNumberOfClusters()==0) return 0;
646   int iResult=0;
647   AliHLTUInt32_t capacity=size;
648   size=0;
649
650   int slice=AliHLTTPCSpacePointData::GetSlice(mask);
651   int part=AliHLTTPCSpacePointData::GetPatch(mask);
652
653   AliHLTTPCRawClusterData* blockout=reinterpret_cast<AliHLTTPCRawClusterData*>(outputPtr+size);
654   blockout->fVersion=0;
655   blockout->fCount=0;
656
657   if (pDeflater) {
658     pDeflater->Clear();
659     pDeflater->InitBitDataOutput(reinterpret_cast<AliHLTUInt8_t*>(blockout->fClusters), capacity-size-sizeof(AliHLTTPCRawClusterData));
660     blockout->fVersion=pDeflater->GetDeflaterVersion();
661   }
662
663   unsigned lastPadRow=0;
664   AliHLTSpacePointPropertyGrid::iterator clusterID=pGrid->begin();
665   if (clusterID!=pGrid->end()) {
666     for (; clusterID!=pGrid->end(); clusterID++) {
667       if (clusterID.Data().fTrackId>-1) {
668         // this is an assigned cluster, skip
669         // TODO: introduce selectors into AliHLTIndexGrid::begin to loop
670         // consistently over entries, e.g. this check has to be done also
671         // in the forwarding of MC labels in
672         // AliHLTTPCDataCompressionComponent::ForwardMCLabels
673         continue;
674       }
675       if ((unsigned)slice!=AliHLTTPCSpacePointData::GetSlice(clusterID.Data().fId) ||
676           (unsigned)part!=AliHLTTPCSpacePointData::GetPatch(clusterID.Data().fId)) {
677         HLTError("cluster index 0x%08x out of slice %d partition %d", clusterID.Data().fId, slice, part);
678       }
679       int index=AliHLTTPCSpacePointData::GetNumber(clusterID.Data().fId);
680       const AliHLTTPCHWCFData::iterator& input=pDecoder->find(index);
681       if (!(input!=pDecoder->end())) continue;
682       int padrow=input.GetPadRow();
683       if (padrow<0) {
684         // something wrong here, padrow is stored in the cluster header
685         // word which has bit pattern 0x3 in bits bit 30 and 31 which was
686         // not recognized
687         ALIHLTERRORGUARD(1, "can not read cluster header word");
688         iResult=-EBADF;
689         break;
690       }
691
692       float pad =input.GetPad();
693       float time =input.GetTime();
694       float sigmaY2=input.GetSigmaY2();
695       float sigmaZ2=input.GetSigmaZ2();
696
697       if (!pDeflater) {
698         AliHLTTPCRawCluster& c=blockout->fClusters[blockout->fCount];
699         padrow+=AliHLTTPCTransform::GetFirstRow(part);
700         c.SetPadRow(padrow);
701         c.SetCharge(input.GetCharge());
702         c.SetPad(pad);  
703         c.SetTime(time);
704         c.SetSigmaY2(sigmaY2);
705         c.SetSigmaZ2(sigmaZ2);
706         c.SetQMax(input.GetQMax());
707       } else {
708         AliHLTUInt64_t padrow64=input.GetPadRow();
709         if (padrow64==lastPadRow) {
710           padrow64-=lastPadRow;
711         } else if (padrow64>lastPadRow) {
712           padrow64-=lastPadRow;
713           lastPadRow+=padrow64;
714         } else {
715           AliFatal("padrows not ordered");
716         }
717
718         AliHLTUInt64_t pad64=0;
719         if (!isnan(pad)) pad64=(AliHLTUInt64_t)round(pad*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kPad].fScale);
720         AliHLTUInt64_t time64=0;
721         if (!isnan(time)) time64=(AliHLTUInt64_t)round(time*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kTime].fScale);
722         AliHLTUInt64_t sigmaY264=0;
723         if (!isnan(sigmaY2)) sigmaY264=(AliHLTUInt64_t)round(sigmaY2*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaY2].fScale);
724         AliHLTUInt64_t sigmaZ264=0;
725         if (!isnan(sigmaZ2)) sigmaZ264=(AliHLTUInt64_t)round(sigmaZ2*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaZ2].fScale);
726         pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kPadRow , padrow64);
727         pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kPad    , pad64);  
728         pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kTime   , time64);
729         pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kSigmaY2, sigmaY264);
730         pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kSigmaZ2, sigmaZ264);
731         pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kCharge , input.GetCharge());
732         pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kQMax   , input.GetQMax());
733       }
734       blockout->fCount++;
735     }
736   }
737   AliHLTComponent_BlockData bd;
738   AliHLTComponent::FillBlockData(bd);
739   bd.fOffset        = size+offset;
740   if (!pDeflater) {
741     bd.fSize        = sizeof(AliHLTTPCRawClusterData)+blockout->fCount*sizeof(AliHLTTPCRawCluster);
742     bd.fDataType    = AliHLTTPCDefinitions::fgkRawClustersDataType;
743   } else {
744     pDeflater->Pad8Bits();
745     bd.fSize        = sizeof(AliHLTTPCRawClusterData)+pDeflater->GetBitDataOutputSizeBytes();
746     pDeflater->CloseBitDataOutput();
747     bd.fDataType    = AliHLTTPCDefinitions::RemainingClustersCompressedDataType();
748   }
749   bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(slice, slice, part, part);
750   outputBlocks.push_back(bd);
751       
752   size += bd.fSize;
753
754   if (iResult<0) return iResult;
755   return size;
756 }
757
758 AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties::AliHLTTPCHWCFSpacePointProperties()
759   : fDecoder(NULL)
760   , fIndex(-1)
761   , fUsed(false)
762   , fTrackId(-1)
763   , fMCId(-1)
764 {
765   // constructor
766 }
767
768 AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties::AliHLTTPCHWCFSpacePointProperties(const AliHLTTPCHWCFData* pDecoder, int index)
769   : fDecoder(pDecoder)
770   , fIndex(index)
771   , fUsed(false)
772   , fTrackId(-1)
773   , fMCId(-1)
774 {
775   // constructor
776 }
777
778 AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties::AliHLTTPCHWCFSpacePointProperties(const AliHLTTPCHWCFSpacePointProperties& src)
779   : fDecoder(src.fDecoder)
780   , fIndex(src.fIndex)
781   , fUsed(src.fUsed)
782   , fTrackId(src.fTrackId)
783   , fMCId(src.fMCId)
784 {
785   // copy constructor
786 }
787
788 AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties& AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties::operator=(const AliHLTTPCHWCFSpacePointProperties& src)
789 {
790   // assignment operator
791   if (&src==this) return *this;
792   fDecoder=src.fDecoder;
793   fIndex=src.fIndex;
794   fUsed=src.fUsed;
795   fTrackId=src.fTrackId;
796   fMCId=src.fMCId;
797
798   return *this;
799 }
800
801 void AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties::Print(ostream& out, Option_t */*option*/) const
802 {
803   // print info
804   if (!Decoder()) {
805     out << "no data";
806     return;
807   }
808   std::stringstream str;
809   const AliHLTTPCHWCFData* decoder=Decoder();
810   str.setf(ios::fixed,ios::floatfield);
811   str << " " << setfill(' ') << setw(3) << decoder->GetPadRow(fIndex) 
812       << " " << setw(8) << setprecision(3) << decoder->GetPad(fIndex)
813       << " " << setw(8) << setprecision(3) << decoder->GetTime(fIndex)
814       << " " << setw(8) << setprecision(1) << decoder->GetSigmaY2(fIndex) 
815       << " " << setw(9) << setprecision(1) << decoder->GetSigmaZ2(fIndex)
816       << " " << setw(5) << decoder->GetCharge(fIndex) 
817       << " " << setw(5) << decoder->GetQMax(fIndex)
818       << " " << fTrackId << " " << fMCId << " " << fUsed;
819   out << str;
820 }
821
822 ostream& operator<<(ostream &out, const AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties& p)
823 {
824   p.Print(out);
825   return out;
826 }