From 11b7424a6411f5ecca6ec168a42125b8d5a89646 Mon Sep 17 00:00:00 2001 From: ziegler Date: Mon, 28 Jul 2025 14:47:06 -0400 Subject: [PATCH 1/7] Dedicated branch for creating ML sample for CVT AI. --- .../main/java/org/jlab/rec/cvt/hit/Hit.java | 93 ++- .../java/org/jlab/rec/cvt/ml/BankOutput.java | 122 +++ .../java/org/jlab/rec/cvt/ml/CVTFilter.java | 622 ++++++++++++++++ .../java/org/jlab/rec/cvt/ml/SampleMaker.java | 698 ++++++++++++++++++ .../jlab/rec/cvt/ml/TrackingPerformance.java | 248 +++++++ .../rec/cvt/services/CVTReconstruction.java | 19 +- .../java/org/jlab/rec/cvt/track/Seed.java | 30 + .../java/org/jlab/rec/cvt/track/Track.java | 31 +- 8 files changed, 1858 insertions(+), 5 deletions(-) create mode 100644 reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/BankOutput.java create mode 100644 reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/CVTFilter.java create mode 100644 reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/SampleMaker.java create mode 100644 reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/TrackingPerformance.java 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..d1e2a999f0 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 @@ -282,8 +289,88 @@ public int getAssociatedTrackID() { } - public void setAssociatedTrackID(int associatedTrackID) { - AssociatedTrackID = associatedTrackID; + public void setAssociatedTrackID(int associatedSeedID) { + AssociatedTrackID = associatedSeedID; + } + + public int getAssociatedSeedID() { + return AssociatedSeedID; + } + + + public void setAssociatedSeedID(int associatedSeedID) { + 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() { diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/BankOutput.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/BankOutput.java new file mode 100644 index 0000000000..1693dd51e7 --- /dev/null +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/BankOutput.java @@ -0,0 +1,122 @@ +/* + * 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.List; +import org.jlab.detector.base.DetectorType; +import org.jlab.io.base.DataBank; +import org.jlab.io.base.DataEvent; +import org.jlab.rec.cvt.bmt.BMTType; +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 BankOutput { + public static DataBank fillHitsBank(DataEvent event, List>hits, String bankName) { + if (hits == null || hits.isEmpty()) return null; + DataBank bank = event.createBank(bankName, 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("sidx", index, (short) hits.get(i).get(j).getSeedBankRow()); + bank.setShort("tidx", index, (short) hits.get(i).get(j).getTrackBankRow()); + bank.setShort("recsid", index, (short) hits.get(i).get(j).getAssociatedSeedID()); + bank.setShort("rectid", index, (short) hits.get(i).get(j).getAssociatedTrackID()); + 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.setByte("type", index, getType(hits.get(i).get(j))); + bank.setShort("strip", index, (short) hits.get(i).get(j).getStrip().getStrip()); + bank.setByte("order", index, (byte) hits.get(i).get(j).MCstatus); + bank.setShort("cid", index, (short) hits.get(i).get(j).getAssociatedClusterID()); + bank.setFloat("cweight", index, (float) hits.get(i).get(j).getCweight()); + bank.setFloat("sweight", index, (float) hits.get(i).get(j).getSweight()); + 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)) { + bank.setFloat("x1", index, (float) hits.get(i).get(j).getStrip().getLine().origin().x()/10); + bank.setFloat("y1", index, (float) hits.get(i).get(j).getStrip().getLine().origin().y()/10); + bank.setFloat("z1", index, (float) hits.get(i).get(j).getStrip().getLine().origin().z()/10); + bank.setFloat("x2", index, (float) hits.get(i).get(j).getStrip().getLine().end().x()/10); + bank.setFloat("y2", index, (float) hits.get(i).get(j).getStrip().getLine().end().y()/10); + bank.setFloat("z2", index, (float) hits.get(i).get(j).getStrip().getLine().end().z()/10); + + } + if(hits.get(i).get(j).getDetector()==DetectorType.BMT + && hits.get(i).get(j).getType()==BMTType.C) { + bank.setFloat("x1", index, (float) hits.get(i).get(j).getStrip().getArc().origin().x()/10); + bank.setFloat("y1", index, (float) hits.get(i).get(j).getStrip().getArc().origin().y()/10); + bank.setFloat("z1", index, (float) hits.get(i).get(j).getStrip().getArc().origin().z()/10); + bank.setFloat("x2", index, (float) hits.get(i).get(j).getStrip().getArc().end().x()/10); + bank.setFloat("y2", index, (float) hits.get(i).get(j).getStrip().getArc().end().y()/10); + bank.setFloat("z2", index, (float) hits.get(i).get(j).getStrip().getArc().end().z()/10); + + } + + index++; + } + } + return bank; + } + + public static DataBank fillSeedsBank(DataEvent event, List seeds, String bankName) { + if (seeds == null || seeds.isEmpty()) return null; + + DataBank bank = event.createBank(bankName, seeds.size()); + + for (int i = 0; i < seeds.size(); i++) { + if(seeds.get(i)==null) + continue; + bank.setShort("id", i, (short) seeds.get(i).getId()); + bank.setFloat("purity", i, (float) seeds.get(i).getPurity()); + bank.setFloat("efficiency", i, (float) seeds.get(i).getEffs()[2]); + } + return bank; + } + + public static DataBank fillTracksBank(DataEvent event, List tracks, String bankName) { + if (tracks == null || tracks.isEmpty()) return null; + + DataBank bank = event.createBank(bankName, tracks.size()); + + for (int i = 0; i < tracks.size(); i++) { + if(tracks.get(i)==null) + continue; + bank.setShort("id", i, (short) tracks.get(i).getId()); + bank.setFloat("purity", i, (float) tracks.get(i).getPurity()); + bank.setFloat("efficiency", i, (float) tracks.get(i).getEffs()[2]); + } + return bank; + } + + + private static byte getType(Hit h) { + DetectorType detector = h.getDetector(); + + if (detector == DetectorType.BST) { + return 0; + } + + if (detector == DetectorType.BMT) { + BMTType type = h.getType(); + switch (type) { + case Z: return 1; + case C: return 2; + default: return -1; + } + } + + return -1; +} + +} diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/CVTFilter.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/CVTFilter.java new file mode 100644 index 0000000000..8e18ec2a59 --- /dev/null +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/CVTFilter.java @@ -0,0 +1,622 @@ +package org.jlab.rec.cvt.ml; + +import org.jlab.rec.cvt.services.*; +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.io.base.DataBank; +import org.jlab.io.base.DataEvent; +import org.jlab.io.hipo.HipoDataEvent; +import org.jlab.rec.cvt.Constants; +import org.jlab.rec.cvt.Geometry; +import org.jlab.rec.cvt.banks.RecoBankWriter; +import org.jlab.rec.cvt.cluster.Cluster; +import org.jlab.rec.cvt.cross.Cross; +import org.jlab.rec.cvt.hit.Hit; +import org.jlab.rec.cvt.track.Seed; +import org.jlab.rec.cvt.track.StraightTrack; +import org.jlab.rec.cvt.track.Track; +import org.jlab.utils.groups.IndexedTable; + +/** + * Service to return reconstructed TRACKS + * format + * + * @author ziegler + * + */ +public class CVTFilter extends ReconstructionEngine { + + + /** + * @param docacutsum the docacutsum to set + */ + public void setDocacutsum(double docacutsum) { + this.docacutsum = docacutsum; + } + + private int Run = -1; + + private String svtHitBank; + private String svtClusterBank; + private String svtCrossBank; + private String bmtHitBank; + private String bmtClusterBank; + private String bmtCrossBank; + private String cvtSeedBank; + private String cvtSeedClusBank; + private String cvtTrackBank; + private String cvtUTrackBank; + private String cvtTrajectoryBank; + private String cvtKFTrajectoryBank; + private String cvtCovMatBank; + private String bankPrefix = ""; + + // run-time options + private int pid = 0; + private int kfIterations = 5; + private boolean kfFilterOn = true; + private boolean initFromMc = false; + + // yaml setting passed to Constants class + private boolean isCosmics = false; + private boolean svtOnly = false; + private String excludeLayers = null; + private String excludeBMTLayers = null; + private int removeRegion = 0; + private int beamSpotConstraint = 2; + private double beamSpotRadius = 0.3; + private String targetMaterial = ""; + private boolean elossPrecorrection = true; + private boolean svtSeeding = true; + private boolean timeCuts = true; + private boolean hvCuts = true; + public boolean useSVTTimingCuts = false; + public boolean removeOverlappingSeeds = true; + public boolean flagSeeds = true; + public boolean gemcIgnBMT0ADC = false; + public boolean KFfailRecovery = true; + public boolean KFfailRecovMisCls = true; + private String matrixLibrary = "EJML"; + private boolean useOnlyTruth = false; + private boolean useSVTLinkerSeeder = true; + private double docacut = 0.75; + private double docacutsum = 1.15; + private int svtmaxclussize = 100; + private int bmtcmaxclussize = 100; + private int bmtzmaxclussize = 100; + private double rcut = 120.0; + private double z0cut = 10; + + public CVTFilter(String name) { + super(name, "ziegler", "6.0"); + } + + public CVTFilter() { + super("CVTEngine", "ziegler", "6.0"); + } + + + @Override + public boolean init() { + this.loadConfiguration(); + Constants.getInstance().initialize(this.getName(), + isCosmics, + svtOnly, + excludeLayers, + excludeBMTLayers, + removeRegion, + beamSpotConstraint, + beamSpotRadius, + targetMaterial, + elossPrecorrection, + svtSeeding, + timeCuts, + hvCuts, + useSVTTimingCuts, + removeOverlappingSeeds, + flagSeeds, + gemcIgnBMT0ADC, + KFfailRecovery, + KFfailRecovMisCls, + matrixLibrary, + useOnlyTruth, + useSVTLinkerSeeder, + docacut, + docacutsum, + svtmaxclussize, + bmtcmaxclussize, + bmtzmaxclussize, + rcut, + z0cut); + + this.initConstantsTables(); + this.registerBanks(); + this.printConfiguration(); + return true; + } + + public final void setOutputBankPrefix(String prefix) { + this.bankPrefix = prefix; + } + + public void registerBanks() { + String prefix = bankPrefix; + if(Constants.getInstance().isCosmics) prefix = "Rec"; + this.setBmtHitBank("BMT" + prefix + "::Hits"); + this.setBmtClusterBank("BMT" + prefix + "::Clusters"); + this.setBmtCrossBank("BMT" + prefix + "::Crosses"); + this.setSvtHitBank("BST" + prefix + "::Hits"); + this.setSvtClusterBank("BST" + prefix + "::Clusters"); + this.setSvtCrossBank("BST" + prefix + "::Crosses"); + this.setSeedBank("CVT" + prefix + "::Seeds"); + this.setSeedClusBank("CVT" + prefix + "::SeedClusters"); + this.setTrackBank("CVT" + prefix + "::Tracks"); + this.setUTrackBank("CVT" + prefix + "::UTracks"); + this.setCovMatBank("CVT" + prefix + "::TrackCovMat"); + this.setTrajectoryBank("CVT" + prefix + "::Trajectory"); + this.setKFTrajectoryBank("CVT" + prefix + "::KFTrajectory"); + super.registerOutputBank(this.bmtHitBank); + super.registerOutputBank(this.bmtClusterBank); + super.registerOutputBank(this.bmtCrossBank); + super.registerOutputBank(this.svtHitBank); + super.registerOutputBank(this.svtClusterBank); + super.registerOutputBank(this.svtCrossBank); + super.registerOutputBank(this.cvtSeedBank); + super.registerOutputBank(this.cvtSeedClusBank); + super.registerOutputBank(this.cvtTrackBank); + super.registerOutputBank(this.cvtUTrackBank); + super.registerOutputBank(this.cvtCovMatBank); + super.registerOutputBank(this.cvtTrajectoryBank); + super.registerOutputBank(this.cvtKFTrajectoryBank); + } + + 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; + } + + public int getPid() { + return pid; + } + + public int getKfIterations() { + return kfIterations; + } + + public boolean isKfFilterOn() { + return kfFilterOn; + } + + public boolean isInitFromMc() { + return initFromMc; + } + + public boolean seedBeamSpot() { + return this.beamSpotConstraint>0; + } + + public boolean kfBeamSpot() { + return this.beamSpotConstraint==2; + } + + /** + * @return the docacut + */ + public double getDocacut() { + return docacut; + } + + /** + * @param docacut the docacut to set + */ + public void setDocacut(double docacut) { + this.docacut = docacut; + } + + /** + * @return the docacutsum + */ + public double getDocacutsum() { + return docacutsum; + } + + /** + * @return the svtmaxclussize + */ + public int getSvtmaxclussize() { + return svtmaxclussize; + } + + /** + * @param svtmaxclussize the svtmaxclussize to set + */ + public void setSvtmaxclussize(int svtmaxclussize) { + this.svtmaxclussize = svtmaxclussize; + } + + /** + * @return the bmtcmaxclussize + */ + public int getBmtcmaxclussize() { + return bmtcmaxclussize; + } + + /** + * @param bmtcmaxclussize the bmtcmaxclussize to set + */ + public void setBmtcmaxclussize(int bmtcmaxclussize) { + this.bmtcmaxclussize = bmtcmaxclussize; + } + + /** + * @return the bmtzmaxclussize + */ + public int getBmtzmaxclussize() { + return bmtzmaxclussize; + } + + /** + * @param bmtzmaxclussize the bmtzmaxclussize to set + */ + public void setBmtzmaxclussize(int bmtzmaxclussize) { + this.bmtzmaxclussize = bmtzmaxclussize; + } + + @Override + public boolean processDataEvent(DataEvent event) { + + Swim swimmer = new Swim(); + + int run = this.getRun(event); + + 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 beamPos = this.getConstantsManager().getConstants(run, "/geometry/beam/position"); + IndexedTable adcStatus = this.getConstantsManager().getConstants(run, "/calibration/svt/adcstatus"); + + Geometry.getInstance().initialize(this.getConstantsManager().getVariation(), run, svtLorentz, bmtVoltage); + + CVTReconstruction reco = new CVTReconstruction(swimmer); + reco.filterHits=true; + + List> hits = reco.readHits(event, svtStatus, bmtStatus, bmtTime, + bmtStripVoltage, bmtStripThreshold, + adcStatus); + + List> clusters = reco.findClusters(); + List> crosses = reco.findCrosses(); + + + List banks = new ArrayList<>(); + + if(crosses != null) { + if(Constants.getInstance().isCosmics) { + CosmicTracksRec trackFinder = new CosmicTracksRec(); + List seeds = trackFinder.getSeeds(event, clusters.get(0), clusters.get(1), crosses); + List tracks = trackFinder.getTracks(event, this.isInitFromMc(), + this.isKfFilterOn(), + this.getKfIterations()); + if(seeds!=null) banks.add(RecoBankWriter.fillStraightSeedsBank(event, seeds, "CVTRec::CosmicSeeds")); + if(tracks!=null) { + banks.add(RecoBankWriter.fillStraightTracksBank(event, tracks, "CVTRec::Cosmics")); + banks.add(RecoBankWriter.fillStraightTracksTrajectoryBank(event, tracks, "CVTRec::Trajectory")); + banks.add(RecoBankWriter.fillStraightTrackKFTrajectoryBank(event, tracks, "CVTRec::KFTrajectory")); + } + } + else { + double[] xyBeam = CVTReconstruction.getBeamSpot(event, beamPos); + TracksFromTargetRec trackFinder = new TracksFromTargetRec(swimmer, xyBeam); + trackFinder.totTruthHits = reco.getTotalNbTruHits(); + List seeds = trackFinder.getSeeds(clusters, crosses); + + + List tracks = trackFinder.getTracks(event, this.isInitFromMc(), + this.isKfFilterOn(), + this.getKfIterations(), + true, this.getPid()); + +// if(seeds!=null) { +// banks.add(RecoBankWriter.fillSeedBank(event, seeds, this.getSeedBank())); +// banks.add(RecoBankWriter.fillSeedClusBank(event, seeds, this.getSeedClusBank())); +// } + if(tracks!=null) { + ((HipoDataEvent) event).getHipoEvent().reset(); +// banks.add(RecoBankWriter.fillTrackBank(event, tracks, this.getTrackBank())); +// // banks.add(RecoBankWriter.fillTrackCovMatBank(event, tracks, this.getCovMat())); +// banks.add(RecoBankWriter.fillTrajectoryBank(event, tracks, this.getTrajectoryBank())); +// banks.add(RecoBankWriter.fillKFTrajectoryBank(event, tracks, this.getKFTrajectoryBank())); + } + } + } +// banks.add(RecoBankWriter.fillSVTHitBank(event, hits.get(0), this.getSvtHitBank())); +// banks.add(RecoBankWriter.fillBMTHitBank(event, hits.get(1), this.getBmtHitBank())); +// banks.add(RecoBankWriter.fillSVTClusterBank(event, clusters.get(0), this.getSvtClusterBank())); +// banks.add(RecoBankWriter.fillBMTClusterBank(event, clusters.get(1), this.getBmtClusterBank())); +// banks.add(RecoBankWriter.fillSVTCrossBank(event, crosses.get(0), this.getSvtCrossBank())); +// banks.add(RecoBankWriter.fillBMTCrossBank(event, crosses.get(1), this.getBmtCrossBank())); +// +// event.appendBanks(banks.toArray(new DataBank[0])); + + + return true; + } + + + public void loadConfiguration() { + + // general (pass-independent) settings + if (this.getEngineConfigString("cosmics")!=null) + this.isCosmics = Boolean.valueOf(this.getEngineConfigString("cosmics")); + + if (this.getEngineConfigString("svtOnly")!=null) + this.svtOnly = Boolean.valueOf(this.getEngineConfigString("svtOnly")); + + if (this.getEngineConfigString("excludeLayers")!=null) + this.excludeLayers = this.getEngineConfigString("excludeLayers"); + + if (this.getEngineConfigString("excludeBMTLayers")!=null) + this.excludeBMTLayers = this.getEngineConfigString("excludeBMTLayers"); + + if (this.getEngineConfigString("removeRegion")!=null) + this.removeRegion = Integer.valueOf(this.getEngineConfigString("removeRegion")); + + if (this.getEngineConfigString("beamSpotConst")!=null) + this.beamSpotConstraint = Integer.valueOf(this.getEngineConfigString("beamSpotConst")); + + if (this.getEngineConfigString("beamSpotRadius")!=null) + this.beamSpotRadius = Double.valueOf(this.getEngineConfigString("beamSpotRadius")); + + if(this.getEngineConfigString("targetMat")!=null) + this.targetMaterial = this.getEngineConfigString("targetMat"); + + if(this.getEngineConfigString("elossPreCorrection")!=null) + this.elossPrecorrection = Boolean.parseBoolean(this.getEngineConfigString("elossPreCorrection")); + + if(this.getEngineConfigString("svtSeeding")!=null) + this.svtSeeding = Boolean.parseBoolean(this.getEngineConfigString("svtSeeding")); + + if(this.getEngineConfigString("timeCuts")!=null) + this.timeCuts = Boolean.parseBoolean(this.getEngineConfigString("timeCuts")); + + if(this.getEngineConfigString("hvCuts")!=null) + this.hvCuts = Boolean.parseBoolean(this.getEngineConfigString("hvCuts")); + + if(this.getEngineConfigString("useSVTTimingCuts")!=null) + this.useSVTTimingCuts = Boolean.parseBoolean(this.getEngineConfigString("useSVTTimingCuts")); + + if(this.getEngineConfigString("removeOverlappingSeeds")!=null) + this.removeOverlappingSeeds = Boolean.parseBoolean(this.getEngineConfigString("removeOverlappingSeeds")); + + if(this.getEngineConfigString("flagSeeds")!=null) + this.flagSeeds = Boolean.parseBoolean(this.getEngineConfigString("flagSeeds")); + + if(this.getEngineConfigString("gemcIgnBMT0ADC")!=null) + this.gemcIgnBMT0ADC = Boolean.parseBoolean(this.getEngineConfigString("gemcIgnBMT0ADC")); + + if(this.getEngineConfigString("KFfailRecovery")!=null) + this.KFfailRecovery = Boolean.parseBoolean(this.getEngineConfigString("KFfailRecovery")); + + if(this.getEngineConfigString("KFfailRecovMisCls")!=null) + this.KFfailRecovMisCls = Boolean.parseBoolean(this.getEngineConfigString("KFfailRecovMisCls")); + + if (this.getEngineConfigString("matLib")!=null) + this.matrixLibrary = this.getEngineConfigString("matLib"); + + // service dependent configuration settings + if(this.getEngineConfigString("elossPid")!=null) + this.pid = Integer.parseInt(this.getEngineConfigString("elossPid")); + + if (this.getEngineConfigString("kfFilterOn")!=null) + this.kfFilterOn = Boolean.valueOf(this.getEngineConfigString("kfFilterOn")); + + if (this.getEngineConfigString("initFromMC")!=null) + this.initFromMc = Boolean.valueOf(this.getEngineConfigString("initFromMC")); + + if (this.getEngineConfigString("useOnlyTruthHits")!=null) + this.useOnlyTruth = Boolean.valueOf(this.getEngineConfigString("useOnlyTruthHits")); + + if (this.getEngineConfigString("useSVTLinkerSeeder")!=null) + this.useSVTLinkerSeeder = Boolean.valueOf(this.getEngineConfigString("useSVTLinkerSeeder")); + + if (this.getEngineConfigString("kfIterations")!=null) + this.kfIterations = Integer.valueOf(this.getEngineConfigString("kfIterations")); + + if (this.getEngineConfigString("docacut")!=null) + this.setDocacut((double) Double.valueOf(this.getEngineConfigString("docacut"))); + + if (this.getEngineConfigString("docacutsum")!=null) + this.setDocacutsum((double) Double.valueOf(this.getEngineConfigString("docacutsum"))); + + if (this.getEngineConfigString("svtmaxclussize")!=null) + this.setSvtmaxclussize((int) Integer.valueOf(this.getEngineConfigString("svtmaxclussize"))); + + if (this.getEngineConfigString("bmtcmaxclussize")!=null) + this.setBmtcmaxclussize((int) Integer.valueOf(this.getEngineConfigString("bmtcmaxclussize"))); + + if (this.getEngineConfigString("bmtzmaxclussize")!=null) + this.setBmtzmaxclussize((int) Integer.valueOf(this.getEngineConfigString("bmtzmaxclussize"))); + + if (this.getEngineConfigString("rcut")!=null) + this.rcut = Double.valueOf(this.getEngineConfigString("rcut")); + + if (this.getEngineConfigString("z0cut")!=null) + this.z0cut = Double.valueOf(this.getEngineConfigString("z0cut")); + + } + + + 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 void setSvtClusterBank(String bstClusterBank) { + this.svtClusterBank = bstClusterBank; + } + + public void setSvtCrossBank(String bstCrossBank) { + this.svtCrossBank = bstCrossBank; + } + + public void setBmtHitBank(String bmtHitBank) { + this.bmtHitBank = bmtHitBank; + } + + public void setBmtClusterBank(String bmtClusterBank) { + this.bmtClusterBank = bmtClusterBank; + } + + public void setBmtCrossBank(String bmtCrossBank) { + this.bmtCrossBank = bmtCrossBank; + } + + public void setSeedBank(String cvtSeedBank) { + this.cvtSeedBank = cvtSeedBank; + } + + public void setSeedClusBank(String cvtSeedClusBank) { + this.cvtSeedClusBank = cvtSeedClusBank; + } + + public void setTrackBank(String cvtTrackBank) { + this.cvtTrackBank = cvtTrackBank; + } + + public void setUTrackBank(String cvtTrack0Bank) { + this.cvtUTrackBank = cvtTrack0Bank; + } + + public void setTrajectoryBank(String cvtTrajectoryBank) { + this.cvtTrajectoryBank = cvtTrajectoryBank; + } + + public void setCovMatBank(String cvtTrackCovMat) { + this.cvtCovMatBank = cvtTrackCovMat; + } + + public void setKFTrajectoryBank(String cvtKFTrajectoryBank) { + this.cvtKFTrajectoryBank = cvtKFTrajectoryBank; + } + + public String getSvtHitBank() { + return svtHitBank; + } + + public String getSvtClusterBank() { + return svtClusterBank; + } + + public String getSvtCrossBank() { + return svtCrossBank; + } + + public String getBmtHitBank() { + return bmtHitBank; + } + + public String getBmtClusterBank() { + return bmtClusterBank; + } + + public String getBmtCrossBank() { + return bmtCrossBank; + } + + public String getSeedBank() { + return cvtSeedBank; + } + + public String getSeedClusBank() { + return cvtSeedClusBank; + } + public String getTrackBank() { + return cvtTrackBank; + } + + public String getUTrackBank() { + return cvtUTrackBank; + } + + public String getTrajectoryBank() { + return cvtTrajectoryBank; + } + + public String getKFTrajectoryBank() { + return cvtKFTrajectoryBank; + } + + public String getCovMat() { + return cvtCovMatBank; + } + + + public void printConfiguration() { + + System.out.println("["+this.getName()+"] run with cosmics setting set to "+Constants.getInstance().isCosmics); + System.out.println("["+this.getName()+"] run with SVT only set to "+Constants.getInstance().svtOnly); + if(this.excludeLayers!=null) + System.out.println("["+this.getName()+"] run with layers "+this.excludeLayers+" excluded in fit, based on yaml"); + if(this.excludeBMTLayers!=null) + System.out.println("["+this.getName()+"] run with BMT layers "+this.getEngineConfigString("excludeBMTLayers")+" excluded"); + if(this.removeRegion>0) + System.out.println("["+this.getName()+"] run with region "+this.getEngineConfigString("removeRegion")+" removed"); + System.out.println("["+this.getName()+"] run with beamSpotConst set to "+Constants.getInstance().beamSpotConstraint+ " (0=no-constraint, 1=seed only, 2=seed and KF)"); + System.out.println("["+this.getName()+"] run with beam spot size set to "+Constants.getInstance().getBeamRadius()); + System.out.println("["+this.getName()+"] Target material set to "+ Constants.getInstance().getTargetType()); + System.out.println("["+this.getName()+"] Pre-Eloss correction set to " + Constants.getInstance().preElossCorrection); + System.out.println("["+this.getName()+"] run SVT-based seeding set to "+ Constants.getInstance().svtSeeding); + System.out.println("["+this.getName()+"] run BMT timing cuts set to "+ Constants.getInstance().timeCuts); + System.out.println("["+this.getName()+"] run BMT HV masks "+ Constants.getInstance().bmtHVCuts); + System.out.println("["+this.getName()+"] run with matLib "+ Constants.getInstance().KFMatrixLibrary.toString() + " library"); + System.out.println("["+this.getName()+"] ELoss mass set for particle "+ pid); + System.out.println("["+this.getName()+"] run with Kalman-Filter status set to "+this.kfFilterOn); + System.out.println("["+this.getName()+"] initialize KF from true MC information "+this.initFromMc); + System.out.println("["+this.getName()+"] number of KF iterations set to "+this.kfIterations); + System.out.println("["+this.getName()+"] SLA doca cut "+this.docacut); + System.out.println("["+this.getName()+"] SLA docasum cut "+this.docacutsum); + System.out.println("["+this.getName()+"] max svt cluster size "+this.getSvtmaxclussize()); + System.out.println("["+this.getName()+"] max bmt-c cluster size "+this.getBmtcmaxclussize()); + System.out.println("["+this.getName()+"] max btm-z cluster size "+this.getBmtzmaxclussize()); + System.out.println("["+this.getName()+"] helix radius cut (mm) "+this.rcut); + System.out.println("["+this.getName()+"] z0 cut (mm from target edges) "+this.z0cut); + + + } + + + +} diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/SampleMaker.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/SampleMaker.java new file mode 100644 index 0000000000..a600b58e67 --- /dev/null +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/SampleMaker.java @@ -0,0 +1,698 @@ +package org.jlab.rec.cvt.ml; + +import org.jlab.rec.cvt.services.*; +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.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.banks.RecoBankWriter; +import org.jlab.rec.cvt.cluster.Cluster; +import org.jlab.rec.cvt.cross.Cross; +import org.jlab.rec.cvt.hit.Hit; +import org.jlab.rec.cvt.track.Seed; +import org.jlab.rec.cvt.track.StraightTrack; +import org.jlab.rec.cvt.track.Track; +import org.jlab.utils.groups.IndexedTable; + +/** + * Service to return reconstructed TRACKS + * format + * + * @author ziegler + * + */ +public class SampleMaker extends ReconstructionEngine { + + + /** + * @param docacutsum the docacutsum to set + */ + public void setDocacutsum(double docacutsum) { + this.docacutsum = docacutsum; + } + + private int Run = -1; + + private String svtHitBank; + private String svtClusterBank; + private String svtCrossBank; + private String bmtHitBank; + private String mlHitBank; + private String mlSeedBank; + private String mlTrackBank; + private String bmtClusterBank; + private String bmtCrossBank; + private String cvtSeedBank; + private String cvtSeedClusBank; + private String cvtTrackBank; + private String cvtUTrackBank; + private String cvtTrajectoryBank; + private String cvtKFTrajectoryBank; + private String cvtCovMatBank; + private String bankPrefix = ""; + + // run-time options + private int pid = 0; + private int kfIterations = 5; + private boolean kfFilterOn = true; + private boolean initFromMc = false; + + // yaml setting passed to Constants class + private boolean isCosmics = false; + private boolean svtOnly = false; + private String excludeLayers = null; + private String excludeBMTLayers = null; + private int removeRegion = 0; + private int beamSpotConstraint = 2; + private double beamSpotRadius = 0.3; + private String targetMaterial = ""; + private boolean elossPrecorrection = true; + private boolean svtSeeding = true; + private boolean timeCuts = true; + private boolean hvCuts = true; + public boolean useSVTTimingCuts = false; + public boolean removeOverlappingSeeds = true; + public boolean flagSeeds = true; + public boolean gemcIgnBMT0ADC = false; + public boolean KFfailRecovery = true; + public boolean KFfailRecovMisCls = true; + private String matrixLibrary = "EJML"; + private boolean useOnlyTruth = false; + private boolean useSVTLinkerSeeder = true; + private double docacut = 0.75; + private double docacutsum = 1.15; + private int svtmaxclussize = 100; + private int bmtcmaxclussize = 100; + private int bmtzmaxclussize = 100; + private double rcut = 120.0; + private double z0cut = 10; + + public SampleMaker(String name) { + super(name, "ziegler", "6.0"); + } + + public SampleMaker() { + super("CVTEngine", "ziegler", "6.0"); + } + + + @Override + public boolean init() { + this.loadConfiguration(); + Constants.getInstance().initialize(this.getName(), + isCosmics, + svtOnly, + excludeLayers, + excludeBMTLayers, + removeRegion, + beamSpotConstraint, + beamSpotRadius, + targetMaterial, + elossPrecorrection, + svtSeeding, + timeCuts, + hvCuts, + useSVTTimingCuts, + removeOverlappingSeeds, + flagSeeds, + gemcIgnBMT0ADC, + KFfailRecovery, + KFfailRecovMisCls, + matrixLibrary, + useOnlyTruth, + useSVTLinkerSeeder, + docacut, + docacutsum, + svtmaxclussize, + bmtcmaxclussize, + bmtzmaxclussize, + rcut, + z0cut); + + this.initConstantsTables(); + this.registerBanks(); + this.printConfiguration(); + return true; + } + + public final void setOutputBankPrefix(String prefix) { + this.bankPrefix = prefix; + } + + public void registerBanks() { + String prefix = bankPrefix; + if(Constants.getInstance().isCosmics) prefix = "Rec"; + this.setMlHitBank("CVT" + prefix + "::MLHit"); + this.setMlSeedBank("CVT" + prefix + "::MLSeed"); + this.setMlTrackBank("CVT" + prefix + "::MLTrack"); + this.setBmtHitBank("BMT" + prefix + "::Hits"); + this.setBmtClusterBank("BMT" + prefix + "::Clusters"); + this.setBmtCrossBank("BMT" + prefix + "::Crosses"); + this.setSvtHitBank("BST" + prefix + "::Hits"); + this.setSvtClusterBank("BST" + prefix + "::Clusters"); + this.setSvtCrossBank("BST" + prefix + "::Crosses"); + this.setSeedBank("CVT" + prefix + "::Seeds"); + this.setSeedClusBank("CVT" + prefix + "::SeedClusters"); + this.setTrackBank("CVT" + prefix + "::Tracks"); + this.setUTrackBank("CVT" + prefix + "::UTracks"); + this.setCovMatBank("CVT" + prefix + "::TrackCovMat"); + this.setTrajectoryBank("CVT" + prefix + "::Trajectory"); + this.setKFTrajectoryBank("CVT" + prefix + "::KFTrajectory"); + super.registerOutputBank(this.bmtHitBank); + super.registerOutputBank(this.mlSeedBank); + super.registerOutputBank(this.mlTrackBank); + super.registerOutputBank(this.mlHitBank); + super.registerOutputBank(this.bmtClusterBank); + super.registerOutputBank(this.bmtCrossBank); + super.registerOutputBank(this.svtHitBank); + super.registerOutputBank(this.svtClusterBank); + super.registerOutputBank(this.svtCrossBank); + super.registerOutputBank(this.cvtSeedBank); + super.registerOutputBank(this.cvtSeedClusBank); + super.registerOutputBank(this.cvtTrackBank); + super.registerOutputBank(this.cvtUTrackBank); + super.registerOutputBank(this.cvtCovMatBank); + super.registerOutputBank(this.cvtTrajectoryBank); + super.registerOutputBank(this.cvtKFTrajectoryBank); + } + + 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; + } + + public int getPid() { + return pid; + } + + public int getKfIterations() { + return kfIterations; + } + + public boolean isKfFilterOn() { + return kfFilterOn; + } + + public boolean isInitFromMc() { + return initFromMc; + } + + public boolean seedBeamSpot() { + return this.beamSpotConstraint>0; + } + + public boolean kfBeamSpot() { + return this.beamSpotConstraint==2; + } + + /** + * @return the docacut + */ + public double getDocacut() { + return docacut; + } + + /** + * @param docacut the docacut to set + */ + public void setDocacut(double docacut) { + this.docacut = docacut; + } + + /** + * @return the docacutsum + */ + public double getDocacutsum() { + return docacutsum; + } + + /** + * @return the svtmaxclussize + */ + public int getSvtmaxclussize() { + return svtmaxclussize; + } + + /** + * @param svtmaxclussize the svtmaxclussize to set + */ + public void setSvtmaxclussize(int svtmaxclussize) { + this.svtmaxclussize = svtmaxclussize; + } + + /** + * @return the bmtcmaxclussize + */ + public int getBmtcmaxclussize() { + return bmtcmaxclussize; + } + + /** + * @param bmtcmaxclussize the bmtcmaxclussize to set + */ + public void setBmtcmaxclussize(int bmtcmaxclussize) { + this.bmtcmaxclussize = bmtcmaxclussize; + } + + /** + * @return the bmtzmaxclussize + */ + public int getBmtzmaxclussize() { + return bmtzmaxclussize; + } + + /** + * @param bmtzmaxclussize the bmtzmaxclussize to set + */ + public void setBmtzmaxclussize(int bmtzmaxclussize) { + this.bmtzmaxclussize = bmtzmaxclussize; + } + + @Override + public boolean processDataEvent(DataEvent event) { + + Swim swimmer = new Swim(); + + int run = this.getRun(event); + + 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 beamPos = this.getConstantsManager().getConstants(run, "/geometry/beam/position"); + IndexedTable adcStatus = this.getConstantsManager().getConstants(run, "/calibration/svt/adcstatus"); + + Geometry.getInstance().initialize(this.getConstantsManager().getVariation(), run, svtLorentz, bmtVoltage); + + CVTReconstruction reco = new CVTReconstruction(swimmer); + + List> hits = reco.readHits(event, svtStatus, bmtStatus, bmtTime, + bmtStripVoltage, bmtStripThreshold, + adcStatus); + List> clusters = reco.findClusters(); + for(int i = 0; i < clusters.size(); i++) { + for(int j = 0; j < clusters.get(i).size(); j++) { + double clsSize = clusters.get(i).get(j).size(); + double centroid = clusters.get(i).get(j).getCentroid(); + double seed = (double) clusters.get(i).get(j).getSeed().getStrip().getStrip(); + for(Hit h : clusters.get(i).get(j)) { + double strip = h.getStrip().getStrip(); + double cweight = 1/(1+Math.abs(strip-centroid)); + double sweight = 1/(1+Math.abs(strip-seed)); + h.setCweight(cweight); + h.setSweight(sweight); + } + } + } + List> crosses = reco.findCrosses(); + + + List banks = new ArrayList<>(); + List seeds = null; + List tracks = null; + if(crosses != null) { + if(Constants.getInstance().isCosmics) { + CosmicTracksRec trackFinder = new CosmicTracksRec(); + List seedsSt = trackFinder.getSeeds(event, clusters.get(0), clusters.get(1), crosses); + List tracksSt = trackFinder.getTracks(event, this.isInitFromMc(), + this.isKfFilterOn(), + this.getKfIterations()); + if(seedsSt!=null) banks.add(RecoBankWriter.fillStraightSeedsBank(event, seedsSt, "CVTRec::CosmicSeeds")); + if(tracksSt!=null) { + banks.add(RecoBankWriter.fillStraightTracksBank(event, tracksSt, "CVTRec::Cosmics")); + banks.add(RecoBankWriter.fillStraightTracksTrajectoryBank(event, tracksSt, "CVTRec::Trajectory")); + banks.add(RecoBankWriter.fillStraightTrackKFTrajectoryBank(event, tracksSt, "CVTRec::KFTrajectory")); + } + } + else { + double[] xyBeam = CVTReconstruction.getBeamSpot(event, beamPos); + TracksFromTargetRec trackFinder = new TracksFromTargetRec(swimmer, xyBeam); + trackFinder.totTruthHits = reco.getTotalNbTruHits(); + seeds = trackFinder.getSeeds(clusters, crosses); + + + tracks = trackFinder.getTracks(event, this.isInitFromMc(), + this.isKfFilterOn(), + this.getKfIterations(), + true, this.getPid()); + + if(seeds!=null) { + banks.add(RecoBankWriter.fillSeedBank(event, seeds, this.getSeedBank())); + banks.add(RecoBankWriter.fillSeedClusBank(event, seeds, this.getSeedClusBank())); + int bankrow=0; + for(Seed s : seeds) { + for(Cluster c: s.getClusters()) { + for(Hit h : c) { + h.setAssociatedSeedID(s.getId()); + h.setSeedBankRow(bankrow); + } + } + bankrow++; + } + } + if(tracks!=null) { + banks.add(RecoBankWriter.fillTrackBank(event, tracks, this.getTrackBank())); + // banks.add(RecoBankWriter.fillTrackCovMatBank(event, tracksSt, this.getCovMat())); + banks.add(RecoBankWriter.fillTrajectoryBank(event, tracks, this.getTrajectoryBank())); + banks.add(RecoBankWriter.fillKFTrajectoryBank(event, tracks, this.getKFTrajectoryBank())); + int bankrow2=0; + for(Track t : tracks) { + for(Cluster c: t.getSeed().getClusters()) { + for(Hit h : c) { + h.setAssociatedTrackID(t.getId()); + h.setTrackBankRow(bankrow2); + } + } + bankrow2++; + } + } + } + } + + banks.add(RecoBankWriter.fillSVTHitBank(event, hits.get(0), this.getSvtHitBank())); + banks.add(RecoBankWriter.fillBMTHitBank(event, hits.get(1), this.getBmtHitBank())); + banks.add(RecoBankWriter.fillSVTClusterBank(event, clusters.get(0), this.getSvtClusterBank())); + banks.add(RecoBankWriter.fillBMTClusterBank(event, clusters.get(1), this.getBmtClusterBank())); + banks.add(RecoBankWriter.fillSVTCrossBank(event, crosses.get(0), this.getSvtCrossBank())); + banks.add(RecoBankWriter.fillBMTCrossBank(event, crosses.get(1), this.getBmtCrossBank())); + + //ML banks + TrackingPerformance.TrackingPerformance(event, hits, seeds, tracks); + if(hits!=null) { + banks.add(BankOutput.fillHitsBank(event, hits, this.getMlHitBank())); + } + if(seeds!=null) { + banks.add(BankOutput.fillSeedsBank(event, seeds, this.getMlSeedBank())); + } + if(tracks!=null) { + banks.add(BankOutput.fillTracksBank(event, tracks, this.getMlTrackBank())); + } + + event.appendBanks(banks.toArray(new DataBank[0])); + + + return true; + } + + + public void loadConfiguration() { + + // general (pass-independent) settings + if (this.getEngineConfigString("cosmics")!=null) + this.isCosmics = Boolean.valueOf(this.getEngineConfigString("cosmics")); + + if (this.getEngineConfigString("svtOnly")!=null) + this.svtOnly = Boolean.valueOf(this.getEngineConfigString("svtOnly")); + + if (this.getEngineConfigString("excludeLayers")!=null) + this.excludeLayers = this.getEngineConfigString("excludeLayers"); + + if (this.getEngineConfigString("excludeBMTLayers")!=null) + this.excludeBMTLayers = this.getEngineConfigString("excludeBMTLayers"); + + if (this.getEngineConfigString("removeRegion")!=null) + this.removeRegion = Integer.valueOf(this.getEngineConfigString("removeRegion")); + + if (this.getEngineConfigString("beamSpotConst")!=null) + this.beamSpotConstraint = Integer.valueOf(this.getEngineConfigString("beamSpotConst")); + + if (this.getEngineConfigString("beamSpotRadius")!=null) + this.beamSpotRadius = Double.valueOf(this.getEngineConfigString("beamSpotRadius")); + + if(this.getEngineConfigString("targetMat")!=null) + this.targetMaterial = this.getEngineConfigString("targetMat"); + + if(this.getEngineConfigString("elossPreCorrection")!=null) + this.elossPrecorrection = Boolean.parseBoolean(this.getEngineConfigString("elossPreCorrection")); + + if(this.getEngineConfigString("svtSeeding")!=null) + this.svtSeeding = Boolean.parseBoolean(this.getEngineConfigString("svtSeeding")); + + if(this.getEngineConfigString("timeCuts")!=null) + this.timeCuts = Boolean.parseBoolean(this.getEngineConfigString("timeCuts")); + + if(this.getEngineConfigString("hvCuts")!=null) + this.hvCuts = Boolean.parseBoolean(this.getEngineConfigString("hvCuts")); + + if(this.getEngineConfigString("useSVTTimingCuts")!=null) + this.useSVTTimingCuts = Boolean.parseBoolean(this.getEngineConfigString("useSVTTimingCuts")); + + if(this.getEngineConfigString("removeOverlappingSeeds")!=null) + this.removeOverlappingSeeds = Boolean.parseBoolean(this.getEngineConfigString("removeOverlappingSeeds")); + + if(this.getEngineConfigString("flagSeeds")!=null) + this.flagSeeds = Boolean.parseBoolean(this.getEngineConfigString("flagSeeds")); + + if(this.getEngineConfigString("gemcIgnBMT0ADC")!=null) + this.gemcIgnBMT0ADC = Boolean.parseBoolean(this.getEngineConfigString("gemcIgnBMT0ADC")); + + if(this.getEngineConfigString("KFfailRecovery")!=null) + this.KFfailRecovery = Boolean.parseBoolean(this.getEngineConfigString("KFfailRecovery")); + + if(this.getEngineConfigString("KFfailRecovMisCls")!=null) + this.KFfailRecovMisCls = Boolean.parseBoolean(this.getEngineConfigString("KFfailRecovMisCls")); + + if (this.getEngineConfigString("matLib")!=null) + this.matrixLibrary = this.getEngineConfigString("matLib"); + + // service dependent configuration settings + if(this.getEngineConfigString("elossPid")!=null) + this.pid = Integer.parseInt(this.getEngineConfigString("elossPid")); + + if (this.getEngineConfigString("kfFilterOn")!=null) + this.kfFilterOn = Boolean.valueOf(this.getEngineConfigString("kfFilterOn")); + + if (this.getEngineConfigString("initFromMC")!=null) + this.initFromMc = Boolean.valueOf(this.getEngineConfigString("initFromMC")); + + if (this.getEngineConfigString("useOnlyTruthHits")!=null) + this.useOnlyTruth = Boolean.valueOf(this.getEngineConfigString("useOnlyTruthHits")); + + if (this.getEngineConfigString("useSVTLinkerSeeder")!=null) + this.useSVTLinkerSeeder = Boolean.valueOf(this.getEngineConfigString("useSVTLinkerSeeder")); + + if (this.getEngineConfigString("kfIterations")!=null) + this.kfIterations = Integer.valueOf(this.getEngineConfigString("kfIterations")); + + if (this.getEngineConfigString("docacut")!=null) + this.setDocacut((double) Double.valueOf(this.getEngineConfigString("docacut"))); + + if (this.getEngineConfigString("docacutsum")!=null) + this.setDocacutsum((double) Double.valueOf(this.getEngineConfigString("docacutsum"))); + + if (this.getEngineConfigString("svtmaxclussize")!=null) + this.setSvtmaxclussize((int) Integer.valueOf(this.getEngineConfigString("svtmaxclussize"))); + + if (this.getEngineConfigString("bmtcmaxclussize")!=null) + this.setBmtcmaxclussize((int) Integer.valueOf(this.getEngineConfigString("bmtcmaxclussize"))); + + if (this.getEngineConfigString("bmtzmaxclussize")!=null) + this.setBmtzmaxclussize((int) Integer.valueOf(this.getEngineConfigString("bmtzmaxclussize"))); + + if (this.getEngineConfigString("rcut")!=null) + this.rcut = Double.valueOf(this.getEngineConfigString("rcut")); + + if (this.getEngineConfigString("z0cut")!=null) + this.z0cut = Double.valueOf(this.getEngineConfigString("z0cut")); + + } + + + 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 void setSvtClusterBank(String bstClusterBank) { + this.svtClusterBank = bstClusterBank; + } + + public void setSvtCrossBank(String bstCrossBank) { + this.svtCrossBank = bstCrossBank; + } + + public void setBmtHitBank(String bmtHitBank) { + this.bmtHitBank = bmtHitBank; + } + + public void setMlHitBank(String mlHitBank) { + this.mlHitBank = mlHitBank; + } + + public void setMlSeedBank(String mlSeedBank) { + this.mlSeedBank = mlSeedBank; + } + + public void setMlTrackBank(String mlTrackBank) { + this.mlTrackBank = mlTrackBank; + } + + public void setBmtClusterBank(String bmtClusterBank) { + this.bmtClusterBank = bmtClusterBank; + } + + public void setBmtCrossBank(String bmtCrossBank) { + this.bmtCrossBank = bmtCrossBank; + } + + public void setSeedBank(String cvtSeedBank) { + this.cvtSeedBank = cvtSeedBank; + } + + public void setSeedClusBank(String cvtSeedClusBank) { + this.cvtSeedClusBank = cvtSeedClusBank; + } + + public void setTrackBank(String cvtTrackBank) { + this.cvtTrackBank = cvtTrackBank; + } + + public void setUTrackBank(String cvtTrack0Bank) { + this.cvtUTrackBank = cvtTrack0Bank; + } + + public void setTrajectoryBank(String cvtTrajectoryBank) { + this.cvtTrajectoryBank = cvtTrajectoryBank; + } + + public void setCovMatBank(String cvtTrackCovMat) { + this.cvtCovMatBank = cvtTrackCovMat; + } + + public void setKFTrajectoryBank(String cvtKFTrajectoryBank) { + this.cvtKFTrajectoryBank = cvtKFTrajectoryBank; + } + + public String getSvtHitBank() { + return svtHitBank; + } + + public String getSvtClusterBank() { + return svtClusterBank; + } + + public String getSvtCrossBank() { + return svtCrossBank; + } + + public String getBmtHitBank() { + return bmtHitBank; + } + + public String getMlHitBank() { + return this.mlHitBank; + } + + public String getMlSeedBank() { + return this.mlSeedBank; + } + + public String getMlTrackBank() { + return this.mlTrackBank; + } + public String getBmtClusterBank() { + return bmtClusterBank; + } + + public String getBmtCrossBank() { + return bmtCrossBank; + } + + public String getSeedBank() { + return cvtSeedBank; + } + + public String getSeedClusBank() { + return cvtSeedClusBank; + } + public String getTrackBank() { + return cvtTrackBank; + } + + public String getUTrackBank() { + return cvtUTrackBank; + } + + public String getTrajectoryBank() { + return cvtTrajectoryBank; + } + + public String getKFTrajectoryBank() { + return cvtKFTrajectoryBank; + } + + public String getCovMat() { + return cvtCovMatBank; + } + + + public void printConfiguration() { + + System.out.println("["+this.getName()+"] run with cosmics setting set to "+Constants.getInstance().isCosmics); + System.out.println("["+this.getName()+"] run with SVT only set to "+Constants.getInstance().svtOnly); + if(this.excludeLayers!=null) + System.out.println("["+this.getName()+"] run with layers "+this.excludeLayers+" excluded in fit, based on yaml"); + if(this.excludeBMTLayers!=null) + System.out.println("["+this.getName()+"] run with BMT layers "+this.getEngineConfigString("excludeBMTLayers")+" excluded"); + if(this.removeRegion>0) + System.out.println("["+this.getName()+"] run with region "+this.getEngineConfigString("removeRegion")+" removed"); + System.out.println("["+this.getName()+"] run with beamSpotConst set to "+Constants.getInstance().beamSpotConstraint+ " (0=no-constraint, 1=seed only, 2=seed and KF)"); + System.out.println("["+this.getName()+"] run with beam spot size set to "+Constants.getInstance().getBeamRadius()); + System.out.println("["+this.getName()+"] Target material set to "+ Constants.getInstance().getTargetType()); + System.out.println("["+this.getName()+"] Pre-Eloss correction set to " + Constants.getInstance().preElossCorrection); + System.out.println("["+this.getName()+"] run SVT-based seeding set to "+ Constants.getInstance().svtSeeding); + System.out.println("["+this.getName()+"] run BMT timing cuts set to "+ Constants.getInstance().timeCuts); + System.out.println("["+this.getName()+"] run BMT HV masks "+ Constants.getInstance().bmtHVCuts); + System.out.println("["+this.getName()+"] run with matLib "+ Constants.getInstance().KFMatrixLibrary.toString() + " library"); + System.out.println("["+this.getName()+"] ELoss mass set for particle "+ pid); + System.out.println("["+this.getName()+"] run with Kalman-Filter status set to "+this.kfFilterOn); + System.out.println("["+this.getName()+"] initialize KF from true MC information "+this.initFromMc); + System.out.println("["+this.getName()+"] number of KF iterations set to "+this.kfIterations); + System.out.println("["+this.getName()+"] SLA doca cut "+this.docacut); + System.out.println("["+this.getName()+"] SLA docasum cut "+this.docacutsum); + System.out.println("["+this.getName()+"] max svt cluster size "+this.getSvtmaxclussize()); + System.out.println("["+this.getName()+"] max bmt-c cluster size "+this.getBmtcmaxclussize()); + System.out.println("["+this.getName()+"] max btm-z cluster size "+this.getBmtzmaxclussize()); + System.out.println("["+this.getName()+"] helix radius cut (mm) "+this.rcut); + System.out.println("["+this.getName()+"] z0 cut (mm from target edges) "+this.z0cut); + + + } + + + +} 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..706af4cc2b 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 @@ -78,9 +78,26 @@ public List> readHits(DataEvent event, IndexedTable svtStatus, } } setTotalNbTruHits(totmctru); + + if(filterHits) { + //filter hits + 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 boolean filterHits=false; 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() { From f6cac3eaf00c71b99c82701607ddce43bf74f659 Mon Sep 17 00:00:00 2001 From: ziegler Date: Mon, 28 Jul 2025 14:48:18 -0400 Subject: [PATCH 2/7] CVT AI banks --- etc/bankdefs/hipo4/cvtnn.json | 104 ++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 etc/bankdefs/hipo4/cvtnn.json diff --git a/etc/bankdefs/hipo4/cvtnn.json b/etc/bankdefs/hipo4/cvtnn.json new file mode 100644 index 0000000000..6d71f044ea --- /dev/null +++ b/etc/bankdefs/hipo4/cvtnn.json @@ -0,0 +1,104 @@ +[ + { + "name": "CVTRec::MLHit", + "group": 20500, + "item" : 51, + "info": "reconstructed hits (1st pass tracking)", + "entries": [ + {"name":"id", "type":"S", "info":"id of the hit"}, + {"name":"sidx", "type":"S", "info":"row in the MLSeed bank"}, + {"name":"tidx", "type":"S", "info":"row in the MLTrack bank"}, + {"name":"rectid", "type":"S", "info":"reconstructed track id associated with the hit"}, + {"name":"recsid", "type":"S", "info":"reconstructed seed id associated with 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":"type", "type":"B", "info":"detector type: 0=SVT; 1=BMT-Z; 2=BMT-C"}, + {"name":"strip", "type":"S", "info":"strip number"}, + {"name":"order", "type":"B", "info":"order 0=MC hit-on-track; 1=noise hit"}, + {"name":"cid", "type":"S", "info":"associated cluster id"}, + {"name":"cweight", "type":"F", "info":"1/1+|difference to associated cluster centroid|"}, + {"name":"sweight", "type":"F", "info":"1/1+|normalized difference to associated cluster seed|"}, + {"name":"x1", "type":"F", "info":"geometric strip first end-point x-coordinate"}, + {"name":"y1", "type":"F", "info":"geometric strip first end-point y-coordinate"}, + {"name":"z1", "type":"F", "info":"geometric strip first end-point z-coordinate"}, + {"name":"x2", "type":"F", "info":"geometric strip second end-point x-coordinate"}, + {"name":"y2", "type":"F", "info":"geometric strip second end-point y-coordinate"}, + {"name":"z2", "type":"F", "info":"geometric strip second end-point z-coordinate"} + ] + }, + { + "name": "CVT::MLHit", + "group": 20500, + "item" : 52, + "info": "reconstructed hits (2nd pass tracking)", + "entries": [ + {"name":"id", "type":"S", "info":"id of the hit"}, + {"name":"sidx", "type":"S", "info":"row in the MLSeed bank"}, + {"name":"tidx", "type":"S", "info":"row in the MLTrack bank"}, + {"name":"rectid", "type":"S", "info":"reconstructed track id associated with the hit"}, + {"name":"recsid", "type":"S", "info":"reconstructed seed id associated with 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":"type", "type":"B", "info":"detector type: 0=SVT; 1=BMT-Z; 2=BMT-C"}, + {"name":"strip", "type":"S", "info":"strip number"}, + {"name":"order", "type":"B", "info":"order 0=MC hit-on-track; 1=noise hit"}, + {"name":"cid", "type":"S", "info":"associated cluster id"}, + {"name":"cweight", "type":"F", "info":"1/1+|normalized difference to associated cluster centroid|"}, + {"name":"sweight", "type":"F", "info":"1/1+|normalized difference to associated cluster seed|"}, + {"name":"x1", "type":"F", "info":"geometric strip first end-point x-coordinate"}, + {"name":"y1", "type":"F", "info":"geometric strip first end-point y-coordinate"}, + {"name":"z1", "type":"F", "info":"geometric strip first end-point z-coordinate"}, + {"name":"x2", "type":"F", "info":"geometric strip second end-point x-coordinate"}, + {"name":"y2", "type":"F", "info":"geometric strip second end-point y-coordinate"}, + {"name":"z2", "type":"F", "info":"geometric strip second end-point z-coordinate"} + ] + }, + { + "name": "CVTRec::MLSeed", + "group": 20500, + "item" : 61, + "info": "reconstructed seeds (1st pass tracking)", + "entries": [ + {"name":"id", "type":"S", "info":"id of the seed"}, + {"name":"purity", "type":"F", "info":"seed purity: Nb of reconstructed true hits in seed / total hits on seed"}, + {"name":"efficiency", "type":"F", "info":"seed purity: Nb of reconstructed true hits in seed / MC hits in gemerated track"} + ] + }, + { + "name": "CVTRec::MLTrack", + "group": 20500, + "item" : 62, + "info": "reconstructed seeds (1st pass tracking)", + "entries": [ + {"name":"id", "type":"S", "info":"id of the seed"}, + {"name":"purity", "type":"F", "info":"seed purity: Nb of reconstructed true hits in track / total hits on track"}, + {"name":"efficiency", "type":"F", "info":"seed purity: Nb of reconstructed true hits in track / MC hits in gemerated track"} + ] + }, + { + "name": "CVT::MLSeed", + "group": 20500, + "item" : 63, + "info": "reconstructed seeds (2nd pass tracking)", + "entries": [ + {"name":"id", "type":"S", "info":"id of the track"}, + {"name":"purity", "type":"F", "info":"seed purity: Nb of reconstructed true hits in seed / total hits on seed"}, + {"name":"efficiency", "type":"F", "info":"seed purity: Nb of reconstructed true hits in seed / MC hits in gemerated track"} + ] + }, + { + "name": "CVT::MLTrack", + "group": 20500, + "item" : 64, + "info": "reconstructed seeds (2nd pass tracking)", + "entries": [ + {"name":"id", "type":"S", "info":"id of the track"}, + {"name":"purity", "type":"F", "info":"seed purity: Nb of reconstructed true hits in track / total hits on track"}, + {"name":"efficiency", "type":"F", "info":"seed purity: Nb of reconstructed true hits in track / MC hits in gemerated track"} + ] + } + + +] From 1b613b4c67b6dcedc2d0651ad4dc148506210e71 Mon Sep 17 00:00:00 2001 From: ziegler Date: Mon, 28 Jul 2025 14:58:27 -0400 Subject: [PATCH 3/7] added services to create ML samples. --- etc/services/mc-mlcvt.yaml | 27 +++++++++++++++++++++++++++ etc/services/mc-mlcvtfilter.yaml | 27 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 etc/services/mc-mlcvt.yaml create mode 100644 etc/services/mc-mlcvtfilter.yaml diff --git a/etc/services/mc-mlcvt.yaml b/etc/services/mc-mlcvt.yaml new file mode 100644 index 0000000000..744a9d596c --- /dev/null +++ b/etc/services/mc-mlcvt.yaml @@ -0,0 +1,27 @@ +io-services: + reader: + class: org.jlab.io.clara.HipoToHipoReader + name: HipoToHipoReader + writer: + class: org.jlab.io.clara.HipoToHipoWriter + name: HipoToHipoWriter +services: + - class: org.jlab.clas.swimtools.MagFieldsEngine + name: MAGFIELDS + - class: org.jlab.rec.cvt.ml.SampleMaker + name: CVTFP +configuration: + global: + variation: rga_fall2018_bg +# dcMinistagger: "NOTONREFWIRE" +# dcFeedthroughs: "OFF" +# io-services: +# writer: +# schema_dir: "absolute-path-to-schema-folder" + 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/etc/services/mc-mlcvtfilter.yaml b/etc/services/mc-mlcvtfilter.yaml new file mode 100644 index 0000000000..0c3cfc7b3f --- /dev/null +++ b/etc/services/mc-mlcvtfilter.yaml @@ -0,0 +1,27 @@ +io-services: + reader: + class: org.jlab.io.clara.HipoToHipoReader + name: HipoToHipoReader + writer: + class: org.jlab.io.clara.HipoToHipoWriter + name: HipoToHipoWriter +services: + - class: org.jlab.clas.swimtools.MagFieldsEngine + name: MAGFIELDS + - class: org.jlab.rec.cvt.ml.CVTFilter + name: CVTFP +configuration: + global: + variation: rga_fall2018_bg +# dcMinistagger: "NOTONREFWIRE" +# dcFeedthroughs: "OFF" +# io-services: +# writer: +# schema_dir: "absolute-path-to-schema-folder" + services: + MAGFIELDS: + magfieldSolenoidMap: Symm_solenoid_r601_phi1_z1201_13June2018.dat + magfieldTorusMap: Symm_torus_r2501_phi16_z251_24Apr2018.dat + +mime-types: + - binary/data-hipo From 213833b4de9afb364e1e41eb906eebb293939370 Mon Sep 17 00:00:00 2001 From: ziegler Date: Thu, 2 Apr 2026 14:19:07 -0400 Subject: [PATCH 4/7] Branch for DCDDAT project. Contains a service that creates hits with geometry information bank and a bank viewer. --- .../main/java/org/jlab/rec/cvt/Constants.java | 2 +- .../org/jlab/rec/cvt/banks/HitReader.java | 9 +- .../org/jlab/rec/cvt/ml/qcddat/Browser.java | 26 + .../jlab/rec/cvt/ml/qcddat/SampleMaker.java | 202 ++++++ .../org/jlab/rec/cvt/ml/qcddat/Viewer.java | 610 ++++++++++++++++++ 5 files changed, 845 insertions(+), 4 deletions(-) create mode 100644 reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/qcddat/Browser.java create mode 100644 reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/qcddat/SampleMaker.java create mode 100644 reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/qcddat/Viewer.java 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..77382c2d1e 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 QDCDATSample=true; // 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..f7765251c2 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 @@ -133,11 +133,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().QDCDATSample) { 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().QDCDATSample) { 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 +301,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().QDCDATSample) { if(this.passTimingCuts(ADC, time)==false) continue; } diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/qcddat/Browser.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/qcddat/Browser.java new file mode 100644 index 0000000000..91eca7c8ec --- /dev/null +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/qcddat/Browser.java @@ -0,0 +1,26 @@ +/* + * 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.qcddat; + +import javafx.application.Application; +/** + * + * @author veronique + */ +public class Browser { + + 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]; + + Viewer.configure(inputFile); + Application.launch(Viewer.class); + } +} \ No newline at end of file diff --git a/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/qcddat/SampleMaker.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/qcddat/SampleMaker.java new file mode 100644 index 0000000000..588473489b --- /dev/null +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/qcddat/SampleMaker.java @@ -0,0 +1,202 @@ +package org.jlab.rec.cvt.ml.qcddat; + +import 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 SampleMaker extends ReconstructionEngine { + + + private int Run = -1; + + private String svtHitBank; + + public SampleMaker(String name) { + super(name, "ziegler", "6.0"); + } + + public SampleMaker() { + super("CVTQCDDATEngine", "ziegler", "6.0"); + } + + + @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 processDataEvent(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/qcddat/Viewer.java b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/qcddat/Viewer.java new file mode 100644 index 0000000000..d485c7f4e4 --- /dev/null +++ b/reconstruction/cvt/src/main/java/org/jlab/rec/cvt/ml/qcddat/Viewer.java @@ -0,0 +1,610 @@ +package org.jlab.rec.cvt.ml.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 Viewer 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.rec.cvt.ml.qcddat.Viewer "); + System.exit(1); + } + configure(args[0]); + launch(args); + } + + // ---------- bounded cache ---------- + private static final int MAX_CACHE_SIZE = 200; + + 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 showSVT; + private CheckBox showBMTC; + private CheckBox showBMTZ; + + 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 mctrue; + + HitPoint(double x, double y, double z, DetectorKind kind, int loc, int mct) { + this.x = x; + this.y = y; + this.z = z; + this.kind = kind; + this.pointloc = loc; + this.mctrue = mct; + } + } + + @Override + public void start(Stage stage) { + if (inputFile == null || bankName == null) { + throw new IllegalStateException("Viewer.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.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() { + 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)) { + 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 VBox buildLegendPane() { + 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 help = new Label( + "Mouse drag: rotate\n" + + "Scroll: zoom\n" + + "N / Right arrow: next\n" + + "P / Left arrow: previous\n" + + "R: reset view" + ); + help.setWrapText(true); + + VBox box = new VBox( + 8, + legendTitle, + showSVT, svtColor, + showBMTC, cColor, + showBMTZ, zColor, + new Separator(), + locTitle, + showLoc1, + showLoc2, + showLoc3, + new Separator(), + help + ); + box.setPadding(new Insets(12)); + box.setPrefWidth(220); + box.setStyle("-fx-background-color: #f7f7f7;"); + return box; + } + + private Label coloredLabel(String text) { + Label lbl = new Label(text); + lbl.setStyle("-fx-font-weight: bold;"); + return lbl; + } + + private void enableMouseControls(SubScene scene) { + scene.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> { + 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 List extractAllThreePoints(DataBank bank) { + List out = new ArrayList<>(); + + for (int i = 0; i < bank.rows(); i++) { + int layer = bank.getByte("layer", 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, mct + )); + + out.add(new HitPoint( + bank.getFloat("x2", i), + bank.getFloat("y2", i), + bank.getFloat("z2", i), + kind, 2, mct + )); + + out.add(new HitPoint( + bank.getFloat("x3", i), + bank.getFloat("y3", i), + bank.getFloat("z3", i), + kind, 3, 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; + }; + } +} \ No newline at end of file From e7cd4093a5dbe12af08ff61af3a55705685720bb Mon Sep 17 00:00:00 2001 From: ziegler Date: Thu, 2 Apr 2026 14:21:24 -0400 Subject: [PATCH 5/7] QCDDAT display launcher script --- bin/run_cvt_viewer.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100755 bin/run_cvt_viewer.sh diff --git a/bin/run_cvt_viewer.sh b/bin/run_cvt_viewer.sh new file mode 100755 index 0000000000..ba94490b63 --- /dev/null +++ b/bin/run_cvt_viewer.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +set -euo pipefail + +INPUT_FILE="$1" + +if [ -z "$INPUT_FILE" ] ; then + echo "Usage: ./run_bank_browser.sh " + echo "Example: ./run_bank_browser.sh data.hipo " + exit 1 +fi + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" +PROJECT_DIR="$REPO_DIR/reconstruction/cvt" +POM_FILE="$PROJECT_DIR/pom.xml" + +if [ ! -f "$POM_FILE" ]; then + echo "ERROR: No pom.xml found at $POM_FILE" + exit 2 +fi + +INPUT_ABS="$(cd "$(dirname "$INPUT_FILE")" && pwd)/$(basename "$INPUT_FILE")" + +if [ ! -f "$INPUT_ABS" ]; then + echo "ERROR: Input file not found: $INPUT_FILE" + exit 3 +fi + +mvn -f "$POM_FILE" -q exec:java \ + -Dexec.mainClass="org.jlab.rec.cvt.ml.qcddat.Browser" \ + -Dexec.args="$INPUT_ABS" + From eb2ef6563b017f9e1550cd714ff981afaf192c28 Mon Sep 17 00:00:00 2001 From: ziegler Date: Thu, 2 Apr 2026 14:24:15 -0400 Subject: [PATCH 6/7] QCDDAT hits bankdefs added QCDDAT hits service yaml file --- etc/bankdefs/hipo4/cvtqcddat.json | 27 +++++++++++++++++++++++++++ etc/services/mc-qcddat.yaml | 27 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 etc/bankdefs/hipo4/cvtqcddat.json create mode 100644 etc/services/mc-qcddat.yaml 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..307d017d2f --- /dev/null +++ b/etc/services/mc-qcddat.yaml @@ -0,0 +1,27 @@ +io-services: + reader: + class: org.jlab.io.clara.HipoToHipoReader + name: HipoToHipoReader + writer: + class: org.jlab.io.clara.HipoToHipoWriter + name: HipoToHipoWriter +services: + - class: org.jlab.clas.swimtools.MagFieldsEngine + name: MAGFIELDS + - class: org.jlab.rec.cvt.ml.qcddat.SampleMaker + name: CVTFP +configuration: + global: + variation: rga_fall2018_bg +# dcMinistagger: "NOTONREFWIRE" +# dcFeedthroughs: "OFF" +# io-services: +# writer: +# schema_dir: "absolute-path-to-schema-folder" + services: + MAGFIELDS: + magfieldSolenoidMap: Symm_solenoid_r601_phi1_z1201_13June2018.dat + magfieldTorusMap: Symm_torus_r2501_phi16_z251_24Apr2018.dat + +mime-types: + - binary/data-hipo From 507e1075db923a5686546d2042d3680a6500e5bc Mon Sep 17 00:00:00 2001 From: ziegler Date: Mon, 13 Apr 2026 14:36:25 -0400 Subject: [PATCH 7/7] Fix to get the status of the BMT raw hits for MC --- .../cvt/src/main/java/org/jlab/rec/cvt/banks/HitReader.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 f7765251c2..4f2321af17 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().QDCDATSample) { + order = bankDGTZ.trueOrder(i); + } //if (order == 1) { // continue; //}