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 : AliVZEROTriggerMask
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 "AliVZEROTriggerMask.h"
33 : #include "AliVZEROConst.h"
34 : #include "AliVZEROCalibData.h"
35 : #include "AliESDVZERO.h"
36 : #include "AliVZEROReconstructor.h"
37 :
38 : //______________________________________________________________________
39 20 : ClassImp(AliVZEROTriggerMask)
40 :
41 : //______________________________________________________________________
42 :
43 : AliVZEROTriggerMask::AliVZEROTriggerMask()
44 8 : :TObject(),
45 8 : fV0ADist(0),
46 8 : fV0CDist(0),
47 8 : fRecoParam(NULL)
48 40 : {
49 : // Default constructor
50 : //
51 16 : Float_t zV0A = TMath::Abs(GetZPosition("VZERO/V0A"));
52 16 : Float_t zV0C = TMath::Abs(GetZPosition("VZERO/V0C"));
53 :
54 : // distance in time units from nominal vertex to V0
55 16 : fV0ADist = zV0A/TMath::Ccgs()*1e9;
56 16 : fV0CDist = zV0C/TMath::Ccgs()*1e9;
57 16 : }
58 :
59 : //________________________________________________________________________________
60 : Double_t AliVZEROTriggerMask::GetZPosition(const char* symname){
61 : // Get the global z coordinate of the given V0 alignable volume
62 : //
63 : Double_t *tr;
64 32 : TGeoPNEntry *pne = gGeoManager->GetAlignableEntry(symname);
65 16 : if (!pne) {
66 0 : AliFatalClass(Form("TGeoPNEntry with symbolic name %s does not exist!",symname));
67 0 : return 0;
68 : }
69 :
70 16 : TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
71 16 : if(pnode){
72 16 : TGeoHMatrix* hm = pnode->GetMatrix();
73 16 : tr = hm->GetTranslation();
74 16 : }else{
75 0 : const char* path = pne->GetTitle();
76 0 : if(!gGeoManager->cd(path)){
77 0 : AliFatalClass(Form("Volume path %s not valid!",path));
78 0 : return 0;
79 : }
80 0 : tr = gGeoManager->GetCurrentMatrix()->GetTranslation();
81 0 : }
82 16 : return tr[2];
83 :
84 16 : }
85 :
86 : //________________________________________________________________________________
87 :
88 :
89 : void AliVZEROTriggerMask::FillMasks(AliESDVZERO *esdV0,
90 : AliVZEROCalibData *cal,
91 : TF1 *slewing)
92 : {
93 : // Fill up the trigger mask word
94 : // using the TDC data (already corrected for
95 : // slewing and misalignment between channels)
96 :
97 16 : esdV0->SetBit(AliESDVZERO::kTriggerBitsFilled,kTRUE);
98 8 : esdV0->SetBit(AliESDVZERO::kDecisionFilled,kTRUE);
99 :
100 : const Float_t p1 = 2.50; // photostatistics term in the time resolution
101 8 : Float_t p2 = (AliCDBManager::Instance()->GetRun() >= 215011) ? 1.80 : 3.00; // slewing related term in the time resolution, smaller in Run2
102 :
103 : // loop over vzero channels
104 : Float_t timeAW = 0,timeCW = 0;
105 : Float_t weightA = 0,weightC = 0;
106 : Int_t ntimeA = 0, ntimeC = 0;
107 8 : Double_t timesA[32], timesC[32];
108 8 : Double_t wA[32],wC[32];
109 8 : Int_t indA[32], indC[32];
110 1040 : for (Int_t i = 0; i < 64; ++i) {
111 512 : Float_t adc = esdV0->GetAdc(i);
112 512 : if (adc > GetRecoParam()->GetAdcThresHold()) {
113 90 : Float_t tdc = esdV0->GetTime(i);
114 90 : if (tdc > (AliVZEROReconstructor::kInvalidTime + 1e-6)) {
115 82 : Float_t nphe = adc*kChargePerADC/(cal->GetGain(i)*TMath::Qe());
116 : Float_t intTimeRes = kIntTimeRes;
117 : // For Run2 reco use the time resolution ring by ring
118 82 : if (AliCDBManager::Instance()->GetRun() >= 215011) intTimeRes = kIntTimeResRing[i/8];
119 246 : Float_t timeErr = TMath::Sqrt(intTimeRes*intTimeRes+
120 164 : p1*p1/nphe+
121 164 : p2*p2*(slewing->GetParameter(0)*slewing->GetParameter(1))*(slewing->GetParameter(0)*slewing->GetParameter(1))*
122 164 : TMath::Power(adc/cal->GetCalibDiscriThr(i,kTRUE,AliCDBManager::Instance()->GetRun()),2.*(slewing->GetParameter(1)-1.))/
123 82 : (cal->GetCalibDiscriThr(i,kTRUE,AliCDBManager::Instance()->GetRun())*cal->GetCalibDiscriThr(i,kTRUE,AliCDBManager::Instance()->GetRun())));
124 :
125 82 : if (i < 32) { // in V0C
126 34 : timesC[ntimeC] = tdc;
127 34 : wC[ntimeC] = 1.0/(timeErr*timeErr);
128 34 : indC[ntimeC] = i;
129 34 : ntimeC++;
130 34 : timeCW += tdc/(timeErr*timeErr);
131 34 : weightC += 1.0/(timeErr*timeErr);
132 34 : }
133 : else { // in V0A
134 48 : timesA[ntimeA] = tdc;
135 48 : wA[ntimeA] = 1.0/(timeErr*timeErr);
136 48 : indA[ntimeA] = i - 32;
137 48 : ntimeA++;
138 48 : timeAW += tdc/(timeErr*timeErr);
139 48 : weightA += 1.0/(timeErr*timeErr);
140 : }
141 82 : }
142 90 : }
143 : } // end of loop over channels
144 :
145 16 : if (weightA > 0) timeAW = timeAW/weightA;
146 : else timeAW = AliVZEROReconstructor::kInvalidTime;
147 :
148 16 : if (weightC > 0) timeCW = timeCW/weightC;
149 : else timeCW = AliVZEROReconstructor::kInvalidTime;
150 :
151 8 : esdV0->SetBit(AliESDVZERO::kRobustMeanTime,kTRUE);
152 :
153 : Double_t medianTimeA = AliVZEROReconstructor::kInvalidTime;
154 16 : if (ntimeA > 0) medianTimeA = TMath::Median(ntimeA,timesA,wA);
155 : Double_t medianTimeC = AliVZEROReconstructor::kInvalidTime;
156 16 : if (ntimeC > 0) medianTimeC = TMath::Median(ntimeC,timesC,wC);
157 :
158 : Float_t robTimeAW = 0,robTimeCW = 0;
159 : Float_t robWeightA = 0,robWeightC = 0;
160 : Int_t nrobTimeA = 0, nrobTimeC = 0;
161 8 : Int_t robIndA[32], robIndC[32];
162 112 : for(Int_t i = 0; i < ntimeA; ++i) {
163 144 : AliDebug(1,Form("ChannelsAResiduals %f %f %d",timesA[i]-medianTimeA,1./TMath::Sqrt(wA[i]),ntimeA));
164 48 : if (TMath::Abs(timesA[i]-medianTimeA) < GetRecoParam()->GetMaxResid()/TMath::Sqrt(wA[i])) {
165 48 : robIndA[nrobTimeA] = indA[i];
166 48 : nrobTimeA++;
167 48 : robTimeAW += timesA[i]*wA[i];
168 48 : robWeightA += wA[i];
169 48 : }
170 : }
171 84 : for(Int_t i = 0; i < ntimeC; ++i) {
172 102 : AliDebug(1,Form("ChannelsCResiduals %f %f %d",timesC[i]-medianTimeC,1./TMath::Sqrt(wC[i]),ntimeC));
173 34 : if (TMath::Abs(timesC[i]-medianTimeC) < GetRecoParam()->GetMaxResid()/TMath::Sqrt(wC[i])) {
174 34 : robIndC[nrobTimeC] = indC[i];
175 34 : nrobTimeC++;
176 34 : robTimeCW += timesC[i]*wC[i];
177 34 : robWeightC += wC[i];
178 34 : }
179 : }
180 :
181 16 : if (robWeightA > 0) robTimeAW = robTimeAW/robWeightA;
182 : else robTimeAW = AliVZEROReconstructor::kInvalidTime;
183 :
184 16 : if (robWeightC > 0) robTimeCW = robTimeCW/robWeightC;
185 : else robTimeCW = AliVZEROReconstructor::kInvalidTime;
186 :
187 24 : AliDebug(1,Form("V0timesA %f %f %f %f %d",timeAW,(weightA > 0) ? (1./TMath::Sqrt(weightA)) : 0,
188 : medianTimeA,robTimeAW,ntimeA));
189 24 : AliDebug(1,Form("V0timesC %f %f %f %f %d",timeCW,(weightC > 0) ? (1./TMath::Sqrt(weightC)) : 0,
190 : medianTimeC,robTimeCW,ntimeC));
191 :
192 8 : esdV0->SetV0ATime(robTimeAW);
193 8 : esdV0->SetV0CTime(robTimeCW);
194 24 : esdV0->SetV0ATimeError((robWeightA > 0) ? (1./TMath::Sqrt(robWeightA)) : 0);
195 24 : esdV0->SetV0CTimeError((robWeightC > 0) ? (1./TMath::Sqrt(robWeightC)) : 0);
196 :
197 8 : esdV0->SetV0ADecision(AliESDVZERO::kV0Empty);
198 8 : esdV0->SetV0CDecision(AliESDVZERO::kV0Empty);
199 :
200 16 : if (robTimeAW > (fV0ADist + GetRecoParam()->GetTimeWindowBBALow()) &&
201 8 : robTimeAW < (fV0ADist + GetRecoParam()->GetTimeWindowBBAUp()))
202 8 : esdV0->SetV0ADecision(AliESDVZERO::kV0BB);
203 0 : else if (robTimeAW > (-fV0ADist + GetRecoParam()->GetTimeWindowBGALow()) &&
204 0 : robTimeAW < (-fV0ADist + GetRecoParam()->GetTimeWindowBGAUp()))
205 0 : esdV0->SetV0ADecision(AliESDVZERO::kV0BG);
206 0 : else if (robTimeAW > (AliVZEROReconstructor::kInvalidTime + 1e-6))
207 0 : esdV0->SetV0ADecision(AliESDVZERO::kV0Fake);
208 :
209 16 : if (robTimeCW > (fV0CDist + GetRecoParam()->GetTimeWindowBBCLow()) &&
210 8 : robTimeCW < (fV0CDist + GetRecoParam()->GetTimeWindowBBCUp()))
211 8 : esdV0->SetV0CDecision(AliESDVZERO::kV0BB);
212 0 : else if (robTimeCW > (-fV0CDist + GetRecoParam()->GetTimeWindowBGCLow()) &&
213 0 : robTimeCW < (-fV0CDist + GetRecoParam()->GetTimeWindowBGCUp()))
214 0 : esdV0->SetV0CDecision(AliESDVZERO::kV0BG);
215 0 : else if (robTimeCW > (AliVZEROReconstructor::kInvalidTime + 1e-6))
216 0 : esdV0->SetV0CDecision(AliESDVZERO::kV0Fake);
217 :
218 : UInt_t aBBtriggerV0A = 0; // bit mask for Beam-Beam trigger in V0A
219 : UInt_t aBGtriggerV0A = 0; // bit mask for Beam-Gas trigger in V0A
220 : UInt_t aBBtriggerV0C = 0; // bit mask for Beam-Beam trigger in V0C
221 : UInt_t aBGtriggerV0C = 0; // bit mask for Beam-Gas trigger in V0C
222 :
223 112 : for(Int_t i = 0; i < nrobTimeA; ++i) {
224 48 : if (esdV0->GetV0ADecision() == AliESDVZERO::kV0BB)
225 48 : aBBtriggerV0A |= (1 << (robIndA[i]));
226 0 : else if (esdV0->GetV0ADecision() == AliESDVZERO::kV0BG)
227 0 : aBGtriggerV0A |= (1 << (robIndA[i]));
228 : }
229 :
230 84 : for(Int_t i = 0; i < nrobTimeC; ++i) {
231 34 : if (esdV0->GetV0CDecision() == AliESDVZERO::kV0BB)
232 34 : aBBtriggerV0C |= (1 << (robIndC[i]));
233 0 : else if (esdV0->GetV0CDecision() == AliESDVZERO::kV0BG)
234 0 : aBGtriggerV0C |= (1 << (robIndC[i]));
235 : }
236 :
237 8 : esdV0->SetBBtriggerV0A(aBBtriggerV0A);
238 8 : esdV0->SetBGtriggerV0A(aBGtriggerV0A);
239 8 : esdV0->SetBBtriggerV0C(aBBtriggerV0C);
240 8 : esdV0->SetBGtriggerV0C(aBGtriggerV0C);
241 8 : }
|