diff --git a/build-coatjava.sh b/build-coatjava.sh index 1586b1fa05..8cc3a57168 100755 --- a/build-coatjava.sh +++ b/build-coatjava.sh @@ -395,6 +395,8 @@ done for pom in $(find common-tools -name pom.xml); do if [[ "$pom" =~ coat-libs ]]; then install_jars $pom $prefix_dir/lib/clas 'coat-libs-*.jar' + elif [[ "$pom" =~ clas-qcddat ]]; then + install_jars $pom $prefix_dir/lib/services # else # FIXME, consumers may be need these after https://github.com/JeffersonLab/coatjava/pull/632 ; alternatively add needed deps to `coat-libs` # install_jars $pom $prefix_dir/lib/services fi diff --git a/common-tools/clas-qcddat/README.md b/common-tools/clas-qcddat/README.md new file mode 100644 index 0000000000..59fb897b2f --- /dev/null +++ b/common-tools/clas-qcddat/README.md @@ -0,0 +1,17 @@ +# QCDDAT Tools + +> [!NOTE] +> See [documentation from Veronique](https://clasweb.jlab.org/wiki/images/d/d0/CVT_QCDDAT_Subpackage_Documentation.pdf), the original +> developer; see also [Veronique's wikipage for further documentation](https://clasweb.jlab.org/wiki/index.php/Veronique_Ziegler_Documentation). + +## `CVT::QCDDATHit` Bank Validation + +Run reconstruction, _e.g._, +```bash +run-clara -y $COATJAVA/etc/services/mc-qcddat.yaml -t 4 -n 500 -c ./clara -o ./clarout raw.evio +``` + +Run the CVT event display: +```bash +run-coatjava org.jlab.qcddat.CVTBrowser clarout/rec_raw.evio.hipo +``` diff --git a/common-tools/clas-qcddat/pom.xml b/common-tools/clas-qcddat/pom.xml new file mode 100644 index 0000000000..b3401fb771 --- /dev/null +++ b/common-tools/clas-qcddat/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + org.jlab.clas + clas-qcddat + 14.2.0-SNAPSHOT + jar + + + org.jlab.clas + common-tools + 14.2.0-SNAPSHOT + + + + + org.jlab.clas + clas-io + 14.2.0-SNAPSHOT + + + org.openjfx + javafx-base + linux + + + org.openjfx + javafx-graphics + linux + + + org.openjfx + javafx-controls + linux + + + + diff --git a/common-tools/clas-qcddat/src/main/java/org/jlab/qcddat/CVTBrowser.java b/common-tools/clas-qcddat/src/main/java/org/jlab/qcddat/CVTBrowser.java new file mode 100644 index 0000000000..843dfe4fd9 --- /dev/null +++ b/common-tools/clas-qcddat/src/main/java/org/jlab/qcddat/CVTBrowser.java @@ -0,0 +1,22 @@ +package org.jlab.qcddat; + +import javafx.application.Application; +/** + * + * @author veronique + */ +public class CVTBrowser { + + public static void main(String[] args) { + if (args.length < 1) { + System.err.println("Usage: java Viewer "); + System.err.println("Example: java Viewer file.hipo"); + System.exit(1); + } + + String inputFile = args[0]; + + CVTViewer.configure(inputFile); + Application.launch(CVTViewer.class); + } +} diff --git a/common-tools/clas-qcddat/src/main/java/org/jlab/qcddat/CVTViewer.java b/common-tools/clas-qcddat/src/main/java/org/jlab/qcddat/CVTViewer.java new file mode 100644 index 0000000000..25b735956a --- /dev/null +++ b/common-tools/clas-qcddat/src/main/java/org/jlab/qcddat/CVTViewer.java @@ -0,0 +1,682 @@ +package org.jlab.qcddat; + +import javafx.application.Application; +import javafx.geometry.Insets; +import javafx.scene.*; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.Separator; +import javafx.scene.input.KeyCode; +import javafx.scene.input.MouseEvent; +import javafx.scene.input.ScrollEvent; +import javafx.scene.layout.*; +import javafx.scene.paint.Color; +import javafx.scene.paint.PhongMaterial; +import javafx.scene.shape.Box; +import javafx.scene.shape.Sphere; +import javafx.scene.transform.Rotate; +import javafx.stage.Stage; +import org.jlab.io.base.DataBank; +import org.jlab.io.base.DataEvent; +import org.jlab.io.hipo.HipoDataSource; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author veronique + */ + +public class CVTViewer extends Application { + + // ---------- config ---------- + private static String inputFile; + private static String bankName; + + public static void configure(String input) { + inputFile = input; + bankName = "CVT::QCDDATHit"; + } + + public static void main(String[] args) { + if (args.length < 1) { + System.err.println("Usage: java org.jlab.qcddat.CVTViewer "); + System.exit(1); + } + configure(args[0]); + launch(args); + } + + // ---------- bounded cache ---------- + private static final int MAX_CACHE_SIZE = 200; + private static final int MAX_LAYER = 12; + private static final int MAX_SECTOR = 18; + + private HipoDataSource reader; + private final List> eventPointCache = new ArrayList<>(); + private final List eventRowCountCache = new ArrayList<>(); + + // global event number of first cached event + private int cacheStartEventNumber = 0; + + // current global event number + private int currentEventNumber = -1; + + // next global event number expected from persistent reader + private int nextUnreadEventNumber = 0; + + private int totalEvents = 0; + + // ---------- gui ---------- + private CheckBox showLoc1; + private CheckBox showLoc2; + private CheckBox showLoc3; + private CheckBox[] showLayer = new CheckBox[MAX_LAYER]; + private CheckBox[] showSector = new CheckBox[MAX_SECTOR]; + private CheckBox showSVT; + private CheckBox showBMTC; + private CheckBox showBMTZ; + private CheckBox showPersistence; + + private Label hoverLabel; + private Label infoLabel; + private Label countsLabel; + + // ---------- 3D ---------- + private final Group world = new Group(); + private final Group pointsGroup = new Group(); + + private final Rotate rotateX = new Rotate(20, Rotate.X_AXIS); + private final Rotate rotateY = new Rotate(-35, Rotate.Y_AXIS); + + private double anchorX; + private double anchorY; + private double anchorAngleX; + private double anchorAngleY; + + private PerspectiveCamera camera; + + private static final double DRAW_SCALE = 5.0; + private static final double POINT_RADIUS = 1.8; + + private enum DetectorKind { + SVT, + BMT_C, + BMT_Z, + UNKNOWN + } + + private static class HitPoint { + final double x; + final double y; + final double z; + final DetectorKind kind; + final int pointloc; + final int layer; + final int sector; + final int mctrue; + + HitPoint(double x, double y, double z, DetectorKind kind, int loc, int layer, int sector, int mct) { + this.x = x; + this.y = y; + this.z = z; + this.kind = kind; + this.pointloc = loc; + this.layer = layer; + this.sector = sector; + this.mctrue = mct; + } + } + + @Override + public void start(Stage stage) { + if (inputFile == null || bankName == null) { + throw new IllegalStateException("CVTViewer.configure(inputFile) must be called before launch."); + } + + initializeFile(inputFile); + buildWorld(); + + camera = new PerspectiveCamera(true); + camera.setNearClip(0.1); + camera.setFarClip(100000); + camera.setTranslateZ(-1400); + + SubScene subScene = new SubScene(world, 1200, 850, true, SceneAntialiasing.BALANCED); + subScene.setFill(Color.rgb(18, 18, 22)); + subScene.setCamera(camera); + + enableMouseControls(subScene); + + BorderPane root = new BorderPane(); + root.setCenter(subScene); + root.setTop(buildTopBar()); + root.setRight(buildLegendPane()); + + Scene scene = new Scene(root, 1450, 900, true); + + scene.setOnKeyPressed(e -> { + if (e.getCode() == KeyCode.RIGHT || e.getCode() == KeyCode.N) { + nextEvent(); + } else if (e.getCode() == KeyCode.LEFT || e.getCode() == KeyCode.P) { + previousEvent(); + } else if (e.getCode() == KeyCode.PLUS || e.getCode() == KeyCode.ADD || (e.getCode() == KeyCode.EQUALS && e.isShiftDown())) { + camera.setTranslateZ(camera.getTranslateZ() + 50); + } else if (e.getCode() == KeyCode.MINUS || e.getCode() == KeyCode.SUBTRACT) { + camera.setTranslateZ(camera.getTranslateZ() - 50); + } else if (e.getCode() == KeyCode.R) { + resetView(); + } + }); + + stage.setTitle("COATJAVA Bank 3D Event Browser"); + stage.setScene(scene); + stage.show(); + + if (totalEvents == 0) { + infoLabel.setText("No events found in file: " + inputFile); + countsLabel.setText(""); + } else if (loadNextEventIntoCache()) { + renderCachedEvent(); + } else { + infoLabel.setText("Could not load first event"); + countsLabel.setText(""); + } + } + + private void initializeFile(String fileName) { + File f = new File(fileName); + if (!f.exists()) { + throw new IllegalArgumentException("Input file does not exist: " + fileName); + } + + HipoDataSource counter = new HipoDataSource(); + counter.open(fileName); + totalEvents = 0; + while (counter.hasEvent()) { + counter.getNextEvent(); + totalEvents++; + } + counter.close(); + + reader = new HipoDataSource(); + reader.open(fileName); + + eventPointCache.clear(); + eventRowCountCache.clear(); + + cacheStartEventNumber = 0; + currentEventNumber = -1; + nextUnreadEventNumber = 0; + + System.out.printf("Initialized file %s with %d events%n", fileName, totalEvents); + } + + private boolean loadNextEventIntoCache() { + if (reader == null || !reader.hasEvent()) { + return false; + } + + DataEvent event = reader.getNextEvent(); + int thisEventNumber = nextUnreadEventNumber; + nextUnreadEventNumber++; + + if (!event.hasBank(bankName)) { + return false; + } + + DataBank bank = event.getBank(bankName); + List points = extractAllThreePoints(bank); + + eventPointCache.add(points); + eventRowCountCache.add(bank.rows()); + + if (eventPointCache.size() > MAX_CACHE_SIZE) { + eventPointCache.remove(0); + eventRowCountCache.remove(0); + cacheStartEventNumber++; + } + + currentEventNumber = thisEventNumber; + return true; + } + + private boolean isCurrentEventCached() { + return currentEventNumber >= cacheStartEventNumber + && currentEventNumber < cacheStartEventNumber + eventPointCache.size(); + } + + private int currentCacheIndex() { + return currentEventNumber - cacheStartEventNumber; + } + + private void renderCachedEvent() { + if(!showPersistence.isSelected()) + pointsGroup.getChildren().clear(); + + if (!isCurrentEventCached()) { + infoLabel.setText(String.format( + "Event %d is no longer in cache. Cache window: [%d .. %d]", + currentEventNumber + 1, + cacheStartEventNumber + 1, + cacheStartEventNumber + eventPointCache.size() + )); + countsLabel.setText(""); + hoverLabel.setText("Hover over a point to see coordinates"); + return; + } + + int cacheIndex = currentCacheIndex(); + List points = eventPointCache.get(cacheIndex); + int rowCount = eventRowCountCache.get(cacheIndex); + + int nSVT = 0; + int nBMTC = 0; + int nBMTZ = 0; + int nLoc1 = 0; + int nLoc2 = 0; + int nLoc3 = 0; + int nMcTrue0 = 0; + int nOther = 0; + + for (HitPoint p : points) { + if (!isVisible(p.kind) || !isVisibleLoc(p.pointloc) || !isVisibleLayer(p.layer) || !isVisibleSector(p.sector)) { + continue; + } + + Node marker = makeMarker(p); + pointsGroup.getChildren().add(marker); + + switch (p.kind) { + case SVT -> nSVT++; + case BMT_C -> nBMTC++; + case BMT_Z -> nBMTZ++; + default -> { } + } + + switch (p.pointloc) { + case 1 -> nLoc1++; + case 2 -> nLoc2++; + case 3 -> nLoc3++; + default -> { } + } + + if (p.mctrue == 0) { + nMcTrue0++; + } else { + nOther++; + } + } + + infoLabel.setText(String.format( + "File: %s Bank: %s Event %d / %d Rows: %d Cache: [%d .. %d]", + new File(inputFile).getName(), + bankName, + currentEventNumber + 1, + totalEvents, + rowCount, + cacheStartEventNumber + 1, + cacheStartEventNumber + eventPointCache.size() + )); + + countsLabel.setText(String.format( + "SVT=%d BMT_C=%d BMT_Z=%d loc1=%d loc2=%d loc3=%d mctrue0=%d other=%d", + nSVT, nBMTC, nBMTZ, nLoc1, nLoc2, nLoc3, nMcTrue0, nOther + )); + } + + private void buildWorld() { + world.getTransforms().addAll(rotateX, rotateY); + + Group axes = new Group( + makeAxis(300, 1.0, 1.0, Color.RED), + makeAxis(1.0, 300, 1.0, Color.LIME), + makeAxis(1.0, 1.0, 300, Color.DEEPSKYBLUE) + ); + + world.getChildren().add(axes); + world.getChildren().add(pointsGroup); + } + + private Node makeAxis(double sx, double sy, double sz, Color color) { + Box box = new Box(sx, sy, sz); + box.setMaterial(new PhongMaterial(color)); + return box; + } + + private HBox buildTopBar() { + Button prev = new Button("Previous Event"); + Button next = new Button("Next Event"); + Button reset = new Button("Reset View"); + + prev.setOnAction(e -> previousEvent()); + next.setOnAction(e -> nextEvent()); + reset.setOnAction(e -> resetView()); + + infoLabel = new Label("Loading..."); + countsLabel = new Label(""); + hoverLabel = new Label("Hover over a point to see coordinates"); + + infoLabel.setTextFill(Color.BLACK); + countsLabel.setTextFill(Color.BLACK); + hoverLabel.setTextFill(Color.DARKBLUE); + + HBox controls = new HBox( + 10, + prev, next, reset, + new Separator(), + infoLabel, + new Separator(), + countsLabel, + new Separator(), + hoverLabel + ); + controls.setPadding(new Insets(10)); + controls.setStyle("-fx-background-color: #e9edf2;"); + return controls; + } + + private HBox buildLegendPane() { + + Label persistenceTitle = new Label("Persistence"); + persistenceTitle.setStyle("-fx-font-size: 14px; -fx-font-weight: bold;"); + showPersistence = new CheckBox("Persist"); + showPersistence.setSelected(false); + Button clearPersistence = new Button("Clear"); + clearPersistence.setOnAction(e -> { pointsGroup.getChildren().clear(); }); + + Label legendTitle = new Label("Detectors"); + legendTitle.setStyle("-fx-font-size: 14px; -fx-font-weight: bold;"); + + showSVT = new CheckBox("SVT"); + showSVT.setSelected(true); + showBMTC = new CheckBox("BMT C"); + showBMTC.setSelected(true); + showBMTZ = new CheckBox("BMT Z"); + showBMTZ.setSelected(true); + + showSVT.setOnAction(e -> renderCachedEvent()); + showBMTC.setOnAction(e -> renderCachedEvent()); + showBMTZ.setOnAction(e -> renderCachedEvent()); + + Label svtColor = coloredLabel("Magenta"); + svtColor.setTextFill(Color.MAGENTA); + + Label cColor = coloredLabel("LimeGreen"); + cColor.setTextFill(Color.LIMEGREEN); + + Label zColor = coloredLabel("Cyan"); + zColor.setTextFill(Color.CYAN); + + Label locTitle = new Label("Point location"); + locTitle.setStyle("-fx-font-size: 14px; -fx-font-weight: bold;"); + + showLoc1 = new CheckBox("loc 1 = origin"); + showLoc1.setSelected(true); + showLoc2 = new CheckBox("loc 2 = midpoint"); + showLoc2.setSelected(true); + showLoc3 = new CheckBox("loc 3 = end"); + showLoc3.setSelected(true); + + showLoc1.setOnAction(e -> renderCachedEvent()); + showLoc2.setOnAction(e -> renderCachedEvent()); + showLoc3.setOnAction(e -> renderCachedEvent()); + + Label layerTitle = new Label("Layer"); + layerTitle.setStyle("-fx-font-size: 14px; -fx-font-weight: bold;"); + for (int l=0; l renderCachedEvent()); + } + Button layerNone = new Button("None"); + layerNone.setOnAction(e -> { for(int l=0; l { for(int l=0; l renderCachedEvent()); + } + Button sectorNone = new Button("None"); + sectorNone.setOnAction(e -> { for(int s=0; s { for(int s=0; s { + anchorX = e.getSceneX(); + anchorY = e.getSceneY(); + anchorAngleX = rotateX.getAngle(); + anchorAngleY = rotateY.getAngle(); + }); + + scene.addEventHandler(MouseEvent.MOUSE_DRAGGED, e -> { + rotateX.setAngle(anchorAngleX - (anchorY - e.getSceneY()) * 0.35); + rotateY.setAngle(anchorAngleY + (anchorX - e.getSceneX()) * 0.35); + }); + + scene.addEventHandler(ScrollEvent.SCROLL, e -> { + camera.setTranslateZ(camera.getTranslateZ() + e.getDeltaY() * 0.6); + }); + } + + private void resetView() { + rotateX.setAngle(20); + rotateY.setAngle(-35); + if (camera != null) { + camera.setTranslateZ(-1400); + } + } + + private void previousEvent() { + if (totalEvents == 0) { + return; + } + if (currentEventNumber > cacheStartEventNumber) { + currentEventNumber--; + renderCachedEvent(); + } else if (currentEventNumber > 0) { + infoLabel.setText(String.format( + "Cannot go back farther: event %d is outside the cache window [%d .. %d]", + currentEventNumber, + cacheStartEventNumber + 1, + cacheStartEventNumber + eventPointCache.size() + )); + } + } + + private void nextEvent() { + if (totalEvents == 0) { + return; + } + + if (currentEventNumber + 1 < nextUnreadEventNumber) { + currentEventNumber++; + renderCachedEvent(); + return; + } + + if (loadNextEventIntoCache()) { + renderCachedEvent(); + } + } + + private Node makeMarker(HitPoint p) { + PhongMaterial material = new PhongMaterial(colorFor(p.kind)); + + Node marker; + if (p.mctrue == 0) { + Box b = new Box(2.8 * POINT_RADIUS, 2.8 * POINT_RADIUS, 2.8 * POINT_RADIUS); + b.setMaterial(material); + marker = b; + } else { + Sphere s = new Sphere(POINT_RADIUS); + s.setMaterial(material); + marker = s; + } + + marker.setTranslateX(p.x * DRAW_SCALE); + marker.setTranslateY(-p.y * DRAW_SCALE); + marker.setTranslateZ(p.z * DRAW_SCALE); + + marker.setOnMouseEntered(e -> hoverLabel.setText(String.format( + "%s loc=%d mctrue=%d (x, y, z) = (%.4f, %.4f, %.4f)", + detectorName(p.kind), p.pointloc, p.mctrue, p.x, p.y, p.z + ))); + + marker.setOnMouseExited(e -> hoverLabel.setText("Hover over a point to see coordinates")); + + return marker; + } + + private String detectorName(DetectorKind kind) { + return switch (kind) { + case SVT -> "SVT"; + case BMT_C -> "BMT_C"; + case BMT_Z -> "BMT_Z"; + case UNKNOWN -> "UNKNOWN"; + }; + } + + private boolean isVisible(DetectorKind kind) { + return switch (kind) { + case SVT -> showSVT.isSelected(); + case BMT_C -> showBMTC.isSelected(); + case BMT_Z -> showBMTZ.isSelected(); + default -> true; + }; + } + + private boolean isVisibleLoc(int loc) { + return switch (loc) { + case 1 -> showLoc1.isSelected(); + case 2 -> showLoc2.isSelected(); + case 3 -> showLoc3.isSelected(); + default -> true; + }; + } + + private boolean isVisibleLayer(int layer) { + return showLayer[layer-1].isSelected(); + } + + private boolean isVisibleSector(int sector) { + return showSector[sector-1].isSelected(); + } + + private List extractAllThreePoints(DataBank bank) { + List out = new ArrayList<>(); + + for (int i = 0; i < bank.rows(); i++) { + int layer = bank.getByte("layer", i); + int sector = bank.getByte("sector", i); + DetectorKind kind = detectorKindFromLayer(layer); + int mct = bank.getByte("mctrue", i); + + out.add(new HitPoint( + bank.getFloat("x1", i), + bank.getFloat("y1", i), + bank.getFloat("z1", i), + kind, 1, layer, sector, mct + )); + + out.add(new HitPoint( + bank.getFloat("x2", i), + bank.getFloat("y2", i), + bank.getFloat("z2", i), + kind, 2, layer, sector, mct + )); + + out.add(new HitPoint( + bank.getFloat("x3", i), + bank.getFloat("y3", i), + bank.getFloat("z3", i), + kind, 3, layer, sector, mct + )); + } + + return out; + } + + private DetectorKind detectorKindFromLayer(int layer) { + if (layer >= 1 && layer <= 6) { + return DetectorKind.SVT; + } + if (layer >= 7 && layer <= 12) { + return isBmtCLayer(layer) ? DetectorKind.BMT_C : DetectorKind.BMT_Z; + } + return DetectorKind.UNKNOWN; + } + + private boolean isBmtCLayer(int layer) { + return (layer == 7 || layer == 10 || layer == 12); + } + + private Color colorFor(DetectorKind kind) { + return switch (kind) { + case SVT -> Color.MAGENTA; + case BMT_C -> Color.LIMEGREEN; + case BMT_Z -> Color.CYAN; + case UNKNOWN -> Color.WHITE; + }; + } +} diff --git a/common-tools/pom.xml b/common-tools/pom.xml index 2cb363df1a..3f09e738c3 100644 --- a/common-tools/pom.xml +++ b/common-tools/pom.xml @@ -29,6 +29,7 @@ clara-io clas-tracking clas-decay-tools + clas-qcddat coat-libs diff --git a/etc/bankdefs/hipo4/cvtqcddat.json b/etc/bankdefs/hipo4/cvtqcddat.json new file mode 100644 index 0000000000..3a3118c34b --- /dev/null +++ b/etc/bankdefs/hipo4/cvtqcddat.json @@ -0,0 +1,27 @@ +[ + { + "name": "CVT::QCDDATHit", + "group": 20500, + "item" : 71, + "info": "reconstructed hits", + "entries": [ + {"name":"id", "type":"S", "info":"id of the hit"}, + {"name":"mctid", "type":"S", "info":"MC track id associated with the hit"}, + {"name":"sector", "type":"B", "info":"sector"}, + {"name":"layer", "type":"B", "info":"layer (1...6)=SVT; (7...12)=BMT"}, + {"name":"strip", "type":"S", "info":"strip number"}, + {"name":"energy", "type":"F", "info":"energy"}, + {"name":"time", "type":"F", "info":"time"}, + {"name":"mctrue", "type":"B", "info":"order 0=MC hit-on-track; 1=noise hit"}, + {"name":"x1", "type":"F", "info":"geometric strip origin x-coordinate"}, + {"name":"y1", "type":"F", "info":"geometric strip origin y-coordinate"}, + {"name":"z1", "type":"F", "info":"geometric strip origin z-coordinate"}, + {"name":"x2", "type":"F", "info":"geometric strip mid-point x-coordinate"}, + {"name":"y2", "type":"F", "info":"geometric strip mid-point y-coordinate"}, + {"name":"z2", "type":"F", "info":"geometric strip mid-point z-coordinate"}, + {"name":"x3", "type":"F", "info":"geometric strip end-point x-coordinate"}, + {"name":"y3", "type":"F", "info":"geometric strip end-point y-coordinate"}, + {"name":"z3", "type":"F", "info":"geometric strip end-point z-coordinate"} + ] + } +] diff --git a/etc/services/mc-qcddat.yaml b/etc/services/mc-qcddat.yaml new file mode 100644 index 0000000000..147d5dcea3 --- /dev/null +++ b/etc/services/mc-qcddat.yaml @@ -0,0 +1,26 @@ +io-services: + reader: + class: org.jlab.io.clara.Clas12Reader + name: Clas12Reader + writer: + class: org.jlab.io.clara.Clas12Writer + name: Clas12Writer +services: + - class: org.jlab.clas.reco.DecoderEngine + name: DECO + - class: org.jlab.clas.swimtools.MagFieldsEngine + name: MAGFIELDS + - class: org.jlab.rec.cvt.ml.QCDDATSampleMaker + name: CVTFP +configuration: + global: + variation: rga_fall2018_bg + io-services: + writer: + schema_dir: cvtqcddat + services: + MAGFIELDS: + magfieldSolenoidMap: Symm_solenoid_r601_phi1_z1201_13June2018.dat + magfieldTorusMap: Symm_torus_r2501_phi16_z251_24Apr2018.dat +mime-types: + - binary/data-hipo diff --git a/pom.xml b/pom.xml index 0334839d09..a2cf0e6699 100644 --- a/pom.xml +++ b/pom.xml @@ -102,6 +102,13 @@ linux + + org.openjfx + javafx-controls + 23.0.2 + linux + + org.slf4j slf4j-api diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/Constants.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/Constants.java index 51303f0636..1ae3a6267f 100644 --- a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/Constants.java +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/Constants.java @@ -20,7 +20,7 @@ public class Constants { public static double CAANGLE4=19.; public static double CAANGLE5=3.5; public boolean seedingDebugMode =false; - + public boolean QCDDATSample=true; // FIXME(CD): should this be configurable from `yaml`? // private constructor for a singleton diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/banks/HitReader.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/banks/HitReader.java index 86174629b7..a243f2272e 100644 --- a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/banks/HitReader.java +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/banks/HitReader.java @@ -117,7 +117,11 @@ public void fetch_BMTHits(DataEvent event, Swim swim, IndexedTable status, int strip = bankDGTZ.getShort("component", i); double ADCtoEdep = bankDGTZ.getInt("ADC", i); double time = bankDGTZ.getFloat("time", i); - int order = bankDGTZ.trueOrder(i); + int order = bankDGTZ.getByte("order", i);; + if(Constants.getInstance().timeCuts + && !Constants.getInstance().QCDDATSample) { + order = bankDGTZ.trueOrder(i); + } //if (order == 1) { // continue; //} @@ -133,11 +137,13 @@ public void fetch_BMTHits(DataEvent event, Swim swim, IndexedTable status, // create the strip object for the BMT Strip BmtStrip = new Strip(strip, ADCtoEdep, time); BmtStrip.setStatus(status.getIntValue("status", sector, layer, strip)); - if(Constants.getInstance().timeCuts) { + if(Constants.getInstance().timeCuts + && !Constants.getInstance().QCDDATSample) { if(time!=0 && (timetmax)) BmtStrip.setStatus(2);// calculate the strip parameters for the BMT hit } - if(Constants.getInstance().bmtHVCuts) { + if(Constants.getInstance().bmtHVCuts + && !Constants.getInstance().QCDDATSample) { if(bmtStripVoltage!=null && bmtStripVoltage.hasEntry(sector,layer,0) && bmtStripVoltageThresh!=null && bmtStripVoltageThresh.hasEntry(sector,layer,0)) { double hv = bmtStripVoltage.getDoubleValue("HV", sector,layer,0); @@ -299,7 +305,8 @@ public void fetch_SVTHits(DataEvent event, int omitLayer, int omitHemisphere, if(tdcs.containsKey(key)) { time = tdcs.get(key); //time tag - if(Constants.getInstance().useSVTTimingCuts) { + if(Constants.getInstance().useSVTTimingCuts && + !Constants.getInstance().QCDDATSample) { if(this.passTimingCuts(ADC, time)==false) continue; } diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/hit/Hit.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/hit/Hit.java index 296a82605c..2406c183b5 100644 --- a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/hit/Hit.java +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/hit/Hit.java @@ -29,12 +29,19 @@ public class Hit implements Comparable { private int _TrkgStatus = -1; // TrkgStatusFlag factor (-1: no fit; 0: global helical fit; 1: KF fit) public double _QualityFac; // a quality factor depending on the hit status and goodness of fit private int _AssociatedClusterID = -1; // the cluster ID associated with that hit + private int AssociatedSeedID = -1; // the seed ID associated with that hit private int AssociatedTrackID = -1; // the track ID associated with that hit public boolean newClustering = false; public int MCstatus = -1; public boolean isCorrupted; - + private int _seedBankRow=-1; + private int _trackBankRow=-1; + private int associateMCTrkId=-1; + + private double cweight = 0; //normalized difference to associated cluster centroid + private double sweight = 0; //normalized difference to associated cluster seed + // constructor public Hit(DetectorType detector, BMTType type, int sector, int layer, Strip strip) { this._Detector = detector; // 0 = SVT, 1 = BMT @@ -286,6 +293,86 @@ public void setAssociatedTrackID(int associatedTrackID) { AssociatedTrackID = associatedTrackID; } + public int getAssociatedSeedID() { + return AssociatedSeedID; + } + + + public void setAssociatedSeedID(int associatedSeedID) { + this.AssociatedSeedID = associatedSeedID; + } + + + /** + * @return the associateMCTrkId + */ + public int getAssociateMCTrkId() { + return associateMCTrkId; + } + + /** + * @param associateMCTrkId the associateMCTrkId to set + */ + public void setAssociateMCTrkId(int associateMCTrkId) { + this.associateMCTrkId = associateMCTrkId; + } + + /** + * @return the _seedBankRow + */ + public int getSeedBankRow() { + return _seedBankRow; + } + + /** + * @param _seedBankRow the _seedBankRow to set + */ + public void setSeedBankRow(int _seedBankRow) { + this._seedBankRow = _seedBankRow; + } + + /** + * @return the _trackBankRow + */ + public int getTrackBankRow() { + return _trackBankRow; + } + + /** + * @param _trackBankRow the _trackBankRow to set + */ + public void setTrackBankRow(int _trackBankRow) { + this._trackBankRow = _trackBankRow; + } + + /** + * @return the cweight + */ + public double getCweight() { + return cweight; + } + + /** + * @param cweight the cweight to set + */ + public void setCweight(double cweight) { + this.cweight = cweight; + } + + /** + * @return the sweight + */ + public double getSweight() { + return sweight; + } + + /** + * @param sweight the sweight to set + */ + public void setSweight(double sweight) { + this.sweight = sweight; + } + public String toString() { String str = String.format("Hit id=%d, layer=%d, sector=%d, strip=%d, energy=%.3f, time=%.3f, residual=%.3f, clusterID=%d, trackID=%d", this.getId(), this.getLayer(), this.getSector(), diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/QCDDATSampleMaker.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/QCDDATSampleMaker.java new file mode 100644 index 0000000000..51cc049540 --- /dev/null +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/QCDDATSampleMaker.java @@ -0,0 +1,194 @@ +package org.jlab.rec.cvt.ml; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.jlab.clas.reco.ReconstructionEngine; +import org.jlab.clas.swimtools.Swim; +import org.jlab.detector.base.DetectorType; +import org.jlab.io.base.DataBank; +import org.jlab.io.base.DataEvent; +import org.jlab.rec.cvt.Constants; +import org.jlab.rec.cvt.Geometry; +import org.jlab.rec.cvt.bmt.BMTType; +import org.jlab.rec.cvt.hit.Hit; +import org.jlab.utils.groups.IndexedTable; + +import org.jlab.geom.prim.Line3D; +import org.jlab.geom.prim.Arc3D; +import org.jlab.rec.cvt.banks.HitReader; + +/** + * Service to return reconstructed TRACKS + * format + * + * @author ziegler + * + */ +public class QCDDATSampleMaker extends ReconstructionEngine { + + private String svtHitBank; + + public QCDDATSampleMaker(String name) { + super(name, "ziegler", "6.0"); + } + + public QCDDATSampleMaker() { + super("CVTQCDDATEngine", "ziegler", "6.0"); + } + + @Override + public void detectorChanged(int run) {} + + @Override + public boolean init() { + this.initConstantsTables(); + this.registerBanks(); + return true; + } + + public void registerBanks() { + this.setSvtHitBank("CVT::QCDDATHit"); + super.registerOutputBank(this.svtHitBank); + } + + public int getRun(DataEvent event) { + + if (event.hasBank("RUN::config") == false) { + System.err.println("RUN CONDITIONS NOT READ!"); + return 0; + } + + DataBank bank = event.getBank("RUN::config"); + int run = bank.getInt("run", 0); + if(Constants.getInstance().seedingDebugMode) { + System.out.println("EVENT "+bank.getInt("event", 0)); + } + return run; + } + + @Override + public boolean processDataEventUser(DataEvent event) { + + int run = this.getRun(event); + Swim swimmer = new Swim(); + IndexedTable svtStatus = this.getConstantsManager().getConstants(run, "/calibration/svt/status"); + IndexedTable svtLorentz = this.getConstantsManager().getConstants(run, "/calibration/svt/lorentz_angle"); + IndexedTable bmtStatus = this.getConstantsManager().getConstants(run, "/calibration/mvt/bmt_status"); + IndexedTable bmtTime = this.getConstantsManager().getConstants(run, "/calibration/mvt/bmt_time"); + IndexedTable bmtVoltage = this.getConstantsManager().getConstants(run, "/calibration/mvt/bmt_voltage"); + IndexedTable bmtStripVoltage = this.getConstantsManager().getConstants(run, "/calibration/mvt/bmt_strip_voltage"); + IndexedTable bmtStripThreshold = this.getConstantsManager().getConstants(run, "/calibration/mvt/bmt_strip_voltage_thresholds"); + IndexedTable adcStatus = this.getConstantsManager().getConstants(run, "/calibration/svt/adcstatus"); + + Geometry.getInstance().initialize(this.getConstantsManager().getVariation(), run, svtLorentz, bmtVoltage); + + HitReader hitRead = new HitReader(); + hitRead.fetch_SVTHits(event, -1, -1, svtStatus, adcStatus); + hitRead.fetch_BMTHits(event, swimmer, bmtStatus, bmtTime, + bmtStripVoltage, bmtStripThreshold); + List> hits = new ArrayList<>(); + if(hitRead.getSVTHits() == null) { + hits.add(new ArrayList<>()); + } + else { + hits.add((ArrayList) hitRead.getSVTHits()); + } + if(hitRead.getBMTHits() == null) { + hits.add(new ArrayList<>()); + } + else { + hits.add((ArrayList) hitRead.getBMTHits()); + } + + if (event.hasBank("MC::True")) { + DataBank mcTrue = event.getBank("MC::True"); + TrackingPerformance.MatchHitsToMC(hits, mcTrue); + } + + if (hits.isEmpty()) + return false; + DataBank bank = event.createBank(this.svtHitBank, hits.get(0).size()+hits.get(1).size()); + int index=0; + for(int i = 0; i < hits.size(); i++) { + for(int j = 0; j < hits.get(i).size(); j++) { + bank.setShort("id", index, (short) hits.get(i).get(j).getId()); + bank.setShort("mctid", index, (short) hits.get(i).get(j).getAssociateMCTrkId()); + bank.setByte("sector", index, (byte) hits.get(i).get(j).getSector()); + int layer = hits.get(i).get(j).getLayer(); + if(i>0) layer+=6; + bank.setByte("layer", index, (byte) layer); + bank.setShort("strip", index, (short) hits.get(i).get(j).getStrip().getStrip()); + bank.setFloat("energy", index, (short) hits.get(i).get(j).getStrip().getEdep()); + bank.setFloat("time", index, (short) hits.get(i).get(j).getStrip().getTime()); + int mctrue=-1; + if(hits.get(i).get(j).MCstatus==0) { + mctrue=0; + } else { + mctrue=1; + } + bank.setByte("mctrue", index, (byte) mctrue); + if(hits.get(i).get(j).getDetector()==DetectorType.BST || + (hits.get(i).get(j).getDetector()==DetectorType.BMT + && hits.get(i).get(j).getType()==BMTType.Z)) { + Line3D sline = hits.get(i).get(j).getStrip().getLine(); + bank.setFloat("x1", index, (float) sline.origin().x()/10); + bank.setFloat("y1", index, (float) sline.origin().y()/10); + bank.setFloat("z1", index, (float) sline.origin().z()/10); + bank.setFloat("x2", index, (float) sline.midpoint().x()/10); + bank.setFloat("y2", index, (float) sline.midpoint().y()/10); + bank.setFloat("z2", index, (float) sline.midpoint().z()/10); + bank.setFloat("x3", index, (float) sline.end().x()/10); + bank.setFloat("y3", index, (float) sline.end().y()/10); + bank.setFloat("z3", index, (float) sline.end().z()/10); + + } + if(hits.get(i).get(j).getDetector()==DetectorType.BMT + && hits.get(i).get(j).getType()==BMTType.C) { + Arc3D sarc = hits.get(i).get(j).getStrip().getArc(); + bank.setFloat("x1", index, (float) sarc.origin().x()/10); + bank.setFloat("y1", index, (float) sarc.origin().y()/10); + bank.setFloat("z1", index, (float) sarc.origin().z()/10); + bank.setFloat("x2", index, (float) sarc.point(sarc.theta()/2).x()/10); + bank.setFloat("y2", index, (float) sarc.point(sarc.theta()/2).y()/10); + bank.setFloat("z2", index, (float) sarc.point(sarc.theta()/2).z()/10); + bank.setFloat("x3", index, (float) sarc.end().x()/10); + bank.setFloat("y3", index, (float) sarc.end().y()/10); + bank.setFloat("z3", index, (float) sarc.end().z()/10); + } + + index++; + } + } + //bank.show(); + event.appendBanks(bank); + + return true; + } + + + + public void initConstantsTables() { + String[] tables = new String[]{ + "/calibration/svt/status", + "/calibration/svt/lorentz_angle", + "/calibration/mvt/bmt_time", + "/calibration/mvt/bmt_status", + "/calibration/mvt/bmt_voltage", + "/calibration/mvt/bmt_strip_voltage", + "/calibration/mvt/bmt_strip_voltage_thresholds", + "/geometry/beam/position", + "/calibration/svt/adcstatus" + }; + requireConstants(Arrays.asList(tables)); + this.getConstantsManager().setVariation("default"); + } + + public void setSvtHitBank(String bstHitBank) { + this.svtHitBank = bstHitBank; + } + public String getSvtHitBank() { + return this.svtHitBank; + } +} diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/TrackingPerformance.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/TrackingPerformance.java new file mode 100644 index 0000000000..70fc59df73 --- /dev/null +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/TrackingPerformance.java @@ -0,0 +1,248 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ +package org.jlab.rec.cvt.ml; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.jlab.detector.base.DetectorType; +import org.jlab.io.base.DataBank; +import org.jlab.io.base.DataEvent; +import org.jlab.rec.cvt.cluster.Cluster; +import org.jlab.rec.cvt.hit.Hit; +import org.jlab.rec.cvt.track.Seed; +import org.jlab.rec.cvt.track.Track; + +/** + * + * @author ziegler + */ +public class TrackingPerformance { + public static void MatchHitToMC(Hit h, Map map) { + if(map.containsKey(h.getId())) { + h.setAssociateMCTrkId(map.get(h.getId())); + } + } + + public static Map TruthMap(DataBank mcTrue, int detId) { + Map map = new HashMap<>(); + for (int k = 0; k < mcTrue.rows(); k++) { + if(mcTrue.getInt("mtid", k)==0 && mcTrue.getByte("detector", k) == detId) { + map.put(mcTrue.getInt("hitn", k), mcTrue.getInt("tid", k)); + } + } + return map; + } + + public static void MatchHitsToMC(List>hits, DataBank mcTrue){ //1. + Map smap = TrackingPerformance.TruthMap(mcTrue, DetectorType.BST.getDetectorId()); + Map bmap = TrackingPerformance.TruthMap(mcTrue, DetectorType.BMT.getDetectorId()); + for(Hit h : hits.get(0)) { + TrackingPerformance.MatchHitToMC(h, smap); + } + for(Hit h : hits.get(1)) { + TrackingPerformance.MatchHitToMC(h, bmap); + } + } + + private static double calcPurity(Seed s, int mctid) { + int nTotalHits=0; + int nMCMatchedHits=0; + for(Cluster c: s.getClusters()) { + for(Hit h : c) { + nTotalHits++; + if(h.getAssociateMCTrkId()==mctid) { + nMCMatchedHits++; + } + } + } + + if(nTotalHits==0) return 0; + return (double) nMCMatchedHits/(double) nTotalHits; + } + + private static double calcPurity(Track t, int mctid) { + return calcPurity(t.getSeed(), mctid); + } + + private static void setPurity(Seed s, int mctid) { + double purity = calcPurity(s, mctid); + s.setPurity(purity); + } + + private static void setPurity(Track t, int mctid) { + double purity = calcPurity(t, mctid); + t.setPurity(purity); + } + + private static void setSeedsPurity(List seeds) { //2. + for(Seed s : seeds) { + int mcmatchId = matchToMCtID(s); + double purity = calcPurity(s, mcmatchId); + s.setPurity(purity); + } + } + + private static void setTracksPurity(List tracks) { //3. + for(Track t : tracks) { + int mcmatchId = matchToMCtID(t); + double purity = calcPurity(t, mcmatchId); + t.setPurity(purity); + } + } + + private static int matchToMCtID(Seed s) { + Map> map = new HashMap<>(); + for(Cluster c: s.getClusters()) { + for(Hit h : c) { + if(!map.containsKey(h.getAssociateMCTrkId())) { + map.put(h.getAssociateMCTrkId(), new ArrayList<>()); + map.get(h.getAssociateMCTrkId()).add(h); + } else { + map.get(h.getAssociateMCTrkId()).add(h); + } + } + } + Map.Entry> maxEntry = map.entrySet() + .stream() + .max(Comparator.comparingInt(e -> e.getValue().size())) + .orElse(null); // returns null if map is empty + + if(maxEntry!=null) { + return maxEntry.getKey(); + } + return -1; + } + + private static int matchToMCtID(Track t) { + Map> map = new HashMap<>(); + for(Cluster c: t.getSeed().getClusters()) { + for(Hit h : c) { + if(h.getAssociateMCTrkId()==-1) continue; + if(!map.containsKey(h.getAssociateMCTrkId())) { + map.put(h.getAssociateMCTrkId(), new ArrayList<>()); + map.get(h.getAssociateMCTrkId()).add(h); + } else { + map.get(h.getAssociateMCTrkId()).add(h); + } + } + } + Map.Entry> maxEntry = map.entrySet() + .stream() + .max(Comparator.comparingInt(e -> e.getValue().size())) + .orElse(null); // returns null if map is empty + + if(maxEntry!=null) { + return maxEntry.getKey(); + } + return -1; + } + + private static List>> getMCHOTs(List>hits){ //0. + Map> map1 = new HashMap<>(); + Map> map2 = new HashMap<>(); + List>> maps = new ArrayList<>(); + + for(Hit h : hits.get(0)) { + if(!map1.containsKey(h.getAssociateMCTrkId())) { + map1.put(h.getAssociateMCTrkId(), new ArrayList<>()); + map1.get(h.getAssociateMCTrkId()).add(h); + } else { + map1.get(h.getAssociateMCTrkId()).add(h); + } + } + for(Hit h : hits.get(1)) { + if(!map2.containsKey(h.getAssociateMCTrkId())) { + map2.put(h.getAssociateMCTrkId(), new ArrayList<>()); + map2.get(h.getAssociateMCTrkId()).add(h); + } else { + map2.get(h.getAssociateMCTrkId()).add(h); + } + } + maps.add(map1); + maps.add(map2); + + return maps; + } + + private static double[] calcEfficiency(Seed s, List>> maps) { + int nMCMatchedBstHits=0; + int nMCMatchedBmtHits=0; + int mcmatchId = matchToMCtID(s); + int nbst = 0; + if(!maps.get(0).isEmpty() && + maps.get(0).containsKey(mcmatchId)) { + nbst=maps.get(0).get(mcmatchId).size(); + } + int nbmt = 0; + if(!maps.get(1).isEmpty() && + maps.get(1).containsKey(mcmatchId)) { + nbmt=maps.get(1).get(mcmatchId).size(); + } + for(Cluster c: s.getClusters()) { + for(Hit h : c) { + if(h.getAssociateMCTrkId()==mcmatchId && h.getDetector()==DetectorType.BST) { + nMCMatchedBstHits++; + } + if(h.getAssociateMCTrkId()==mcmatchId && h.getDetector()==DetectorType.BMT) { + nMCMatchedBmtHits++; + } + } + } + + double bstE = 0; + double bmtE = 0; + double E = 0; + if(nbst!=0) + bstE = (double) nMCMatchedBstHits/(double)nbst; + if(nbmt!=0) + bmtE = (double) nMCMatchedBmtHits/(double)nbmt; + if(nbst+nbmt!=0) + E = (double) (nMCMatchedBstHits+nMCMatchedBmtHits)/(double)(nbst+nbmt); + + return new double[] {bstE, bmtE, E}; + } + + private static double[] calcEfficiency(Track t, List>> maps) { + return calcEfficiency(t.getSeed(), maps); + } + + private static void setSeedsEfficiency(List seeds, List>> maps) { //4. + for(Seed s : seeds) { + + double[] effs = TrackingPerformance.calcEfficiency(s, maps); + s.setEffs(effs); + } + } + + private static void setTracksEfficiency(List tracks, List>> maps) { //4. + for(Track t : tracks) { + double[] effs = TrackingPerformance.calcEfficiency(t, maps); + t.setEffs(effs); + } + } + + public static void TrackingPerformance(DataEvent event, List>hits, + List seeds, List tracks) { + if (event.hasBank("MC::True")) { + DataBank mcTrue = event.getBank("MC::True"); + MatchHitsToMC(hits, mcTrue); + } + List>> hmaps = getMCHOTs(hits); + + if(seeds!=null) { + setSeedsPurity(seeds); + setSeedsEfficiency(seeds, hmaps); + } + if(tracks!=null) { + setTracksEfficiency(tracks, hmaps); + setTracksPurity(tracks); + } + } +} + + diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/services/CVTReconstruction.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/services/CVTReconstruction.java index 05bfe8869d..a34366fd5f 100644 --- a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/services/CVTReconstruction.java +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/services/CVTReconstruction.java @@ -28,6 +28,8 @@ public class CVTReconstruction { private List> CVTclusters = new ArrayList<>(); private List> CVTcrosses = new ArrayList<>(); + public boolean filterHits = false; + private Swim swimmer; public CVTReconstruction() { @@ -78,9 +80,27 @@ public List> readHits(DataEvent event, IndexedTable svtStatus, } } setTotalNbTruHits(totmctru); + + //filter hits + if(filterHits) { + List> hits = new ArrayList<>(); + for(int b=0; b<2; b++) { + hits.add(new ArrayList<>()); + for(Hit h : CVThits.get(b)) { + if(h.MCstatus!=0) { + hits.get(b).add(h); + } + } + } + for(int b=0; b<2; b++) { + CVThits.set(b, hits.get(b)); + } + } + return CVThits; } - + + public List> findClusters() { List clusters = new ArrayList<>(); diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/track/Seed.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/track/Seed.java index 14da31acc7..68dca1cbb9 100644 --- a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/track/Seed.java +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/track/Seed.java @@ -44,6 +44,8 @@ public class Seed implements Comparable{ public double percentTruthMatch; public double totpercentTruthMatch; public int FirstPassIdx; + private double purity=0; + private double[] effs;// eff for hits on tracks from MC: [0]=BST eff; [1]=BMT eff; [2] = total eff public Seed() { } @@ -749,6 +751,34 @@ private static List appendSeedList(List seeds, List ovlrem) { return ovlrem2; } + + /** + * @return the purity + */ + public double getPurity() { + return purity; + } + + /** + * @param purity the purity to set + */ + public void setPurity(double purity) { + this.purity = purity; + } + + /** + * @return the effs + */ + public double[] getEffs() { + return effs; + } + + /** + * @param effs the effs to set + */ + public void setEffs(double[] effs) { + this.effs = effs; + } public class Key implements Comparable { diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/track/Track.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/track/Track.java index eea7abe5e6..c40e6490e2 100644 --- a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/track/Track.java +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/track/Track.java @@ -61,7 +61,8 @@ public class Track extends Trajectory implements Comparable { private double secondaryChi2; // for track with no beamSpot information private int secondaryNDF; // for track with no beamSpot information private int _status = 0; - + private double purity=0; + private double[] effs;// eff for hits on tracks from MC: [0]=BST eff; [1]=BMT eff; [2] = total eff public Track(Helix helix) { super(helix); @@ -649,6 +650,34 @@ public static void checkForOverlaps(List tracks, String msg) { } } + /** + * @return the purity + */ + public double getPurity() { + return purity; + } + + /** + * @param purity the purity to set + */ + public void setPurity(double purity) { + this.purity = purity; + } + + /** + * @return the effs + */ + public double[] getEffs() { + return effs; + } + + /** + * @param effs the effs to set + */ + public void setEffs(double[] effs) { + this.effs = effs; + } + @Override public String toString() {