View Javadoc

1   package org.lcsim.recon.tracking.digitization.sisim.config;
2   
3   import hep.physics.matrix.BasicMatrix;
4   import hep.physics.vec.BasicHep3Vector;
5   import hep.physics.vec.VecOp;
6   
7   import java.util.List;
8   
9   import org.lcsim.detector.IDetectorElement;
10  import org.lcsim.detector.IRotation3D;
11  import org.lcsim.detector.ITranslation3D;
12  import org.lcsim.detector.RotationPassiveXYZ;
13  import org.lcsim.detector.Transform3D;
14  import org.lcsim.detector.Translation3D;
15  import org.lcsim.detector.solids.IPolyhedron;
16  import org.lcsim.detector.solids.Polygon3D;
17  import org.lcsim.detector.tracker.silicon.ChargeCarrier;
18  import org.lcsim.detector.tracker.silicon.SiPixels;
19  import org.lcsim.detector.tracker.silicon.SiSensor;
20  import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
21  import org.lcsim.geometry.Detector;
22  import org.lcsim.geometry.compact.Subdetector;
23  import org.lcsim.geometry.subdetector.SiTrackerEndcap;
24  import org.lcsim.geometry.subdetector.SiTrackerEndcap2;
25  import org.lcsim.util.Driver;
26  
27  public class SiVertexEndcapSensorSetup extends Driver
28  {
29  	
30  	String subdetectorName;
31  	double readoutPitchX = 0.05;
32  	double readoutPitchY = 0.25;
33  	double sensePitchX = 0.05;
34  	double sensePitchY = 0.25;
35  	double transferEfficiency = 1.0;
36  
37  	public SiVertexEndcapSensorSetup()
38  	{}
39  	
40  	public SiVertexEndcapSensorSetup(String subdetectorName)
41  	{
42  		this.subdetectorName = subdetectorName;
43  	}
44  	
45  	public void setSubdetectorName(String subdetectorName)
46  	{
47  		this.subdetectorName = subdetectorName;
48  	}
49  	
50  	public void detectorChanged(Detector detector)
51  	{
52  		if (subdetectorName == null)
53  			throw new RuntimeException("The subdetectorName was not set.");
54  		
55  		Subdetector subdetector = detector.getSubdetector(subdetectorName);
56  		if (subdetector instanceof SiTrackerEndcap || subdetector instanceof SiTrackerEndcap2)
57  			setupSensorDetectorElements(subdetector);
58  		else
59  			throw new RuntimeException("The subdetector " + subdetectorName + " is not an instance of SiTrackerEndcap or SiTrackerEndcap2.");
60  	}
61  	
62  	public void setReadoutPitchX(double x)
63  	{
64  		this.readoutPitchX = x;
65  	}
66  	
67  	public void setReadoutPitchY(double y)
68  	{
69  		this.readoutPitchY = y;
70  	}
71  	
72  	public void setSensePitchX(double x)
73  	{
74  		this.sensePitchX = x;
75  	}
76  	
77  	public void setSensePitchY(double y)
78  	{
79  		this.sensePitchY = y;
80  	}
81  	
82  	public void setTransferEfficiency(double t)
83  	{
84  		this.transferEfficiency = t;
85  	}
86  	
87  	private void setupSensorDetectorElements(Subdetector subdet)
88  	{
89          for (IDetectorElement endcap : subdet.getDetectorElement().getChildren()) {
90              for (IDetectorElement layer : endcap.getChildren()) 
91              {
92                  int nwedges = layer.getChildren().size();
93                  for (IDetectorElement wedge : layer.getChildren()) 
94                  {
95                      for (IDetectorElement module : wedge.getChildren()) 
96                      {	
97                      	// find sensors on the module
98                      	List<SiSensor> sensors = module.findDescendants(SiSensor.class);
99  
100                     	// require that sensors are found
101     					if (sensors.size() == 0)
102     						throw new RuntimeException("No sensors found in module.");
103 
104     					// loop over sensors (can be double-sided)
105     					for (SiSensor sensor : sensors)
106     					{
107     						// get sensor field from id
108     						int sensorId = sensor.getIdentifierHelper().getValue(sensor.getIdentifier(), "sensor");
109 
110     						// Get the sensor solid.
111     						IPolyhedron sensor_solid = (IPolyhedron) sensor.getGeometry().getLogicalVolume().getSolid();
112 
113     						// Get solids for inner and outer surfaces.
114     						Polygon3D inner_surface = sensor_solid.getFacesNormalTo(new BasicHep3Vector(0, -1, 0)).get(0);
115     						Polygon3D outer_surface = sensor_solid.getFacesNormalTo(new BasicHep3Vector(0, 1, 0)).get(0);
116 
117     						//
118     						// Determine p and n sides based on sensor id.
119     						//
120     						
121     						Polygon3D p_side;
122     						Polygon3D n_side;
123     						int side;
124 
125     						if (sensorId == 0) // inner sensor
126     						{
127     							p_side = inner_surface;
128     							n_side = outer_surface;
129     							side = 1;
130     						} 
131     						else // outer sensor
132     						{
133     							p_side = outer_surface;
134     							n_side = inner_surface;
135     							side = -1;
136     						}
137 
138     						double strip_angle = Math.PI / nwedges;
139 
140     						// Compute the geometric propertes of the electrodes.
141     						ITranslation3D electrodes_position = new Translation3D(VecOp.mult(-p_side.getDistance(), new BasicHep3Vector(0, 0, 1)));  // translate to outside of polygon
142     						IRotation3D electrodes_rotation = new RotationPassiveXYZ(side * (Math.PI / 2), 0, strip_angle);          //
143     						Transform3D electrodes_transform = new Transform3D(electrodes_position, electrodes_rotation);
144 
145     						//
146     						// Pixel-specific code starts here.
147     						//
148     						
149     						// Set the bias surfaces.
150     						sensor.setBiasSurface(ChargeCarrier.ELECTRON, p_side);
151     						sensor.setBiasSurface(ChargeCarrier.HOLE, n_side);
152             
153     						//  Define the pixel electrodes.
154     						SiSensorElectrodes readout_electrodes = new SiPixels(ChargeCarrier.ELECTRON, readoutPitchX, readoutPitchY, sensor, electrodes_transform);
155     						SiSensorElectrodes sense_electrodes = new SiPixels(ChargeCarrier.ELECTRON, sensePitchX, sensePitchY, sensor, electrodes_transform);
156 
157     						//  Tell the sensor about the electrodes.
158     						sensor.setSenseElectrodes(sense_electrodes);
159     						sensor.setReadoutElectrodes(readout_electrodes);
160 
161     						//  Define the transfer efficiency from sense electrodes to readout electrodes.
162     						//  For pixels, we do a direct transfer of charge from sense electrodes to readout electrodes.
163     						double[][] transfer_efficiencies = {{transferEfficiency}};
164     						sensor.setTransferEfficiencies(ChargeCarrier.ELECTRON, new BasicMatrix(transfer_efficiencies));
165     					}
166                     }
167                 }
168             }
169         }
170 	}
171 }