12 #include <JANA/JCalibration.h>
34 _DBG_<<
"FDC geometry not available!" <<endl;
38 JCalibration *jcalib = dapp->GetJCalibration(runnumber);
39 map<string, double> targetparms;
40 if (jcalib->Get(
"TARGET/target_parms",targetparms)==
false){
41 TARGET_Z = targetparms[
"TARGET_Z_POSITION"];
48 gPARMS->SetDefaultParameter(
"TRKFIND:DEBUG_HISTS",
DEBUG_HISTS);
51 gPARMS->SetDefaultParameter(
"TRKFIND:BEAM_VAR",
BEAM_VAR);
61 "Matching distance for connecting FDC segments",
66 match_center_dist2=
new TH2F(
"match_center_dist2",
"matching distance squared between two circle centers vs p",50,0,1.5,100,0,100);
114 if (a->
q!=b->
q)
return a->
q<b->
q;
121 return (a->
hits[0]->wire->origin.z()<b->
hits[0]->wire->origin.z());
132 vector<const DFDCSegment*>segments;
133 eventLoop->Get(segments);
136 if (segments.size()==0.)
return NOERROR;
141 vector<DFDCSegment*>packages[4];
142 for (
unsigned int i=0;i<segments.size();i++){
148 vector<vector<int> >is_paired;
149 for (
unsigned int i=0;i<4;i++){
150 vector<int>
temp(packages[i].
size());
151 is_paired.push_back(temp);
155 vector<pair<const DFDCSegment*,const DFDCSegment*> >paired_segments;
156 for (
unsigned int i=0;i<3;i++){
157 if (packages[i].
size()>0)
LinkSegments(i,packages,paired_segments,is_paired);
161 vector<vector<const DFDCSegment *> >triplets;
162 vector<int>is_tripled(paired_segments.size());
163 for (
unsigned int i=0;i<paired_segments.size();i++){
164 for (
unsigned int j=0;j<paired_segments.size();j++){
166 if (is_tripled[i] || is_tripled[j])
continue;
167 if (paired_segments[i].second==paired_segments[j].first){
171 vector<const DFDCSegment *>triplet;
172 triplet.push_back(paired_segments[i].first);
173 triplet.push_back(paired_segments[i].second);
174 triplet.push_back(paired_segments[j].second);
175 triplets.push_back(triplet);
182 vector<int>is_quadrupled(triplets.size());
183 vector<vector<const DFDCSegment *> >quadruplets;
184 for (
unsigned int i=0;i<triplets.size();i++){
185 for (
unsigned int j=0;j<paired_segments.size();j++){
186 if (is_tripled[j] || is_quadrupled[i])
continue;
187 if (triplets[i][2]==paired_segments[j].first){
191 vector<const DFDCSegment*>quadruplet=triplets[i];
192 quadruplet.push_back(paired_segments[j].second);
193 quadruplets.push_back(quadruplet);
200 vector<vector<const DFDCSegment *> >mytracks;
201 for (
unsigned int i=0;i<quadruplets.size();i++){
202 mytracks.push_back(quadruplets[i]);
206 for (
unsigned int i=0;i<is_tripled.size();i++){
207 if (is_tripled[i]==0){
208 vector<const DFDCSegment *>mytrack;
209 mytrack.push_back(paired_segments[i].first);
210 mytrack.push_back(paired_segments[i].second);
211 mytracks.push_back(mytrack);
216 for (
unsigned int i=0;i<triplets.size();i++){
217 if (is_quadrupled[i]==0){
218 mytracks.push_back(triplets[i]);
224 for (
unsigned int i=0;i<mytracks.size();i++){
233 for (
unsigned int m=0;m<mytracks[i].size();m++){
234 rc+=mytracks[i][m]->rc;
235 xc+=mytracks[i][m]->xc;
236 yc+=mytracks[i][m]->yc;
237 tanl+=mytracks[i][m]->tanl;
238 for (
unsigned int n=0;n<mytracks[i][m]->hits.size();n++){
239 const DFDCPseudo *hit=mytracks[i][m]->hits[n];
242 double r=hit->
xy.Mod();
248 double mysize=double(mytracks[i].
size());
264 const DFDCPseudo *myhit=mytracks[0][0]->hits[0];
266 double p=0.003*fit.
r0*Bz/cos(atan(fit.
tanl));
277 if (
rc<0.5*max_r && max_r<10.0){
309 for (
unsigned int m=0;m<mytracks[i].size();m++){
310 track->AddAssociatedObject(mytracks[i][m]);
313 _data.push_back(track);
319 for (
unsigned int i=0;i<4;i++){
320 for (
unsigned int k=0;k<packages[i].size();k++){
326 vector<pair<unsigned int,unsigned int> >unused_segments;
327 for (
unsigned int j=0;j<4;j++){
328 for (
unsigned int i=0;i<packages[j].size();i++){
329 if (is_paired[j][i]==0){
330 unused_segments.push_back(make_pair(j,i));
336 if (unused_segments.size()>1){
338 unused_segments.clear();
339 for (
unsigned int j=0;j<4;j++){
340 for (
unsigned int i=0;i<packages[j].size();i++){
341 if (is_paired[j][i]==0){
342 unused_segments.push_back(make_pair(j,i));
346 if (unused_segments.size()>1){
353 for (
unsigned int j=0;j<4;j++){
354 for (
unsigned int i=0;i<packages[j].size();i++){
355 if (is_paired[j][i]==0){
364 track->
rc=segment->
rc;
365 track->
xc=segment->
xc;
366 track->
yc=segment->
yc;
374 track->AddAssociatedObject(segment);
376 _data.push_back(track);
390 double sin2ks=
sin(twoks);
391 double cos2ks=cos(twoks);
392 double one_minus_cos2ks=1.-cos2ks;
393 double one_over_twokappa=1./
twokappa;
397 double dx=x-hit->
xy.X();
398 double dy=y-hit->
xy.Y();
400 return (dx*dx+dy*dy);
406 vector<DFDCSegment*>package,
407 unsigned int &match_id){
415 double doca2_min=1e6,doca2;
416 for (
unsigned int j=0;j<package.size();j++){
420 if (doca2<doca2_min){
432 if (match!=NULL)
return match;
437 for (
unsigned int i=0;i<package.size();i++){
441 if (doca2<doca2_min){
449 if (match!=NULL)
return match;
452 double circle_center_diff2_min=1e6;
453 for (
unsigned int j=0;j<package.size();j++){
456 double dx=segment->
xc-segment2->
xc;
457 double dy=segment->
yc-segment2->
yc;
458 double circle_center_diff2=dx*dx+dy*dy;
460 if (circle_center_diff2<circle_center_diff2_min){
461 circle_center_diff2_min=circle_center_diff2;
462 if (circle_center_diff2_min<9.0){
479 xs=segment->
xc+segment->
rc*cos(segment->
Phi1);
481 zs=segment->
hits[0]->wire->origin.z();
485 double my_phi0=segment->
phi0;
486 double my_tanl=segment->
tanl;
493 double cosp=cos(my_phi0);
494 double sinp=
sin(my_phi0);
496 double sin2ks=
sin(twoks);
497 double cos2ks=cos(twoks);
503 p=0.003*Bz*segment->
rc/cos(atan(my_tanl));
505 cosphi=cosp*cos2ks-sinp*sin2ks;
506 sinphi=sinp*cos2ks+cosp*sin2ks;
515 vector<const DFDCSegment *>segments,
519 const DFDCPseudo *hit=segments[0]->hits[segments[0]->hits.size()-1];
521 double xhit=hit->
xy.X();
522 double yhit=hit->
xy.Y();
527 double phi1=atan2(yhit-
yc,xhit-
xc);
528 double q_over_rc_tanl=
q/(
rc*
tanl);
529 double dphi_s=dz*q_over_rc_tanl;
530 double dphi1=phi1-dphi_s;
531 double x=
xc+
rc*cos(dphi1);
533 pos.SetXYZ(x,y,zmin);
541 unsigned int num_segments=segments.size();
542 double zmax=segments[num_segments-1]->hits[0]->wire->origin.z();
543 unsigned int num_samples=20*num_segments;
544 double one_over_denom=1./double(num_samples);
545 dz=(zmax-
zmin)*one_over_denom;
546 for (
unsigned int i=0;i<num_samples;i++){
547 double my_dphi=phi1+(z-
zmin)*q_over_rc_tanl;
548 x=
xc+
rc*cos(my_dphi);
554 Bz=fabs(Bz)*one_over_denom;
558 double pt=0.003*Bz*
rc;
559 double px=pt*
sin(dphi1);
560 double py=pt*cos(dphi1);
562 mom.SetXYZ(px,py,pz);
577 double xhit=hit->
xy.X();
578 double yhit=hit->
xy.Y();
583 double phi1=atan2(yhit-segment->
yc,xhit-segment->
xc);
584 double q_over_rc_tanl=segment->
q/(segment->
rc*segment->
tanl);
585 double dphi_s=dz*q_over_rc_tanl;
586 double dphi1=phi1-dphi_s;
587 double x=segment->
xc+segment->
rc*cos(dphi1);
588 double y=segment->
yc+segment->
rc*
sin(dphi1);
589 pos.SetXYZ(x,y,zmin);
598 double pt=0.003*Bz*segment->
rc;
599 double px=pt*
sin(dphi1);
600 double py=pt*cos(dphi1);
601 double pz=pt*segment->
tanl;
602 mom.SetXYZ(px,py,pz);
611 vector<DFDCSegment *>packages[4], vector<pair<const DFDCSegment*,const DFDCSegment*> >&paired_segments,
612 vector<vector<int> >&is_paired){
613 unsigned int match_id=0;
614 unsigned int pack2=pack1+1;
617 for (
unsigned int i=0;i<packages[pack1].size();i++){
622 if (packages[pack2].
size()>0
623 && (match2=
GetTrackMatch(segment,packages[pack2],match_id))!=NULL){
624 if (is_paired[pack2][match_id])
continue;
626 pair<const DFDCSegment*,const DFDCSegment*> mypair;
627 mypair.first=segment;
628 mypair.second=match2;
629 paired_segments.push_back(mypair);
630 is_paired[pack2][match_id]=1;
631 is_paired[pack1][i]=1;
647 double dx=hit->
xy.X()-pos.x();
648 double dy=hit->
xy.Y()-pos.y();
649 double d2=dx*dx+dy*dy;
650 if (d2<
Match(mom.Mag()))
return true;
659 for (
unsigned int i=0;i<_data.size();i++){
660 bool got_segment_in_package=
false;
663 vector<const DFDCSegment*>segments;
664 _data[i]->GetT(segments);
667 for (
unsigned int j=0;j<segments.size();j++){
668 if (segments[j]->package==segment->
package){
669 got_segment_in_package=
true;
673 if (got_segment_in_package==
false){
680 if (segment->
hits[0]->wire->origin.z()<pos.z()){
684 bool got_match=
GetTrackMatch(_data[i]->charge(),pos,mom,segment);
686 if (got_match==
false){
687 double dx=segment->
xc-_data[i]->xc;
688 double dy=segment->
yc-_data[i]->yc;
689 if (dx*dx+dy*dy<9.0) got_match=
true;
693 _data[i]->AddAssociatedObject(segment);
696 segments.push_back(segment);
704 for (
unsigned int m=0;m<segments.size();m++){
705 for (
unsigned int k=0;k<segments[m]->hits.size();k++){
709 double r=hit->
xy.Mod();
717 if (fit.FitTrackRiemann(_data[i]->rc)==NOERROR){
727 double p=0.003*fit.r0*Bz/cos(atan(fit.tanl));
738 if (
rc<0.5*max_r && max_r<10.0){
743 fit.FitTrack_FixedZvertex(
TARGET_Z);
748 fit.FindSenseOfRotation();
755 _data[i]->chisq=fit.chisq;
756 _data[i]->Ndof=fit.ndof;
758 _data[i]->setPosition(pos);
759 _data[i]->setMomentum(mom);
771 vector<DFDCSegment *>packages[4],
772 vector<vector<int> >&is_paired){
773 DHoughFind hough(-400.0, +400.0, -400.0, +400.0, 100, 100);
775 vector<pair<unsigned int, unsigned int> >associated_segments;
776 for (
unsigned int i=0;i<unused_segments.size();i++){
777 unsigned int packNum=unused_segments[i].first;
778 unsigned int segmentNum=unused_segments[i].second;
779 const DFDCSegment* segment=packages[packNum][segmentNum];
780 for (
unsigned int m=0;m<segment->
hits.size();m++){
782 associated_segments.push_back(unused_segments[i]);
790 hough.
SetLimits(Ro.X()-width, Ro.X()+width, Ro.Y()-width, Ro.Y()+width,
796 hough.
SetLimits(Ro.X()-width, Ro.X()+width, Ro.Y()-width, Ro.Y()+width, 100, 100);
799 vector<DVector2> points=hough.
GetPoints();
800 set<pair<unsigned int, unsigned int> >associated_segments_to_use;
801 unsigned int num_hits_to_use=0;
802 for (
unsigned int m=0;m<points.size();m++){
810 double dist = fabs(g.X()*Ro_minus_h.Y() - g.Y()*Ro_minus_h.X());
816 associated_segments_to_use.emplace(associated_segments[m]);
819 if (num_hits_to_use>5&&associated_segments_to_use.size()>1){
820 bool same_package=
false;
821 set<pair<unsigned int,unsigned int> >::iterator it=associated_segments_to_use.begin();
822 for (; it!=associated_segments_to_use.end(); ++it){
823 unsigned int first_packNo=(*it).first;
824 unsigned int first_segmentNo=(*it).second;
825 set<pair<unsigned int,unsigned int> >::iterator it2=associated_segments_to_use.begin();
826 for (; it2!=associated_segments_to_use.end(); ++it2){
827 unsigned int packNo=(*it2).first;
828 unsigned int segmentNo=(*it2).second;
829 if (packNo==first_packNo){
830 if (segmentNo==first_segmentNo)
continue;
837 if (same_package==
false){
840 set<pair<unsigned int,unsigned int> >::iterator it=associated_segments_to_use.begin();
842 bool got_first_segment=
false;
843 for (; it!=associated_segments_to_use.end(); ++it){
844 unsigned int packNo=(*it).first;
845 unsigned int segmentNo=(*it).second;
847 if (got_first_segment==
false){
848 first_segment=segment;
849 got_first_segment=
true;
851 for (
unsigned int m=0;m<segment->
hits.size();m++){
879 for (it=associated_segments_to_use.begin();
880 it!=associated_segments_to_use.end(); ++it){
881 unsigned int packNo=(*it).first;
882 unsigned int segmentNo=(*it).second;
884 track->AddAssociatedObject(segment);
885 is_paired[packNo][segmentNo]=1;
888 _data.push_back(track);
void setMomentum(const DVector3 &aMomentum)
DVector2 xy
rough x,y coordinates in lab coordinate system
bool GetFDCZ(vector< double > &z_wires) const
z-locations for each of the FDC wire planes in cm
bool SwimToPlane(DVector3 &pos, DVector3 &mom, const DVector3 &origin, const DVector3 &norm, double *pathlen=NULL)
bool LinkSegmentsHough(vector< pair< unsigned int, unsigned int > > &unused_segements, vector< DFDCSegment * >packages[4], vector< vector< int > > &is_paired)
DMagneticFieldMap * GetBfield(unsigned int run_number=1)
bool LinkStraySegment(const DFDCSegment *segment)
const DFDCWire * wire
DFDCWire for this wire.
class DFDCPseudo: definition for a reconstructed point in the FDC
void AddPoint(const DVector2 &point)
DMagneticFieldStepper class.
bool DTrackCandidate_segment_cmp(const DFDCSegment *a, const DFDCSegment *b)
double DocaSqToHelix(const DFDCPseudo *hit)
jerror_t AddHitXYZ(float x, float y, float z)
jerror_t AddHit(float r, float phi, float z)
vector< const DFDCPseudo * > hits
TH2F * match_center_dist2
void SetLimits(double xmin, double xmax, double ymin, double ymax, unsigned int Nbinsx, unsigned int Nbinsy)
DGeometry * GetDGeometry(unsigned int run_number)
const DMagneticFieldMap * bfield
vector< DVector2 > GetPoints(void)
jerror_t evnt(JEventLoop *eventLoop, uint64_t eventnumber)
Called every event.
jerror_t FitTrackRiemann(float rc)
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
<A href="index.html#legend"> <IMG src="CORE.png" width="100"> </A>
void setPID(Particle_t locPID)
virtual double GetBz(double x, double y, double z) const =0
jerror_t brun(JEventLoop *eventLoop, int32_t runnumber)
Called everytime a new run number is detected.
double FactorForSenseOfRotation
float chisq
Chi-squared for the track (not chisq/dof!)
void FindSenseOfRotation(void)
double FDC_HOUGH_THRESHOLD
double GetMaxBinContent(void)
jerror_t GetPositionAndMomentum(const DFDCSegment *segment)
jerror_t FitTrack_FixedZvertex(float z_vertex)
jerror_t fini(void)
Called after last event of last event source has been processed.
jerror_t PruneHit(int idx)
int Ndof
Number of degrees of freedom in the fit.
void setPosition(const DVector3 &aPosition)
bool DTrackCandidate_segment_cmp_by_z(const DFDCSegment *a, const DFDCSegment *b)
class DFDCSegment: definition for a track segment in the FDC
jerror_t SetStepSize(double step)
bool GetTargetZ(double &z_target) const
z-location of center of target
void LinkSegments(unsigned int pack1, vector< DFDCSegment * >packages[4], vector< pair< const DFDCSegment *, const DFDCSegment * > > &paired_segments, vector< vector< int > > &is_paired)
DMagneticFieldStepper * stepper
DFDCSegment * GetTrackMatch(DFDCSegment *segment, vector< DFDCSegment * >package, unsigned int &match_id)