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