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> *
9 //* for The ALICE HLT Project. *
11 //* Permission to use, copy, modify and distribute this software and its *
12 //* documentation strictly for non-commercial purposes is hereby granted *
13 //* without fee, provided that the above copyright notice appears in all *
14 //* copies and that both the copyright notice and this permission notice *
15 //* appear in the supporting documentation. The authors make no claims *
16 //* about the suitability of this software for any purpose. It is *
17 //* provided "as is" without express or implied warranty. *
18 //**************************************************************************
20 // @file AliHLTTPCHWClusterMerger.cxx
21 // @author Matthias Richter, Sergey Gorbunov
23 // @brief Merger class for HLT TPC Hardware clusters
24 // Handles merging of branch border clusters
26 #include "AliHLTTPCHWClusterMerger.h"
27 #include "AliHLTTPCTransform.h"
28 #include "AliHLTTPCSpacePointData.h"
30 /** ROOT macro for the implementation of ROOT specific class methods */
31 ClassImp(AliHLTTPCHWClusterMerger)
33 const int gkIndexGridTimeStep=10;
34 AliHLTTPCHWClusterMerger::AliHLTTPCHWClusterMerger()
37 , fRemovedClusterIds()
38 , fIndex(AliHLTTPCTransform::GetNSlice(), 1,
39 AliHLTTPCTransform::GetNRows(), 1,
40 AliHLTTPCTransform::GetNTimeBins(), gkIndexGridTimeStep)
44 // see header file for class documentation
46 // refer to README to build package
48 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
52 AliHLTTPCHWClusterMerger::~AliHLTTPCHWClusterMerger()
57 bool AliHLTTPCHWClusterMerger::CheckCandidate(int /*slice*/, int partition, int partitionrow, float pad, float /*time*/) const
59 /// check cluster if it is a candidate for merging
60 int slicerow=partitionrow+AliHLTTPCTransform::GetFirstRow(partition);
62 // FIXME: implement the logic here
63 if (TMath::Abs(pad-AliHLTTPCTransform::GetNPads(slicerow)/2)<2) {
69 int AliHLTTPCHWClusterMerger::AddCandidate(int slice,
76 unsigned short charge,
81 /// add a candidate for merging and register in the index grid
82 int slicerow=partitionrow+AliHLTTPCTransform::GetFirstRow(partition);
83 if (id!=~AliHLTUInt32_t(0)) {
85 slice=AliHLTTPCSpacePointData::GetSlice(id);
86 } else if ((unsigned)slice!=AliHLTTPCSpacePointData::GetSlice(id)) {
87 HLTError("cluster id 0x%08x is not consistent with specified slice %d", id, slice);
90 partition=AliHLTTPCSpacePointData::GetPatch(id);
91 } else if ((unsigned)partition!=AliHLTTPCSpacePointData::GetPatch(id)) {
92 HLTError("cluster id 0x%08x is not consistent with specified partition %d", id, partition);
95 fClusters.push_back(AliClusterRecord(slice, partition, id,
96 AliHLTTPCRawCluster(partitionrow, pad, time, sigmaY2, sigmaZ2, charge, qmax)));
97 fIndex.CountSpacePoint(slice, slicerow, (int)time);
99 return fClusters.size();
102 int AliHLTTPCHWClusterMerger::Merge()
105 /// first all candidates are filled into the index grid, looping over all clusters
106 /// in the grid automatically results in time ordered clusters per row (ordering with
107 /// respect to cells, within a cell two clusters can be reversed)
110 if ((iResult=FillIndex())<0) {
114 vector<int> cellClusters;
115 for (AliSortedClusters::iterator& cli=fIndex.begin();
116 cli!=fIndex.end(); cli++) {
117 if (cellClusters.size()==0) {
118 // no partner for merging, put this one on the stack and continue
119 cellClusters.push_back(*cli);
122 AliHLTTPCRawCluster c1=fClusters[*cli].GetCluster();
123 int slicerow1=c1.GetPadRow()+AliHLTTPCTransform::GetFirstRow(fClusters[*cli].GetPartition());
124 vector<int>::iterator partner=cellClusters.begin();
126 while (partner!=cellClusters.end()) {
127 AliHLTTPCRawCluster c2=fClusters[*partner].GetCluster();
128 int slicerow2=c2.GetPadRow()+AliHLTTPCTransform::GetFirstRow(fClusters[*partner].GetPartition());
129 if ((fClusters[*partner].GetSlice()!=fClusters[*cli].GetSlice()) ||
130 (slicerow2!=slicerow1) ||
131 (c2.GetTime()+gkIndexGridTimeStep<c1.GetTime())) {
132 // already out of range to be a partner for merging
133 // remove and go to next
134 partner=cellClusters.erase(partner);
138 // check if two clusters need to be merged
139 // FIXME: implement correct logic
140 // - clusters on different sides of the branch border
141 // - pad difference within limit
142 // - time difference within limit (specify limit, studies needed)
143 // - cluster shape using charge, qmax and sigma
144 // - single pad cluster on either one or the other side or on both
145 if (false && // the condition below was just for testing
146 TMath::Abs(c2.GetPad()-c1.GetPad())<2 &&
147 TMath::Abs(c2.GetTime()-c1.GetTime())<2) {
148 // merge c1 and c2 into c1
149 // FIXME: implement merging
155 fRemovedClusterIds.push_back(fClusters[*partner].GetId());
156 HLTDebug("merging %d into %d", *partner, *cli);
157 fClusters[*partner].Clear();
158 cellClusters.erase(partner);
166 // did not find any partner, put on stack
167 cellClusters.push_back(*cli);
170 if (iResult<0) return iResult;
174 int AliHLTTPCHWClusterMerger::FillIndex()
176 /// loop over cached raw clusters and fill index
177 for (AliHLTUInt32_t pos=0; pos<fClusters.size(); pos++) {
178 int slicerow=fClusters[pos].GetCluster().GetPadRow()+AliHLTTPCTransform::GetFirstRow(fClusters[pos].GetPartition());
179 fIndex.AddSpacePoint(pos, fClusters[pos].GetSlice(), slicerow, (int)fClusters[pos].GetCluster().GetTime());
184 void AliHLTTPCHWClusterMerger::Clear()
188 fRemovedClusterIds.clear();