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 AliHLTTPCHWCFProcessorUnit.cxx
21 : // @author Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de>
22 : // @author Torsten Alt <talt@cern.ch>
23 : // @date
24 : // @brief Channel Processor unit of FPGA ClusterFinder Emulator for TPC
25 : // @brief ( see AliHLTTPCHWCFEmulator class )
26 : // @note
27 :
28 : #include "AliHLTTPCHWCFProcessorUnit.h"
29 : #include <iostream>
30 : #include <cstdio>
31 :
32 :
33 : AliHLTTPCHWCFProcessorUnit::AliHLTTPCHWCFProcessorUnit()
34 : :
35 6 : fOutput(),
36 3 : fkBunch(0),
37 3 : fBunchIndex(0),
38 3 : fWasDeconvoluted(0),
39 3 : fDeconvolute(0),
40 3 : fSingleSeqLimit(0),
41 3 : fUseTimeBinWindow(0),
42 3 : fDebug(0)
43 6 : {
44 : //constructor
45 3 : Init();
46 6 : }
47 :
48 :
49 : AliHLTTPCHWCFProcessorUnit::~AliHLTTPCHWCFProcessorUnit()
50 6 : {
51 : //destructor
52 9 : }
53 :
54 : AliHLTTPCHWCFProcessorUnit::AliHLTTPCHWCFProcessorUnit(const AliHLTTPCHWCFProcessorUnit&)
55 : :
56 0 : fOutput(),
57 0 : fkBunch(0),
58 0 : fBunchIndex(0),
59 0 : fWasDeconvoluted(0),
60 0 : fDeconvolute(0),
61 0 : fSingleSeqLimit(0),
62 0 : fUseTimeBinWindow(0),
63 0 : fDebug(0)
64 0 : {
65 : // dummy
66 0 : Init();
67 0 : }
68 :
69 : AliHLTTPCHWCFProcessorUnit& AliHLTTPCHWCFProcessorUnit::operator=(const AliHLTTPCHWCFProcessorUnit&)
70 : {
71 : // dummy
72 0 : return *this;
73 : }
74 :
75 : int AliHLTTPCHWCFProcessorUnit::Init()
76 : {
77 : // initialise
78 :
79 6 : fkBunch = 0;
80 3 : fBunchIndex = 0;
81 3 : fWasDeconvoluted = 0;
82 3 : return 0;
83 : }
84 :
85 : int AliHLTTPCHWCFProcessorUnit::InputStream( const AliHLTTPCHWCFBunch *bunch )
86 : {
87 : // input stream of data
88 :
89 0 : if( bunch && fDebug ){
90 0 : printf("\nHWCF Processor: input bunch F %1d R %3d P %3d NS %2ld:\n",
91 0 : bunch->fFlag, bunch->fRow, bunch->fPad, bunch->fData.size());
92 0 : for( unsigned int i=0; i<bunch->fData.size(); i++ ){
93 0 : AliHLTTPCHWCFDigit d = bunch->fData[i];
94 0 : printf(" q %2d t %3d peak %2d ", d.fQ, d.fTime, d.fPeak);
95 0 : printf("(");
96 0 : for( int j=0; j<3; j++ ) printf(" {%d,%2.0f}",d.fMC.fClusterID[j].fMCID, d.fMC.fClusterID[j].fWeight );
97 0 : printf(" )\n");
98 0 : }
99 0 : }
100 :
101 0 : fkBunch = bunch;
102 0 : fBunchIndex = 0;
103 0 : fWasDeconvoluted = 0;
104 0 : return 0;
105 : }
106 :
107 : const AliHLTTPCHWCFClusterFragment *AliHLTTPCHWCFProcessorUnit::OutputStream()
108 : {
109 : // output stream of data
110 :
111 : //const AliHLTUInt32_t kTimeBinWindow = 5;
112 : const AliHLTUInt32_t kHalfTimeBinWindow = 2;
113 :
114 0 : if( !fkBunch ) return 0;
115 :
116 0 : fOutput.fFlag = fkBunch->fFlag;
117 0 : fOutput.fRow = fkBunch->fRow;
118 0 : fOutput.fPad = fkBunch->fPad;
119 0 : fOutput.fBranch = fkBunch->fBranch;
120 0 : fOutput.fBorder = fkBunch->fBorder;
121 0 : fOutput.fQmax = 0;
122 0 : fOutput.fQ = 0;
123 0 : fOutput.fT = 0;
124 0 : fOutput.fT2 = 0;
125 0 : fOutput.fP = 0;
126 0 : fOutput.fP2 = 0;
127 0 : fOutput.fTMean = 0;
128 0 : fOutput.fNPads = 0;
129 0 : fOutput.fNDeconvolutedTime = 0;
130 0 : fOutput.fIsDeconvolutedPad = 0;
131 0 : fOutput.fConsecutiveTimeDeconvolution = 0;
132 0 : fOutput.fMC.clear();
133 :
134 0 : if( fkBunch->fFlag==2 && fkBunch->fData.size()==1 ){ // rcu trailer word, forward it
135 0 : fOutput.fRow = fkBunch->fData[0].fQ;
136 0 : }
137 :
138 0 : if( fkBunch->fFlag >1 ){
139 0 : fkBunch = 0;
140 0 : return &fOutput;
141 : }
142 :
143 0 : if( fkBunch->fFlag < 1 ) return 0;
144 :
145 0 : if( fBunchIndex >= fkBunch->fData.size() ) return 0;
146 :
147 0 : AliHLTUInt32_t iStart = fBunchIndex;
148 : AliHLTUInt32_t iPeak = fBunchIndex;
149 : AliHLTUInt32_t qPeak = 0;
150 :
151 : // find next/best peak
152 :
153 0 : for( ; fBunchIndex<fkBunch->fData.size(); fBunchIndex++ ){
154 0 : const AliHLTTPCHWCFDigit &d = fkBunch->fData[fBunchIndex];
155 0 : if( d.fPeak != 1 ) continue;
156 0 : if( fDeconvolute ){
157 0 : iPeak = fBunchIndex;
158 0 : qPeak = d.fQ;
159 0 : fBunchIndex++;
160 0 : break;
161 : } else {
162 0 : if( d.fQ>qPeak ){
163 : qPeak = d.fQ;
164 0 : iPeak = fBunchIndex;
165 0 : }
166 : }
167 0 : }
168 :
169 0 : if( qPeak == 0 ) return 0;
170 :
171 : // find next minimum !!! At the moment the minimum finder is on only when no timebin window set
172 :
173 : bool isDeconvoluted = 0;
174 :
175 0 : if( !fUseTimeBinWindow ){
176 0 : for( ; fBunchIndex<fkBunch->fData.size(); fBunchIndex++ ){
177 0 : if( fDeconvolute ){
178 0 : if( fkBunch->fData[fBunchIndex].fPeak != 0 ){
179 0 : fBunchIndex++;
180 0 : break;
181 : }
182 : }
183 : }
184 0 : if( fBunchIndex<fkBunch->fData.size() ) isDeconvoluted = 1;
185 : } else{
186 0 : if( !fDeconvolute ){
187 0 : fBunchIndex = fkBunch->fData.size();
188 0 : } else {
189 : // find next peak
190 0 : if( fBunchIndex+1<fkBunch->fData.size() && fkBunch->fData[fBunchIndex+1].fPeak==1 ){
191 0 : fBunchIndex = fBunchIndex+1;
192 : isDeconvoluted = 1;
193 0 : } else if( fBunchIndex+2<fkBunch->fData.size() && fkBunch->fData[fBunchIndex+2].fPeak==1 ){
194 0 : fBunchIndex = fBunchIndex+1;
195 : isDeconvoluted = 1;
196 0 : } else if( fBunchIndex+3<fkBunch->fData.size() && fkBunch->fData[fBunchIndex+3].fPeak==1 ){
197 0 : fBunchIndex = fBunchIndex+2;
198 : isDeconvoluted = 1;
199 0 : } else if( fBunchIndex+1<fkBunch->fData.size() ){
200 0 : fBunchIndex = fBunchIndex+2;
201 0 : } else if( fBunchIndex<fkBunch->fData.size() ){
202 0 : fBunchIndex = fBunchIndex+1;
203 0 : }
204 : }
205 : }
206 :
207 0 : AliHLTUInt32_t iEnd = fBunchIndex;
208 :
209 0 : if( fUseTimeBinWindow ){
210 0 : if( iPeak > iStart + kHalfTimeBinWindow ) iStart = iPeak - kHalfTimeBinWindow;
211 0 : if( iEnd > iPeak + kHalfTimeBinWindow + 1) iEnd = iPeak + kHalfTimeBinWindow + 1;
212 : }
213 :
214 0 : fOutput.fQmax = qPeak*fkBunch->fGain;
215 0 : fOutput.fQ = 0;
216 0 : fOutput.fT = 0;
217 0 : fOutput.fT2 = 0;
218 0 : fOutput.fP = 0;
219 0 : fOutput.fP2 = 0;
220 0 : fOutput.fTMean = fkBunch->fData[iPeak].fTime;
221 0 : fOutput.fNPads = 1;
222 0 : fOutput.fNDeconvolutedTime = ( fWasDeconvoluted || isDeconvoluted ) ?1 :0;
223 0 : fOutput.fConsecutiveTimeDeconvolution = fOutput.fNDeconvolutedTime;
224 0 : fOutput.fMC.clear();
225 :
226 0 : fWasDeconvoluted = isDeconvoluted;
227 :
228 0 : for( AliHLTUInt32_t i=iStart; i<iEnd; i++ ){
229 0 : const AliHLTTPCHWCFDigit &d = fkBunch->fData[i];
230 0 : AliHLTUInt64_t q = d.fQ*fkBunch->fGain;
231 0 : fOutput.fQ += q;
232 0 : fOutput.fT += q*d.fTime;
233 0 : fOutput.fT2+= q*d.fTime*d.fTime;
234 0 : fOutput.fP += q*fkBunch->fPad;
235 0 : fOutput.fP2+= q*fkBunch->fPad*fkBunch->fPad;
236 0 : fOutput.fMC.push_back(d.fMC);
237 : }
238 :
239 0 : if( fkBunch->fData.size()==1 && fOutput.fQ < fSingleSeqLimit ) return 0;
240 :
241 0 : return &fOutput;
242 0 : }
|