diff --git a/tracking/src/main/java/org/hps/recon/tracking/ClusteringAlgorithm.java b/tracking/src/main/java/org/hps/recon/tracking/ClusteringAlgorithm.java index 2b95bb154a..b9e61982ac 100644 --- a/tracking/src/main/java/org/hps/recon/tracking/ClusteringAlgorithm.java +++ b/tracking/src/main/java/org/hps/recon/tracking/ClusteringAlgorithm.java @@ -2,20 +2,21 @@ import java.util.List; +import org.lcsim.event.LCRelation; + /** - * An interface for finding clusters of RawTrackerHits on a sensor. - * @author Matt Graham + * An interface for finding clusters of hits on a sensor. */ public interface ClusteringAlgorithm { /** - * Finds the clusters given a list of RawTrackerHits on a particular silicon sensor with - * electrodes given by SiSensorElectrodes. A list of clusters is returned, with each cluster - * being a list of RawTrackerHits the form the cluster. + * Finds clusters given a list of hits on sensor. * - * @param hits base hits - * @return list of clusters, with each cluster being a list of RawTrackerHits + * @param hits Collection of hits to cluster. Most algorithms will use + * fitted hits which are persited as LCRelations between the + * RawTrackerHit and the resulting fit parameters. + * @return List of clusters, with each cluster being a list of LCRelations */ - public List> findClusters(List hits); + public List< List< LCRelation > > findClusters(List< LCRelation > hits); -} \ No newline at end of file +} diff --git a/tracking/src/main/java/org/hps/recon/tracking/DataTrackerHitDriver.java b/tracking/src/main/java/org/hps/recon/tracking/DataTrackerHitDriver.java index f223b02cf4..60703937cd 100644 --- a/tracking/src/main/java/org/hps/recon/tracking/DataTrackerHitDriver.java +++ b/tracking/src/main/java/org/hps/recon/tracking/DataTrackerHitDriver.java @@ -1,15 +1,10 @@ package org.hps.recon.tracking; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import org.lcsim.detector.IDetectorElement; import org.lcsim.detector.tracker.silicon.SiSensor; import org.lcsim.event.EventHeader; -import org.lcsim.event.LCRelation; -import org.lcsim.event.SimTrackerHit; import org.lcsim.geometry.Detector; import org.lcsim.lcio.LCIOUtil; import org.lcsim.recon.tracking.digitization.sisim.CDFSiSensorSim; @@ -17,24 +12,17 @@ import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D; import org.lcsim.util.Driver; -/** - * - * @author Matt Graham - */ -// TODO: Add documentation about what this Driver does. --JM public class DataTrackerHitDriver extends Driver { // Debug switch for development. private boolean debug = false; - // Collection name. - private String readoutCollectionName = "TrackerHits"; + // Subdetector name. private String subdetectorName = "Tracker"; - // Name of FittedTrackerHit output collection. - private String fittedTrackerHitCollectionName = "SVTFittedRawTrackerHits"; // Name of StripHit1D output collection. private String stripHitOutputCollectionName = "StripClusterer_SiTrackerHitStrip1D"; + // Clustering parameters. private double clusterSeedThreshold = 4.0; private double clusterNeighborThreshold = 3.0; @@ -44,6 +32,7 @@ public class DataTrackerHitDriver extends Driver { private double neighborDeltaT = 24.0; private int clusterMaxSize = 10; private int clusterCentralStripAveragingThreshold = 4; + // Clustering errors by number of TrackerHits. private static final double clusterErrorMultiplier = 1.0; private double oneClusterErr = clusterErrorMultiplier / Math.sqrt(12.); @@ -51,19 +40,17 @@ public class DataTrackerHitDriver extends Driver { private double threeClusterErr = clusterErrorMultiplier / 3.0; private double fourClusterErr = clusterErrorMultiplier / 2.0; private double fiveClusterErr = clusterErrorMultiplier / 1.0; - // weight the hits in a cluster by charge? (if not, all hits have equal weight) + + // Weight the hits in a cluster by charge? (if not, all hits have equal + // weight) private boolean useWeights = true; - // Various data lists required by digitization. - private List processPaths = new ArrayList(); - private List processDEs = new ArrayList(); - private Set processSensors = new HashSet(); - // Digi class objects. - // private SiDigitizer stripDigitizer; - // private HPSFittedRawTrackerHitMaker hitMaker; - private StripMaker stripClusterer; - // private DumbShaperFit shaperFit; - int[] counts = new int[14]; + // Clusterer + private StripMaker stripClusterer; + + // List of sensors to process + private List sensors; + //If flag is false do not save the StripCluster Collection if bigger than threshold (to remove monster events) private boolean saveMonsterEvents = true; @@ -75,9 +62,6 @@ public void setDebug(boolean debug) { this.debug = debug; } - // public void setReadoutCollectionName(String readoutCollectionName) { - // this.readoutCollectionName = readoutCollectionName; - // } public void setSubdetectorName(String subdetectorName) { this.subdetectorName = subdetectorName; } @@ -162,23 +146,9 @@ public DataTrackerHitDriver() { @Override public void detectorChanged(Detector detector) { - // Call sub-Driver's detectorChanged methods. - super.detectorChanged(detector); - - // Process detectors specified by path, otherwise process entire - // detector - IDetectorElement deDetector = detector.getDetectorElement(); - - for (String path : processPaths) - processDEs.add(deDetector.findDetectorElement(path)); - - if (processDEs.isEmpty()) - processDEs.add(deDetector); - - for (IDetectorElement detectorElement : processDEs) - processSensors.addAll(detectorElement.findDescendants(SiSensor.class)); // if (debug) - // System.out.println("added " + processSensors.size() + " sensors"); - + // Get the collection of sensors to process + sensors = detector.getSubdetector("Tracker").getDetectorElement().findDescendants(SiSensor.class); + // Create the sensor simulation. CDFSiSensorSim stripSim = new CDFSiSensorSim(); @@ -191,15 +161,12 @@ public void detectorChanged(Detector detector) { stripClusteringAlgo.setTimeWindow(timeWindow); stripClusteringAlgo.setNeighborDeltaT(neighborDeltaT); - // hitMaker=new HPSFittedRawTrackerHitMaker(shaperFit); - // Create the clusterers and set hit-making parameters. stripClusterer = new StripMaker(stripSim, stripClusteringAlgo); - stripClusterer.setMaxClusterSize(clusterMaxSize); stripClusterer.setCentralStripAveragingThreshold(clusterCentralStripAveragingThreshold); stripClusterer.setDebug(debug); - // Set the cluster errors. + // Set the cluster errors. DefaultSiliconResolutionModel model = new DefaultSiliconResolutionModel(); model.setOneClusterErr(oneClusterErr); @@ -210,9 +177,6 @@ public void detectorChanged(Detector detector) { model.setUseWeights(useWeights); stripClusterer.setResolutionModel(model); - - // Set the detector to process. - processPaths.add(subdetectorName); } /** @@ -220,27 +184,13 @@ public void detectorChanged(Detector detector) { */ @Override public void process(EventHeader event) { - // Call sub-Driver processing. - // super.process(event); - // Make new lists for output. + // Create the collection of 1D strip hits List stripHits1D = new ArrayList(); - // Make strip hits. - for (SiSensor sensor : processSensors) - stripHits1D.addAll(stripClusterer.makeHits(sensor)); - - // Debug prints. - if (debug) { - if (event.hasCollection(SimTrackerHit.class, this.readoutCollectionName)) - System.out.println("SimTrackerHit collection " + this.readoutCollectionName - + " has " + event.get(SimTrackerHit.class, this.readoutCollectionName).size() + " hits."); - if (event.hasCollection(FittedRawTrackerHit.class, fittedTrackerHitCollectionName)) - System.out.println("FittedRawTrackerHit collection " - + this.fittedTrackerHitCollectionName + " has " + event.get(LCRelation.class, fittedTrackerHitCollectionName).size() + " hits."); - System.out.println("TrackerHit collection " + this.stripHitOutputCollectionName + " has " + stripHits1D.size() + " hits."); - } - + // Cluster fitted raw hits + for (SiSensor sensor : sensors) stripHits1D.addAll(stripClusterer.makeHits(sensor)); + if (debug) System.out.println("[ DataTrackerHitDriver ] - " + this.stripHitOutputCollectionName + " has " + stripHits1D.size() + " hits."); @@ -252,16 +202,6 @@ public void process(EventHeader event) { int flag = LCIOUtil.bitSet(0, 31, true); // Turn on 64-bit cell ID. event.put(this.stripHitOutputCollectionName, stripHits1D, SiTrackerHitStrip1D.class, 0, toString()); - for (SiTrackerHit stripHit : stripHits1D) - counts[((SiTrackerHitStrip1D) stripHit).getRawHits().get(0).getLayerNumber()-1]++; - } - @Override - public void endOfData() { - if (debug) - - for (int layer = 0; layer < 14; layer++) - System.out.format("layer %d, count %d\n",layer, counts[layer]); - } } diff --git a/tracking/src/main/java/org/hps/recon/tracking/DefaultSiliconResolutionModel.java b/tracking/src/main/java/org/hps/recon/tracking/DefaultSiliconResolutionModel.java index ff59679bca..ccf4ca8564 100644 --- a/tracking/src/main/java/org/hps/recon/tracking/DefaultSiliconResolutionModel.java +++ b/tracking/src/main/java/org/hps/recon/tracking/DefaultSiliconResolutionModel.java @@ -7,6 +7,7 @@ import org.lcsim.detector.tracker.silicon.SiSensorElectrodes; import org.lcsim.detector.tracker.silicon.SiStrips; import org.lcsim.detector.tracker.silicon.SiStriplets; +import org.lcsim.event.LCRelation; import hep.physics.vec.BasicHep3Vector; import hep.physics.vec.Hep3Vector; @@ -15,7 +16,7 @@ public class DefaultSiliconResolutionModel implements SiliconResolutionModel{ @Override - public double getMeasuredResolution(List cluster, SiSensorElectrodes electrodes) + public double getMeasuredResolution(List< LCRelation > cluster, SiSensorElectrodes electrodes) { double measured_resolution; @@ -51,13 +52,13 @@ public double getMeasuredResolution(List cluster, SiSensorE // be handled differently because it does not inherit from SiStrips. // To clean this up, the getStripLength method should be added to // SiSensorElectrodes. This would elimininate the need for casting. - public double getUnmeasuredResolution(List cluster, SiSensorElectrodes electrodes, Map strip_map) { + public double getUnmeasuredResolution(List< LCRelation > cluster, SiSensorElectrodes electrodes, Map strip_map) { // Get length of longest strip in hit if (electrodes instanceof SiStriplets) return ((SiStriplets) electrodes).getStripLength(strip_map.get(cluster.get(0))); double hit_length = 0; - for (FittedRawTrackerHit hit : cluster) { + for (LCRelation hit : cluster) { hit_length = Math.max(hit_length, ((SiStrips) electrodes).getStripLength(strip_map.get(hit))); } return hit_length / Math.sqrt(12); diff --git a/tracking/src/main/java/org/hps/recon/tracking/FittedRawTrackerHit.java b/tracking/src/main/java/org/hps/recon/tracking/FittedRawTrackerHit.java index dfccbfc519..d76ea386a9 100644 --- a/tracking/src/main/java/org/hps/recon/tracking/FittedRawTrackerHit.java +++ b/tracking/src/main/java/org/hps/recon/tracking/FittedRawTrackerHit.java @@ -11,7 +11,6 @@ * @version $Id: HPSFittedRawTrackerHit.java,v 1.3 2013/04/16 22:05:43 phansson * Exp $ */ -// TODO: Add class documentation. public class FittedRawTrackerHit extends BaseLCRelation { public FittedRawTrackerHit(RawTrackerHit hit, ShapeFitParameters fit) { @@ -50,6 +49,16 @@ public static double getAmp(LCRelation rel) { return ShapeFitParameters.getAmp(getShapeFitParameters(rel)); } + /** + * Get the fit chi2 probability. + * + * @param relation The relation between a RawTrackerHit and + * ShapeFitParameter. + */ + public static double getChi2Prob(LCRelation relation) { + return ShapeFitParameters.getChiProb(getShapeFitParameters(relation)); + } + @Override public String toString() { return String.format("HPSFittedRawTrackerHit: hit cell id %d on sensor %s with fit %s\n", this.getRawTrackerHit().getCellID(), getRawTrackerHit().getDetectorElement().getName(), this.getShapeFitParameters().toString()); diff --git a/tracking/src/main/java/org/hps/recon/tracking/NearestNeighborRMSClusterer.java b/tracking/src/main/java/org/hps/recon/tracking/NearestNeighborRMSClusterer.java index 5439aef0c1..865199fcdd 100644 --- a/tracking/src/main/java/org/hps/recon/tracking/NearestNeighborRMSClusterer.java +++ b/tracking/src/main/java/org/hps/recon/tracking/NearestNeighborRMSClusterer.java @@ -12,18 +12,12 @@ import org.apache.commons.math3.special.Gamma; import org.hps.readout.svt.HPSSVTConstants; -//===> import org.hps.conditions.deprecated.HPSSVTCalibrationConstants; import org.lcsim.detector.identifier.IIdentifier; import org.lcsim.detector.tracker.silicon.HpsSiSensor; -//===> import org.lcsim.detector.tracker.silicon.SiSensor; import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper; +import org.lcsim.event.LCRelation; import org.lcsim.event.RawTrackerHit; -/** - * - * @author Matt Graham - */ -// TODO: Add class documentation. public class NearestNeighborRMSClusterer implements ClusteringAlgorithm { private static String _NAME = "NearestNeighborRMS"; @@ -102,27 +96,26 @@ public void setClusterThreshold(double cluster_threshold) { } /** - * Find clusters using the nearest neighbor algorithm. + * Use a nearest neighbor algorithm to create clusters. * - * @param base_hits List of RawTrackerHits to be clustered - * @return list of clusters, with a cluster being a list of RawTrackerHits + * @param fittedHits Collection of fitted raw tracker hits to cluster. + * @return Collection of fitted hits */ @Override - public List> findClusters(List base_hits) { + public List> findClusters(List fittedHits) { - // Check that the seed threshold is at least as large as the neighbor threshold + // Check that the seed threshold is at least as large as the neighbor + // threshold if (_seed_threshold < _neighbor_threshold) { throw new RuntimeException("Tracker hit clustering error: seed threshold below neighbor threshold"); } - // Create maps that show the channel status and relate the channel number to the raw hit - // and vice versa - int mapsize = 2 * base_hits.size(); -// Map clusterable = new HashMap(mapsize); + // Create maps that show the channel status and relate the channel + // number to the raw hit and vice versa + int mapsize = 2 * fittedHits.size(); Set clusterableSet = new HashSet(mapsize); -// Map hit_to_channel = new HashMap(mapsize); - Map channel_to_hit = new HashMap(mapsize); + Map channel_to_hit = new HashMap(mapsize); // Create list of channel numbers to be used as cluster seeds List cluster_seeds = new ArrayList(); @@ -130,79 +123,59 @@ public List> findClusters(List ba // Loop over the raw hits and construct the maps used to relate cells and hits, initialize // the // clustering status map, and create a list of possible cluster seeds - for (FittedRawTrackerHit base_hit : base_hits) { + for (LCRelation fittedHit : fittedHits) { - RawTrackerHit rth = base_hit.getRawTrackerHit(); + RawTrackerHit rawHit = FittedRawTrackerHit.getRawTrackerHit(fittedHit); + // get the channel number for this hit - SiTrackerIdentifierHelper sid_helper = (SiTrackerIdentifierHelper) rth.getIdentifierHelper(); - IIdentifier id = rth.getIdentifier(); + SiTrackerIdentifierHelper sid_helper = (SiTrackerIdentifierHelper) rawHit.getIdentifierHelper(); + IIdentifier id = rawHit.getIdentifier(); int channel_number = sid_helper.getElectrodeValue(id); -// // Check for duplicate RawTrackerHit -// if (hit_to_channel.containsKey(base_hit)) { -// throw new RuntimeException("Duplicate hit: " + id.toString()); -// } // Check for duplicate RawTrackerHits or channel numbers if (channel_to_hit.containsKey(channel_number)) { - // throw new RuntimeException("Duplicate channel number: "+channel_number); -// System.out.println("Duplicate channel number: " + channel_number); - //if the hit currently in the map has smaller time, use it and discard the new hit //TODO: be smarter about this - if (Math.abs(((FittedRawTrackerHit) channel_to_hit.get(channel_number)).getT0()) < Math.abs(base_hit.getT0())) { + if (Math.abs(FittedRawTrackerHit.getT0(channel_to_hit.get(channel_number))) + < Math.abs(FittedRawTrackerHit.getT0(fittedHit))) { continue; } } // Add this hit to the maps that relate channels and hits -// hit_to_channel.put(base_hit, channel_number); - channel_to_hit.put(channel_number, base_hit); + channel_to_hit.put(channel_number, fittedHit); // Get the signal from the readout chip - double signal = base_hit.getAmp(); + double signal = FittedRawTrackerHit.getAmp(fittedHit); double noiseRMS = 0; for(int sampleN = 0; sampleN < HPSSVTConstants.TOTAL_NUMBER_OF_SAMPLES; sampleN++){ - noiseRMS += ((HpsSiSensor) rth.getDetectorElement()).getNoise(channel_number, sampleN); + noiseRMS += ((HpsSiSensor) rawHit.getDetectorElement()).getNoise(channel_number, sampleN); } noiseRMS = noiseRMS/HPSSVTConstants.TOTAL_NUMBER_OF_SAMPLES; - //===> double noiseRMS = HPSSVTCalibrationConstants.getNoise((SiSensor) rth.getDetectorElement(), channel_number); - - // Mark this hit as available for clustering if it is above the neighbor threshold - if (signal / noiseRMS >= _neighbor_threshold && passChisqCut(base_hit)) { + if (signal / noiseRMS >= _neighbor_threshold && passChisqCut(fittedHit)) { clusterableSet.add(channel_number); } // Add this hit to the list of seeds if it is above the seed threshold - if (signal / noiseRMS >= _seed_threshold && passTimingCut(base_hit) && passChisqCut(base_hit)) { + if (signal / noiseRMS >= _seed_threshold && passTimingCut(fittedHit) && passChisqCut(fittedHit)) { cluster_seeds.add(channel_number); } } -// System.out.println("Hits to be clustered:"); -// for (int i = 0; i < 639; i++) { -// FittedRawTrackerHit base_hit = channel_to_hit.get(i); -// if (base_hit != null) { -// System.out.format("channel %d\tt0 %f\t amp %f\n", i, base_hit.getT0(), base_hit.getAmp()); -// } -// } - // Create a list of clusters - List> cluster_list = new ArrayList>(); + // TODO: Create a cluster class instead + List> cluster_list = new ArrayList>(); // Now loop over the cluster seeds to form clusters for (int seed_channel : cluster_seeds) { - // First check if this hit is still available for clustering -// if (!clusterable.get(seed_channel)) { -// continue; -// } if (!clusterableSet.contains(seed_channel)) { continue; } // Create a new cluster - List cluster = new ArrayList(); + List cluster = new ArrayList(); double cluster_signal = 0.; double cluster_noise_squared = 0.; double cluster_weighted_time = 0.; @@ -212,7 +185,6 @@ public List> findClusters(List ba // Add the seed channel to the unchecked list and mark it as unavailable for clustering unchecked.addLast(seed_channel); -// clusterable.put(seed_channel, false); clusterableSet.remove(seed_channel); // Check the neighbors of channels added to the cluster @@ -221,20 +193,15 @@ public List> findClusters(List ba // Pull the next channel off the queue and add it's hit to the cluster int clustered_cell = unchecked.removeFirst(); cluster.add(channel_to_hit.get(clustered_cell)); - FittedRawTrackerHit hit = channel_to_hit.get(clustered_cell); - cluster_signal += hit.getAmp(); + LCRelation hit = channel_to_hit.get(clustered_cell); + cluster_signal += FittedRawTrackerHit.getAmp(hit); double strip_noise = 0; for(int sampleN = 0; sampleN < HPSSVTConstants.TOTAL_NUMBER_OF_SAMPLES; sampleN++){ - strip_noise += ((HpsSiSensor) hit.getRawTrackerHit().getDetectorElement()).getNoise(clustered_cell, sampleN); + strip_noise += ((HpsSiSensor) FittedRawTrackerHit.getRawTrackerHit(hit).getDetectorElement()).getNoise(clustered_cell, sampleN); } strip_noise = strip_noise/HPSSVTConstants.TOTAL_NUMBER_OF_SAMPLES; cluster_noise_squared += Math.pow(strip_noise, 2); - //===> cluster_noise_squared += Math.pow(HPSSVTCalibrationConstants.getNoise((SiSensor) hit.getRawTrackerHit().getDetectorElement(), clustered_cell), 2); - cluster_weighted_time += hit.getT0() * hit.getAmp(); - // cluster_noise_squared +=0; //need to get the noise from the calib. const. class - // Get the neigbor channels - // Set neighbor_channels = - // electrodes.getNearestNeighborCells(clustered_cell); + cluster_weighted_time += FittedRawTrackerHit.getT0(hit) * FittedRawTrackerHit.getAmp(hit); Collection neighbor_channels = getNearestNeighborCells(clustered_cell); // Now loop over the neighbors and see if we can add them to the cluster @@ -245,9 +212,8 @@ public List> findClusters(List ba continue; } - FittedRawTrackerHit neighbor_hit = channel_to_hit.get(channel); - if (Math.abs(neighbor_hit.getT0() - cluster_weighted_time / cluster_signal) > _neighborDeltaT) { -// System.out.format("new hit t0 %f, cluster t0 %f\n", neighbor_hit.getT0(), cluster_weighted_time / cluster_signal); + LCRelation neighbor_hit = channel_to_hit.get(channel); + if (Math.abs(FittedRawTrackerHit.getT0(neighbor_hit) - cluster_weighted_time / cluster_signal) > _neighborDeltaT) { continue; } @@ -267,33 +233,19 @@ public List> findClusters(List ba } // End of loop over seeds -// for (List cluster : cluster_list) { -// System.out.format("cluster with %d hits\n",cluster.size()); -// for (FittedRawTrackerHit base_hit : cluster) { -// System.out.format("channel %d\tt0 %f\t amp %f\n", base_hit.getRawTrackerHit().getIdentifierFieldValue("strip"), base_hit.getT0(), base_hit.getAmp()); -// } -// } // Finished finding clusters return cluster_list; } - private boolean passTimingCut(FittedRawTrackerHit hit) { - double time = hit.getT0(); + private boolean passTimingCut(LCRelation fittedHit) { + double time = FittedRawTrackerHit.getT0(fittedHit); return (Math.abs(time - _meanTime) < _timeWindow); } - private boolean passChisqCut(FittedRawTrackerHit hit) { - return hit.getShapeFitParameters().getChiProb() > _minChiProb; + private boolean passChisqCut(LCRelation fittedHit) { + return FittedRawTrackerHit.getChi2Prob(fittedHit) > _minChiProb; } -// public int getNeighborCell(int cell, int ncells_0, int ncells_1) { -// int neighbor_cell = cell + ncells_0; -// if (isValidCell(neighbor_cell)) { -// return neighbor_cell; -// } else { -// return -1; -// } -// } public Collection getNearestNeighborCells(int cell) { Collection neighbors = new ArrayList(2); for (int ineigh = -1; ineigh <= 1; ineigh = ineigh + 2) { diff --git a/tracking/src/main/java/org/hps/recon/tracking/SensorSetup.java b/tracking/src/main/java/org/hps/recon/tracking/SensorSetup.java new file mode 100644 index 0000000000..3286fd8ca7 --- /dev/null +++ b/tracking/src/main/java/org/hps/recon/tracking/SensorSetup.java @@ -0,0 +1,57 @@ +package org.hps.recon.tracking; + +import java.util.List; + +import org.lcsim.detector.tracker.silicon.SiSensor; +import org.lcsim.event.EventHeader; +import org.lcsim.event.LCRelation; +import org.lcsim.event.RawTrackerHit; +import org.lcsim.recon.tracking.digitization.sisim.config.RawTrackerHitSensorSetup; + + +/** + * Driver used to load FittedRawTrackerHits onto a sensor readout. + */ +public class SensorSetup extends RawTrackerHitSensorSetup { + + /// Name of the collection of fitted hits + private String fittedHitColName_ = ""; + + /// Constructor + public SensorSetup() { } + + /** + * Set the name of the FittedRawTrackerHit collection to load onto a sensor + * readout. + * + * @param fittedHitColName Name of the FittedRawTrackerHit collection to + * load. + */ + public void setFittedHitCollection(String fittedHitColName) { fittedHitColName_ = fittedHitColName; } + + @Override + protected void process(EventHeader event) { + + super.process(event); + + if (!event.hasCollection(LCRelation.class, fittedHitColName_)) return; + + List< LCRelation > fittedHits = event.get(LCRelation.class, fittedHitColName_); + + loadFittedHits(fittedHits); + } + + /** + * Method to process all FittedRawTrackerHits and load them onto a sensor + * readout. + * + * @param fittedHits The collection of FittedRawTrackerHits to load. + */ + public void loadFittedHits(List< LCRelation > fittedHits) { + + for (LCRelation fittedHit : fittedHits) { + RawTrackerHit rawHit = FittedRawTrackerHit.getRawTrackerHit(fittedHit); + ((SiSensor) rawHit.getDetectorElement()).getReadout().addHit(fittedHit); + } + } +} diff --git a/tracking/src/main/java/org/hps/recon/tracking/ShapeFitParameters.java b/tracking/src/main/java/org/hps/recon/tracking/ShapeFitParameters.java index d16f7ee883..e9db1e35ee 100644 --- a/tracking/src/main/java/org/hps/recon/tracking/ShapeFitParameters.java +++ b/tracking/src/main/java/org/hps/recon/tracking/ShapeFitParameters.java @@ -23,6 +23,14 @@ public ShapeFitParameters(double t0, double amplitude) { _t0 = t0; _amp = amplitude; } + + public ShapeFitParameters(GenericObject parameters) { + setT0(getT0(parameters)); + setT0Err(getT0Err(parameters)); + setAmp(getAmp(parameters)); + setAmpErr(getAmpErr(parameters)); + setChiProb(getChiProb(parameters)); + } public void setT0(double t0) { _t0 = t0; diff --git a/tracking/src/main/java/org/hps/recon/tracking/SiliconResolutionModel.java b/tracking/src/main/java/org/hps/recon/tracking/SiliconResolutionModel.java index 1d1b252e5c..bd1764aa3e 100644 --- a/tracking/src/main/java/org/hps/recon/tracking/SiliconResolutionModel.java +++ b/tracking/src/main/java/org/hps/recon/tracking/SiliconResolutionModel.java @@ -3,12 +3,13 @@ import java.util.List; import java.util.Map; +import org.lcsim.event.LCRelation; import org.lcsim.detector.tracker.silicon.SiSensorElectrodes; import hep.physics.vec.Hep3Vector; public interface SiliconResolutionModel { - public double getMeasuredResolution(List cluster, SiSensorElectrodes electrodes); - public double getUnmeasuredResolution(List cluster, SiSensorElectrodes electrodes, Map strip_map); + public double getMeasuredResolution(List< LCRelation > cluster, SiSensorElectrodes electrodes); + public double getUnmeasuredResolution(List< LCRelation > cluster, SiSensorElectrodes electrodes, Map strip_map); public Hep3Vector weightedAveragePosition(List signals, List positions); } diff --git a/tracking/src/main/java/org/hps/recon/tracking/StripMaker.java b/tracking/src/main/java/org/hps/recon/tracking/StripMaker.java index 220cf0c757..09b071fecf 100644 --- a/tracking/src/main/java/org/hps/recon/tracking/StripMaker.java +++ b/tracking/src/main/java/org/hps/recon/tracking/StripMaker.java @@ -10,7 +10,6 @@ import java.util.Map; import org.lcsim.detector.IDetectorElement; -import org.lcsim.detector.IReadout; import org.lcsim.detector.identifier.IIdentifier; import org.lcsim.detector.tracker.silicon.ChargeCarrier; import org.lcsim.detector.tracker.silicon.DopedSilicon; @@ -20,12 +19,15 @@ import org.lcsim.detector.tracker.silicon.SiStriplets; import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper; import org.lcsim.detector.tracker.silicon.ThinSiStrips; +import org.lcsim.event.LCRelation; import org.lcsim.event.RawTrackerHit; import org.lcsim.recon.tracking.digitization.sisim.SiSensorSim; import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHit; import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D; import org.lcsim.recon.tracking.digitization.sisim.TrackerHitType; +import org.hps.readout.svt.HPSSVTConstants; + /** * * @author Matt Graham @@ -45,7 +47,8 @@ public class StripMaker { // Identifier helper (reset once per sensor) SiTrackerIdentifierHelper _sid_helper; // Temporary map connecting hits to strip numbers for sake of speed (reset once per sensor) - Map _strip_map = new HashMap(); + //Map _strip_map = new HashMap(); + Map< LCRelation, Integer > stripMap_ = new HashMap< LCRelation, Integer >(); boolean _debug = false; private SiliconResolutionModel _res_model = new DefaultSiliconResolutionModel(); @@ -88,77 +91,85 @@ public List makeHits(IDetectorElement detector) { // Make hits for a sensor public List makeHits(SiSensor sensor) { - // System.out.println("makeHits: " + sensor.getName()); List hits = new ArrayList(); - // Get SiTrackerIdentifierHelper for this sensor and refresh the strip map used to increase - // speed + // Get SiTrackerIdentifierHelper for this sensor and refresh the + // strip map used to increase speed _sid_helper = (SiTrackerIdentifierHelper) sensor.getIdentifierHelper(); - _strip_map.clear(); + stripMap_.clear(); + + // Get the collection of LCRelations (RawTrackerHit to fit parameters) + // from the sensor readout. + List< LCRelation > fittedHits = sensor.getReadout().getHits(LCRelation.class); + + // Map out the electrodes to the corresponding hit + // TODO: Do we need a map for each sensor type? + // TODO: Are we still using the thin sensors class? + Map> electrode_hits = new LinkedHashMap>(); + Map> thin_hits = new LinkedHashMap>(); + Map> stripletHits = new LinkedHashMap>(); - // Get hits for this sensor - IReadout ro = sensor.getReadout(); - List hps_hits = ro.getHits(FittedRawTrackerHit.class); + for (LCRelation fittedHit : fittedHits) { - Map> electrode_hits = new LinkedHashMap>(); - Map> thin_hits = new LinkedHashMap>(); - Map> stripletHits = new LinkedHashMap>(); + // Get the RawTrackerHit associated with the fitted hit. + RawTrackerHit hit = FittedRawTrackerHit.getRawTrackerHit(fittedHit); - for (FittedRawTrackerHit hps_hit : hps_hits) { + // Get the ID and create strip map, get electrodes. + IIdentifier id = hit.getIdentifier(); + int strip = _sid_helper.getElectrodeValue(id); + + // Drop the unbonded channel + if (strip == HPSSVTConstants.TOTAL_STRIPS_PER_SENSOR) continue; - // get id and create strip map, get electrodes. - IIdentifier id = hps_hit.getRawTrackerHit().getIdentifier(); - _strip_map.put(hps_hit, _sid_helper.getElectrodeValue(id)); + stripMap_.put(fittedHit, _sid_helper.getElectrodeValue(id)); // Get electrodes and check that they are strips - // System.out.println("proc raw hit from: " + - // DetectorElementStore.getInstance().find(raw_hit.getIdentifier()).get(0).getName()); ChargeCarrier carrier = ChargeCarrier.getCarrier(_sid_helper.getSideValue(id)); - SiSensorElectrodes electrodes = ((SiSensor) hps_hit.getRawTrackerHit().getDetectorElement()).getReadoutElectrodes(carrier); + SiSensorElectrodes electrodes = ((SiSensor) hit.getDetectorElement()).getReadoutElectrodes(carrier); if (electrodes instanceof ThinSiStrips) { if (thin_hits.get(electrodes) == null) - thin_hits.put(electrodes, new ArrayList()); - thin_hits.get(electrodes).add(hps_hit); + thin_hits.put(electrodes, new ArrayList()); + thin_hits.get(electrodes).add(fittedHit); } else if (electrodes instanceof SiStriplets) { if (_debug) System.out.println("StripMaker::makeHits : Electrodes are of SiStriplets"); - if (stripletHits.get(electrodes) == null) stripletHits.put(electrodes, new ArrayList()); + if (stripletHits.get(electrodes) == null) stripletHits.put(electrodes, new ArrayList()); - stripletHits.get(electrodes).add(hps_hit); + stripletHits.get(electrodes).add(fittedHit); } else { if (electrode_hits.get(electrodes) == null) - electrode_hits.put(electrodes, new ArrayList()); - electrode_hits.get(electrodes).add(hps_hit); + electrode_hits.put(electrodes, new ArrayList()); + electrode_hits.get(electrodes).add(fittedHit); } } for (Map.Entry entry : electrode_hits.entrySet()) - hits.addAll(makeHits(sensor, (SiStrips) entry.getKey(), (List) entry.getValue())); + hits.addAll(makeHits(sensor, (SiStrips) entry.getKey(), (List) entry.getValue())); for (Map.Entry entry : thin_hits.entrySet()) - hits.addAll(makeHits(sensor, (ThinSiStrips) entry.getKey(), (List) entry.getValue())); + hits.addAll(makeHits(sensor, (ThinSiStrips) entry.getKey(), (List) entry.getValue())); for (Map.Entry entry : stripletHits.entrySet()) - hits.addAll(makeHits(sensor, (SiStriplets) entry.getKey(), (List) entry.getValue())); + hits.addAll(makeHits(sensor, (SiStriplets) entry.getKey(), (List) entry.getValue())); if (_debug) - System.out.println(this.getClass().getSimpleName() + "::makeHits returning " + hits.size() + " clusters from sensor"); + System.out.println(this.getClass().getSimpleName() + "::makeHits returning " + hits.size() + " clusters from sensor "+sensor.getName()); return hits; } - public List makeHits(SiSensor sensor, SiSensorElectrodes electrodes, List hps_hits) { + public List makeHits(SiSensor sensor, SiSensorElectrodes electrodes, List fittedHits) { // Call the clustering algorithm to make clusters - List> cluster_list = _clustering.findClusters(hps_hits); + List> cluster_list = _clustering.findClusters(fittedHits); if (_debug) System.out.println(this.getClass().getSimpleName() + "::makeHits : Found clusters = " + cluster_list.size()); // Create an empty list for the pixel hits to be formed from clusters List hits = new ArrayList(); // Make a pixel hit from this cluster - for (List cluster : cluster_list) + for (List cluster : cluster_list) // Make a TrackerHit from the cluster if it meets max cluster size requirement if (cluster.size() <= _max_cluster_nstrips) { @@ -181,7 +192,7 @@ public void setMaxClusterSize(int max_cluster_nstrips) { _max_cluster_nstrips = max_cluster_nstrips; } - private SiTrackerHitStrip1D makeTrackerHit(List cluster, SiSensorElectrodes electrodes) { + private SiTrackerHitStrip1D makeTrackerHit(List cluster, SiSensorElectrodes electrodes) { Hep3Vector position = getPosition(cluster, electrodes); if (_debug) System.out.println("StripMaker::makeTrackerHit : Cluster position: " + position.toString()); @@ -193,15 +204,15 @@ private SiTrackerHitStrip1D makeTrackerHit(List cluster, Si double energy = getEnergy(cluster); TrackerHitType type = new TrackerHitType(TrackerHitType.CoordinateSystem.GLOBAL, TrackerHitType.MeasurementType.STRIP_1D); List rth_cluster = new ArrayList(); - for (FittedRawTrackerHit bth : cluster) - rth_cluster.add(bth.getRawTrackerHit()); + for (LCRelation bth : cluster) + rth_cluster.add(FittedRawTrackerHit.getRawTrackerHit(bth)); SiTrackerHitStrip1D hit = new SiTrackerHitStrip1D(position, covariance, energy, time, rth_cluster, type); if (_debug) System.out.println(this.getClass().getSimpleName() + " SiTrackerHitStrip1D created at " + position + "(" + hit.getPositionAsVector().toString() + ")" + " E " + energy + " time " + time); return hit; } - private Hep3Vector getPosition(List cluster, SiSensorElectrodes electrodes) { + private Hep3Vector getPosition(List cluster, SiSensorElectrodes electrodes) { if (_debug) System.out.println("StripMaker::getPosition : Calculating position for cluster size " + cluster.size()); List signals = new ArrayList(); List positions = new ArrayList(); @@ -209,20 +220,20 @@ private Hep3Vector getPosition(List cluster, SiSensorElectr if (_debug) System.out.println(this.getClass().getSimpleName() + " Loop of " + cluster.size() + " and add signals and positions to vectors"); - for (FittedRawTrackerHit hit : cluster) { - signals.add(hit.getAmp()); + for (LCRelation hit : cluster) { + signals.add(FittedRawTrackerHit.getAmp(hit)); if (electrodes instanceof ThinSiStrips) { - positions.add(((ThinSiStrips) electrodes).getStripCenter(_strip_map.get(hit))); + positions.add(((ThinSiStrips) electrodes).getStripCenter(stripMap_.get(hit))); // if (hit.getRawTrackerHit().getLayerNumber() < 4) -// System.out.println("thinStripCenter is at " + ((ThinSiStrips) electrodes).getStripCenter(_strip_map.get(hit)).toString()); +// System.out.println("thinStripCenter is at " + ((ThinSiStrips) electrodes).getStripCenter(stripMap_.get(hit)).toString()); } else if (electrodes instanceof SiStriplets) { - Hep3Vector position = ((SiStriplets) electrodes).getStripCenter(_strip_map.get(hit)); + Hep3Vector position = ((SiStriplets) electrodes).getStripCenter(stripMap_.get(hit)); if (_debug) System.out.println("StripMaker::getPosition : Position " + position.toString()); positions.add(position); } else { - positions.add(((SiStrips) electrodes).getStripCenter(_strip_map.get(hit))); + positions.add(((SiStrips) electrodes).getStripCenter(stripMap_.get(hit))); // if (hit.getRawTrackerHit().getLayerNumber() < 4) -// System.out.println("stripCenter is at " + ((SiStrips) electrodes).getStripCenter(_strip_map.get(hit)).toString()); +// System.out.println("stripCenter is at " + ((SiStrips) electrodes).getStripCenter(stripMap_.get(hit)).toString()); } } @@ -266,19 +277,16 @@ private Hep3Vector getPosition(List cluster, SiSensorElectr System.out.println(this.getClass().getSimpleName() + " final cluster position " + newpos.toString()); return ((SiSensor) electrodes.getDetectorElement()).getGeometry().getLocalToGlobal().transformed(position); - // return electrodes.getLocalToGlobal().transformed(position); } - private double getTime(List cluster) { + private double getTime(List cluster) { double time_sum = 0; double signal_sum = 0; -// System.out.format("Hits:\n"); - for (FittedRawTrackerHit hit : cluster) { + for (LCRelation hit : cluster) { - double signal = hit.getAmp(); - double time = hit.getT0(); -// System.out.format("t0=%f\tA=%f\n",hit.getT0(),hit.getAmp()); + double signal = FittedRawTrackerHit.getAmp(hit); + double time = FittedRawTrackerHit.getT0(hit); time_sum += time * signal * signal; signal_sum += signal * signal; @@ -287,10 +295,10 @@ private double getTime(List cluster) { return time_sum / signal_sum; } - private SymmetricMatrix getCovariance(List cluster, SiSensorElectrodes electrodes) { + private SymmetricMatrix getCovariance(List cluster, SiSensorElectrodes electrodes) { SymmetricMatrix covariance = new SymmetricMatrix(3); covariance.setElement(0, 0, Math.pow(_res_model.getMeasuredResolution(cluster, electrodes), 2)); - covariance.setElement(1, 1, Math.pow(_res_model.getUnmeasuredResolution(cluster, electrodes, _strip_map), 2)); + covariance.setElement(1, 1, Math.pow(_res_model.getUnmeasuredResolution(cluster, electrodes, stripMap_), 2)); covariance.setElement(2, 2, 0.0); SymmetricMatrix covariance_global = electrodes.getLocalToGlobal().transformed(covariance); @@ -315,10 +323,10 @@ private SymmetricMatrix getCovariance(List cluster, SiSenso // return new SymmetricMatrix((Matrix)covariance_global); } - private double getEnergy(List cluster) { + private double getEnergy(List cluster) { double total_charge = 0.0; - for (FittedRawTrackerHit hit : cluster) { - double signal = hit.getAmp(); + for (LCRelation hit : cluster) { + double signal = FittedRawTrackerHit.getAmp(hit); total_charge += signal; } return total_charge * DopedSilicon.ENERGY_EHPAIR; diff --git a/tracking/src/test/java/org/hps/recon/tracking/DataTrackerHitDriverTest.java b/tracking/src/test/java/org/hps/recon/tracking/DataTrackerHitDriverTest.java new file mode 100644 index 0000000000..9c12932910 --- /dev/null +++ b/tracking/src/test/java/org/hps/recon/tracking/DataTrackerHitDriverTest.java @@ -0,0 +1,95 @@ +package org.hps.recon.tracking; + +import java.io.File; +import java.net.URL; +import junit.framework.TestCase; +import org.hps.conditions.database.DatabaseConditionsManager; +import org.hps.detector.svt.SvtDetectorSetup; +import org.lcsim.recon.tracking.digitization.sisim.config.RawTrackerHitSensorSetup; +import org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver; +import org.lcsim.util.cache.FileCache; +import org.lcsim.util.loop.LCSimLoop; + +/** + * + * This class provides a testbed for SVT hit reconstruction on data. Running + * once with rerunFromFittedHits set false emulates the full recon chain from + * scratch. Running again with rerunFromFittedHits set true tests whether we can + * successfully reconstruct from an output LCIO file with the + * FittedRawTrackerHit collections. Should check that the output + * StripClusterer_SiTrackerHitStrip1D are the same in both cases. + * + * [ DataTrackerHitDriver ] - StripClusterer_SiTrackerHitStrip1D has 56 hits. + * layer 0, count 9 layer 1, count 9 layer 2, count 3 layer 3, count 5 layer 4, + * count 7 layer 5, count 9 layer 6, count 2 layer 7, count 4 layer 8, count 1 + * layer 9, count 2 layer 10, count 1 layer 11, count 1 layer 12, count 3 layer + * 13, count 0 + * + * I could automate this but not worth the effort at this time. + * + * + * @author Norman A Graf + */ +public class DataTrackerHitDriverTest extends TestCase { + + public static void testIt() throws Exception { + FileCache cache = new FileCache(); + int nEvents = 1; + LCSimLoop loop = new LCSimLoop(); + + final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance(); + manager.addConditionsListener(new SvtDetectorSetup()); + + RawTrackerHitSensorSetup rawSensorSetup = new RawTrackerHitSensorSetup(); + String[] readoutCollections = {"SVTRawTrackerHits"}; + rawSensorSetup.setReadoutCollections(readoutCollections); + + RawTrackerHitFitterDriver rthfDriver = new RawTrackerHitFitterDriver(); + rthfDriver.setFitAlgorithm("Pileup"); + rthfDriver.setUseTimestamps(false); + rthfDriver.setCorrectTimeOffset(true); + rthfDriver.setCorrectT0Shift(false); + rthfDriver.setUseTruthTime(false); + rthfDriver.setSubtractTOF(true); + rthfDriver.setSubtractTriggerTime(true); + rthfDriver.setCorrectChanT0(false); + rthfDriver.setDebug(false); + + boolean rerunFromFittedHits = false; + DataTrackerHitDriver dthDriver = new DataTrackerHitDriver(); + dthDriver.setDebug(true); + + loop.add(rawSensorSetup); + loop.add(rthfDriver); + loop.add(dthDriver); + loop.add(new ReadoutCleanupDriver()); + + String fileName = "tstDataTrackerHitDriver.slcio"; + File inputFile = cache.getCachedFile(new URL("http://www.lcsim.org/test/hps-java/" + fileName)); + loop.setLCIORecordSource(inputFile); + loop.loop(nEvents); + loop.dispose(); + + System.out.println("Loop from raw processed " + loop.getTotalSupplied() + " events."); + + System.out.println("rerunning from LCIO fitted hits"); + + SensorSetup sensorSetup = new SensorSetup(); + sensorSetup.setReadoutCollections(new String[]{"SVTRawTrackerHits"}); + sensorSetup.setFittedHitCollection("SVTFittedRawTrackerHits"); + + LCSimLoop loop2 = new LCSimLoop(); + loop2.setLCIORecordSource(inputFile); + + loop2.add(sensorSetup); +// loop2.add(dthDriver); + loop.add(new ReadoutCleanupDriver()); + loop2.loop(nEvents); + loop2.dispose(); + + System.out.println("Loop from fitted LCIO processed " + loop.getTotalSupplied() + " events."); + + System.out.println("Done!"); + } + +}