diff options
-rw-r--r-- | src/dc.c | 78 |
1 files changed, 76 insertions, 2 deletions
@@ -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. */ |