12 #include <JANA/JCalibration.h>
19 DIRC_DEBUG_HISTS =
false;
20 gPARMS->SetDefaultParameter(
"DIRC:DEBUG_HISTS",DIRC_DEBUG_HISTS);
22 DIRC_TRUTH_BARHIT =
false;
23 gPARMS->SetDefaultParameter(
"DIRC:TRUTH_BARHIT",DIRC_TRUTH_BARHIT);
25 DIRC_TRUTH_PIXELTIME =
false;
26 gPARMS->SetDefaultParameter(
"DIRC:TRUTH_PIXELTIME",DIRC_TRUTH_PIXELTIME);
30 gPARMS->SetDefaultParameter(
"DIRC:CUT_TDIFFD",DIRC_CUT_TDIFFD);
32 gPARMS->SetDefaultParameter(
"DIRC:CUT_TDIFFR",DIRC_CUT_TDIFFR);
36 gPARMS->SetDefaultParameter(
"DIRC:LIGHT_V",DIRC_LIGHT_V);
39 DIRC_SIGMA_THETAC = 0.0085;
40 gPARMS->SetDefaultParameter(
"DIRC:SIGMA_THETAC",DIRC_SIGMA_THETAC);
44 dFinalStatePIDs.push_back(
PiPlus);
45 dFinalStatePIDs.push_back(
KPlus);
46 dFinalStatePIDs.push_back(
Proton);
48 dMaxChannels = 108*64;
50 dCriticalAngle = asin(1.00028/1.47125);
54 CreateDebugHistograms();
60 dDIRCLutReader =
dapp->
GetDIRCLut(loop->GetJEvent().GetRunNumber());
63 vector<const DDIRCGeometry*> locDIRCGeometry;
64 loop->Get(locDIRCGeometry);
65 dDIRCGeometry = locDIRCGeometry[0];
82 hDiff = (TH1I*)gROOT->FindObject(
"hDiff");
83 hDiff_Pixel[0] = (TH2I*)gROOT->FindObject(
"hDiff_Pixel_N");
84 hDiff_Pixel[1] = (TH2I*)gROOT->FindObject(
"hDiff_Pixel_S");
85 hDiffT = (TH1I*)gROOT->FindObject(
"hDiffT");
86 hDiffD = (TH1I*)gROOT->FindObject(
"hDiffD");
87 hDiffR = (TH1I*)gROOT->FindObject(
"hDiffR");
88 hTime = (TH1I*)gROOT->FindObject(
"hTime");
89 hCalc = (TH1I*)gROOT->FindObject(
"hCalc");
90 hNph = (TH1I*)gROOT->FindObject(
"hNph");
91 if(!hDiff) hDiff =
new TH1I(
"hDiff",
";t_{calc}-t_{measured} [ns];entries [#]", 400,-20,20);
92 if(!hDiff_Pixel[0]) hDiff_Pixel[0] =
new TH2I(
"hDiff_Pixel_N",
"; Channel ID; t_{calc}-t_{measured} [ns];entries [#]", dMaxChannels, 0, dMaxChannels, 400,-20,20);
93 if(!hDiff_Pixel[1]) hDiff_Pixel[1] =
new TH2I(
"hDiff_Pixel_S",
"; Channel ID; t_{calc}-t_{measured} [ns];entries [#]", dMaxChannels, 0, dMaxChannels, 400,-20,20);
94 if(!hDiffT) hDiffT =
new TH1I(
"hDiffT",
";t_{calc}-t_{measured} [ns];entries [#]", 400,-20,20);
95 if(!hDiffD) hDiffD =
new TH1I(
"hDiffD",
";t_{calc}-t_{measured} [ns];entries [#]", 400,-20,20);
96 if(!hDiffR) hDiffR =
new TH1I(
"hDiffR",
";t_{calc}-t_{measured} [ns];entries [#]", 400,-20,20);
97 if(!hTime) hTime =
new TH1I(
"hTime",
";propagation time [ns];entries [#]", 1000,0,200);
98 if(!hCalc) hCalc =
new TH1I(
"hCalc",
";calculated time [ns];entries [#]", 1000,0,200);
99 if(!hNph) hNph =
new TH1I(
"hNph",
";detected photons [#];entries [#]", 150,0,150);
102 for(uint loc_i=0; loc_i<dFinalStatePIDs.size(); loc_i++) {
107 hDeltaThetaC[locPID] = (TH1I*)gROOT->FindObject(Form(
"hDeltaThetaC_%s",locParticleName.data()));
108 if(!hDeltaThetaC[locPID])
109 hDeltaThetaC[locPID] =
new TH1I(Form(
"hDeltaThetaC_%s",locParticleName.data()),
"cherenkov angle; #Delta#theta_{C} [rad]", 200,-0.5,0.5);
110 hDeltaThetaC_Pixel[locPID] = (TH2I*)gROOT->FindObject(Form(
"hDeltaThetaC_Pixel_%s",locParticleName.data()));
111 if(!hDeltaThetaC_Pixel[locPID])
112 hDeltaThetaC_Pixel[locPID] =
new TH2I(Form(
"hDeltaThetaC_Pixel_%s",locParticleName.data()),
"cherenkov angle; Pixel ID; #Delta#theta_{C} [rad]", 10000, 0, 10000, 200,-0.5,0.5);
122 bool DDIRCLut::CalcLUT(TVector3 locProjPos, TVector3 locProjMom,
const vector<const DDIRCPmtHit*> locDIRCHits,
double locFlightTime,
Particle_t locPID, shared_ptr<DDIRCMatchParams>& locDIRCMatchParams,
const vector<const DDIRCTruthBarHit*> locDIRCBarHits, map<shared_ptr<const DDIRCMatchParams>, vector<const DDIRCPmtHit*> >& locDIRCTrackMatchParams)
const
127 TVector3 momInBar = locProjMom;
128 TVector3 posInBar = locProjPos;
133 if(DIRC_TRUTH_BARHIT && locDIRCBarHits.size() > 0) {
135 TVector3 bestMatchPos, bestMatchMom;
136 double bestFlightTime = 999.;
137 double bestMatchDist = 999.;
138 for(
int i=0; i<(int)locDIRCBarHits.size(); i++) {
139 TVector3 locDIRCBarHitPos(locDIRCBarHits[i]->
x, locDIRCBarHits[i]->
y, locDIRCBarHits[i]->z);
140 TVector3 locDIRCBarHitMom(locDIRCBarHits[i]->px, locDIRCBarHits[i]->
py, locDIRCBarHits[i]->pz);
141 if((posInBar - locDIRCBarHitPos).Mag() < bestMatchDist) {
142 bestMatchDist = (posInBar - locDIRCBarHitPos).Mag();
143 bestMatchPos = locDIRCBarHitPos;
144 bestMatchMom = locDIRCBarHitMom;
145 bestFlightTime = locDIRCBarHits[i]->t;
149 momInBar = bestMatchMom;
150 posInBar = bestMatchPos;
151 locFlightTime = bestFlightTime;
155 if(locDIRCMatchParams ==
nullptr)
156 locDIRCMatchParams = std::make_shared<DDIRCMatchParams>();
159 double locAngle = CalcAngle(momInBar, locMass);
160 map<Particle_t, double> locExpectedAngle = CalcExpectedAngles(momInBar);
161 map<Particle_t, double> logLikelihoodSum;
163 for(uint loc_i = 0; loc_i<dFinalStatePIDs.size(); loc_i++) {
164 logLikelihoodSum[dFinalStatePIDs[loc_i]]=0;
165 if(fabs(
ParticleMass(dFinalStatePIDs[loc_i])-
ParticleMass(locPID)) < 0.01) locHypothesisPID = dFinalStatePIDs[loc_i];
170 int nPhotonsThetaC = 0;
171 double meanThetaC = 0.;
172 double meanDeltaT = 0.;
173 for (
unsigned int loc_i = 0; loc_i < locDIRCHits.size(); loc_i++){
175 const DDIRCPmtHit* locDIRCHit = locDIRCHits[loc_i];
176 bool locIsGood =
false;
177 CalcPhoton(locDIRCHit, locFlightTime, posInBar, momInBar, locExpectedAngle, locAngle, locHypothesisPID, logLikelihoodSum, nPhotonsThetaC, meanThetaC, meanDeltaT, locIsGood);
181 locDIRCTrackMatchParams[locDIRCMatchParams].push_back(locDIRCHit);
186 if(DIRC_DEBUG_HISTS) {
187 dapp->RootWriteLock();
188 hNph->Fill(nPhotons);
197 locDIRCMatchParams->dThetaC = meanThetaC/(double)nPhotonsThetaC;
198 locDIRCMatchParams->dDeltaT = meanDeltaT/(double)nPhotonsThetaC;
199 locDIRCMatchParams->dExpectedThetaC = locAngle;
200 locDIRCMatchParams->dLikelihoodElectron = logLikelihoodSum[
Positron];
201 locDIRCMatchParams->dLikelihoodPion = logLikelihoodSum[
PiPlus];
202 locDIRCMatchParams->dLikelihoodKaon = logLikelihoodSum[
KPlus];
203 locDIRCMatchParams->dLikelihoodProton = logLikelihoodSum[
Proton];
204 locDIRCMatchParams->dNPhotons = nPhotons;
205 locDIRCMatchParams->dExtrapolatedPos = posInBar;
206 locDIRCMatchParams->dExtrapolatedMom = momInBar;
207 locDIRCMatchParams->dExtrapolatedTime = locFlightTime;
212 vector<pair<double,double>>
DDIRCLut::CalcPhoton(
const DDIRCPmtHit *locDIRCHit,
double locFlightTime, TVector3 posInBar, TVector3 momInBar, map<Particle_t, double> locExpectedAngle,
double locAngle,
Particle_t locPID, map<Particle_t, double> &logLikelihoodSum,
int &nPhotonsThetaC,
double &meanThetaC,
double &meanDeltaT,
bool &isGood)
const
215 pair<double, double> locDIRCPhoton(-999., -999.);
216 vector<pair<double, double>> locDIRCPhotons;
218 TVector3 fnX1 = TVector3 (1,0,0);
219 TVector3 fnY1 = TVector3 (0,1,0);
220 TVector3 fnZ1 = TVector3 (0,0,1);
222 double tangle,luttheta,evtime;
227 int bar = dDIRCGeometry->GetBar(posInBar.Y());
228 if(bar < 0 || bar > 47)
return locDIRCPhotons;
231 int channel = locDIRCHit->
ch;
234 int box = (bar < 24) ? 1 : 0;
235 if((box == 0 && channel < dMaxChannels) || (box == 1 && channel >= dMaxChannels))
236 return locDIRCPhotons;
239 double hitTime = locDIRCHit->
t - locFlightTime;
242 vector<const DDIRCTruthPmtHit*> locTruthDIRCHits;
243 locDIRCHit->Get(locTruthDIRCHits);
244 if(DIRC_TRUTH_PIXELTIME && locTruthDIRCHits.size() > 0) {
245 double locTruthTime = locTruthDIRCHits[0]->t - locFlightTime;
246 hitTime = locTruthTime;
250 bool reflected = hitTime>0;
253 double radiatorL = dDIRCGeometry->GetBarLength(bar);
254 double barend = dDIRCGeometry->GetBarEnd(bar);
255 double lenz = fabs(barend - posInBar.X());
258 double rlenz = 2*radiatorL - lenz;
260 if(reflected) lenz = 2*radiatorL - lenz;
263 int box_channel = channel%dMaxChannels;
264 if(dDIRCLutReader->GetLutPixelAngleSize(bar, box_channel) == 0)
265 return locDIRCPhotons;
268 for(uint i = 0; i < dDIRCLutReader->GetLutPixelAngleSize(bar, box_channel); i++){
270 dird = dDIRCLutReader->GetLutPixelAngle(bar, box_channel, i);
271 evtime = dDIRCLutReader->GetLutPixelTime(bar, box_channel, i);
272 pathid = dDIRCLutReader->GetLutPixelPath(bar, box_channel, i);
275 bool samepath(
false);
276 if(!locTruthDIRCHits.empty() && fabs(pathid - locTruthDIRCHits[0]->path)<0.0001)
279 for(
int r=0; r<2; r++){
280 if(!reflected && r==1)
continue;
285 for(
int u = 0;
u < 4;
u++){
286 if(
u == 0) dir = dird;
287 if(
u == 1) dir.SetXYZ( dird.X(),-dird.Y(), dird.Z());
288 if(
u == 2) dir.SetXYZ( dird.X(), dird.Y(), -dird.Z());
289 if(
u == 3) dir.SetXYZ( dird.X(),-dird.Y(), -dird.Z());
290 if(r) dir.SetXYZ( -dir.X(), dir.Y(), dir.Z());
291 if(dir.Angle(fnY1) < dCriticalAngle || dir.Angle(fnZ1) < dCriticalAngle)
continue;
293 luttheta = dir.Angle(TVector3(-1,0,0));
294 if(luttheta > TMath::PiOver2()) luttheta = TMath::Pi()-luttheta;
295 tangle = momInBar.Angle(dir);
297 double bartime = lenz/cos(luttheta)/DIRC_LIGHT_V;
298 double totalTime = bartime+evtime;
301 double locDeltaT = totalTime-hitTime;
303 if(DIRC_DEBUG_HISTS) {
304 dapp->RootWriteLock();
305 hTime->Fill(hitTime);
306 hCalc->Fill(totalTime);
308 if(fabs(tangle-0.5*(locExpectedAngle[
PiPlus]+locExpectedAngle[
KPlus]))<0.2){
309 hDiff->Fill(locDeltaT);
310 hDiff_Pixel[box]->Fill(channel%dMaxChannels, locDeltaT);
312 hDiffT->Fill(locDeltaT);
313 if(r) hDiffR->Fill(locDeltaT);
314 else hDiffD->Fill(locDeltaT);
321 if(fabs(locDeltaT) < 100.0 && fabs(tangle-0.5*(locExpectedAngle[
PiPlus]+locExpectedAngle[
KPlus]))<0.2) {
322 locDIRCPhoton.first = totalTime;
323 locDIRCPhoton.second = tangle;
324 locDIRCPhotons.push_back(locDIRCPhoton);
328 if(!r && fabs(locDeltaT)>DIRC_CUT_TDIFFD)
continue;
329 if( r && fabs(locDeltaT)>DIRC_CUT_TDIFFR)
continue;
331 if(DIRC_DEBUG_HISTS) {
332 dapp->RootWriteLock();
339 if(fabs(tangle-0.5*(locExpectedAngle[
PiPlus]+locExpectedAngle[KPlus]))>0.05)
continue;
348 meanThetaC += tangle;
349 meanDeltaT += locDeltaT;
352 for(uint loc_j = 0; loc_j<dFinalStatePIDs.size(); loc_j++) {
353 logLikelihoodSum[dFinalStatePIDs[loc_j]] += TMath::Log( CalcLikelihood(locExpectedAngle[dFinalStatePIDs[loc_j]], tangle));
360 return locDIRCPhotons;
364 vector<pair<double,double>>
DDIRCLut::CalcPhoton(
const DDIRCPmtHit *locDIRCHit,
double locFlightTime, TVector3 posInBar, TVector3 momInBar, map<Particle_t, double> locExpectedAngle,
double locAngle,
Particle_t locPID, map<Particle_t, double> &logLikelihoodSum)
const
366 int nPhotonsThetaC=0;
367 double meanThetaC=0.0, meanDeltaT=0.0;
369 return CalcPhoton(locDIRCHit, locFlightTime, posInBar, momInBar, locExpectedAngle, locAngle, locPID, logLikelihoodSum, nPhotonsThetaC, meanThetaC, meanDeltaT, isGood);
374 double locLikelihood = TMath::Exp(-0.5*( (locExpectedThetaC-locThetaC)/DIRC_SIGMA_THETAC * (locExpectedThetaC-locThetaC)/DIRC_SIGMA_THETAC ) ) + 0.00001;
376 return locLikelihood;
380 return acos(
sqrt(momInBar.Mag()*momInBar.Mag() + locMass*locMass)/momInBar.Mag()/dIndex);
385 map<Particle_t, double> locExpectedAngles;
386 for(uint loc_i = 0; loc_i<dFinalStatePIDs.size(); loc_i++) {
387 locExpectedAngles[dFinalStatePIDs[loc_i]] = acos(
sqrt(momInBar.Mag()*momInBar.Mag() +
ParticleMass(dFinalStatePIDs[loc_i])*
ParticleMass(dFinalStatePIDs[loc_i]))/momInBar.Mag()/dIndex);
389 return locExpectedAngles;
vector< pair< double, double > > CalcPhoton(const DDIRCPmtHit *locDIRCHit, double locFlightTime, TVector3 posInBar, TVector3 momInBar, map< Particle_t, double > locExpectedAngle, double locAngle, Particle_t locPID, map< Particle_t, double > &logLikelihoodSum, int &nPhotonsThetaC, double &meanThetaC, double &meanDeltaT, bool &isGood) const
static char * ParticleName_ROOT(Particle_t p)
double CalcAngle(TVector3 momInBar, double locMass) const
static char * ParticleType(Particle_t p)
double CalcLikelihood(double locExpectedThetaC, double locThetaC) const
DDIRCLutReader * GetDIRCLut(unsigned int run_number)
static double ParticleMass(Particle_t p)
bool CreateDebugHistograms()
bool CalcLUT(TVector3 locProjPos, TVector3 locProjMom, const vector< const DDIRCPmtHit * > locDIRCHits, double locFlightTime, Particle_t locPID, shared_ptr< DDIRCMatchParams > &locDIRCMatchParams, const vector< const DDIRCTruthBarHit * > locDIRCBarHits, map< shared_ptr< const DDIRCMatchParams >, vector< const DDIRCPmtHit * > > &locDIRCTrackMatchParams) const
map< Particle_t, double > CalcExpectedAngles(TVector3 momInBar) const
bool brun(JEventLoop *loop)