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