11 #include <TPolyLine.h>
14 #define MAX_STEPS 1000
17 #include <JANA/JApplication.h>
40 ascnd=(xx[n-1]>=xx[0]);
43 if ( (x>=xx[jm])==ascnd)
48 if (x==xx[0])
return 0;
49 else if (x==xx[n-1])
return n-2;
61 double frac=(t-cdc_drift_table[
index])/dt;
62 d=0.01*(double(index)+frac);
92 gPARMS->SetDefaultParameter(
"BCAL_CALIB:DEBUG_HISTS",DEBUG_HISTS);
94 DEBUG_PLOT_LINES=
false;
95 gPARMS->SetDefaultParameter(
"BCAL_CALIB:DEBUG_PLOT_LINES",DEBUG_PLOT_LINES);
99 Hcdc_prob = (TH1F*)gROOT->FindObject(
"Hcdc_prob");
101 Hcdc_prob=
new TH1F(
"Hcdc_prob",
"Confidence level for time-based fit",100,0.0,1.);
103 Hcdcmatch = (TH1F*)gROOT->FindObject(
"Hcdcmatch");
105 Hcdcmatch=
new TH1F(
"Hcdcmatch",
"CDC hit matching distance",1000,0.0,50.);
107 Hcdcmatch_stereo = (TH1F*)gROOT->FindObject(
"Hcdcmatch_stereo");
108 if (!Hcdcmatch_stereo){
109 Hcdcmatch_stereo=
new TH1F(
"Hcdcmatch_stereo",
"CDC stereo hit matching distance",1000,0.0,50.);
112 Hbcalmatchxy=(TH2F*)gROOT->FindObject(
"Hbcalmatchxy");
114 Hbcalmatchxy=
new TH2F(
"Hbcalmatchxy",
"BCAL #deltay vs #deltax",400,-50.,50.,
129 JCalibration *jcalib = dapp->GetJCalibration((loop->GetJEvent()).GetRunNumber());
130 typedef map<string,double>::iterator iter_double;
131 vector< map<string, double> > tvals;
132 if (jcalib->Get(
"CDC/cdc_drift_table", tvals)==
false){
133 for(
unsigned int i=0; i<tvals.size(); i++){
134 map<string, double> &row = tvals[i];
135 iter_double iter = row.find(
"t");
140 jerr <<
" CDC time-to-distance table not available... bailing..." << endl;
144 map<string, double> cdc_res_parms;
145 jcalib->Get(
"CDC/cdc_resolution_parms", cdc_res_parms);
146 CDC_RES_PAR1 = cdc_res_parms[
"res_par1"];
147 CDC_RES_PAR2 = cdc_res_parms[
"res_par2"];
177 vector<const DBCALShower*>bcalshowers;
178 loop->Get(bcalshowers);
181 vector<const DCDCTrackHit*>cdcs;
188 vector<const DCDCTrackHit*>axialhits;
189 vector<const DCDCTrackHit*>stereohits;
190 for (
unsigned int i=0;i<cdcs.size();i++){
191 int ring=cdcs[i]->wire->ring;
192 if (ring<=4) axialhits.push_back(cdcs[i]);
193 else if (ring<=12) stereohits.push_back(cdcs[i]);
194 else if (ring<=16) axialhits.push_back(cdcs[i]);
195 else if (ring<=24) stereohits.push_back(cdcs[i]);
196 else axialhits.push_back(cdcs[i]);
200 vector<cdc_segment_t>axial_segments;
201 vector<bool>used_axial(axialhits.size());
202 FindSegments(axialhits,axial_segments,used_axial);
204 if (axial_segments.size()>0 && stereohits.size()>0){
207 vector<cdc_track_t>tracks;
208 LinkSegments(axial_segments,used_axial,axialhits,stereohits,tracks);
210 for (
unsigned int i=0;i<tracks.size();i++){
213 vector<const DCDCTrackHit *>hits=tracks[i].axial_hits;
214 hits.insert(hits.end(),tracks[i].stereo_hits.begin(),tracks[i].stereo_hits.end());
220 for (
unsigned int j=0;j<hits.size();j++){
221 double L=(hits[0]->wire->origin-hits[j]->wire->origin).Perp();
222 double t_test=hits[j]->tdrift-L/29.98;
223 if (t_test<minT) minT=t_test;
228 if (GuessForStateVector(tracks[i],S)==NOERROR){
230 if (DoFilter(S,hits)==NOERROR){
231 MatchToBCAL(bcalshowers,S);
244 vector<const DCDCTrackHit *>&hits){
245 unsigned int numhits=hits.size();
246 unsigned int maxindex=numhits-1;
249 deque<trajectory_t>trajectory;
256 C0(state_x,state_x)=
C0(state_y,state_y)=1.0;
257 C0(state_tx,state_tx)=
C0(state_ty,state_ty)=0.01;
259 double chi2=1e16,chi2_old=1e16;
260 unsigned int ndof=0,ndof_old=0;
264 for(iter=0;iter<20;iter++){
269 if (SetReferenceTrajectory(mOuterZ,S,trajectory,
270 hits[maxindex])!=NOERROR)
break;
273 if (KalmanFilter(S,C,hits,trajectory,chi2,ndof)!=NOERROR)
277 if (fabs(chi2_old-chi2)<0.1
278 || TMath::Prob(chi2,ndof)<TMath::Prob(chi2_old,ndof_old))
break;
285 double prob=TMath::Prob(chi2_old,ndof_old);
291 pthread_mutex_lock(&mutex);
293 Hcdc_prob->Fill(prob);
296 pthread_mutex_unlock(&mutex);
304 if (DEBUG_PLOT_LINES){
305 PlotLines(trajectory);
312 return VALUE_OUT_OF_RANGE;
318 vector<cdc_segment_t>&segments,
319 vector<bool>&used_in_segment){
320 if (hits.size()==0)
return RESOURCE_UNAVAILABLE;
323 vector<pair<unsigned int,unsigned int> > pairs;
324 for (
unsigned int i=0;i<hits.size()-1;i++){
325 for (
unsigned int j=i+1;j<hits.size();j++){
326 int r1=hits[i]->wire->ring;
327 int r2=hits[j]->wire->ring;
328 int s1=hits[i]->wire->straw;
329 int s2=hits[j]->wire->straw;
330 double d=(hits[i]->wire->origin-hits[j]->wire->origin).Perp();
333 pthread_mutex_lock(&mutex);
335 pthread_mutex_unlock(&mutex);
339 || (abs(r1-r2)==0 && abs(s1-s2)==1)){
340 pair <unsigned int,unsigned int> mypair(i,j);
341 pairs.push_back(mypair);
346 for (
unsigned int i=0;i<pairs.size();i++){
347 if (used_in_segment[pairs[i].first]==
false
348 && used_in_segment[pairs[i].second]==
false){
349 vector<const DCDCTrackHit *>neighbors;
351 unsigned int old_first=pairs[old].first;
352 unsigned int old_second=pairs[old].second;
353 used_in_segment[old_first]=
true;
354 used_in_segment[old_second]=
true;
355 neighbors.push_back(hits[old_first]);
356 neighbors.push_back(hits[old_second]);
357 for (
unsigned int j=i+1;j<pairs.size();j++){
358 unsigned int first=pairs[j].first;
359 unsigned int second=pairs[j].second;
360 old_first=pairs[old].first;
361 old_second=pairs[old].second;
362 if ((used_in_segment[old_first] || used_in_segment[old_second])
363 && (first==old_first || first==old_second || second==old_second
364 || second==old_first)){
365 if (used_in_segment[first]==
false){
366 used_in_segment[first]=
true;
367 neighbors.push_back(hits[first]);
369 if (used_in_segment[second]==
false){
370 used_in_segment[second]=
true;
371 neighbors.push_back(hits[second]);
373 if (used_in_segment[old_first]==
false){
374 used_in_segment[old_first]=
true;
375 neighbors.push_back(hits[old_first]);
377 if (used_in_segment[old_second]==
false){
378 used_in_segment[old_second]=
true;
379 neighbors.push_back(hits[old_second]);
386 sort(neighbors.begin(),neighbors.end(),
cdc_hit_cmp);
387 mysegment.
dir=neighbors[neighbors.size()-1]->wire->origin
388 -neighbors[0]->wire->origin;
389 mysegment.
dir.SetMag(1.);
390 mysegment.
hits=neighbors;
392 segments.push_back(mysegment);
403 vector<const DCDCTrackHit *>&hits,
404 deque<trajectory_t>&trajectory,
405 double &chi2,
unsigned int &ndof,
413 double V=1.2*(0.78*0.78/12.);
422 unsigned int cdc_index=hits.size()-1;
424 const DCDCWire *wire=hits[cdc_index]->wire;
426 double z0=origin.z();
431 DVector3 wirepos=origin+((trajectory[0].z-z0)/vz)*wdir;
434 double dx=
S(state_x)-wirepos.X();
435 double dy=
S(state_y)-wirepos.Y();
436 double old_doca2=dx*dx+dy*dy;
443 for (
unsigned int k=1;k<trajectory.size();k++){
444 if (C(0,0)<=0. || C(1,1)<=0. || C(2,2)<=0. || C(3,3)<=0.)
445 return UNRECOVERABLE_ERROR;
448 S=trajectory[k].S+J*(S-S0);
460 wirepos=origin+((trajectory[k].z-z0)/wdir.z())*wdir;
463 dx=
S(state_x)-wirepos.X();
464 dy=
S(state_y)-wirepos.Y();
467 if (doca2>old_doca2 && more_hits){
469 double tx=
S(state_tx),ty=
S(state_ty);
470 DVector3 pos0(
S(state_x),
S(state_y),trajectory[k].z);
476 double dx0=diff.x(),dy0=diff.y();
477 double wdir_dot_diff=diff.Dot(wdir);
478 double tdir_dot_diff=diff.Dot(tdir);
479 double tdir_dot_wdir=tdir.Dot(wdir);
480 double D=1.-tdir_dot_wdir*tdir_dot_wdir;
481 double N=tdir_dot_wdir*wdir_dot_diff-tdir_dot_diff;
482 double N1=wdir_dot_diff-tdir_dot_wdir*tdir_dot_diff;
496 double one_over_d=1./d;
497 double diffx=diff.x(),diffy=diff.y(),diffz=diff.z();
499 H(state_x)=H_T(state_x)=diffx*one_over_d;
500 H(state_y)=H_T(state_y)=diffy*one_over_d;
502 double wx=wdir.x(),wy=wdir.y();
504 double dN1dtx=2.*tx*wdir_dot_diff-wx*tdir_dot_diff-tdir_dot_wdir*dx0;
505 double dDdtx=2.*tx-2.*tdir_dot_wdir*wx;
506 double dtdtx=scale*(dN1dtx-t*dDdtx);
508 double dN1dty=2.*ty*wdir_dot_diff-wy*tdir_dot_diff-tdir_dot_wdir*dy0;
509 double dDdty=2.*ty-2.*tdir_dot_wdir*wy;
510 double dtdty=scale*(dN1dty-t*dDdty);
512 double dNdtx=wx*wdir_dot_diff-dx0;
513 double dsdtx=scale*(dNdtx-s*dDdtx);
515 double dNdty=wy*wdir_dot_diff-dy0;
516 double dsdty=scale*(dNdty-s*dDdty);
518 H(state_tx)=H_T(state_tx)
519 =one_over_d*(diffx*(s+tx*dsdtx-wx*dtdtx)+diffy*(ty*dsdtx-wy*dtdtx)
520 +diffz*(dsdtx-dtdtx));
521 H(state_ty)=H_T(state_ty)
522 =one_over_d*(diffx*(tx*dsdty-wx*dtdty)+diffy*(s+ty*dsdty-wy*dtdty)
523 +diffz*(dsdty-dtdty));
526 double InvV=1./(V+H*C*H_T);
539 if (Ctest(0,0)>0.0 && Ctest(1,1)>0.0 && Ctest(2,2)>0.0 && Ctest(3,3)>0.0)
548 d=FindDoca(trajectory[k].z,S,wdir,origin);
552 double Vtemp=V-H*C*H_T;
560 return VALUE_OUT_OF_RANGE;
568 wire=hits[cdc_index]->wire;
573 wirepos=origin+((trajectory[k].z-z0)/vz)*wdir;
576 dx=
S(state_x)-wirepos.x();
577 dy=
S(state_y)-wirepos.y();
581 else more_hits=
false;
596 DMatrix4x4 J(1.,0.,1.,0., 0.,1.,0.,1., 0.,0.,1.,0., 0.,0.,0.,1.);
599 double dz=(
S(state_ty)>0.?-1.:1.)*ds/
sqrt(1.+
S(state_tx)*
S(state_tx)+
S(state_ty)*
S(state_ty));
605 unsigned int numsteps=0;
613 temp.
J(state_x,state_tx)=-dz;
614 temp.
J(state_y,state_ty)=-dz;
616 temp.
t=(t+=ds/29.98);
618 temp.
S(state_x)=
S(state_x)+
S(state_tx)*dz;
619 temp.
S(state_y)=
S(state_y)+
S(state_ty)*dz;
620 temp.
S(state_tx)=
S(state_tx);
621 temp.
S(state_ty)=
S(state_ty);
623 trajectory.push_front(temp);
627 }
while (
S(state_y)>min_y && numsteps<
MAX_STEPS);
629 if (trajectory.size()<2)
return UNRECOVERABLE_ERROR;
635 for (
unsigned int i=0;i<trajectory.size();i++){
636 printf(
" x %f y %f z %f\n",trajectory[i].
S(state_x),
637 trajectory[i].
S(state_y),trajectory[i].z);
648 vector<bool>&used_axial,
649 vector<const DCDCTrackHit *>&axial_hits,
650 vector<const DCDCTrackHit *>&stereo_hits,
651 vector<cdc_track_t>&LinkedSegments){
653 unsigned int num_axial=axial_segments.size();
654 for (
unsigned int i=0;i<num_axial-1;i++){
655 if (axial_segments[i].matched==
false){
659 DVector3 pos0=axial_segments[i].hits[0]->wire->origin;
660 DVector3 vhat=axial_segments[i].dir;
662 for (
unsigned int j=i+1;j<num_axial;j++){
663 if (axial_segments[j].matched==
false){
664 DVector3 pos1=axial_segments[j].hits[0]->wire->origin;
665 DVector3 dir1=axial_segments[j].hits[0]->wire->udir;
667 double s=diff.Dot(vhat);
668 double d=(diff-s*vhat).Mag();
671 pthread_mutex_lock(&mutex);
672 Hcdcmatch_stereo->Fill(d);
673 pthread_mutex_unlock(&mutex);
677 axial_segments[j].matched=
true;
679 axial_segments[j].hits.begin(),
680 axial_segments[j].hits.end());
694 bool got_match=
false;
695 for (
unsigned int j=0;j<axial_hits.size();j++){
696 if (used_axial[j]==
false){
697 if (MatchCDCHit(vhat,pos0,axial_hits[j])){
714 vector<unsigned int>used_stereo(stereo_hits.size());
715 for (
unsigned int j=0;j<stereo_hits.size();j++){
716 if (used_stereo[j]==
false){
717 if (MatchCDCHit(vhat,pos0,stereo_hits[j])){
725 if (num_stereo>0 && num_stereo+num_axial>4){
727 LinkedSegments.push_back(mytrack);
742 double vhat_dot_uhat=vhat.Dot(uhat);
743 double scale=1./(1.-vhat_dot_uhat*vhat_dot_uhat);
744 double s=scale*(vhat_dot_uhat*diff.Dot(vhat)-diff.Dot(uhat));
745 double t=scale*(diff.Dot(vhat)-vhat_dot_uhat*diff.Dot(uhat));
746 double d=(diff+s*uhat-t*vhat).Mag();
761 double vx=track.
dir.x();
762 double vy=track.
dir.y();
767 double sumv=0,sumx=0,sumy=0,sumz=0,sumxx=0,sumyy=0,sumxz=0,sumyz=0;
768 for (
unsigned int i=0;i<track.
stereo_hits.size();i++){
772 double ux_s=dir_s.x();
773 double uy_s=dir_s.y();
774 double dx=xa-origin_s.x();
775 double dy=ya-origin_s.y();
776 double s=(dx*vy-dy*vx)/(ux_s*vy-uy_s*vx);
778 double x=pos1.x(),
y=pos1.y(),z=pos1.z();
780 if (z>17.0 && z<167.0){
791 double xdenom=sumv*sumxz-sumx*sumz;
792 if (fabs(xdenom)<
EPS)
return VALUE_OUT_OF_RANGE;
794 double ydenom=sumv*sumyz-sumy*sumz;
795 if (fabs(ydenom)<
EPS)
return VALUE_OUT_OF_RANGE;
797 double xtemp=sumv*sumxx-sumx*sumx;
798 double xslope=xtemp/xdenom;
799 double ytemp=sumv*sumyy-sumy*sumy;
800 double yslope=ytemp/ydenom;
803 double z0y=(sumyy*sumz-sumy*sumyz)/ytemp;
806 double delta_z=(yslope>0)?0.5:-0.5;
809 mOuterZ=z0y+ya/yslope+delta_z;
811 S(state_x)=xa+xslope*delta_z;
812 S(state_y)=ya+yslope*delta_z;
831 double vhat_dot_diff=diff.Dot(vhat);
832 double uhat_dot_diff=diff.Dot(uhat);
833 double uhat_dot_vhat=uhat.Dot(vhat);
834 double D=1.-uhat_dot_vhat*uhat_dot_vhat;
835 double N=uhat_dot_vhat*vhat_dot_diff-uhat_dot_diff;
836 double N1=vhat_dot_diff-uhat_dot_vhat*uhat_dot_diff;
848 unsigned int last_index=traj.size()-1;
850 TCanvas *
c1=
dynamic_cast<TCanvas *
>(gROOT->FindObject(
"endviewA Canvas"));
853 TPolyLine *line=
new TPolyLine();
855 line->SetLineColor(1);
856 line->SetLineWidth(1);
858 line->SetNextPoint(traj[last_index].
S(state_x),traj[last_index].
S(state_y));
859 line->SetNextPoint(traj[0].
S(state_x),traj[0].
S(state_y));
867 c1=
dynamic_cast<TCanvas *
>(gROOT->FindObject(
"endviewA Large Canvas"));
870 TPolyLine *line=
new TPolyLine();
872 line->SetLineColor(1);
873 line->SetLineWidth(1);
875 line->SetNextPoint(traj[last_index].
S(state_x),traj[last_index].
S(state_y));
876 line->SetNextPoint(traj[0].
S(state_x),traj[0].
S(state_y));
884 c1=
dynamic_cast<TCanvas *
>(gROOT->FindObject(
"sideviewA Canvas"));
887 TPolyLine *line=
new TPolyLine();
889 line->SetLineColor(1);
890 line->SetLineWidth(1);
892 line->SetNextPoint(traj[last_index].z,traj[last_index].
S(state_x));
893 line->SetNextPoint(traj[0].z,traj[0].
S(state_x));
901 c1=
dynamic_cast<TCanvas *
>(gROOT->FindObject(
"sideviewB Canvas"));
904 TPolyLine *line=
new TPolyLine();
906 line->SetLineColor(1);
907 line->SetLineWidth(1);
909 line->SetNextPoint(traj[last_index].z,traj[last_index].
S(state_y));
910 line->SetNextPoint(traj[0].z,traj[0].
S(state_y));
925 double denom=
sqrt(
S(state_tx)*
S(state_tx)+
S(state_ty)*
S(state_ty));
926 double ux=
S(state_tx)/denom;
927 double uy=
S(state_ty)/denom;
928 double x0=
S(state_x);
929 double y0=
S(state_y);
932 vector<bcal_match_t>matching_bcals;
934 for (
unsigned int i=0;i<bcalshowers.size();i++){
935 double x=bcalshowers[i]->x,
y=bcalshowers[i]->y;
936 double s=(x-x0)*ux+(
y-y0)*uy;
944 pthread_mutex_lock(&mutex);
946 Hbcalmatchxy->Fill(dx,dy);
949 pthread_mutex_unlock(&mutex);
952 if (fabs(dx)<2.0 && fabs(dy)<1.0){
954 temp.
dir.SetXYZ(ux,uy,1.);
956 temp.
match=bcalshowers[i];
957 matching_bcals.push_back(temp);
960 if (matching_bcals.size()>0){
961 for (
unsigned int i=0;i<matching_bcals.size();i++){
bool MatchCDCHit(const DVector3 &vhat, const DVector3 &pos0, const DCDCTrackHit *hit)
bool cdc_hit_cmp(const DCDCTrackHit *a, const DCDCTrackHit *b)
jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber)
Called everytime a new run number is detected.
const DBCALShower * match
bool MatchToBCAL(vector< const DBCALShower * > &bcalshowers, DMatrix4x1 &S)
unsigned int locate(vector< double > &xx, double x)
double cdc_drift_distance(double t)
void PlotLines(deque< trajectory_t > &traj)
jerror_t KalmanFilter(DMatrix4x1 &S, DMatrix4x4 &C, vector< const DCDCTrackHit * > &hits, deque< trajectory_t > &trajectory, double &chi2, unsigned int &ndof, bool timebased=false)
static char index(char c)
~DEventProcessor_bcal_calib()
jerror_t SetReferenceTrajectory(double z, DMatrix4x1 &S, deque< trajectory_t > &trajectory, const DCDCTrackHit *last_cdc)
static void locate(const double *xx, int n, double x, int *j)
jerror_t init(void)
Called once at program start.
jerror_t fini(void)
Called after last event of last event source has been processed.
DEventProcessor_bcal_calib()
jerror_t GuessForStateVector(const cdc_track_t &track, DMatrix4x1 &S)
vector< const DCDCTrackHit * > stereo_hits
vector< const DCDCTrackHit * > hits
double FindDoca(double z, const DMatrix4x1 &S, const DVector3 &vhat, const DVector3 &origin)
vector< double > cdc_drift_table
jerror_t LinkSegments(vector< cdc_segment_t > &axial_segments, vector< bool > &used_axial, vector< const DCDCTrackHit * > &axial_hits, vector< const DCDCTrackHit * > &stereo_hits, vector< cdc_track_t > &LinkedSegments)
vector< const DCDCTrackHit * > axial_hits
jerror_t DoFilter(DMatrix4x1 &S, vector< const DCDCTrackHit * > &hits)
jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber)
Called every event.
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
jerror_t FindSegments(vector< const DCDCTrackHit * > &hits, vector< cdc_segment_t > &segments, vector< bool > &used_hits)
printf("string=%s", string)