lcsim/src/org/lcsim/contrib/SiStripSim
diff -u -r1.1 -r1.2
--- CDFSiSensorSim.java 18 May 2007 21:59:23 -0000 1.1
+++ CDFSiSensorSim.java 3 Jul 2007 23:36:52 -0000 1.2
@@ -15,10 +15,14 @@
import org.lcsim.detector.Rotation3D;
import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
+import org.lcsim.detector.tracker.silicon.SiStrips;
import org.lcsim.detector.tracker.silicon.ChargeCarrier;
+import org.lcsim.detector.ITransform3D;
import hep.physics.vec.Hep3Vector;
import hep.physics.vec.BasicHep3Vector;
+import hep.physics.matrix.BasicMatrix;
import hep.physics.vec.VecOp;
import java.util.List;
@@ -26,9 +30,8 @@
import java.util.HashSet;
import java.util.Map;
-import java.util.EnumMap;
import java.util.SortedMap;
-import java.util.TreeMap;
+import java.util.EnumMap;
/**
*
@@ -39,12 +42,13 @@
// Fields
SiSensor _sensor = null;
+ ChargeTransferModel _transfer_model = null;
Map<ChargeCarrier,Hep3Vector> _drift_direction = null;
- Map<ChargeCarrier,SortedMap<Integer,SiElectrodeData>> _sense_data = null;
- Map<ChargeCarrier,SortedMap<Integer,SiElectrodeData>> _readout_data = null;
-
+ Map<ChargeCarrier,SiElectrodeDataCollection> _sense_data = null;
+ Map<ChargeCarrier,SiElectrodeDataCollection> _readout_data = null;
+
// SiElectrodeSim
-
+
// Static parameters - not intended to be user modifiable
private static double _DEPOSITION_GRANULARITY = 0.10; // 10% of pitch or depleted thickness
@@ -55,20 +59,20 @@
public CDFSiSensorSim()
{
_drift_direction = new EnumMap<ChargeCarrier,Hep3Vector>(ChargeCarrier.class);
- _sense_data = new EnumMap<ChargeCarrier,SortedMap<Integer,SiElectrodeData>>(ChargeCarrier.class);
- _readout_data = new EnumMap<ChargeCarrier,SortedMap<Integer,SiElectrodeData>>(ChargeCarrier.class);
+ _sense_data = new EnumMap<ChargeCarrier,SiElectrodeDataCollection>(ChargeCarrier.class);
+ _readout_data = new EnumMap<ChargeCarrier,SiElectrodeDataCollection>(ChargeCarrier.class);
for (ChargeCarrier carrier : ChargeCarrier.values())
{
- _sense_data.put(carrier,new TreeMap<Integer,SiElectrodeData>());
- _readout_data.put(carrier,new TreeMap<Integer,SiElectrodeData>());
- }
+ _sense_data.put(carrier,new SiElectrodeDataCollection());
+ _readout_data.put(carrier,new SiElectrodeDataCollection());
+ }
}
-
+
// Implementation of SiSensorSim interface
//==================================
// Get charge map on electrodes
- public SortedMap<Integer,SiElectrodeData> getReadoutData(ChargeCarrier carrier)
+ public SiElectrodeDataCollection getReadoutData(ChargeCarrier carrier)
{
return _readout_data.get(carrier);
}
@@ -78,17 +82,38 @@
{
_sensor = sensor;
depositChargeOnSense();
- transferChargeToReadout();
+ transferChargeToReadout();
+ clearSense();
}
-
+
+ private void clearSense()
+ {
+ for (ChargeCarrier carrier : ChargeCarrier.values())
+ {
+ _sense_data.get(carrier).clear();
+ }
+ }
+
+ public void clearReadout()
+ {
+ for (ChargeCarrier carrier : ChargeCarrier.values())
+ {
+ _readout_data.get(carrier).clear();
+ }
+ }
+
private void depositChargeOnSense()
{
+ ITransform3D global_to_sensor = _sensor.getGeometry().getGlobalToLocal();
List<SimTrackerHit> hits = _sensor.getReadout().getHits(SimTrackerHit.class);
for (SimTrackerHit hit : hits)
{
+ TrackSegment track = new TrackSegment(hit);
+ track.transform(global_to_sensor);
+
int nsegments = 0;
// Compute number of segments
@@ -97,17 +122,34 @@
_drift_direction.put( carrier, this.driftDirection(carrier,new BasicHep3Vector(0.0,0.0,0.0)) );
if (_sensor.hasElectrodesOnSide(carrier))
{
- nsegments = Math.max(nsegments,nSegments(hit,carrier, _DEPOSITION_GRANULARITY));
+ nsegments = Math.max(nsegments,nSegments(track,carrier, _DEPOSITION_GRANULARITY));
}
}
-
+
+// System.out.println("Number of subsegments: " + nsegments);
+
// Set up segments
- double segment_length = hit.getPathLength()/nsegments;
- double segment_charge = hit.getdEdx()/nsegments/_sensor.getBulk().ENERGY_EHPAIR;
-
- Hep3Vector segment_step = VecOp.mult(segment_length,VecOp.unit( new BasicHep3Vector(hit.getMomentum()) ));
- Hep3Vector segment_center = VecOp.add( new BasicHep3Vector(hit.getStartPoint()), VecOp.mult(0.5,segment_step) );
-
+// double segment_length = hit.getPathLength()/nsegments;
+// double segment_charge = hit.getdEdx()/nsegments/_sensor.getBulk().ENERGY_EHPAIR;
+
+// Hep3Vector segment_step = VecOp.mult(segment_length,VecOp.unit( new BasicHep3Vector(hit.getMomentum()) ));
+// Hep3Vector segment_center = VecOp.add( new BasicHep3Vector(hit.getStartPoint()), VecOp.mult(0.5,segment_step) );
+
+
+
+ // Set up segments
+ double segment_length = track.getLength()/nsegments;
+ double segment_charge = track.getEloss()/nsegments/_sensor.getBulk().ENERGY_EHPAIR;
+
+// System.out.println("length of subsegments: " + segment_length);
+// System.out.println("total charge: " + segment_charge);
+
+ Hep3Vector segment_step = VecOp.mult(segment_length,track.getDirection());
+ Hep3Vector segment_center = VecOp.add( track.getP1(),VecOp.mult(0.5,segment_step) );
+
+// System.out.println("Segment step: " + segment_step);
+// System.out.println("Segment center: " + segment_center);
+
// Loop over segments
for (int iseg = 0; iseg < nsegments; iseg++)
{
@@ -117,41 +159,32 @@
for (ChargeCarrier carrier : ChargeCarrier.values())
{
if (_sensor.hasElectrodesOnSide(carrier))
- {
+ {
+
Rotation3D sensor_to_electrodes = new Rotation3D();
sensor_to_electrodes.setPassiveXYZ(0.0,0.0,-_sensor.getElectrodeAngle(carrier));
Hep3Vector electrode_drift_destination = VecOp.mult(sensor_to_electrodes.getRotationMatrix(),driftDestination(segment_center,carrier));
ErrorEllipse2D electrode_charge_distribution = diffusionEllipse(segment_center,carrier).rotate(-_sensor.getElectrodeAngle(carrier));
-
- Map<Integer,Integer> sense_charge = _sensor.getElectrodes(carrier).
- computeElectrodeData(segment_charge,electrode_drift_destination,electrode_charge_distribution);
- for (Integer strip : sense_charge.keySet())
- {
- if (!_sense_data.get(carrier).containsKey(strip))
- {
- _sense_data.get(carrier).put(strip,new SiElectrodeData());
- }
- _sense_data.get(carrier).get(strip).add(sense_charge.get(strip),hit);
- }
-
-
+ SortedMap<Integer,Integer> sense_charge = _sensor.getElectrodes(carrier).
+ computeElectrodeData(segment_charge,electrode_drift_destination,electrode_charge_distribution);
-// _sense_data.get(carrier).
-// add(_sensor.getElectrodes(carrier).computeElectrodeData(segment_charge,electrode_drift_destination,electrode_charge_distribution));
+// System.out.println("Sense charge map: " + sense_charge);
+ _sense_data.get(carrier).add(new SiElectrodeDataCollection(sense_charge,hit));
-// _electrodes.get(carrier).depositCharge(segment_charge,electrode_drift_destination,electrode_charge_distribution);
-
}
}
// step to next segment
segment_center = VecOp.add(segment_center, segment_step);
}
-
- }
+
+ System.out.println("Final sense charge map: " + _sense_data.get(ChargeCarrier.HOLE).getChargeMap());
+
+
+ }
}
@@ -159,63 +192,176 @@
{
for (ChargeCarrier carrier : ChargeCarrier.values())
{
-// _transfer_model.transferCharge(_sensor.getElectrodes(carrier)
- }
+ if (_sensor.hasElectrodesOnSide(carrier))
+ {
+ if (_sensor.isACCoupled(carrier))
+ {
+// System.out.println("Is AC coupled");
+
+ SiSensorElectrodes sense_electrodes = _sensor.getSenseElectrodes(carrier);
+ SiSensorElectrodes readout_electrodes = _sensor.getReadoutElectrodes(carrier);
+ BasicMatrix transfer_efficiencies = _sensor.getTransferEfficiencies(carrier);
+
+ SiElectrodeDataCollection sense_data = _sense_data.get(carrier);
+ SiElectrodeDataCollection readout_data = _readout_data.get(carrier);
+
+ for (Integer sense_cell : sense_data.keySet())
+ {
+
+// System.out.println("Processing sense cell : "+sense_cell);
+
+ SiElectrodeData sense_cell_data = sense_data.get(sense_cell);
+
+// System.out.println("Sense cell charge : "+sense_cell_data.getCharge());
+
+ int sense_row = sense_electrodes.getRowNumber(sense_cell);
+ int sense_col = sense_electrodes.getColumnNumber(sense_cell);
+ int row_steps = transfer_efficiencies.getNRows()-1;
+ int col_steps = transfer_efficiencies.getNColumns()-1;
+
+// System.out.println("sense_row : "+sense_row);
+// 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++)
+ {
+
+// System.out.println("irow : "+irow);
+
+ for (int icol = sense_col - col_steps; icol <= sense_col + col_steps; icol++)
+ {
+
+// System.out.println("icol : "+icol);
+
+ int sense_id = sense_electrodes.getCellID(irow,icol);
+ Hep3Vector sense_position = sense_electrodes.getCellPosition(sense_id);
+ int readout_cell = readout_electrodes.getCellID(sense_position);
+
+// System.out.println("sense_id : "+sense_id);
+// System.out.println("sense_position: "+sense_position);
+// 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));
+
+ if ( readout_electrodes.isValidCell(readout_cell) &&
+ readout_electrodes.getPositionInCell(sense_position).x() == 0.0 &&
+ readout_electrodes.getPositionInCell(sense_position).y() == 0.0 )
+ {
+// System.out.println("transferring...");
+ double transfer_efficiency = transfer_efficiencies.e(Math.abs(irow-sense_row),Math.abs(icol-sense_col));
+// System.out.println("transfer efficiency: "+transfer_efficiency);
+// System.out.println("sense charge: "+sense_cell_data.getCharge());
+
+ SiElectrodeData readout_datum = new SiElectrodeData((int)(transfer_efficiency*sense_cell_data.getCharge()),
+ sense_cell_data.getSimulatedHits());
+ readout_data.add(readout_cell,readout_datum);
+// System.out.println("transferring 3...");
+// System.out.println("Current readout charge map: " + _readout_data.get(carrier).getChargeMap());
+ }
+// System.out.println("4...");
+ }
+// System.out.println("5...");
+ }
+// System.out.println("6...");
+ }
+// System.out.println("7...");
+ }
+ else
+ {
+ _readout_data.put(carrier,_sense_data.get(carrier));
+ }
+ System.out.println("Final readout charge map: " + _readout_data.get(carrier).getChargeMap());
+ }
+ }
}
-
- private int nSegments(SimTrackerHit hit, ChargeCarrier carrier, double deposition_granularity)
+ private int nSegments(TrackSegment track, ChargeCarrier carrier, double deposition_granularity)
{
- // Decide how to cut track into pieces as a fraction of strip pitch
+ // Decide how to cut track into pieces as a fraction of strip pitch
int nsegments = 0;
if (!_sensor.hasElectrodesOnSide(carrier)) return nsegments;
- // Construct endpoints for charge deposition
- Hep3Vector p1 = new BasicHep3Vector(hit.getStartPoint());
- Hep3Vector p2 = new BasicHep3Vector(hit.getEndPoint());
-
-
-// System.out.println("Track P1: " + track.getP1());
-// System.out.println("Track P2: " + track.getP2());
+// 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));
+// System.out.println("Drift Destination of P2: " + driftDestination(track.getP2(),carrier));
- nsegments = (int)Math.ceil(VecOp.sub(p2,p1).z()/(_sensor.getThickness()*deposition_granularity));
+ nsegments = (int)Math.ceil(track.getVector().z()/(_sensor.getThickness()*deposition_granularity));
- Hep3Vector deposition_line = VecOp.sub( driftDestination(p2,carrier), driftDestination(p1,carrier) );
-
- int naxes = _sensor.getElectrodes(carrier).getNAxes();
+ Hep3Vector deposition_line = VecOp.sub( driftDestination(track.getP2(),carrier),
+ driftDestination(track.getP1(),carrier) );
+
+ int naxes = _sensor.getElectrodes(carrier).getNAxes();
for (int iaxis = 0; iaxis < naxes; iaxis++)
{
double projected_deposition_length = Math.abs(VecOp.dot(deposition_line,_sensor.getMeasuredCoordinates(carrier)[iaxis]));
-
+
// System.out.println("Projected deposition Length: " + projected_deposition_length);
int required_segments = (int)Math.ceil(projected_deposition_length/
(deposition_granularity*_sensor.getElectrodes(carrier).getPitch(iaxis)));
nsegments = Math.max(nsegments,required_segments);
- }
+ }
return nsegments;
}
+// private int nSegments(SimTrackerHit hit, ChargeCarrier carrier, double deposition_granularity)
+// {
+// // Decide how to cut track into pieces as a fraction of strip pitch
+// int nsegments = 0;
+// if (!_sensor.hasElectrodesOnSide(carrier)) return nsegments;
+//
+// // Construct endpoints for charge deposition
+// Hep3Vector p1 = new BasicHep3Vector(hit.getStartPoint());
+// Hep3Vector p2 = new BasicHep3Vector(hit.getEndPoint());
+//
+// System.out.println("Track P1: " + p1);
+// System.out.println("Track P2: " + p2);
+// System.out.println("Drift Destination of P1: " + driftDestination(p1,carrier));
+// System.out.println("Drift Destination of P2: " + driftDestination(p2,carrier));
+//
+// nsegments = (int)Math.ceil(VecOp.sub(p2,p1).z()/(_sensor.getThickness()*deposition_granularity));
+//
+// Hep3Vector deposition_line = VecOp.sub( driftDestination(p2,carrier), driftDestination(p1,carrier) );
+//
+// int naxes = _sensor.getElectrodes(carrier).getNAxes();
+// for (int iaxis = 0; iaxis < naxes; iaxis++)
+// {
+// double projected_deposition_length = Math.abs(VecOp.dot(deposition_line,_sensor.getMeasuredCoordinates(carrier)[iaxis]));
+//
+//// System.out.println("Projected deposition Length: " + projected_deposition_length);
+//
+// int required_segments = (int)Math.ceil(projected_deposition_length/
+// (deposition_granularity*_sensor.getElectrodes(carrier).getPitch(iaxis)));
+// nsegments = Math.max(nsegments,required_segments);
+// }
+// return nsegments;
+// }
+
private Hep3Vector driftDestination(Hep3Vector origin, ChargeCarrier carrier)
{
-// System.out.println("Beginning driftDestination");
+// System.out.println("Beginning driftDestination");
return VecOp.add(origin,driftVector(origin, carrier));
}
private Hep3Vector driftVector(Hep3Vector origin, ChargeCarrier carrier)
{
-// System.out.println("Beginning driftVector");
+// System.out.println("Beginning driftVector");
double drift_vector_scale = _sensor.distanceFromSide(origin,carrier)/_drift_direction.get(carrier).z();
return VecOp.mult(drift_vector_scale,_drift_direction.get(carrier));
}
private Hep3Vector driftDirection(ChargeCarrier carrier, Hep3Vector local_position)
{
-// System.out.println("Beginning driftDirection");
+// System.out.println("Beginning driftDirection");
// System.out.println("Position: "+local_position);
@@ -230,13 +376,13 @@
double tan_lorentz = _sensor.getBulk().tanLorentzAngle(b_field.magnitude(), carrier);
-// System.out.println("Tan lorentz: "+tan_lorentz);
+// System.out.println("Tan lorentz: "+tan_lorentz);
Hep3Vector drift_direction = VecOp.mult(carrier.charge(),VecOp.unit(VecOp.add(
e_field,VecOp.mult(tan_lorentz, VecOp.cross(e_field,VecOp.unit(b_field)))
)));
-// System.out.println("Drift direction: "+drift_direction);
+// System.out.println("Drift direction: "+drift_direction);
return drift_direction;
@@ -250,12 +396,12 @@
double difference_V = _sensor.getBiasVoltage() - _sensor.getDepletionVoltage();
double sum_V = _sensor.getBiasVoltage() + _sensor.getDepletionVoltage();
double common_factor = 2.0*_sensor.distanceFromSide(point,carrier)*_sensor.getDepletionVoltage()/_sensor.getThickness();
-
-// System.out.println("sum_V: "+sum_V);
-// System.out.println("common_factor: "+common_factor);
+
+// System.out.println("sum_V: "+sum_V);
+// System.out.println("common_factor: "+common_factor);
// Calculate charge spreading without magnetic field
- double sigmasq = _sensor.getBulk().K_BOLTZMANN * _sensor.getBulk().getTemperature() *
+ double sigmasq = _sensor.getBulk().K_BOLTZMANN * _sensor.getBulk().getTemperature() *
_sensor.getThickness()*_sensor.getThickness() / _sensor.getDepletionVoltage();
if (_sensor.getBulk().isNtype() == (carrier==ChargeCarrier.HOLE))
{
@@ -268,7 +414,7 @@
double sigma = Math.sqrt(sigmasq);
-// System.out.println("Sigma: "+sigma);
+// System.out.println("Sigma: "+sigma);
// 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));
@@ -279,32 +425,31 @@
double major_axis = minor_axis*(1.0/cos_theta_lorentz); // + drift angle correction
double phi_ellipse = -phi_electrode; // orientation of ellipse, relative to electrode coordinates
-// System.out.println("Minor axis: "+minor_axis);
-// System.out.println("Major axis: "+major_axis);
-
+// System.out.println("Minor axis: "+minor_axis);
+// System.out.println("Major axis: "+major_axis);
+
// Create error ellipse
return new ErrorEllipse2D(major_axis, minor_axis, phi_ellipse);
}
-
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
lcsim/src/org/lcsim/contrib/SiStripSim
diff -u -r1.3 -r1.4
--- Kpix.java 8 May 2007 06:41:53 -0000 1.3
+++ Kpix.java 3 Jul 2007 23:36:52 -0000 1.4
@@ -9,10 +9,9 @@
package org.lcsim.contrib.SiStripSim;
-import java.util.TreeMap;
import java.util.SortedMap;
-import java.util.Map;
-import org.lcsim.detector.tracker.silicon.*;
+import java.util.TreeMap;
+import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
/**
*
@@ -50,19 +49,31 @@
}
}
- public Map<Integer,Integer> readout(SiSensorElectrodes electrodes)
+ public SortedMap<Integer,Integer> readout(SiSensorElectrodes electrodes)
{
- Map<Integer,Integer> raw_charge = electrodes.getChargeMap();
+ SortedMap<Integer,Integer> raw_charge = electrodes.getChargeMap();
int nchannels = electrodes.getNCells();
addNoise(raw_charge, nchannels);
- Map<Integer,Integer> digitized_charge = digitize(raw_charge);
+ SortedMap<Integer,Integer> digitized_charge = digitize(raw_charge);
electrodes.clear();
return digitized_charge;
}
- private void addNoise(Map<Integer,Integer> electrode_charge, int nchannels)
+ public SortedMap<Integer,Integer> readout(SortedMap<Integer,Integer> raw_charge, SiSensorElectrodes electrodes)
+ {
+ int nchannels = electrodes.getNCells();
+
+ addNoise(raw_charge, nchannels);
+ SortedMap<Integer,Integer> digitized_charge = digitize(raw_charge);
+ raw_charge.clear();
+
+ return digitized_charge;
+ }
+
+
+ private void addNoise(SortedMap<Integer,Integer> electrode_charge, int nchannels)
{
for (Integer channel : electrode_charge.keySet())
{
@@ -71,10 +82,10 @@
return;
}
- private Map<Integer,Integer> digitize(Map<Integer,Integer> electrode_charge)
+ private SortedMap<Integer,Integer> digitize(SortedMap<Integer,Integer> electrode_charge)
{
- Map<Integer,Integer> digitized_charge = new TreeMap<Integer,Integer>();
+ SortedMap<Integer,Integer> digitized_charge = new TreeMap<Integer,Integer>();
for (Integer channel : electrode_charge.keySet())
{