3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /// @file AliHLTTPCRawSpacePointContainer.h
20 /// @author Matthias Richter
22 /// @brief Helper class for handling of HLT TPC space point data blocks
25 #include "AliHLTTPCRawSpacePointContainer.h"
26 #include "AliHLTTPCRawCluster.h"
27 #include "AliHLTTPCDefinitions.h"
28 #include "AliHLTTPCSpacePointData.h"
29 #include "AliHLTTPCTransform.h"
30 #include "AliHLTComponent.h"
31 #include "AliHLTTemplates.h"
32 #include "AliHLTErrorGuard.h"
37 /** ROOT macro for the implementation of ROOT specific class methods */
38 ClassImp(AliHLTTPCRawSpacePointContainer)
40 AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointContainer()
41 : AliHLTSpacePointContainer()
45 // see header file for class documentation
47 // refer to README to build package
49 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
52 AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointContainer(const AliHLTTPCRawSpacePointContainer& c)
53 : AliHLTSpacePointContainer(c)
54 , fClusters(c.fClusters.begin(), c.fClusters.end())
60 AliHLTTPCRawSpacePointContainer& AliHLTTPCRawSpacePointContainer::operator=(const AliHLTTPCRawSpacePointContainer& c)
62 /// assignment operator
63 if (&c==this) return *this;
64 AliHLTSpacePointContainer::operator=(c);
65 fClusters=c.fClusters;
70 AliHLTTPCRawSpacePointContainer::~AliHLTTPCRawSpacePointContainer()
76 int AliHLTTPCRawSpacePointContainer::AddInputBlock(const AliHLTComponentBlockData* pDesc)
78 // add input block to the collection
79 if (!pDesc) return -EINVAL;
81 if (pDesc->fDataType!=AliHLTTPCDefinitions::fgkRawClustersDataType) {
82 HLTWarning("ignoring data block of type %s", AliHLTComponent::DataType2Text(pDesc->fDataType).c_str());
85 if (!pDesc->fPtr || pDesc->fSize<sizeof(AliHLTTPCRawClusterData)) return -ENODATA;
87 // consistency check of the input block
88 const AliHLTTPCRawClusterData* pClusterData=reinterpret_cast<AliHLTTPCRawClusterData*>(pDesc->fPtr);
89 if (pClusterData->fCount*sizeof(AliHLTTPCRawCluster)+sizeof(AliHLTTPCRawClusterData)!=pDesc->fSize) {
90 HLTError("data block of type %s corrupted: number of entries %d is not consistent with block size %d",
91 AliHLTComponent::DataType2Text(pDesc->fDataType).c_str(), pClusterData->fCount, pDesc->fSize);
95 AliHLTUInt8_t minslice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
96 //AliHLTUInt8_t maxslice = AliHLTTPCDefinitions::GetMaxSliceNr( pDesc->fSpecification );
97 AliHLTUInt8_t minpart = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
98 //AliHLTUInt8_t maxpart = AliHLTTPCDefinitions::GetMaxPatchNr( pDesc->fSpecification );
99 //bool bIsSinglePartition=(pDesc->fSpecification==kAliHLTVoidDataSpec?false:minslice==maxslice && minpart==maxpart);
101 for (UInt_t i=0; i<pClusterData->fCount; i++) {
102 AliHLTUInt32_t clusterID=~(AliHLTUInt32_t)0;
103 // cluster ID from slice, partition and index
104 clusterID=AliHLTTPCSpacePointData::GetID(minslice, minpart, i);
106 if (fClusters.find(clusterID)==fClusters.end()) {
108 fClusters[clusterID]=AliHLTTPCRawSpacePointProperties(&pClusterData->fClusters[i]);
111 HLTError("cluster with ID 0x%08x already existing, skipping cluster %d of data block 0x%08x",
112 clusterID, i, pDesc->fSpecification);
119 int AliHLTTPCRawSpacePointContainer::GetClusterIDs(vector<AliHLTUInt32_t>& tgt) const
121 // get array of cluster IDs
123 transform(fClusters.begin(), fClusters.end(), back_inserter(tgt), HLT::AliGetKey());
127 bool AliHLTTPCRawSpacePointContainer::Check(AliHLTUInt32_t clusterID) const
129 // check if the cluster is available
130 return fClusters.find(clusterID)!=fClusters.end();
133 const vector<AliHLTUInt32_t>* AliHLTTPCRawSpacePointContainer::GetClusterIDs(AliHLTUInt32_t mask)
135 // get array of cluster IDs filtered by mask
136 if (fSelections.find(mask)!=fSelections.end()) {
137 // return existing selection
138 return fSelections.find(mask)->second;
140 // create new collection
141 vector<AliHLTUInt32_t>* selected=new vector<AliHLTUInt32_t>;
142 if (!selected) return NULL;
143 UInt_t slice=AliHLTTPCSpacePointData::GetSlice(mask);
144 UInt_t partition=AliHLTTPCSpacePointData::GetPatch(mask);
145 //HLTInfo("creating collection 0x%08x", mask);
147 // the first cluster with number 0 has equal ID to mask unless
148 // the mask selects multiple partitions/slices
149 std::map<AliHLTUInt32_t, AliHLTTPCRawSpacePointProperties>::const_iterator cl=fClusters.find(mask);
151 if (slice>=(unsigned)AliHLTTPCTransform::GetNSlice() ||
152 partition>=(unsigned)AliHLTTPCTransform::GetNumberOfPatches()) {
153 cl=fClusters.begin();
156 for (; cl!=fClusters.end(); cl++) {
157 UInt_t s=AliHLTTPCSpacePointData::GetSlice(cl->first);
158 UInt_t p=AliHLTTPCSpacePointData::GetPatch(cl->first);
159 if ((slice>=(unsigned)AliHLTTPCTransform::GetNSlice() || s==slice) &&
160 (partition>=(unsigned)AliHLTTPCTransform::GetNumberOfPatches() || p==partition)) {
161 selected->push_back(cl->first);
163 // no need to continue, we are out of the range
167 //HLTInfo("collection 0x%08x with %d spacepoints", mask, selected->size());
168 fSelections[mask]=selected;
172 float AliHLTTPCRawSpacePointContainer::GetX(AliHLTUInt32_t clusterID) const
175 if (fClusters.find(clusterID)==fClusters.end() ||
176 fClusters.find(clusterID)->second.Data()==NULL) return 0.0;
177 // FIXME: understand deviation from the nominal x value
178 // there is a small deviation in the x coordinate - padrow number correlation
179 // in principle, the clusterfinder only uses the mapping to set the x parameter.
180 // now extracting the x value from the padrow no.
181 //return fClusters.find(clusterID)->second.Data()->fX;
182 return AliHLTTPCTransform::Row2X(fClusters.find(clusterID)->second.Data()->fPadRow);
185 float AliHLTTPCRawSpacePointContainer::GetXWidth(AliHLTUInt32_t clusterID) const
187 // get error for X coordinate
188 if (fClusters.find(clusterID)==fClusters.end() ||
189 fClusters.find(clusterID)->second.Data()==NULL) return 0.0;
190 return 0.0; // fixed in padrow number
193 float AliHLTTPCRawSpacePointContainer::GetY(AliHLTUInt32_t clusterID) const
196 if (fClusters.find(clusterID)==fClusters.end() ||
197 fClusters.find(clusterID)->second.Data()==NULL) return 0.0;
198 return fClusters.find(clusterID)->second.Data()->GetPad();
201 float AliHLTTPCRawSpacePointContainer::GetYWidth(AliHLTUInt32_t clusterID) const
203 // get error for Y coordinate
204 if (fClusters.find(clusterID)==fClusters.end() ||
205 fClusters.find(clusterID)->second.Data()==NULL) return 0.0;
206 return fClusters.find(clusterID)->second.Data()->GetSigmaY2();
209 float AliHLTTPCRawSpacePointContainer::GetZ(AliHLTUInt32_t clusterID) const
212 if (fClusters.find(clusterID)==fClusters.end() ||
213 fClusters.find(clusterID)->second.Data()==NULL) return 0.0;
214 return fClusters.find(clusterID)->second.Data()->GetTime();
217 float AliHLTTPCRawSpacePointContainer::GetZWidth(AliHLTUInt32_t clusterID) const
219 // get error for Z coordinate
220 if (fClusters.find(clusterID)==fClusters.end() ||
221 fClusters.find(clusterID)->second.Data()==NULL) return 0.0;
222 return fClusters.find(clusterID)->second.Data()->GetSigmaZ2();
225 float AliHLTTPCRawSpacePointContainer::GetCharge(AliHLTUInt32_t clusterID) const
228 if (fClusters.find(clusterID)==fClusters.end() ||
229 fClusters.find(clusterID)->second.Data()==NULL) return 0.0;
230 return fClusters.find(clusterID)->second.Data()->GetCharge();
233 float AliHLTTPCRawSpacePointContainer::GetMaxSignal(AliHLTUInt32_t clusterID) const
236 if (fClusters.find(clusterID)==fClusters.end() ||
237 fClusters.find(clusterID)->second.Data()==NULL) return 0.0;
238 return fClusters.find(clusterID)->second.Data()->GetQMax();
241 float AliHLTTPCRawSpacePointContainer::GetPhi(AliHLTUInt32_t clusterID) const
245 // phi can be derived directly from the id, no need to search
246 // for existing cluster
247 int slice=AliHLTTPCSpacePointData::GetSlice(clusterID);
248 return ( slice + 0.5 ) * TMath::Pi() / 9.0;
251 void AliHLTTPCRawSpacePointContainer::Clear(Option_t * option)
253 // clear the object and reset pointer references
256 for (std::map<AliHLTUInt32_t, vector<AliHLTUInt32_t>*>::iterator selection=fSelections.begin();
257 selection!=fSelections.end(); selection++) {
258 if (selection->second) delete selection->second;
262 AliHLTSpacePointContainer::Clear(option);
265 void AliHLTTPCRawSpacePointContainer::Print(ostream& out, Option_t */*option*/) const
268 out << "AliHLTTPCRawSpacePointContainer::Print" << endl;
269 out << "n clusters: " << fClusters.size() << endl;
270 for (std::map<AliHLTUInt32_t, AliHLTTPCRawSpacePointProperties>::const_iterator cl=fClusters.begin();
271 cl!=fClusters.end(); cl++) {
272 out << " " << cl->first << cl->second << endl;
276 AliHLTSpacePointContainer* AliHLTTPCRawSpacePointContainer::SelectByMask(AliHLTUInt32_t mask, bool /*bAlloc*/) const
278 /// create a collection of clusters for a space point mask
279 std::auto_ptr<AliHLTTPCRawSpacePointContainer> c(new AliHLTTPCRawSpacePointContainer);
280 if (!c.get()) return NULL;
282 UInt_t slice=AliHLTTPCSpacePointData::GetSlice(mask);
283 UInt_t partition=AliHLTTPCSpacePointData::GetPatch(mask);
284 for (std::map<AliHLTUInt32_t, AliHLTTPCRawSpacePointProperties>::const_iterator cl=fClusters.begin();
285 cl!=fClusters.end(); cl++) {
286 UInt_t s=AliHLTTPCSpacePointData::GetSlice(cl->first);
287 UInt_t p=AliHLTTPCSpacePointData::GetPatch(cl->first);
288 if ((slice>=(unsigned)AliHLTTPCTransform::GetNSlice() || s==slice) &&
289 (partition>=(unsigned)AliHLTTPCTransform::GetNumberOfPatches() || p==partition)) {
290 c->fClusters[cl->first]=cl->second;
296 AliHLTSpacePointContainer* AliHLTTPCRawSpacePointContainer::SelectByTrack(int trackId, bool /*bAlloc*/) const
298 /// create a collection of clusters for a specific track
299 std::auto_ptr<AliHLTTPCRawSpacePointContainer> c(new AliHLTTPCRawSpacePointContainer);
300 if (!c.get()) return NULL;
302 HLT::copy_map_if(fClusters.begin(), fClusters.end(), c->fClusters, HLT::AliHLTUnaryPredicate<AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties, int>(&AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties::GetTrackId,trackId));
306 AliHLTSpacePointContainer* AliHLTTPCRawSpacePointContainer::SelectByMC(int mcId, bool /*bAlloc*/) const
308 /// create a collection of clusters for a specific MC track
309 std::auto_ptr<AliHLTTPCRawSpacePointContainer> c(new AliHLTTPCRawSpacePointContainer);
310 if (!c.get()) return NULL;
312 HLT::copy_map_if(fClusters.begin(), fClusters.end(), c->fClusters, HLT::AliHLTUnaryPredicate<AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties, int>(&AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties::GetMCId,mcId));
316 AliHLTSpacePointContainer* AliHLTTPCRawSpacePointContainer::UsedClusters(bool /*bAlloc*/) const
318 /// create a collection of all used clusters
319 std::auto_ptr<AliHLTTPCRawSpacePointContainer> c(new AliHLTTPCRawSpacePointContainer);
320 if (!c.get()) return NULL;
322 HLT::copy_map_if(fClusters.begin(), fClusters.end(), c->fClusters, HLT::AliHLTUnaryPredicate<AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties, bool>(&AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties::IsUsed,true));
326 AliHLTSpacePointContainer* AliHLTTPCRawSpacePointContainer::UnusedClusters(bool /*bAlloc*/) const
328 /// create a collection of all unused clusters
329 std::auto_ptr<AliHLTTPCRawSpacePointContainer> c(new AliHLTTPCRawSpacePointContainer);
330 if (!c.get()) return NULL;
332 HLT::copy_map_if(fClusters.begin(), fClusters.end(), c->fClusters, HLT::AliHLTUnaryPredicate<AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties, bool>(&AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties::IsUsed,false));
336 int AliHLTTPCRawSpacePointContainer::MarkUsed(const AliHLTUInt32_t* clusterIDs, int arraySize)
338 /// mark the clusters with specified IDs as used
339 if (!clusterIDs) return -EINVAL;
341 for (int i=0; i<arraySize; i++) {
342 if (fClusters.find(clusterIDs[i])==fClusters.end()) continue;
343 fClusters[clusterIDs[i]].MarkUsed();
349 int AliHLTTPCRawSpacePointContainer::SetTrackID(int trackID, const AliHLTUInt32_t* clusterIDs, int arraySize)
351 /// set track id for specified clusters
352 if (!clusterIDs) return -EINVAL;
354 for (int i=0; i<arraySize; i++) {
355 if (fClusters.find(clusterIDs[i])==fClusters.end()) continue;
356 fClusters[clusterIDs[i]].SetTrackId(trackID);
362 int AliHLTTPCRawSpacePointContainer::GetTrackID(AliHLTUInt32_t clusterID) const
364 /// get track id for specified cluster
365 map<AliHLTUInt32_t, AliHLTTPCRawSpacePointProperties>::const_iterator element=fClusters.find(clusterID);
366 if (element==fClusters.end()) return -1;
367 return element->second.GetTrackId();
370 int AliHLTTPCRawSpacePointContainer::SetMCID(int mcID, const AliHLTUInt32_t* clusterIDs, int arraySize)
372 /// set mc id for specified clusters
373 if (!clusterIDs) return -EINVAL;
375 for (int i=0; i<arraySize; i++) {
376 if (fClusters.find(clusterIDs[i])==fClusters.end()) continue;
377 fClusters[clusterIDs[i]].SetMCId(mcID);
383 int AliHLTTPCRawSpacePointContainer::Write(AliHLTUInt8_t* outputPtr, AliHLTUInt32_t size, AliHLTComponentBlockDataList& outputBlocks, const char* /*option*/) const
385 /// write blocks to HLT component output
386 if (!outputPtr) return -EINVAL;
388 AliHLTUInt32_t capacity=size;
391 for (int slice=0; slice<AliHLTTPCTransform::GetNSlice() && iResult>=0; slice++) {
392 for (int part=0; part<AliHLTTPCTransform::GetNPatches() && iResult>=0; part++) {
393 AliHLTUInt32_t mask=AliHLTTPCSpacePointData::GetID(slice,part,0);
394 // FIXME: make GetClusterIDs a const function and handle the cast there
395 const vector<AliHLTUInt32_t>* collection=const_cast<AliHLTTPCRawSpacePointContainer*>(this)->GetClusterIDs(mask);
396 if (!collection) continue;
397 if (size+sizeof(AliHLTTPCRawClusterData)+collection->size()*sizeof(AliHLTTPCRawCluster)>capacity) {
398 ALIHLTERRORGUARD(1,"too little space to write cluster output block");
402 AliHLTTPCRawClusterData* blockout=reinterpret_cast<AliHLTTPCRawClusterData*>(outputPtr+size);
403 blockout->fVersion=0;
405 vector<AliHLTUInt32_t>::const_iterator clusterID=collection->begin();
406 if (clusterID!=collection->end()) {
407 std::map<AliHLTUInt32_t, AliHLTTPCRawSpacePointProperties>::const_iterator cl=fClusters.find(*clusterID);
408 for (; clusterID!=collection->end(); clusterID++, (cl!=fClusters.end())?cl++:cl) {
409 if (cl!=fClusters.end() && cl->first!=*clusterID) cl=fClusters.find(*clusterID);
410 if (cl==fClusters.end() || cl->second.Data()==NULL) continue;
411 AliHLTTPCRawCluster& c=blockout->fClusters[blockout->fCount];
412 int padrow=cl->second.Data()->GetPadRow();
413 padrow+=AliHLTTPCTransform::GetFirstRow(part);
415 c.SetCharge(cl->second.Data()->GetCharge());
416 float pad =cl->second.Data()->GetPad();
417 float time =cl->second.Data()->GetTime();
418 float sigmaY2=cl->second.Data()->GetSigmaY2();
419 float sigmaZ2=cl->second.Data()->GetSigmaZ2();
424 c.SetSigmaY2(sigmaY2);
425 c.SetSigmaZ2(sigmaZ2);
426 c.SetQMax(cl->second.Data()->GetQMax());
430 AliHLTComponent_BlockData bd;
431 AliHLTComponent::FillBlockData(bd);
433 bd.fSize = sizeof(AliHLTTPCRawClusterData)+blockout->fCount*sizeof(AliHLTTPCRawCluster);
434 bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(slice, slice, part, part);
435 bd.fDataType = AliHLTTPCDefinitions::fgkRawClustersDataType;
436 outputBlocks.push_back(bd);
442 if (iResult<0) return iResult;
446 AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties::AliHLTTPCRawSpacePointProperties()
455 AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties::AliHLTTPCRawSpacePointProperties(const AliHLTTPCRawCluster* pCluster)
464 AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties::AliHLTTPCRawSpacePointProperties(const AliHLTTPCRawSpacePointProperties& src)
465 : fCluster(src.fCluster)
467 , fTrackId(src.fTrackId)
473 AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties& AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties::operator=(const AliHLTTPCRawSpacePointProperties& src)
475 // assignment operator
476 if (&src==this) return *this;
477 fCluster=src.fCluster;
479 fTrackId=src.fTrackId;
485 void AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties::Print(ostream& out, Option_t */*option*/) const
492 const AliHLTTPCRawCluster* data=Data();
493 out << " " << data->GetPadRow() << " " << data->GetPad() << " " << data->GetTime()
494 << " " << data->GetSigmaY2() << " " << data->GetSigmaZ2()
495 << " " << data->GetCharge() << " " << data->GetQMax()
496 << " " << fTrackId << " " << fMCId << " " << fUsed;
499 ostream& operator<<(ostream &out, const AliHLTTPCRawSpacePointContainer::AliHLTTPCRawSpacePointProperties& p)