diff --git a/DAQController.cc b/DAQController.cc index 878cce56..43d52e87 100644 --- a/DAQController.cc +++ b/DAQController.cc @@ -107,7 +107,6 @@ int DAQController::Arm(std::shared_ptr& options){ digi->AcquisitionStop(); } } - fCounter = 0; if (OpenThreads()) { fLog->Entry(MongoLog::Warning, "Error opening threads"); fStatus = DAXHelpers::Idle; @@ -162,7 +161,7 @@ int DAQController::Stop(){ if (one_still_running) std::this_thread::sleep_for(std::chrono::milliseconds(100)); }while(one_still_running && counter++ < 10); if (counter >= 10) fLog->Entry(MongoLog::Local, "Boards taking a while to clear"); - std::cout<<"Deactivating boards"<Entry(MongoLog::Local, "Stopping boards"); for( auto const& link : fDigitizers ){ for(auto digi : link.second){ digi->AcquisitionStop(true); @@ -191,7 +190,7 @@ int DAQController::Stop(){ fPLL = 0; fLog->SetRunId(-1); fOptions.reset(); - std::cout<<"Finished end"<Entry(MongoLog::Local, "Finished end sequence"); fStatus = DAXHelpers::Idle; return 0; } @@ -209,6 +208,7 @@ void DAQController::ReadData(int link){ std::vector mutex_wait_times; mutex_wait_times.reserve(1<<20); int words = 0; + unsigned transfer_batch = fOptions->GetInt("transfer_batch", 8); int bytes_this_loop(0); fRunning[link] = true; std::chrono::microseconds sleep_time(fOptions->GetInt("us_between_reads", 10)); @@ -217,9 +217,8 @@ void DAQController::ReadData(int link){ while(fReadLoop){ for(auto& digi : fDigitizers[link]) { - // Every 1k reads check board status - if(readcycler%10000==0){ - readcycler=0; + // periodically report board status + if(readcycler == 0){ board_status = digi->GetAcquisitionStatus(); fLog->Entry(MongoLog::Local, "Board %i has status 0x%04x", digi->bid(), board_status); @@ -235,8 +234,7 @@ void DAQController::ReadData(int link){ fLog->Entry(MongoLog::Local, "Board %i has PLL unlock", digi->bid()); fPLL++; } - if (err_val & 0x2) fLog->Entry(MongoLog::Local, "Board %i has VME bus error", - digi->bid()); + if (err_val & 0x2) fLog->Entry(MongoLog::Local, "Board %i has VME bus error", digi->bid()); } } if((words = digi->Read(dp))<0){ @@ -249,7 +247,7 @@ void DAQController::ReadData(int link){ bytes_this_loop += words*sizeof(char32_t); } } // for digi in digitizers - if (local_buffer.size() > 0) { + if (local_buffer.size() && (readcycler % transfer_batch == 0)) { fDataRate += bytes_this_loop; auto t_start = std::chrono::high_resolution_clock::now(); while (fFormatters[(++c)%num_threads]->ReceiveDatapackets(local_buffer, bytes_this_loop)) {} @@ -258,7 +256,7 @@ void DAQController::ReadData(int link){ t_end-t_start).count()); bytes_this_loop = 0; } - readcycler++; + if (++readcycler > 10000) readcycler = 0; std::this_thread::sleep_for(sleep_time); } // while run if (mutex_wait_times.size() > 0) { @@ -333,10 +331,13 @@ void DAQController::StatusUpdate(mongocxx::collection* collection) { buf.second += x.second; } } + int rate_alt = std::accumulate(retmap.begin(), retmap.end(), 0, + [&](int tot, const std::pair& p) {return std::move(tot) + p.second;}); auto doc = document{} << "host" << fHostname << "time" << bsoncxx::types::b_date(std::chrono::system_clock::now())<< - "rate" << rate/1e6 << + "rate_old" << rate*1e-6 << + "rate" << rate_alt*1e-6 << "status" << fStatus << "buffer_size" << (buf.first + buf.second)/1e6 << "mode" << (fOptions ? fOptions->GetString("name", "none") : "none") << @@ -348,7 +349,7 @@ void DAQController::StatusUpdate(mongocxx::collection* collection) { doc << std::to_string(pair.first) << short(pair.second>>10); // KB not MB } << close_document << finalize; - collection->insert_one(std::move(doc)); // opts is const& + collection->insert_one(std::move(doc)); return; } @@ -361,7 +362,7 @@ void DAQController::InitLink(std::vector>& digis, fLog->Entry(MongoLog::Warning, "Errors during baseline fitting"); return; } else if (ret > 0) { - fLog->Entry(MongoLog::Message, "Baselines didn't converge so we'll use Plan B"); + fLog->Entry(MongoLog::Debug, "Baselines didn't converge so we'll use Plan B"); } } @@ -602,6 +603,10 @@ int DAQController::FitBaselines(std::vector> &digis, // iterate if (channel_finished[bid][ch] >= convergence_threshold) { done &= true; + if (channel_finished[bid][ch]++ == convergence_threshold) { + fLog->Entry(MongoLog::Local, "%i.%i converged after %i steps: %.1f", bid, ch, + step, bl_per_channel[bid][ch][step]); + } continue; } diff --git a/DAQController.hh b/DAQController.hh index 8c9219fb..a4334826 100644 --- a/DAQController.hh +++ b/DAQController.hh @@ -56,8 +56,7 @@ private: int fNProcessingThreads; // For reporting to frontend - std::atomic_int fDataRate; - std::atomic_long fCounter; + volatile std::atomic_long fDataRate; std::atomic_int fPLL; }; diff --git a/DDC10.cc b/DDC10.cc index 197f355a..5bcb70de 100644 --- a/DDC10.cc +++ b/DDC10.cc @@ -16,6 +16,15 @@ DDC10::DDC10(){ } DDC10::~DDC10(){ + fHopts.signal_threshold = fHopts.sign = fHopts.rise_time_cut = fHopts.dynamic_veto_limit = fHopts.static_veto_duration = 0; + fHopts.integration_threshold = fHopts.rho_0 = fHopts.rho_1 = fHopts.rho_2 = fHopts.rho_3 = 0; + fHopts.window = fHopts.prescaling = fHopts.component_status = fHopts.width_cut = fHopts.delay = 0; + try{ + if (fHopts.address != "") + Initialize(fHopts); + }catch(std::exception& e) { + std::cout<<"HEV cleanup threw: " << e.what() << std::endl; + } } int DDC10::Initialize(HEVOptions d_opts) diff --git a/Makefile b/Makefile index 07f58b8f..6a43c00d 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ SHELL = /bin/bash -O extglob -c CC = g++ CXX = g++ BUILD_COMMIT = "$(shell git log -n 1 --pretty=oneline | awk '{print $$1}')" -CFLAGS = -Wall -Wextra -pedantic -pedantic-errors -g -DLINUX -DREDAX_BUILD_COMMIT='$(BUILD_COMMIT)' -std=c++17 -pthread $(shell pkg-config --cflags libmongocxx) +CFLAGS = -Wall -Wextra -pedantic -pedantic-errors -g -O2 -DLINUX -DREDAX_BUILD_COMMIT='$(BUILD_COMMIT)' -std=c++17 -pthread $(shell pkg-config --cflags libmongocxx) CPPFLAGS := $(CFLAGS) IS_READER0 := false ifeq "$(shell hostname)" "reader0" diff --git a/MongoLog.cc b/MongoLog.cc index 4619fbf1..fbac52f1 100644 --- a/MongoLog.cc +++ b/MongoLog.cc @@ -51,19 +51,17 @@ void MongoLog::Flusher() { std::unique_lock lk(fMutex); fCV.wait(lk, [&]{return fQueue.size() > 0 || fFlush == false;}); if (fQueue.size()) { - auto [today, ms, priority, message] = std::move(fQueue.front()); + auto [today, priority, message] = std::move(fQueue.front()); fQueue.pop_front(); lk.unlock(); - std::stringstream msg; - msg<= fLogLevel){ try{ auto d = bsoncxx::builder::stream::document{} << "user" << fHostname << - "message" << std::move(message) << + "message" << message.substr(45) << // 45 overhead chars "priority" << priority << "runid" << fRunId << bsoncxx::builder::stream::finalize; @@ -84,11 +82,15 @@ void MongoLog::Flusher() { } // while } -std::string MongoLog::FormatTime(struct tm* date, int ms) { - std::string out("YYYY-MM-DD HH:mm:SS.SSS"); +std::string MongoLog::FormatTime(struct tm* date, int ms, char* writeto) { + std::string out; + if (writeto == nullptr) { + out = "YYYY-MM-DD HH:mm:SS.SSS | fRunId |"; + writeto = out.data(); + } // this is kinda awkward but we can't use c++20's time-formatting gubbins so :( - sprintf(out.data(), "%04i-%02i-%02i %02i:%02i:%02i.%03i", date->tm_year+1900, - date->tm_mon+1, date->tm_mday, date->tm_hour, date->tm_min, date->tm_sec, ms); + std::sprintf(writeto, "%04i-%02i-%02i %02i:%02i:%02i.%03i | %6i |", date->tm_year+1900, + date->tm_mon+1, date->tm_mday, date->tm_hour, date->tm_min, date->tm_sec, ms, fRunId); return out; } @@ -114,7 +116,7 @@ int MongoLog::RotateLogFile() { auto filename = LogFilePath(&today); std::cout<<"Logging to " << filename << std::endl; auto pp = filename.parent_path(); - if (!fs::exists(pp) && !fs::create_directories(pp)) { + if (!pp.empty() && !fs::exists(pp) && !fs::create_directories(pp)) { std::cout << "Could not create output directories for logging!" << std::endl; return -1; } @@ -123,7 +125,7 @@ int MongoLog::RotateLogFile() { std::cout << "Could not rotate logfile!\n"; return -1; } - fOutfile << FormatTime(&today, ms) << " [INIT]: logfile initialized: commit " << REDAX_BUILD_COMMIT << "\n"; + fOutfile << FormatTime(&today, ms) << " INIT | logfile initialized, commit " << REDAX_BUILD_COMMIT << "\n"; fToday = Today(&today); if (fDeleteAfterDays == 0) return 0; std::vector days_per_month = {31,28,31,30,31,30,31,31,30,31,30,31}; @@ -139,11 +141,11 @@ int MongoLog::RotateLogFile() { last_week.tm_mday += days_per_month[last_week.tm_mon]; // off by one error??? } auto p = LogFileName(&last_week); - if (std::experimental::filesystem::exists(p)) { - fOutfile << FormatTime(&today, ms) << " [INIT]: Deleting " << p << '\n'; - std::experimental::filesystem::remove(p); + if (fs::exists(p)) { + fOutfile << FormatTime(&today, ms) << " INIT | Deleting " << p << '\n'; + fs::remove(p); } else { - fOutfile << FormatTime(&today, ms) << " [INIT]: No older logfile to delete :(\n"; + fOutfile << FormatTime(&today, ms) << " INIT | No older logfile to delete :(\n"; } return 0; } @@ -151,24 +153,27 @@ int MongoLog::RotateLogFile() { int MongoLog::Entry(int priority, const std::string& message, ...){ auto [today, ms] = Now(); - // Thanks Martin - // http://www.martinbroadhurst.com/string-formatting-in-c.html + // if we had c++20 this would look much cleaner va_list args; va_start (args, message); // First pass just gets what the length will be size_t len = std::vsnprintf(NULL, 0, message.c_str(), args); va_end (args); // Declare with proper length - std::string msg(len + 1, 0); - va_start (args, message); + int length_overhead = 50; + std::string full_message(length_overhead + len + 1, '\0'); // Fill the new string we just made - std::vsnprintf(msg.data(), len+1, message.c_str(), args); + FormatTime(&today, ms, full_message.data()); + int end_i = std::strlen("YYYY-MM-DD HH:MM:SS.SSS | fRunID |"); + end_i += std::sprintf(full_message.data() + end_i, " %7s | ", fPriorities[priority+1].c_str()); + va_start (args, message); + std::vsnprintf(full_message.data() + end_i, len+1, message.c_str(), args); va_end (args); - // strip the trailing \0 - msg.pop_back(); + // strip trailing \0 + while (full_message.back() == '\0') full_message.pop_back(); { - std::unique_lock lg(fMutex); - fQueue.emplace_back(std::make_tuple(std::move(today), ms, priority, std::move(msg))); + std::lock_guard lg(fMutex); + fQueue.emplace_back(std::make_tuple(Today(&today), priority, std::move(full_message))); } fCV.notify_one(); return 0; diff --git a/MongoLog.hh b/MongoLog.hh index 712c0d2d..90a0084c 100644 --- a/MongoLog.hh +++ b/MongoLog.hh @@ -77,7 +77,7 @@ protected: std::tuple Now(); void Flusher(); int RotateLogFile(); - virtual std::string FormatTime(struct tm*, int); + virtual std::string FormatTime(struct tm*, int, char* = nullptr); virtual int Today(struct tm*); virtual std::string LogFileName(struct tm*); virtual std::experimental::filesystem::path OutputDirectory(struct tm*); @@ -96,7 +96,7 @@ protected: int fDeleteAfterDays; int fToday; std::mutex fMutex; - std::list> fQueue; + std::list> fQueue; std::condition_variable fCV; std::experimental::filesystem::path fOutputDir; std::thread fFlushThread; diff --git a/Options.cc b/Options.cc index 34fcd41c..b0083a39 100644 --- a/Options.cc +++ b/Options.cc @@ -233,6 +233,19 @@ std::vector Options::GetThresholds(int board) { } } +std::vector Options::GetBLTalloc() { + int default_value = 23; + std::vector ret; + try{ + for (auto& val : bson_options["blt_alloc"].get_array().value) + ret.push_back(val.get_int32().value); + } catch(std::exception& e) { + fLog->Entry(MongoLog::Local, "Using default BLT allocs"); + ret.push_back(default_value); + } + return ret; +} + int Options::GetV1495Opts(std::map& ret) { if (bson_options.find("V1495") == bson_options.end()) return 1; diff --git a/Options.hh b/Options.hh index 59d109c7..738bcb81 100644 --- a/Options.hh +++ b/Options.hh @@ -83,6 +83,7 @@ public: std::vector GetBoards(std::string); std::vector GetRegisters(int, bool=false); std::vector GetDAC(int, int, uint16_t); + std::vector GetBLTalloc(); int GetV1495Opts(std::map&); int GetCrateOpt(CrateOptions &ret); int GetHEVOpt(HEVOptions &ret); diff --git a/StraxFormatter.cc b/StraxFormatter.cc index 3ebddf8e..ad88c7ca 100644 --- a/StraxFormatter.cc +++ b/StraxFormatter.cc @@ -329,11 +329,11 @@ void StraxFormatter::WriteOutChunk(int chunk_i){ struct timespec comp_start, comp_end; clock_gettime(CLOCK_THREAD_CPUTIME_ID, &comp_start); - std::vector*> buffers{{&fChunks[chunk_i], &fOverlaps[chunk_i]}}; - std::vector uncompressed_size(3, 0); + std::list* buffers[2] = {&fChunks[chunk_i], &fOverlaps[chunk_i]}; + long uncompressed_size[3] = {0L, 0L, 0L}; std::string uncompressed; - std::vector> out_buffer(3); - std::vector wsize(3); + std::shared_ptr out_buffer[3]; + int wsize[3]; long max_compressed_size = 0; for (int i = 0; i < 2; i++) { diff --git a/V1495.hh b/V1495.hh index d5ecb4f2..d114d4d3 100644 --- a/V1495.hh +++ b/V1495.hh @@ -4,19 +4,6 @@ #include #include -//Register address definitions taken from XENON1T m_veto class in kodiaq -//https://github.com/coderdj/kodiaq and XENON1T DAQ m_veto config files - -/* -#define V1495_ModuleReset 0x800A -#define V1495_MaskInA 0x1020 -#define V1495_MaskInB 0x1024 -#define V1495_MaskInD 0x1028 -#define V1495_MajorityThreshold 0x1014 -#define V1495_CoincidenceWidth 0x1010 -#define V1495_CTRL 0x1018 -*/ - class MongoLog; class Options; diff --git a/V1724.cc b/V1724.cc index 01725174..e1bd5b03 100644 --- a/V1724.cc +++ b/V1724.cc @@ -37,7 +37,7 @@ V1724::V1724(std::shared_ptr& log, std::shared_ptr& opts, int fRolloverCounter = 0; fLastClock = 0; fBLTSafety = opts->GetDouble("blt_safety_factor", 1.5); - BLT_SIZE = opts->GetInt("blt_size", 512*1024); + fBLTalloc = opts->GetBLTalloc(); // there's a more elegant way to do this, but I'm not going to write it fClockPeriod = std::chrono::nanoseconds((1l<<31)*fClockCycle); fArtificialDeadtimeChannel = 790; @@ -48,8 +48,9 @@ V1724::~V1724(){ End(); if (fBLTCounter.empty()) return; std::stringstream msg; - msg << "BLT report for board " << fBID << " (BLT " << BLT_SIZE << ")"; + msg << "BLT report for board " << fBID; for (auto p : fBLTCounter) msg << " | " << p.first << " " << int(std::log2(p.second)); + msg << " | " << long(fTotReadTime.count()); fLog->Entry(MongoLog::Local, msg.str()); } @@ -209,23 +210,33 @@ unsigned int V1724::ReadRegister(unsigned int reg){ } int V1724::Read(std::unique_ptr& outptr){ + using namespace std::chrono; + auto t_start = high_resolution_clock::now(); if ((GetAcquisitionStatus() & 0x8) == 0) return 0; // Initialize int blt_words=0, nb=0, ret=-5; std::vector> xfer_buffers; - xfer_buffers.reserve(16); + xfer_buffers.reserve(4); - int count = 0; - int alloc_words = BLT_SIZE/sizeof(char32_t)*fBLTSafety; + unsigned count = 0; + int alloc_bytes, request_bytes; char32_t* thisBLT = nullptr; do{ - + // each loop allocate more memory than the last one. + // there's a fine line to walk between making many small allocations for full digitizers + // and fewer, large allocations for empty digitizers. 16 19 20 23 seem to be optimal + // for the readers, but this depends heavily on specific machines. + if (count < fBLTalloc.size()) { + alloc_bytes = 1 << fBLTalloc[count]; + } else { + alloc_bytes = 1 << (fBLTalloc.back() + count - fBLTalloc.size() + 1); + } // Reserve space for this block transfer - thisBLT = new char32_t[alloc_words]; + thisBLT = new char32_t[alloc_bytes/sizeof(char32_t)]; + request_bytes = alloc_bytes/fBLTSafety; - ret = CAENVME_FIFOBLTReadCycle(fBoardHandle, fBaseAddress, - ((unsigned char*)thisBLT), - BLT_SIZE, cvA32_U_MBLT, cvD64, &nb); + ret = CAENVME_FIFOBLTReadCycle(fBoardHandle, fBaseAddress, thisBLT, + request_bytes, cvA32_U_MBLT, cvD64, &nb); if( (ret != cvSuccess) && (ret != cvBusError) ){ fLog->Entry(MongoLog::Error, "Board %i read error after %i reads: (%i) and transferred %i bytes this read", @@ -236,9 +247,9 @@ int V1724::Read(std::unique_ptr& outptr){ for (auto& b : xfer_buffers) delete[] b.first; return -1; } - if (nb > BLT_SIZE) fLog->Entry(MongoLog::Message, - "Board %i got %i more bytes than asked for (headroom %i)", - fBID, nb-BLT_SIZE, alloc_words*sizeof(char32_t)-nb); + if (nb > request_bytes) fLog->Entry(MongoLog::Message, + "Board %i got %x more bytes than asked for (headroom %i)", + fBID, nb-request_bytes, alloc_bytes-nb); count++; blt_words+=nb/sizeof(char32_t); @@ -246,26 +257,21 @@ int V1724::Read(std::unique_ptr& outptr){ }while(ret != cvBusError); - /*Now, unfortunately we need to make one copy of the data here or else our memory - usage explodes. We declare above a buffer of several MB, which is the maximum capacity - of the board in case every channel is 100% saturated (the practical largest - capacity is certainly smaller depending on settings). But if we just keep reserving - O(MB) blocks and filling 50kB with actual data, we're gonna run out of memory. - So here we declare the return buffer as *just* large enough to hold the actual - data and free up the rest of the memory reserved as buffer. - In tests this does not seem to impact our ability to read out the V1724 at the - maximum bandwidth of the link. */ + // Now we have to concatenate all this data into a single continuous buffer + // because I'm too lazy to write a class that allows us to use fragmented + // buffers as if they were continuous if(blt_words>0){ std::u32string s; s.reserve(blt_words); for (auto& xfer : xfer_buffers) { s.append(xfer.first, xfer.second); } - fBLTCounter[count]++; + fBLTCounter[int(std::ceil(std::log2(blt_words)))]++; auto [ht, cc] = GetClockInfo(s); outptr = std::make_unique(std::move(s), ht, cc); } for (auto b : xfer_buffers) delete[] b.first; + fTotReadTime += duration_cast(high_resolution_clock::now()-t_start); return blt_words; } diff --git a/V1724.hh b/V1724.hh index f338ec13..d4c6c44d 100644 --- a/V1724.hh +++ b/V1724.hh @@ -71,8 +71,8 @@ protected: unsigned int fVMEAlignmentRegister; unsigned int fBoardErrRegister; - int BLT_SIZE; - std::map fBLTCounter; + std::vector fBLTalloc; + std::map fBLTCounter; bool MonitorRegister(uint32_t reg, uint32_t mask, int ntries, int sleep, uint32_t val=1); virtual std::tuple GetClockInfo(std::u32string_view); @@ -90,9 +90,10 @@ protected: std::shared_ptr fLog; std::atomic_bool fError; - float fBLTSafety, fBufferSafety; + float fBLTSafety; int fSampleWidth, fClockCycle; int16_t fArtificialDeadtimeChannel; + std::chrono::nanoseconds fTotReadTime; }; diff --git a/V2718.cc b/V2718.cc index b58233a1..23313cb0 100644 --- a/V2718.cc +++ b/V2718.cc @@ -31,7 +31,7 @@ int V2718::SendStartSignal(){ // Line 3 : LED Pulser CAENVME_SetOutputConf(fBoardHandle, cvOutput3, cvDirect, cvActiveHigh, cvMiscSignals); // Line 4 : NV S-IN Logic - CAENVME_SetOutputConf(fBoardHandle, cvOutput4, cvDirect, cvActiveHigh, cvMiscSignals); // soonTM + CAENVME_SetOutputConf(fBoardHandle, cvOutput4, cvDirect, cvActiveHigh, cvManualSW); // Set the output register diff --git a/docs/daq_options.md b/docs/daq_options.md index 7a57e0a9..40078b40 100644 --- a/docs/daq_options.md +++ b/docs/daq_options.md @@ -289,7 +289,7 @@ Redax accepts a variety of options that control various low-level operations. Th | Option | Description | | ---- | ---- | -| baseline_max_steps | Int. The maximum number of steps during baselining. Steps involve measuring the baseline and trying to adjust it towards the target value. Default 20. | +| baseline_max_steps | Int. The maximum number of steps during baselining. Steps involve measuring the baseline and trying to adjust it towards the target value. Default 30. | | baseline_adjustment_threshold | Int. How close the measured baseline must be to the target baseline in ADC units. If the absolute difference is less than this value, a channel is considered to have converged. Default 10. | | baselie_convergence_threshold | Int. How many consecutive times a channel must be within the adjustment threshold to be considered stable and finished. Default 3. | | baseline_min_adjustment | Int. The minimum change to the DAC value, given in DAC units. Note that the DAC is 16-bit while the digitizer is only 14-bit, so a conversion of approximately 0.25 does apply. Default 10. | @@ -298,8 +298,9 @@ Redax accepts a variety of options that control various low-level operations. Th | baseline_fraction_around_max | Float. What fraction of total samples in the pulse must be around the mode for the pulse to be accepted. Default 0.8. | | baseline_triggers_per_step | Int. How many software triggers to send for each baseline step. Default 3. | | baseline_ms_between_triggers | Int. How long between software triggers. Default 10. | -| blt_size | Int. How many bytes to read from the digitizer during each BLT readout. This should be rather larger than your expected event sizes. Default 0x80000. | -| blt_safety_factor | Float. Sometimes the digitizer returns more bytes during a BLT readout than you ask for (it depends on the number and size of events in the digitizer's memory). This value is how much extra memory to allocate so you don't overrun the readout buffer. Default 1.5. | +| blt_alloc | Array of integers. An array of (probably increasing) values of how much memory to allocate when reading out a specific board, in log2. Allocating memory is expensive, and it's a waste of time to always allocate a large buffer when the digitizer usually only has one photon, but if a board is full you have to make a lot of single photon-sized allocs to read it all out. Tuning this value depends on what the data looks like and how fast your server allocates memory. [16 19 20 23] is optimal for the XENONnT readout servers, and this saves minutes of CPU time per hour. Default [19]. | +| blt_safety_factor | Float. Sometimes the digitizer returns more bytes during a BLT readout than you ask for (it depends on the number and size of events in the digitizer's memory). This value is how much less to ask for than you allocate you don't overrun the readout buffer. Default 1.5. | | do_sn_check | 0/1. Whether or not to have each board check its serial number during initialization. Default 0. | | us_between_reads | Int. How many microseconds to sleep between polling digitizers for data. This has a major performance impact that will matter when under extremely high loads (ie, the bleeding edge of what your server(s) and boards are capable of), but otherwise shouldn't matter much. Default 10. | +| transfer_batch | Int. How many data packets to accumulate in one readout thread before passing off to a processing thread. Default 16. | diff --git a/main.cc b/main.cc index be725529..cf8e83d3 100644 --- a/main.cc +++ b/main.cc @@ -39,22 +39,24 @@ void UpdateStatus(std::shared_ptr pool, std::string dbname, auto client = pool->acquire(); auto db = (*client)[dbname]; auto collection = db["status"]; + auto next_sec = ceil(system_clock::now()); + const auto dt = seconds(1); + std::this_thread::sleep_until(next_sec); while (b_run == true) { - auto start = std::chrono::system_clock::now(); try{ controller->StatusUpdate(&collection); }catch(const std::exception &e){ std::cout<<"Can't connect to DB to update."<: id number of this readout instance, required\n" << "--uri : full MongoDB URI, required\n" << "--db : name of the database to use, default \"daq\"\n"