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