Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DTrackCandidate_factory_CDC.h
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DTrackCandidate_factory_CDC.h
4 // Created: Thu Sep 6 14:47:48 EDT 2007
5 // Creator: davidl (on Darwin Amelia.local 8.10.1 i386)
6 //
7 
8 #ifndef _DTrackCandidate_factory_CDC_
9 #define _DTrackCandidate_factory_CDC_
10 
11 #include <map>
12 #include <vector>
13 using namespace std;
14 
15 #include "TDirectory.h"
16 
17 #include <JANA/JFactory.h>
18 using namespace jana;
19 
20 #include "DTrackCandidate.h"
21 #include "DHelicalFit.h"
22 #include "CDC/DCDCTrackHit.h"
23 #include <DVector3.h>
24 #include <HDGEOMETRY/DGeometry.h>
26 
27 class DTrackCandidate_factory_CDC : public JFactory<DTrackCandidate>
28 {
29  public:
32  const char* Tag(void){return "CDC";}
33 
35  {
36  NONE = 0x000,
37  NOISE = 0x001,
38  USED = 0x002, //set if used in a super layer seed (whether that seed was rejected later or not)
39  OUT_OF_TIME = 0x004
40  };
41 
43  {
44  WIRE_DIRECTION_AXIAL = 0,
45  WIRE_DIRECTION_STEREOLEFT = 1, //rotated by 6 degrees counter-clockwise
46  WIRE_DIRECTION_STEREORIGHT = 2 //rotated by 6 degrees clockwise
47  };
48 
49  class DCDCTrkHit
50  {
51  public:
52  void Reset(void);
53  inline double Dist2(DCDCTrkHit* trkhit) const{return (trkhit->hit->wire->origin - this->hit->wire->origin).Mag2();}
54 
55  const DCDCTrackHit* hit;
56  unsigned int index;
57  unsigned int flags;
58  float var_z;
60  float dPhiStereo;
61  bool dValidStereoHitPosFlag; //false if prior to calc, or if hit doesn't intersect circle
62  };
63 
64  // Collection of adjacent DCDCTrkHit's on a ring.
66  {
67  public:
68  //hits are stored in order from the first straw to the last straw
69  //generally, this in order from lowest straw # to highest straw #
70  //unless it crosses straw = 1 barrier: then first straw is lowest-# straw with phi > pi, and last straw is highest-# straw with phi < pi
71  vector<DCDCTrkHit*> hits;
72  bool linked;
73  signed char ring;
74  };
75 
76  // Collection of information about a given potential spiral turn
77  typedef struct
78  {
79  signed char dSpiralTurnRingFlag; //-1 if potential turn looks like the track is turning back outwards, 1 if turning back inwards
80  signed char dDefiniteSpiralTurnRingFlag; //same as dSpiralTurnRingFlag if DEFINITE turn, 0 otherwise
81  signed char dSpiralTurnRing; //is ring# of turn
83 
84  // Collection of adjacent DCDCRingSeed's in a super layer
86  {
87  public:
88  void Reset(void);
89  bool Are_AllHitsOnRingShared(const DCDCSuperLayerSeed* locCDCSuperLayerSeed, int locRing) const;
90  inline void Get_Hits(vector<DCDCTrkHit*>& locHits) const
91  {
92  locHits.clear();
93  for(size_t loc_i = 0; loc_i < dCDCRingSeeds.size(); ++loc_i)
94  locHits.insert(locHits.end(), dCDCRingSeeds[loc_i].hits.begin(), dCDCRingSeeds[loc_i].hits.end());
95  }
96 
97  vector<DCDCRingSeed> dCDCRingSeeds; //stored in order from innermost (lowest) ring to outermost (highest) ring
98  unsigned char dSuperLayer;
99  unsigned int dSeedIndex;
100  bool linked;
102  map<int, DSpiralParams_t> dSpiralLinkParams; //key is the dSeedIndex of the DCDCSuperLayerSeed in this super layer it is linked to (can point to itself (self-linked)!)
103  };
104 
105  // Collection of adjacent DCDCSuperLayerSeed's in the CDC
106  // Each unique combination of axial DCDCSuperLayerSeed's has it's own DCDCTrackCircle object
107  // Every possible combination of stereo DCDCSuperLayerSeed's used to link these axial DCDCSuperLayerSeed's together is stored in the 2D-vectors
108  // This is until the best combination is found: then the unused combinations are cleared and only one combination will remain
110  {
111  public:
112  void Reset(void);
113  DCDCSuperLayerSeed* Get_LastSuperLayerSeed(void) const;
114  DCDCSuperLayerSeed* Get_SuperLayerSeed(unsigned int locSuperLayer) const;
115  void Strip_StereoSuperLayerSeed(unsigned int locSuperLayer);
116  void Add_LastSuperLayerSeed(DCDCSuperLayerSeed* locSuperLayerSeed);
117  void Truncate_Circle(unsigned int locNewLastSuperLayer);
118  void Absorb_TrackCircle(const DCDCTrackCircle* locTrackCircle);
119  bool Check_IfInputIsSubset(const DCDCTrackCircle* locTrackCircle);
120  void Get_AllStereoSuperLayerSeeds(vector<DCDCSuperLayerSeed*>& locStereoSuperLayerSeeds);
121  unsigned int Get_NumStereoSuperLayerSeeds(void);
122 
123  vector<DCDCSuperLayerSeed*> dSuperLayerSeeds_Axial;
124  //for dSuperLayerSeeds_InnerStereo and dSuperLayerSeeds_OuterStereo:
125  //each vector<DCDCSuperLayerSeed*> is a series of adjacent stereo seeds that could potentially belong together
126  //for example:
127  // dSuperLayerSeeds_InnerStereo[0] is likely (not necessarily) a vector with size = 2:
128  //the first in this vector is a DCDCSuperLayerSeed from super layer 2 (SL2), the second is from SL3 and is definitely adjacent to the one from SL2.
129  // dSuperLayerSeeds_InnerStereo[1] is also likely a vector with size = 2, but a different combination of adjacent super layer seeds than the previous one.
130  // once the best seeds have been selected, dSuperLayerSeeds_InnerStereo will have size = 1.
131  //the reason that InnerStereo and OuterStereo are kept separately is to keep track of all possible combinations of adjacent super layers
132  //that way they are evaluated together when determining which stereo super layer seeds are best
133  //Note: if super layer 4 is missing (e.g. dead high voltage board), but inner (and/or outer) super layers are present, all super layers will be "inner"
134  //this is so that the stereo super layer combinatorics are evaluated correctly in the Find_ThetaZ() function
135  //Note: if super layers 1 through 3 are missing (e.g. a decay product), then dSuperLayerSeeds_InnerStereo will be empty
136  vector<vector<DCDCSuperLayerSeed*> > dSuperLayerSeeds_InnerStereo;
137  vector<vector<DCDCSuperLayerSeed*> > dSuperLayerSeeds_OuterStereo;
138 
139  DHelicalFit* fit; //the circle fit
140  float dWeightedChiSqPerDF; //of circle fit //weighted: is (chisq/ndf)/(#axial_super_layers^2): prefer fits with more axial super layers (not necessarily more hits)
141  float dWeightedChiSqPerDF_Stereo; //of theta/z determination //weighted: is (chisq/ndf)/(#axial_super_layers^2): prefer fits with more stereo super layers (not necessarily more hits)
142  float dAverageDriftTime; //of axial hits close to the circle fit
143  vector<unsigned int> HitBitPattern; //bit pattern of hits in the track circle (first is just axial, then is all)
144  float dTheta;
145  float dVertexZ;
146  signed char dSpiralTurnRing; //is ring# of confirmed match spiral turn, -1 if no turn
147 
148  //dTruncationSourceCircles: if this object's (not this member's) circle was truncated, this member points to the track circles that indicated truncation was necessary
149  //more than 1 possible if two circles were merged after truncation:
150  //e.g. two tracks have SL1 & SL4 but different SL7, and their SL7's are rejected by other tracks who have the same SL7s
151  vector<const DCDCTrackCircle*> dTruncationSourceCircles;
152  bool dHasNonTruncatedSeedsFlag_InnerStereo; //true if any inner stereo seeds are present and are unique: not from a truncated source
153  bool dHasNonTruncatedSeedsFlag_OuterStereo; //true if any outer stereo seeds are present and are unique: not from a truncated source
154  };
155 
157  {
158  public:
159  void BracketMinimumChisq(double &a,double &b, double &c, double &chi2a, double &chi2b, double &chi2c);
160  double FindMinimumChisq(double a, double b, double c, double &lambda);
161  double ChiXY(double lambda);
162 
163  unsigned int n;
164  vector<float> s;
165  vector<float> var_s;
166  vector<float> z;
167  vector<float> var_z;
168  vector<float> w;
169  float z0;
170  float tanl;
171  };
172 
173  typedef struct
174  {
175  float x, y, perp2;
176  float z, var_z;
177  } intersection_t;
178 
179  typedef vector<vector<DCDCRingSeed> >::iterator ringiter;
180 
181  private:
182  jerror_t init(void); ///< Called once at program start.
183  jerror_t brun(JEventLoop *locEventLoop, int32_t runnumber); ///< Called everytime a new run number is detected.
184  jerror_t evnt(JEventLoop *locEventLoop, uint64_t eventnumber); ///< Called every event.
185  jerror_t erun(void); ///< Called everytime run number changes, provided brun has been called.
186  jerror_t fini(void); ///< Called after last event of last event source has been processed.
187 
188  // Utility Functions
189  void Reset_Pools(void);
190  DCDCTrkHit* Get_Resource_CDCTrkHit(void);
191  DCDCSuperLayerSeed* Get_Resource_CDCSuperLayerSeed(void);
192  DHelicalFit* Get_Resource_HelicalFit(void);
193  DCDCTrackCircle* Get_Resource_CDCTrackCircle(void);
194 
195  // Make Super Layer Seeds
196  jerror_t Get_CDCHits(JEventLoop* loop);
197  void Find_SuperLayerSeeds(vector<DCDCTrkHit*>& locSuperLayerHits, unsigned int locSuperLayer);
198  void Link_RingSeeds(vector<DCDCRingSeed*>& parent, ringiter ring, ringiter ringend, unsigned int locSuperLayer, unsigned int locNumPreviousRingsWithoutHit);
199  double MinDist2(const DCDCRingSeed& locInnerRingSeed, const DCDCRingSeed& locOuterRingSeed);
200  double MinDist2(const vector<DCDCTrkHit*>& locInnerSeedHits, const vector<DCDCTrkHit*>& locOuterSeedHits);
201  void Reject_SuperLayerSeeds_HighSeedDensity(unsigned int locSuperLayer);
202  void Calc_SuperLayerPhiRange(DCDCSuperLayerSeed* locSuperLayerSeed, double& locSeedFirstPhi, double& locSeedLastPhi);
203  bool Check_IfPhiRangesOverlap(double locFirstSeedPhi, double locLastSeedPhi, double locTargetFirstPhi, double locTargetLastPhi);
204 
205  // Search for spirals
206  void Set_SpiralLinkParams(void);
207  bool SearchFor_SpiralTurn_TwoSeedsSharingManyHits(DCDCSuperLayerSeed* locSuperLayerSeed1, DCDCSuperLayerSeed* locSuperLayerSeed2);
208  bool SearchFor_SpiralTurn_TwoSeedsSharingFewHits(DCDCSuperLayerSeed* locSuperLayerSeed1, DCDCSuperLayerSeed* locSuperLayerSeed2);
209  bool SearchFor_SpiralTurn_ManyHitsAdjacentRing(DCDCSuperLayerSeed* locSuperLayerSeed1, DCDCSuperLayerSeed* locSuperLayerSeed2, int locRingToCheck, int locMinStrawsAdjacentRing, int& locMaxSpiralNumHits);
210  bool SearchFor_SpiralTurn_MissingOrBetweenRings(DCDCSuperLayerSeed* locSuperLayerSeed1, DCDCSuperLayerSeed* locSuperLayerSeed2);
211  bool SearchFor_SpiralTurn_SingleSeed(DCDCSuperLayerSeed* locSuperLayerSeed);
212  void Print_SuperLayerSeeds(void);
213 
214  //Link Super Layers to Create DCDCTrackCircle Objects
215  bool Build_TrackCircles(vector<DCDCTrackCircle*>& locCDCTrackCircles);
216  bool Link_SuperLayers(vector<DCDCTrackCircle*>& locCDCTrackCircles, unsigned int locOuterSuperLayer);
217  void Link_SuperLayers_FromAxial(vector<DCDCTrackCircle*>& locCDCTrackCircles, unsigned int locOuterSuperLayer, unsigned int locInnerSuperLayer);
218  void Link_SuperLayers_FromStereo(vector<DCDCTrackCircle*>& locCDCTrackCircles, unsigned int locOuterSuperLayer, unsigned int locInnerSuperLayer);
219  bool Link_SuperLayers_FromStereo_ToAxial(vector<DCDCTrackCircle*>& locCDCTrackCircles, unsigned int locOuterSuperLayer, unsigned int locInnerSuperLayer);
220  void Link_SuperLayers_FromStereo_ToStereo(vector<DCDCTrackCircle*>& locCDCTrackCircles, unsigned int locOuterSuperLayer, unsigned int locInnerSuperLayer);
221  bool Check_IfShouldAttemptLink(const DCDCSuperLayerSeed* locSuperLayerSeed, bool locInnerSeedFlag);
222  bool Attempt_SeedLink(DCDCSuperLayerSeed* locSuperLayerSeed1, DCDCSuperLayerSeed* locSuperLayerSeed2);
223  bool Attempt_SeedLink(DCDCRingSeed& locRingSeed1, DCDCRingSeed& locRingSeed2, wire_direction_t locWireDirection1, wire_direction_t locWireDirection2);
224  void Recycle_DCDCTrackCircle(DCDCTrackCircle* locCDCTrackCircle);
225 
226  // Continue DCDCTrackCircle Creation
227  void Print_TrackCircles(vector<DCDCTrackCircle*>& locCDCTrackCircles);
228  void Print_TrackCircle(DCDCTrackCircle* locCDCTrackCircle);
229  void Reject_DefiniteSpiralArms(vector<DCDCTrackCircle*>& locCDCTrackCircles);
230  void Drop_IncompleteGroups(vector<DCDCTrackCircle*>& locCDCTrackCircles);
231  void Fit_Circles(vector<DCDCTrackCircle*>& locCDCTrackCircles, bool locFitOnlyIfNullFitFlag, bool locAddStereoLayerIntersectionsFlag, bool locFitDuringLinkingFlag = false);
232  DVector3 Find_IntersectionBetweenSuperLayers(const DCDCSuperLayerSeed* locInnerSuperLayerSeed, const DCDCSuperLayerSeed* locOuterSuperLayerSeed);
233 
234  // Filter Track Circles and Stereo Wires
235  void Handle_StereoAndFilter(vector<DCDCTrackCircle*>& locCDCTrackCircles, bool locFinalPassFlag);
236  void Truncate_TrackCircles(vector<DCDCTrackCircle*>& locCDCTrackCircles);
237  void Set_HitBitPattern_Axial(vector<DCDCTrackCircle*>& locCDCTrackCircles);
238  void Filter_TrackCircles_Axial(vector<DCDCTrackCircle*>& locCDCTrackCircles);
239  void Create_NewCDCSuperLayerSeeds(DCDCTrackCircle* locCDCTrackCircle);
240  DCDCSuperLayerSeed* Create_NewStereoSuperLayerSeed(DCDCSuperLayerSeed* locCDCSuperLayerSeed, const DCDCTrackCircle* locCDCTrackCircle, map<DCDCTrkHit*, DCDCTrkHit*>& locProjectedStereoHitMap);
241  bool Calc_StereoPosition(const DCDCWire *wire, const DHelicalFit* fit, DVector3 &pos, double &var_z, double& locPhiStereo, double d = 0.0);
242 
243  // Select Best Stereo Seeds and Calculate Theta & Z
244  bool Select_CDCSuperLayerSeeds(DCDCTrackCircle* locCDCTrackCircle, bool locFinalPassFlag);
245  void Select_ThetaZStereoHits(const DCDCTrackCircle* locCDCTrackCircle, int locInnerSeedSeriesIndex, int locOuterSeedSeriesIndex, bool locFinalPassFlag, vector<DCDCTrkHit*>& locComboHits);
246  void Calc_StereoHitDeltaPhis(unsigned int locSuperLayer, vector<DCDCTrkHit*>& locHits, const DCDCTrackCircle* locCDCTrackCircle, vector<pair<DCDCTrkHit*, double> >& locDeltaPhis);
247  double MinDeltaPhi(const vector<DCDCTrkHit*>& locInnerSeedHits, const vector<DCDCTrkHit*>& locOuterSeedHits);
248  void Recycle_DCDCSuperLayerSeed(DCDCSuperLayerSeed* locCDCSuperLayerSeed);
249  bool Find_ThetaZ(const DHelicalFit* locFit, const vector<DCDCTrkHit*>& locStereoHits, double& locTheta, double& locZ, double& locChiSqPerNDF);
250  bool Find_ThetaZ_Regression(const DHelicalFit* locFit, const vector<DCDCTrkHit*>& locStereoHits, double& locTheta, double& locZ, double& locChiSqPerNDF);
251  bool Find_Theta(const DHelicalFit* locFit, const vector<DCDCTrkHit*>& locStereoHits, double& locTheta, double& locThetaMin, double& locThetaMax, double& locChiSqPerNDF);
252  bool Find_Z(const DHelicalFit* locFit, const vector<DCDCTrkHit*>& locStereoHits, double locThetaMin, double locThetaMax, double& locZ);
253  void Set_HitBitPattern_All(vector<DCDCTrackCircle*>& locCDCTrackCircles);
254  void Filter_TrackCircles_Stereo(vector<DCDCTrackCircle*>& locCDCTrackCircles);
255 
256  // Finalize and Create DTrackCandidate Objects
257  void Add_UnusedHits(vector<DCDCTrackCircle*>& locCDCTrackCircles);
258  void Create_TrackCandidiate(DCDCTrackCircle* locCDCTrackCircle);
259  bool Calc_PositionAndMomentum(DCDCTrackCircle* locCDCTrackCircle, DVector3 &pos, DVector3 &mom);
260 
262  unsigned int MAX_ALLOWED_CDC_HITS;
264  double MAX_HIT_DIST; // cm
265  double MAX_HIT_DIST2; // cm
266  unsigned int MIN_SEED_HITS;
273  unsigned int MAX_ALLOWED_TRACK_CIRCLES; //bail if exceed this many
275  unsigned int MAX_SUPERLAYER_NEW_TRACK; //don't allow new track seeds to start after this super layer //track seeds could start late if track is a decay product, or HV board is dead
282 
287 
288  double TARGET_Z;
289  double VERTEX_Z_MIN;
290  double VERTEX_Z_MAX;
291 
292  map<DCDCTrkHit*, unsigned int> dStereoHitNumUsedMap; //map of circle-projected (hit-z-group) hit to # DCDCSuperLayerSeeds it's in (when drops to 0, can recycle the hit memory)
293 
294  // Resource Pools for saving time and re-using memory
295  vector<DCDCTrkHit*> dCDCTrkHitPool_Available;
296  vector<DCDCTrkHit*> dCDCTrkHitPool_All;
297 
298  vector<DCDCSuperLayerSeed*> dCDCSuperLayerSeedPool_Available;
299  vector<DCDCSuperLayerSeed*> dCDCSuperLayerSeedPool_All;
300 
301  vector<DCDCTrackCircle*> dCDCTrackCirclePool_Available;
302  vector<DCDCTrackCircle*> dCDCTrackCirclePool_All;
303 
304  vector<DHelicalFit*> dHelicalFitPool_All;
305  vector<DHelicalFit*> dHelicalFitPool_Available;
306 
307  vector<unsigned int> dNumStrawsPerRing; //index is ring index
308  vector<unsigned int> superlayer_boundaries;
309 
310  unsigned int dNumCDCHits;
311  vector<DCDCTrkHit*> cdctrkhits;
312  vector<vector<DCDCTrkHit*> > cdchits_by_superlayer;
313  vector<vector<DCDCSuperLayerSeed*> > dSuperLayerSeeds; //index 0 -> 6 is super layer 1 -> 7
314 
317 
319  //dRejectedPhiRegions: due to hit density being too high in that region
320  map<unsigned int, vector<pair<double, double> > > dRejectedPhiRegions; //key is super layer, pair is first/last phi (not necessarily min/max! (could pass thorugh phi = 0 barrier))
321 };
322 
323 #endif // _DTrackCandidate_factory_CDC_
324 
const DMagneticFieldMap * dMagneticField
const DCDCWire * wire
Definition: DCDCTrackHit.h:37
TVector3 DVector3
Definition: DVector3.h:14
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
#define c
vector< DHelicalFit * > dHelicalFitPool_Available
vector< const DCDCTrackCircle * > dTruncationSourceCircles
vector< vector< DCDCSuperLayerSeed * > > dSuperLayerSeeds_InnerStereo
vector< vector< DCDCSuperLayerSeed * > > dSuperLayerSeeds_OuterStereo
map< DCDCTrkHit *, unsigned int > dStereoHitNumUsedMap
void Get_Hits(vector< DCDCTrkHit * > &locHits) const
vector< DHelicalFit * > dHelicalFitPool_All
vector< vector< DCDCTrkHit * > > cdchits_by_superlayer
vector< DCDCTrkHit * > dCDCTrkHitPool_Available
vector< vector< DCDCSuperLayerSeed * > > dSuperLayerSeeds
vector< DCDCTrackCircle * > dCDCTrackCirclePool_Available
vector< vector< DCDCRingSeed > >::iterator ringiter
vector< DCDCTrackCircle * > dCDCTrackCirclePool_All
vector< DCDCSuperLayerSeed * > dCDCSuperLayerSeedPool_All
vector< DCDCSuperLayerSeed * > dCDCSuperLayerSeedPool_Available
map< unsigned int, vector< pair< double, double > > > dRejectedPhiRegions
vector< unsigned int > superlayer_boundaries