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