Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 :
16 : /* $Id$ */
17 : //-------------------------------------------
18 : // Class : AliADDecision
19 : //
20 : // Fill up the trigger mask word.
21 : //
22 :
23 : #include <Riostream.h>
24 : #include <TGeoManager.h>
25 : #include <TGeoMatrix.h>
26 : #include <TGeoPhysicalNode.h>
27 : #include <TF1.h>
28 : #include <TMath.h>
29 :
30 : #include <AliGeomManager.h>
31 : #include "AliLog.h"
32 : #include "AliADDecision.h"
33 : #include "AliADConst.h"
34 : #include "AliADCalibData.h"
35 : #include "AliESDAD.h"
36 : #include "AliADReconstructor.h"
37 :
38 : //______________________________________________________________________
39 16 : ClassImp(AliADDecision)
40 :
41 : //______________________________________________________________________
42 :
43 : AliADDecision::AliADDecision()
44 0 : :TObject(),
45 0 : fADADist(0),
46 0 : fADCDist(0),
47 0 : fRecoParam(NULL),
48 0 : fEarlyHitCutShape(NULL)
49 0 : {
50 : // Default constructor
51 : //AD has two layers, filling average
52 0 : Float_t zADA = (TMath::Abs(GetZPosition("AD/ADA1")) + TMath::Abs(GetZPosition("AD/ADA2")))/2;
53 0 : Float_t zADC = (TMath::Abs(GetZPosition("AD/ADC1")) + TMath::Abs(GetZPosition("AD/ADC2")))/2;
54 :
55 : // distance in time units from nominal vertex to AD
56 0 : fADADist = zADA/TMath::Ccgs()*1e9;
57 0 : fADCDist = zADC/TMath::Ccgs()*1e9;
58 :
59 : //fADADist = 56.6958892608299081;
60 : //fADCDist = 65.1917667655268360;
61 :
62 0 : fEarlyHitCutShape = new TF1("fEarlyHitCutShape", " [0]+(x>[2])*[1]*(x-[2])**2");
63 :
64 0 : }
65 :
66 : //______________________________________________________________________
67 : AliADDecision::~AliADDecision()
68 0 : {
69 : // d-tor
70 0 : delete fEarlyHitCutShape;
71 0 : }
72 :
73 :
74 : //________________________________________________________________________________
75 : Double_t AliADDecision::GetZPosition(const char* symname)
76 : {
77 : // Get the global z coordinate of the given AD alignable volume
78 : //
79 : Double_t *tr;
80 0 : TGeoPNEntry *pne = gGeoManager->GetAlignableEntry(symname);
81 0 : if (!pne) {
82 0 : AliFatalClass(Form("TGeoPNEntry with symbolic name %s does not exist!",symname));
83 0 : return 0;
84 : }
85 :
86 0 : TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
87 0 : if(pnode){
88 0 : TGeoHMatrix* hm = pnode->GetMatrix();
89 0 : tr = hm->GetTranslation();
90 0 : }else{
91 0 : const char* path = pne->GetTitle();
92 0 : if(!gGeoManager->cd(path)){
93 0 : AliFatalClass(Form("Volume path %s not valid!",path));
94 0 : return 0;
95 : }
96 0 : tr = gGeoManager->GetCurrentMatrix()->GetTranslation();
97 0 : }
98 0 : return tr[2];
99 :
100 0 : }
101 :
102 : //________________________________________________________________________________
103 : void AliADDecision::FillDecisions(AliESDAD *esdAD)
104 : {
105 : // Fill up offline trigger decisions
106 : // using the TDC data (already corrected for
107 : // slewing and misalignment between channels)
108 :
109 0 : esdAD->SetBit(AliESDAD::kDecisionFilled,kTRUE);
110 0 : esdAD->SetBit(AliESDAD::kTriggerBitsFilled,kTRUE);
111 :
112 : // loop over AD channels
113 : Double_t timeADA =0., timeADC = 0.;
114 : Double_t weightADA =0., weightADC = 0.;
115 : UInt_t ntimeADA=0, ntimeADC=0;
116 0 : UInt_t itimeADA[8], itimeADC[8];
117 :
118 : //Compute average time with basic method(charge weighted average)
119 : Double_t timeBasicADA=0, timeBasicADC=0;
120 : Double_t weightBasicADA =0., weightBasicADC = 0.;
121 : UInt_t ntimeBasicADA=0, ntimeBasicADC=0;
122 0 : UInt_t itimeBasicADA[8], itimeBasicADC[8];
123 :
124 0 : for (Int_t i = 0; i < 16; ++i) {
125 0 : Float_t adc = esdAD->GetAdc(i);
126 0 : if (adc > GetRecoParam()->GetAdcThresHold()) {
127 0 : Float_t time = esdAD->GetTime(i);
128 0 : if(time > (AliADReconstructor::kInvalidTime+1.e-6)){
129 : Float_t timeErr = 1;
130 0 : if (adc>1) timeErr = 1/adc;
131 :
132 0 : if (i<8) {
133 0 : itimeBasicADC[ntimeBasicADC] = i;
134 0 : ntimeBasicADC++;
135 0 : timeBasicADC += time/(timeErr*timeErr);
136 0 : weightBasicADC += 1./(timeErr*timeErr);
137 0 : }
138 : else{
139 0 : itimeBasicADA[ntimeBasicADA] = i-8;
140 0 : ntimeBasicADA++;
141 0 : timeBasicADA += time/(timeErr*timeErr);
142 0 : weightBasicADA += 1./(timeErr*timeErr);
143 : }
144 :
145 0 : }
146 0 : }
147 : } // end of loop over channels
148 :
149 :
150 0 : if(weightBasicADA > 1) timeBasicADA /= weightBasicADA;
151 : else timeBasicADA = -1024.;
152 0 : if(weightBasicADC > 1) timeBasicADC /= weightBasicADC;
153 : else timeBasicADC = -1024.;
154 :
155 : //Robust time: Pad coincidence and early hit removal
156 : Double_t timeRobustADA=0, timeRobustADC=0;
157 : Double_t weightRobustADA =0., weightRobustADC = 0.;
158 : UInt_t ntimeRobustADA=0, ntimeRobustADC=0;
159 0 : UInt_t itimeRobustADA[8], itimeRobustADC[8];
160 :
161 0 : fEarlyHitCutShape->SetParameter(0,GetRecoParam()->GetMaxResid());
162 0 : fEarlyHitCutShape->SetParameter(1,GetRecoParam()->GetResidRise());
163 :
164 : //C-side
165 0 : fEarlyHitCutShape->SetParameter(2,2*fADCDist - 10);
166 0 : for (Int_t i = 0; i < 4; ++i) {
167 0 : Float_t adc1 = esdAD->GetAdc(i);
168 0 : Float_t adc2 = esdAD->GetAdc(i+4);
169 0 : if (adc1 > GetRecoParam()->GetAdcThresHold() && adc2 > GetRecoParam()->GetAdcThresHold()) {
170 0 : Float_t time1 = esdAD->GetTime(i);
171 0 : Float_t time2 = esdAD->GetTime(i+4);
172 0 : if(time1 > (AliADReconstructor::kInvalidTime+1.e-6) && time2 > (AliADReconstructor::kInvalidTime+1.e-6)){
173 0 : Float_t timeErr1 = 1/adc1;
174 0 : Float_t timeErr2 = 1/adc2;
175 0 : Float_t timeDiff = TMath::Abs(time1-time2);
176 0 : Float_t timeSum = time1+time2;
177 : Float_t earlyHitCut = 1000;
178 0 : if(TMath::Abs(timeSum - 2*fADCDist) < 20) earlyHitCut = fEarlyHitCutShape->Eval(timeSum);
179 0 : if(timeDiff < earlyHitCut){
180 0 : itimeRobustADC[ntimeRobustADC] = i;
181 0 : ntimeRobustADC++;
182 0 : timeRobustADC += time1/(timeErr1*timeErr1);
183 0 : weightRobustADC += 1./(timeErr1*timeErr1);
184 :
185 0 : itimeRobustADC[ntimeRobustADC] = i+4;
186 0 : ntimeRobustADC++;
187 0 : timeRobustADC += time2/(timeErr2*timeErr2);
188 0 : weightRobustADC += 1./(timeErr2*timeErr2);
189 0 : }
190 0 : }
191 0 : }
192 :
193 : }
194 :
195 : //A-side
196 0 : fEarlyHitCutShape->SetParameter(2,2*fADADist - 10);
197 0 : for (Int_t i = 8; i < 12; ++i) {
198 0 : Float_t adc1 = esdAD->GetAdc(i);
199 0 : Float_t adc2 = esdAD->GetAdc(i+4);
200 0 : if (adc1 > GetRecoParam()->GetAdcThresHold() && adc2 > GetRecoParam()->GetAdcThresHold()) {
201 0 : Float_t time1 = esdAD->GetTime(i);
202 0 : Float_t time2 = esdAD->GetTime(i+4);
203 0 : if(time1 > (AliADReconstructor::kInvalidTime+1.e-6) && time2 > (AliADReconstructor::kInvalidTime+1.e-6)){
204 0 : Float_t timeErr1 = 1/adc1;
205 0 : Float_t timeErr2 = 1/adc2;
206 0 : Float_t timeDiff = TMath::Abs(time1-time2);
207 0 : Float_t timeSum = time1+time2;
208 : Float_t earlyHitCut = 1000;
209 0 : if(TMath::Abs(timeSum - 2*fADADist) < 20) earlyHitCut = fEarlyHitCutShape->Eval(timeSum);
210 0 : if(timeDiff < earlyHitCut){
211 0 : itimeRobustADA[ntimeRobustADA] = i-8;
212 0 : ntimeRobustADA++;
213 0 : timeRobustADA += time1/(timeErr1*timeErr1);
214 0 : weightRobustADA += 1./(timeErr1*timeErr1);
215 :
216 0 : itimeRobustADA[ntimeRobustADA] = i-4;
217 0 : ntimeRobustADA++;
218 0 : timeRobustADA += time2/(timeErr2*timeErr2);
219 0 : weightRobustADA += 1./(timeErr2*timeErr2);
220 0 : }
221 0 : }
222 0 : }
223 :
224 : }
225 :
226 0 : if(weightRobustADA > 1) timeRobustADA /= weightRobustADA;
227 : else timeRobustADA = -1024.;
228 0 : if(weightRobustADC > 1) timeRobustADC /= weightRobustADC;
229 : else timeRobustADC = -1024.;
230 :
231 : /*/Use basic time for decisions
232 : timeADA = timeBasicADA; timeADC = timeBasicADC;
233 : weightADA = weightBasicADA; weightADC = weightBasicADC;
234 : ntimeADA = ntimeBasicADA; ntimeADC = ntimeBasicADC;
235 : for(Int_t i=0; i<8; ++i){itimeADA[i] = itimeBasicADA[i]; itimeADC[i] = itimeBasicADC[i];}/*/
236 :
237 : //Use Robust time for decisions
238 0 : esdAD->SetBit(AliESDAD::kRobustMeanTime,kTRUE);
239 : timeADA = timeRobustADA; timeADC = timeRobustADC;
240 : weightADA = weightRobustADA; weightADC = weightRobustADC;
241 : ntimeADA = ntimeRobustADA; ntimeADC = ntimeRobustADC;
242 0 : for(Int_t i=0; i<8; ++i){itimeADA[i] = itimeRobustADA[i]; itimeADC[i] = itimeRobustADC[i];}
243 :
244 0 : esdAD->SetADATime(timeADA);
245 0 : esdAD->SetADCTime(timeADC);
246 0 : esdAD->SetADATimeError((weightADA > 1) ? (1./TMath::Sqrt(weightADA)) : 666);
247 0 : esdAD->SetADCTimeError((weightADC > 1) ? (1./TMath::Sqrt(weightADC)) : 666);
248 :
249 0 : esdAD->SetADADecision(AliESDAD::kADEmpty);
250 0 : esdAD->SetADCDecision(AliESDAD::kADEmpty);
251 :
252 0 : if (timeADA > (fADADist + GetRecoParam()->GetTimeWindowBBALow()) &&
253 0 : timeADA < (fADADist + GetRecoParam()->GetTimeWindowBBAUp()))
254 0 : esdAD->SetADADecision(AliESDAD::kADBB);
255 0 : else if (timeADA > (-fADADist + GetRecoParam()->GetTimeWindowBGALow()) &&
256 0 : timeADA < (-fADADist + GetRecoParam()->GetTimeWindowBGAUp()))
257 0 : esdAD->SetADADecision(AliESDAD::kADBG);
258 0 : else if (timeADA > (AliADReconstructor::kInvalidTime + 1e-6))
259 0 : esdAD->SetADADecision(AliESDAD::kADFake);
260 :
261 0 : if (timeADC > (fADCDist + GetRecoParam()->GetTimeWindowBBCLow()) &&
262 0 : timeADC < (fADCDist + GetRecoParam()->GetTimeWindowBBCUp()))
263 0 : esdAD->SetADCDecision(AliESDAD::kADBB);
264 0 : else if (timeADC > (-fADCDist + GetRecoParam()->GetTimeWindowBGCLow()) &&
265 0 : timeADC < (-fADCDist + GetRecoParam()->GetTimeWindowBGCUp()))
266 0 : esdAD->SetADCDecision(AliESDAD::kADBG);
267 0 : else if (timeADC > (AliADReconstructor::kInvalidTime + 1e-6))
268 0 : esdAD->SetADCDecision(AliESDAD::kADFake);
269 :
270 : UInt_t aBBtriggerADA = 0; // bit mask for Beam-Beam trigger in ADA
271 : UInt_t aBGtriggerADA = 0; // bit mask for Beam-Gas trigger in ADA
272 : UInt_t aBBtriggerADC = 0; // bit mask for Beam-Beam trigger in ADC
273 : UInt_t aBGtriggerADC = 0; // bit mask for Beam-Gas trigger in ADC
274 :
275 0 : for(Int_t i = 0; i < ntimeADA; ++i) {
276 0 : if (esdAD->GetADADecision() == AliESDAD::kADBB)
277 0 : aBBtriggerADA |= (1 << (itimeADA[i]));
278 0 : else if (esdAD->GetADADecision() == AliESDAD::kADBG)
279 0 : aBGtriggerADA |= (1 << (itimeADA[i]));
280 : }
281 :
282 0 : for(Int_t i = 0; i < ntimeADC; ++i) {
283 0 : if (esdAD->GetADCDecision() == AliESDAD::kADBB)
284 0 : aBBtriggerADC |= (1 << (itimeADC[i]));
285 0 : else if (esdAD->GetADCDecision() == AliESDAD::kADBG)
286 0 : aBGtriggerADC |= (1 << (itimeADC[i]));
287 : }
288 :
289 0 : esdAD->SetBBtriggerADA(aBBtriggerADA);
290 0 : esdAD->SetBGtriggerADA(aBGtriggerADA);
291 0 : esdAD->SetBBtriggerADC(aBBtriggerADC);
292 0 : esdAD->SetBGtriggerADC(aBGtriggerADC);
293 :
294 :
295 0 : }
|