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