Line data Source code
1 :
2 : /////////////////////////////////////////////////////////////////////////////////////////////////////
3 : // Class for emulation of the SAMPA chip (SAMPA digital Chain) in C++ //
4 : /////////////////////////////////////////////////////////////////////////////////////////////////////
5 :
6 :
7 : /** @file AliTPCSAMPAEmulator.h
8 : * @brief This the header File for the SAMPA class
9 :
10 : author: marian.ivanov@cern.ch
11 : mesut.arslandok@cern.ch
12 :
13 : For the moment very limitted subsut of the functionality implemented.
14 : Only part realted to the Digiital filtering - SB3 and SB2
15 :
16 : In current interface all actions are done in once DigitalFilterFloat(Int_t npoints, Double_t *dataArray, Double_t &baseline);
17 : Class control variables:
18 : Int_t fDigitFilterType; // to select appropraite filter BC3(0), MAFMI(1), BC3MI(2)
19 : Int_t fgBaselineExportType; // to export corrected signal (0) or pedestal estimators (1)
20 :
21 : Interface will change soon - implementing pipe of the filters
22 : e.g:
23 : Signal->BC3->Rounding->ZerroSupression
24 : https://alice.its.cern.ch/jira/browse/ATO-129
25 : Using that the code will be more modular.
26 :
27 : */
28 :
29 :
30 :
31 : #include <AliTPCSAMPAEmulator.h>
32 : #include <TH1F.h>
33 : #include <TMath.h>
34 : #include <TSystem.h>
35 : #include <AliDAQ.h>
36 : #include <AliRawReader.h>
37 : #include <AliRawVEvent.h>
38 : #include <AliRawData.h>
39 : #include <AliRawVEquipment.h>
40 : #include <AliRawEquipmentHeader.h>
41 : #include <AliTPCRawStreamV3.h>
42 : #include <TCanvas.h>
43 : #include <AliRawDataHeader.h>
44 : #include <AliRawDataHeaderV3.h>
45 : #include <cassert>
46 :
47 : /** @brief Constroctor of SAMPA Class
48 : *
49 : * Consturctor of SAMPA Class, some variables are set.\n
50 : * The input Data is altered, so after running the complete emulation you have the
51 : * SAMPA Processed Data in the Channel Pointer.\n
52 : */
53 :
54 :
55 24 : ClassImp(AliTPCSAMPAEmulator)
56 :
57 : Int_t AliTPCSAMPAEmulator::fgBaselineExportType=0;
58 :
59 : AliTPCSAMPAEmulator::AliTPCSAMPAEmulator() :
60 0 : TNamed(),
61 0 : fDigitFilterType(0), // type of the digital filter - BC3 default
62 : //
63 0 : fBC3SlopeDown(0.2), // BC3 slope down parameter
64 0 : fBC3SlopeUp(0.1), // BC3 slope up parameter
65 0 : fBC3Round(-1), // Rounding error of BC3 filter
66 0 : fBC3DiffCutMI(2.5), // BC3 cut on the signal difference - for MI implementation
67 : //
68 0 : fMAFMIKernelWidth(10), // kernel width for MAF filtering
69 0 : fMAFMIDiffCut(-1) // cut on the diff to skip "signal"
70 0 : {
71 : //
72 : // Constructor of SAMPA Class
73 : //
74 :
75 :
76 0 : }
77 :
78 :
79 :
80 : /** @brief Destructor of SAMPA Class
81 : *
82 : * Destructor of SAMPA Class\n
83 : */
84 0 : AliTPCSAMPAEmulator::~AliTPCSAMPAEmulator() {
85 : //
86 : // Destructor of SAMPA Class
87 : //
88 0 : }
89 :
90 :
91 : Bool_t AliTPCSAMPAEmulator::DigitalFilterFloat(Int_t npoints, Double_t *dataArray, Double_t &baseline){
92 : //
93 : // Run digittal filter - as configured using fDigitFilterType
94 : // In future more sophisticated configuration of filters, pipe of filters should be implemented
95 : // to be agreed on interface ( e.g BC3 -> Rounding -> ZerroSpuression )
96 : // Current implementation used to make fast studies of the indeusced noise
97 : //
98 : //
99 0 : if (fDigitFilterType==0) return BC3SlopeFilterFloat(npoints,dataArray,baseline);
100 0 : if (fDigitFilterType==1) return MovingAverageFilter(npoints,dataArray,baseline);
101 : //
102 0 : if (fDigitFilterType==2) return BC3SlopeFilterMI(npoints,dataArray,baseline);
103 : //
104 0 : assert(false);
105 0 : }
106 :
107 : void AliTPCSAMPAEmulator::SetBC3Parameters(Double_t slopeDown, Double_t slopeUp, Double_t round){
108 : //
109 : //
110 : //
111 0 : fBC3SlopeDown=slopeDown;
112 0 : fBC3SlopeUp=slopeUp;
113 0 : fBC3Round=round;
114 0 : }
115 :
116 :
117 : Bool_t AliTPCSAMPAEmulator::BC3SlopeFilterFloat(Int_t npoints, Double_t *dataArray, Double_t &baseline){
118 : //
119 : // BC3 filter
120 : //
121 0 : return AliTPCSAMPAEmulator::BC3SlopeFilterFloat(npoints,dataArray, fBC3SlopeDown,fBC3SlopeUp, fBC3Round,baseline);
122 : }
123 :
124 : Bool_t AliTPCSAMPAEmulator::BC3SlopeFilterMI(Int_t npoints, Double_t *dataArray, Double_t &baseline){
125 : //
126 : // BC3 filter
127 : //
128 0 : return AliTPCSAMPAEmulator::BC3SlopeFilterMI(npoints,dataArray, fBC3SlopeDown,fBC3SlopeUp, fBC3Round,baseline,fBC3DiffCutMI);
129 : }
130 :
131 : Bool_t AliTPCSAMPAEmulator::BC3SlopeFilterFloat(Int_t npoints, Double_t *dataArray, Double_t slopeDown, Double_t slopeUp, Double_t round, Double_t &slopeBaseline) {
132 : //
133 : //
134 : //
135 : // BC2 filter as should be implemented in SAMPA
136 : // from Konstantin description
137 : // https://alice.its.cern.ch/jira/browse/ATO-129
138 : // discussed here the root/C code snippet for the slope based filter. The filter is applied as
139 : //
140 : // data_filtered=data-baseline(data);
141 : //
142 : // The filter is floating point. To simulate the integer behavior of the hardware based filter, define INTFILTER and choose the slopes to be binary compatible (1.0, 0.5, 0.25 etc.).
143 : // #define SLOPEUP 1.0
144 : // #define SLOPEDOWN 2.0
145 :
146 0 : if (npoints<=1) return kFALSE;
147 0 : for (Int_t iTimeBin=0; iTimeBin<npoints; iTimeBin++){
148 0 : Double_t data=dataArray[iTimeBin];
149 0 : if (data>slopeBaseline) {
150 0 : slopeBaseline+=slopeUp;
151 0 : if (slopeBaseline>data) slopeBaseline=data;
152 0 : } else if (data<slopeBaseline) {
153 0 : slopeBaseline-=slopeDown;
154 0 : if (slopeBaseline<data) slopeBaseline=data;
155 : };
156 0 : if (round>0){
157 : // return round(slopeBaseline);
158 0 : slopeBaseline=TMath::Nint(slopeBaseline*round)/round;
159 0 : }
160 0 : if (fgBaselineExportType==0){
161 0 : dataArray[iTimeBin]-=slopeBaseline;
162 0 : dataArray[iTimeBin]=TMath::Nint(dataArray[iTimeBin]);
163 0 : }
164 0 : if (fgBaselineExportType==1){
165 0 : dataArray[iTimeBin]=slopeBaseline;
166 0 : }
167 : }
168 0 : return kTRUE;
169 0 : };
170 :
171 :
172 : Bool_t AliTPCSAMPAEmulator::BC3SlopeFilterMI(Int_t npoints, Double_t *dataArray, Double_t slopeDown, Double_t slopeUp, Double_t round, Double_t &slopeBaseline, Double_t diffCutMI) {
173 : //
174 : //
175 : //
176 : // BC2 filter as should be implemented in SAMPA
177 : // from Konstantin description
178 : // https://alice.its.cern.ch/jira/browse/ATO-129
179 : // discussed here the root/C code snippet for the slope based filter. The filter is applied as
180 : //
181 : // data_filtered=data-baseline(data);
182 : //
183 : // The filter is floating point. To simulate the integer behavior of the hardware based filter, define INTFILTER and choose the slopes to be binary compatible (1.0, 0.5, 0.25 etc.).
184 : // #define SLOPEUP 1.0
185 : // #define SLOPEDOWN 2.0
186 :
187 0 : Double_t *tmpArray= new Double_t[npoints];
188 0 : memcpy(tmpArray, dataArray, npoints*sizeof(Double_t));
189 :
190 0 : if (npoints<=1) return kFALSE;
191 0 : for (Int_t iTimeBin=0; iTimeBin<npoints; iTimeBin++){
192 0 : Double_t data=tmpArray[iTimeBin];
193 0 : Double_t maxDiff=TMath::Max( TMath::Abs(tmpArray[(iTimeBin+npoints+1)%npoints]-data), TMath::Abs(tmpArray[(iTimeBin+npoints-1)%npoints]-data));
194 0 : if (maxDiff<=diffCutMI){
195 0 : if (data>slopeBaseline) {
196 0 : slopeBaseline+=slopeUp;
197 0 : if (slopeBaseline>data) slopeBaseline=data;
198 0 : } else if (data<slopeBaseline) {
199 0 : slopeBaseline-=slopeDown;
200 0 : if (slopeBaseline<data) slopeBaseline=data;
201 : };
202 0 : if (round>0){
203 : // return round(slopeBaseline);
204 0 : slopeBaseline=TMath::Nint(slopeBaseline*round)/round;
205 0 : }
206 : }
207 0 : if (fgBaselineExportType==0){
208 0 : dataArray[iTimeBin]-=slopeBaseline;
209 0 : dataArray[iTimeBin]=TMath::Nint(dataArray[iTimeBin]);
210 0 : }
211 0 : if (fgBaselineExportType==1){
212 0 : dataArray[iTimeBin]=slopeBaseline;
213 0 : }
214 : }
215 0 : delete [] tmpArray;
216 0 : return kTRUE;
217 0 : };
218 :
219 :
220 : Bool_t AliTPCSAMPAEmulator::MovingAverageFilter(Int_t npoints, Double_t *dataArray, Double_t &baseline){
221 : //
222 : //
223 : //
224 0 : return MovingAverageFilter(npoints,dataArray, fMAFMIKernelWidth, fMAFMIDiffCut,fMAFMIOnlyMinima, baseline);
225 : }
226 :
227 : Bool_t AliTPCSAMPAEmulator::MovingAverageFilter(Int_t npoints, Double_t *dataArray, Double_t length, Double_t skipDiff, Bool_t onlyMinima, Double_t &baseline){
228 : //
229 : // Baseline update formula:
230 : // baseline:=(baseline*length+data)/(length+1);
231 : //
232 0 : if (npoints<=1) return kFALSE;
233 0 : for (Int_t iTimeBin=0; iTimeBin<npoints; iTimeBin++){
234 0 : Double_t data=dataArray[iTimeBin];
235 0 : if (skipDiff>0){ // skip data point in case it is assumed to be signal ()too big diff)
236 0 : if ( (TMath::Abs(dataArray[(iTimeBin+npoints-1)%npoints]+baseline-data)>skipDiff) ||
237 0 : (TMath::Abs(dataArray[(iTimeBin+npoints+1)%npoints]-data)>skipDiff)) {
238 0 : continue;
239 : }
240 0 : if ( !(dataArray[(iTimeBin+npoints-1)%npoints]+baseline>data &&TMath::Abs(dataArray[(iTimeBin+npoints+1)%npoints]>data))){
241 0 : continue; //use only local minima
242 : }
243 : }
244 0 : baseline=(baseline*length+data)/(length+1);
245 0 : dataArray[iTimeBin]-=baseline;
246 0 : dataArray[iTimeBin]=TMath::Nint(dataArray[iTimeBin]);
247 0 : if (fgBaselineExportType==1){
248 0 : dataArray[iTimeBin]=baseline;
249 0 : }
250 0 : }
251 0 : assert(false);
252 : }
253 :
254 :
255 : void AliTPCSAMPAEmulator::SetMAFMIParameters(Double_t MAFMIKernelWidth, Double_t MAFMIDiffCut, Bool_t onlyMinima){
256 : //
257 : //
258 : //
259 0 : fMAFMIKernelWidth=MAFMIKernelWidth; // kernel width for MAF filtering
260 0 : fMAFMIDiffCut=MAFMIDiffCut; // cut on the diff to skip "signal"
261 0 : fMAFMIOnlyMinima=onlyMinima; //
262 0 : }
263 :
264 :
265 : Bool_t AliTPCSAMPAEmulator::ZeroSuppression(Int_t npoints, Double_t *dataArray, Double_t threshold) {
266 : //
267 : // Zero suppression - sets all values below threshold to zero.
268 : // Useful for evaluating the effect of zero suppression on the results.
269 : // pre- and post-samples may be implemented as well.
270 : //
271 0 : if (npoints<=1) return kFALSE;
272 0 : for (Int_t iTimeBin=0; iTimeBin<npoints; iTimeBin++){
273 0 : Double_t data=dataArray[iTimeBin];
274 0 : if (data<threshold) dataArray[iTimeBin]=0;
275 : }
276 0 : return kTRUE;
277 0 : };
|