View Javadoc

1   /*
2    * HelicalTrackHitDriver.java
3    *
4    * Created on November 30, 2007, 3:50 PM
5    *
6    */
7   
8   package org.lcsim.fit.helicaltrack;
9   
10  import hep.physics.matrix.SymmetricMatrix;
11  import hep.physics.vec.BasicHep3Vector;
12  import hep.physics.vec.Hep3Vector;
13  import hep.physics.vec.VecOp;
14  
15  import java.util.ArrayList;
16  import java.util.Arrays;
17  import java.util.HashMap;
18  import java.util.HashSet;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.Set;
22  
23  import org.lcsim.detector.IDetectorElement;
24  import org.lcsim.detector.ITransform3D;
25  import org.lcsim.detector.solids.LineSegment3D;
26  import org.lcsim.detector.tracker.silicon.SiSensor;
27  import org.lcsim.detector.tracker.silicon.SiTrackerModule;
28  import org.lcsim.event.base.MyLCRelation;
29  import org.lcsim.event.EventHeader;
30  import org.lcsim.event.LCRelation;
31  import org.lcsim.event.MCParticle;
32  import org.lcsim.event.RawTrackerHit;
33  import org.lcsim.event.SimTrackerHit;
34  import org.lcsim.event.TrackerHit;
35  import org.lcsim.event.base.BaseTrackerHitMC;
36  import org.lcsim.event.base.BaseHit;
37  import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
38  import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHit;
39  import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D;
40  import org.lcsim.recon.tracking.digitization.sisim.TrackerHitType.CoordinateSystem;
41  import org.lcsim.recon.tracking.vsegment.geom.SegmentationManager;
42  import org.lcsim.recon.tracking.vsegment.geom.Sensor;
43  import org.lcsim.recon.tracking.vsegment.geom.SensorType;
44  import org.lcsim.recon.tracking.vsegment.geom.sensortypes.Cylinder;
45  import org.lcsim.recon.tracking.vsegment.hit.DigiTrackerHit;
46  import org.lcsim.recon.tracking.vsegment.hit.TrackerCluster;
47  import org.lcsim.spacegeom.SpacePointVector;
48  import org.lcsim.util.Driver;
49  
50  /**
51   * Create the appropriate HelicalTrackHits for the specified TrackerHit
52   * collections.  The resulting HelicalTrackHits encapsulate the information
53   * needed to perform a helical track hit for either a segmented strip
54   * detector, a pixel detector, or cross hits from a stereo detector.
55   *
56   * At this time, this driver supports the virtual segmentation hits
57   * produced by the packages in contrib.onoprien.tracking.  Additional
58   * coding needs to be done to support fully segmented detectors.
59   *
60   * The list of hit collections to be converted must be specified
61   * before the process method is executed.
62   *
63   * Currently,
64   * @author Richard Partridge
65   * @version 1.0
66   */
67  public class HelicalTrackHitDriver extends Driver {
68      /**
69       * Type of hits to be converted/
70       */
71      public enum HitType {
72          /**
73           * Anything that uses BaseTrackerHit or BaseTrackerHitMC, for examples
74           * hits created by PixSim or TrackerHitCheater
75           */
76          Base,
77          /**
78           * Virtual segmentation (OldTrackerHit) hits.
79           */
80          VirtualSegmentation,
81          /**
82           *
83           *  Digitized (SiTrackerHit)
84           */
85          Digitized
86      }
87      protected StereoHitMaker _crosser = new StereoHitMaker(2., 10.);
88      protected HitIdentifier _ID = new HitIdentifier();
89      private SegmentationManager _segman;
90      private List<String> _vscol = new ArrayList<String>();
91      private List<String> _bscol = new ArrayList<String>();
92      private List<String> _digcol = new ArrayList<String>();
93      protected String _outname = "HelicalTrackHits";
94      protected String _hitrelname = "HelicalTrackHitRelations";
95      protected String _mcrelname = "HelicalTrackMCRelations";
96      private Hep3Vector _uloc = new BasicHep3Vector(1., 0., 0.);
97      private Hep3Vector _vloc = new BasicHep3Vector(0., 1., 0.);
98      private Hep3Vector _zhat = new BasicHep3Vector(0., 0., 1.);
99      protected Hep3Vector _orgloc = new BasicHep3Vector(0., 0., 0.);
100     private double _eps = 1.0e-6;
101     
102     /** Creates a new instance of HelicalTrackHitDriver */
103     public HelicalTrackHitDriver() {
104     }
105     
106     /**
107      * Create the HelicalTrackHits for the specified hit collections.
108      * @param event EventHeader of the event to be processed
109      */
110     @Override
111     public void process(EventHeader event) {
112         super.process(event);
113 
114         //  Initialize the list of HelicalTrackHits and vector with local z direction
115         List<HelicalTrackHit> helhits = new ArrayList<HelicalTrackHit>();
116         Hep3Vector lz = new BasicHep3Vector(0., 0., 1.);
117         
118         //  Create a List of LCRelations to relate HelicalTrackHits to the original hits
119         List<LCRelation> hitrelations = new ArrayList<LCRelation>();
120         
121         for (String colname : _bscol) {
122             List<TrackerHit> hitlist = (List<TrackerHit>) event.get(colname);
123             for (TrackerHit hit : hitlist) {
124                 Hep3Vector pos = new BasicHep3Vector(hit.getPosition());
125                 SymmetricMatrix cov = new SymmetricMatrix(3, hit.getCovMatrix(), true);
126                 TrackerHit ohit = hit;
127                 
128 //                try {
129                     //create a BaseTrackerHitMC from a BaseTrackerHit if necessary
130                     if (!(hit instanceof BaseTrackerHitMC)){
131                         List<SimTrackerHit> thesehits = new ArrayList<SimTrackerHit>();
132                         List<RawTrackerHit> rawhits = (List<RawTrackerHit>)hit.getRawHits();
133                         for (RawTrackerHit raw : rawhits) {
134                             if(raw.getSimTrackerHits() != null)
135                              thesehits.addAll(raw.getSimTrackerHits());
136                         }
137                         hit = new BaseTrackerHitMC(hit.getPosition(), hit.getCovMatrix(),
138                                 hit.getTime(), hit.getdEdx(), hit.getType(), thesehits);
139                         ((BaseTrackerHitMC)hit).addRawTrackerHits(rawhits);
140                         
141                     if(thesehits.size() != 0)
142                     {
143                     SimTrackerHit simhit = ((BaseTrackerHitMC)hit).getSimHits().get(0);
144                     HelicalTrackHit hthit = new HelicalTrack3DHit(pos, cov, hit.getdEdx(), hit.getTime(), hit.getRawHits(),
145                                 _ID.getName(simhit), _ID.getLayer(simhit), _ID.getBarrelEndcapFlag(simhit));
146 //                    IDetectorElementContainer cont = DetectorElementStore.getInstance().find(simhit.getIdentifier());
147 //                    if (cont.isEmpty()) {
148 //                        throw new RuntimeException("Detector Container is empty!");
149 //                    } else {
150 //                        IDetectorElement de = cont.get(0);
151                         
152                     for (MCParticle p : ((BaseTrackerHitMC)hit).mcParticles()) hthit.addMCParticle(p);
153                     hitrelations.add(new MyLCRelation(hthit, ohit));
154                     helhits.add(hthit);
155                     }
156                     else
157                     {
158                      if(rawhits.size() != 0)
159                      {
160                       IDetectorElement de = ((BaseHit) rawhits.get(0)).getDetectorElement();
161                     HelicalTrackHit hthit = new HelicalTrack3DHit(pos, cov, hit.getdEdx(), hit.getTime(), hit.getRawHits(),
162                                 _ID.getName(de), _ID.getLayer(de), _ID.getBarrelEndcapFlag(de));
163                      hitrelations.add(new MyLCRelation(hthit, ohit));
164                      helhits.add(hthit);
165       
166                      }
167                      else throw new RuntimeException("No way to identify de");
168                     } 
169                    }
170 //                }
171 //
172 //                } catch(Exception e) {
173 //                    System.out.println("Warning, could not complete Identification for smeared hits. Reason: "+e.getMessage());
174 //                    HelicalTrackHit hthit = new HelicalTrack3DHit(pos, cov, hit.getdEdx(), hit.getTime(),
175 //                            hit.getRawHits(), "Unknown", 0, BarrelEndcapFlag.BARREL);
176 //                    hitrelations.add(new MyLCRelation(hthit, ohit));
177 //                    helhits.add(hthit);
178 //                }
179             }
180         }
181         
182         //  Loop over the collections of hits with virtual segmentation
183         for (String colname : _vscol) {
184 
185             //  Get the segmentation manager if we haven't already done so
186             if (_segman == null) _segman = (SegmentationManager) event.get("SegmentationManager");
187             
188             //  Make a mapping between the stereo strips and corresponding hits
189             Map<HelicalTrackStrip, org.lcsim.recon.tracking.vsegment.hit.TrackerHit> stripmap =
190                     new HashMap<HelicalTrackStrip, org.lcsim.recon.tracking.vsegment.hit.TrackerHit>();
191             
192             //  Get the hit map that gives the list of hits on a particular sensor
193             Map<Sensor, List<org.lcsim.recon.tracking.vsegment.hit.TrackerHit>> hitmap =
194                     (Map<Sensor, List<org.lcsim.recon.tracking.vsegment.hit.TrackerHit>>) event.get(colname);
195             
196             //  Loop over sensors in the hit map
197             for (Sensor sensor : hitmap.keySet()) {
198                 //  Get a list of hits for this sensor and loop over the hits
199                 List<org.lcsim.recon.tracking.vsegment.hit.TrackerHit> sensorhits = hitmap.get(sensor);
200                 for (org.lcsim.recon.tracking.vsegment.hit.TrackerHit hit : sensorhits) {
201                     //  Convert to an old tracker hit for reference
202                     ArrayList<TrackerCluster> parents = new ArrayList<TrackerCluster>(1);
203                     parents.add(hit.getCluster());
204                     //  Check if we have a strip or pixel hit
205                     if (sensor.getType().getHitDimension() == 1) {
206                         //  Strip hit - now check if this hit is part of a stereo pair
207                         if (_segman.getStereoPartners(sensor) == null) {
208                             //  Isolated axial hit - convert it and add to the hit list
209                             HelicalTrackHit axialhit = MakeAxialHit(hit);
210                             if (axialhit != null) {
211                                 hitrelations.add(new MyLCRelation(axialhit, hit));
212                                 helhits.add(axialhit);
213                             }
214                         } else {
215                             //  Stereo hit - convert it and add it to the list of stereo strips
216                             HelicalTrackStrip strip = MakeStrip(hit);
217                             stripmap.put(strip, hit);
218                         }
219                     } else {
220                         //  Pixel hit - convert it and add to the hit list
221                         HelicalTrackHit pixelhit = MakePixelHit(hit);
222                         hitrelations.add(new MyLCRelation(pixelhit, hit));
223                         helhits.add(pixelhit);
224                     }
225                 }
226             }
227             
228             //  Make the stereo hits
229             List<HelicalTrackStrip> striplist = new ArrayList<HelicalTrackStrip>(stripmap.keySet());
230             List<HelicalTrackCross> stereohits = _crosser.MakeHits(striplist);
231             for (HelicalTrackCross hit : stereohits) {
232                 for (HelicalTrackStrip strip : hit.getStrips()) {
233                     hitrelations.add(new MyLCRelation(hit, stripmap.get(strip)));
234                 }
235                 helhits.add(hit);
236             }
237         }
238 
239         //  Loop over the collections of hits produced by the sisim digitization code
240         for (String colname : _digcol) {
241 
242             //  Get the list of SiTrackerHits for this collection
243             List<SiTrackerHit> hitlist = (List<SiTrackerHit>) event.get(colname);
244 
245             //  Create collections for modules, strip hits by sensor, and hit cross references
246             Set<SiTrackerModule> modules = new HashSet<SiTrackerModule>();
247             Map<SiSensor, List<HelicalTrackStrip>> sensormap = new HashMap<SiSensor, List<HelicalTrackStrip>>();
248             Map<HelicalTrackStrip, SiTrackerHitStrip1D> stripmap = new HashMap<HelicalTrackStrip, SiTrackerHitStrip1D>();
249 
250             //  Loop over the SiTrackerHits in this collection
251             for (SiTrackerHit hit : hitlist) {
252                 
253                 if (hit instanceof SiTrackerHitStrip1D) {
254                     //determine if the hit is stereoed or not
255                     SiTrackerHitStrip1D h = (SiTrackerHitStrip1D) hit;
256                     
257                     //  Get the sensor and parent modules
258                     SiSensor sensor = h.getSensor();
259                     SiTrackerModule m = (SiTrackerModule) sensor.getParent();
260 
261                     //  Check if we have a stereo hit (i.e., the module has 2 children)
262                     if (m.getChildren().size()==2) {
263                         
264                         //  Add the module to the set of modules containing stereo hits
265                         modules.add(m);
266 
267                         //  Create a HelicalTrackStrip for this hit
268                         HelicalTrackStrip strip = makeDigiStrip(h);
269 
270                         //  Get the list of strips for this module - create a new list if one doesn't already exist
271                         List<HelicalTrackStrip> modhits = sensormap.get(sensor);
272                         if (modhits == null) {
273                             modhits = new ArrayList<HelicalTrackStrip>();
274                             sensormap.put(sensor, modhits);
275                         }
276                         
277                         //  Add the strip to the list of strips on this sensor
278                         modhits.add(strip);
279                         
280                         //  Map a reference back to the hit needed to create the stereo hit LC relations
281                         stripmap.put(strip, h);
282 
283                     } else {
284                         //System.out.println("trying to make an axial hit???");
285                         HelicalTrackHit dah = makeDigiAxialHit(h);
286                         helhits.add(dah); //isolated hit
287                         hitrelations.add(new MyLCRelation(dah,hit));
288                     }
289                 }
290                 //for other types, make 3d hits
291                 else {
292                     HelicalTrackHit hit3d = makeDigi3DHit(hit);
293                     helhits.add(hit3d);
294                     hitrelations.add(new MyLCRelation(hit3d, hit));
295                 }
296             }
297             //  Now create the stereo hits
298             //  Create a list of stereo hits
299             List<HelicalTrackCross> stereohits = new ArrayList<HelicalTrackCross>();
300 
301             //  Loop over the modules with hits
302             for (SiTrackerModule m : modules) {
303 
304                 //  Make sure we have 2 sensors, and get the sensors for this module
305                 if (m.getChildren().size() != 2) continue;
306                 SiSensor sensor1 = (SiSensor) m.getChildren().get(0);
307                 SiSensor sensor2 = (SiSensor) m.getChildren().get(1);
308 
309                 //  Form the stereo hits and add them to our hit list
310                 stereohits.addAll(_crosser.MakeHits(sensormap.get(sensor1), sensormap.get(sensor2)));
311             }
312 
313             helhits.addAll(stereohits);
314             
315             //add LCRelation for strip hits
316             for (HelicalTrackCross cross : stereohits) {
317                 for (HelicalTrackStrip strip : cross.getStrips()) {
318                     hitrelations.add(new MyLCRelation(cross,stripmap.get(strip)));
319                 }
320             }
321             
322         }
323         
324         //  Create the LCRelations between HelicalTrackHits and MC particles
325         List<LCRelation> mcrelations = new ArrayList<LCRelation>();
326         for (HelicalTrackHit hit : helhits) {
327             for (MCParticle mcp : hit.getMCParticles()) {
328                 mcrelations.add(new MyLCRelation(hit, mcp));
329             }
330         }
331         
332         //  Put the HelicalTrackHits back into the event
333         event.put(_outname, helhits, HelicalTrackHit.class, 0);
334         event.put(_hitrelname, hitrelations, LCRelation.class, 0);
335         event.put(_mcrelname, mcrelations, LCRelation.class, 0);
336         return;
337     }
338     
339     /**
340      * Add a TrackerHit collection to be processed.
341      * @param name Name of the hit collection
342      * @param type Type of collection
343      */
344     public void addCollection(String name, HitType type) {
345         if (type == HitType.VirtualSegmentation) {
346             _vscol.add(name);
347         } else if (type == HitType.Base) {
348             _bscol.add(name);
349         } else if (type == HitType.Digitized)
350             _digcol.add(name);
351         return;
352     }
353     
354     public void setDigiCollectionName(String name)
355     {
356     	_digcol.add(name);
357     }
358     
359     public void setDigiCollectionNames(String names[])
360     {
361     	_digcol.addAll(Arrays.asList(names));
362     }
363     
364     public void setVirtualSegmentationCollectionName(String name)
365     {
366     	_vscol.add(name);
367     }
368     
369     public void setVirtualSegmentationCollectionNames(String names[])
370     {
371     	_vscol.addAll(Arrays.asList(names));
372     }
373     
374     public void setBaseCollectionName(String name)
375     {
376     	_bscol.add(name);
377     }
378     
379     public void setBaseCollectionNames(String names[])
380     {
381     	_bscol.addAll(Arrays.asList(names));
382     }
383             
384     /**
385      * Name of the HelicalTrackHit collection to be put back in the event.
386      * @param outname Name to use for the HelicalTrackHit collection
387      */
388     public void OutputCollection(String outname) {
389         _outname = outname;
390         return;
391     }
392     
393     public void setOutputCollectionName(String outname) {
394         _outname = outname;
395         return;
396     }
397     
398     public void HitRelationName(String hitrelname) {
399         _hitrelname = hitrelname;
400         return;
401     }
402     
403     public void MCRelationName(String mcrelname) {
404         _mcrelname = mcrelname;
405         return;
406     }
407 
408     public void setMaxSeperation(double maxsep) {
409         _crosser.setMaxSeparation(maxsep);
410         return;
411     }
412 
413     public void setTolerance(double tolerance) {
414         _crosser.setTolerance(tolerance);
415         return;
416     }
417     
418     private HelicalTrackHit MakeAxialHit(org.lcsim.recon.tracking.vsegment.hit.TrackerHit hit) {
419         HelicalTrackStrip strip = MakeStrip(hit);
420         if (VecOp.cross(strip.v(), _zhat).magnitude() > _eps) return null;
421         double zmin = VecOp.add(HitUtils.StripCenter(strip), VecOp.mult(strip.vmin(), strip.v())).z();
422         double zmax = VecOp.add(HitUtils.StripCenter(strip), VecOp.mult(strip.vmax(), strip.v())).z();
423         HelicalTrackHit axialhit = new HelicalTrack2DHit(strip.origin(), HitUtils.StripCov(strip),
424                 strip.dEdx(), strip.time(), strip.rawhits(), strip.detector(), strip.layer(), strip.BarrelEndcapFlag(),
425                 zmin, zmax);
426         List<MCParticle> mcplist = getMCParticles(hit.getCluster());
427         for (MCParticle mcp : mcplist) {
428             axialhit.addMCParticle(mcp);
429         }
430         return axialhit;
431     }
432     
433     private HelicalTrackStrip MakeStrip(org.lcsim.recon.tracking.vsegment.hit.TrackerHit hit) {
434         Hep3Vector u;
435         Hep3Vector v;
436         Hep3Vector org;
437         double umeas;
438         double du;
439         double vmin;
440         double vmax;
441         Sensor s = hit.getSensor();
442         SensorType stype = s.getType();
443         if  (stype instanceof Cylinder) {
444             SpacePointVector seg = hit.getSegment();
445             v = VecOp.unit(seg.getDirection());
446             Hep3Vector r = new BasicHep3Vector(hit.getPosition().x(), hit.getPosition().y(), 0.0);
447             u = VecOp.unit(VecOp.cross(v, r));
448             umeas = 0.;
449             du = r.magnitude() * Math.sqrt(hit.getLocalCovMatrix().diagonal(0));
450             org = VecOp.mult(0.5, VecOp.add(seg.getStartPoint(), seg.getEndPoint()));
451             vmax = seg.getDirection().magnitude() / 2.;
452             vmin = -vmax;
453         } else {
454             org = s.localToGlobal(_orgloc);
455             u = VecOp.sub(s.localToGlobal(_uloc), org);
456             v = VecOp.sub(s.localToGlobal(_vloc), org);
457             umeas = hit.getLocalPosition().x();
458             du = Math.sqrt(hit.getLocalCovMatrix().diagonal(0));
459             vmin = hit.getLocalSegment().getStartPoint().y();
460             vmax = hit.getLocalSegment().getEndPoint().y();
461         }
462         
463         double dEdx = hit.getSignal();
464         double time = hit.getTime();
465         IDetectorElement de = s.getDetectorElement();
466         String det = _ID.getName(de);
467         int lyr = _ID.getLayer(de);
468         if (_segman.getStereoPartners(s) != null) lyr = lyr / 2;
469         BarrelEndcapFlag beflag = _ID.getBarrelEndcapFlag(de);
470         
471         HelicalTrackStrip strip = new HelicalTrackStrip(org, u, v, umeas, du, vmin, vmax, dEdx, time, null,
472                 det, lyr, beflag);
473         List<MCParticle> mcplist = getMCParticles(hit.getCluster());
474         for (MCParticle mcp : mcplist) {
475             strip.addMCParticle(mcp);
476         }
477         return strip;
478     }
479     
480     private HelicalTrackHit MakePixelHit(org.lcsim.recon.tracking.vsegment.hit.TrackerHit hit) {
481         IDetectorElement de = hit.getSensor().getDetectorElement();
482         HelicalTrackHit pixel = new HelicalTrack3DHit(hit.getPosition(), hit.getCovMatrix(), hit.getSignal(),
483                 hit.getTime(), null, _ID.getName(de), _ID.getLayer(de), _ID.getBarrelEndcapFlag(de));
484         List<MCParticle> mcplist = getMCParticles(hit.getCluster());
485         for (MCParticle mcp : mcplist) {
486             pixel.addMCParticle(mcp);
487         }
488         
489         return pixel;
490     }
491     
492     private List<MCParticle> getMCParticles(TrackerCluster cluster) {
493         List<MCParticle> mcplist = new ArrayList<MCParticle>();
494         for (DigiTrackerHit dhit : cluster.getDigiHits()) {
495             //  Get the elemental hits - not sure what the dif is...
496             for (DigiTrackerHit dhit2 : dhit.getElementalHits()) {
497                 //  Get the MCParticle and add it to the hit
498                 MCParticle mcp = dhit2.getMCParticle();
499                 if (mcp != null) mcplist.add(mcp);
500             }
501         }
502         return mcplist;
503     }
504     
505     protected HelicalTrackHit makeDigi3DHit(SiTrackerHit h) {
506         
507         IDetectorElement de = h.getSensor();
508         int lyr = _ID.getLayer(de);
509         BarrelEndcapFlag be = _ID.getBarrelEndcapFlag(de);
510         
511         HelicalTrackHit hit = new HelicalTrack3DHit(h.getPositionAsVector(),
512                 h.getCovarianceAsMatrix(), h.getdEdx(), h.getTime(),
513                 h.getRawHits(), _ID.getName(de), lyr, be);
514         
515         for (MCParticle p : h.getMCParticles()) hit.addMCParticle(p);
516         
517         return hit;
518         
519     }
520     
521     private HelicalTrackHit makeDigiAxialHit(SiTrackerHitStrip1D h){
522         
523         double z1 = h.getHitSegment().getEndPoint().z();
524         double z2 = h.getHitSegment().getStartPoint().z();
525         double zmin = Math.min(z1,z2);
526         double zmax = Math.max(z1,z2);
527         IDetectorElement de = h.getSensor();
528         
529         HelicalTrackHit hit = new HelicalTrack2DHit(h.getPositionAsVector(),
530                 h.getCovarianceAsMatrix(), h.getdEdx(), h.getTime(),
531                 h.getRawHits(), _ID.getName(de), _ID.getLayer(de),
532                 _ID.getBarrelEndcapFlag(de), zmin, zmax);
533         
534         for (MCParticle p : h.getMCParticles()) hit.addMCParticle(p);
535         return hit;
536     }
537     
538     
539     private HelicalTrackStrip makeDigiStrip(SiTrackerHitStrip1D h){
540 
541         //  Get the tranform from global coordinates to electrode coordinates
542         //  We will use this to get the local hit coordinates and measurement error
543         ITransform3D trans = h.getReadoutElectrodes().getGlobalToLocal();
544 
545         //  Get the global coordinates of the electrode origin
546         Hep3Vector org = h.getReadoutElectrodes().getLocalToGlobal().transformed(_orgloc);
547 
548         //  Get the unit vectors for the measured and unmeasured directions
549         Hep3Vector u = h.getMeasuredCoordinate();
550         Hep3Vector v = h.getUnmeasuredCoordinate();
551 
552         //  Get the measured coordinate (i.e., the distance from the origin along the u direction)
553         double umeas = trans.transformed(h.getPositionAsVector()).x();
554 
555         //  Get the limits on the unmeasured coordinate
556         LineSegment3D vseg = h.getHitSegment();
557         double vmin = trans.transformed(vseg.getStartPoint()).y();
558         double vmax = trans.transformed(vseg.getEndPoint()).y();
559 
560         //  Get the error on the measured coordinate
561         double du = Math.sqrt(trans.rotated(h.getCovarianceAsMatrix()).diagonal(0));
562 
563         //  Get the identifier information
564         IDetectorElement de = h.getSensor();
565         String det = _ID.getName(de);
566         int lyr = _ID.getLayer(de);
567         BarrelEndcapFlag be = _ID.getBarrelEndcapFlag(de);
568 
569         //  Get the energy deposit, time, and raw hits from the SiTrackerHitStrip1D
570         double dEdx = h.getdEdx();
571         double time = h.getTime();
572         List<RawTrackerHit> rawhits = h.getRawHits();
573 
574         //  Create a new HelicalTrackStrip
575         HelicalTrackStrip strip = new HelicalTrackStrip(org, u, v, umeas, du,
576                 vmin, vmax, dEdx, time, rawhits, det, lyr, be);
577 
578         //  Save the MCParticles associated with this hit
579         for (MCParticle p : h.getMCParticles()) strip.addMCParticle(p);
580 
581         //  Done!
582         return strip;
583     }
584     
585 }