diff --git a/common-tools/clas-detector/src/main/java/org/jlab/detector/base/DetectorType.java b/common-tools/clas-detector/src/main/java/org/jlab/detector/base/DetectorType.java
index 4ee7c44cf8..a07cbc2452 100644
--- a/common-tools/clas-detector/src/main/java/org/jlab/detector/base/DetectorType.java
+++ b/common-tools/clas-detector/src/main/java/org/jlab/detector/base/DetectorType.java
@@ -33,7 +33,8 @@ public enum DetectorType {
URWT (23, "URWT"),
AHDC (24, "AHDC"),
ATOF (25, "ATOF"),
- RECOIL (26, "RECOIL"),
+ RTRK (26, "RTRK"),
+ RTOF (27, "RTOF"),
MUCAL (28, "MUCAL"),
MUVT (29, "MUVT"),
MURT (30, "MURT"),
diff --git a/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/RecoilConstants.java b/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/RecoilConstants.java
deleted file mode 100644
index 805407434e..0000000000
--- a/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/RecoilConstants.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package org.jlab.detector.geant4.v2.recoil;
-
-
-import org.jlab.detector.calib.utils.DatabaseConstantProvider;
-import org.jlab.geom.prim.Point3D;
-
-
-public class RecoilConstants {
-
- private final static String CCDBPATH = "/geometry/recoil/";
-
- public final static int NMAXREGIONS = 3; //max number of regions
- public final static int NREGIONS = 3; //number of regions
- public final static int NSECTORS = 2; //number of sectors
- public final static int NLAYERS = 2; //number of layers
- public final static int NCHAMBERS = 1; //number of chambers in a sector
-
- public final static double HORIZONTHAL_OPENING_ANGLE = 34.;
- public final static double VERTICAL_OPENING_ANGLE = 50.;
- public final static double RADIUS[] = {33.5,55.5,79.5};
- public final static double WIDTH[] = new double[NMAXREGIONS];
- public final static double HEIGHT[] = new double[NMAXREGIONS];
-
- public final static double THTILT = 0; // theta tilt (deg)
- /* public final static double XENLARGEMENT = 0.5; // cm
- public final static double YENLARGEMENT = 1.; // cm
- public final static double ZENLARGEMENT = 0.1; // cm
-
- // Sector geometrical parameters
- public final static double THOPEN = 34.; // opening angle between endplate planes (deg)
- public final static double THTILT = 0; // theta tilt (deg)
- public final static double THMIN = 4.694; // polar angle to the base of first chamber (deg)
- public final static double SECTORHEIGHT = 146.21; //height of each sector (cm)
- public final static double DX0CHAMBER0 = 5.197; // halfbase of chamber 1 (cm)*/
-
- // Chamber volumes and materials (units are cm)
- public final static double[] CHAMBERVOLUMESTHICKNESS = {0.0025, 0.0005,0.3, // window
- 0.0025, 0.0005,0.4, // cathode
- 0.0005, 0.005, 0.0005, // uRWell + DlC
- 0.0005, 0.005, 0.0005, // Capacitive sharing layer1
- 0.0005, 0.005, 0.0005, // Capacitive sharing layer2
- 0.005, 0.0005,0.005, 0.005, 0.0005,0.005, 0.005, // Readout
- 0.0127, 0.3, 0.0125}; // support
- public final static String[] CHAMBERVOLUMESNAME = {"window_kapton", "window_Al", "window_gas",
- "cathode_kapton", "cathode_Al", "cathode_gas",
- "muRwell_Cu", "muRwell_kapton", "muRwell_dlc",
- "capa_sharing_layer1_glue","capa_sharing_layer1_Cr","capa_sharing_layer1_kapton",
- "capa_sharing_layer2_glue","capa_sharing_layer2_Cr","capa_sharing_layer2_kapton",
- "readout1_glue", "readout1_Cu", "readout1_kapton", "readout2_glue", "readout2_Cu", "readout2_kapton", "readout3_glue",
- "support_skin1_g10", "support_honeycomb_nomex", "support_skin2_g10"};
-
- // URWELL position in the CLAS12 frame
- /* public final static double TGT2DC0 = 228.078; // cm
- // public final static double URWELL2DC0 = 2; // cm
- public final static double URWELL2DC0[] = new double[NMAXREGIONS];
- public final static double DIST2TGT[] = new double[NMAXREGIONS];
- public final static double W2TGT[] = new double[NMAXREGIONS];;
- public final static double YMIN[] = new double[NMAXREGIONS];
- public final static double ZMIN[] = new double[NMAXREGIONS];*/
-
- public final static double PITCH = 0.1 ; // cm
- public final static double STEREOANGLE = 90; // deg
-
- /*
- * @return String a path to a directory in CCDB of the format {@code "/geometry/detector/"}
- */
- public static String getCcdbPath()
- {
- return CCDBPATH;
- }
-
- /**
- * Loads the the necessary tables for the URWELL geometry for a given DatabaseConstantProvider.
- *
- * @return DatabaseConstantProvider the same thing
- */
- public static DatabaseConstantProvider connect( DatabaseConstantProvider cp )
- {
- // cp.loadTable( CCDBPATH +"RWELL");
-
- load(cp );
- return cp;
- }
-
- /**
- * Reads all the necessary constants from CCDB into static variables.
- * Please use a DatabaseConstantProvider to access CCDB and load the following tables:
- * @param cp a ConstantProvider that has loaded the necessary tables
- */
-
- public static synchronized void load( DatabaseConstantProvider cp )
- {
- // read constants from svt table
-// NREGIONS = cp.getInteger( CCDBPATH+"svt/nRegions", 0 );
-
- for (int i=0; i (volume.getName().contains(volumeName)))
- .findAny()
- .orElse(null);
- }
-
- /**
- * Returns the sector volume for the given sector number
- *
- * @param sector (1-6)
- * @return the sector volume
- */
- public Geant4Basic getSectorVolume(int region, int sector) {
-
- int r = region;
- int s = sector;
-
- String volName = "region_Recoil_" + r + "_s" + s;
- return this.getAllVolumes().stream()
- .filter(volume -> (volume.getName().contains(volName)))
- .findAny()
- .orElse(null);
- }
-
- public static void main(String[] args) {
- DatabaseConstantProvider cp = new DatabaseConstantProvider(11, "default");
-
- RecoilConstants.connect(cp);
-
- RecoilGeant4Factory factory = new RecoilGeant4Factory(cp, 1);
-
- factory.getAllVolumes().forEach(volume -> {
- System.out.println(volume.gemcString());
- });
-
- }
-}
diff --git a/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/tof/RTOFConstants.java b/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/tof/RTOFConstants.java
new file mode 100644
index 0000000000..5ef906db7b
--- /dev/null
+++ b/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/tof/RTOFConstants.java
@@ -0,0 +1,43 @@
+package org.jlab.detector.geant4.v2.recoil.tof;
+
+import org.jlab.detector.calib.utils.DatabaseConstantProvider;
+
+public class RTOFConstants {
+
+ public final static int NSECTORS = 2; //number of sectors
+ public final static int NROWS = 5; //number of rows of bars in a sector
+ public final static int NCOLUMNS = 63; //number of columns of bars in a sector
+
+ public final static double LONG_BAR_LENGTH = 27.5; // cm
+ public final static double SHORT_BAR_LENGTH = 4; // cm
+
+ public final static double BAR_WIDTH = 1; // cm
+ public final static double BAR_THICKNESS = 0.5; // cm
+
+ public final static double HORIZONTAL_STARTING_ANGLE = 40.;
+ public final static double HORIZONTAL_OPENING_ANGLE = 29.;
+ public final static double RADIUS = 122.; // cm
+
+ public final static double WIDTH = NCOLUMNS * BAR_WIDTH;
+ public final static double LENGTH = (NROWS-1) * LONG_BAR_LENGTH + SHORT_BAR_LENGTH;
+ public final static double THICKNESS = 0.5; // cm
+
+ public static DatabaseConstantProvider connect( DatabaseConstantProvider cp )
+ {
+ load(cp );
+ return cp;
+ }
+
+ /**
+ * Reads all the necessary constants from CCDB into static variables.
+ * Please use a DatabaseConstantProvider to access CCDB and load the following tables:
+ * @param cp a ConstantProvider that has loaded the necessary tables
+ */
+ public static synchronized void load( DatabaseConstantProvider cp )
+ {
+ //WIDTH = NCOLUMNS * BAR_WIDTH;
+ //LENGTH = (NROWS-1) * LONG_BAR_LENGTH + SHORT_BAR_LENGTH;
+ //THICKNESS = 0.5; // cm
+ }
+
+}
\ No newline at end of file
diff --git a/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/tof/RTOFGeant4Factory.java b/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/tof/RTOFGeant4Factory.java
new file mode 100644
index 0000000000..82926db40a
--- /dev/null
+++ b/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/tof/RTOFGeant4Factory.java
@@ -0,0 +1,129 @@
+package org.jlab.detector.geant4.v2.recoil.tof;
+
+import eu.mihosoft.vrl.v3d.Vector3d;
+import org.jlab.detector.geant4.v2.Geant4Factory;
+import org.jlab.detector.volume.G4World;
+import org.jlab.detector.volume.G4Box;
+import org.jlab.detector.volume.Geant4Basic;
+import org.jlab.detector.calib.utils.DatabaseConstantProvider;
+
+/**
+ * Generate GEANT4 volume for the RECOIL TOF detector
+ *
+ * @author Nilanga Wickramaarachchi
+ */
+public final class RTOFGeant4Factory extends Geant4Factory {
+
+ private int nSectors = RTOFConstants.NSECTORS;
+ private int nRows = RTOFConstants.NROWS;
+ private int nCols = RTOFConstants.NCOLUMNS;
+
+ public RTOFGeant4Factory( DatabaseConstantProvider cp) {
+ RTOFConstants.connect(cp );
+ this.init(cp);
+ }
+
+ public void init(DatabaseConstantProvider cp) {
+ motherVolume = new G4World("root");
+ for (int isector = 0; isector < nSectors; isector++) {
+ Geant4Basic sectorVolume = createSector(isector, nRows, nCols);
+ sectorVolume.setName("recoil_tof_sector" + (isector + 1));
+ sectorVolume.setMother(motherVolume);
+ }
+ }
+
+ public Vector3d getCenterCoordinate(int isector)
+ {
+ int is=isector;
+ Vector3d vCenter = new Vector3d(0, 0, 0);
+ vCenter.x = (-1+is*2)*(RTOFConstants.RADIUS)*Math.sin(Math.toRadians(RTOFConstants.HORIZONTAL_OPENING_ANGLE/2+RTOFConstants.HORIZONTAL_STARTING_ANGLE));
+ vCenter.y = 0;
+ vCenter.z =RTOFConstants.RADIUS*Math.cos(Math.toRadians(RTOFConstants.HORIZONTAL_OPENING_ANGLE/2+RTOFConstants.HORIZONTAL_STARTING_ANGLE));
+ return vCenter;
+ }
+
+ public Geant4Basic createSector(int isector, int nRows, int nCols ) {
+
+ double hlx = RTOFConstants.WIDTH/2+1;
+ double hly = RTOFConstants.LENGTH/2+1;
+ double hlz = RTOFConstants.THICKNESS/2+1;
+
+ Vector3d vCenter = this.getCenterCoordinate(isector);
+
+ Geant4Basic sectorVolume = new G4Box("recoil_tof_sector" + (isector + 1), hlx, hly, hlz);
+
+ if(isector==0) sectorVolume.rotate("yxz",Math.toRadians((RTOFConstants.HORIZONTAL_OPENING_ANGLE/2+RTOFConstants.HORIZONTAL_STARTING_ANGLE)),0,0);
+ if(isector==1) sectorVolume.rotate("yxz",Math.toRadians(-(RTOFConstants.HORIZONTAL_OPENING_ANGLE/2+RTOFConstants.HORIZONTAL_STARTING_ANGLE)),0,0);
+ sectorVolume.translate(vCenter.x, vCenter.y, vCenter.z);
+ sectorVolume.setId(isector + 1, 0, 0);
+
+ // Bars construction
+ for (int row = 0; row < nRows; row++) {
+ for (int col = 0; col < nCols; col++) {
+
+ Geant4Basic barVolume = this.createBar(isector, row, col);
+
+ barVolume.setName("bar_sector" + (isector + 1) + "_row" + (row + 1) + "_column" + (col + 1));
+
+ barVolume.setMother(sectorVolume);
+
+ barVolume.setId(isector + 1, row +1, col+1, 0);
+ }
+ }
+
+ return sectorVolume;
+ }
+
+ public Geant4Basic createBar(int iSector, int iRow, int iCol) {
+
+ int nCols = RTOFConstants.NCOLUMNS;
+
+ double barDX = RTOFConstants.BAR_WIDTH/2;
+ double barDY;
+
+ if (iRow == (nRows - 1) / 2) barDY = RTOFConstants.SHORT_BAR_LENGTH/2;
+ else barDY = RTOFConstants.LONG_BAR_LENGTH/2;
+
+ double barDZ = RTOFConstants.BAR_THICKNESS/2;
+
+ Geant4Basic barVolume = new G4Box("bar_sector" + (iSector + 1) + "_row" + (iRow + 1) + "_column" + (iCol + 1), barDX, barDY, barDZ);
+
+ // Constants for positioning
+ double y_start = -(RTOFConstants.LENGTH - RTOFConstants.LONG_BAR_LENGTH)/2; // Starting Y position
+ double x_spacing = RTOFConstants.BAR_WIDTH;
+ double x_start = -(RTOFConstants.WIDTH - x_spacing)/2; // starting X position
+ double dy_long = RTOFConstants.LONG_BAR_LENGTH;
+ double dy_short = RTOFConstants.SHORT_BAR_LENGTH;
+
+ //Position calculation
+ double z_pos = 0;
+ double x_pos = x_start + (iCol * x_spacing);
+
+ double y_pos;
+ if (iRow < (nRows - 1) / 2) {
+ y_pos = y_start + (iRow * dy_long);
+ }
+ else if (iRow == (nRows - 1) / 2) {// middle row
+ y_pos = 0;
+ }
+ else {
+ y_pos = y_start + (iRow -1) * dy_long + dy_short;
+ }
+
+ barVolume.setPosition(x_pos, y_pos, z_pos);
+
+ return barVolume;
+ }
+
+ public static void main(String[] args) {
+ DatabaseConstantProvider cp = new DatabaseConstantProvider(11, "default");
+
+ RTOFConstants.connect(cp);
+
+ RTOFGeant4Factory factory = new RTOFGeant4Factory(cp);
+
+ factory.getAllVolumes().forEach(volume -> {
+ System.out.println(volume.gemcString());
+ });
+ }
+}
\ No newline at end of file
diff --git a/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/trk/RTRKConstants.java b/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/trk/RTRKConstants.java
new file mode 100644
index 0000000000..5df67bf460
--- /dev/null
+++ b/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/trk/RTRKConstants.java
@@ -0,0 +1,106 @@
+package org.jlab.detector.geant4.v2.recoil.trk;
+
+import org.jlab.detector.calib.utils.DatabaseConstantProvider;
+
+public class RTRKConstants {
+
+ private final static String CCDBPATH = "/geometry/recoil/trk/";
+
+ public final static int NMAXREGIONS = 3; //max number of regions
+ public final static int NREGIONS = 3; //number of regions
+ public final static int NSECTORS = 2; //number of sectors
+ public final static int NLAYERS = 2; //number of layers
+ public final static int NCHAMBERS = 1; //number of chambers in a sector
+
+ public final static double HORIZONTHAL_OPENING_ANGLE = 34.;
+ public final static double VERTICAL_OPENING_ANGLE = 50.;
+ public final static double RADIUS[] = {33.5,55.5,79.5};
+ public final static double WIDTH[] = new double[NMAXREGIONS];
+ public final static double HEIGHT[] = new double[NMAXREGIONS];
+
+ public final static double THTILT = 0; // theta tilt (deg)
+ /* public final static double XENLARGEMENT = 0.5; // cm
+ public final static double YENLARGEMENT = 1.; // cm
+ public final static double ZENLARGEMENT = 0.1; // cm
+
+ // Sector geometrical parameters
+ public final static double THOPEN = 34.; // opening angle between endplate planes (deg)
+ public final static double THTILT = 0; // theta tilt (deg)
+ public final static double THMIN = 4.694; // polar angle to the base of first chamber (deg)
+ public final static double SECTORHEIGHT = 146.21; //height of each sector (cm)
+ public final static double DX0CHAMBER0 = 5.197; // halfbase of chamber 1 (cm)*/
+
+ // Chamber volumes and materials (units are cm)
+ public final static double[] CHAMBERVOLUMESTHICKNESS = {
+ 0.0025, 0.0005,0.3, // window
+ 0.0025, 0.0005,0.4, // cathode
+ 0.0005, 0.005, 0.0005, // uRWell + DlC
+ 0.0005, 0.005, 0.0005, // Capacitive sharing layer1
+ 0.0005, 0.005, 0.0005, // Capacitive sharing layer2
+ 0.005, 0.0005,0.005, 0.005, 0.0005,0.005, 0.005, // Readout
+ 0.0127, 0.3, 0.0125}; // support
+ public final static String[] CHAMBERVOLUMESNAME = {
+ "window_kapton", "window_Al", "window_gas",
+ "cathode_kapton", "cathode_Al", "cathode_gas",
+ "muRwell_Cu", "muRwell_kapton", "muRwell_dlc",
+ "capa_sharing_layer1_glue","capa_sharing_layer1_Cr","capa_sharing_layer1_kapton",
+ "capa_sharing_layer2_glue","capa_sharing_layer2_Cr","capa_sharing_layer2_kapton",
+ "readout1_glue", "readout1_Cu", "readout1_kapton", "readout2_glue", "readout2_Cu", "readout2_kapton", "readout3_glue",
+ "support_skin1_g10", "support_honeycomb_nomex", "support_skin2_g10"};
+
+ // URWELL position in the CLAS12 frame
+ /* public final static double TGT2DC0 = 228.078; // cm
+ // public final static double URWELL2DC0 = 2; // cm
+ public final static double URWELL2DC0[] = new double[NMAXREGIONS];
+ public final static double DIST2TGT[] = new double[NMAXREGIONS];
+ public final static double W2TGT[] = new double[NMAXREGIONS];;
+ public final static double YMIN[] = new double[NMAXREGIONS];
+ public final static double ZMIN[] = new double[NMAXREGIONS];*/
+
+ public final static double PITCH = 0.1 ; // cm
+ public final static double STEREOANGLE = 90; // deg
+
+ /*
+ * @return String a path to a directory in CCDB of the format {@code "/geometry/detector/"}
+ */
+ public static String getCcdbPath()
+ {
+ return CCDBPATH;
+ }
+
+ /**
+ * Loads the the necessary tables for the URWELL geometry for a given DatabaseConstantProvider.
+ *
+ * @return DatabaseConstantProvider the same thing
+ */
+ public static DatabaseConstantProvider connect( DatabaseConstantProvider cp )
+ {
+ // cp.loadTable( CCDBPATH +"RWELL");
+
+ load(cp );
+ return cp;
+ }
+
+ /**
+ * Reads all the necessary constants from CCDB into static variables.
+ * Please use a DatabaseConstantProvider to access CCDB and load the following tables:
+ * @param cp a ConstantProvider that has loaded the necessary tables
+ */
+ public static synchronized void load( DatabaseConstantProvider cp )
+ {
+ // read constants from svt table
+// NREGIONS = cp.getInteger( CCDBPATH+"svt/nRegions", 0 );
+
+ for (int i=0; i (volume.getName().contains(volumeName)))
+ .findAny()
+ .orElse(null);
+ }
+
+ /**
+ * Returns the sector volume for the given sector number
+ *
+ * @param sector (1-6)
+ * @return the sector volume
+ */
+ public Geant4Basic getSectorVolume(int region, int sector) {
+
+ int r = region;
+ int s = sector;
+
+ String volName = "region_rtrk_" + r + "_s" + s;
+ return this.getAllVolumes().stream()
+ .filter(volume -> (volume.getName().contains(volName)))
+ .findAny()
+ .orElse(null);
+ }
+
+ public static void main(String[] args) {
+ DatabaseConstantProvider cp = new DatabaseConstantProvider(11, "default");
+ RTRKConstants.connect(cp);
+ RTRKGeant4Factory factory = new RTRKGeant4Factory(cp, 1);
+ factory.getAllVolumes().forEach(volume -> {
+ System.out.println(volume.gemcString());
+ });
+ }
+}
diff --git a/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/RecoilStripFactory.java b/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/trk/RTRKStripFactory.java
similarity index 54%
rename from common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/RecoilStripFactory.java
rename to common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/trk/RTRKStripFactory.java
index 9a4144f2a6..7368335c7e 100644
--- a/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/RecoilStripFactory.java
+++ b/common-tools/clas-jcsg/src/main/java/org/jlab/detector/geant4/v2/recoil/trk/RTRKStripFactory.java
@@ -1,4 +1,4 @@
-package org.jlab.detector.geant4.v2.recoil;
+package org.jlab.detector.geant4.v2.recoil.trk;
import eu.mihosoft.vrl.v3d.Vector3d;
import java.util.List;
@@ -15,12 +15,12 @@
/**
* Creates and handles the URWELL detector strips as 3D lines
- *
+ *
* @author bondi, niccolai
*/
-public final class RecoilStripFactory {
-
- private RecoilGeant4Factory factory;
+public final class RTRKStripFactory {
+
+ private RTRKGeant4Factory factory;
private IndexedList globalStrips = new IndexedList(3);
private IndexedList localStrips = new IndexedList(3);
private IndexedList planeStrips = new IndexedList(3);
@@ -29,16 +29,16 @@ public final class RecoilStripFactory {
private int nChambers;
private int nLayers;
- public RecoilStripFactory() {
+ public RTRKStripFactory() {
}
/**
* Create the strip factory based on constants from CCDB.
- * Currently constants are defined in the RecoilConstants class.
+ * Currently constants are defined in the RTRKConstants class.
* They will be moved to CCDB when finalized).
* @param cp database provide
*/
- public RecoilStripFactory(DatabaseConstantProvider cp) {
+ public RTRKStripFactory(DatabaseConstantProvider cp) {
this.init(cp);
}
@@ -49,15 +49,15 @@ public RecoilStripFactory(DatabaseConstantProvider cp) {
public void init(DatabaseConstantProvider cp) {
this.init(cp, 1);
}
-
+
/**
* Create the strip factory based on constants from CCDB.
- * Currently constants are defined in the URWellConstants class.
+ * Currently constants are defined in the RTRKConstants class.
* They will be moved to CCDB when finalized).
* @param cp database provide
* @param regions
*/
- public RecoilStripFactory(DatabaseConstantProvider cp, int regions) {
+ public RTRKStripFactory(DatabaseConstantProvider cp, int regions) {
this.init(cp, regions);
}
@@ -67,45 +67,45 @@ public RecoilStripFactory(DatabaseConstantProvider cp, int regions) {
* @param regions
*/
public void init(DatabaseConstantProvider cp, int regions) {
- factory = new RecoilGeant4Factory(cp, regions);
- nRegions = Math.min(RecoilConstants.NMAXREGIONS, regions);
- nSectors = RecoilConstants.NSECTORS;
- nChambers = RecoilConstants.NCHAMBERS;
- nLayers = RecoilConstants.NLAYERS;
+ factory = new RTRKGeant4Factory(cp, regions);
+ nRegions = Math.min(RTRKConstants.NMAXREGIONS, regions);
+ nSectors = RTRKConstants.NSECTORS;
+ nChambers = RTRKConstants.NCHAMBERS;
+ nLayers = RTRKConstants.NLAYERS;
this.fillStripLists();
- // this.fillPlaneLists();
+ // this.fillPlaneLists();
}
-
+
/**
* Calculates the total number of strips in a sector
- *
+ *
* @return the strip number
*/
public int getNStripSector() {
int nStrips = 0;
for (int i = 0; i < nChambers; i++) {
- for (int j = 0; j < nRegions; j++) {
- nStrips += getNStripChamber(i,j);
- }
- }
+ for (int j = 0; j < nRegions; j++) {
+ nStrips += getNStripChamber(i,j);
+ }
+ }
return nStrips;
}
-
+
/**
* Calculates the number of strips in the given chamber
- *
+ *
* @param ichamber (0, 1, 2)
* @return the strip number (1-N)
*/
public int getNStripChamber(int ichamber, int regions) {
-
- int iregion = regions;
- int chamber = ichamber;
+
+ int iregion = regions;
+ int chamber = ichamber;
double[] dim = factory.getChamber_daughter_Dimensions(iregion,chamber);
-
+
double yHalf = dim[1];
- double xHalf = dim[0];
-
+ double xHalf = dim[0];
+
// C-------------D //
// ------------- //
// ------------- //
@@ -113,56 +113,56 @@ public int getNStripChamber(int ichamber, int regions) {
/**
* * number of strip in AB**
*/
-
- int nAB = (int) (2 * xHalf / RecoilConstants.PITCH);
- int nAC = (int) (2 * yHalf / RecoilConstants.PITCH);
-
- int nStrips = nAB + nAC;
-
+
+ int nAB = (int) (2 * xHalf / RTRKConstants.PITCH);
+ int nAC = (int) (2 * yHalf / RTRKConstants.PITCH);
+
+ int nStrips = nAB + nAC;
+
return nStrips;
}
-
+
/**
* Provides the index of the chamber containing the strip with the given ID
- *
+ *
* @param strip (1 to N)
* @return the chamber index (0, 1, 2)
*/
public int getChamberIndex(int strip) {
int nStripTotal = 0;
-
+
for(int i=0; i strip ID chamber (from 1 to getNStripChamber)
int nStripTotal = 0;
if (chamberIndex > 0) {
for (int i = 0; i < chamberIndex; i++) {
- for (int j = 0; j < nRegions; j++) {
- nStripTotal += this.getNStripChamber(i,j);
- }
- }
+ for (int j = 0; j < nRegions; j++) {
+ nStripTotal += this.getNStripChamber(i,j);
+ }
+ }
}
-
- //Strip ID: from 1 to getNStripChamber
+
+ //Strip ID: from 1 to getNStripChamber
int cStrip = strip - nStripTotal;
return cStrip;
}
-
+
/**
* Builds the given strip line in the CLAS12 frame
* @param sector (1-6)
@@ -171,79 +171,79 @@ private int getLocalStripId(int strip) {
* @return the 3D strip line as a Line3d
*/
private Line3d createStrip(int sector, int region, int layer, int strip) {
-
+
int chamberIndex = getChamberIndex(strip);
int cStrip = this.getLocalStripId(strip);
-
+
// CHAMBER reference frame
// new numeration with stri ID_strip=0 crossing (0,0,0) of chamber
double[] dim = factory.getChamber_daughter_Dimensions(region-1,chamberIndex);
double yHalf = dim[1];
- double xHalf = dim[0];
-
- double DY = -xHalf; //v strip
-
+ double xHalf = dim[0];
+
+ double DY = -xHalf; //v strip
+
// Y coordinate of the intersection point between the x=0 and the strip line crossing for B
-
- if (layer % 2 != 0) { //u strip
- DY = -yHalf;
- }
- // ID of the strip
- int nS = (int) (DY / RecoilConstants.PITCH);
+
+ if (layer % 2 != 0) { //u strip
+ DY = -yHalf;
+ }
+ // ID of the strip
+ int nS = (int) (DY / RTRKConstants.PITCH);
int nCStrip = nS + (cStrip - 1);
- double c = nCStrip * RecoilConstants.PITCH;
-
- // Take 2 points in the strip straight line. They needs to define Line object
+ double c = nCStrip * RTRKConstants.PITCH;
+
+ // Take 2 points in the strip straight line. They needs to define Line object
//u strips
double oX = -xHalf;
double oY = c;
double oZ = 0;
-
+
double eX = xHalf;
double eY = c;
double eZ = 0;
-
+
if (layer % 2 == 0) { //v strips
- oX = c;
- oY = -yHalf;
- oZ = 0;
-
- eX = c;
- eY = yHalf;
- eZ = 0;
- }
-
- Vector3d origin = new Vector3d(oX, oY, oZ);
- Vector3d end = new Vector3d(eX, eY, eZ);
-
+ oX = c;
+ oY = -yHalf;
+ oZ = 0;
+
+ eX = c;
+ eY = yHalf;
+ eZ = 0;
+ }
+
+ Vector3d origin = new Vector3d(oX, oY, oZ);
+ Vector3d end = new Vector3d(eX, eY, eZ);
+
// Get Chamber Volume
Geant4Basic chamberVolume = factory.getChamberVolume(sector, region, chamberIndex+1, layer);
-
- // 2 point defined before wrt the GLOBAL frame
+
+ // 2 point defined before wrt the GLOBAL frame
Vector3d globalOrigin = chamberVolume.getGlobalTransform().transform(origin);
-
+
Vector3d globalEnd = chamberVolume.getGlobalTransform().transform(end);
-
+
Straight line = new Line3d(globalOrigin, globalEnd);
-
+
// CHECK intersections between line and volume
chamberVolume.makeSensitive();
List Hits = chamberVolume.getIntersections(line);
-
+
if (Hits.size() >= 1) {
-
- Vector3d TestOrigin = Hits.get(0).origin();
- Vector3d TestEnd = Hits.get(0).end();
-
+
+ Vector3d TestOrigin = Hits.get(0).origin();
+ Vector3d TestEnd = Hits.get(0).end();
+
return new Line3d(Hits.get(0).origin(), Hits.get(0).end());
-
+
} else {
return null;
}
}
-
- /**
+
+ /**
* Provides the given strip line in the Chamber local frame
* @param region (1-2)
* @param sector (1-6)
@@ -251,19 +251,19 @@ private Line3d createStrip(int sector, int region, int layer, int strip) {
* @param strip (1-N)
* @return the 3D strip line as a Line3d
*/
-
private Line3d getChamberStrip(int region, int sector, int chamber, int layer, int strip) {
-
- Line3d globalStrip = createStrip(sector, region, layer, strip);
- Geant4Basic chamberVolume = factory.getChamberVolume(sector, region, chamber, layer);
-
- Vector3d origin = chamberVolume.getGlobalTransform().invert().transform(globalStrip.origin());
- Vector3d end = chamberVolume.getGlobalTransform().invert().transform(globalStrip.end());
-
- Line3d localStrip = new Line3d(origin, end);
-
- return localStrip;
+
+ Line3d globalStrip = createStrip(sector, region, layer, strip);
+ Geant4Basic chamberVolume = factory.getChamberVolume(sector, region, chamber, layer);
+
+ Vector3d origin = chamberVolume.getGlobalTransform().invert().transform(globalStrip.origin());
+ Vector3d end = chamberVolume.getGlobalTransform().invert().transform(globalStrip.end());
+
+ Line3d localStrip = new Line3d(origin, end);
+
+ return localStrip;
}
+
/**
* Provides the given strip line in the sector local frame
* @param sector (1-6)
@@ -272,20 +272,18 @@ private Line3d getChamberStrip(int region, int sector, int chamber, int layer, i
* @return the 3D strip line as a Line3d
*/
private Line3d getLocalStrip(int region, int sector, int layer, int strip) {
-
-
+
Line3d globalStrip = createStrip(sector, region, layer, strip);
Geant4Basic sVolume = factory.getSectorVolume(region, sector);
-
+
Vector3d origin = sVolume.getGlobalTransform().invert().transform(globalStrip.origin());
Vector3d end = sVolume.getGlobalTransform().invert().transform(globalStrip.end());
-
+
Line3d localStrip = new Line3d(origin, end);
-
+
return localStrip;
}
-
private void fillStripLists() {
for(int ir=0; ir-xHalf && c-yHalf && c-xHalf && c-yHalf && c-xHalf && c-yHalf && c-xHalf && c-yHalf && c
+ * Uses found hits information. Creates a {@link RTOFCluster} matching them.
+ *
+ *
+ * @author pilleux, Nilanga Wickramaarachchi
+ */
+public class ClusterFinder {
+
+ /**
+ * list of clusters.
+ */
+ private ArrayList clusters;
+
+ /**
+ * Sets the list of clusters.
+ *
+ * @param clusters a {@link ArrayList} of {@link RTOFCluster}.
+ *
+ */
+ public void setClusters(ArrayList clusters) {
+ this.clusters = clusters;
+ }
+
+ /**
+ * Gets the list of clusters.
+ *
+ * @return a {@link ArrayList} of {@link RTOFCluster}.
+ *
+ */
+ public ArrayList getClusters() {
+ return clusters;
+ }
+
+
+ /**
+ * Cluster hits around a given hit, based on the time and geometric
+ * proximity.
+ *
+ * Hits are compared based on their y difference, which
+ * is distance in cm and time difference.
+ *
+ * If the hit satisfies all conditions, it is marked as clustered and added
+ * to the cluster hit list.
+ *
+ *
+ * @param The type of the hit objects, which must extend
+ * {@link RTOFRawHit}. This allows the method to work with different types of
+ * hits that are subclasses of {@link RTOFRawHit} (e.g., {@link RTOFHit}).
+ * @param i The index from which hits are read in the list to compare
+ * against the current hit.
+ * @param hits The list of hits to be clustered, can be any subclass of
+ * {@link RTOFRawHit}.
+ * @param this_hit The hit currently being considered for clustering.
+ * @param sigma_y The threshold for the y-distance [cm] between the hits.
+ * @param sigma_t The threshold for the time difference [ns] between the
+ * hits.
+ * @param cluster_id The ID of the cluster being formed.
+ * @param this_cluster_hits The list that will store the clustered hits.
+ * This list can accept hits of type RTOFRawHit or RTOFHit. Clustered hits are
+ * added to this list.
+ *
+ */
+ public void clusterHits(int i, ArrayList hits, RTOFRawHit this_hit, Number sigma_y, double sigma_t, int cluster_id, ArrayList super T> this_cluster_hits) {
+ // Loop through less energetic clusters
+ for (int j = i + 1; j < hits.size(); j++) {
+ T other_hit = hits.get(j);
+ // Skip already clustered hits
+ if (other_hit.getIsInACluster()) {
+ continue;
+ }
+ // Check the distance between the hits
+ double delta_T = Math.abs(this_hit.getTime() - other_hit.getTime());
+ //The y distance is a distance in cm
+ Boolean condition_y;
+ double delta_Y = Math.abs(this_hit.getY() - other_hit.getY());
+ condition_y = (delta_Y <= sigma_y.doubleValue());
+
+ //If hit is within limits, it is clustered
+ if (condition_y) {
+ if (delta_T < sigma_t) {
+ other_hit.setIsInACluster(true);
+ other_hit.setAssociatedClusterIndex(cluster_id);
+ this_cluster_hits.add(other_hit);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Builds clusters in the {@link DateEvent} using hits found and stored in a
+ * {@link HitFinder}.
+ *
+ * @param hitfinder the {@link HitFinder} containing the hits that were
+ * found
+ *
+ * @param sigma_y the tolerance for clustering in y [cm]
+ *
+ * @param sigma_t the tolerance for clustering in time [ns]
+ *
+ */
+ public void makeClusters(HitFinder hitfinder, double sigma_y, double sigma_t, DataEvent event) {
+
+ //A list of clusters is built for each event
+ clusters.clear();
+ int cluster_id = 1;
+
+ //Getting the list of hits, they must have been ordered by energy already
+ ArrayList rtof_hits = hitfinder.getRTOFHits();
+
+ //Loop through all bar hits
+ for (int i_bar = 0; i_bar < rtof_hits.size(); i_bar++) {
+ RTOFHit this_rtof_hit = rtof_hits.get(i_bar);
+ //Skip hits that have already been clustered
+ if (this_rtof_hit.getIsInACluster()) {
+ continue;
+ }
+
+ ArrayList this_cluster_rtof_hits = new ArrayList<>();
+ this_rtof_hit.setIsInACluster(true);
+ this_rtof_hit.setAssociatedClusterIndex(cluster_id);
+ this_cluster_rtof_hits.add(this_rtof_hit);
+
+ //Matching bar hits in clusters
+ clusterHits(i_bar, rtof_hits, this_rtof_hit, sigma_y, sigma_t, cluster_id, this_cluster_rtof_hits);
+
+ RTOFCluster cluster = new RTOFCluster(this_cluster_rtof_hits, event);
+ clusters.add(cluster);
+ cluster_id++;
+ }
+ }
+
+ /**
+ * Builds clusters in the {@link DataEvent} using hits found and stored in a
+ * {@link HitFinder}.
+ *
+ * @param event the {@link DataEvent} containing the clusters to be built
+ *
+ * @param hitfinder the {@link HitFinder} containing the hits that were
+ * found
+ *
+ */
+ public void makeClusters(DataEvent event, HitFinder hitfinder) {
+ makeClusters(hitfinder,
+ Parameters.SIGMA_Y_CLUSTERING,
+ Parameters.SIGMA_T_CLUSTERING, event);
+ }
+
+ /**
+ * Default constructor that initializes the list clusters as new empty list.
+ */
+ public ClusterFinder() {
+ clusters = new ArrayList<>();
+ }
+}
diff --git a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/HitFinder.java b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/HitFinder.java
new file mode 100644
index 0000000000..d79024693c
--- /dev/null
+++ b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/HitFinder.java
@@ -0,0 +1,113 @@
+package org.jlab.service.recoil.tof;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import org.jlab.io.base.DataBank;
+import org.jlab.io.base.DataEvent;
+
+/**
+ * The {@code HitFinder} class finds hits in the recoil tof.
+ *
+ *
+ * Uses recoil tof tdc bank information
+ *
+ * Creates a {@link ArrayList} of {@link RTOFHit} for rtof hits read.
+ *
+ *
+ *
+ * @author pilleux, Nilanga Wickramaarachchi
+ */
+public class HitFinder {
+
+ /**
+ * list of rtof hits
+ */
+ private ArrayList rtofHits;
+
+ /**
+ * Default constructor that initializes the list of hits as new empty lists.
+ */
+ public HitFinder() {
+ this.rtofHits = new ArrayList<>();
+ }
+
+ // Getter and Setter for rtofHits
+ public ArrayList getRTOFHits() {
+ return rtofHits;
+ }
+
+ public void setRTOFHits(ArrayList rtof_hits) {
+ this.rtofHits = rtof_hits;
+ }
+
+ /**
+ *
+ * @param event the {@link DataEvent} containing hits.
+ *
+ */
+ public void findHits(DataEvent event) {
+ //For each event a list of rtof hits is filled
+ this.rtofHits.clear();
+ //They are read from the RTOF TDC bank
+ DataBank bank = event.getBank("RTOF::tdc");
+ int nt = bank.rows(); // number of hits
+ //Hits in the bar downstream and upstream will be matched
+ ArrayList hit_up = new ArrayList<>();
+ ArrayList hit_down = new ArrayList<>();
+
+ //Looping through all hits
+ for (int i = 0; i < nt; i++) {
+ //Getting their properties
+ int sector = bank.getByte("sector", i);
+ int layer = bank.getByte("layer", i);
+ int component = bank.getByte("component", i);
+ int order = bank.getShort("order", i);
+ int tdc = bank.getShort("TDC", i);
+ int tot = bank.getShort("ToT", i);
+
+ //Building a Hit
+ RTOFRawHit hit = new RTOFRawHit(sector, layer, component, order, tdc, tot);
+ if (hit.getEnergy() < 0.01) {
+ continue; //energy threshold
+ }
+
+ //Sorting the hits into upstream and downstream bar hits
+ //Lists are built for up/down bar to match them after
+ if (null == hit.getType()) {
+ System.out.print("Undefined hit type \n");
+ } else {
+ switch (hit.getType()) {
+ case "bar up" ->
+ hit_up.add(hit);
+ case "bar down" ->
+ hit_down.add(hit);
+ default ->
+ System.out.print("Undefined hit type \n");
+ }
+ }
+ }//End loop through all hits
+
+ //Starting loop through up hits in the bar
+ for (int i_up = 0; i_up < hit_up.size(); i_up++) {
+ RTOFRawHit this_hit_up = hit_up.get(i_up);
+ int countMatches = 0;
+ //Starting loop through down hits in the bar
+ for (int i_down = 0; i_down < hit_down.size(); i_down++) {
+ RTOFRawHit this_hit_down = hit_down.get(i_down);
+ //Matching the hits: if same bar and different order, they make up a rtof hit
+ if (this_hit_up.matchBar(this_hit_down)) {
+ if (countMatches > 0) {
+ //If the up hit was already involved in a match, do not make an additionnal match
+ //Chosing to ignore double matches for now because it happened for <1% of events in cosmic runs
+ continue;
+ }
+ RTOFHit this_rtof_hit = new RTOFHit(this_hit_down, this_hit_up);
+ this.rtofHits.add(this_rtof_hit);
+ countMatches++;
+ }
+ }
+ }
+ //Once all has been listed, hits are sorted by energy
+ Collections.sort(this.rtofHits, (hit1, hit2) -> Double.compare(hit2.getEnergy(), hit1.getEnergy()));
+ }
+}
diff --git a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/Parameters.java b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/Parameters.java
new file mode 100644
index 0000000000..c6b8f7f9fc
--- /dev/null
+++ b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/Parameters.java
@@ -0,0 +1,25 @@
+package org.jlab.service.recoil.tof;
+
+/**
+ *
+ * @author npilleux, Nilanga Wickramaarachchi
+ */
+public class Parameters {
+
+ public static final double VEFF = 20.0;//cm/ns
+ public static final double TDC2TIME = 0.015625;//ns per channel bin
+ public static final double ATT_L = 160.0;//cm
+ public static final double TOT2ENERGY = 1.956 * 0.5 /1000;//to MeV
+
+ //public static double SIGMA_Y_TRACK_MATCHING_BAR = 20.0;//in cm
+ public static double SIGMA_Y_CLUSTERING = 4.0;//in cm
+ public static double SIGMA_T_CLUSTERING = 100;// in ns
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String[] args) {
+ // TODO code application logic here
+ }
+
+}
diff --git a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RTOFCluster.java b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RTOFCluster.java
new file mode 100644
index 0000000000..a5cf256a59
--- /dev/null
+++ b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RTOFCluster.java
@@ -0,0 +1,240 @@
+package org.jlab.service.recoil.tof;
+
+import java.util.ArrayList;
+import org.jlab.io.base.DataEvent;
+
+/**
+ * The {@code RTOFCluster} represents clusters in the recoil tof
+ *
+ *
+ * Create clusters and compute their basic properties from the hits composing
+ * them.
+ *
+ *
+ * @author pilleux, Nilanga Wickramaarachchi
+ */
+public class RTOFCluster {
+
+ /**
+ * list of hits in the bars.
+ */
+ ArrayList rtofHits;
+ /**
+ * cluster properties:position [cm], time [ns], energy[MeV],
+ * type of the maximum hit (to set resolutions) and index and sector of the maximum hit.
+ */
+ double x, y, z, time, energy;
+ String typeMaxHit;
+ int indexMaxHit, sectorMaxHit;
+
+ public ArrayList getRTOFHits() {
+ return rtofHits;
+ }
+
+ public void setRTOFHits(ArrayList rtof_hits) {
+ this.rtofHits = rtof_hits;
+ }
+
+ public double getX() {
+ return x;
+ }
+
+ public void setX(double x) {
+ this.x = x;
+ }
+
+ public double getY() {
+ return y;
+ }
+
+ public void setY(double y) {
+ this.y = y;
+ }
+
+ public double getZ() {
+ return z;
+ }
+
+ public void setZ(double z) {
+ this.z = z;
+ }
+
+ public double getTime() {
+ return time;
+ }
+
+ public void setTime(double time) {
+ this.time = time;
+ }
+
+ public double getEnergy() {
+ return energy;
+ }
+
+ public void setEnergy(double energy) {
+ this.energy = energy;
+ }
+
+
+ public String getTypeMaxHit() {
+ return typeMaxHit;
+ }
+
+ public void setTypeMaxHit(String typeMaxHit) {
+ this.typeMaxHit = typeMaxHit;
+ }
+
+ public int getIndexMaxHit() {
+ return indexMaxHit;
+ }
+
+ public void setIndexMaxHit(int indexMaxHit) {
+ this.indexMaxHit = indexMaxHit;
+ }
+
+ public int getSectorMaxHit() {
+ return sectorMaxHit;
+ }
+
+ public void setSectorMaxHit(int sectorMaxHit) {
+ this.sectorMaxHit = sectorMaxHit;
+ }
+
+ /**
+ * Compute the cluster properties.
+ *
+ * Cluster coordinates and time are defined as the coordinates and time of
+ * the max energy hit.
+ *
+ * TO DO: Test other choices for the definitions.
+ *
+ */
+ public final void computeClusterProperties() {
+ this.energy = 0;
+ double max_energy = -1;
+ RTOFRawHit max_energy_hit = new RTOFRawHit();
+
+ for (int i_bar = 0; i_bar < this.rtofHits.size(); i_bar++) {
+ RTOFHit this_rtof_hit = this.rtofHits.get(i_bar);
+ double this_energy = this_rtof_hit.getEnergy();
+ this.energy += this_energy;
+ if (this_energy > max_energy) {
+ max_energy_hit = this_rtof_hit;
+ max_energy = this_energy;
+ }
+ }
+
+ this.time = max_energy_hit.getTime();
+ this.x = max_energy_hit.getX();
+ this.y = max_energy_hit.getY();
+ this.z = max_energy_hit.getZ();
+ this.typeMaxHit = max_energy_hit.getType();
+ this.sectorMaxHit = max_energy_hit.getSector();
+ }
+
+
+ /**
+ * Computes the energy deposited in the bars.
+ *
+ * @return the energy deposited in the bars.
+ *
+ */
+ public double getEdepBar() {
+ double energy = 0;
+ for (int i = 0; i < this.rtofHits.size(); i++) {
+ RTOFRawHit this_hit = this.rtofHits.get(i);
+ energy += this_hit.getEnergy();
+ }
+ return energy;
+ }
+
+ /**
+ * Compute the cluster phi angle in radians.
+ *
+ * @return a double that is angle in radians
+ *
+ */
+ public double getPhi() {
+ return Math.atan2(this.y, this.x);
+ }
+
+
+ /**
+ * Retrieve the hit with maximal energy in the cluster. It must have been
+ * computed previously.
+ *
+ * @return a RTOFRawHit that is the maximal energy hit in the cluster
+ *
+ */
+ public final RTOFRawHit getMaxHit() {
+ if (this.typeMaxHit == null) {
+ System.out.print("You did not compute the maximal hit! \n");
+ return null;
+ }
+ if (null == this.typeMaxHit) {
+ System.out.print("Unrecognized type! \n");
+ return null;
+ } else {
+ switch (this.typeMaxHit) {
+ case "bar" -> {
+ return this.rtofHits.get(this.indexMaxHit);
+ }
+ default -> {
+ System.out.print("Unrecognized type! \n");
+ return null;
+ }
+ }
+ }
+ }
+
+ /**
+ * Computes the sum of TOT in the cluster.
+ *
+ * @return an int representing the summed TOT
+ *
+ */
+ public int getTot() {
+ int tot = 0;
+ for (int i = 0; i < this.rtofHits.size(); i++) {
+ RTOFHit this_hit = this.rtofHits.get(i);
+ tot += this_hit.getTot();
+ }
+ return tot;
+ }
+
+ /**
+ * Returns the TDC of the maximal hit in the cluster.
+ *
+ * @return an int representing the TDC of the maximal hit.
+ *
+ */
+ public int getTdc() {
+ return this.getMaxHit().getTdc();
+ }
+
+ /**
+ * Constructor that initializes the list of bar hits
+ * and computes the cluster properties.
+ *
+ * @param rtof_hits a {@link ArrayList} of {@link RTOFHit}.
+ *
+ */
+ public RTOFCluster(ArrayList rtof_hits) {
+ this.rtofHits = rtof_hits;
+ this.computeClusterProperties();
+ }
+
+ /**
+ * Constructor that initializes the list of bar hits
+ * and computes the cluster properties.
+ *
+ * @param rtof_hits a {@link ArrayList} of {@link RTOFHit}.
+ * @param event a {@link DataEvent} with which track matching will be done.
+ *
+ */
+ public RTOFCluster(ArrayList rtof_hits, DataEvent event) {
+ this.rtofHits = rtof_hits;
+ this.computeClusterProperties();
+ }
+
+}
diff --git a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RTOFEngine.java b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RTOFEngine.java
new file mode 100644
index 0000000000..0bde218987
--- /dev/null
+++ b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RTOFEngine.java
@@ -0,0 +1,82 @@
+package org.jlab.service.recoil.tof;
+
+import java.util.ArrayList;
+
+import org.jlab.clas.reco.ReconstructionEngine;
+import org.jlab.io.base.DataBank;
+import org.jlab.io.base.DataEvent;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import org.jlab.detector.calib.utils.DatabaseConstantProvider;
+import org.jlab.io.hipo.HipoDataSource;
+import org.jlab.service.recoil.tof.RecoBankWriter;
+import org.jlab.service.recoil.tof.RTOFCluster;
+import org.jlab.service.recoil.tof.ClusterFinder;
+import org.jlab.service.recoil.tof.RTOFRawHit;
+import org.jlab.service.recoil.tof.RTOFHit;
+import org.jlab.service.recoil.tof.HitFinder;
+
+/**
+ * Service to return reconstructed RTOF hits and clusters
+ *
+ * @author npilleux, Nilanga Wickramaarachchi
+ *
+ */
+public class RTOFEngine extends ReconstructionEngine {
+
+ public RTOFEngine() {
+ super("RTOF", "Nilanga Wickramaarachchi", "1.0");
+ }
+
+ RecoBankWriter rbc;
+
+ private final AtomicInteger run = new AtomicInteger(0);
+
+ @Override
+ public boolean processDataEventUser(DataEvent event) {
+
+ if (!event.hasBank("RUN::config")) {
+ return true;
+ }
+
+
+ //Hit finder init
+ HitFinder hitfinder = new HitFinder();
+ hitfinder.findHits(event);
+
+ ArrayList RTOFHits = hitfinder.getRTOFHits();
+
+ //Exit if hit list is empty
+ if (RTOFHits.isEmpty()) {
+ // System.out.println("No hits : ");
+ // event.show();
+ return true;
+ }
+
+ ClusterFinder clusterFinder = new ClusterFinder();
+ clusterFinder.makeClusters(event,hitfinder);
+ ArrayList Clusters = clusterFinder.getClusters();
+
+ if (RTOFHits.size() != 0) {
+ rbc.appendRTOFBanks(event, RTOFHits, Clusters);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean init() {
+ rbc = new RecoBankWriter();
+
+ this.registerOutputBank("RTOF::hits", "RTOF::clusters");
+
+ return true;
+ }
+
+ public static void main(String arg[]) {
+ }
+
+ @Override
+ public void detectorChanged(int run) {}
+
+}
+
diff --git a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RTOFHit.java b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RTOFHit.java
new file mode 100644
index 0000000000..87330bc1ce
--- /dev/null
+++ b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RTOFHit.java
@@ -0,0 +1,140 @@
+package org.jlab.service.recoil.tof;
+
+import org.jlab.detector.geant4.v2.recoil.tof.RTOFConstants;
+
+/**
+ *
+ * Represents a hit in the recoil tof bar. Extends class RTOFRawHit. Is further defined
+ * by the two hits upstream and downstream composing a full rtof hit. y position,
+ * time and energy are defined from the up/down hits.
+ *
+ * @author npilleux, Nilanga Wickramaarachchi
+ */
+public class RTOFHit extends RTOFRawHit {
+
+ //A rtof hit is the combination of a downstream and upstream hits
+ private RTOFRawHit hitUp, hitDown;
+
+ public RTOFRawHit getHitUp() {
+ return hitUp;
+ }
+
+ public void setHitUp(RTOFRawHit hit_up) {
+ this.hitUp = hit_up;
+ }
+
+ public RTOFRawHit getHitDown() {
+ return hitDown;
+ }
+
+ public void setHitDown(RTOFRawHit hit_down) {
+ this.hitDown = hit_down;
+ }
+
+ /**
+ * Computes rtof hit y local coordinate from up/downstream hit times.
+ *
+ */
+ public final void computeLocalY() {
+ this.setLocalY(Parameters.VEFF/2. * (hitUp.getTime() - hitDown.getTime()));
+ }
+
+ /**
+ * Computes rtof hit y coordinate in the global coordinate system.
+ *
+ */
+ public final void computeGlobalY() {
+ double localY = this.getLocalY();
+ int nRows = RTOFConstants.NROWS;
+ double y_start = -(RTOFConstants.LENGTH - RTOFConstants.LONG_BAR_LENGTH)/2; // Starting Y position
+ double dy_long = RTOFConstants.LONG_BAR_LENGTH;
+ double dy_short = RTOFConstants.SHORT_BAR_LENGTH;
+
+ double y_pos; // y coordinate of the center of bar wrt to the global coordinate system
+ if(hitUp.getRow()-1 < (nRows - 1)/2)
+ {
+ y_pos = y_start + ((hitUp.getRow()-1) * dy_long);
+ }
+ else if (hitUp.getRow()-1 == (nRows-1) / 2) // middle row
+ {
+ y_pos = 0;
+ }
+ else
+ {
+ y_pos = y_start + (hitUp.getRow()-2) * dy_long + dy_short;
+ }
+
+ this.setY(y_pos + localY);
+ }
+
+ /**
+ * Computes rtof hit time from up/downstream hit times.
+ * The time is set as the time of the most energetic hit.
+ * It is corrected for propagation time.
+ *
+ */
+ public final void computeTime() {
+ //We pick the most energetic signal as the timing signal
+ double time_at_sipm, distance_to_sipm;
+ if(this.hitDown.getEnergy() > this.hitUp.getEnergy()) {
+ time_at_sipm = this.hitDown.getTime();
+ if(this.hitDown.getRow() == 3) distance_to_sipm = RTOFConstants.SHORT_BAR_LENGTH/2. - this.getLocalY();
+ else distance_to_sipm = RTOFConstants.LONG_BAR_LENGTH/2. - this.getLocalY();
+ }
+ else {
+ time_at_sipm = this.hitUp.getTime();
+ if(this.hitUp.getRow() == 3) distance_to_sipm = RTOFConstants.SHORT_BAR_LENGTH/2. + this.getLocalY();
+ else distance_to_sipm = RTOFConstants.LONG_BAR_LENGTH/2. + this.getLocalY();
+ }
+ this.setTime(time_at_sipm - distance_to_sipm/Parameters.VEFF);
+ }
+
+ /**
+ * Computes rtof hit energy from up/downstream hits.
+ * The energy of the up/downstream hits is corrected for attenuation now that y is known.
+ * The energy of the rtof hit is the sum of the energy of the up/downstream hits.
+ *
+ */
+ public final void computeEnergy() {
+ this.computeLocalY();
+ double distance_hit_to_sipm_up, distance_hit_to_sipm_down;
+
+ if (hitUp.getRow() == 3) distance_hit_to_sipm_up = RTOFConstants.SHORT_BAR_LENGTH / 2. + this.getLocalY();
+ else distance_hit_to_sipm_up = RTOFConstants.LONG_BAR_LENGTH / 2. + this.getLocalY();
+
+ if (hitDown.getRow() == 3) distance_hit_to_sipm_down = RTOFConstants.SHORT_BAR_LENGTH / 2. - this.getLocalY();
+ else distance_hit_to_sipm_down = RTOFConstants.LONG_BAR_LENGTH / 2. - this.getLocalY();
+
+ double Edep_up = hitUp.getEnergy() * Math.exp(distance_hit_to_sipm_up / Parameters.ATT_L);
+ double Edep_down = hitDown.getEnergy() * Math.exp(distance_hit_to_sipm_down / Parameters.ATT_L);
+ this.setEnergy(Edep_up + Edep_down);
+ }
+
+ public RTOFHit(RTOFRawHit hit_down, RTOFRawHit hit_up) {
+ boolean hits_match = hit_down.matchBar(hit_up);
+ if (!hits_match) {
+ throw new UnsupportedOperationException("Hits do not match \n");
+ }
+ this.setType("bar");
+ this.setOrder(2);//Fake order for bar hits
+ this.hitUp = hit_up;
+ this.hitDown = hit_down;
+ this.setSector(hit_up.getSector());
+ this.setRow(hit_up.getRow());
+ this.setColumn(hit_up.getColumn());
+ this.setX(hit_up.getX());
+ this.setZ(hit_up.getZ());
+ this.computeLocalY();
+ this.computeGlobalY();
+ this.computeTime();
+ this.computeEnergy();
+ this.setTdc((hit_down.getTdc() + hit_up.getTdc())/2);
+ this.setTot((hit_down.getTot() + hit_up.getTot()));
+ }
+
+ public RTOFHit() {
+ super();
+ this.setType("bar");
+ this.setOrder(2);//Fake order for rtof hits
+ }
+}
diff --git a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RTOFRawHit.java b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RTOFRawHit.java
new file mode 100644
index 0000000000..3feabdc5ac
--- /dev/null
+++ b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RTOFRawHit.java
@@ -0,0 +1,398 @@
+package org.jlab.service.recoil.tof;
+
+import org.jlab.detector.geant4.v2.recoil.tof.RTOFConstants;
+
+/**
+ *
+ * Represents a hit in the recoil tof. Stores info about the sector, row, column,
+ * order, TDC, ToT. Type is bar up/bar down/ bar. Stores whether
+ * the hit is part of a cluster. Calculates time, energy based on TDC/ToT.
+ *
+ * @author npilleux, Nilanga Wickramaarachchi
+ */
+public class RTOFRawHit {
+
+ private int sector, row, column, order;
+ private int tdc, tot;
+ private double time, energy, x, y, z, local_y;
+ private String type;
+ private boolean isInACluster;
+ private int associatedClusterIndex;
+ int idTDC;
+
+ /**
+ * Constructor for a hit in the recoil tof. Initializes the hit's sector, row,
+ * column, order, TDC, ToT. Sets the hit's initial state regarding
+ * clustering. Set up the hit's type, time, energy, and spatial coordinates.
+ *
+ * @param sector The sector of the detector where the hit occurred.
+ * @param row The row of the detector where the hit was detected.
+ * @param column The column within the row that registered the hit.
+ * @param order Order of the hit.
+ * @param tdc TDC value.
+ * @param tot ToT value.
+ *
+ */
+ public RTOFRawHit(int sector, int row, int column, int order, int tdc, int tot) {
+ this.sector = sector;
+ this.row = row;
+ this.column = column;
+ this.order = order;
+ this.tdc = tdc;
+ this.tot = tot;
+ this.isInACluster = false;
+
+ this.makeType();
+ this.convertTdcToTime();
+ this.convertTotToEnergy();
+ this.calculateXYZ();
+ }
+
+ public RTOFRawHit() {
+ }
+
+ public int getSector() {
+ return sector;
+ }
+
+ public void setSector(int sector) {
+ this.sector = sector;
+ }
+
+ public int getRow() {
+ return row;
+ }
+
+ public void setRow(int row) {
+ this.row = row;
+ }
+
+ public int getOrder() {
+ return order;
+ }
+
+ public void setOrder(int order) {
+ this.order = order;
+ }
+
+ public int getColumn() {
+ return column;
+ }
+
+ public void setColumn(int column) {
+ this.column = column;
+ }
+
+ public int getTdc() {
+ return tdc;
+ }
+
+ public void setTdc(int tdc) {
+ this.tdc = tdc;
+ }
+
+ public int getTot() {
+ return tot;
+ }
+
+ public void setTot(int tot) {
+ this.tot = tot;
+ }
+
+ public double getTime() {
+ return time;
+ }
+
+ public void setTime(double time) {
+ this.time = time;
+ }
+
+ public double getEnergy() {
+ return energy;
+ }
+
+ public void setEnergy(double energy) {
+ this.energy = energy;
+ }
+
+ public double getX() {
+ return x;
+ }
+
+ public void setX(double x) {
+ this.x = x;
+ }
+
+ public double getY() {
+ return y;
+ }
+
+ public void setY(double y) {
+ this.y = y;
+ }
+
+ public double getLocalY() {
+ return local_y;
+ }
+
+ public void setLocalY(double local_y) {
+ this.local_y = local_y;
+ }
+
+ public double getZ() {
+ return z;
+ }
+
+ public void setZ(double z) {
+ this.z = z;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public boolean getIsInACluster() {
+ return isInACluster;
+ }
+
+ public void setIsInACluster(boolean is_in_a_cluster) {
+ this.isInACluster = is_in_a_cluster;
+ }
+
+ public int getAssociatedClusterIndex() {
+ return associatedClusterIndex;
+ }
+
+ public void setAssociatedClusterIndex(int index) {
+ this.associatedClusterIndex = index;
+ }
+
+ public int getIdTDC() {
+ return idTDC;
+ }
+
+ public void setIdTDC(int index) {
+ this.idTDC = index;
+ }
+
+
+ /**
+ * Assigns a type to the hit.
+ *
+ */
+ public final String makeType() {
+ //Type of hit can be bar up, bar down or bar.
+ //Avoids testing components and order every time.
+ String itype = "undefined";
+ if (this.order == 0) {
+ itype = "bar down";
+ } else if (this.order == 1) {
+ itype = "bar up";
+ }
+ this.type = itype;
+ return itype;
+ }
+
+ /**
+ * Converts TDC to time (ns). Sets the hit time parameter to a raw time for
+ * up/down bar hits.
+ *
+ * @return 0 if the time was successfully set, or 1 if the hit type is
+ * unsupported.
+ */
+ public final int convertTdcToTime() {
+ double tdc2time, veff, distance_to_sipm;
+ if (null == this.type) {
+ System.out.print("Null hit type, cannot convert tdc to time.");
+ return 1;
+ } else {
+ switch (this.type) {
+ case "bar up" -> {
+ tdc2time = Parameters.TDC2TIME;
+ veff = Parameters.VEFF;
+ //The distance will be computed at barhit level when y information is available
+ distance_to_sipm = 0;
+ }
+ case "bar down" -> {
+ tdc2time = Parameters.TDC2TIME;
+ veff = Parameters.VEFF;
+ //The distance will be computed at barhit level when y information is available
+ distance_to_sipm = 0;
+ }
+ case "bar" -> {
+ System.out.print("Bar hit type, cannot convert tdc to time.");
+ return 1;
+ }
+ default -> {
+ System.out.print("Undefined hit type, cannot convert tdc to time.");
+ return 1;
+ }
+ }
+ }
+ //Hit time. Will need implementation of offsets.
+ this.time = tdc2time * this.tdc - distance_to_sipm / veff;
+ return 0;
+ }
+
+ /**
+ * Converts ToT to energy (MeV). Sets the hit energy parameter to a raw
+ * energy for up/down bar hits.
+ *
+ * @return 0 if the energy was successfully set, or 1 if the hit type is
+ * unsupported.
+ */
+ public final int convertTotToEnergy() {
+ double tot2energy;
+ if (null == this.type) {
+ System.out.print("Null hit type, cannot convert tot to energy.");
+ return 1;
+ } else {
+ switch (this.type) {
+ case "bar up" -> {
+ tot2energy = Parameters.TOT2ENERGY;
+ //only half the information in the bar,
+ //the attenuation will be computed when the full hit is formed
+ this.energy = tot2energy * this.tot;
+ }
+ case "bar down" -> {
+ tot2energy = Parameters.TOT2ENERGY;
+ //only half the information in the bar,
+ //the attenuation will be computed when the full hit is formed
+ this.energy = tot2energy * this.tot;
+ }
+ case "bar" -> {
+ System.out.print("Bar hit type, cannot convert tot to energy.");
+ return 1;
+ }
+ default -> {
+ System.out.print("Undefined hit type, cannot convert tot to energy.");
+ return 1;
+ }
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Calculates spatial coordinates (cm) for the hit based on row and column number of the bar within a sector.
+ * The row and column variables are obtained from the bank information.
+ *
+ * @return 0 if the coordinates were successfully set, or 1 if the hit type
+ * is undefined or unsupported.
+ */
+ public final int calculateXYZ() {
+
+ // Constants for positioning
+ int nRows = RTOFConstants.NROWS;
+ double y_start = -(RTOFConstants.LENGTH - RTOFConstants.LONG_BAR_LENGTH)/2; // Starting Y position
+ double x_spacing = RTOFConstants.BAR_WIDTH;
+ double x_start = -(RTOFConstants.WIDTH - x_spacing)/2; // starting X position
+ double dy_long = RTOFConstants.LONG_BAR_LENGTH;
+ double dy_short = RTOFConstants.SHORT_BAR_LENGTH;
+
+ //Position calculation
+ double z_pos = 0;
+ double x_pos = x_start + ((this.column-1) * x_spacing);
+
+ double y_pos;
+ if(this.row-1 < (nRows - 1) / 2)
+ {
+ y_pos = y_start + ((this.row-1) * dy_long);
+ }
+ else if (this.row-1 == (nRows - 1) / 2) // middle row
+ {
+ y_pos = 0;
+ }
+ else
+ {
+ y_pos = y_start + (this.row -2) * dy_long + dy_short;
+ }
+
+ double[] localCoords = {x_pos, y_pos, z_pos};
+
+ // Calculate center coordinates for the sector
+ double sector_x = (-1+(this.sector-1)*2)*(RTOFConstants.RADIUS)*Math.sin(Math.toRadians(RTOFConstants.HORIZONTAL_OPENING_ANGLE/2+RTOFConstants.HORIZONTAL_STARTING_ANGLE));
+ double sector_y = 0;
+ double sector_z = RTOFConstants.RADIUS*Math.cos(Math.toRadians(RTOFConstants.HORIZONTAL_OPENING_ANGLE/2+RTOFConstants.HORIZONTAL_STARTING_ANGLE));
+
+ // Global coordinates of the sector
+ double[] globalCoordsSector = {sector_x, sector_y, sector_z};
+
+ // Rotation angle in radians
+ double thetaY = 0;
+
+ if(this.sector==1) thetaY = Math.toRadians(-(RTOFConstants.HORIZONTAL_OPENING_ANGLE/2+RTOFConstants.HORIZONTAL_STARTING_ANGLE));
+ if(this.sector==2) thetaY = Math.toRadians(RTOFConstants.HORIZONTAL_OPENING_ANGLE/2+RTOFConstants.HORIZONTAL_STARTING_ANGLE);
+
+ // Rotation matrix around the Y-axis
+ double[][] Ry = {
+ {Math.cos(thetaY), 0, Math.sin(thetaY)},
+ {0, 1, 0},
+ {-Math.sin(thetaY), 0, Math.cos(thetaY)}
+ };
+
+ // Rotate local coordinates
+ double[] rotatedCoords = new double[3];
+ for (int i = 0; i < 3; i++) {
+ rotatedCoords[i] = Ry[i][0] * localCoords[0] + Ry[i][1] * localCoords[1] + Ry[i][2] * localCoords[2];
+ }
+
+ // Calculate global coordinates for the hit
+ double[] globalCoordsBar = new double[3];
+ for (int i = 0; i < 3; i++) {
+ globalCoordsBar[i] = globalCoordsSector[i] + rotatedCoords[i];
+ }
+
+
+ this.x = globalCoordsBar[0];
+ this.y = globalCoordsBar[1];
+ this.z = globalCoordsBar[2];
+ return 0;
+ }
+
+ /**
+ * Compares two RTOFRawHit objects to check if they match in the bar.
+ *
+ * - If the sector or row or column of the two hits do not match, the method
+ * returns {@code false}.
+ * - If both hits are in the same SiPM (i.e., their order is the same), or
+ * have incorrect order, the method returns {@code false}.
+ *
+ * If none of these conditions are violated, the method returns
+ * {@code true}, indicating the two hits match.
+ *
+ * @param hit2match The RTOFRawHit object to compare with the current instance.
+ * @return {@code true} if the hits match; {@code false} otherwise.
+ */
+ public boolean matchBar(RTOFRawHit hit2match) {
+ if (this.getSector() != hit2match.getSector()) {
+ //Two hits in different sectors
+ return false;
+ } else if (this.getRow() != hit2match.getRow()) {
+ //Two hits in different rows
+ return false;
+ } else if (this.getColumn() != hit2match.getColumn()) {
+ //Two hits in different columns
+ return false;
+ } else if (this.getOrder() > 1 || hit2match.getOrder() > 1) {
+ //At least one hit has incorrect order
+ return false;
+ } else {
+ //Match if one is order 0 and the other is order 1
+ return this.getOrder() != hit2match.getOrder();
+ }
+ }
+
+ /**
+ * Computes the azimuthal angle (phi) of the hit in rad.
+ *
+ * @return The azimuthal angle (phi) in radians, in the range [-π, π].
+ */
+ public double getPhi() {
+ return Math.atan2(this.y, this.x);
+ }
+}
diff --git a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RecoBankWriter.java b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RecoBankWriter.java
new file mode 100644
index 0000000000..1383871435
--- /dev/null
+++ b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/tof/RecoBankWriter.java
@@ -0,0 +1,115 @@
+package org.jlab.service.recoil.tof;
+
+import java.util.ArrayList;
+import org.jlab.io.base.DataBank;
+import org.jlab.io.base.DataEvent;
+
+/**
+ * The {@code RecoBankWriter} writes the banks needed for the recoil tof
+ * reconstruction: hits and clusters info.
+ *
+ * @author pilleux, Nilanga Wickramaarachchi
+ */
+public class RecoBankWriter {
+
+ /**
+ * Writes the bank of recoil tof hits.
+ *
+ * @param event the {@link DataEvent} in which to add the bank
+ * @param rtofHits the {@link ArrayList} of {@link RTOFHit} containing the rtof
+ * hits to be added to the bank
+ *
+ * @return {@link DataBank} the bank with all the hits read in the event.
+ *
+ */
+ public static DataBank fillRTOFRawHitBank(DataEvent event, ArrayList rtofHits) {
+
+ ArrayList hitList = new ArrayList<>();
+ hitList.addAll(rtofHits);
+
+ DataBank bank = event.createBank("RTOF::hits", hitList.size());
+
+ if (bank == null) {
+ System.err.println("COULD NOT CREATE A RTOF::hits BANK!!!!!!");
+ return null;
+ }
+
+ for (int i = 0; i < hitList.size(); i++) {
+ bank.setShort("id", i, (short) (i + 1));
+ bank.setShort("clusterid", i, (short) hitList.get(i).getAssociatedClusterIndex());
+ bank.setByte("sector", i, (byte) hitList.get(i).getSector());
+ bank.setByte("layer", i, (byte) hitList.get(i).getRow());
+ bank.setByte("component", i, (byte) hitList.get(i).getColumn());
+ bank.setFloat("time", i, (float) hitList.get(i).getTime());
+ bank.setFloat("x", i, (float) (hitList.get(i).getX()));
+ bank.setFloat("y", i, (float) (hitList.get(i).getY()));
+ bank.setFloat("z", i, (float) (hitList.get(i).getZ()));
+ bank.setFloat("energy", i, (float) hitList.get(i).getEnergy());
+ }
+ return bank;
+ }
+
+ /**
+ * Writes the bank of rtof clusters.
+ *
+ * @param event the {@link DataEvent} in which to add the bank
+ * @param clusterList the {@link ArrayList} of {@link RTOFCluster}
+ * containing the clusters info to be added to the bank
+ *
+ * @return {@link DataBank} the bank with all the clusters built in the
+ * event.
+ *
+ */
+ public static DataBank fillRTOFClusterBank(DataEvent event, ArrayList clusterList) {
+
+ DataBank bank = event.createBank("RTOF::clusters", clusterList.size());
+
+ if (bank == null) {
+ System.err.println("COULD NOT CREATE A RTOF::clusters BANK!!!!!!");
+ return null;
+ }
+
+ for (int i = 0; i < clusterList.size(); i++) {
+ bank.setShort("id", i, (short) (i + 1));
+ bank.setShort("size", i, (short) clusterList.get(i).getRTOFHits().size());
+ bank.setByte("sector", i, (byte) clusterList.get(i).getSectorMaxHit());
+ bank.setFloat("time", i, (float) clusterList.get(i).getTime());
+ bank.setFloat("x", i, (float) (clusterList.get(i).getX()));
+ bank.setFloat("y", i, (float) (clusterList.get(i).getY()));
+ bank.setFloat("z", i, (float) (clusterList.get(i).getZ()));
+ bank.setFloat("energy", i, (float) clusterList.get(i).getEnergy());
+ }
+ return bank;
+ }
+
+ /**
+ * Appends the rtof banks to an event.
+ *
+ * @param event the {@link DataEvent} in which to append the banks
+ * @param clusterList the {@link ArrayList} of {@link RTOFCluster}
+ * containing the clusters info to be added to the bank
+ * @param rtofHits the {@link ArrayList} of {@link RTOFHit} containing the bar
+ * hits info to be added
+ *
+ * @return 0 if it worked, 1 if it failed
+ *
+ */
+ public int appendRTOFBanks(DataEvent event, ArrayList rtofHits, ArrayList clusterList) {
+
+ DataBank hitbank = this.fillRTOFRawHitBank(event, rtofHits);
+ if (hitbank != null) {
+ event.appendBank(hitbank);
+ } else {
+ return 1;
+ }
+
+ DataBank clusterbank = fillRTOFClusterBank(event, clusterList);
+ if (clusterbank != null) {
+ event.appendBank(clusterbank);
+ } else {
+ return 1;
+ }
+
+ return 0;
+ }
+}
diff --git a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/RecoilCluster.java b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/trk/RTRKCluster.java
similarity index 72%
rename from reconstruction/recoil/src/main/java/org/jlab/service/recoil/RecoilCluster.java
rename to reconstruction/recoil/src/main/java/org/jlab/service/recoil/trk/RTRKCluster.java
index 66a6a5d914..c8c2ac152f 100644
--- a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/RecoilCluster.java
+++ b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/trk/RTRKCluster.java
@@ -1,7 +1,8 @@
-package org.jlab.service.recoil;
+package org.jlab.service.recoil.trk;
import java.util.ArrayList;
import java.util.List;
+import org.jlab.detector.geant4.v2.recoil.trk.RTRKConstants;
import org.jlab.detector.base.DetectorDescriptor;
import org.jlab.detector.base.DetectorType;
import org.jlab.geom.prim.Line3D;
@@ -9,21 +10,21 @@
/**
* recoil in-layer cluster
- *
+ *
* @author bondi, devita, niccolai
*/
-public class RecoilCluster extends ArrayList {
-
+public class RTRKCluster extends ArrayList {
- private DetectorDescriptor desc = new DetectorDescriptor(DetectorType.RECOIL);
- private int id;
+
+ private DetectorDescriptor desc = new DetectorDescriptor(DetectorType.RTRK);
+ private int id;
private Line3D clusterLine = new Line3D();
public int indexMaxStrip = -1;
private byte clusterStatus = 1;
- public RecoilCluster(RecoilStrip strip){
- this.desc.setSectorLayerComponent(strip.getDescriptor().getSector(),
- strip.getDescriptor().getLayer(), 0);
+ public RTRKCluster(RTRKStrip strip){
+ this.desc.setSectorLayerComponent(strip.getDescriptor().getSector(),
+ strip.getDescriptor().getLayer(), 0);
this.add(strip);
this.clusterLine.copy(strip.getLine());
this.indexMaxStrip = 0;
@@ -49,11 +50,11 @@ public int getChamber() {
return this.get(0).getChamber();
}
- public Line3D getLine() {return this.clusterLine;}
+ public Line3D getLine() {return this.clusterLine;}
public double getEnergy(){
double energy = 0.0;
- for(RecoilStrip strip : this){
+ for(RTRKStrip strip : this){
energy += strip.getEnergy();
}
return energy;
@@ -61,7 +62,7 @@ public double getEnergy(){
public double getTime(){
double time = 0.0;
- for(RecoilStrip strip : this){
+ for(RTRKStrip strip : this){
time += strip.getTime()*strip.getEnergy();
}
time /= this.getEnergy();
@@ -72,19 +73,19 @@ public double getSeedTime(){
if(this.indexMaxStrip >= 0 && this.indexMaxStrip < this.size()){
return this.get(indexMaxStrip).getTime();
}
- return 0.0;
+ return 0.0;
}
-
- public RecoilStrip getSeedStrip() {
- return this.get(this.indexMaxStrip);
+
+ public RTRKStrip getSeedStrip() {
+ return this.get(this.indexMaxStrip);
}
public int getMaxStrip(){
return this.get(this.indexMaxStrip).getDescriptor().getComponent();
}
- public boolean addStrip(RecoilStrip strip){
- for(RecoilStrip s : this){
+ public boolean addStrip(RTRKStrip strip){
+ for(RTRKStrip s : this){
if(s.isNeighbour(strip)){
this.add(strip);
if(strip.getEnergy()>this.get(indexMaxStrip).getEnergy()){
@@ -99,7 +100,7 @@ public boolean addStrip(RecoilStrip strip){
public int getADC(){
int adc = 0;
- for(RecoilStrip s : this){
+ for(RTRKStrip s : this){
adc+= s.getADC();
}
return adc;
@@ -107,15 +108,15 @@ public int getADC(){
public void setStatus(int val) {this.clusterStatus+=val;}
- public byte getStatus() {return clusterStatus;}
+ public byte getStatus() {return clusterStatus;}
public void setClusterId(int id){
this.id = id;
- for(RecoilStrip strip : this){
+ for(RTRKStrip strip : this){
strip.setClusterId(id);
}
}
-
+
public void redoClusterLine(){
Point3D pointOrigin = new Point3D(0.0,0.0,0.0);
@@ -138,37 +139,36 @@ public void redoClusterLine(){
pointEnd.setX(pointEnd.x()+line.end().x()*le);
pointEnd.setY(pointEnd.y()+line.end().y()*le);
pointEnd.setZ(pointEnd.z()+line.end().z()*le);
-
+
logSumm += le;
summE += energy;
}
-
+
this.clusterLine.set(
- pointOrigin.x()/logSumm,
- pointOrigin.y()/logSumm,
- pointOrigin.z()/logSumm,
- pointEnd.x()/logSumm,
- pointEnd.y()/logSumm,
- pointEnd.z()/logSumm
+ pointOrigin.x()/logSumm,
+ pointOrigin.y()/logSumm,
+ pointOrigin.z()/logSumm,
+ pointEnd.x()/logSumm,
+ pointEnd.y()/logSumm,
+ pointEnd.z()/logSumm
);
}
-
- public static List createClusters(List stripList){
-
- List clusterList = new ArrayList<>();
+ public static List createClusters(List stripList){
+
+ List clusterList = new ArrayList<>();
if(!stripList.isEmpty()){
- for(int loop = 0; loop < stripList.size(); loop++){ //Loop over all strips
- boolean stripAdded = false;
- for(RecoilCluster cluster : clusterList) {
+ for(int loop = 0; loop < stripList.size(); loop++){ //Loop over all strips
+ boolean stripAdded = false;
+ for(RTRKCluster cluster : clusterList) {
if(cluster.addStrip(stripList.get(loop))){ //Add adjacent strip to newly seeded peak
stripAdded = true;
}
}
if(!stripAdded){
- RecoilCluster newPeak = new RecoilCluster(stripList.get(loop)); //Non-adjacent strip seeds new peak
+ RTRKCluster newPeak = new RTRKCluster(stripList.get(loop)); //Non-adjacent strip seeds new peak
clusterList.add(newPeak);
}
}
@@ -178,11 +178,11 @@ public static List createClusters(List stripList){
clusterList.get(loop).redoClusterLine();
}
return clusterList;
- }
+ }
- public static List getClusters(List clusters, int sector, int layer) {
- List selectedClusters = new ArrayList<>();
- for(RecoilCluster cluster : clusters) {
+ public static List getClusters(List clusters, int sector, int layer) {
+ List selectedClusters = new ArrayList<>();
+ for(RTRKCluster cluster : clusters) {
if(cluster.getSector()==sector && cluster.getLayer()==layer)
selectedClusters.add(cluster);
}
@@ -192,11 +192,11 @@ public static List getClusters(List clusters, int
@Override
public String toString(){
StringBuilder str = new StringBuilder();
- str.append(String.format("----> cluster ( %3d %3d ) ENERGY = %12.5f\n",
- this.desc.getSector(),this.desc.getLayer(), this.getEnergy()));
+ str.append(String.format("----> cluster ( %3d %3d ) ENERGY = %12.5f\n",
+ this.desc.getSector(),this.desc.getLayer(), this.getEnergy()));
str.append(this.clusterLine.toString());
str.append("\n");
- for(RecoilStrip strip : this){
+ for(RTRKStrip strip : this){
str.append("\t\t");
str.append(strip.toString());
str.append("\n");
@@ -204,9 +204,5 @@ public String toString(){
return str.toString();
}
-
-
-
-
}
diff --git a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/RecoilCross.java b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/trk/RTRKCross.java
similarity index 68%
rename from reconstruction/recoil/src/main/java/org/jlab/service/recoil/RecoilCross.java
rename to reconstruction/recoil/src/main/java/org/jlab/service/recoil/trk/RTRKCross.java
index a2a2ba85e5..4ff69ec157 100644
--- a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/RecoilCross.java
+++ b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/trk/RTRKCross.java
@@ -1,7 +1,8 @@
-package org.jlab.service.recoil;
+package org.jlab.service.recoil.trk;
import java.util.ArrayList;
import java.util.List;
+import org.jlab.detector.geant4.v2.recoil.trk.RTRKConstants;
import org.jlab.geom.prim.Plane3D;
import org.jlab.geom.prim.Point3D;
import org.jlab.geom.prim.Vector3D;
@@ -10,8 +11,8 @@
* recoil V-W clusters
* @author devita, niccolai
*/
-public class RecoilCross {
-
+public class RTRKCross {
+
private int id;
private int sector;
@@ -26,17 +27,15 @@ public class RecoilCross {
private double time;
private int status;
-
-
- public RecoilCross(RecoilCluster c1, RecoilCluster c2) {
+ public RTRKCross(RTRKCluster c1, RTRKCluster c2) {
- Vector3D dir = c1.getLine().direction().cross(c2.getLine().direction());
+ Vector3D dir = c1.getLine().direction().cross(c2.getLine().direction());
Plane3D plane = new Plane3D(c1.getLine().origin(), c1.getLine().direction().cross(dir));
Point3D point = new Point3D();
int nint = plane.intersectionSegment(c2.getLine(), point);
if(nint==1) {
this.sector = c1.getSector();
- this.region = (c1.getLayer()-1)/(RecoilConstants.NLAYER/RecoilConstants.NREGION)+1;
+ this.region = (c1.getLayer()-1)/(RTRKConstants.NLAYERS/RTRKConstants.NREGIONS)+1;
this.cross = point;
this.energy = c1.getEnergy() + c2.getEnergy();
this.time = (c1.getTime() + c2.getTime())/2;
@@ -44,11 +43,11 @@ public RecoilCross(RecoilCluster c1, RecoilCluster c2) {
this.cluster2 = c2.getId();
}
}
-
+
public void setId(int id) {
this.id = id;
}
-
+
public int getId() {
return id;
}
@@ -68,19 +67,19 @@ public int getChamber() {
public int getCluster1() {
return cluster1;
}
-
+
public int getCluster2() {
return cluster2;
}
-
+
public Point3D point() {
return cross;
- }
-
+ }
+
public double getEnergy() {
return energy;
}
-
+
public double getTime() {
return time;
}
@@ -88,21 +87,21 @@ public double getTime() {
public int getStatus() {
return status;
}
-
- public static List createCrosses(List clusters) {
+
+ public static List createCrosses(List clusters) {
- List crosses = new ArrayList<>();
+ List crosses = new ArrayList<>();
- for(int is=0; is clustersV = RecoilCluster.getClusters(clusters, is+1, (RecoilConstants.NLAYER/RecoilConstants.NREGION)*ir+1);
- List clustersW = RecoilCluster.getClusters(clusters, is+1, (RecoilConstants.NLAYER/RecoilConstants.NREGION)*ir+2);
+ for(int is=0; is clustersV = RTRKCluster.getClusters(clusters, is+1, (RTRKConstants.NLAYERS/RTRKConstants.NREGIONS)*ir+1);
+ List clustersW = RTRKCluster.getClusters(clusters, is+1, (RTRKConstants.NLAYERS/RTRKConstants.NREGIONS)*ir+2);
- for(RecoilCluster v : clustersV) {
- for(RecoilCluster w : clustersW) {
+ for(RTRKCluster v : clustersV) {
+ for(RTRKCluster w : clustersW) {
if(v.getChamber()==w.getChamber()) {
- RecoilCross cross = new RecoilCross(v, w);
+ RTRKCross cross = new RTRKCross(v, w);
if(cross.point()!=null) crosses.add(cross);
cross.setId(crosses.size());
}
diff --git a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/RecoilEngine.java b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/trk/RTRKEngine.java
similarity index 76%
rename from reconstruction/recoil/src/main/java/org/jlab/service/recoil/RecoilEngine.java
rename to reconstruction/recoil/src/main/java/org/jlab/service/recoil/trk/RTRKEngine.java
index bbb1bc8bfc..e8263b3533 100644
--- a/reconstruction/recoil/src/main/java/org/jlab/service/recoil/RecoilEngine.java
+++ b/reconstruction/recoil/src/main/java/org/jlab/service/recoil/trk/RTRKEngine.java
@@ -1,4 +1,4 @@
-package org.jlab.service.recoil;
+package org.jlab.service.recoil.trk;
import java.util.List;
import java.util.Optional;
@@ -8,7 +8,8 @@
import org.jlab.clas.reco.ReconstructionEngine;
import org.jlab.detector.base.DetectorType;
import org.jlab.detector.calib.utils.DatabaseConstantProvider;
-import org.jlab.detector.geant4.v2.recoil.RecoilStripFactory;
+import org.jlab.detector.geant4.v2.recoil.trk.RTRKConstants;
+import org.jlab.detector.geant4.v2.recoil.trk.RTRKStripFactory;
import org.jlab.geom.prim.Point3D;
import org.jlab.groot.data.H1F;
import org.jlab.groot.fitter.DataFitter;
@@ -22,69 +23,65 @@
/**
*
* recoil reconstruction engine
- *
+ *
* @author bondi, devita, niccolai
*/
-public class RecoilEngine extends ReconstructionEngine {
-
- public static Logger LOGGER = Logger.getLogger(RecoilEngine.class.getName());
-
- public static RecoilStripFactory factory = new RecoilStripFactory();
-
- public RecoilEngine() {
- super("Recoil","niccolai","1.0");
+public class RTRKEngine extends ReconstructionEngine {
+
+ public static Logger LOGGER = Logger.getLogger(RTRKEngine.class.getName());
+
+ public static RTRKStripFactory factory = new RTRKStripFactory();
+
+ public RTRKEngine() {
+ super("RTRK","niccolai","1.0");
}
-
+
@Override
public boolean init() {
-
+
// init ConstantsManager to read constants from CCDB
String variationName = Optional.ofNullable(this.getEngineConfigString("variation")).orElse("default");
DatabaseConstantProvider cp = new DatabaseConstantProvider(11, variationName);
- factory.init(cp, RecoilConstants.NREGION);
- // register output banks for drop option
- this.registerOutputBank("RECOIL::hits");
- this.registerOutputBank("RECOIL::clusters");
- this.registerOutputBank("RECOIL::crosses");
-
+ factory.init(cp, RTRKConstants.NREGIONS);
+ // register output banks for drop option
+ this.registerOutputBank("RTRK::hits");
+ this.registerOutputBank("RTRK::clusters");
+ this.registerOutputBank("RTRK::crosses");
+
LOGGER.log(Level.INFO, "--> recoil is ready...");
return true;
}
-
-
-
-
+
@Override
public boolean processDataEventUser(DataEvent event) {
- List strips = RecoilStrip.getStrips(event, factory, this.getConstantsManager());
- List clusters = RecoilCluster.createClusters(strips);
- List crosses = RecoilCross.createCrosses(clusters);
+ List strips = RTRKStrip.getStrips(event, factory, this.getConstantsManager());
+ List clusters = RTRKCluster.createClusters(strips);
+ List crosses = RTRKCross.createCrosses(clusters);
this.writeHipoBanks(event, strips, clusters, crosses);
return true;
}
-
- private void writeHipoBanks(DataEvent de,
- List strips,
- List clusters,
- List crosses){
-
- DataBank bankS = de.createBank("RECOIL::hits", strips.size());
+ private void writeHipoBanks(DataEvent de,
+ List strips,
+ List clusters,
+ List crosses){
+
+ DataBank bankS = de.createBank("RTRK::hits", strips.size());
for(int h = 0; h < strips.size(); h++){
bankS.setShort("id", h, (short) strips.get(h).getId());
bankS.setByte("sector", h, (byte) strips.get(h).getDescriptor().getSector());
bankS.setByte("layer", h, (byte) strips.get(h).getDescriptor().getLayer());
bankS.setShort("strip", h, (short) strips.get(h).getDescriptor().getComponent());
bankS.setFloat("energy", h, (float) strips.get(h).getEnergy());
- bankS.setFloat("time", h, (float) strips.get(h).getTime());
+ bankS.setFloat("time", h, (float) strips.get(h).getTime());
bankS.setShort("status", h, (short) strips.get(h).getStatus());
bankS.setShort("clusterId", h, (short) strips.get(h).getClusterId());
}
- DataBank bankC = de.createBank("RECOIL::clusters", clusters.size());
+ DataBank bankC = de.createBank("RTRK::clusters", clusters.size());
for(int c = 0; c < clusters.size(); c++){
bankC.setShort("id", c, (short) clusters.get(c).getId());
bankC.setByte("sector", c, (byte) clusters.get(c).get(0).getDescriptor().getSector());
@@ -99,10 +96,10 @@ private void writeHipoBanks(DataEvent de,
bankC.setFloat("ye", c, (float) clusters.get(c).getLine().end().y());
bankC.setFloat("ze", c, (float) clusters.get(c).getLine().end().z());
bankC.setShort("size", c, (short) clusters.get(c).size());
- bankC.setShort("status", c, (short) clusters.get(c).getStatus());
- }
+ bankC.setShort("status", c, (short) clusters.get(c).getStatus());
+ }
- DataBank bankX = de.createBank("RECOIL::crosses", crosses.size());
+ DataBank bankX = de.createBank("RTRK::crosses", crosses.size());
for(int c = 0; c < crosses.size(); c++){
bankX.setShort("id", c, (short) crosses.get(c).getId());
bankX.setByte("sector", c, (byte) crosses.get(c).getSector());
@@ -112,13 +109,12 @@ private void writeHipoBanks(DataEvent de,
bankX.setFloat("x", c, (float) crosses.get(c).point().x());
bankX.setFloat("y", c, (float) crosses.get(c).point().y());
bankX.setFloat("z", c, (float) crosses.get(c).point().z());
- bankX.setShort("cluster1", c, (short) crosses.get(c).getCluster1());
- bankX.setShort("cluster2", c, (short) crosses.get(c).getCluster2());
- bankX.setShort("status", c, (short) crosses.get(c).getStatus());
- }
+ bankX.setShort("cluster1", c, (short) crosses.get(c).getCluster1());
+ bankX.setShort("cluster2", c, (short) crosses.get(c).getCluster2());
+ bankX.setShort("status", c, (short) crosses.get(c).getStatus());
+ }
de.appendBanks(bankS,bankC,bankX);
}
-
public static void fitGauss(H1F histo) {
double mean = histo.getMean();
@@ -135,7 +131,7 @@ public static void fitGauss(H1F histo) {
f1.setParameter(0, amp);
f1.setParameter(1, mean);
f1.setParameter(2, sigma);
-
+
if(amp>5) {
f1.setParLimits(0, amp*0.2, amp*1.2);
f1.setParLimits(1, mean*0.5, mean*1.5);
@@ -149,36 +145,36 @@ public static void fitGauss(H1F histo) {
f1.setRange(mean-2.0*sigma,mean+2.0*sigma);
DataFitter.fit(f1, histo, "Q");
}
- }
+ }
public static void main (String arg[]) {
-
- RecoilEngine engine = new RecoilEngine();
+
+ RTRKEngine engine = new RTRKEngine();
engine.init();
-
+
String input = "/Users/devita/urwell3d.hipo";
-
+
DataGroup dg = new DataGroup(3, 2);
String[] axes = {"x", "y"};
- for(int il=0; il this.desc.getSector()) return -1;
if(ob.getDescriptor().getLayer() < this.desc.getLayer()) return 1;
@@ -161,46 +160,46 @@ public int compareTo(Object o) {
return -1;
}
- public static List getStrips(DataEvent event, RecoilStripFactory factory, ConstantsManager ccdb) {
+ public static List getStrips(DataEvent event, RTRKStripFactory factory, ConstantsManager ccdb) {
- List strips = new ArrayList<>();
+ List strips = new ArrayList<>();
- if(event.hasBank("RECOIL::adc")){
- RawDataBank bank = new RawDataBank("RECOIL::adc");
+ if(event.hasBank("RTRK::adc")){
+ RawDataBank bank = new RawDataBank("RTRK::adc");
bank.read(event);
- //DataBank bank = event.getBank("RECOIL::adc");
+ //DataBank bank = event.getBank("RTRK::adc");
for(int i = 0; i < bank.rows(); i++){
int sector = bank.getByte("sector", i);
int layer = bank.getByte("layer", i);
int comp = bank.getShort("component", i);
int adc = bank.getInt("ADC", i);
double time = bank.getFloat("time", i);
-
- RecoilStrip strip = new RecoilStrip(sector, layer, comp);
-// strip.setTriggerPhase(triggerPhase);
- strip.setId(bank.trueIndex(i)+1);
- strip.setADC(adc);
- strip.setTDC((int) time);
- strip.setEnergy(strip.ADC*RecoilConstants.ADCTOENERGY);
- strip.setTime(strip.TDC*RecoilConstants.TDCTOTIME);
- strip.setLine(factory.getStrip(sector, layer, comp));
- strip.setChamber(factory.getChamberIndex(comp)+1);
- strip.setStatus(0);
+ RTRKStrip strip = new RTRKStrip(sector, layer, comp);
- if(strip.getEnergy()>RecoilConstants.THRESHOLD) strips.add(strip);
+// strip.setTriggerPhase(triggerPhase);
+strip.setId(bank.trueIndex(i)+1);
+strip.setADC(adc);
+strip.setTDC((int) time);
+strip.setEnergy(strip.ADC*RTRKParameters.ADCTOENERGY);
+strip.setTime(strip.TDC*RTRKParameters.TDCTOTIME);
+strip.setLine(factory.getStrip(sector, layer, comp));
+strip.setChamber(factory.getChamberIndex(comp)+1);
+strip.setStatus(0);
+
+if(strip.getEnergy()>RTRKParameters.THRESHOLD) strips.add(strip);
}
- }
+ }
return strips;
}
@Override
public String toString(){
StringBuilder str = new StringBuilder();
- str.append(String.format("----> strip (%3d %3d %3d) ADC/TDC %5d %5d ENERGY = %8.5f TIME = %8.5f ",
- this.desc.getSector(),this.desc.getLayer(),this.desc.getComponent(),
- this.ADC,this.TDC,this.getEnergy(),this.getTime()));
+ str.append(String.format("----> strip (%3d %3d %3d) ADC/TDC %5d %5d ENERGY = %8.5f TIME = %8.5f ",
+ this.desc.getSector(),this.desc.getLayer(),this.desc.getComponent(),
+ this.ADC,this.TDC,this.getEnergy(),this.getTime()));
return str.toString();
}
}