// Copyright (2019-2022) Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-or-later #include #include "../common/RawToConvertedGeometry.h" TEST_CASE("RawToConvertedGeometry_Half_and_quarter","[RawToConvertedGeometry]") { REQUIRE(half(7, -10, 20) == 3); REQUIRE(half(7, 9, 20) == 7); REQUIRE(half(27, 9, 20) == 27); REQUIRE(half(7, -10, 20) == Approx(3.5)); REQUIRE(half(7, 9, 20) == 7); REQUIRE(half(27, 9, 20) == 27); REQUIRE(quarter(6, -10, 20) == 1); REQUIRE(quarter(26, -10, 20) == 26); REQUIRE(quarter(-16, -10, 20) == -16); } TEST_CASE("RawToConvertedGeometry_LineCopyAndAddMultipixel","[RawToConvertedGeometry]") { int16_t in[1024]; int16_t out[1030]; for (int16_t i = 0; i < 1024; i++) in[i] = i; LineCopyAndAddMultipixel(out, in); REQUIRE(out[0] == 0); REQUIRE(out[100] == 100); REQUIRE(out[255] == 255); REQUIRE(out[255+1] == 255); REQUIRE(out[256+1] == 256); REQUIRE(out[256+2] == 256); REQUIRE(out[259+2] == 259); REQUIRE(out[400+2] == 400); REQUIRE(out[600+4] == 600); REQUIRE(out[768+5] == 768); REQUIRE(out[768+6] == 768); REQUIRE(out[1000+6] == 1000); REQUIRE(out[1015+6] == 1015); REQUIRE(out[1029] == 1029 - 6); } TEST_CASE("RawToConvertedGeometry_LineCopyAndAddMultipixelNormalRow","[RawToConvertedGeometry]") { int16_t in[1024]; int16_t out[1030]; for (int16_t i = 0; i < 1024; i++) in[i] = i; LineCopyAndAdjustMultipixel(out, in, 0, 500); REQUIRE(out[0] == 0); REQUIRE(out[100] == 100); REQUIRE(out[255] == 255/2); REQUIRE(out[255+1] == 255/2); REQUIRE(out[256+1] == 256/2); REQUIRE(out[256+2] == 256/2); REQUIRE(out[259+2] == 259); REQUIRE(out[400+2] == 400); REQUIRE(out[600+4] == 600); REQUIRE(out[768+5] == 768); // > 500 so not modified REQUIRE(out[768+6] == 768); // > 500 so not modified REQUIRE(out[1000+6] == 1000); REQUIRE(out[1015+6] == 1015); REQUIRE(out[1029] == 1029 - 6); } TEST_CASE("RawToConvertedGeometry_LineCopyAndAdjustMultipixelBin2x2","[RawToConvertedGeometry]") { int16_t in[2048]; int16_t out[514]; for (int16_t i = 0; i < 2048; i++) in[i] = i; LineCopyAndAdjustMultipixelBin2x2(out, in, -1, 6000); CHECK(out[0] == 0+1+1024+1025); CHECK(out[100] == 200+201+1224+1225); CHECK(out[127] == 254+255/2+254+1024+255/2+1024/2); CHECK(out[128] == 255/2+256/2+1024/2+255/2+256/2+1024/2); CHECK(out[129] == 257+256/2+1024/2+257+1024+256/2); CHECK(out[201] == 400+401+400+401+1024+1024); CHECK(out[302] == 600+601+600+601+1024+1024); CHECK(out[385] == 766+767/2+1024+766+767/2+1024/2); CHECK(out[386] == 767/2+768/2+1024/2+1024/2+767/2+768/2); CHECK(out[403] == 800+801+800+801+1024+1024); CHECK(out[513] == 6000); // overload } TEST_CASE("RawToConvertedGeometry_LineCopyAndAdjustMultipixelBin2x2MidRow","[RawToConvertedGeometry]") { int16_t in[1024]; int16_t out[514]; for (int16_t i = 0; i < 1024; i++) in[i] = i; LineCopyAndAdjustMultipixelBin2x2MidRow(out, in, -1, 2000); REQUIRE(out[0] == 0+1); REQUIRE(out[100] == 200 + 201); REQUIRE(out[127] == 254 + 255/2); REQUIRE(out[128] == 256/2 + 255/2); REQUIRE(out[129] == 256/2 + 257); REQUIRE(out[201] == 400+401); REQUIRE(out[302] == 600+601); REQUIRE(out[385] == 766+767/2); REQUIRE(out[386] == 767/2+768/2); REQUIRE(out[403] == 800+801); REQUIRE(out[513] == 2000); // overload } TEST_CASE("RawToConvertedGeometry_TransferModuleAdjustMultipixelsBin2x2","[RawToConvertedGeometry]") { int16_t in[RAW_MODULE_SIZE]; int16_t out[(CONVERTED_MODULE_COLS/2) * (CONVERTED_MODULE_LINES/2)]; for (int i = 0; i < RAW_MODULE_SIZE; i++) in[i] = i % 1024; TransferModuleAdjustMultipixelsBin2x2(out, in, (CONVERTED_MODULE_COLS/2), -1, 8000); CHECK(out[0] == 0 + 1 + 0 + 1); CHECK(out[1] == 2 + 3 + 2 + 3); CHECK(out[513] == 1020 + 1021 + 1020 + 1021); CHECK(out[514] == 1022 + 1023 + 1022 + 1023); CHECK(out[(CONVERTED_MODULE_COLS/2) * 100 + 1] == 2 + 3 + 2 + 3); CHECK(out[(CONVERTED_MODULE_COLS/2) * 100 + 127] == 2*(254 + 255/2)); CHECK(out[(CONVERTED_MODULE_COLS/2) * 100 + 128] == 2*(255/2 + 256/2)); CHECK(out[(CONVERTED_MODULE_COLS/2) * 128] == 0 + 1); CHECK(out[(CONVERTED_MODULE_COLS/2) * 128 + 1] == 2 + 3); CHECK(out[(CONVERTED_MODULE_COLS/2) * 128 + 127] == 254+255/2); CHECK(out[(CONVERTED_MODULE_COLS/2) * 128 + 128] == 255/2+256/2); CHECK(out[(CONVERTED_MODULE_COLS/2) * 128 + 128 + 129 * 2] == 767/2+768/2); CHECK(out[(CONVERTED_MODULE_COLS/2) * 129] == 0 + 1); CHECK(out[(CONVERTED_MODULE_COLS/2) * 129 + 1] == 2 + 3); CHECK(out[(CONVERTED_MODULE_COLS/2) * 129 + 127] == 254+255/2); CHECK(out[(CONVERTED_MODULE_COLS/2) * 129 + 128] == 255/2+256/2); CHECK(out[(CONVERTED_MODULE_COLS/2) * 129 + 128 + 129 * 2] == 767/2+768/2); CHECK(out[(CONVERTED_MODULE_COLS/2) * (CONVERTED_MODULE_LINES/2) - 1] == 1022+1023+1022+1023); } TEST_CASE("RawToConvertedGeometry_LineCopyAndAddMultipixelMiddleRow","[RawToConvertedGeometry]") { int16_t in[1024]; int16_t out[1030]; for (int16_t i = 0; i < 1024; i++) in[i] = i; LineCopyAndAdjustMultipixelMidRow(out, in, 0, 500); REQUIRE(out[0] == 0); REQUIRE(out[100] == 100/2); REQUIRE(out[255] == 255/4); REQUIRE(out[255+1] == 255/4); REQUIRE(out[256+1] == 256/4); REQUIRE(out[256+2] == 256/4); REQUIRE(out[259+2] == 259/2); REQUIRE(out[400+2] == 400/2); REQUIRE(out[600+4] == 600); // > 500 so not modified REQUIRE(out[768+5] == 768); // > 500 so not modified REQUIRE(out[768+6] == 768); // > 500 so not modified REQUIRE(out[1000+6] == 1000); // > 500 so not modified REQUIRE(out[1015+6] == 1015); // > 500 so not modified REQUIRE(out[1029] == 1029 - 6); // > 500 so not modified } TEST_CASE("RawToConvertedGeometry_Transform","[RawToConvertedGeometry]") { DiffractionExperiment x(2, {4,4,6,6}, 0,0, false); x.Mode(DetectorMode::Conversion); REQUIRE(x.GetModulesNum(2) == 6); REQUIRE(x.GetPixelsNum() == CONVERTED_MODULE_SIZE * x.GetModulesNum()); std::vector input(x.GetModulesNum(3) * RAW_MODULE_SIZE); std::vector output(x.GetPixelsNum()); for (uint32_t i = 0; i < x.GetModulesNum(3) * RAW_MODULE_SIZE; i++) input[i] = i; for (int i = 0; i < x.GetModulesNum(3); i++) TransferModule(output.data() + x.GetPixel0OfModule(i), input.data() + i * RAW_MODULE_SIZE, (x.IsUpsideDown() ? -1 : 1) * x.GetXPixelsNum()); REQUIRE(output[0] == input[0]); REQUIRE(output[253] == input[253]); REQUIRE(output[256] == input[255]); REQUIRE(output[1029] == input[1023]); // Row just below middle row REQUIRE(output[254*(2*1030)+1006] == input[254*1024+1000]); // Middle row REQUIRE(output[255*(2*1030)+518] == input[255*1024+514]); REQUIRE(output[256*(2*1030)+518] == input[255*1024+514]); // Split corner (module 0) REQUIRE(output[255*(2*1030)+255] == input[255*1024+255]); REQUIRE(output[256*(2*1030)+255] == input[255*1024+255]); REQUIRE(output[255*(2*1030)+256] == input[255*1024+255]); REQUIRE(output[256*(2*1030)+256] == input[255*1024+255]); // Split corner (module 0) REQUIRE(output[258*(2*1030)+255] == input[256*1024+255]); REQUIRE(output[257*(2*1030)+255] == input[256*1024+255]); REQUIRE(output[258*(2*1030)+256] == input[256*1024+255]); REQUIRE(output[257*(2*1030)+256] == input[256*1024+255]); // Row just above middle row REQUIRE(output[259*(2*1030)+302] == input[257*1024+300]); // Split corner (module 1) REQUIRE(output[255*(2*1030)+1030+255] == input[512*1024+255*1024+255]); REQUIRE(output[256*(2*1030)+1030+255] == input[512*1024+255*1024+255]); REQUIRE(output[255*(2*1030)+1030+256] == input[512*1024+255*1024+255]); REQUIRE(output[256*(2*1030)+1030+256] == input[512*1024+255*1024+255]); // Module 1 REQUIRE(output[1030+5] == input[512*1024 + 5]); REQUIRE(output[1030+256] == input[512*1024 + 255]); // Module 2 REQUIRE(output[1030*514*2 + 256] == input[512*1024*2 + 255]); } TEST_CASE("RawToConvertedGeometry_Transform_AdjustMultipixels","[RawToConvertedGeometry]") { DiffractionExperiment x(2, {4,4,6,6}, 0, 0, false); x.Mode(DetectorMode::Conversion); x.Summation(2); // Ensure the image is 32-bit REQUIRE(x.GetPixelDepth() == 4); REQUIRE(x.GetModulesNum(3) == 6); REQUIRE(x.GetPixelsNum() == CONVERTED_MODULE_SIZE * x.GetModulesNum()); std::vector input(x.GetModulesNum(3) * RAW_MODULE_SIZE); std::vector output(x.GetPixelsNum()); for (int32_t i = 0; i < x.GetModulesNum(3) * RAW_MODULE_SIZE; i++) input[i] = i % x.GetOverflow(); for (int i = 0; i < x.GetModulesNum(3); i++) TransferModuleAdjustMultipixels(output.data() + x.GetPixel0OfModule(i), input.data() + i * RAW_MODULE_SIZE, (x.IsUpsideDown() ? -1 : 1) * x.GetXPixelsNum(), x.GetUnderflow(), x.GetOverflow()); REQUIRE(output[0] == input[0]); REQUIRE(output[253] == input[253]); REQUIRE(output[256] == input[255]/2); REQUIRE(output[1029] == input[1023]); // Row just below middle row REQUIRE(output[254*(2*1030)+1006] == input[254*1024+1000]); // Middle row REQUIRE(output[255*(2*1030)+518] == input[255*1024+514]/2); REQUIRE(output[256*(2*1030)+518] == input[255*1024+514]/2); // Split corner (module 0) REQUIRE(output[255*(2*1030)+255] == input[255*1024+255]/4); REQUIRE(output[256*(2*1030)+255] == input[255*1024+255]/4); REQUIRE(output[255*(2*1030)+256] == input[255*1024+255]/4); REQUIRE(output[256*(2*1030)+256] == input[255*1024+255]/4); // Split corner (module 0) REQUIRE(output[258*(2*1030)+255] == input[256*1024+255]/4); REQUIRE(output[257*(2*1030)+255] == input[256*1024+255]/4); REQUIRE(output[258*(2*1030)+256] == input[256*1024+255]/4); REQUIRE(output[257*(2*1030)+256] == input[256*1024+255]/4); // Row just above middle row REQUIRE(output[259*(2*1030)+302] == input[257*1024+300]); // Split corner (module 1) REQUIRE(output[255*(2*1030)+1030+255] == input[512*1024+255*1024+255]/4); REQUIRE(output[256*(2*1030)+1030+255] == input[512*1024+255*1024+255]/4); REQUIRE(output[255*(2*1030)+1030+256] == input[512*1024+255*1024+255]/4); REQUIRE(output[256*(2*1030)+1030+256] == input[512*1024+255*1024+255]/4); // Module 1 REQUIRE(output[1030+5] == input[512*1024 + 5]); REQUIRE(output[1030+256] == input[512*1024 + 255] / 2); // Module 2 REQUIRE(output[1030*514*2 + 256] == input[512*1024*2 + 255] / 2); } TEST_CASE("RawToConvertedGeometry_Transform_AdjustMultipixelsBin2x2","[RawToConvertedGeometry]") { DiffractionExperiment x(2, {4,4}, 8, 36, true); x.Mode(DetectorMode::Conversion); x.Summation(2).Binning2x2(true); REQUIRE(x.GetPixelDepth() == 4); std::vector input(x.GetModulesNum() * RAW_MODULE_SIZE); std::vector output(x.GetPixelsNum()); for (int32_t i = 0; i < x.GetModulesNum() * RAW_MODULE_SIZE; i++) input[i] = i % 98765; for (int i = 0; i < x.GetModulesNum(); i++) TransferModuleAdjustMultipixelsBin2x2(output.data() + x.GetPixel0OfModule(i), input.data() + i * RAW_MODULE_SIZE, (x.IsUpsideDown() ? -1 : 1) * x.GetXPixelsNum(), x.GetUnderflow(), x.GetOverflow()); CHECK(output[0] == input[(6*RAW_MODULE_LINES+511)*RAW_MODULE_COLS] + input[(6*RAW_MODULE_LINES+511)*RAW_MODULE_COLS+1] + input[(6*RAW_MODULE_LINES+510)*RAW_MODULE_COLS] + input[(6*RAW_MODULE_LINES+510)*RAW_MODULE_COLS+1]); CHECK(output[124/2] == input[(6*RAW_MODULE_LINES+511)*RAW_MODULE_COLS+124] + input[(6*RAW_MODULE_LINES+511)*RAW_MODULE_COLS+125] + input[(6*RAW_MODULE_LINES+510)*RAW_MODULE_COLS+124] + input[(6*RAW_MODULE_LINES+510)*RAW_MODULE_COLS+125]); CHECK(output[1038/2] == input[(7*RAW_MODULE_LINES+511)*RAW_MODULE_COLS] + input[(7*RAW_MODULE_LINES+511)*RAW_MODULE_COLS+1] + input[(7*RAW_MODULE_LINES+510)*RAW_MODULE_COLS] + input[(7*RAW_MODULE_LINES+510)*RAW_MODULE_COLS+1]); CHECK(output[((514+36)/2+513/2)*x.GetXPixelsNum()] == input[(4*RAW_MODULE_LINES)*RAW_MODULE_COLS] + input[(4*RAW_MODULE_LINES)*RAW_MODULE_COLS+1] + input[(4*RAW_MODULE_LINES+1)*RAW_MODULE_COLS] + input[(4*RAW_MODULE_LINES+1)*RAW_MODULE_COLS+1]); CHECK(output[(x.GetYPixelsNum()-1)*x.GetXPixelsNum()] == input[0] + input[1] + input[1024] + input[1025]); } TEST_CASE("RawToConvertedGeometry_Transform_upside_down","[RawToConvertedGeometry]") { DiffractionExperiment x(2,{4,4,6,6}, 0, 0, true); x.Mode(DetectorMode::Conversion); REQUIRE(x.GetModulesNum(3) == 6); REQUIRE(x.GetPixelsNum() == CONVERTED_MODULE_SIZE * x.GetModulesNum()); auto input = (uint32_t *) calloc(x.GetModulesNum(2) * RAW_MODULE_SIZE, sizeof(uint32_t)); auto output = (uint32_t *) calloc(x.GetPixelsNum(), sizeof(uint32_t)); for (uint32_t i = 0; i < x.GetModulesNum(3) * RAW_MODULE_SIZE; i++) input[i] = i; for (int i = 0; i < x.GetModulesNum(3); i++) TransferModule(output + x.GetPixel0OfModule(i + x.GetFirstModuleOfDataStream(3)), input + i * RAW_MODULE_SIZE, (x.IsUpsideDown() ? -1 : 1) * x.GetXPixelsNum()); REQUIRE(output[514*1030*4+0] == input[511*1024+0]); REQUIRE(output[514*1030*4+253] == input[511*1024+253]); REQUIRE(output[514*1030*4+256] == input[511*1024+255]); REQUIRE(output[514*1030*4+1029] == input[511*1024+1023]); // Row just below middle row REQUIRE(output[514*1030*4+254*(2*1030)+1006] == input[257*1024+1000]); // Middle row REQUIRE(output[514*1030*4+255*(2*1030)+518] == input[256*1024+514]); REQUIRE(output[514*1030*4+256*(2*1030)+518] == input[256*1024+514]); // Split corner (module 0) REQUIRE(output[514*1030*4+255*(2*1030)+255] == input[256*1024+255]); REQUIRE(output[514*1030*4+256*(2*1030)+255] == input[256*1024+255]); REQUIRE(output[514*1030*4+255*(2*1030)+256] == input[256*1024+255]); REQUIRE(output[514*1030*4+256*(2*1030)+256] == input[256*1024+255]); // Split corner (module 0) REQUIRE(output[514*1030*4+258*(2*1030)+255] == input[255*1024+255]); REQUIRE(output[514*1030*4+257*(2*1030)+255] == input[255*1024+255]); REQUIRE(output[514*1030*4+258*(2*1030)+256] == input[255*1024+255]); REQUIRE(output[514*1030*4+257*(2*1030)+256] == input[255*1024+255]); // Row just above middle row REQUIRE(output[514*1030*4+259*(2*1030)+302] == input[254*1024+300]); // Split corner (module 1) REQUIRE(output[514*1030*4+257*(2*1030)+1030+255] == input[512*1024+255*1024+255]); REQUIRE(output[514*1030*4+258*(2*1030)+1030+255] == input[512*1024+255*1024+255]); REQUIRE(output[514*1030*4+257*(2*1030)+1030+256] == input[512*1024+255*1024+255]); REQUIRE(output[514*1030*4+258*(2*1030)+1030+256] == input[512*1024+255*1024+255]); // Module 1 REQUIRE(output[514*1030*4+1030+5] == input[512*1024 + 511*1024 + 5]); REQUIRE(output[514*1030*4+1030+256] == input[512*1024 + 511*1024 + 255]); // Module 2 REQUIRE(output[1030*514*2 + 256] == input[512*1024*2 + 511*1024 + 255]); free(input); free(output); } TEST_CASE("RawToConvertedGeometry","[RawToConvertedGeometry]") { DiffractionExperiment x(2,{4,4,6,6}, 0, 0, true); x.Mode(DetectorMode::Conversion); REQUIRE(x.GetModulesNum(2) == 6); REQUIRE(x.GetPixelsNum() == CONVERTED_MODULE_SIZE * x.GetModulesNum()); auto input = (uint32_t *) calloc(x.GetModulesNum() * RAW_MODULE_SIZE, sizeof(uint32_t)); auto output = (uint32_t *) calloc(x.GetPixelsNum(), sizeof(uint32_t)); auto input2 = (uint32_t *) calloc(x.GetModulesNum() * RAW_MODULE_SIZE, sizeof(uint32_t)); for (uint32_t i = 0; i < x.GetModulesNum() * RAW_MODULE_SIZE; i++) input[i] = 3*i-1; RawToConvertedGeometry(x, output, input); ConvertedToRawGeometry(x, input2, output); uint64_t diff = 0; for (int i = 0; i < x.GetModulesNum(2) * RAW_MODULE_SIZE; i++) { if (input[i] != input2[i]) diff++; } REQUIRE(diff == 0); free(input); free(output); free(input2); } TEST_CASE("RawToConvertedGeometry_int64","[RawToConvertedGeometry]") { DiffractionExperiment x(2,{4,4,6,6}, 0, 0, true); x.Mode(DetectorMode::Conversion); REQUIRE(x.GetModulesNum(2) == 6); REQUIRE(x.GetPixelsNum() == CONVERTED_MODULE_SIZE * x.GetModulesNum()); std::vector input(x.GetModulesNum() * RAW_MODULE_SIZE); std::vector output(x.GetPixelsNum()); std::vector input2(x.GetModulesNum() * RAW_MODULE_SIZE); for (uint32_t i = 0; i < x.GetModulesNum() * RAW_MODULE_SIZE; i++) input[i] = 3*i-1; RawToConvertedGeometry(x, output.data(), input.data()); ConvertedToRawGeometry(x, input2.data(), output.data()); uint64_t diff = 0; for (int i = 0; i < x.GetModulesNum(2) * RAW_MODULE_SIZE; i++) { if (input[i] != input2[i]) diff++; } REQUIRE(diff == 0); } TEST_CASE("RawToConvertedGeometry_FP","[RawToConvertedGeometry]") { DiffractionExperiment x(2,{4,4,6,6}, 0, 0, true); x.Mode(DetectorMode::Conversion); REQUIRE(x.GetModulesNum(2) == 6); REQUIRE(x.GetPixelsNum() == CONVERTED_MODULE_SIZE * x.GetModulesNum()); std::vector input(x.GetModulesNum() * RAW_MODULE_SIZE); std::vector output(x.GetPixelsNum()); std::vector input2(x.GetModulesNum() * RAW_MODULE_SIZE); for (uint32_t i = 0; i < x.GetModulesNum() * RAW_MODULE_SIZE; i++) input[i] = 3*i-1; RawToConvertedGeometry(x, output.data(), input.data()); ConvertedToRawGeometry(x, input2.data(), output.data()); uint64_t diff = 0; for (int i = 0; i < x.GetModulesNum(2) * RAW_MODULE_SIZE; i++) { if (input[i] != Approx(input2[i])) diff++; } REQUIRE(diff == 0); } TEST_CASE("RawToConvertedGeometry_Gaps","[RawToConvertedGeometry]") { DiffractionExperiment x(2,{4,4}, 8, 36, true); x.Mode(DetectorMode::Conversion); REQUIRE(x.GetModulesNum(1) == 4); REQUIRE(x.GetXPixelsNum() == 2 * CONVERTED_MODULE_COLS + 8); REQUIRE(x.GetYPixelsNum() == 4 * CONVERTED_MODULE_LINES + 3*36); REQUIRE(x.GetPixelsNum() == x.GetXPixelsNum() * x.GetYPixelsNum()); auto input = (uint32_t *) calloc(x.GetModulesNum() * RAW_MODULE_SIZE, sizeof(uint32_t)); auto output = (uint32_t *) calloc(x.GetPixelsNum(), sizeof(uint32_t)); auto input2 = (uint32_t *) calloc(x.GetModulesNum() * RAW_MODULE_SIZE, sizeof(uint32_t)); for (uint32_t i = 0; i < x.GetModulesNum() * RAW_MODULE_SIZE; i++) input[i] = 3*i-1; RawToConvertedGeometry(x, output, input); ConvertedToRawGeometry(x, input2, output); uint64_t diff = 0; for (int i = 0; i < x.GetModulesNum() * RAW_MODULE_SIZE; i++) { if (input[i] != input2[i]) diff++; } REQUIRE(diff == 0); free(input); free(output); free(input2); } TEST_CASE("RawToConvertedCoordinate","[RawToConvertedGeometry]") { DiffractionExperiment experiment(2,{4,4}, 8, 36, true); auto [x1,y1] = RawToConvertedCoordinate(experiment, 0, 0); REQUIRE(x1 == 0); REQUIRE(y1 == 2163); auto [x2,y2] = RawToConvertedCoordinate(experiment, 1, RAW_MODULE_COLS-1); REQUIRE(x2 == 2067); REQUIRE(y2 == 2163); auto [x3,y3] = RawToConvertedCoordinate(experiment, 6, RAW_MODULE_COLS* (RAW_MODULE_LINES-1)); REQUIRE(x3 == 0); REQUIRE(y3 == 0); auto [x4,y4] = RawToConvertedCoordinate(experiment, 3, RAW_MODULE_COLS*258 + 811); REQUIRE(x4 == 1030+8+811 + 3*2); REQUIRE(y4 == 2163-(514+36+258+2)); auto [x5,y5] = RawToConvertedCoordinate(experiment, 7, RAW_MODULE_SIZE-1); REQUIRE(x5 == 2067); REQUIRE(y5 == 0); }