Line data Source code
1 : // $Id$
2 : //****************************************************************************
3 : //* This file is property of and copyright by the ALICE HLT Project *
4 : //* ALICE Experiment at CERN, All rights reserved. *
5 : //* *
6 : //* Primary Authors: Sergey Gorbunov, Torsten Alt *
7 : //* Developers: Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de> *
8 : //* Torsten Alt <talt@cern.ch> *
9 : //* for The ALICE HLT Project. *
10 : //* *
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 : //****************************************************************************
19 :
20 : // @file AliHLTTPCHWCFMergerUnit.cxx
21 : // @author Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de>
22 : // @author Torsten Alt <talt@cern.ch>
23 : // @date
24 : // @brief Channel Merger unit of FPGA ClusterFinder Emulator for TPC
25 : // @brief ( see AliHLTTPCHWCFEmulator class )
26 : // @note
27 :
28 : #include "AliHLTTPCHWCFMergerUnit.h"
29 : #include <iostream>
30 :
31 24819 : AliHLTTPCHWCFMergerUnit::AliHLTTPCHWCFMergerUnit()
32 : :
33 6 : fDebug(0),
34 3 : fMatchDistance(0),
35 3 : fMatchTimeFollow(0),
36 3 : fDeconvolute(0),
37 3 : fByPassMerger(0),
38 3 : fInput()
39 6 : {
40 : //constructor
41 3 : Init();
42 6 : }
43 :
44 :
45 : AliHLTTPCHWCFMergerUnit::~AliHLTTPCHWCFMergerUnit()
46 6 : {
47 : //destructor
48 12420 : }
49 :
50 0 : AliHLTTPCHWCFMergerUnit::AliHLTTPCHWCFMergerUnit(const AliHLTTPCHWCFMergerUnit&)
51 : :
52 0 : fDebug(0),
53 0 : fMatchDistance(0),
54 0 : fMatchTimeFollow(0),
55 0 : fDeconvolute(0),
56 0 : fByPassMerger(0),
57 0 : fInput()
58 0 : {
59 : // dummy
60 0 : Init();
61 0 : }
62 :
63 : AliHLTTPCHWCFMergerUnit& AliHLTTPCHWCFMergerUnit::operator=(const AliHLTTPCHWCFMergerUnit&)
64 : {
65 : // dummy
66 0 : return *this;
67 : }
68 :
69 : int AliHLTTPCHWCFMergerUnit::Init()
70 : {
71 : // initialise
72 :
73 6 : fInput.fFlag = 0;
74 18 : for( int i=0; i<2; i++ ){
75 6 : fSearchRange[i] = fMemory[i];
76 6 : fInsertRange[i] = (fMemory[i]+AliHLTTPCHWCFDefinitions::kMaxNTimeBins);
77 6 : fSearchStart[i] = 0;
78 6 : fSearchEnd[i] = 0;
79 6 : fInsertEnd[i] = 0;
80 6 : fInsertRow[i] = -1;
81 6 : fInsertPad[i] = -1;
82 : }
83 3 : return 0;
84 : }
85 :
86 : int AliHLTTPCHWCFMergerUnit::InputStream( const AliHLTTPCHWCFClusterFragment *fragment )
87 : {
88 : // input stream of data
89 :
90 0 : fInput.fFlag = 0;
91 :
92 0 : if( fragment ){
93 0 : fInput = *fragment;
94 0 : fInput.fSlope = 0;
95 0 : fInput.fLastQ = fInput.fQ;
96 0 : if( fDebug ){
97 0 : std::cout<<"Merger: input Br: "<<fragment->fBranch<<" F: "<<fragment->fFlag<<" R: "<<fragment->fRow
98 0 : <<" Q: "<<(fragment->fQ>>AliHLTTPCHWCFDefinitions::kFixedPoint)
99 0 : <<" P: "<<fragment->fPad<<" Tmean: "<<fragment->fTMean;
100 0 : if( fragment->fFlag==1 && fragment->fQ > 0 ){
101 0 : std::cout<<" Pw: "<<((float)fragment->fP)/fragment->fQ
102 0 : <<" Tw: "<<((float)fragment->fT)/fragment->fQ;
103 0 : std::cout<<" MC: ";
104 0 : for( unsigned int j=0; j<fragment->fMC.size(); j++ ){
105 0 : for( int k=0; k<3; k++ ){
106 0 : std::cout<<"("<<fragment->fMC[j].fClusterID[k].fMCID<<" "<<fragment->fMC[j].fClusterID[k].fWeight<<") ";
107 : }
108 : }
109 0 : std::cout<<std::endl;
110 0 : }
111 0 : else std::cout<<std::endl;
112 : }
113 : }
114 0 : return 0;
115 : }
116 :
117 : const AliHLTTPCHWCFClusterFragment *AliHLTTPCHWCFMergerUnit::OutputStream()
118 : {
119 : // output stream of data
120 :
121 0 : if( fInput.fFlag==0 ) return 0;
122 :
123 0 : if( fByPassMerger ){
124 0 : fInsertRange[0][0] = fInput;
125 0 : fInput.fFlag = 0;
126 0 : return &fInsertRange[0][0];
127 : }
128 :
129 0 : if( fInput.fFlag!=1 ){
130 :
131 0 : for( int ib=0; ib<2; ib++){
132 :
133 : // move insert range to search range
134 :
135 0 : if( fSearchStart[ib]>=fSearchEnd[ib] && fInsertEnd[ib]>0 ){
136 0 : AliHLTTPCHWCFClusterFragment *tmp = fSearchRange[ib];
137 0 : fSearchRange[ib] = fInsertRange[ib];
138 0 : fSearchStart[ib] = 0;
139 0 : fSearchEnd[ib] = fInsertEnd[ib];
140 0 : fInsertRange[ib] = tmp;
141 0 : fInsertEnd[ib] = 0;
142 0 : fInsertPad[ib]++;
143 0 : }
144 :
145 : // flush the search range
146 :
147 0 : if( fSearchStart[ib]<fSearchEnd[ib] ){
148 0 : fSearchStart[ib]++;
149 0 : return &(fSearchRange[ib][fSearchStart[ib]-1]);
150 : }
151 :
152 0 : fInsertRow[ib] = -1;
153 0 : fInsertPad[ib] = -1;
154 : }
155 :
156 0 : fInsertRange[0][0] = fInput; // forward the input
157 0 : fInput.fFlag = 0;
158 0 : return &fInsertRange[0][0];
159 : }
160 :
161 0 : if( fInput.fFlag!=1 ) return 0; // should not happen
162 :
163 0 : int ib = fInput.fBranch;
164 :
165 : // move insert range to search range
166 :
167 0 : if( (int)fInput.fRow!=fInsertRow[ib] || (int)fInput.fPad!=fInsertPad[ib] ){
168 :
169 0 : if( fSearchStart[ib]>=fSearchEnd[ib] && fInsertEnd[ib]>0 ){
170 : // cout<<"move insert range pad "<<fInsertPad[ib]<<endl;
171 0 : AliHLTTPCHWCFClusterFragment *tmp = fSearchRange[ib];
172 0 : fSearchRange[ib] = fInsertRange[ib];
173 0 : fSearchStart[ib] = 0;
174 0 : fSearchEnd[ib] = fInsertEnd[ib];
175 0 : fInsertRange[ib] = tmp;
176 0 : fInsertEnd[ib] = 0;
177 0 : fInsertPad[ib]++;
178 0 : }
179 : }
180 :
181 : // flush the search range
182 :
183 0 : if( (int)fInput.fRow!=fInsertRow[ib] || (int)fInput.fPad!=fInsertPad[ib] ){
184 0 : if( fSearchStart[ib]<fSearchEnd[ib] ){
185 : //cout<<"push from search range at "<<fSearchStart[ib]<<" of "<<fSearchEnd[ib]<<endl;
186 0 : fSearchStart[ib]++;
187 0 : return &(fSearchRange[ib][fSearchStart[ib]-1]);
188 : }
189 : }
190 :
191 0 : fInsertRow[ib] = fInput.fRow;
192 0 : fInsertPad[ib] = fInput.fPad;
193 :
194 : // flush the search range
195 :
196 0 : if( fSearchStart[ib]<fSearchEnd[ib] && fSearchRange[ib][fSearchStart[ib]].fTMean>=fInput.fTMean+fMatchDistance
197 : ){
198 : //cout<<"push from search range at "<<fSearchStart[ib]<<" of "<<fSearchEnd[ib]<<endl;
199 0 : fSearchStart[ib]++;
200 0 : return &(fSearchRange[ib][fSearchStart[ib]-1]);
201 : }
202 :
203 : // merge
204 :
205 : AliHLTTPCHWCFClusterFragment *ret = 0;
206 :
207 0 : if( fSearchStart[ib]<fSearchEnd[ib] && fSearchRange[ib][fSearchStart[ib]].fTMean+fMatchDistance>fInput.fTMean ){
208 0 : AliHLTTPCHWCFClusterFragment &s = fSearchRange[ib][fSearchStart[ib]++];
209 0 : if( fDeconvolute && s.fSlope && s.fLastQ<fInput.fLastQ ){
210 : //cout<<"push from search range at "<<fSearchStart[ib]-1<<" of "<<fSearchEnd[ib]<<endl;
211 : // deconvolution in pad direction, mark both clusters
212 0 : s.fIsDeconvolutedPad = 1;
213 0 : fInput.fIsDeconvolutedPad = 1;
214 : ret = &s;
215 0 : } else {
216 : // cout<<"merge search range at "<<fSearchStart-1<<" of "<<fSearchEnd<<endl;
217 0 : fInput.fSlope = s.fSlope;
218 0 : if( !fInput.fSlope && s.fLastQ > fInput.fQ ) fInput.fSlope = 1;
219 0 : if (fInput.fQmax < s.fQmax) fInput.fQmax = s.fQmax;
220 0 : fInput.fNPads += s.fNPads;
221 0 : if( s.fConsecutiveTimeDeconvolution == 2 ) fInput.fConsecutiveTimeDeconvolution = 2;
222 0 : else if( s.fConsecutiveTimeDeconvolution > 0 && fInput.fConsecutiveTimeDeconvolution ==1 ) fInput.fConsecutiveTimeDeconvolution=s.fConsecutiveTimeDeconvolution+1;
223 :
224 0 : fInput.fNDeconvolutedTime += s.fNDeconvolutedTime; // count N deconvoluted 1-d fragments
225 0 : fInput.fQ += s.fQ;
226 0 : fInput.fT += s.fT;
227 0 : fInput.fT2 += s.fT2;
228 0 : fInput.fP += s.fP;
229 0 : fInput.fP2 += s.fP2;
230 0 : fInput.fMC.insert(fInput.fMC.end(), s.fMC.begin(), s.fMC.end());
231 0 : if( !fMatchTimeFollow ) fInput.fTMean = s.fTMean;
232 : ret = 0;
233 : }
234 0 : }
235 :
236 : // insert
237 :
238 0 : fInsertRange[ib][fInsertEnd[ib]++] = fInput;
239 0 : fInput.fFlag = 0;
240 : return ret;
241 0 : }
|