From fa0c7334f105aa2806c6c5b11c0ee0444e622d28 Mon Sep 17 00:00:00 2001 From: Darryl Masson Date: Mon, 20 Dec 2021 11:23:34 +0100 Subject: [PATCH 1/2] Adds pre-trigger compensation --- V1724.cc | 10 +++++++++- V1724.hh | 4 ++++ V1724_MV.cc | 11 ++++++++--- V1730.cc | 3 ++- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/V1724.cc b/V1724.cc index 7ffbdbd0..3eb4aaa8 100644 --- a/V1724.cc +++ b/V1724.cc @@ -30,6 +30,8 @@ V1724::V1724(std::shared_ptr& log, std::shared_ptr& opts, int fBoardErrRegister = 0xEF00; fInputDelayRegister = 0x8034; fInputDelayChRegister = 0x1034; + fPreTrigRegsiter = 0x8038; + fPreTrigChRegister = 0x1038; fError = false; fSampleWidth = 10; @@ -44,6 +46,7 @@ V1724::V1724(std::shared_ptr& log, std::shared_ptr& opts, int fClockPeriod = std::chrono::nanoseconds((1l<<31)*fClockCycle); fArtificialDeadtimeChannel = 790; fDefaultDelay = 0xA * 2 * fSampleWidth; // see register document + fDefaultPreTrig = 6 * 2 * fSampleWidth // see register document } V1724::~V1724(){ @@ -77,6 +80,7 @@ int V1724::Init(int link, int crate, std::shared_ptr& opts) { fLog->Entry(MongoLog::Local, "Board %i reset", fBID); } fDelayPerCh.assign(fNChannels, fDefaultDelay); + fPreTrigPerCh.assign(fNChannels, fDefaultPreTrig); std::this_thread::sleep_for(std::chrono::milliseconds(10)); if (opts->GetInt("do_sn_check", 0) != 0) { if ((word = ReadRegister(fSNRegisterLSB)) == 0xFFFFFFFF) { @@ -193,6 +197,10 @@ int V1724::WriteRegister(unsigned int reg, unsigned int value){ fDelayPerCh.assign(fNChannels, 2*fSampleWidth*value); else if ((reg & fInputDelayChRegister) == fInputDelayChRegister) fDelayPerCh[(reg>>16)&0xF] = 2*fSampleWidth*value; + else if (reg == fPreTrigRegister) + fPreTrigPerCh.assign(fNChannels, 2*fSampleWidth*value); + else if ((reg & fPreTrigChRegister) == fPreTrigChRegister) + fPreTrigPerCh[(reg>>16)&0xF] = 2*fSampleWidth*value; if((ret = CAENVME_WriteCycle(fBoardHandle, fBaseAddress+reg, &write,cvA32_U_DATA,cvD32)) != cvSuccess){ fLog->Entry(MongoLog::Warning, @@ -358,6 +366,6 @@ std::tuple V1724::UnpackChannelHead // will never be a large difference in timestamps in one data packet if (ch_time > 15e8 && header_time < 5e8 && rollovers != 0) rollovers--; else if (ch_time < 5e8 && header_time > 15e8) rollovers++; - return {((rollovers<<31)+ch_time)*fClockCycle - fDelayPerCh[ch], words, 0, sv.substr(2, words-2)}; + return {((rollovers<<31)+ch_time)*fClockCycle - fDelayPerCh[ch] - fPreTrigPerCh[ch], words, 0, sv.substr(2, words-2)}; } diff --git a/V1724.hh b/V1724.hh index b47a50fa..6ce4360f 100644 --- a/V1724.hh +++ b/V1724.hh @@ -72,10 +72,13 @@ protected: unsigned int fBoardErrRegister; unsigned int fInputDelayRegister; unsigned int fInputDelayChRegister; + unsigned int fPreTrigRegister; + unsigned int fPreTrigChRegister; std::vector fBLTalloc; std::map fBLTCounter; std::vector fDelayPerCh; + std::vector fPreTrigPerCh; bool MonitorRegister(uint32_t reg, uint32_t mask, int ntries, int sleep, uint32_t val=1); virtual std::tuple GetClockInfo(std::u32string_view); @@ -84,6 +87,7 @@ protected: int fBID; unsigned int fBaseAddress; int fDefaultDelay; + int fDefaultPreTrig; // Stuff for clock reset tracking int fRolloverCounter; diff --git a/V1724_MV.cc b/V1724_MV.cc index 3a49af72..b6785c74 100644 --- a/V1724_MV.cc +++ b/V1724_MV.cc @@ -9,22 +9,27 @@ V1724(log, opts, bid, address) { fInputDelayRegister = fInputDelayChRegister = 0xFFFFFFFF; // disabled fArtificialDeadtimeChannel = 791; fDefaultDelay = 0; + fDefaultPreTrig = 0; // no default provided + fPreTrigRegister = 0x8114; // actually the post-trig register + fPreTrigChRegister = 0xFFFFFFFF; // disabled } V1724_MV::~V1724_MV(){} std::tuple V1724_MV::UnpackChannelHeader(std::u32string_view sv, long rollovers, - uint32_t header_time, uint32_t event_time, int event_words, int n_channels, short) { + uint32_t header_time, uint32_t event_time, int event_words, int n_channels, short ch) { int words = (event_words-4)/n_channels; - // returns {timestamp (ns), baseline, waveform} + // returns {timestamp (ns), words this ch, baseline, waveform} // More rollover logic here, because processing is multithreaded. // We leverage the fact that readout windows are // short and polled frequently compared to the rollover timescale, so there // will never be a large difference in timestamps in one data packet + // also 'fPreTrig' is actually the post-trigger, so we convert back here + int pre_trig_ns = words * 2 * fSampleWidth - fPreTrigPerCh[ch]; if (event_time > 15e8 && header_time < 5e8 && rollovers != 0) rollovers--; else if (event_time < 5e8 && header_time > 15e8) rollovers++; - return {((rollovers<<31)+event_time)*fClockCycle, + return {((rollovers<<31)+event_time)*fClockCycle - pre_trig_ns, words, 0, sv.substr(0, words)}; diff --git a/V1730.cc b/V1730.cc index 39850bc4..038c2cf6 100644 --- a/V1730.cc +++ b/V1730.cc @@ -9,6 +9,7 @@ V1730::V1730(std::shared_ptr& log, std::shared_ptr& options, fClockCycle = 2; fArtificialDeadtimeChannel = 792; fDefaultDelay = 2*fSampleWidth*0xA; // see register document + fDefaultPreTrig = 6*fSampleWidth; // undocumented value? } V1730::~V1730(){} @@ -25,7 +26,7 @@ std::tuple V1730::UnpackChannelHeader(std::u32string_view sv, long, uint32_t, uint32_t, int, int, short ch) { // returns {timestamp (ns), words this channel, baseline, waveform} int words = sv[0]&0x7FFFFF; - return {(long(sv[1]) | (long(sv[2]&0xFFFF)<<32))*fClockCycle - fDelayPerCh[ch], + return {(long(sv[1]) | (long(sv[2]&0xFFFF)<<32))*fClockCycle - fDelayPerCh[ch] - fPreTrigPerCh[ch]*2, // factor of 2 is special here, see CAEN docs words, (sv[2]>>16)&0x3FFF, sv.substr(3, words-3)}; From 83098d36dcf34f7ac2ca45adb006982e8553c02b Mon Sep 17 00:00:00 2001 From: Darryl Masson Date: Mon, 20 Dec 2021 11:26:29 +0100 Subject: [PATCH 2/2] Typos --- V1724.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/V1724.cc b/V1724.cc index 3eb4aaa8..c435a9df 100644 --- a/V1724.cc +++ b/V1724.cc @@ -30,7 +30,7 @@ V1724::V1724(std::shared_ptr& log, std::shared_ptr& opts, int fBoardErrRegister = 0xEF00; fInputDelayRegister = 0x8034; fInputDelayChRegister = 0x1034; - fPreTrigRegsiter = 0x8038; + fPreTrigRegister = 0x8038; fPreTrigChRegister = 0x1038; fError = false; @@ -46,7 +46,7 @@ V1724::V1724(std::shared_ptr& log, std::shared_ptr& opts, int fClockPeriod = std::chrono::nanoseconds((1l<<31)*fClockCycle); fArtificialDeadtimeChannel = 790; fDefaultDelay = 0xA * 2 * fSampleWidth; // see register document - fDefaultPreTrig = 6 * 2 * fSampleWidth // see register document + fDefaultPreTrig = 6 * 2 * fSampleWidth; // see register document } V1724::~V1724(){