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"}
+ ]
+ }
+
+
+]
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
diff --git a/reconstruction/cvt/pom.xml b/reconstruction/cvt/pom.xml
index 2516e9eb29..4ab19b4992 100644
--- a/reconstruction/cvt/pom.xml
+++ b/reconstruction/cvt/pom.xml
@@ -95,6 +95,10 @@
junit
junit
+
+ org.jlab.jnp
+ jnp-hipo4
+
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