lcsim/src/org/lcsim/contrib/SiStripSim
diff -u -r1.6 -r1.7
--- CDFSiSensorSim.java 14 Oct 2007 06:14:59 -0000 1.6
+++ CDFSiSensorSim.java 3 Dec 2007 23:30:10 -0000 1.7
@@ -9,18 +9,14 @@
package org.lcsim.contrib.SiStripSim;
-
-//import org.lcsim.detector.tracker.silicon.ErrorEllipse2D;
-
+import org.lcsim.detector.solids.GeomOp3D;
import org.lcsim.event.SimTrackerHit;
import org.lcsim.detector.tracker.silicon.SiSensor;
import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
import org.lcsim.detector.tracker.silicon.ChargeCarrier;
import org.lcsim.detector.ITransform3D;
-import org.lcsim.detector.Transform3D;
import org.lcsim.detector.IRotation3D;
-import org.lcsim.detector.RotationPassiveXYZ;
import org.lcsim.detector.tracker.silicon.ChargeDistribution;
import org.lcsim.detector.tracker.silicon.GaussianDistribution2D;
@@ -82,31 +78,44 @@
// Simulate charge deposition
public void simulate(SiSensor sensor)
{
+// System.out.println("# Sense strips: " + sensor.getSenseElectrodes(ChargeCarrier.HOLE).getNCells(0));
+// System.out.println("# Readout strips: " + sensor.getReadoutElectrodes(ChargeCarrier.HOLE).getNCells(0));
+
_sensor = sensor;
depositChargeOnSense();
transferChargeToReadout();
clearSense();
}
- private void clearSense()
+ public void clearReadout()
{
for (ChargeCarrier carrier : ChargeCarrier.values())
{
- _sense_data.get(carrier).clear();
+ _readout_data.get(carrier).clear();
}
}
- public void clearReadout()
+ // Private
+ private void clearSense()
{
for (ChargeCarrier carrier : ChargeCarrier.values())
{
- _readout_data.get(carrier).clear();
+ _sense_data.get(carrier).clear();
}
}
private void depositChargeOnSense()
{
+ // Set up drift directions // FIXME: put this in a setup method.
+ for (ChargeCarrier carrier : ChargeCarrier.values())
+ {
+ if (_sensor.hasElectrodesOnSide(carrier))
+ {
+ _drift_direction.put( carrier, this.driftDirection(carrier,new BasicHep3Vector(0.0,0.0,0.0)) );
+ }
+ }
+
ITransform3D global_to_sensor = _sensor.getGeometry().getGlobalToLocal();
List<SimTrackerHit> hits = _sensor.getReadout().getHits(SimTrackerHit.class);
@@ -121,9 +130,9 @@
// Compute number of segments
for (ChargeCarrier carrier : ChargeCarrier.values())
{
- _drift_direction.put( carrier, this.driftDirection(carrier,new BasicHep3Vector(0.0,0.0,0.0)) );
if (_sensor.hasElectrodesOnSide(carrier))
{
+// _drift_direction.put( carrier, this.driftDirection(carrier,new BasicHep3Vector(0.0,0.0,0.0)) );
nsegments = Math.max(nsegments,nSegments(track,carrier, _DEPOSITION_GRANULARITY));
}
}
@@ -162,7 +171,7 @@
{
if (_sensor.hasElectrodesOnSide(carrier))
{
- SiSensorElectrodes electrodes = _sensor.getElectrodes(carrier);
+ SiSensorElectrodes electrodes = _sensor.getSenseElectrodes(carrier);
ChargeDistribution charge_distribution = diffusionDistribution(segment_charge,segment_center,carrier);
charge_distribution.transform(electrodes.getParentToLocal());
@@ -243,7 +252,7 @@
// System.out.println("sense_col : "+sense_col);
// System.out.println("row_steps : "+row_steps);
// System.out.println("col_steps : "+col_steps);
-//
+
// System.out.println("transfer_efficiencies : "+transfer_efficiencies);
for (int irow = sense_row - row_steps; irow <= sense_row + row_steps; irow++)
@@ -265,7 +274,7 @@
// System.out.println("readout_cell : "+readout_cell);
// System.out.println("position_in_cell : "+readout_electrodes.getPositionInCell(sense_position));
-
+//
// System.out.println("Sense position : "+sense_electrodes.getCellPosition(sense_id));
// System.out.println("Readout position : "+readout_electrodes.getCellPosition(readout_cell));
@@ -307,14 +316,16 @@
// Decide how to cut track into pieces as a fraction of strip pitch
int nsegments = 0;
if (!_sensor.hasElectrodesOnSide(carrier)) return nsegments;
- SiSensorElectrodes electrodes = _sensor.getElectrodes(carrier);
+ SiSensorElectrodes electrodes = _sensor.getSenseElectrodes(carrier);
// System.out.println("Track P1: " + track.getP1());
// System.out.println("Track P2: " + track.getP2());
// System.out.println("Drift Destination of P1: " + driftDestination(track.getP1(),carrier));
// System.out.println("Drift Destination of P2: " + driftDestination(track.getP2(),carrier));
- nsegments = (int)Math.ceil(track.getVector().z()/(_sensor.getThickness()*deposition_granularity));
+ nsegments = (int)Math.ceil(Math.abs(VecOp.dot(track.getVector(),electrodes.getGeometry().getNormal()))/(_sensor.getThickness()*deposition_granularity));
+
+// nsegments = (int)Math.ceil(track.getVector().z()/(_sensor.getThickness()*deposition_granularity)); // old way
Hep3Vector deposition_line = VecOp.sub( driftDestination(track.getP2(),carrier),
driftDestination(track.getP1(),carrier) );
@@ -348,7 +359,10 @@
private Hep3Vector driftVector(Hep3Vector origin, ChargeCarrier carrier)
{
// System.out.println("Beginning driftVector");
- double drift_vector_scale = _sensor.distanceFromSide(origin,carrier)/_drift_direction.get(carrier).z();
+
+ double drift_vector_scale = _sensor.distanceFromSide(origin,carrier)/VecOp.dot(_drift_direction.get(carrier),_sensor.getBiasSurface(carrier).getNormal());
+// double drift_vector_scale = _sensor.distanceFromSide(origin,carrier)/_drift_direction.get(carrier).z();
+
return VecOp.mult(drift_vector_scale,_drift_direction.get(carrier));
}
@@ -406,21 +420,58 @@
double sigma = Math.sqrt(sigmasq);
// Corrections for magnetic field -- this is an approximation, may have to be done better for high fields
- double cos_theta_lorentz = VecOp.cosTheta(_drift_direction.get(carrier));
- double phi_lorentz = VecOp.phi(_drift_direction.get(carrier));
- double minor_axis_length = sigma*(1.0/cos_theta_lorentz); // drift time correction
- double major_axis_length = minor_axis_length*(1.0/cos_theta_lorentz); // + drift angle correction
+ // Special case if field is parallel to drift direction
+ Hep3Vector drift_direction = _drift_direction.get(carrier);
+ Hep3Vector bias_surface_normal = _sensor.getBiasSurface(carrier).getNormal();
+
+ Hep3Vector major_axis;
+ Hep3Vector minor_axis;
- // FIXME: this has a Z component!!! (is that OK??)
+ double major_axis_length;
+ double minor_axis_length;
+
+ if (VecOp.cross(drift_direction,bias_surface_normal).magnitude() < GeomOp3D.ANGULAR_TOLERANCE)
+ {
+ major_axis = VecOp.cross(bias_surface_normal,_sensor.getBiasSurface(carrier).getEdges().get(0).getDirection()); // arbitrary vector in plane
+ minor_axis = VecOp.cross(bias_surface_normal,major_axis);
+
+ major_axis_length = minor_axis_length = sigma;
+ }
+ else
+ {
+ major_axis = VecOp.unit(VecOp.cross(bias_surface_normal,VecOp.cross(_drift_direction.get(carrier),bias_surface_normal)));
+ minor_axis = VecOp.cross(bias_surface_normal,major_axis);
+
+// double phi_lorentz = VecOp.phi(_drift_direction.get(carrier)); // FIXME: careful here... calculate axis directions to instantiate distribution.
+ // Project-to-plane would definitely be convenient here!!!
+
+ double cos_theta_lorentz = VecOp.dot(_drift_direction.get(carrier),_sensor.getBiasSurface(carrier).getNormal());
+// double cos_theta_lorentz = VecOp.cosTheta(_drift_direction.get(carrier)); // FIXME: careful with cosTheta here!
+// System.out.println("Cos theta lorentz: "+cos_theta_lorentz);
+
+ minor_axis_length = sigma*(1.0/cos_theta_lorentz); // drift time correction
+ major_axis_length = minor_axis_length*(1.0/cos_theta_lorentz); // + drift angle correction
+ }
+
+
+ major_axis = VecOp.mult(major_axis_length,major_axis);
+ minor_axis = VecOp.mult(minor_axis_length,minor_axis);
+
+// System.out.println("Major axis: "+major_axis);
+// System.out.println("Minor axis: "+minor_axis);
+
+ // FIXME: this has a Z component!!! (is that OK?? I think the whole thing transforms into the electrode coordinates before integrating charge.)
Hep3Vector drift_destination = driftDestination(origin,carrier);
// System.out.println("Drift destination: "+drift_destination);
- ChargeDistribution distribution = new GaussianDistribution2D(segment_charge, drift_destination,new BasicHep3Vector(major_axis_length,0.0,0.0),new BasicHep3Vector(0.0,minor_axis_length,0.0));
+ ChargeDistribution distribution = new GaussianDistribution2D(segment_charge, drift_destination,major_axis,minor_axis);
- ITransform3D phi_rotation = new Transform3D(new RotationPassiveXYZ(0.0,0.0,-phi_lorentz));
- distribution.transform(phi_rotation);
+// ChargeDistribution distribution = new GaussianDistribution2D(segment_charge, drift_destination,new BasicHep3Vector(major_axis_length,0.0,0.0),new BasicHep3Vector(0.0,minor_axis_length,0.0));
+//
+// ITransform3D phi_rotation = new Transform3D(new RotationPassiveXYZ(0.0,0.0,-phi_lorentz));
+// distribution.transform(phi_rotation);
// System.out.println("Done calculating charge distribution for carrier: "+carrier);
lcsim/src/org/lcsim/contrib/SiStripSim
diff -u -r1.5 -r1.6
--- StripClusterMaker.java 21 Nov 2007 22:26:39 -0000 1.5
+++ StripClusterMaker.java 3 Dec 2007 23:30:10 -0000 1.6
@@ -27,12 +27,11 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
-import org.lcsim.detector.Rotation3D;
-import org.lcsim.detector.RotationPassiveXYZ;
import org.lcsim.detector.tracker.silicon.ChargeCarrier;
import org.lcsim.detector.tracker.silicon.DopedSilicon;
import org.lcsim.detector.tracker.silicon.SiSensor;
import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
+import org.lcsim.detector.tracker.silicon.SiStrips;
import org.lcsim.event.SimTrackerHit;
import org.lcsim.event.base.BaseTrackerHitMC;
@@ -101,19 +100,7 @@
_strip_map.put(raw_hit,strip_id);
// Get side of sensor
- ChargeCarrier carrier;
- if (id.getValue(side_field) == 1)
- {
- carrier = ChargeCarrier.HOLE;
- }
- else if (id.getValue(side_field) == -1)
- {
- carrier = ChargeCarrier.ELECTRON;
- }
- else
- {
- throw new RuntimeException("Invalid side field in RawTrackerHit.");
- }
+ ChargeCarrier carrier = ChargeCarrier.getCarrier(id.getValue(side_field));
// Zero strip number to refer only to electrode set
id.setValue(strip_field,0);
@@ -237,7 +224,7 @@
double signal = _readout_chip.decodeCharge(hit);
total_charge += signal;
- position = VecOp.add(position,VecOp.mult(signal,electrodes.getCellPosition(_strip_map.get(hit))));
+ position = VecOp.add(position,VecOp.mult(signal,((SiStrips)electrodes).getStripCenter(_strip_map.get(hit))));
}
position = VecOp.mult(1/total_charge,position);