diff options
-rw-r--r-- | src/dc.c | 51 | ||||
-rw-r--r-- | src/event.h | 17 | ||||
-rw-r--r-- | src/zdab_utils.c | 3 |
3 files changed, 65 insertions, 6 deletions
@@ -429,12 +429,33 @@ int is_slot_early(event *ev, int flasher_pmt_id) * time slope (high TAC = very early hits), they get flagged and a * calibration is not provided (which is compatible with a flashing * channel). If this is the case, you can fall back to raw TACs and QHS - * when calibration is not available. */ - if (ev->pmt_hits[i].ept < -100) continue; + * when calibration is not available. + * + * Another update: + * + * I looked into this further and there are cases when the TAC is too + * high, but in these cases *both* the ECA time and the ECA+PCA time + * are set to -9999.0. However, there are still cases where *only* the + * ECA+PCA time is set to -9999.0 but the ECA time is OK. I sent + * another email to Javi and he figured it out: + * + * I just recall that in SNO+ we have a similar hit-level test for PCA: + * if a channel has a very low QHS, having a good time-walk calibration + * is hard so we just set the time to invalid. There might have been + * something similar in SNO, although I didn't find anything after a + * quick look in the SNO docs. + * + * I looked into it and *all* of the hits I saw were indeed caused by a + * very low QHS value. + * + * Here, we use the pt1 value which is the ECA+PCA time except without + * walk correction which is what was causing the issue with the bad + * regular time. */ + if (ev->pmt_hits[i].pt1 < -100) continue; if (i/32 == flasher_pmt_id/32) { /* This hit is in the same slot as the potential flasher. */ - t_slot += ev->pmt_hits[i].ept; + t_slot += ev->pmt_hits[i].pt1; n_slot += 1; continue; } @@ -445,7 +466,7 @@ int is_slot_early(event *ev, int flasher_pmt_id) distance = NORM(pmt_dir); if (distance < 400.0) { - t_nearby += ev->pmt_hits[i].ept; + t_nearby += ev->pmt_hits[i].pt1; n_nearby += 1; continue; } @@ -583,7 +604,22 @@ int is_flasher(event *ev) qlx_pc[nhit] = qlx; } - t_pc[nhit] = ev->pmt_hits[i].t; + if (ev->pmt_hits[i].pt1 < -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].pt1; + } channel_pc[nhit] = channel; @@ -656,6 +692,9 @@ int is_flasher(event *ev) /* Skip PMTs in the same card as the high charge channel. */ if (id/4 == flasher_pc/4) continue; + /* Require good calibrations. */ + if (ev->pmt_hits[i].pt1 < -100) continue; + nhit += 1; /* Calculate the distance from the current channel to the high charge @@ -668,7 +707,7 @@ int is_flasher(event *ev) /* If this channel fired more than 50 ns after the high charge channel, * increment nhit_late. */ - if (ev->pmt_hits[i].t > t + 50.0) nhit_late += 1; + if (ev->pmt_hits[i].pt1 > t + 50.0) nhit_late += 1; } /* If at least 70% of the regular PMTs fired within 50 ns and were at diff --git a/src/event.h b/src/event.h index 70b8898..7c7f990 100644 --- a/src/event.h +++ b/src/event.h @@ -28,20 +28,37 @@ /* Struct to hold all data from a single event used for fitting. */ typedef struct pmt_hit { + /* Set to 1 if the PMT was hit. */ int hit; + /* ECA calibrated time (ns). */ float ept; + /* Time in nano-secs relative to event T0 (ns). */ float t; + /* ECA calibrated QHL (pedestal subtracted). */ float ehl; + /* ECA calibrated QHL (pedestal subtracted). */ float ehs; + /* ECA calibrated QLX (pedestal subtracted). */ float elx; + /* Integrated charge. */ float qhl; + /* Short-time integrated charge. */ float qhs; + /* Low-gain integrated charge. */ float qlx; + /* Uncalibrated high-gain, long integration charge. */ uint16_t qihl; + /* Uncalibrated high-gain, short integration charge. */ uint16_t qihs; + /* Uncalibrated low-gain, long integration charge. */ uint16_t qilx; + /* Bitmask used to disqualify hits from the likelihood calculation. See the + * PMT_FLAG_* bitmasks above. */ int flags; + /* Set of 1-bit PMT flags. See the KPF_* bitmasks in zdab_utils.h. */ int pf; + /* Non-walk corrected PMT time. */ + float pt1; } pmt_hit; typedef struct event { diff --git a/src/zdab_utils.c b/src/zdab_utils.c index b46ca1f..de76172 100644 --- a/src/zdab_utils.c +++ b/src/zdab_utils.c @@ -100,8 +100,11 @@ int get_event(zebraFile *f, event *ev, zebraBank *bev) ev->pmt_hits[id].qhs = bpmt.phs; ev->pmt_hits[id].qlx = bpmt.plx; ev->pmt_hits[id].pf = bpmt.pf; + ev->pmt_hits[id].pt1 = bpmt.pt1; + /* Clear the PMT_FLAG_DIS bit. */ ev->pmt_hits[id].flags &= ~PMT_FLAG_DIS; + if (bpmt.pf & KPF_DIS) ev->pmt_hits[id].flags |= PMT_FLAG_DIS; |