diff --git a/CODEOWNERS b/CODEOWNERS
index 4e5bf0dddb..15c8aeae9a 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -86,6 +86,7 @@ reconstruction/swaps/ @baltzell @raffaelladevita
reconstruction/tof/ @zieglerv @raffaelladevita
reconstruction/urwell/ @raffaelladevita @tongtongcao
reconstruction/vtx/ @zieglerv
+reconstruction/calib/ @raffaelladevita
# etc
etc/bankdefs/ @baltzell @raffaelladevita @c-dilks
diff --git a/etc/bankdefs/hipo4/dc.json b/etc/bankdefs/hipo4/dc.json
index 53852e00b3..4558300006 100644
--- a/etc/bankdefs/hipo4/dc.json
+++ b/etc/bankdefs/hipo4/dc.json
@@ -580,6 +580,43 @@
{"name":"dx", "type":"F", "info":"pathlength of the track through the detector element (cm)"},
{"name":"edge", "type":"F", "info":"distance to the closest detector edge (cm), -1 if edge is not defined, 0 if outside, >0 if inside"}
]
+ },
+ {
+ "name": "DC::calib",
+ "group": 20600,
+ "item" : 55,
+ "info": "reconstructed hits using DC timing information",
+ "entries": [
+ {"name":"id", "type":"S", "info":"id of the hit"},
+ {"name":"status", "type":"S", "info":"id of the hit"},
+ {"name":"sector", "type":"B", "info":"DC sector"},
+ {"name":"superlayer", "type":"B", "info":"DC superlayer (1...6)"},
+ {"name":"layer", "type":"B", "info":"DC layer in superlayer (1...6)"},
+ {"name":"wire", "type":"S", "info":"wire id of DC"},
+ {"name":"TDC", "type":"I", "info":"raw time of the hit"},
+ {"name":"jitter", "type":"B", "info":"time jitter (ns)"},
+ {"name":"doca", "type":"F", "info":"doca of the hit calculated from TDC (in cm)"},
+ {"name":"docaError", "type":"F", "info":"uncertainty on doca of the hit calculated from TDC (in cm)"},
+ {"name":"trkDoca", "type":"F", "info":"track doca of the hit (in cm)"},
+ {"name":"timeResidual", "type":"F", "info":"time residual of the hit (in cm)"},
+ {"name":"fitResidual", "type":"F", "info":"fit residual of the hit (in cm, from KF)"},
+ {"name":"DAFWeight", "type":"F", "info":"Weight by DAF; the 1st bit of status indicates that a hit is belong to single or double"},
+ {"name":"LR", "type":"B", "info":"Left/Right ambiguity of the hit"},
+ {"name":"X", "type":"F", "info":"wire x-coordinate in tilted-sector"},
+ {"name":"Z", "type":"F", "info":"wire z-coordinate in tilted-sector"},
+ {"name":"B", "type":"F", "info":"B-field intensity at hit position in tilted-sector system"},
+ {"name":"Alpha", "type":"F", "info":"local angle (degr.) in tilted-sector system"},
+ {"name":"TProp", "type":"F", "info":"t propagation along the wire (ns)"},
+ {"name":"TFlight", "type":"F", "info":"time of flight correction (ns)"},
+ {"name":"T0", "type":"F", "info":"T0 (ns)"},
+ {"name":"TStart", "type":"F", "info":"event start time used (ns)"},
+ {"name":"dDoca", "type":"F", "info":"delta Doca correction (cm)"},
+ {"name":"clusterID", "type":"S", "info":"ID of associated cluster"},
+ {"name":"trkID", "type":"B", "info":"ID of associated track"},
+ {"name":"time", "type":"F", "info":"time used in tracking (ns)"},
+ {"name":"beta", "type":"F", "info":"beta used in tracking"},
+ {"name":"tBeta", "type":"F", "info":"beta-dependent time correction used in tracking"}
+ ]
}
]
diff --git a/etc/bankdefs/hipo4/rich.json b/etc/bankdefs/hipo4/rich.json
index bb92d867dc..8b5a57415d 100644
--- a/etc/bankdefs/hipo4/rich.json
+++ b/etc/bankdefs/hipo4/rich.json
@@ -220,5 +220,47 @@
{"name":"best_ntot", "type":"F", "info":"Number of photon used for likelihood"},
{"name":"best_mass", "type":"F", "info":"Reconstructed mass for best hypothesis"}
]
+ },
+ {
+ "name": "RICH::calib",
+ "group": 21800,
+ "item" : 51,
+ "info": "Reconstructed Photons in RICH selected for detector calibration",
+ "entries": [
+ {"name":"hindex", "type":"S", "info":"related row in the RICH::hits bank"},
+ {"name":"pindex", "type":"B", "info":"related row in the REC::Particle bank"},
+ {"name":"sector", "type":"B", "info":"Hit sector"},
+ {"name":"pmt", "type":"S", "info":"Hit pmt" },
+ {"name":"anode", "type":"S", "info":"Hit anode" },
+ {"name":"x", "type":"F", "info":"Hit x" },
+ {"name":"y", "type":"F", "info":"Hit y" },
+ {"name":"z", "type":"F", "info":"Hit z" },
+ {"name":"time", "type":"F", "info":"Hit time" },
+ {"name":"rawtime", "type":"F", "info":"Hit rawtime" },
+ {"name":"duration", "type":"S", "info":"Hit duration" },
+ {"name":"status", "type":"S", "info":"Hit status" },
+ {"name":"used", "type":"B", "info":"eligible for PID in time (1=yes, 0=no) angle (10=yes, 0=no) hypo (100=by other) or cluster (2)"},
+ {"name":"emilay", "type":"B", "info":"aerogel layer of photon emission"},
+ {"name":"emico", "type":"B", "info":"aerogel component of photon emission"},
+ {"name":"enico", "type":"B", "info":"aerogel component of photon entrance point"},
+ {"name":"emqua", "type":"S", "info":"aerogel quadrant of photon emission"},
+ {"name":"start_time", "type":"F", "info":"time at photon emission point"},
+ {"name":"traced_the", "type":"F", "info":"Lab theta angle for traced solution"},
+ {"name":"traced_phi", "type":"F", "info":"Lab phi angle for traced solution"},
+ {"name":"traced_hitx", "type":"F", "info":"Lab hitx angle for traced solution"},
+ {"name":"traced_hity", "type":"F", "info":"Lab hity angle for traced solution"},
+ {"name":"traced_hitz", "type":"F", "info":"Lab hitz angle for traced solution"},
+ {"name":"traced_path", "type":"F", "info":"path for traced solution"},
+ {"name":"traced_time", "type":"F", "info":"time for traced solution"},
+ {"name":"traced_nrfl", "type":"S", "info":"n reflections for traced solution"},
+ {"name":"traced_nrfr", "type":"S", "info":"n refractions for traced solution"},
+ {"name":"traced_1rfl", "type":"S", "info":"first reflection type for traced solution"},
+ {"name":"traced_layers", "type":"I", "info":"sequence of hit layers (reflections)"},
+ {"name":"traced_compos", "type":"I", "info":"sequence of hit components (reflections)"},
+ {"name":"traced_etaC", "type":"F", "info":"etaC angle for traced solution" },
+ {"name":"etac_ref", "type":"F", "info":"Cherenkov angle expected value"},
+ {"name":"etac_rms", "type":"F", "info":"Cherenkov angle expected resolution"},
+ {"name":"prob", "type":"F", "info":"probability for traced solution with given hypo"}
+ ]
}
]
diff --git a/etc/bankdefs/hipo4/tof.json b/etc/bankdefs/hipo4/tof.json
index d59609e816..6cc8001915 100644
--- a/etc/bankdefs/hipo4/tof.json
+++ b/etc/bankdefs/hipo4/tof.json
@@ -151,7 +151,45 @@
{"name":"midbarAlgo_1B_tCorr", "type":"F", "info":"corrected hit time using middle of bar algorithm to compute the path length between 1A and 1B"},
{"name":"EmaxAlgo_1B_tCorr", "type":"F", "info":"corrected hit time using Emax algorithm to compute the path length between 1A and 1B"} ]
},
-
+ {
+ "name": "FTOF::calib",
+ "group": 21200,
+ "item" : 35,
+ "info": "reconstructed hit info from FTOF calibration",
+ "entries": [
+ {"name":"id", "type":"S", "info":"id of the hit"},
+ {"name":"status", "type":"S", "info":"hit status defined based on presence (0) or absence (1) of TDCR-TDCL-ADCR-ADCL"},
+ {"name":"trackid", "type":"S", "info":"matched DC track id"},
+ {"name":"sector", "type":"B", "info":"sector of FTOF"},
+ {"name":"layer", "type":"B", "info":"panel id of FTOF (1-1A, 2-1B, 3-2"},
+ {"name":"component", "type":"S", "info":"paddle id of FTOF"},
+ {"name":"energy", "type":"F", "info":"E dep (MeV) of hit"},
+ {"name":"time", "type":"F", "info":"Hit time (ns)"},
+ {"name":"x", "type":"F", "info":"Global X coor (cm) of hit"},
+ {"name":"y", "type":"F", "info":"Global Y coor (cm) of hit"},
+ {"name":"z", "type":"F", "info":"Global Z coor (cm) of hit"},
+ {"name":"tx", "type":"F", "info":"Global X coor (cm) of hit from DC info - trackid index"},
+ {"name":"ty", "type":"F", "info":"Global Y coor (cm) of hit from DC info - trackid index"},
+ {"name":"tz", "type":"F", "info":"Global Z coor (cm) of hit from DC info - trackid index"},
+ {"name":"adc1", "type":"I", "info":"ADCL"},
+ {"name":"adc2", "type":"I", "info":"ADCR"},
+ {"name":"tdc1", "type":"I", "info":"TDCL"},
+ {"name":"tdc2", "type":"I", "info":"TDCR"},
+ {"name":"pindex", "type":"S", "info":"particle positionin REC::Particle"},
+ {"name":"pid", "type":"I", "info":"particle id"},
+ {"name":"charge", "type":"B", "info":"particle charge"},
+ {"name":"px", "type":"F", "info":"particle momentum x component"},
+ {"name":"py", "type":"F", "info":"particle momentum y component"},
+ {"name":"pz", "type":"F", "info":"particle momentum z component"},
+ {"name":"vx", "type":"F", "info":"particle vertex x coordinate"},
+ {"name":"vy", "type":"F", "info":"particle vertex y coordinate"},
+ {"name":"vz", "type":"F", "info":"particle vertex z coordinate"},
+ {"name":"chi2", "type":"F", "info":"track chi2"},
+ {"name":"NDF", "type":"S", "info":"NDF"},
+ {"name":"pathLength", "type":"F", "info":"pathlength of the track from the vertex (doca point to the beamline to the midpoint between the entrance and exit of the hit bar"},
+ {"name":"pathLengthThruBar", "type":"F", "info":"pathlength of the track from the entrance point to the exit point through the hit bar "}
+ ]
+ },
{
"name": "CTOF::rawhits",
"group": 20400,
@@ -228,6 +266,43 @@
{"name":"z", "type":"F", "info":"Global Z coor (cm) of cluster seed"},
{"name":"pathLengthThruBar", "type":"F", "info":"pathlength of the track from the entrance point to the exit point through the cluster bars "}
]
- }
-
+ },
+ {
+ "name": "CTOF::calib",
+ "group": 20400,
+ "item" : 25,
+ "info": "reconstructed hit info from CTOF calibration",
+ "entries": [
+ {"name":"id", "type":"S", "info":"id of the hit"},
+ {"name":"status", "type":"S", "info":"hit status defined based on presence (0) or absence (1) of TDCR-TDCL-ADCR-ADCL"},
+ {"name":"trackid", "type":"S", "info":"matched DC track id"},
+ {"name":"component", "type":"S", "info":"paddle id of CTOF"},
+ {"name":"energy", "type":"F", "info":"E dep (MeV) of hit"},
+ {"name":"time", "type":"F", "info":"Hit time (ns)"},
+ {"name":"x", "type":"F", "info":"Global X coor (cm) of hit"},
+ {"name":"y", "type":"F", "info":"Global Y coor (cm) of hit"},
+ {"name":"z", "type":"F", "info":"Global Z coor (cm) of hit"},
+ {"name":"tx", "type":"F", "info":"Global X coor (cm) of hit from DC info - trackid index"},
+ {"name":"ty", "type":"F", "info":"Global Y coor (cm) of hit from DC info - trackid index"},
+ {"name":"tz", "type":"F", "info":"Global Z coor (cm) of hit from DC info - trackid index"},
+ {"name":"adc1", "type":"I", "info":"ADCL"},
+ {"name":"adc2", "type":"I", "info":"ADCR"},
+ {"name":"tdc1", "type":"I", "info":"TDCL"},
+ {"name":"tdc2", "type":"I", "info":"TDCR"},
+ {"name":"pindex", "type":"S", "info":"particle positionin REC::Particle"},
+ {"name":"pid", "type":"I", "info":"particle id"},
+ {"name":"charge", "type":"B", "info":"particle charge"},
+ {"name":"px", "type":"F", "info":"particle momentum x component"},
+ {"name":"py", "type":"F", "info":"particle momentum y component"},
+ {"name":"pz", "type":"F", "info":"particle momentum z component"},
+ {"name":"vx", "type":"F", "info":"particle vertex x coordinate"},
+ {"name":"vy", "type":"F", "info":"particle vertex y coordinate"},
+ {"name":"vz", "type":"F", "info":"particle vertex z coordinate"},
+ {"name":"vt", "type":"F", "info":"vertex-corrected event start time" },
+ {"name":"chi2", "type":"F", "info":"track chi2"},
+ {"name":"NDF", "type":"S", "info":"NDF"},
+ {"name":"pathLength", "type":"F", "info":"pathlength of the track from the vertex (doca point to the beamline to the midpoint between the entrance and exit of the hit bar"},
+ {"name":"pathLengthThruBar", "type":"F", "info":"pathlength of the track from the entrance point to the exit point through the hit bar "}
+ ]
+ }
]
diff --git a/etc/bankdefs/util/bankSplit.py b/etc/bankdefs/util/bankSplit.py
index cb869f80c5..37d8e3f363 100755
--- a/etc/bankdefs/util/bankSplit.py
+++ b/etc/bankdefs/util/bankSplit.py
@@ -69,10 +69,10 @@ def create(dirname, banklist):
dets = band + raster + rich + rtpc + alert
# additions for the calibration schema:
-calib = ["BAND::adc","BAND::laser","BAND::tdc","BAND::hits","BAND::rawhits","CND::adc","CND::hits","CND::tdc","CTOF::adc","CTOF::hits","CTOF::tdc","CVTRec::Tracks","CVTRec::UTracks","ECAL::adc","ECAL::calib","ECAL::clusters","ECAL::peaks","ECAL::tdc","FMT::Hits","FMT::Clusters","FMT::Tracks","FMT::Trajectory","FT::particles","FTCAL::adc","FTCAL::clusters","FTCAL::hits","FTHODO::adc","FTHODO::clusters","FTHODO::hits","FTTRK::clusters","FTTRK::hits","FTTRK::crosses","FTOF::adc","FTOF::hits","FTOF::tdc","HTCC::adc","HTCC::rec","LTCC::adc","LTCC::clusters","RASTER::adc","RF::adc","RF::tdc","RICH::tdc","RICH::Hit","RICH::Particle","RICH::Hadron","RICH::Photon","RICH::Ring","RTPC::adc","RTPC::hits","RTPC::tracks","RUN::rf","RUN::trigger","TimeBasedTrkg::TBHits","TimeBasedTrkg::TBTracks"]
+calib = ["BAND::adc","BAND::laser","BAND::tdc","BAND::hits","BAND::rawhits","CND::adc","CND::hits","CND::tdc","CTOF::calib","CVTRec::Tracks","CVTRec::UTracks","DC::calib","ECAL::adc","ECAL::calib","ECAL::clusters","ECAL::peaks","ECAL::tdc","FMT::Hits","FMT::Clusters","FMT::Tracks","FMT::Trajectory","FT::particles","FTCAL::adc","FTCAL::clusters","FTCAL::hits","FTHODO::adc","FTHODO::clusters","FTHODO::hits","FTTRK::clusters","FTTRK::hits","FTTRK::crosses","FTOF::adc","FTOF::calib","HTCC::adc","HTCC::rec","LTCC::adc","LTCC::clusters","RASTER::adc","RF::adc","RF::tdc","RICH::calib","RTPC::adc","RTPC::hits","RTPC::tracks","RUN::rf","RUN::trigger","TimeBasedTrkg::TBTracks"]
# additions for the monitoring schema:
-mon = ["BMT::adc","BMTRec::Clusters","BMTRec::Crosses","BMTRec::Hits","BMTRec::LayerEffs","BST::adc","BSTRec::Clusters","BSTRec::Crosses","BSTRec::Hits","BSTRec::LayerEffs","CND::clusters","CVTRec::Trajectory","ECAL::hits","FMT::adc","FTTRK::adc","HEL::adc","HitBasedTrkg::HBTracks","RAW::vtp","TimeBasedTrkg::TBCrosses","TimeBasedTrkg::TBSegments","TimeBasedTrkg::TBSegmentTrajectory","TimeBasedTrkg::Trajectory"]
+mon = ["BMT::adc","BMTRec::Clusters","BMTRec::Crosses","BMTRec::Hits","BMTRec::LayerEffs","BST::adc","BSTRec::Clusters","BSTRec::Crosses","BSTRec::Hits","BSTRec::LayerEffs","CND::clusters","CTOF::adc","CTOF::hits","CTOF::tdc","CVTRec::Trajectory","ECAL::hits","FMT::adc","FTTRK::adc","FTOF::adc","FTOF::hits","FTOF::tdc","HEL::adc","HitBasedTrkg::HBTracks","RAW::vtp","RICH::Particle","RICH::Ring","TimeBasedTrkg::TBCrosses","TimeBasedTrkg::TBHits","TimeBasedTrkg::TBSegments","TimeBasedTrkg::TBSegmentTrajectory","TimeBasedTrkg::Trajectory"]
# trigger validation needs these:
trig = ["RAW::vtp","HTCC::rec","ECAL::adc","ECAL::calib","ECAL::clusters","ECAL::hits","ECAL::moments","ECAL::peaks","ECAL::tdc","ECAL::trigger"]
diff --git a/etc/services/data-ai.yaml b/etc/services/data-ai.yaml
index 87dfb05f7c..46daa569c3 100644
--- a/etc/services/data-ai.yaml
+++ b/etc/services/data-ai.yaml
@@ -61,6 +61,8 @@ services:
name: RTPC
- class: org.jlab.rec.service.vtx.VTXEngine
name: VTX
+ - class: org.jlab.calibration.service.CalibBanksEngine
+ name: CALIB
configuration:
global:
variation: rgb_spring2019
diff --git a/etc/services/data-aicv.yaml b/etc/services/data-aicv.yaml
index 2014375db7..8516df30e3 100644
--- a/etc/services/data-aicv.yaml
+++ b/etc/services/data-aicv.yaml
@@ -72,6 +72,8 @@ services:
name: RTPC
- class: org.jlab.rec.service.vtx.VTXEngine
name: VTX
+ - class: org.jlab.calibration.service.CalibBanksEngine
+ name: CALIB
configuration:
global:
variation: rgb_spring2019
diff --git a/etc/services/data-cv.yaml b/etc/services/data-cv.yaml
index ec5d6a7599..00554281fd 100644
--- a/etc/services/data-cv.yaml
+++ b/etc/services/data-cv.yaml
@@ -59,6 +59,8 @@ services:
name: RTPC
- class: org.jlab.rec.service.vtx.VTXEngine
name: VTX
+ - class: org.jlab.calibration.service.CalibBanksEngine
+ name: CALIB
configuration:
global:
variation: rgb_spring2019
diff --git a/etc/services/dcalign.yaml b/etc/services/dcalign.yaml
index 2e90ebe9ac..692d3083a1 100644
--- a/etc/services/dcalign.yaml
+++ b/etc/services/dcalign.yaml
@@ -51,6 +51,8 @@ services:
name: RICH
- class: org.jlab.service.rtpc.RTPCEngine
name: RTPC
+ - class: org.jlab.calibration.service.CalibBanksEngine
+ name: CALIB
configuration:
global:
variation: rgb_spring2019
diff --git a/etc/services/denoise.yaml b/etc/services/denoise.yaml
index 97d1c8d89d..0c98be66a5 100644
--- a/etc/services/denoise.yaml
+++ b/etc/services/denoise.yaml
@@ -74,6 +74,8 @@ services:
name: RICH
- class: org.jlab.service.rtpc.RTPCEngine
name: RTPC
+ - class: org.jlab.calibration.service.CalibBanksEngine
+ name: CALIB
configuration:
global:
variation: rgb_spring2019
diff --git a/etc/services/kpp.yaml b/etc/services/kpp.yaml
index ce9d4a7298..d56b4f905f 100644
--- a/etc/services/kpp.yaml
+++ b/etc/services/kpp.yaml
@@ -70,6 +70,8 @@ services:
name: RICH
- class: org.jlab.service.rtpc.RTPCEngine
name: RTPC
+ - class: org.jlab.calibration.service.CalibBanksEngine
+ name: CALIB
configuration:
services:
MAGFIELDS:
diff --git a/etc/services/mc-ai.yaml b/etc/services/mc-ai.yaml
index fed6688c01..8412fc9a15 100644
--- a/etc/services/mc-ai.yaml
+++ b/etc/services/mc-ai.yaml
@@ -61,6 +61,8 @@ services:
name: RTPC
- class: org.jlab.rec.service.vtx.VTXEngine
name: VTX
+ - class: org.jlab.calibration.service.CalibBanksEngine
+ name: CALIB
configuration:
# global:
# variation: rga_fall2018_mc
diff --git a/etc/services/mc-aicv.yaml b/etc/services/mc-aicv.yaml
index bcbb864a6b..d86b4549d2 100644
--- a/etc/services/mc-aicv.yaml
+++ b/etc/services/mc-aicv.yaml
@@ -72,6 +72,8 @@ services:
name: RTPC
- class: org.jlab.rec.service.vtx.VTXEngine
name: VTX
+ - class: org.jlab.calibration.service.CalibBanksEngine
+ name: CALIB
configuration:
# global:
# variation: rga_fall2018_mc
diff --git a/etc/services/mc-cv.yaml b/etc/services/mc-cv.yaml
index a7ec84aed3..d3294abc34 100644
--- a/etc/services/mc-cv.yaml
+++ b/etc/services/mc-cv.yaml
@@ -59,6 +59,8 @@ services:
name: RTPC
- class: org.jlab.rec.service.vtx.VTXEngine
name: VTX
+ - class: org.jlab.calibration.service.CalibBanksEngine
+ name: CALIB
configuration:
# global:
# variation: rga_fall2018_mc
diff --git a/reconstruction/calib/pom.xml b/reconstruction/calib/pom.xml
new file mode 100644
index 0000000000..dbe1b9e768
--- /dev/null
+++ b/reconstruction/calib/pom.xml
@@ -0,0 +1,39 @@
+
+
+ 4.0.0
+
+ org.jlab.clas12.detector
+ clas12detector-calib
+ 13.1.0-SNAPSHOT
+ jar
+
+
+ org.jlab.clas12
+ reconstruction
+ 13.1.0-SNAPSHOT
+
+
+
+
+
+ org.jlab.clas
+ clas-io
+ 13.1.0-SNAPSHOT
+
+
+
+ org.jlab.clas
+ clas-detector
+ 13.1.0-SNAPSHOT
+
+
+
+ org.jlab.clas
+ clas-reco
+ 13.1.0-SNAPSHOT
+
+
+
+
diff --git a/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/CTOFBankBuilder.java b/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/CTOFBankBuilder.java
new file mode 100644
index 0000000000..0da81f014d
--- /dev/null
+++ b/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/CTOFBankBuilder.java
@@ -0,0 +1,127 @@
+package org.jlab.calibration.detectors;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.jlab.detector.base.DetectorType;
+import org.jlab.io.base.DataBank;
+import org.jlab.io.base.DataEvent;
+
+/**
+ *
+ * @author devita
+ */
+public class CTOFBankBuilder extends CalibBankBuilder {
+
+ public CTOFBankBuilder() {
+ super(DetectorType.CTOF);
+ super.init("CTOF::adc", "CTOF::tdc", "CTOF::hits", "CVTRec::Tracks",
+ "REC::Track", "REC::Scintillator", "REC::Particle");
+ }
+ @Override
+ public boolean isGoodEvent(DataEvent event) {
+
+ DataBank part = event.getBank("REC::Particle");
+ if(part.rows()<2 ||
+ part.getInt("pid", 0)!=11 ||
+ ((int) (Math.abs(part.getShort("status", 0))/1000))!=2)
+ return false;
+ else {
+ for(int i=1; i4000)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public DataBank buildCalibBank(DataEvent event) {
+ DataBank part = event.getBank("REC::Particle");
+ DataBank scin = event.getBank("REC::Scintillator");
+ DataBank trac = event.getBank("REC::Track");
+ DataBank cvts = event.getBank("CVTRec::Tracks");
+ DataBank hits = event.getBank("CTOF::hits");
+ DataBank adcs = event.getBank("CTOF::adc");
+ DataBank tdcs = event.getBank("CTOF::tdc");
+
+ Map sinds = new HashMap<>();
+ for(int is=0; is tinds = new HashMap<>();
+ for(int it=0; it0 && tinds.containsKey(tid)) {
+ int tindex = tinds.get(tid);
+ int pindex = trac.getShort("pindex", tindex);
+ if(sinds.containsKey(pindex))
+ ngood++;
+ }
+ }
+
+ if(ngood>0) {
+ DataBank calib = event.createBank("CTOF::calib", ngood);
+
+ int row =0;
+ for(int i=0; i0 && tinds.containsKey(tid)) {
+ int tindex = tinds.get(tid);
+ int pindex = trac.getShort("pindex", tindex);
+ if(sinds.containsKey(pindex)) {
+ int sindex = sinds.get(pindex);
+ calib.setShort("id", row, hits.getShort("id", i));
+ calib.setShort("status", row, hits.getShort("status", i));
+ calib.setShort("trackid", row, hits.getShort("trkID", i));
+ calib.setShort("pindex", row, (short) pindex);
+ calib.setShort("component", row, hits.getShort("component", i));
+ calib.setFloat("energy", row, hits.getFloat("energy", i));
+ calib.setFloat("time", row, hits.getFloat("time", i));
+ calib.setFloat("x", row, hits.getFloat("x", i));
+ calib.setFloat("y", row, hits.getFloat("y", i));
+ calib.setFloat("z", row, hits.getFloat("z", i));
+ calib.setFloat("tx", row, scin.getFloat("hx", sindex));
+ calib.setFloat("ty", row, scin.getFloat("hy", sindex));
+ calib.setFloat("tz", row, scin.getFloat("hz", sindex));
+ calib.setInt("pid", row, part.getInt("pid", pindex));
+ calib.setByte("charge", row, part.getByte("charge", pindex));
+ calib.setFloat("px", row, part.getFloat("px", pindex));
+ calib.setFloat("py", row, part.getFloat("py", pindex));
+ calib.setFloat("pz", row, part.getFloat("pz", pindex));
+ calib.setFloat("vx", row, part.getFloat("vx", pindex));
+ calib.setFloat("vy", row, part.getFloat("vy", pindex));
+ calib.setFloat("vz", row, part.getFloat("vz", pindex));
+ calib.setFloat("vt", row, part.getFloat("vt", pindex));
+ calib.setFloat("pathLength", row, scin.getFloat("path", sindex));
+ calib.setFloat("pathLengthThruBar", row, hits.getFloat("pathLengthThruBar", i));
+ calib.setFloat("chi2", row, trac.getFloat("chi2", tindex));
+ calib.setShort("NDF", row, trac.getShort("NDF", tindex));
+ calib.setInt("adc1", row, adcs.getInt("ADC", hits.getShort("adc_idx1", i)));
+ calib.setInt("adc2", row, adcs.getInt("ADC", hits.getShort("adc_idx2", i)));
+ calib.setInt("tdc1", row, tdcs.getInt("TDC", hits.getShort("tdc_idx1", i)));
+ calib.setInt("tdc2", row, tdcs.getInt("TDC", hits.getShort("tdc_idx2", i)));
+ row++;
+ }
+ }
+ }
+ return calib;
+ }
+ return null;
+ }
+}
diff --git a/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/CalibBankBuilder.java b/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/CalibBankBuilder.java
new file mode 100644
index 0000000000..b3d154ea10
--- /dev/null
+++ b/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/CalibBankBuilder.java
@@ -0,0 +1,46 @@
+package org.jlab.calibration.detectors;
+
+import java.util.Arrays;
+import java.util.List;
+import org.jlab.detector.base.DetectorType;
+import org.jlab.io.base.DataBank;
+import org.jlab.io.base.DataEvent;
+
+/**
+ *
+ * @author devita
+ */
+public abstract class CalibBankBuilder {
+
+ private DetectorType type;
+ private List bankNames;
+ private String outputBankName;
+
+ public CalibBankBuilder(DetectorType type) {
+ this.type = type;
+ this.outputBankName = type.getName()+"::calib";
+ }
+
+ public void init(String... banks) {
+ bankNames = Arrays.asList(banks);
+ }
+
+ public String getOutputBankName() {
+ return this.outputBankName;
+ }
+
+ public DataBank getCalibBank(DataEvent event) {
+ for(String b : bankNames)
+ if(!event.hasBank(b))
+ return null;
+
+ if(this.isGoodEvent(event))
+ return this.buildCalibBank(event);
+ else
+ return null;
+ }
+
+ public abstract boolean isGoodEvent(DataEvent event);
+
+ public abstract DataBank buildCalibBank(DataEvent event);
+}
diff --git a/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/DCBankBuilder.java b/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/DCBankBuilder.java
new file mode 100644
index 0000000000..26e67ab293
--- /dev/null
+++ b/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/DCBankBuilder.java
@@ -0,0 +1,135 @@
+package org.jlab.calibration.detectors;
+
+import java.util.ArrayList;
+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;
+
+/**
+ *
+ * @author devita
+ */
+public class DCBankBuilder extends CalibBankBuilder {
+
+ private static final int MINCLUSTERSIZE = 5;
+ private static final double MAXRESIDUAL = 0.1; // cm
+ private static final double CHI2PIDCUT = 5; // cm
+
+ public DCBankBuilder() {
+ super(DetectorType.DC);
+ super.init("TimeBasedTrkg::TBHits","TimeBasedTrkg::TBHits","TimeBasedTrkg::TBTracks",
+ "REC::Track", "REC::Particle");
+ }
+ @Override
+ public boolean isGoodEvent(DataEvent event) {
+
+ DataBank part = event.getBank("REC::Particle");
+
+ if(part.rows()<2 ||
+ part.getInt("pid", 0)!=11 ||
+ (part.getFloat("chi2pid", 0))>CHI2PIDCUT ||
+ ((int) (Math.abs(part.getShort("status", 0))/1000))!=2)
+ return false;
+
+ boolean hasHadron = false;
+ for(int i=1; i pinds = new HashMap<>();
+ for(int it=0; it> clusters = new HashMap<>();
+ for(int i=0; i0 &&
+ trackid>0 &&
+ tflight>0 &&
+ fitresi=MINCLUSTERSIZE)
+ ngood += clusters.get(key).size();
+ else
+ clusters.get(key).clear();
+ }
+
+ if(ngood>0) {
+ DataBank calib = event.createBank("DC::calib", ngood);
+
+ int row = 0;
+ for(List cluster : clusters.values()) {
+ if(cluster.isEmpty()) continue;
+ for(int i : cluster) {
+ calib.setShort("id", row, tbhs.getShort("id",i));
+ calib.setShort("status", row, tbhs.getShort("status",i));
+ calib.setByte("superlayer", row, tbhs.getByte("superlayer",i));
+ calib.setByte("layer", row, tbhs.getByte("layer",i));
+ calib.setByte("sector", row, tbhs.getByte("sector",i));
+ calib.setShort("wire", row, tbhs.getShort("wire",i));
+ calib.setInt("TDC", row, tbhs.getInt("TDC",i));
+ calib.setByte("jitter", row, tbhs.getByte("jitter",i));
+ calib.setFloat("time", row, tbhs.getFloat("time",i));
+ calib.setFloat("doca", row, tbhs.getFloat("doca",i));
+ calib.setFloat("docaError", row, tbhs.getFloat("docaError",i));
+ calib.setFloat("trkDoca", row, tbhs.getFloat("trkDoca",i));
+ calib.setFloat("timeResidual", row, tbhs.getFloat("timeResidual",i));
+ calib.setFloat("fitResidual", row, tbhs.getFloat("fitResidual",i));
+ calib.setFloat("DAFWeight", row, tbhs.getFloat("DAFWeight",i));
+ calib.setByte("LR", row, tbhs.getByte("LR",i));
+ calib.setFloat("X", row, tbhs.getFloat("X",i));
+ calib.setFloat("Z", row, tbhs.getFloat("Z",i));
+ calib.setFloat("B", row, tbhs.getFloat("B",i));
+ calib.setFloat("Alpha", row, tbhs.getFloat("Alpha",i));
+ calib.setFloat("TProp", row, tbhs.getFloat("TProp",i));
+ calib.setFloat("TFlight", row, tbhs.getFloat("TFlight",i));
+ calib.setFloat("T0", row, tbhs.getFloat("T0",i));
+ calib.setFloat("TStart", row, tbhs.getFloat("TStart",i));
+ calib.setFloat("beta", row, tbhs.getFloat("beta",i));
+ calib.setFloat("tBeta", row, tbhs.getFloat("tBeta",i));
+ calib.setFloat("dDoca", row, tbhs.getFloat("dDoca",i));
+ calib.setShort("clusterID", row, tbhs.getShort("clusterID",i));
+ calib.setByte("trkID", row, tbhs.getByte("trkID",i));
+ row++;
+ }
+ }
+ return calib;
+ }
+ return null;
+ }
+}
diff --git a/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/FTOFBankBuilder.java b/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/FTOFBankBuilder.java
new file mode 100644
index 0000000000..0b9a540760
--- /dev/null
+++ b/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/FTOFBankBuilder.java
@@ -0,0 +1,121 @@
+package org.jlab.calibration.detectors;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.jlab.detector.base.DetectorType;
+import org.jlab.io.base.DataBank;
+import org.jlab.io.base.DataEvent;
+
+/**
+ *
+ * @author devita
+ */
+public class FTOFBankBuilder extends CalibBankBuilder {
+
+ public FTOFBankBuilder() {
+ super(DetectorType.FTOF);
+ super.init("FTOF::adc", "FTOF::tdc", "FTOF::hits", "TimeBasedTrkg::TBTracks",
+ "REC::Track", "REC::Scintillator", "REC::Particle");
+ }
+ @Override
+ public boolean isGoodEvent(DataEvent event) {
+
+ DataBank part = event.getBank("REC::Particle");
+ if(part.rows()<2 ||
+ part.getInt("pid", 0)!=11 ||
+ ((int) (Math.abs(part.getShort("status", 0))/1000))!=2)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public DataBank buildCalibBank(DataEvent event) {
+ DataBank part = event.getBank("REC::Particle");
+ DataBank scin = event.getBank("REC::Scintillator");
+ DataBank trac = event.getBank("REC::Track");
+ DataBank tbts = event.getBank("TimeBasedTrkg::TBTracks");
+ DataBank hits = event.getBank("FTOF::hits");
+ DataBank adcs = event.getBank("FTOF::adc");
+ DataBank tdcs = event.getBank("FTOF::tdc");
+
+ Map> paths = new HashMap<>();
+ for(int is=0; is());
+ paths.get(pindex).put(layer, path);
+ }
+ }
+
+
+ Map tinds = new HashMap<>();
+ for(int it=0; it0) ngood++;
+ }
+
+ if(ngood>0) {
+ DataBank calib = event.createBank("FTOF::calib", ngood);
+
+ int row =0;
+ for(int i=0; i0) {
+ int tindex = tinds.get(tid);
+ int pindex = trac.getShort("pindex", tindex);
+ int layer = hits.getByte("layer", i);
+ double path = paths.containsKey(pindex) &&
+ paths.get(pindex).containsKey(layer) ?
+ paths.get(pindex).get(layer) : 0;
+ calib.setShort("id", row, hits.getShort("id", i));
+ calib.setShort("status", row, hits.getShort("status", i));
+ calib.setShort("trackid", row, hits.getShort("trackid", i));
+ calib.setShort("pindex", row, (short) pindex);
+ calib.setByte("sector", row, hits.getByte("sector", i));
+ calib.setByte("layer", row, hits.getByte("layer", i));
+ calib.setShort("component", row, hits.getShort("component", i));
+ calib.setFloat("energy", row, hits.getFloat("energy", i));
+ calib.setFloat("time", row, hits.getFloat("time", i));
+ calib.setFloat("x", row, hits.getFloat("x", i));
+ calib.setFloat("y", row, hits.getFloat("y", i));
+ calib.setFloat("z", row, hits.getFloat("z", i));
+ calib.setFloat("tx", row, hits.getFloat("tx", i));
+ calib.setFloat("ty", row, hits.getFloat("ty", i));
+ calib.setFloat("tz", row, hits.getFloat("tz", i));
+ calib.setInt("pid", row, part.getInt("pid", pindex));
+ calib.setByte("charge", row, part.getByte("charge", pindex));
+ calib.setFloat("px", row, part.getFloat("px", pindex));
+ calib.setFloat("py", row, part.getFloat("py", pindex));
+ calib.setFloat("pz", row, part.getFloat("pz", pindex));
+ calib.setFloat("vx", row, part.getFloat("vx", pindex));
+ calib.setFloat("vy", row, part.getFloat("vy", pindex));
+ calib.setFloat("vz", row, part.getFloat("vz", pindex));
+ calib.setFloat("pathLength", row, (float) path);
+ calib.setFloat("pathLengthThruBar", row, hits.getFloat("pathLengthThruBar", i));
+ calib.setFloat("chi2", row, trac.getFloat("chi2", tindex));
+ calib.setShort("NDF", row, trac.getShort("NDF", tindex));
+ calib.setInt("adc1", row, adcs.getInt("ADC", hits.getShort("adc_idx1", i)));
+ calib.setInt("adc2", row, adcs.getInt("ADC", hits.getShort("adc_idx2", i)));
+ calib.setInt("tdc1", row, tdcs.getInt("TDC", hits.getShort("tdc_idx1", i)));
+ calib.setInt("tdc2", row, tdcs.getInt("TDC", hits.getShort("tdc_idx2", i)));
+ row++;
+ }
+ }
+ return calib;
+ }
+ return null;
+ }
+}
diff --git a/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/RICHBankBuilder.java b/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/RICHBankBuilder.java
new file mode 100644
index 0000000000..5f52852a1f
--- /dev/null
+++ b/reconstruction/calib/src/main/java/org/jlab/calibration/detectors/RICHBankBuilder.java
@@ -0,0 +1,120 @@
+package org.jlab.calibration.detectors;
+
+import java.util.ArrayList;
+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;
+
+/**
+ *
+ * @author devita
+ */
+public class RICHBankBuilder extends CalibBankBuilder {
+
+ public RICHBankBuilder() {
+ super(DetectorType.RICH);
+ super.init("RICH::Hit", "RICH::Photon", "REC::Particle");
+ }
+ @Override
+ public boolean isGoodEvent(DataEvent event) {
+
+ DataBank part = event.getBank("REC::Particle");
+ if(part.rows()<1 ||
+ part.getInt("pid", 0)!=11 ||
+ ((int) (Math.abs(part.getShort("status", 0))/1000))!=2)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public DataBank buildCalibBank(DataEvent event) {
+ DataBank part = event.getBank("REC::Particle");
+ DataBank rich = event.getBank("RICH::Particle");
+ DataBank hits = event.getBank("RICH::Hit");
+ DataBank phos = event.getBank("RICH::Photon");
+
+ List goodPhotons = new ArrayList<>();
+ for(int i=0; i part2Rich = new HashMap<>();
+ for(int i=0; i goodClusters = new ArrayList<>();
+ for(int i=0; i0) goodClusters.add(i);
+ }
+
+ if(!goodPhotons.isEmpty() || !goodClusters.isEmpty()) {
+ DataBank calib = event.createBank("RICH::calib", goodPhotons.size()+goodClusters.size());
+
+ int row =0;
+ for(int i : goodPhotons) {
+ int hindex = phos.getShort("hindex", i);
+ int pindex = phos.getByte("pindex", i);
+ calib.setByte( "pindex", row, (byte) pindex);
+ calib.setShort("hindex", row, (short) hindex);
+ calib.setByte( "sector", row, (byte) hits.getShort("sector", hindex));
+ calib.setShort("pmt", row, hits.getShort("pmt", hindex));
+ calib.setShort("anode", row, hits.getShort("anode", hindex));
+ calib.setShort("status", row, hits.getShort("status", hindex));
+ calib.setByte( "used", row, phos.getByte("used", i));
+ calib.setFloat("x", row, hits.getFloat("x", hindex));
+ calib.setFloat("y", row, hits.getFloat("y", hindex));
+ calib.setFloat("z", row, hits.getFloat("z", hindex));
+ calib.setFloat("time", row, hits.getFloat("time", hindex));
+ calib.setFloat("rawtime", row, hits.getFloat("rawtime", hindex));
+ calib.setShort("duration", row, hits.getShort("duration", hindex));
+ calib.setByte("emilay", row, rich.getByte("emilay", part2Rich.get(pindex)));
+ calib.setByte("emico", row, rich.getByte("emico", part2Rich.get(pindex)));
+ calib.setShort("emqua", row, rich.getShort("emqua", part2Rich.get(pindex)));
+ calib.setFloat("start_time", row, phos.getFloat("start_time", i));
+ calib.setFloat("traced_the", row, phos.getFloat("traced_the", i));
+ calib.setFloat("traced_phi", row, phos.getFloat("traced_phi", i));
+ calib.setFloat("traced_hitx", row, phos.getFloat("traced_hitx", i));
+ calib.setFloat("traced_hity", row, phos.getFloat("traced_hity", i));
+ calib.setFloat("traced_hitz", row, phos.getFloat("traced_hitz", i));
+ calib.setFloat("traced_path", row, phos.getFloat("traced_path", i));
+ calib.setFloat("traced_time", row, phos.getFloat("traced_time", i));
+ calib.setShort("traced_nrfl", row, phos.getShort("traced_nrfl", i));
+ calib.setShort("traced_nrfr", row, phos.getShort("traced_nrfr", i));
+ calib.setShort("traced_1rfl", row, phos.getShort("traced_1rfl", i));
+ calib.setInt("traced_layers", row, phos.getInt("traced_layers", i));
+ calib.setInt("traced_compos", row, phos.getInt("traced_compos", i));
+ calib.setFloat("traced_etaC", row, phos.getFloat("traced_etaC", i));
+ calib.setFloat("etac_ref", row, phos.getFloat("etac_ref", i));
+ calib.setFloat("etac_rms", row, phos.getFloat("etac_rms", i));
+ calib.setFloat("prob", row, phos.getFloat("prob", i));
+ row++;
+ }
+ for(int i : goodClusters) {
+ calib.setShort("hindex", row, (short) i);
+ calib.setByte( "sector", row, (byte) hits.getShort("sector", i));
+ calib.setShort("pmt", row, hits.getShort("pmt", i));
+ calib.setShort("anode", row, hits.getShort("anode", i));
+ calib.setShort("status", row, hits.getShort("status", i));
+ calib.setByte( "used", row, (byte) 2);
+ calib.setFloat("x", row, hits.getFloat("x", i));
+ calib.setFloat("y", row, hits.getFloat("y", i));
+ calib.setFloat("z", row, hits.getFloat("z", i));
+ calib.setFloat("time", row, hits.getFloat("time", i));
+ calib.setFloat("rawtime", row, hits.getFloat("rawtime", i));
+ calib.setShort("duration", row, hits.getShort("duration", i));
+ row++;
+ }
+ return calib;
+ }
+ return null;
+ }
+}
diff --git a/reconstruction/calib/src/main/java/org/jlab/calibration/service/CalibBanksEngine.java b/reconstruction/calib/src/main/java/org/jlab/calibration/service/CalibBanksEngine.java
new file mode 100644
index 0000000000..486ba3e748
--- /dev/null
+++ b/reconstruction/calib/src/main/java/org/jlab/calibration/service/CalibBanksEngine.java
@@ -0,0 +1,78 @@
+package org.jlab.calibration.service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+import org.jlab.calibration.detectors.CTOFBankBuilder;
+import org.jlab.calibration.detectors.DCBankBuilder;
+import org.jlab.calibration.detectors.CalibBankBuilder;
+import org.jlab.calibration.detectors.FTOFBankBuilder;
+import org.jlab.calibration.detectors.RICHBankBuilder;
+import org.jlab.clas.reco.ReconstructionEngine;
+import org.jlab.detector.base.DetectorType;
+import org.jlab.io.base.DataBank;
+import org.jlab.io.base.DataEvent;
+
+/**
+ *
+ * @author devita
+ */
+public class CalibBanksEngine extends ReconstructionEngine {
+
+ private final Map calibrators = new HashMap<>();
+
+ public static final String CONF_DETECTORS = "detectors";
+ private final List detectors = new ArrayList<>();
+
+ static final Logger logger = Logger.getLogger(CalibBanksEngine.class.getName());
+
+ public CalibBanksEngine() {
+ super("CALIB", "devita", "1.0");
+ calibrators.put(DetectorType.DC , new DCBankBuilder());
+ calibrators.put(DetectorType.FTOF, new FTOFBankBuilder());
+ calibrators.put(DetectorType.CTOF, new CTOFBankBuilder());
+ calibrators.put(DetectorType.RICH, new RICHBankBuilder());
+ }
+
+ @Override
+ public boolean init() {
+ String[] dets = getEngineConfigString(CONF_DETECTORS,"CTOF,DC,FTOF,RICH").split(",");
+ for(String d : dets) {
+ DetectorType type = DetectorType.getType(d.trim());
+ if(type != DetectorType.UNDEFINED)
+ detectors.add(type);
+ }
+ if(detectors.isEmpty())
+ return false;
+
+ String[] outputBanks = new String[detectors.size()];
+ for(int i=0; i banks = new ArrayList<>();
+
+ for(DetectorType d : detectors) {
+
+ CalibBankBuilder calibrator = calibrators.get(d);
+
+ if(calibrator.isGoodEvent(event)) {
+ DataBank calib = calibrator.getCalibBank(event);
+ if(calib!=null) banks.add(calib);
+ }
+ }
+
+ if(!banks.isEmpty())
+ event.appendBanks(banks.toArray(new DataBank[banks.size()]));
+ return true;
+ }
+
+}
diff --git a/reconstruction/pom.xml b/reconstruction/pom.xml
index 11b64932b2..d603747940 100644
--- a/reconstruction/pom.xml
+++ b/reconstruction/pom.xml
@@ -37,6 +37,7 @@
bg
postproc
recoil
+ calib
diff --git a/reconstruction/tof/src/main/java/org/jlab/rec/tof/banks/ftof/RecoBankWriter.java b/reconstruction/tof/src/main/java/org/jlab/rec/tof/banks/ftof/RecoBankWriter.java
index 8ab216be27..2692176c61 100644
--- a/reconstruction/tof/src/main/java/org/jlab/rec/tof/banks/ftof/RecoBankWriter.java
+++ b/reconstruction/tof/src/main/java/org/jlab/rec/tof/banks/ftof/RecoBankWriter.java
@@ -245,7 +245,7 @@ public void appendFTOFBanks(DataEvent event, List hits, List clust
if (fTOFBanks.size() == 1) {
event.appendBanks(fTOFBanks.get(0));
}
-
+
}
}