diff --git a/include/aare/RawMasterFile.hpp b/include/aare/RawMasterFile.hpp index 57189f7..3454a30 100644 --- a/include/aare/RawMasterFile.hpp +++ b/include/aare/RawMasterFile.hpp @@ -42,14 +42,15 @@ class RawFileNameComponents { class ScanParameters { bool m_enabled = false; - std::string m_dac; + DACIndex m_dac = DACIndex::DAC_2; int m_start = 0; int m_stop = 0; int m_step = 0; - // TODO! add settleTime, requires string to time conversion + int64_t m_settleTime = 0; // [ns] public: ScanParameters(const std::string &par); + ScanParameters(const bool enabled, const DACIndex dac, const int start, const int stop, const int step, const int64_t settleTime); ScanParameters() = default; ScanParameters(const ScanParameters &) = default; ScanParameters &operator=(const ScanParameters &) = default; @@ -57,9 +58,10 @@ class ScanParameters { int start() const; int stop() const; int step() const; - const std::string &dac() const; - bool enabled() const; - void increment_stop(); + DACIndex dac() const; + bool enabled() const; + int64_t settleTime() const; + void increment_stop(); }; /** diff --git a/include/aare/defs.hpp b/include/aare/defs.hpp index a91759e..ab37f33 100644 --- a/include/aare/defs.hpp +++ b/include/aare/defs.hpp @@ -215,6 +215,121 @@ enum class DetectorType { Unknown }; +/** +* @brief detector dacs indexes +*/ +enum DACIndex { + DAC_0, + DAC_1, + DAC_2, + DAC_3, + DAC_4, + DAC_5, + DAC_6, + DAC_7, + DAC_8, + DAC_9, + DAC_10, + DAC_11, + DAC_12, + DAC_13, + DAC_14, + DAC_15, + DAC_16, + DAC_17, + VSVP, + VTRIM, + VRPREAMP, + VRSHAPER, + VSVN, + VTGSTV, + VCMP_LL, + VCMP_LR, + VCAL, + VCMP_RL, + RXB_RB, + RXB_LB, + VCMP_RR, + VCP, + VCN, + VISHAPER, + VTHRESHOLD, + IO_DELAY, + VREF_DS, + VOUT_CM, + VIN_CM, + VREF_COMP, + VB_COMP, + VDD_PROT, + VIN_COM, + VREF_PRECH, + VB_PIXBUF, + VB_DS, + VREF_H_ADC, + VB_COMP_FE, + VB_COMP_ADC, + VCOM_CDS, + VREF_RSTORE, + VB_OPA_1ST, + VREF_COMP_FE, + VCOM_ADC1, + VREF_L_ADC, + VREF_CDS, + VB_CS, + VB_OPA_FD, + VCOM_ADC2, + VCASSH, + VTH2, + VRSHAPER_N, + VIPRE_OUT, + VTH3, + VTH1, + VICIN, + VCAS, + VCAL_N, + VIPRE, + VCAL_P, + VDCSH, + VBP_COLBUF, + VB_SDA, + VCASC_SFP, + VIPRE_CDS, + IBIAS_SFP, + ADC_VPP, + HIGH_VOLTAGE, + TEMPERATURE_ADC, + TEMPERATURE_FPGA, + TEMPERATURE_FPGAEXT, + TEMPERATURE_10GE, + TEMPERATURE_DCDC, + TEMPERATURE_SODL, + TEMPERATURE_SODR, + TEMPERATURE_FPGA2, + TEMPERATURE_FPGA3, + TRIMBIT_SCAN, + V_POWER_A = 100, + V_POWER_B = 101, + V_POWER_C = 102, + V_POWER_D = 103, + V_POWER_IO = 104, + V_POWER_CHIP = 105, + I_POWER_A = 106, + I_POWER_B = 107, + I_POWER_C = 108, + I_POWER_D = 109, + I_POWER_IO = 110, + V_LIMIT = 111, + SLOW_ADC0 = 1000, + SLOW_ADC1, + SLOW_ADC2, + SLOW_ADC3, + SLOW_ADC4, + SLOW_ADC5, + SLOW_ADC6, + SLOW_ADC7, + SLOW_ADC_TEMP +}; + enum class TimingMode { Auto, Trigger }; enum class FrameDiscardPolicy { NoDiscard, Discard, DiscardPartial }; @@ -233,4 +348,12 @@ using DataTypeVariants = std::variant; constexpr uint16_t ADC_MASK = 0x3FFF; // used to mask out the gain bits in Jungfrau +/** + * @brief Convert a string to a DACIndex + * @param arg string representation of the dacIndex + * @return DACIndex + * @throw invalid argument error if the string does not match any DACIndex + */ +template<> DACIndex StringTo(const std::string &arg); + } // namespace aare \ No newline at end of file diff --git a/src/RawFile.test.cpp b/src/RawFile.test.cpp index b707737..603738a 100644 --- a/src/RawFile.test.cpp +++ b/src/RawFile.test.cpp @@ -319,4 +319,4 @@ TEST_CASE("Read file with unordered frames", "[.with-data]") { REQUIRE(std::filesystem::exists(fpath)); File f(fpath); REQUIRE_THROWS((f.read_frame())); -} +} \ No newline at end of file diff --git a/src/RawMasterFile.cpp b/src/RawMasterFile.cpp index f12b7e0..b9d1385 100644 --- a/src/RawMasterFile.cpp +++ b/src/RawMasterFile.cpp @@ -64,6 +64,8 @@ const std::string &RawFileNameComponents::base_name() const { const std::string &RawFileNameComponents::ext() const { return m_ext; } int RawFileNameComponents::file_index() const { return m_file_index; } +ScanParameters::ScanParameters(const bool enabled, const DACIndex dac, const int start, const int stop, const int step, const int64_t settleTime) : m_enabled(enabled), m_dac(dac), m_start(start), m_stop(stop), m_step(step), m_settleTime(settleTime) {}; + // "[enabled\ndac dac 4\nstart 500\nstop 2200\nstep 5\nsettleTime 100us\n]" ScanParameters::ScanParameters(const std::string &par) { std::istringstream iss(par.substr(1, par.size() - 2)); @@ -72,7 +74,7 @@ ScanParameters::ScanParameters(const std::string &par) { if (line == "enabled") { m_enabled = true; } else if (line.find("dac") != std::string::npos) { - m_dac = line.substr(4); + m_dac = StringTo(line.substr(4)); } else if (line.find("start") != std::string::npos) { m_start = std::stoi(line.substr(6)); } else if (line.find("stop") != std::string::npos) { @@ -87,8 +89,9 @@ int ScanParameters::start() const { return m_start; } int ScanParameters::stop() const { return m_stop; } void ScanParameters::increment_stop() { m_stop += 1; } int ScanParameters::step() const { return m_step; } -const std::string &ScanParameters::dac() const { return m_dac; } +DACIndex ScanParameters::dac() const { return m_dac; } bool ScanParameters::enabled() const { return m_enabled; } +int64_t ScanParameters::settleTime() const {return m_settleTime; } RawMasterFile::RawMasterFile(const std::filesystem::path &fpath) : m_fnc(fpath) { @@ -170,6 +173,7 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) { std::ifstream ifs(fpath); json j; ifs >> j; + double v = j["Version"]; m_version = fmt::format("{:.1f}", v); @@ -181,7 +185,8 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) { j["Geometry"]["x"]}; // TODO: isnt it only available for version > 7.1? // - try block default should be 1x1 - m_image_size_in_bytes = j["Image Size in bytes"]; + m_image_size_in_bytes = v < 8.0 ? j["Image Size in bytes"] : j["Image Size"]; + m_frames_in_file = j["Frames in File"]; m_pixels_y = j["Pixels"]["y"]; m_pixels_x = j["Pixels"]["x"]; @@ -206,7 +211,6 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) { } catch (const json::out_of_range &e) { // keep the optional empty } - // ---------------------------------------------------------------- // Special treatment of analog flag because of Moench03 try { @@ -227,7 +231,6 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) { m_analog_flag = 0; } //----------------------------------------------------------------- - try { m_quad = j.at("Quad"); } catch (const json::out_of_range &e) { @@ -239,7 +242,6 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) { // }catch (const json::out_of_range &e) { // m_adc_mask = 0; // } - try { int digital_flag = j.at("Digital Flag"); if (digital_flag) { @@ -248,7 +250,6 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) { } catch (const json::out_of_range &e) { // keep the optional empty } - try { m_transceiver_flag = j.at("Transceiver Flag"); if (m_transceiver_flag) { @@ -257,10 +258,15 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) { } catch (const json::out_of_range &e) { // keep the optional empty } - try { - std::string scan_parameters = j.at("Scan Parameters"); - m_scan_parameters = ScanParameters(scan_parameters); + if(v < 8.0) { + std::string scan_parameters = j.at("Scan Parameters"); + m_scan_parameters = ScanParameters(scan_parameters); + } + else { + auto json_obj = j.at("Scan Parameters"); + m_scan_parameters = ScanParameters(json_obj.at("enable").get(), static_cast(json_obj.at("dacInd").get()), json_obj.at("start offset").get(), json_obj.at("stop offset").get(), json_obj.at("step size").get(), json_obj.at("dac settle time ns").get()); + } if (v < 7.21) { m_scan_parameters .increment_stop(); // adjust for endpoint being included @@ -268,6 +274,7 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) { } catch (const json::out_of_range &e) { // not a scan } + try { m_udp_interfaces_per_module = {j.at("Number of UDP Interfaces"), 1}; } catch (const json::out_of_range &e) { @@ -276,15 +283,24 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) { else if (m_type == DetectorType::Eiger) { m_udp_interfaces_per_module = {1, 2}; } - } - + } try { ROI tmp_roi; - auto obj = j.at("Receiver Roi"); - tmp_roi.xmin = obj.at("xmin"); - tmp_roi.xmax = obj.at("xmax"); - tmp_roi.ymin = obj.at("ymin"); - tmp_roi.ymax = obj.at("ymax"); + if(v < 8.0) { + auto obj = j.at("Receiver Roi"); + tmp_roi.xmin = obj.at("xmin"); + tmp_roi.xmax = obj.at("xmax"); + tmp_roi.ymin = obj.at("ymin"); + tmp_roi.ymax = obj.at("ymax"); + } + else { + //TODO: for now only handle single ROI + auto obj = j.at("Receiver Rois"); + tmp_roi.xmin = obj[0].at("xmin"); + tmp_roi.xmax = obj[0].at("xmax"); + tmp_roi.ymin = obj[0].at("ymin"); + tmp_roi.ymax = obj[0].at("ymax"); + } // if any of the values are set update the roi if (tmp_roi.xmin != 4294967295 || tmp_roi.xmax != 4294967295 || @@ -298,12 +314,8 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) { } } catch (const json::out_of_range &e) { - std::cout << e.what() << std::endl; - // leave the optional empty - } - - // if we have an roi we need to update the geometry for the subfiles - if (m_roi) { + LOG(TLogLevel::logERROR) << e.what() << std::endl; + // leave the optional empty } // Update detector type for Moench diff --git a/src/RawMasterFile.test.cpp b/src/RawMasterFile.test.cpp index b2d8c44..5d8a6c6 100644 --- a/src/RawMasterFile.test.cpp +++ b/src/RawMasterFile.test.cpp @@ -51,7 +51,7 @@ TEST_CASE("Parse scan parameters") { ScanParameters s("[enabled\ndac dac 4\nstart 500\nstop 2200\nstep " "5\nsettleTime 100us\n]"); REQUIRE(s.enabled()); - REQUIRE(s.dac() == "dac 4"); + REQUIRE(s.dac() == DACIndex::DAC_4); REQUIRE(s.start() == 500); REQUIRE(s.stop() == 2200); REQUIRE(s.step() == 5); @@ -60,7 +60,7 @@ TEST_CASE("Parse scan parameters") { TEST_CASE("A disabled scan") { ScanParameters s("[disabled]"); REQUIRE_FALSE(s.enabled()); - REQUIRE(s.dac() == ""); + REQUIRE(s.dac() == DACIndex::DAC_0); REQUIRE(s.start() == 0); REQUIRE(s.stop() == 0); REQUIRE(s.step() == 0); @@ -68,7 +68,7 @@ TEST_CASE("A disabled scan") { TEST_CASE("Parse a master file in .json format", "[.integration]") { auto fpath = - test_data_path() / "jungfrau" / "jungfrau_single_master_0.json"; + test_data_path() / "raw" / "jungfrau" / "jungfrau_single_master_0.json"; REQUIRE(std::filesystem::exists(fpath)); RawMasterFile f(fpath); @@ -224,6 +224,39 @@ TEST_CASE("Parse a master file in .raw format", "[.integration]") { // Packets Caught Mask : 64 bytes } +TEST_CASE("Parse a master file in new .json format", "[.integration][.width-data]") { + + auto file_path = test_data_path() / "raw" / "newmythen03" / "run_87_master_0.json"; + REQUIRE(std::filesystem::exists(file_path)); + + RawMasterFile f(file_path); + + // Version : 8.0 + REQUIRE(f.version() == "8.0"); + + REQUIRE(f.detector_type() == DetectorType::Mythen3); + // Timing Mode : auto + REQUIRE(f.timing_mode() == TimingMode::Auto); + // Geometry : [2, 1] + REQUIRE(f.geometry().col == 2); + REQUIRE(f.geometry().row == 1); + // Image Size : 5120 bytes + REQUIRE(f.image_size_in_bytes() == 5120); + + REQUIRE(f.scan_parameters().enabled() == false); + REQUIRE(f.scan_parameters().dac() == DACIndex::DAC_0); + REQUIRE(f.scan_parameters().start() == 0); + REQUIRE(f.scan_parameters().stop() == 0); + REQUIRE(f.scan_parameters().step() == 0); + REQUIRE(f.scan_parameters().settleTime() == 0); + + auto roi = f.roi().value(); + REQUIRE(roi.xmin == 0); + REQUIRE(roi.xmax == 2559); + REQUIRE(roi.ymin == -1); + REQUIRE(roi.ymax == -1); +} + TEST_CASE("Read eiger master file", "[.integration]") { auto fpath = test_data_path() / "eiger" / "eiger_500k_32bit_master_0.json"; REQUIRE(std::filesystem::exists(fpath)); @@ -292,4 +325,5 @@ TEST_CASE("Read eiger master file", "[.integration]") { // "Packets Caught Mask": "64 bytes" // } // } -} \ No newline at end of file +} + diff --git a/src/defs.cpp b/src/defs.cpp index b93ff06..e4cca6a 100644 --- a/src/defs.cpp +++ b/src/defs.cpp @@ -115,4 +115,120 @@ template <> FrameDiscardPolicy StringTo(const std::string &arg) { // template <> TimingMode StringTo(std::string mode); +template<> DACIndex StringTo(const std::string &arg) { + if(arg == "dac 0") + return DACIndex::DAC_0; + else if(arg == "dac 1") + return DACIndex::DAC_1; + else if(arg == "dac 2") + return DACIndex::DAC_2; + else if(arg == "dac 3") + return DACIndex::DAC_3; + else if(arg == "dac 4") + return DACIndex::DAC_4; + else if(arg == "dac 5") + return DACIndex::DAC_5; + else if(arg == "dac 6") + return DACIndex::DAC_6; + else if(arg == "dac 7") + return DACIndex::DAC_7; + else if(arg == "dac 8") + return DACIndex::DAC_8; + else if(arg == "dac 9") + return DACIndex::DAC_9; + else if(arg == "dac 10") + return DACIndex::DAC_10; + else if(arg == "dac 11") + return DACIndex::DAC_11; + else if(arg == "dac 12") + return DACIndex::DAC_12; + else if(arg == "dac 13") + return DACIndex::DAC_13; + else if(arg == "dac 14") + return DACIndex::DAC_14; + else if(arg == "dac 15") + return DACIndex::DAC_15; + else if(arg == "dac 16") + return DACIndex::DAC_16; + else if(arg == "dac 17") + return DACIndex::DAC_17; + else if(arg == "vsvp") + return DACIndex::VSVP; + else if(arg == "vtrim") + return DACIndex::VTRIM; + else if(arg == "vrpreamp") + return DACIndex::VRPREAMP; + else if(arg == "vrshaper") + return DACIndex::VRSHAPER; + else if (arg == "vsvn") return DACIndex::VSVN; + else if (arg == "vtgstv") return DACIndex::VTGSTV; + else if (arg == "vcmp_ll") return DACIndex::VCMP_LL; + else if (arg == "vcmp_lr") return DACIndex::VCMP_LR; + else if (arg == "vcal") return DACIndex::VCAL; + else if (arg == "vcmp_rl") return DACIndex::VCMP_RL; + else if (arg == "rxb_rb") return DACIndex::RXB_RB; + else if (arg == "rxb_lb") return DACIndex::RXB_LB; + else if (arg == "vcmp_rr") return DACIndex::VCMP_RR; + else if (arg == "vcp") return DACIndex::VCP; + else if (arg == "vcn") return DACIndex::VCN; + else if (arg == "vishaper") return DACIndex::VISHAPER; + else if (arg == "vthreshold") return DACIndex::VTHRESHOLD; + else if (arg == "vref_ds") return DACIndex::VREF_DS; + else if (arg == "vout_cm") return DACIndex::VOUT_CM; + else if (arg == "vin_cm") return DACIndex::VIN_CM; + else if (arg == "vref_comp") return DACIndex::VREF_COMP; + else if (arg == "vb_comp") return DACIndex::VB_COMP; + else if (arg == "vdd_prot") return DACIndex::VDD_PROT; + else if (arg == "vin_com") return DACIndex::VIN_COM; + else if (arg == "vref_prech") return DACIndex::VREF_PRECH; + else if (arg == "vb_pixbuf") return DACIndex::VB_PIXBUF; + else if (arg == "vb_ds") return DACIndex::VB_DS; + else if (arg == "vref_h_adc") return DACIndex::VREF_H_ADC; + else if (arg == "vb_comp_fe") return DACIndex::VB_COMP_FE; + else if (arg == "vb_comp_adc") return DACIndex::VB_COMP_ADC; + else if (arg == "vcom_cds") return DACIndex::VCOM_CDS; + else if (arg == "vref_rstore") return DACIndex::VREF_RSTORE; + else if (arg == "vb_opa_1st") return DACIndex::VB_OPA_1ST; + else if (arg == "vref_comp_fe") return DACIndex::VREF_COMP_FE; + else if (arg == "vcom_adc1") return DACIndex::VCOM_ADC1; + else if (arg == "vref_l_adc") return DACIndex::VREF_L_ADC; + else if (arg == "vref_cds") return DACIndex::VREF_CDS; + else if (arg == "vb_cs") return DACIndex::VB_CS; + else if (arg == "vb_opa_fd") return DACIndex::VB_OPA_FD; + else if (arg == "vcom_adc2") return DACIndex::VCOM_ADC2; + else if (arg == "vcassh") return DACIndex::VCASSH; + else if (arg == "vth2") return DACIndex::VTH2; + else if (arg == "vrshaper_n") return DACIndex::VRSHAPER_N; + else if (arg == "vipre_out") return DACIndex::VIPRE_OUT; + else if (arg == "vth3") return DACIndex::VTH3; + else if (arg == "vth1") return DACIndex::VTH1; + else if (arg == "vicin") return DACIndex::VICIN; + else if (arg == "vcas") return DACIndex::VCAS; + else if (arg == "vcal_n") return DACIndex::VCAL_N; + else if (arg == "vipre") return DACIndex::VIPRE; + else if (arg == "vcal_p") return DACIndex::VCAL_P; + else if (arg == "vdcsh") return DACIndex::VDCSH; + else if (arg == "vbp_colbuf") return DACIndex::VBP_COLBUF; + else if (arg == "vb_sda") return DACIndex::VB_SDA; + else if (arg == "vcasc_sfp") return DACIndex::VCASC_SFP; + else if (arg == "vipre_cds") return DACIndex::VIPRE_CDS; + else if (arg == "ibias_sfp") return DACIndex::IBIAS_SFP; + else if (arg == "trimbits") return DACIndex::TRIMBIT_SCAN; + else if (arg == "highvoltage") return DACIndex::HIGH_VOLTAGE; + else if (arg == "iodelay") return DACIndex::IO_DELAY; + else if (arg == "temp_adc") return DACIndex::TEMPERATURE_ADC; + else if (arg == "temp_fpga") return DACIndex::TEMPERATURE_FPGA; + else if (arg == "temp_fpgaext") return DACIndex::TEMPERATURE_FPGAEXT; + else if (arg == "temp_10ge") return DACIndex::TEMPERATURE_10GE; + else if (arg == "temp_dcdc") return DACIndex::TEMPERATURE_DCDC; + else if (arg == "temp_sodl") return DACIndex::TEMPERATURE_SODL; + else if (arg == "temp_sodr") return DACIndex::TEMPERATURE_SODR; + else if (arg == "temp_fpgafl") return DACIndex::TEMPERATURE_FPGA2; + else if (arg == "temp_fpgafr") return DACIndex::TEMPERATURE_FPGA3; + else if (arg == "temp_slowadc") + return DACIndex::SLOW_ADC_TEMP; + else + throw std::invalid_argument("Could not decode DACIndex from: \"" + arg + "\""); +} + } // namespace aare \ No newline at end of file