1 package org.lcsim.detector.tracker.silicon;
2
3
4
5
6
7
8
9
10
11
12 import hep.physics.matrix.BasicMatrix;
13 import hep.physics.vec.Hep3Vector;
14 import hep.physics.vec.VecOp;
15 import java.util.Collection;
16
17 import java.util.EnumMap;
18 import java.util.Map;
19
20 import org.lcsim.detector.DetectorElement;
21 import org.lcsim.detector.IDetectorElement;
22 import org.lcsim.detector.converter.compact.DeDetector;
23 import org.lcsim.detector.identifier.ExpandedIdentifier;
24 import org.lcsim.detector.identifier.IExpandedIdentifier;
25 import org.lcsim.detector.identifier.IIdentifier;
26 import org.lcsim.detector.identifier.IIdentifierDictionary;
27 import org.lcsim.detector.identifier.IIdentifierHelper;
28 import org.lcsim.detector.solids.GeomOp3D;
29 import org.lcsim.detector.solids.Point3D;
30 import org.lcsim.detector.solids.Polygon3D;
31
32
33
34
35
36 public class SiSensor extends DetectorElement
37 {
38
39
40
41
42
43
44
45 private static double _DEPLETION_VOLTAGE_DEFAULT = 100;
46 private static double _BIAS_VOLTAGE_DEFAULT = 110;
47
48
49
50
51
52 private int _sensorid;
53
54
55 private Map<ChargeCarrier, Polygon3D> _bias_surfaces = new EnumMap<ChargeCarrier,Polygon3D>(ChargeCarrier.class);
56 private Map<ChargeCarrier, SiSensorElectrodes> _sense_electrodes = new EnumMap<ChargeCarrier,SiSensorElectrodes>(ChargeCarrier.class);
57 private Map<ChargeCarrier, SiSensorElectrodes> _readout_electrodes = new EnumMap<ChargeCarrier,SiSensorElectrodes>(ChargeCarrier.class);
58 private Map<ChargeCarrier, BasicMatrix> _transfer_efficiencies = new EnumMap<ChargeCarrier,BasicMatrix>(ChargeCarrier.class);
59
60
61 private DopedSilicon _bulk;
62 private double _thickness;
63
64
65 private double _depletion_voltage;
66 private double _bias_voltage;
67
68
69
70
71
72 public SiSensor(
73 int sensorid,
74 String name,
75 IDetectorElement parent,
76 String support,
77 IIdentifier id
78 )
79 {
80 super(name,parent,support,id);
81 setSensorID(sensorid);
82 setBulk(new DopedSilicon());
83 setDepletionVoltage(SiSensor._DEPLETION_VOLTAGE_DEFAULT);
84 setBiasVoltage(SiSensor._BIAS_VOLTAGE_DEFAULT);
85 }
86
87 public SiSensor(
88 int sensorid,
89 String name,
90 IDetectorElement parent,
91 String support
92 )
93 {
94 super(name,parent,support);
95 setSensorID(sensorid);
96 setBulk(new DopedSilicon());
97 setDepletionVoltage(SiSensor._DEPLETION_VOLTAGE_DEFAULT);
98 setBiasVoltage(SiSensor._BIAS_VOLTAGE_DEFAULT);
99 }
100
101
102
103
104
105
106
107 public void setSensorID(int sensorid)
108 {
109 _sensorid = sensorid;
110 }
111
112 public void setSenseElectrodes(SiSensorElectrodes sense_electrodes)
113 {
114 _sense_electrodes.put(sense_electrodes.getChargeCarrier(),sense_electrodes);
115 }
116
117 public void setReadoutElectrodes(SiSensorElectrodes readout_electrodes)
118 {
119 _readout_electrodes.put(readout_electrodes.getChargeCarrier(),readout_electrodes);
120 }
121
122 public void setBiasSurface(ChargeCarrier carrier, Polygon3D bias_surface)
123 {
124 _bias_surfaces.put(carrier,bias_surface);
125 }
126
127 public void setTransferEfficiencies(ChargeCarrier carrier, BasicMatrix transfer_efficiencies)
128 {
129 _transfer_efficiencies.put(carrier,transfer_efficiencies);
130 }
131
132 public void setBulk(DopedSilicon bulk)
133 {
134 _bulk = bulk;
135 }
136
137 public void setDepletionVoltage(double depletion_voltage)
138 {
139 _depletion_voltage = depletion_voltage;
140 }
141
142 public void setBiasVoltage(double bias_voltage)
143 {
144 _bias_voltage = bias_voltage;
145 }
146
147
148 public int getSensorID()
149 {
150 return _sensorid;
151 }
152
153 public Collection<SiSensorElectrodes> getSenseElectrodes()
154 {
155 return _sense_electrodes.values();
156 }
157
158 public SiSensorElectrodes getSenseElectrodes(ChargeCarrier carrier)
159 {
160 return _sense_electrodes.get(carrier);
161 }
162
163 public Collection<SiSensorElectrodes> getReadoutElectrodes()
164 {
165 return _readout_electrodes.values();
166 }
167
168 public SiSensorElectrodes getReadoutElectrodes(ChargeCarrier carrier)
169 {
170 return _readout_electrodes.get(carrier);
171 }
172
173 public Polygon3D getBiasSurface(ChargeCarrier carrier)
174 {
175 return _bias_surfaces.get(carrier);
176 }
177
178 public BasicMatrix getTransferEfficiencies(ChargeCarrier carrier)
179 {
180 return _transfer_efficiencies.get(carrier);
181 }
182
183 public DopedSilicon getBulk()
184 {
185 return _bulk;
186 }
187
188 public double getThickness()
189 {
190 if (_thickness == 0)
191 {
192
193
194
195
196
197
198
199
200 _thickness = Math.abs(GeomOp3D.distanceBetween( _bias_surfaces.get(ChargeCarrier.HOLE).getPlane(), _bias_surfaces.get(ChargeCarrier.ELECTRON).getPlane()));
201
202
203 }
204 return _thickness;
205 }
206
207 public double getDepletionVoltage()
208 {
209 return _depletion_voltage;
210 }
211
212 public double getBiasVoltage()
213 {
214 return _bias_voltage;
215 }
216
217 public Hep3Vector getBField(Hep3Vector local_position)
218 {
219
220 IDetectorElement ancestor = this.getParent();
221 while (!(ancestor instanceof DeDetector) && !(ancestor==null))
222 {
223 ancestor = ancestor.getParent();
224 }
225 if (ancestor == null) throw new RuntimeException("SiSensor.getBField CANNOT FIND DETECTOR!!");
226
227 Hep3Vector global_position = getGeometry().getLocalToGlobal().transformed(local_position);
228 Hep3Vector field_global = ((DeDetector)ancestor).getBField(global_position);
229
230
231 return getGeometry().getGlobalToLocal().rotated(field_global);
232
233 }
234
235
236
237
238
239
240
241
242
243
244 public boolean isACCoupled(ChargeCarrier carrier)
245 {
246 return (this._readout_electrodes.get(carrier) != null);
247 }
248
249 public boolean isDoubleSided()
250 {
251 boolean double_sided = true;
252 for (ChargeCarrier carrier : ChargeCarrier.values())
253 {
254 double_sided = double_sided && hasElectrodesOnSide(carrier);
255 }
256 return double_sided;
257 }
258
259 public boolean hasStrips()
260 {
261 boolean has_strips = false;
262 for (SiSensorElectrodes electrodes : getReadoutElectrodes())
263 {
264 has_strips = has_strips || (electrodes instanceof SiStrips);
265 }
266 return has_strips;
267 }
268
269 public boolean hasPixels()
270 {
271 boolean has_pixels = false;
272 for (SiSensorElectrodes electrodes : getReadoutElectrodes())
273 {
274 has_pixels = has_pixels || (electrodes instanceof SiPixels);
275 }
276 return has_pixels;
277 }
278
279 public double distanceFromSide(Hep3Vector point, ChargeCarrier carrier)
280 {
281
282
283
284 return -GeomOp3D.distanceBetween(new Point3D(point),_bias_surfaces.get(carrier).getPlane());
285
286
287
288
289 }
290
291 public boolean hasElectrodesOnSide(ChargeCarrier carrier)
292 {
293 if(_sense_electrodes.get(carrier) == null) return false;
294 else return true;
295 }
296
297 public Hep3Vector electricField(Hep3Vector position)
298 {
299
300
301 double electric_field_magnitude = (_bias_voltage-_depletion_voltage)/getThickness() +
302 (2.0*_depletion_voltage)/getThickness() * (1.0 - this.distanceFromSide(position,ChargeCarrier.ELECTRON));
303
304
305
306
307 Hep3Vector electric_field_direction = _bias_surfaces.get(ChargeCarrier.HOLE).getNormal();
308
309
310
311 return VecOp.mult(electric_field_magnitude,electric_field_direction);
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334 }
335
336 public String toString()
337 {
338 String newline = System.getProperty("line.separator");
339 String output = "SiSensor Object: "+newline+
340 " Property 1";
341 return output;
342 }
343
344
345
346
347
348
349
350
351 public IIdentifier makeStripId( int stripNumber, int sideNumber )
352 {
353
354
355 IExpandedIdentifier id = new ExpandedIdentifier(getExpandedIdentifier());
356
357
358 IIdentifierHelper helper = getIdentifierHelper();
359 IIdentifierDictionary dict = helper.getIdentifierDictionary();
360
361
362 id.setValue(dict.getFieldIndex("side"), sideNumber);
363 id.setValue(dict.getFieldIndex("strip"), stripNumber);
364
365
366 return helper.pack( id );
367 }
368 }