Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 131 additions & 31 deletions tracking/src/main/java/org/hps/svt/OccupancyPlots.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
import org.lcsim.detector.ITransform3D;
import org.lcsim.detector.tracker.silicon.ChargeCarrier;
import org.lcsim.detector.tracker.silicon.HpsSiSensor;
import org.lcsim.detector.tracker.silicon.SiStrips;
import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
import org.lcsim.detector.tracker.silicon.SiStriplets;
import org.lcsim.event.EventHeader;
import org.lcsim.event.GenericObject;
import org.lcsim.event.RawTrackerHit;
Expand Down Expand Up @@ -155,10 +156,15 @@ public static Map<Integer, Hep3Vector> createStripPositionMap(HpsSiSensor sensor
Map<Integer, Hep3Vector> positionMap = new HashMap<Integer, Hep3Vector>();
for (ChargeCarrier carrier : ChargeCarrier.values()) {
if (sensor.hasElectrodesOnSide(carrier)) {
SiStrips strips = (SiStrips) sensor.getReadoutElectrodes(carrier);
// Declared as the interface rather than SiStrips: L0 sensors
// (HpsThinSiSensor) carry SiStriplets, which extend SiPixels and
// are not SiStrips. getCellPosition() is on the interface and
// SiStriplets overrides it to return the striplet centre, so the
// polymorphic call is correct for both.
SiSensorElectrodes strips = sensor.getReadoutElectrodes(carrier);
ITransform3D parentToLocal = sensor.getReadoutElectrodes(carrier).getParentToLocal();
ITransform3D localToGlobal = sensor.getReadoutElectrodes(carrier).getLocalToGlobal();
for (int physicalChannel = 0; physicalChannel < 640; physicalChannel++) {
for (int physicalChannel = 0; physicalChannel < sensor.getNumberOfChannels(); physicalChannel++) {
Hep3Vector localStripPosition = strips.getCellPosition(physicalChannel);
Hep3Vector stripPosition = parentToLocal.transformed(localStripPosition);
Hep3Vector globalStripPosition = localToGlobal.transformed(stripPosition);
Expand All @@ -168,7 +174,66 @@ public static Map<Integer, Hep3Vector> createStripPositionMap(HpsSiSensor sensor
}
return positionMap;
}


/**
* Get the number of readout columns of a sensor. Strip sensors (L1-L6, and
* all layers of the pre-2019 geometry) have a single column. L0 striplet
* sensors split their strips into two columns along the strip direction.
*
* @param sensor : HpsSiSensor
* @return The number of columns, always >= 1
*/
private static int getNumberOfColumns(HpsSiSensor sensor) {
SiSensorElectrodes electrodes = sensor.getReadoutElectrodes(ChargeCarrier.HOLE);
// Axis 1 is the column axis for both SiStrips (where it is 1) and
// SiStriplets (where it is 2), but only when the electrodes are 2D.
return electrodes.getNAxes() > 1 ? electrodes.getNCells(1) : 1;
}

/**
* Get the readout column a physical channel belongs to.
*
* Note that SiSensorElectrodes.getColumnNumber(int) is NOT consistent across
* implementations - SiStriplets returns the column, but SiStrips subclasses
* return the strip number itself - so it can only be called on striplets.
*
* @param sensor : HpsSiSensor
* @param physicalChannel : physical channel number
* @return The column number, 0 for strip sensors
*/
private static int getColumnNumber(HpsSiSensor sensor, int physicalChannel) {
SiSensorElectrodes electrodes = sensor.getReadoutElectrodes(ChargeCarrier.HOLE);
if (electrodes instanceof SiStriplets) {
return ((SiStriplets) electrodes).getColumnNumber(physicalChannel);
}
return 0;
}

/**
* Get the plot name suffix identifying a column.
*
* Empty for single-column (strip) sensors, so that both the map keys and the
* histogram names are unchanged from the pre-L0 behaviour.
*
* @param sensor : HpsSiSensor
* @param column : column number
* @return The suffix
*/
private static String getColumnSuffix(HpsSiSensor sensor, int column) {
return getNumberOfColumns(sensor) == 1 ? "" : " - Column " + column;
}

/**
* Get the key used to store the per-column position plots of a sensor.
*
* @param sensor : HpsSiSensor
* @param column : column number
* @return The map key
*/
private static String getPositionPlotKey(HpsSiSensor sensor, int column) {
return sensor.getName() + getColumnSuffix(sensor, column);
}

//Grab the channel associated with the cluster based on position.
private int getClusterChan(SiTrackerHitStrip1D h, HpsSiSensor sensor){
List<RawTrackerHit> rawhits = h.getRawHits();
Expand All @@ -178,10 +243,12 @@ private int getClusterChan(SiTrackerHitStrip1D h, HpsSiSensor sensor){
Hep3Vector pos_global = global.getPositionAsVector();
double clusterHitPos = pos_global.y();
RawTrackerHit hit = rawhits.get(0);
int chan = hit.getIdentifierFieldValue("strip");
double diffmin = Math.abs(getStripPosition(sensor,chan).y() - clusterHitPos);
double diffmin = Double.MAX_VALUE;
for(RawTrackerHit rawhit : rawhits){
int chanhit = rawhit.getIdentifierFieldValue("strip");
// Unbonded channels past the last readout channel have no entry in
// the strip position map.
if (!sensor.isValidChannel(chanhit)) continue;
double diff = Math.abs(getStripPosition(sensor,chanhit).y() - clusterHitPos);
if(diff < diffmin){
diffmin = diff;
Expand Down Expand Up @@ -209,8 +276,10 @@ private void resetPlots() {
clusterOccupancyPlots.get(sensor.getName()).reset();

if (enablePositionPlots) {
positionPlots.get(sensor.getName()).reset();
clusterPositionPlots.get(sensor.getName()).reset();
for (int column = 0; column < getNumberOfColumns(sensor); column++) {
positionPlots.get(getPositionPlotKey(sensor, column)).reset();
clusterPositionPlots.get(getPositionPlotKey(sensor, column)).reset();
}
//clusterPositionPlotCounts.get(sensor.getName()).reset();
}

Expand All @@ -219,8 +288,8 @@ private void resetPlots() {
}

// Reset the hit counters.
occupancyMap.put(sensor.getName(), new int[640]);
clusterOccupancyMap.put(sensor.getName(), new int[640]);
occupancyMap.put(sensor.getName(), new int[sensor.getNumberOfChannels()]);
clusterOccupancyMap.put(sensor.getName(), new int[sensor.getNumberOfChannels()]);
}
}

Expand Down Expand Up @@ -252,11 +321,18 @@ protected void detectorChanged(Detector detector) {
occupancyPlots.put(sensor.getName(),histogramFactory.createHistogram1D(sensor.getName() + " - Occupancy", nChan, 0, nChan));
clusterOccupancyPlots.put(sensor.getName(),histogramFactory.createHistogram1D(sensor.getName() + " - Cluster Occupancy", nChan, 0, nChan));
if (enablePositionPlots){
positionPlots.put(sensor.getName(),histogramFactory.createHistogram1D(sensor.getName() + " - Occupancy vs Position", 1000, -60, 60));
clusterPositionPlots.put(sensor.getName(),histogramFactory.createHistogram1D(sensor.getName() + " - Cluster occupancy vs Position", 1000, -60, 60));
// Strip sensors have a single column and keep the original plot
// names. L0 striplet sensors get one plot per column, so that the
// channel to position mapping stays one to one within each plot.
for (int column = 0; column < getNumberOfColumns(sensor); column++) {
String key = getPositionPlotKey(sensor, column);
String suffix = getColumnSuffix(sensor, column);
positionPlots.put(key,histogramFactory.createHistogram1D(sensor.getName() + " - Occupancy vs Position" + suffix, 1000, -60, 60));
clusterPositionPlots.put(key,histogramFactory.createHistogram1D(sensor.getName() + " - Cluster occupancy vs Position" + suffix, 1000, -60, 60));
}
}
occupancyMap.put(sensor.getName(), new int[640]);
clusterOccupancyMap.put(sensor.getName(), new int[640]);
occupancyMap.put(sensor.getName(), new int[nChan]);
clusterOccupancyMap.put(sensor.getName(), new int[nChan]);
if (enableMaxSamplePlots)
maxSamplePositionPlots.put(sensor.getName(),histogramFactory.createHistogram1D(sensor.getName() + " - Max Sample Number", 6, -0.5, 5.5));
}
Expand Down Expand Up @@ -342,8 +418,15 @@ public void process(EventHeader event) {
}

if (maxSamplePosition == -1 || maxSamplePosition == maxSamplePositionFound) {
occupancyMap.get(((HpsSiSensor) rawHit.getDetectorElement()).getName())[rawHit
.getIdentifierFieldValue("strip")]++;
HpsSiSensor sensor = (HpsSiSensor) rawHit.getDetectorElement();
int strip = rawHit.getIdentifierFieldValue("strip");
// Raw hits can carry the unbonded channel one past the last
// readout channel (639 on a 639 channel strip sensor), which
// StripMaker also drops. It has no strip position and no
// histogram bin, so skip it rather than index past the counters.
if (sensor.isValidChannel(strip)) {
occupancyMap.get(sensor.getName())[strip]++;
}
}

if (enableMaxSamplePlots) {
Expand All @@ -356,14 +439,18 @@ public void process(EventHeader event) {
if (event.hasCollection(SiTrackerHitStrip1D.class, stripClusterCollectionName)) {
List<SiTrackerHitStrip1D> stripHits1D = event.get(SiTrackerHitStrip1D.class, stripClusterCollectionName);
for (SiTrackerHitStrip1D h : stripHits1D) {
int chan = getClusterChan(h,((HpsSiSensor) h.getRawHits().get(0).getDetectorElement()));

HpsSiSensor sensor = (HpsSiSensor) h.getRawHits().get(0).getDetectorElement();
int chan = getClusterChan(h, sensor);
if (!sensor.isValidChannel(chan)) {
continue;
}

if (enableClusterTimeCuts) {
if (h.getTime() < clusterTimeCutMax && h.getTime() > clusterTimeCutMin) {
clusterOccupancyMap.get(((HpsSiSensor) h.getRawHits().get(0).getDetectorElement()).getName())[chan]++;
clusterOccupancyMap.get(sensor.getName())[chan]++;
}
} else {
clusterOccupancyMap.get(((HpsSiSensor) h.getRawHits().get(0).getDetectorElement()).getName())[chan]++;
clusterOccupancyMap.get(sensor.getName())[chan]++;
}
}
}
Expand All @@ -376,7 +463,9 @@ public void process(EventHeader event) {
occupancyPlots.get(sensor.getName()).reset();
clusterOccupancyPlots.get(sensor.getName()).reset();
if (enablePositionPlots) {
positionPlots.get(sensor.getName()).reset();
for (int column = 0; column < getNumberOfColumns(sensor); column++) {
positionPlots.get(getPositionPlotKey(sensor, column)).reset();
}
}
for (int channel = 0; channel < strips.length; channel++) {
double stripOccupancy = (double) strips[channel] / (double) eventCount;
Expand All @@ -385,7 +474,7 @@ public void process(EventHeader event) {

if (enablePositionPlots) {
double stripPosition = this.getStripPosition(sensor, channel).y();
positionPlots.get(sensor.getName()).fill(stripPosition, stripOccupancy);
positionPlots.get(getPositionPlotKey(sensor, getColumnNumber(sensor, channel))).fill(stripPosition, stripOccupancy);
}
}
for (int channel = 0; channel < clusterStrips.length; channel++) {
Expand All @@ -395,7 +484,7 @@ public void process(EventHeader event) {

if (enablePositionPlots) {
double clusterPosition = this.getStripPosition(sensor, channel).y();
clusterPositionPlots.get(sensor.getName()).fill(clusterPosition, clusterOccupancy);
clusterPositionPlots.get(getPositionPlotKey(sensor, getColumnNumber(sensor, channel))).fill(clusterPosition, clusterOccupancy);
}
}
}
Expand All @@ -409,19 +498,30 @@ public void endOfData() {
System.out.println("%======================== Active Edge Sensor Occupancies =======================%");
System.out.println("%===============================================================================%");
System.out.println("% Total Events: " + eventCount);
// Calculate the occupancies at the sensor edge
int[] topActiveEdgeStripOccupancy = new int[6];
int[] bottomActiveEdgeStripOccupancy = new int[6];
// Calculate the occupancies at the sensor edge. The number of layers is
// taken from the geometry rather than assumed to be 6, since the 2019+
// geometry adds L0 for a total of 7.
int nLayers = 0;
for (HpsSiSensor sensor : sensors) {
nLayers = Math.max(nLayers, getLayerNumber(sensor));
}
int[] topActiveEdgeStripOccupancy = new int[nLayers];
int[] bottomActiveEdgeStripOccupancy = new int[nLayers];
for (HpsSiSensor sensor : sensors) {
// The active edge is the last channel on the positron side and the
// second channel on the electron side. Both are sensor-size
// dependent: 638 (of 639) and 1 for strip sensors, 511 (of 512) and 1
// for L0 striplet sensors.
int edgeChannel = sensor.getNumberOfChannels() - 1;
if (sensor.isTopLayer() && sensor.isAxial()) {
if (sensor.getSide().equals(HpsSiSensor.ELECTRON_SIDE)) {
System.out.println("% Top Layer " + getLayerNumber(sensor) + " Hit Counts: "
+ occupancyMap.get(sensor.getName())[1]);
topActiveEdgeStripOccupancy[getLayerNumber(sensor) - 1] += occupancyMap.get(sensor.getName())[1];
} else {
System.out.println("% Top Layer " + getLayerNumber(sensor) + " Hit Counts: "
+ occupancyMap.get(sensor.getName())[638]);
topActiveEdgeStripOccupancy[getLayerNumber(sensor) - 1] += occupancyMap.get(sensor.getName())[638];
+ occupancyMap.get(sensor.getName())[edgeChannel]);
topActiveEdgeStripOccupancy[getLayerNumber(sensor) - 1] += occupancyMap.get(sensor.getName())[edgeChannel];
}
} else if (sensor.isBottomLayer() && sensor.isAxial()) {
if (sensor.getSide().equals(HpsSiSensor.ELECTRON_SIDE)) {
Expand All @@ -430,13 +530,13 @@ public void endOfData() {
bottomActiveEdgeStripOccupancy[getLayerNumber(sensor) - 1] += occupancyMap.get(sensor.getName())[1];
} else {
System.out.println("% Bottom Layer " + getLayerNumber(sensor) + " Hit Counts: "
+ occupancyMap.get(sensor.getName())[638]);
bottomActiveEdgeStripOccupancy[getLayerNumber(sensor) - 1] += occupancyMap.get(sensor.getName())[638];
+ occupancyMap.get(sensor.getName())[edgeChannel]);
bottomActiveEdgeStripOccupancy[getLayerNumber(sensor) - 1] += occupancyMap.get(sensor.getName())[edgeChannel];
}
}
}

for (int layerN = 0; layerN < 6; layerN++) {
for (int layerN = 0; layerN < nLayers; layerN++) {
double topStripOccupancy = (double) topActiveEdgeStripOccupancy[layerN] / (double) eventCount;
topStripOccupancy /= this.timeWindowWeight;
System.out.println("% Top Layer " + (layerN + 1) + ": Occupancy in " + (24 / this.timeWindowWeight)
Expand Down
Loading