1 package org.lcsim.recon.tracking.vsegment.geom.segmenters;
2
3 import hep.physics.vec.BasicHep3Vector;
4 import hep.physics.vec.Hep3Vector;
5 import org.lcsim.detector.IDetectorElement;
6 import org.lcsim.detector.IGeometryInfo;
7 import org.lcsim.detector.ILogicalVolume;
8 import org.lcsim.detector.IPhysicalVolume;
9 import org.lcsim.detector.solids.Tube;
10 import org.lcsim.event.SimTrackerHit;
11
12 import org.lcsim.recon.tracking.vsegment.geom.RegionSegmenter;
13 import org.lcsim.recon.tracking.vsegment.geom.Sensor;
14 import org.lcsim.recon.tracking.vsegment.geom.SensorType;
15 import org.lcsim.recon.tracking.vsegment.geom.sensortypes.WedgeSideParallel;
16 import org.lcsim.recon.tracking.vsegment.transform.Axis;
17 import org.lcsim.recon.tracking.vsegment.transform.Rotation3D;
18 import org.lcsim.recon.tracking.vsegment.transform.Transformation3D;
19
20
21
22
23
24
25
26 public class DiskToWedgesSegmenter extends RegionSegmenter {
27
28
29
30 public DiskToWedgesSegmenter(IDetectorElement disk, int nRadialSlices, int nPhiSlices, double pitch, boolean left) {
31
32 _de = disk;
33 _left = left;
34 _pitch = pitch;
35 _nPhi = nPhiSlices;
36 _nRadial = nRadialSlices;
37
38 IGeometryInfo gInfo = _de.getGeometry();
39 Tube solid = (Tube) gInfo.getLogicalVolume().getSolid();
40 _rMiddleMin = solid.getInnerRadius();
41 double rMax = solid.getOuterRadius();
42 double halfThickness = solid.getZHalfLength();
43
44 _z = gInfo.getPosition().z();
45 _zMin = _z - halfThickness;
46 _zMax = _z + halfThickness;
47
48 _deltaPhi = (2.*Math.PI)/nPhiSlices;
49 _rMin = _rMiddleMin/Math.cos(_deltaPhi/2.);
50 _deltaR = (rMax - _rMin) / nRadialSlices;
51 _deltaRMiddle = _deltaR * Math.cos(_deltaPhi/2.);
52
53 _sType = new SensorType[_nRadial];
54 for (int indexR=0; indexR < _nRadial; indexR++) {
55 _sType[indexR] = new WedgeSideParallel(_rMin+_deltaR*indexR, _deltaR, _deltaPhi, _pitch, _left, 2.*halfThickness);
56 }
57
58 _rotation = new Transformation3D[_nPhi];
59 for (int indexPhi=0; indexPhi < _nPhi; indexPhi++ ) {
60 double angle = (left) ? _deltaPhi * (indexPhi + 1) - Math.PI/2. : _deltaPhi * indexPhi - Math.PI/2.;
61 _rotation[indexPhi] = new Rotation3D(Axis.Z, angle);
62 }
63 }
64
65
66
67
68
69 protected int makePostfix(SimTrackerHit hit) {
70
71 double[] pos = hit.getPoint();
72
73 if (pos[2]<_zMin || pos[2]>_zMax) return -1;
74
75 double r = Math.hypot(pos[0],pos[1]);
76 double phi = Math.atan2(pos[1], pos[0]);
77 phi = (phi > 0.) ? phi : phi + Math.PI * 2.;
78
79 int indexPhi = (int) Math.floor(phi/_deltaPhi);
80 if (indexPhi < 0) indexPhi = 0;
81 if (indexPhi >= _nPhi) indexPhi = _nPhi -1;
82
83 double rMiddle = r * Math.cos(phi - _deltaPhi*(indexPhi+.5));
84 int indexR = (int) Math.floor((rMiddle - _rMiddleMin) / _deltaRMiddle);
85 if ((indexR < 0) || (indexR >= _nRadial)) return -1;
86
87 return (_nRadial * indexPhi) + indexR;
88 }
89
90
91
92
93
94 protected int getMaxPostfix() {
95 return (_nRadial * _nPhi) - 1;
96 }
97
98
99
100
101
102 protected Sensor makeSensor(int postfix) {
103 int indexR = postfix % _nRadial;
104 int indexPhi = postfix / _nRadial;
105 double r = _rMin + indexR * _deltaR;
106 double phi = (indexPhi + 1) * _deltaPhi;
107 Hep3Vector translation = new BasicHep3Vector(r*Math.cos(phi), r*Math.sin(phi), _z);
108 return new Sensor(_de, postfixToID(postfix), _sType[indexR], translation, _rotation[indexPhi]);
109 }
110
111
112
113 IDetectorElement _de;
114
115 boolean _left;
116 double _pitch;
117
118 int _nPhi;
119 int _nRadial;
120
121 double _z;
122 double _zMin;
123 double _zMax;
124
125 double _rMin;
126 double _rMiddleMin;
127
128 double _deltaPhi;
129 double _deltaR;
130 double _deltaRMiddle;
131
132 SensorType[] _sType;
133 Transformation3D[] _rotation;
134 }