aboutsummaryrefslogtreecommitdiff
path: root/src/dc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dc.c')
-rw-r--r--src/dc.c78
1 files changed, 76 insertions, 2 deletions
diff --git a/src/dc.c b/src/dc.c
index ae327d8..9c72f67 100644
--- a/src/dc.c
+++ b/src/dc.c
@@ -784,6 +784,14 @@ int is_slot_early(event *ev, int flasher_pmt_id)
return t_slot_median < t_nearby_median - 10.0;
}
+/* Returns 1 if both:
+ *
+ * - 70% of the normal PMT hits are 50 ns later than the median time in t_pc
+ *
+ * - 70% of the normal PMT hits are at least 12 meters away from the PMT with
+ * id flasher_pmt_id.
+ *
+ * This is used as the final check in the flasher cut. */
static int is_flasher_channel(event *ev, int flasher_pmt_id, double *t_pc, int nhit)
{
int i;
@@ -869,6 +877,10 @@ static int is_flasher_channel(event *ev, int flasher_pmt_id, double *t_pc, int n
*
* - nhit >= 31
*
+ * - Find the channel with the highest QLX charge. If this charge is more than
+ * 80 pedestal subtracted counts higher than the next highest QLX charge,
+ * skip the next three steps. Otherwise, continue.
+ *
* - Loop over all paddle cards with at least 4 hits.
*
* - Look for one channel in this paddle card which has an uncalibrated QHS or
@@ -902,17 +914,20 @@ int is_flasher(event *ev)
int qhs, qhl, qlx;
int qhl_pc[8] = {0};
int qhs_pc[8] = {0};
+ int qlx_all[MAX_PMTS] = {0};
int qlx_pc[8] = {0};
- double t_pc[8] = {0};
+ double t_pc[32] = {0};
int channel_pc[8] = {0};
size_t crate, card, channel, id;
int i, j;
- size_t index[1280], index_qhs[8], index_qhl[8], index_qlx[8];
+ size_t index[MAX_PMTS], index_qhs[8], index_qhl[8], index_qlx[8];
int nhit;
+ size_t id_all[MAX_PMTS];
/* Flasher event must have an nhit greater than 1000. */
if (ev->nhit < 31) return 0;
+ nhit = 0;
for (i = 0; i < MAX_PMTS; i++) {
if (!ev->pmt_hits[i].hit || pmts[i].pmt_type != PMT_NORMAL) continue;
@@ -922,9 +937,68 @@ int is_flasher(event *ev)
id = crate*64 + card*4 + channel/8;
+ qlx = ev->pmt_hits[i].qilx;
+
+ if (qlx < 300) {
+ /* QLX values below 300 are set to 4095. */
+ qlx_all[nhit] = 4095;
+ } else {
+ qlx_all[nhit] = qlx;
+ }
+
+ id_all[nhit] = i;
+
+ nhit += 1;
+
hits_pc[id] += 1;
}
+ argsort(qlx_all, nhit, index);
+
+ id = id_all[index[nhit-1]];
+
+ /* If the highest charge PMT in QLX is 80 pedestal subtracted counts higher
+ * than the next highest QLX charge, check for a flasher. To do this, we
+ * first check that there are at least 4 hits in the slot and then call
+ * is_flasher_channel() with the times from all the hits in the slot.
+ *
+ * This check here was motivated by run 20062 GTID 818162. This flasher
+ * event only has 3 hits in the PC with the flasher channel. Rather than
+ * lower the limit on the number of hits per PC, I instead chose to do a
+ * cut similar to the SNO QvT cut. */
+ if (qlx_all[index[nhit-1]] > qlx_all[index[nhit-2]] + 80) {
+ nhit = 0;
+ for (i = 0; i < MAX_PMTS; i++) {
+ if (!ev->pmt_hits[i].hit || pmts[i].pmt_type != PMT_NORMAL) continue;
+
+ /* If this hit isn't in the same slot as the highest charge
+ * channel, continue. */
+ if (id/32 != i/32) continue;
+
+ if (ev->pmt_hits[i].ept < -100) {
+ /* This can happen if the channel has bad calibration or is in
+ * the TAC curl region.
+ *
+ * It's not really obvious what to do in this situation. To be
+ * conservative, we will just set the time to a negative value.
+ * This means that if this channel ends up being the highest
+ * charge channel, it will basically be guaranteed to be
+ * earlier than the rest of the PMTs, and therefore this part
+ * of the next check will always pass. However it will still
+ * need to pass the cut that 70% of the other PMTs need to be
+ * at least 12 meters away. */
+ t_pc[nhit] = -100;
+ } else {
+ t_pc[nhit] = ev->pmt_hits[i].ept;
+ }
+
+ nhit += 1;
+ }
+
+ /* Require at least 4 hits in the slot. */
+ if (nhit >= 4 && is_flasher_channel(ev,id,t_pc,nhit)) return 1;
+ }
+
argsort(hits_pc, LEN(hits_pc), index);
/* The paddle card with the most hits must have >= 4 hits. */