From 5c2cd2bd76a00211497f795e533efd518becbc36 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Tue, 16 May 2023 10:58:44 +0200 Subject: [PATCH 01/20] TRestRawBiPoToSignalProcess added --- inc/TRestRawBiPoToSignalProcess.h | 142 +++++++++++ src/TRestRawBiPoToSignalProcess.cxx | 379 ++++++++++++++++++++++++++++ 2 files changed, 521 insertions(+) create mode 100644 inc/TRestRawBiPoToSignalProcess.h create mode 100644 src/TRestRawBiPoToSignalProcess.cxx diff --git a/inc/TRestRawBiPoToSignalProcess.h b/inc/TRestRawBiPoToSignalProcess.h new file mode 100644 index 00000000..9faa4beb --- /dev/null +++ b/inc/TRestRawBiPoToSignalProcess.h @@ -0,0 +1,142 @@ +/************************************************************************* + * This file is part of the REST software framework. * + * * + * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) * + * For more information see http://gifna.unizar.es/trex * + * * + * REST is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * REST is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have a copy of the GNU General Public License along with * + * REST in $REST_PATH/LICENSE. * + * If not, see http://www.gnu.org/licenses/. * + * For the list of contributors see $REST_PATH/CREDITS. * + *************************************************************************/ + +#ifndef RestCore_TRestBiPoToSignalProcess +#define RestCore_TRestBiPoToSignalProcess + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "TRestRawSignalEvent.h" +#include "TRestRawToSignalProcess.h" +#include "math.h" + +static const size_t CTAG_SZ = 4; + +const int MATACQ_N_CH = 4; // Number of channels +const int MATACQ_MAX_DATA_SAMP = 10240; // Max number of samples for +const int MATACQ_BIPO_TIMEOUT = 0; // BiPo mode timeout + +static const int MATACQ_UNDERFLOW = 0x0000; +static const int MATACQ_ZERO = 0x8000; +static const int MATACQ_OVERFLOW = 0xFFFF; + +const std::string TAG_RUN_START = "STA"; +const std::string TAG_RUN_BIPO = "ST2"; +const std::string TAG_RUN_STOP = "STO"; +const std::string TAG_ACQ = "ACQ"; +const std::string TAG_ACQ_2 = "AC2"; + +/// A structure to store the configuration settings of Matacq board +struct MatacqBoard { + /// The base memory address of the Matacq board + int32_t address; + + int32_t en_ch[MATACQ_N_CH]; + int32_t trg_ch[MATACQ_N_CH]; + + int32_t Trig_Type; + + int32_t Threshold; + + int32_t Nb_Acq; + + int32_t Posttrig; + + int32_t Time_Tag_On; + + int32_t Sampling_GHz; +}; + +/// A structure to store the BiPo settings +struct BiPoSettings { + int32_t trigger_address; + + int32_t Win1_Posttrig; + int32_t Timeout_200KHz; + + int32_t Trig_Chan[MATACQ_N_CH]; + int32_t Level1_mV[MATACQ_N_CH]; + int32_t Level2_mV[MATACQ_N_CH]; + + int32_t t1_window; + int32_t t2_window; + int32_t t1_t2_timeout; +}; + +//! An process to read binary data from BiPo electronics +class TRestRawBiPoToSignalProcess : public TRestRawToSignalProcess { + protected: + /// The run start time obtained from the file header + Double_t fRunStartTime = 0; ///< + + /// The number of Matacq boards present on the setup + Int_t fNBoards = 0; ///< + + /// A vector of Matacq boards that contain the information of each card + std::vector fMatacqBoard; //< + + /// A vector of BiPo settings + std::vector fBiPoSettings; //< + + void ReadHeader(); + void ReadBoard(); + void ReadBiPoSetup(); + Double_t ReadBiPoEventData(uint16_t* mdata); + + public: + const Double_t GetRunStartTime() { return fRunStartTime; } + + void InitProcess() override; + void Initialize() override; + TRestEvent* ProcessEvent(TRestEvent* inputEvent) override; + const char* GetProcessName() const override { return "BiPoToSignal"; } + + // Constructor + TRestRawBiPoToSignalProcess(); + TRestRawBiPoToSignalProcess(const char* configFilename); + + // Destructor + ~TRestRawBiPoToSignalProcess(); + + ClassDefOverride(TRestRawBiPoToSignalProcess, 1); +}; + +#endif diff --git a/src/TRestRawBiPoToSignalProcess.cxx b/src/TRestRawBiPoToSignalProcess.cxx new file mode 100644 index 00000000..85c7c94c --- /dev/null +++ b/src/TRestRawBiPoToSignalProcess.cxx @@ -0,0 +1,379 @@ +/************************************************************************* + * This file is part of the REST software framework. * + * * + * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) * + * For more information see http://gifna.unizar.es/trex * + * * + * REST is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * REST is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have a copy of the GNU General Public License along with * + * REST in $REST_PATH/LICENSE. * + * If not, see http://www.gnu.org/licenses/. * + * For the list of contributors see $REST_PATH/CREDITS. * + *************************************************************************/ + +/////////////////////////////////////////////////////////////////////// +// The TRestRawBiPoToSignalProcess ... +// +// DOCUMENTATION TO BE WRITTEN (main description, methods, data members) +// +// TODO: This process requires optimization to improve the data processing +// rate. +// +//
+// +// \warning **⚠ REST is under continous development.** This +// documentation +// is offered to you by the REST community. Your HELP is needed to keep this +// code +// up to date. Your feedback will be worth to support this software, please +// report +// any problems/suggestions you may find will using it at [The REST Framework +// forum](http://ezpc10.unizar.es). You are welcome to contribute fixing typos, +// updating +// information or adding/proposing new contributions. See also our +// Contribution +// Guide. +// +// +//-------------------------------------------------------------------------- +// +// RESTsoft - Software for Rare Event Searches with TPCs +// +// History of developments: +// +// 2023-May: First implementation (from https://gitlab.in2p3.fr/bipo/matacqana.git) +// Javier Galan +// +// \class TRestRawBiPoToSignalProcess +// \author Javier Galan +// +//
+///// +#include "TRestRawBiPoToSignalProcess.h" + +using namespace std; + +#include "TTimeStamp.h" +#include "zlib.h" + +ClassImp(TRestRawBiPoToSignalProcess); + +TRestRawBiPoToSignalProcess::TRestRawBiPoToSignalProcess() { Initialize(); } + +TRestRawBiPoToSignalProcess::TRestRawBiPoToSignalProcess(const char* configFilename) + : TRestRawToSignalProcess(configFilename) { + Initialize(); +} + +TRestRawBiPoToSignalProcess::~TRestRawBiPoToSignalProcess() { + // TRestRawBiPoToSignalProcess destructor +} + +void TRestRawBiPoToSignalProcess::Initialize() { + TRestRawToSignalProcess::Initialize(); + + /* + bad_event = false; + line = 0; // line number + Nevent = 0, Nbadevent = 0; // current event number + IDEvent = 0; + */ +} + +void TRestRawBiPoToSignalProcess::InitProcess() { + tStart = 0; // timeStamp of the run initially set to 0 + RESTInfo << "TRestRawBiPoToSignalProcess::InitProcess" << RESTendl; + + //// Validating the file type + char buffer[CTAG_SZ]; + if (fread(buffer, sizeof(char), CTAG_SZ, fInputBinFile) != CTAG_SZ) { + printf("Error: could not read first prefix.\n"); + exit(1); + } + totalBytesReaded += CTAG_SZ * sizeof(char); + + if (buffer != TAG_RUN_BIPO) { + RESTError << "The file " << fInputFileNames[0] << " is not BiPo format" << RESTendl; + exit(1); + } + + /// Reading MATACQ boards and BiPo setup settings + ReadHeader(); +} + +TRestEvent* TRestRawBiPoToSignalProcess::ProcessEvent(TRestEvent* inputEvent) { + RESTDebug << "-------Start of TRestRawBiPoToSignalProcess::ProcessEvent------------" << RESTendl; + + char buffer[CTAG_SZ]; + if (fread(buffer, sizeof(char), CTAG_SZ, fInputBinFile) != CTAG_SZ) { + printf("Error: could not read first ACQ prefix.\n"); + exit(1); + } + + if (std::string(buffer) == TAG_RUN_STOP) { + RESTDebug << "The run ends" << RESTendl; + return nullptr; + } + + if (std::string(buffer) == TAG_ACQ || std::string(buffer) == TAG_ACQ_2) { + RESTDebug << "A new event comes" << RESTendl; + + fSignalEvent->Initialize(); + uint16_t data[MATACQ_MAX_DATA_SAMP]; + + ReadBiPoEventData(data); + + return fSignalEvent; + } + + std::cout << "Buffer : " << buffer << std::endl; + + return nullptr; // can't read data +} + +void TRestRawBiPoToSignalProcess::ReadHeader() { + RESTDebug << "Entering TRestRawBiPoToSignalProcess::ReadHeader" << RESTendl; + int32_t tmp; + + /// Reading the run timestamp + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read timestamp.\n"); + exit(1); + } + fRunStartTime = (Double_t)tmp; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read timestamp (us).\n"); + exit(1); + } + + fRunStartTime += 1.e-6 * (Double_t)tmp; + + std::cout.precision(12); + RESTDebug << "Run start time: " << fRunStartTime << RESTendl; + + uint32_t nBoards; + if (fread(&nBoards, sizeof(uint32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read nBoards.\n"); + exit(1); + } + fNBoards = nBoards; + RESTDebug << "N boards: " << fNBoards << RESTendl; + + for (int n = 0; n < fNBoards; n++) { + ReadBoard(); + + int32_t bipo; + if (fread(&bipo, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read BiPo flag.\n"); + exit(1); + } + + if (bipo != 1) { + RESTError << "The file " << fInputFileNames[0] << " is not BiPo format" << RESTendl; + exit(1); + } + + ReadBiPoSetup(); + } +} + +void TRestRawBiPoToSignalProcess::ReadBoard() { + MatacqBoard board; + int32_t tmp; + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read base matacq address.\n"); + exit(1); + } + board.address = tmp; + + if (fread(board.en_ch, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { + printf("Error: could not read base matacq en_ch.\n"); + exit(1); + } + + if (fread(board.trg_ch, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { + printf("Error: could not read base matacq trg_ch.\n"); + exit(1); + } + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read base matacq address.\n"); + exit(1); + } + board.Trig_Type = tmp; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read base matacq address.\n"); + exit(1); + } + board.Threshold = tmp; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read base matacq address.\n"); + exit(1); + } + board.Nb_Acq = tmp; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read base matacq address.\n"); + exit(1); + } + board.Posttrig = tmp; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read base matacq address.\n"); + exit(1); + } + board.Time_Tag_On = tmp; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read base matacq address.\n"); + exit(1); + } + board.Sampling_GHz = tmp; + + RESTDebug << "MATACQ Base memory address: " << board.address << RESTendl; + RESTDebug << "En[0]: " << board.en_ch[0] << " En[1]: " << board.en_ch[1] << " En[2]: " << board.en_ch[2] + << " En[3]: " << board.en_ch[3] << RESTendl; + RESTDebug << "Trg[0]: " << board.trg_ch[0] << " Trg[1]: " << board.trg_ch[1] + << " Trg[2]: " << board.trg_ch[2] << " Trg[3]: " << board.trg_ch[3] << RESTendl; + RESTDebug << " " << RESTendl; + RESTDebug << "Trigger type: " << board.Trig_Type << " Threshold: " << board.Threshold << RESTendl; + RESTDebug << "Nb_Acq: " << board.Nb_Acq << " Posttrig: " << board.Posttrig << RESTendl; + RESTDebug << "Time_Tag_On: " << board.Time_Tag_On << " Sampling_GHz: " << board.Sampling_GHz << RESTendl; + RESTDebug << " -- " << RESTendl; +} + +void TRestRawBiPoToSignalProcess::ReadBiPoSetup() { + BiPoSettings bipo; + + int32_t tmp; + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read BiPo trigger address.\n"); + exit(1); + } + bipo.trigger_address = tmp; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read BiPo Win1 Posttrig.\n"); + exit(1); + } + bipo.Win1_Posttrig = tmp; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read BiPo timeout 200KHz.\n"); + exit(1); + } + bipo.Timeout_200KHz = tmp; + + if (fread(bipo.Trig_Chan, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { + printf("Error: could not read Trig_Chan.\n"); + exit(1); + } + + if (fread(bipo.Level1_mV, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { + printf("Error: could not read Level1_mV.\n"); + exit(1); + } + + if (fread(bipo.Level2_mV, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { + printf("Error: could not read Level2_mV.\n"); + exit(1); + } + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read BiPo Win1 Posttrig.\n"); + exit(1); + } + bipo.t1_window = tmp; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read BiPo Win1 Posttrig.\n"); + exit(1); + } + bipo.t2_window = tmp; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read BiPo Win1 Posttrig.\n"); + exit(1); + } + bipo.t1_t2_timeout = tmp; + + RESTDebug << "BiPo trigger address: " << bipo.trigger_address << RESTendl; + RESTDebug << "Win1 Posttrig: " << bipo.Win1_Posttrig << RESTendl; + RESTDebug << "Timeout [200KHz]: " << bipo.Timeout_200KHz << RESTendl; + RESTDebug << " " << RESTendl; + RESTDebug << "Trig_Chan[0]: " << bipo.Trig_Chan[0] << " Trig_Chan[1]: " << bipo.Trig_Chan[1] + << " Trig_Chan[2]: " << bipo.Trig_Chan[2] << " Trig_Chan[3]: " << bipo.Trig_Chan[3] << RESTendl; + RESTDebug << "Level1_mV[0]: " << bipo.Level1_mV[0] << " Level1_mV[1]: " << bipo.Level1_mV[1] + << " Level1_mV[2]: " << bipo.Level1_mV[2] << " Level1_mV[3]: " << bipo.Level1_mV[3] << RESTendl; + RESTDebug << "Level2_mV[0]: " << bipo.Level2_mV[0] << " Level2_mV[1]: " << bipo.Level2_mV[1] + << " Level2_mV[2]: " << bipo.Level2_mV[2] << " Level2_mV[3]: " << bipo.Level2_mV[3] << RESTendl; + RESTDebug << " " << RESTendl; + RESTDebug << "T1 window: " << bipo.t1_window << RESTendl; + RESTDebug << "T2 window: " << bipo.t2_window << RESTendl; + RESTDebug << "T1-T2 timeout: " << bipo.t1_t2_timeout << RESTendl; + RESTDebug << " -- " << RESTendl; +} + +Double_t TRestRawBiPoToSignalProcess::ReadBiPoEventData(uint16_t* mdata) { + int32_t tmp; + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read tmp .\n"); + exit(1); + } + std::cout << " Event address --> " << tmp << std::endl; + + // int32_t event_address = tmp; // It is this important? + // Probably board where it took place the event? + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read tmp .\n"); + exit(1); + } + + Double_t eventTimeStamp = tmp; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read tmp .\n"); + exit(1); + } + eventTimeStamp += 1.e-6 * (Double_t)tmp; + + std::cout.precision(12); + std::cout << "Event time stamp: " << eventTimeStamp << std::endl; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read tmp .\n"); + exit(1); + } + int32_t data_size = tmp; + std::cout << "Data size --> " << tmp << std::endl; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read BiPo trigger address.\n"); + exit(1); + } + std::cout << " T1-T2 distance --> " << tmp << std::endl; + + if (fread(mdata, sizeof(uint16_t), data_size, fInputBinFile) != (size_t)data_size) { + printf("Error: could not read MATACQ data.\n"); + exit(1); + } + + for (int n = 0; n < data_size; n++) { + std::cout << n << " : " << mdata[n] << std::endl; + } + + return eventTimeStamp; +} From 7e66abba4fce7b49d19ccd2c99af0d5deead1cf1 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Tue, 16 May 2023 18:17:58 +0200 Subject: [PATCH 02/20] TRestTawBiPoToSignalProcess. Finalising implementation --- inc/TRestRawBiPoToSignalProcess.h | 13 +- src/TRestRawBiPoToSignalProcess.cxx | 213 ++++++++++++++++++++++------ 2 files changed, 185 insertions(+), 41 deletions(-) diff --git a/inc/TRestRawBiPoToSignalProcess.h b/inc/TRestRawBiPoToSignalProcess.h index 9faa4beb..3fd194f3 100644 --- a/inc/TRestRawBiPoToSignalProcess.h +++ b/inc/TRestRawBiPoToSignalProcess.h @@ -83,6 +83,10 @@ struct MatacqBoard { int32_t Time_Tag_On; int32_t Sampling_GHz; + + int32_t ch_shifts[MATACQ_N_CH]; + + int32_t nChannels; }; /// A structure to store the BiPo settings @@ -116,10 +120,17 @@ class TRestRawBiPoToSignalProcess : public TRestRawToSignalProcess { /// A vector of BiPo settings std::vector fBiPoSettings; //< + /// A temporary counter + Int_t fEventCounter = 0; //! + void ReadHeader(); + void ReadFooter(); void ReadBoard(); void ReadBiPoSetup(); - Double_t ReadBiPoEventData(uint16_t* mdata); + Int_t ReadBiPoEventData(uint16_t* mdata); + + UInt_t GetBoardIndex(Int_t address); + Int_t GetBin(Int_t boardIndex, Int_t channel, Int_t bin); public: const Double_t GetRunStartTime() { return fRunStartTime; } diff --git a/src/TRestRawBiPoToSignalProcess.cxx b/src/TRestRawBiPoToSignalProcess.cxx index 85c7c94c..6e67c445 100644 --- a/src/TRestRawBiPoToSignalProcess.cxx +++ b/src/TRestRawBiPoToSignalProcess.cxx @@ -30,16 +30,12 @@ // //
// -// \warning **⚠ REST is under continous development.** This -// documentation +// \warning **⚠ REST is under continous development.** This documentation // is offered to you by the REST community. Your HELP is needed to keep this -// code -// up to date. Your feedback will be worth to support this software, please -// report -// any problems/suggestions you may find will using it at [The REST Framework +// code up to date. Your feedback will be worth to support this software, please +// report any problems/suggestions you may find will using it at [The REST Framework // forum](http://ezpc10.unizar.es). You are welcome to contribute fixing typos, -// updating -// information or adding/proposing new contributions. See also our +// updating information or adding/proposing new contributions. See also our // Contribution // Guide. // @@ -81,15 +77,14 @@ TRestRawBiPoToSignalProcess::~TRestRawBiPoToSignalProcess() { void TRestRawBiPoToSignalProcess::Initialize() { TRestRawToSignalProcess::Initialize(); - /* - bad_event = false; - line = 0; // line number - Nevent = 0, Nbadevent = 0; // current event number - IDEvent = 0; - */ + SetLibraryVersion(LIBRARY_VERSION); } void TRestRawBiPoToSignalProcess::InitProcess() { + TRestRawToSignalProcess::InitProcess(); + + fEventCounter = 0; + tStart = 0; // timeStamp of the run initially set to 0 RESTInfo << "TRestRawBiPoToSignalProcess::InitProcess" << RESTendl; @@ -108,57 +103,125 @@ void TRestRawBiPoToSignalProcess::InitProcess() { /// Reading MATACQ boards and BiPo setup settings ReadHeader(); + if (GetVerboseLevel() >= TRestStringOutput::REST_Verbose_Level::REST_Debug) GetChar(); } TRestEvent* TRestRawBiPoToSignalProcess::ProcessEvent(TRestEvent* inputEvent) { RESTDebug << "-------Start of TRestRawBiPoToSignalProcess::ProcessEvent------------" << RESTendl; + fEventCounter++; + RESTDebug << "--- Starting to process event id: " << fEventCounter << RESTendl; + + /// Initializing the new signal event + fSignalEvent->Initialize(); + fSignalEvent->SetRunOrigin(fRunOrigin); + fSignalEvent->SetSubRunOrigin(fSubRunOrigin); + fSignalEvent->SetID(fEventCounter); char buffer[CTAG_SZ]; if (fread(buffer, sizeof(char), CTAG_SZ, fInputBinFile) != CTAG_SZ) { printf("Error: could not read first ACQ prefix.\n"); exit(1); } + totalBytesReaded += CTAG_SZ * sizeof(char); if (std::string(buffer) == TAG_RUN_STOP) { RESTDebug << "The run ends" << RESTendl; + ReadFooter(); + // The processing thread finishes return nullptr; } if (std::string(buffer) == TAG_ACQ || std::string(buffer) == TAG_ACQ_2) { RESTDebug << "A new event comes" << RESTendl; - fSignalEvent->Initialize(); uint16_t data[MATACQ_MAX_DATA_SAMP]; + Int_t boardAddress = ReadBiPoEventData(data); + Int_t bIndex = GetBoardIndex(boardAddress); + + if (bIndex < 0) { + RESTError << "TRestRawBiPoToSignalProcess::ProcessEvent." << RESTendl; + RESTError << "Board index not found!" << RESTendl; + return nullptr; + } - ReadBiPoEventData(data); + RESTDebug << "Number of channels : " << fMatacqBoard[bIndex].nChannels << RESTendl; + for (int nch = 0; nch < fMatacqBoard[bIndex].nChannels; nch++) { + TRestRawSignal sgnl; + sgnl.Initialize(); + sgnl.SetSignalID(100 * boardAddress + nch); + + Int_t nBins = fBiPoSettings[bIndex].t1_window + fBiPoSettings[bIndex].t2_window; + + for (int b = 0; b < nBins; b++) { + Short_t v = -data[GetBin(bIndex, nch, b)]; // Inversing polarity + if (sgnl.GetSignalID() >= 0) sgnl.AddPoint(v); + } + + RESTDebug << "Adding signal with id : " << sgnl.GetID() << RESTendl; + RESTDebug << "Number of points: " << sgnl.GetNumberOfPoints() << RESTendl; + fSignalEvent->AddSignal(sgnl); + } return fSignalEvent; } - std::cout << "Buffer : " << buffer << std::endl; + // The processing thread will be finished if return nullptr is reached + return nullptr; +} + +/////////////////////////////////////////////// +/// \brief This method reads the header data containing the run timestamp, +/// the number of Matacq boards, and the settings of each of the Matacq and +/// BiPo boards. +/// +void TRestRawBiPoToSignalProcess::ReadFooter() { + RESTDebug << "Entering TRestRawBiPoToSignalProcess::ReadFooter" << RESTendl; + int32_t tmp; + + /// Reading the run start timestamp + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read timestamp.\n"); + exit(1); + } + totalBytesReaded += sizeof(int32_t); + Double_t runEndTime = (Double_t)tmp; + + if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { + printf("Error: could not read timestamp (us).\n"); + exit(1); + } + totalBytesReaded += sizeof(int32_t); + runEndTime += 1.e-6 * (Double_t)tmp; - return nullptr; // can't read data + fRunInfo->SetEndTimeStamp(runEndTime); } +/////////////////////////////////////////////// +/// \brief This method reads the header data containing the run timestamp, +/// the number of Matacq boards, and the settings of each of the Matacq and +/// BiPo boards. +/// void TRestRawBiPoToSignalProcess::ReadHeader() { RESTDebug << "Entering TRestRawBiPoToSignalProcess::ReadHeader" << RESTendl; int32_t tmp; - /// Reading the run timestamp + /// Reading the run start timestamp if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read timestamp.\n"); exit(1); } - fRunStartTime = (Double_t)tmp; + totalBytesReaded += sizeof(int32_t); + Double_t runStartTime = (Double_t)tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read timestamp (us).\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); + runStartTime += 1.e-6 * (Double_t)tmp; - fRunStartTime += 1.e-6 * (Double_t)tmp; + fRunInfo->SetStartTimeStamp(runStartTime); - std::cout.precision(12); RESTDebug << "Run start time: " << fRunStartTime << RESTendl; uint32_t nBoards; @@ -166,6 +229,8 @@ void TRestRawBiPoToSignalProcess::ReadHeader() { printf("Error: could not read nBoards.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); + fNBoards = nBoards; RESTDebug << "N boards: " << fNBoards << RESTendl; @@ -177,6 +242,7 @@ void TRestRawBiPoToSignalProcess::ReadHeader() { printf("Error: could not read BiPo flag.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); if (bipo != 1) { RESTError << "The file " << fInputFileNames[0] << " is not BiPo format" << RESTendl; @@ -194,52 +260,73 @@ void TRestRawBiPoToSignalProcess::ReadBoard() { printf("Error: could not read base matacq address.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); board.address = tmp; if (fread(board.en_ch, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { printf("Error: could not read base matacq en_ch.\n"); exit(1); } + totalBytesReaded += MATACQ_N_CH * sizeof(int32_t); + + int cnt = 0; + board.nChannels = 0; + for (int ich = (MATACQ_N_CH - 1); ich >= 0; ich--) { + if (board.en_ch[ich] == 1) { + board.nChannels = board.nChannels + 1; + board.ch_shifts[ich] = cnt; + cnt++; + } else { + board.ch_shifts[ich] = -1; + } + } if (fread(board.trg_ch, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { printf("Error: could not read base matacq trg_ch.\n"); exit(1); } + totalBytesReaded += MATACQ_N_CH * sizeof(int32_t); if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { - printf("Error: could not read base matacq address.\n"); + printf("Error: could not read Trig type.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); board.Trig_Type = tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { - printf("Error: could not read base matacq address.\n"); + printf("Error: could not read Threshold.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); board.Threshold = tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { - printf("Error: could not read base matacq address.\n"); + printf("Error: could not read Nb_Acq.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); board.Nb_Acq = tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { - printf("Error: could not read base matacq address.\n"); + printf("Error: could not read Posttrig.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); board.Posttrig = tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { - printf("Error: could not read base matacq address.\n"); + printf("Error: could not read Time_Tag_On.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); board.Time_Tag_On = tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { - printf("Error: could not read base matacq address.\n"); + printf("Error: could not read Sampling_GHz.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); board.Sampling_GHz = tmp; RESTDebug << "MATACQ Base memory address: " << board.address << RESTendl; @@ -252,8 +339,14 @@ void TRestRawBiPoToSignalProcess::ReadBoard() { RESTDebug << "Nb_Acq: " << board.Nb_Acq << " Posttrig: " << board.Posttrig << RESTendl; RESTDebug << "Time_Tag_On: " << board.Time_Tag_On << " Sampling_GHz: " << board.Sampling_GHz << RESTendl; RESTDebug << " -- " << RESTendl; + + fMatacqBoard.push_back(board); } +/////////////////////////////////////////////// +/// \brief This method reads the header data corresponding to the +/// BiPo settings. +/// void TRestRawBiPoToSignalProcess::ReadBiPoSetup() { BiPoSettings bipo; @@ -262,51 +355,60 @@ void TRestRawBiPoToSignalProcess::ReadBiPoSetup() { printf("Error: could not read BiPo trigger address.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); bipo.trigger_address = tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read BiPo Win1 Posttrig.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); bipo.Win1_Posttrig = tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read BiPo timeout 200KHz.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); bipo.Timeout_200KHz = tmp; if (fread(bipo.Trig_Chan, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { printf("Error: could not read Trig_Chan.\n"); exit(1); } + totalBytesReaded += MATACQ_N_CH * sizeof(int32_t); if (fread(bipo.Level1_mV, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { printf("Error: could not read Level1_mV.\n"); exit(1); } + totalBytesReaded += MATACQ_N_CH * sizeof(int32_t); if (fread(bipo.Level2_mV, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { printf("Error: could not read Level2_mV.\n"); exit(1); } + totalBytesReaded += MATACQ_N_CH * sizeof(int32_t); if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read BiPo Win1 Posttrig.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); bipo.t1_window = tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read BiPo Win1 Posttrig.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); bipo.t2_window = tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read BiPo Win1 Posttrig.\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); bipo.t1_t2_timeout = tmp; RESTDebug << "BiPo trigger address: " << bipo.trigger_address << RESTendl; @@ -324,15 +426,30 @@ void TRestRawBiPoToSignalProcess::ReadBiPoSetup() { RESTDebug << "T2 window: " << bipo.t2_window << RESTendl; RESTDebug << "T1-T2 timeout: " << bipo.t1_t2_timeout << RESTendl; RESTDebug << " -- " << RESTendl; + + fBiPoSettings.push_back(bipo); } -Double_t TRestRawBiPoToSignalProcess::ReadBiPoEventData(uint16_t* mdata) { +/////////////////////////////////////////////// +/// \brief This method reads the event data corresponding to one event. +/// The sampled channel data that will be made accessible at the `mdata` +/// pointer provided as argument. +/// +/// The event timestamp and the triggered board values will be also read +/// here. The event timestamp will be assigned to the fSignalEvent, while +/// the triggered board address will be returned and it will be used +/// later on to generate a signal id. +/// +Int_t TRestRawBiPoToSignalProcess::ReadBiPoEventData(uint16_t* mdata) { int32_t tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read tmp .\n"); exit(1); } - std::cout << " Event address --> " << tmp << std::endl; + totalBytesReaded += sizeof(int32_t); + Int_t boardAddress = tmp; + + RESTDebug << " Event address --> " << boardAddress << RESTendl; // int32_t event_address = tmp; // It is this important? // Probably board where it took place the event? @@ -341,39 +458,55 @@ Double_t TRestRawBiPoToSignalProcess::ReadBiPoEventData(uint16_t* mdata) { printf("Error: could not read tmp .\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); - Double_t eventTimeStamp = tmp; + Double_t timeStamp = tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read tmp .\n"); exit(1); } - eventTimeStamp += 1.e-6 * (Double_t)tmp; + totalBytesReaded += sizeof(int32_t); + timeStamp += 1.e-6 * (Double_t)tmp; - std::cout.precision(12); - std::cout << "Event time stamp: " << eventTimeStamp << std::endl; + fSignalEvent->SetTime(timeStamp); + + RESTDebug << "Event time stamp: " << timeStamp << RESTendl; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read tmp .\n"); exit(1); } + totalBytesReaded += sizeof(int32_t); int32_t data_size = tmp; - std::cout << "Data size --> " << tmp << std::endl; + RESTDebug << "Data size --> " << tmp << RESTendl; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read BiPo trigger address.\n"); exit(1); } - std::cout << " T1-T2 distance --> " << tmp << std::endl; + totalBytesReaded += sizeof(int32_t); + RESTDebug << " T1-T2 distance --> " << tmp << RESTendl; if (fread(mdata, sizeof(uint16_t), data_size, fInputBinFile) != (size_t)data_size) { printf("Error: could not read MATACQ data.\n"); exit(1); } + totalBytesReaded += data_size * sizeof(uint16_t); - for (int n = 0; n < data_size; n++) { - std::cout << n << " : " << mdata[n] << std::endl; - } + for (int n = 0; n < data_size; n++) mdata[n] -= MATACQ_ZERO; + + return boardAddress; +} + +UInt_t TRestRawBiPoToSignalProcess::GetBoardIndex(Int_t address) { + for (unsigned int n = 0; n < fMatacqBoard.size(); n++) + if (fMatacqBoard[n].address == address) return n; + + return -1; +} - return eventTimeStamp; +Int_t TRestRawBiPoToSignalProcess::GetBin(Int_t boardIndex, Int_t channel, Int_t bin) { + MatacqBoard board = fMatacqBoard[boardIndex]; + return board.ch_shifts[channel] + board.nChannels * bin; } From e900171360444246d6f72f209a6774820bafa639 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Tue, 16 May 2023 19:47:37 +0200 Subject: [PATCH 03/20] TRestRawBiPoToSignalProcess. Improving the way that overflows are handled --- src/TRestRawBiPoToSignalProcess.cxx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/TRestRawBiPoToSignalProcess.cxx b/src/TRestRawBiPoToSignalProcess.cxx index 6e67c445..bb8d25f2 100644 --- a/src/TRestRawBiPoToSignalProcess.cxx +++ b/src/TRestRawBiPoToSignalProcess.cxx @@ -153,7 +153,15 @@ TRestEvent* TRestRawBiPoToSignalProcess::ProcessEvent(TRestEvent* inputEvent) { Int_t nBins = fBiPoSettings[bIndex].t1_window + fBiPoSettings[bIndex].t2_window; for (int b = 0; b < nBins; b++) { - Short_t v = -data[GetBin(bIndex, nch, b)]; // Inversing polarity + Short_t sdata = data[GetBin(bIndex, nch, b)]; + Short_t v = MATACQ_ZERO - sdata; // Inversing polarity + if (sdata == MATACQ_OVERFLOW) { + v = 0; + } + if (sdata == MATACQ_UNDERFLOW) { + v = TMath::Power(2, 12); + } + if (sgnl.GetSignalID() >= 0) sgnl.AddPoint(v); } @@ -494,8 +502,6 @@ Int_t TRestRawBiPoToSignalProcess::ReadBiPoEventData(uint16_t* mdata) { } totalBytesReaded += data_size * sizeof(uint16_t); - for (int n = 0; n < data_size; n++) mdata[n] -= MATACQ_ZERO; - return boardAddress; } From 9e3b80bdec52f135ea183e024c88f1b47940aba1 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Tue, 16 May 2023 19:48:38 +0200 Subject: [PATCH 04/20] TRestRawSignalEvent. Maximum signal is always drawn black --- src/TRestRawSignalEvent.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/TRestRawSignalEvent.cxx b/src/TRestRawSignalEvent.cxx index f49cf150..84b31a46 100644 --- a/src/TRestRawSignalEvent.cxx +++ b/src/TRestRawSignalEvent.cxx @@ -643,6 +643,7 @@ void TRestRawSignalEvent::DrawSignals(TPad* pad, const std::vector& signa signalMaxID->fGraph->GetYaxis()->SetTitle("Amplitude [a.u.]"); pad->Draw(); pad->cd(); + signalMaxID->fGraph->SetLineColor(kBlack); signalMaxID->fGraph->Draw("AL"); for (const auto& signalID : signals) { From b4651620802b344314ee7a5b34a160f8fe7ec1c4 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Tue, 16 May 2023 19:49:15 +0200 Subject: [PATCH 05/20] Adding BiPo RML event data processing example --- pipeline/external/BiPo/BiPoToRawSignal.rml | 74 ++++++++++++++++++++++ pipeline/external/BiPo/globals.xml | 32 ++++++++++ pipeline/external/BiPo/run.xml | 14 ++++ 3 files changed, 120 insertions(+) create mode 100644 pipeline/external/BiPo/BiPoToRawSignal.rml create mode 100644 pipeline/external/BiPo/globals.xml create mode 100644 pipeline/external/BiPo/run.xml diff --git a/pipeline/external/BiPo/BiPoToRawSignal.rml b/pipeline/external/BiPo/BiPoToRawSignal.rml new file mode 100644 index 00000000..84e00884 --- /dev/null +++ b/pipeline/external/BiPo/BiPoToRawSignal.rml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // We define all observables except MinValue because is not yet on validation.root + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pipeline/external/BiPo/globals.xml b/pipeline/external/BiPo/globals.xml new file mode 100644 index 00000000..b627f015 --- /dev/null +++ b/pipeline/external/BiPo/globals.xml @@ -0,0 +1,32 @@ + + + + + + + + %options are : silent, warning, info, silent + + + + + + + + + + + + + diff --git a/pipeline/external/BiPo/run.xml b/pipeline/external/BiPo/run.xml new file mode 100644 index 00000000..e1438ab5 --- /dev/null +++ b/pipeline/external/BiPo/run.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + From b639db54292b7a069ba660ea9147cf7c4878a88f Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Tue, 16 May 2023 21:39:59 +0200 Subject: [PATCH 06/20] TRestRawBiPoToSignalProcess. Documenting --- inc/TRestRawBiPoToSignalProcess.h | 34 ++----------- src/TRestRawBiPoToSignalProcess.cxx | 75 +++++++++++++++++++++++++---- 2 files changed, 70 insertions(+), 39 deletions(-) diff --git a/inc/TRestRawBiPoToSignalProcess.h b/inc/TRestRawBiPoToSignalProcess.h index 3fd194f3..5007fc63 100644 --- a/inc/TRestRawBiPoToSignalProcess.h +++ b/inc/TRestRawBiPoToSignalProcess.h @@ -23,30 +23,8 @@ #ifndef RestCore_TRestBiPoToSignalProcess #define RestCore_TRestBiPoToSignalProcess -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - #include "TRestRawSignalEvent.h" #include "TRestRawToSignalProcess.h" -#include "math.h" static const size_t CTAG_SZ = 4; @@ -108,9 +86,6 @@ struct BiPoSettings { //! An process to read binary data from BiPo electronics class TRestRawBiPoToSignalProcess : public TRestRawToSignalProcess { protected: - /// The run start time obtained from the file header - Double_t fRunStartTime = 0; ///< - /// The number of Matacq boards present on the setup Int_t fNBoards = 0; ///< @@ -120,7 +95,7 @@ class TRestRawBiPoToSignalProcess : public TRestRawToSignalProcess { /// A vector of BiPo settings std::vector fBiPoSettings; //< - /// A temporary counter + /// A temporary counter used to define the event id Int_t fEventCounter = 0; //! void ReadHeader(); @@ -133,16 +108,17 @@ class TRestRawBiPoToSignalProcess : public TRestRawToSignalProcess { Int_t GetBin(Int_t boardIndex, Int_t channel, Int_t bin); public: - const Double_t GetRunStartTime() { return fRunStartTime; } - void InitProcess() override; void Initialize() override; TRestEvent* ProcessEvent(TRestEvent* inputEvent) override; const char* GetProcessName() const override { return "BiPoToSignal"; } + void PrintMetadata() override; + + MatacqBoard GetMatacqBoard(Int_t n) { return fMatacqBoard[n]; } + // Constructor TRestRawBiPoToSignalProcess(); - TRestRawBiPoToSignalProcess(const char* configFilename); // Destructor ~TRestRawBiPoToSignalProcess(); diff --git a/src/TRestRawBiPoToSignalProcess.cxx b/src/TRestRawBiPoToSignalProcess.cxx index bb8d25f2..0ef211b0 100644 --- a/src/TRestRawBiPoToSignalProcess.cxx +++ b/src/TRestRawBiPoToSignalProcess.cxx @@ -63,23 +63,29 @@ using namespace std; ClassImp(TRestRawBiPoToSignalProcess); +/////////////////////////////////////////////// +/// \brief Default constructor +/// TRestRawBiPoToSignalProcess::TRestRawBiPoToSignalProcess() { Initialize(); } -TRestRawBiPoToSignalProcess::TRestRawBiPoToSignalProcess(const char* configFilename) - : TRestRawToSignalProcess(configFilename) { - Initialize(); -} - -TRestRawBiPoToSignalProcess::~TRestRawBiPoToSignalProcess() { - // TRestRawBiPoToSignalProcess destructor -} +/////////////////////////////////////////////// +/// \brief Default destructor +/// +TRestRawBiPoToSignalProcess::~TRestRawBiPoToSignalProcess() {} +/////////////////////////////////////////////// +/// \brief Function to initialize input/output event members and define the section name +/// void TRestRawBiPoToSignalProcess::Initialize() { TRestRawToSignalProcess::Initialize(); SetLibraryVersion(LIBRARY_VERSION); } +/////////////////////////////////////////////// +/// \brief Process initialization. Data members that require initialization just before start processing +/// should be initialized here. +/// void TRestRawBiPoToSignalProcess::InitProcess() { TRestRawToSignalProcess::InitProcess(); @@ -106,6 +112,9 @@ void TRestRawBiPoToSignalProcess::InitProcess() { if (GetVerboseLevel() >= TRestStringOutput::REST_Verbose_Level::REST_Debug) GetChar(); } +/////////////////////////////////////////////// +/// \brief The main processing event function +/// TRestEvent* TRestRawBiPoToSignalProcess::ProcessEvent(TRestEvent* inputEvent) { RESTDebug << "-------Start of TRestRawBiPoToSignalProcess::ProcessEvent------------" << RESTendl; fEventCounter++; @@ -230,8 +239,6 @@ void TRestRawBiPoToSignalProcess::ReadHeader() { fRunInfo->SetStartTimeStamp(runStartTime); - RESTDebug << "Run start time: " << fRunStartTime << RESTendl; - uint32_t nBoards; if (fread(&nBoards, sizeof(uint32_t), 1, fInputBinFile) != 1) { printf("Error: could not read nBoards.\n"); @@ -516,3 +523,51 @@ Int_t TRestRawBiPoToSignalProcess::GetBin(Int_t boardIndex, Int_t channel, Int_t MatacqBoard board = fMatacqBoard[boardIndex]; return board.ch_shifts[channel] + board.nChannels * bin; } + +/////////////////////////////////////////////// +/// \brief Prints out the Matacq boards configuration and BiPo setup +/// +void TRestRawBiPoToSignalProcess::PrintMetadata() { + TRestMetadata::PrintMetadata(); + + RESTMetadata << "Number of Matacq boards : " << fNBoards << RESTendl; + RESTMetadata << " " << RESTendl; + + std::cout << "Size : " << fMatacqBoard.size() << std::endl; + for (int n = 0; n < fNBoards; n++) { + RESTMetadata << "Board address: " << fMatacqBoard[n].address << RESTendl; + RESTMetadata << "----" << RESTendl; + RESTMetadata << " - Enabled channels: " << fMatacqBoard[n].en_ch[0] << " - " + << fMatacqBoard[n].en_ch[1] << " - " << fMatacqBoard[n].en_ch[2] << " - " + << fMatacqBoard[n].en_ch[3] << RESTendl; + RESTMetadata << " - Trigger channels: " << fMatacqBoard[n].trg_ch[0] << " - " + << fMatacqBoard[n].trg_ch[1] << " - " << fMatacqBoard[n].trg_ch[2] << " - " + << fMatacqBoard[n].trg_ch[3] << RESTendl; + RESTMetadata << " - Trigger type: " << fMatacqBoard[n].Trig_Type << RESTendl; + RESTMetadata << " - Threshold: " << fMatacqBoard[n].Threshold << RESTendl; + RESTMetadata << " - Nb_Acq: " << fMatacqBoard[n].Nb_Acq << RESTendl; + RESTMetadata << " - Posttrig: " << fMatacqBoard[n].Posttrig << RESTendl; + RESTMetadata << " - Time_Tag_On: " << fMatacqBoard[n].Time_Tag_On << RESTendl; + RESTMetadata << " - Sampling_GHz: " << fMatacqBoard[n].Sampling_GHz << RESTendl; + } + + RESTMetadata << "+++++++++++++++++++++++++++++++++++++++++++++++++" << RESTendl; + + /* +/// A structure to store the BiPo settings +struct BiPoSettings { + int32_t trigger_address; + + int32_t Win1_Posttrig; + int32_t Timeout_200KHz; + + int32_t Trig_Chan[MATACQ_N_CH]; + int32_t Level1_mV[MATACQ_N_CH]; + int32_t Level2_mV[MATACQ_N_CH]; + + int32_t t1_window; + int32_t t2_window; + int32_t t1_t2_timeout; +}; +*/ +} From 62e3ce6c75775ef888bc07ca982169fe68f00b70 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Tue, 16 May 2023 21:42:51 +0200 Subject: [PATCH 07/20] TRestRawToSignalProcess::PrintMetadata is now virtual --- inc/TRestRawToSignalProcess.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/TRestRawToSignalProcess.h b/inc/TRestRawToSignalProcess.h index 0ef01b37..e35754fd 100644 --- a/inc/TRestRawToSignalProcess.h +++ b/inc/TRestRawToSignalProcess.h @@ -66,7 +66,7 @@ class TRestRawToSignalProcess : public TRestEventProcess { fSubRunOrigin = fRunInfo->GetSubRunNumber(); } - void PrintMetadata() override; + virtual void PrintMetadata() override; void Initialize() override; TRestMetadata* GetProcessMetadata() const { return nullptr; } From ecb330c5a7f78a6912d609ed90f1625aab9bb1cd Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Wed, 17 May 2023 13:01:30 +0200 Subject: [PATCH 08/20] TRestRawBiPoToSignalProcess::PrintMetadata method implemented --- src/TRestRawBiPoToSignalProcess.cxx | 37 ++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/TRestRawBiPoToSignalProcess.cxx b/src/TRestRawBiPoToSignalProcess.cxx index 0ef211b0..3780494d 100644 --- a/src/TRestRawBiPoToSignalProcess.cxx +++ b/src/TRestRawBiPoToSignalProcess.cxx @@ -533,8 +533,8 @@ void TRestRawBiPoToSignalProcess::PrintMetadata() { RESTMetadata << "Number of Matacq boards : " << fNBoards << RESTendl; RESTMetadata << " " << RESTendl; - std::cout << "Size : " << fMatacqBoard.size() << std::endl; for (int n = 0; n < fNBoards; n++) { + RESTMetadata << " " << RESTendl; RESTMetadata << "Board address: " << fMatacqBoard[n].address << RESTendl; RESTMetadata << "----" << RESTendl; RESTMetadata << " - Enabled channels: " << fMatacqBoard[n].en_ch[0] << " - " @@ -549,25 +549,24 @@ void TRestRawBiPoToSignalProcess::PrintMetadata() { RESTMetadata << " - Posttrig: " << fMatacqBoard[n].Posttrig << RESTendl; RESTMetadata << " - Time_Tag_On: " << fMatacqBoard[n].Time_Tag_On << RESTendl; RESTMetadata << " - Sampling_GHz: " << fMatacqBoard[n].Sampling_GHz << RESTendl; + RESTMetadata << " " << RESTendl; + RESTMetadata << "BiPo trigger settings. Address : " << fBiPoSettings[n].trigger_address << RESTendl; + RESTMetadata << "----" << RESTendl; + RESTMetadata << " - Win1 Posttrig: " << fBiPoSettings[n].Win1_Posttrig << RESTendl; + RESTMetadata << " - Timeout [200KHz]: " << fBiPoSettings[n].Timeout_200KHz << RESTendl; + RESTMetadata << " - Trigger channels: " << fBiPoSettings[n].Trig_Chan[0] << " - " + << fBiPoSettings[n].Trig_Chan[1] << " - " << fBiPoSettings[n].Trig_Chan[2] << " - " + << fBiPoSettings[n].Trig_Chan[3] << RESTendl; + RESTMetadata << " - Level 1 [mV]: " << fBiPoSettings[n].Level1_mV[0] << " - " + << fBiPoSettings[n].Level1_mV[1] << " - " << fBiPoSettings[n].Level1_mV[2] << " - " + << fBiPoSettings[n].Level1_mV[3] << RESTendl; + RESTMetadata << " - Level 2 [mV]: " << fBiPoSettings[n].Level2_mV[0] << " - " + << fBiPoSettings[n].Level2_mV[2] << " - " << fBiPoSettings[n].Level2_mV[2] << " - " + << fBiPoSettings[n].Level2_mV[3] << RESTendl; + RESTMetadata << " - T1 window: " << fBiPoSettings[n].t1_window << RESTendl; + RESTMetadata << " - T2 window: " << fBiPoSettings[n].t2_window << RESTendl; + RESTMetadata << " - T1-T2 timeout: " << fBiPoSettings[n].t1_t2_timeout << RESTendl; } RESTMetadata << "+++++++++++++++++++++++++++++++++++++++++++++++++" << RESTendl; - - /* -/// A structure to store the BiPo settings -struct BiPoSettings { - int32_t trigger_address; - - int32_t Win1_Posttrig; - int32_t Timeout_200KHz; - - int32_t Trig_Chan[MATACQ_N_CH]; - int32_t Level1_mV[MATACQ_N_CH]; - int32_t Level2_mV[MATACQ_N_CH]; - - int32_t t1_window; - int32_t t2_window; - int32_t t1_t2_timeout; -}; -*/ } From 39965547ef3b1a4701e6e434ca9e6e7cc9d851df Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Wed, 17 May 2023 13:02:15 +0200 Subject: [PATCH 09/20] Adding truncated data file for validation --- pipeline/external/BiPo/BiPo3Mod2_run_2600.data | Bin 0 -> 307200 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pipeline/external/BiPo/BiPo3Mod2_run_2600.data diff --git a/pipeline/external/BiPo/BiPo3Mod2_run_2600.data b/pipeline/external/BiPo/BiPo3Mod2_run_2600.data new file mode 100644 index 0000000000000000000000000000000000000000..1e117aacb601d49fa6ed6299d884dffcb10339de GIT binary patch literal 307200 zcmb^4>&|WKn%4C(#+(aO1ox-lR}E)i{ABz@^guiTvj(RCAtlj>eo+z<(S$^hm;eGs zR3wTe8!asei%qd9Y6H}6P5b}-jjQhVj#Viuv1Ute?RoCabzk@OJgxQqZpJ(RoqzXt ze)#>r`u4Nuh;+adi~|s>!-fF{_gAg_g=66^LrmY{E1iKKm1nC{}-3vD32H1hZppR z-|~9>*4OJ#ziK^Sf9*AYzMeed{hP((pL${a)2~-L|F+jF4*$)A%acRnCy#pg&EoOT zzOa7#>-9TcuYd0Kio^5u>+wj(-z*;g{0r+}c)k9`*Xv(;z0#w7@mF52_SfHez1kPO z{^slT)T6ch|HI>7dF5}P{#rbKqx+-%^qa-w>wVgqbg%r+uh;+hdi`IoSNBR<{NVL^ z>e1f%&EoNE?bF|=9_{bnEFNF)(uJxi)gGT;kH^39 zZ~o4=+@7(&{V#p{;otjLLwo)A+41S^`tkFp*YVBg@4i3l$A|sn=lmbOoIkvx#Ah%5 z<12IHPrn*9UlFWTXxss<7?~k9>L~8xTNQQXh%93@WM_YmCPtMXzB(%YqP}^dkIy{w ztDH4Uktrftr`SD}T5TN^H5K)uC*!>0aj42{IAFA>C%^LOk^a+XmT@jq=SAVJ%JGmJ z-Vfha^26s}`V#x|U#>s+zE%43Z~Nin=l|-<^*?<1WBz+z*DC*>m%Tdw!RuO;KkypI z-0Xzwr1QU*i7u7yD1W z=Iy1Qe&Lk=Gp}=<|LoiBB&I%klEuWzTHX5qRLS{Oqs>yD<`$q%eOD<#_6Tk zr*3q`x4cI1pSrJ~u5`49c&&zP9M|vJ%B5NH`hhn){rEcD2b<&I85+*k0A}9!-!oQB z*{O5&#An4V-*l$!$Io=@St%yu)qz_!44xvy=0A^KaepE}WDlXZQr2nX*fmPrB&-`+BMup9id^wV_ZG{XMEPY@TF>E{(9gj^l)Mk0Ets@UNPXC^ai zoTjyW`evJUu26I^UwkMZ;`-h`g4g-t)eDh+^4;qxxP76+>>ZGd%7f`jlVZkvJr*C{ zvb$!>LZx~d*40^0;$=@iTy(qK5Lbl?n{^%Tb9{!b@8m=aC=yFXW{ zT6<27^|~xO+Zc^O*y;?w`Iz&T^`6P)=u2*T5#yH+!ZNLg z3VY`+LYL3VLtI6?o8>7(&enJORmo0*aQTg{61-ycURH>ZRcXdQMC*0A>nn^Y=!)I$ z>QFINF=PjpU!Sd>&sF)#*P;C<-seDEo#m}IEqL^mrPb*?Ow2v?#EPnhXVTaeS;Uk) z&Dby%Jw@ZPuoK8~lL`;8s9=>Sn=)yE9?)W)=VU9^Js% zvBp%4+z{avTg+i@JWZR68rL%PAoegs(&g^tAyz|PNIMQAhIpt%p>;zYF-5IbSNn22 z;^+PdM}D8L$|-V{^K{=VPi;HneYNeQ?X9s0PlYkRx_XciqwUK0_M+0d;2l<1_n~!K z{&AP>`LZt6789S2^{cm8t-UH!<7&gBSLYBfV`{O(O^8AY}HWS?7xkaYtBrylXesqv-7Avd2uN#fM^7 zv{Ih*x;%C&h2iVBF&YE=Z`kp9A}mVXF)`cOF40Fg+edoBFPzxxq)geXn}6%OeGXCV zI(M}uPg}^h&uE7GYS|-c^ggd@?++1_7>9L^x4oiDpKEj)O4X*Ibv|AArw)~4)iIS; z?>Ne$mR>@r(&`j({NP~{FLj1{-uL;{!&e6}qQmtgCd~CPmP2)gFuY^B`{Ps+GZgh= zoElRvOrG~lpj4}MFY3CTs^#(0Aq4BKrXJIVev}REs^`njqU!psdUZRGw}`52oiM24 zP*q>n(Bk3l4{ht920V!3Lwn*-3G;F7`iyA~*%h|v#>KLYD|O|qUJ;Gu>9=w0_^zWy z*`~#E*TY>~nY=sj4AE{Fv;5+mttVR+t3k)>tktpqwga-L3AsG+*|F#vrb^jnaew4# z*U@4Ko`BSXwS1K}TPIu9K3|3SHH)%jVx?noJaqa^d)tbFAUA7+ZZZBY_{u8Ax zaDaDl^9)IixZPbbJ;EJMdC%v;aQN*cT(PG-%(~bsR^?iEm2lzN+1iNgdpbHOvXS|> zZ%Q@8G@pETaEh!?nQ@!Vwa7k)Hp3sM?De~9r$fxMzt;mk9rn&G2V>~5t20;V&RK9B zKRRtz)O}T@iy~y{cX!Ha@a{e>X4>m2-Do##Iuxgt^$QPctD+{w8pqugTUBKB8KxQ{ zjHZAm1unx_WT@EbT(!>oK4=+wqTAxl^7L}X___Kr^}~+4Pi4gy!5=5Ptoio$KELUI zD$u@+c;nk>_TsizVCk=C$uy^ac9GWA{f%WF-mdE_OC6W>=~urKitne--+SXgv-}iz z_NCvx8&IEl)YnVh=wv>2aqW=Bm%V4>VU=5ioe0Is*A=oih zkY)YueTv=vDPsDqTfJGWl*3Qu&G5E9Gz&$hm}OSOj_s^s-Gs2G1nlh({X9FyEap{# zVIO8;o3_@6YEwRZuehe|x9`|mEjXQZ0@=P@o#DtBroP7x!aB91arga1(RS=sqYmxy zbn(;3b?qKmjWMZq80(w5$Nb)x7g;Bc>ukHsE|I-egXAe!5~Eo?2IP`xEc%Y4faQPi)8Yhu`lfmSx}KYE>GC z!ru%tXSL_UQ%zY^hm=C~S$E%lc{TdxHU6z{ipER7p8K>)9gLcq` zu3H;@h@355LtSUfSCcg+yW<*Rc>8u(<<5_B9-JDKE^`=Fx1zHy zD}HK}wR~O~i@;W;t1xTVxZ}@C=V7Un2Zy{~tGitHeq5|{qwVNoAwasPNKy6cZqj?U zJza5|(s~ZVfy=7UZR+X9Z#pj{pB#MdybAeYS8I9J4m;NE%Vw*X61qGTSR&@bLEdRp zOx!yA3K?FuRe@XWDaMk9R2Y{jSxpK zS>3oSt8pH@=_GrKoDGJqjc@hbZ+e)o$j0uPaCQ$?G5dI8AhsO6E@Hgxh%zrb+cD*X zz`8z{vv{@JEzbxHs=IzLv#W-V_1i)UgKvxud8>gWkZ_|Tj8v*mZO{5 zC{hR0My8b$3p2YN(7b%z;J96{+RduJyB&k_j-9?B6{(xJh{7Y?KfK99BgT~|M-oP?@9=`Fw4%bz8E#h(-{aUQD zjs3<`K6_a5ptT>y?kc40YOQKq4?Feo8XDxz>!}e{vtYA#1(xr=?`PR+`2;=Xuqm$< z^j?6Aitp>59`fS{Ax|iER9{bivAs1J`uZxrSD9ltwboHNq3d3E=4U$vA=7re!iKsk zco)0T{PIs<^BC$%m*Dqz)!*Hki zYGkK^b(o$o)y#u`oZL@vu`cHs|KysTe$N=(%G-)yuL=%o=f^pwPX%vmT_}bT<=1=n z*E*q?T$+si({|Bg-E}=06<^$*+E`Clv8o;OygI#in7c1LA@Zj;bX{HT=Gei8hMjTV zMmslx=8OSOqJ~+P^_Ui6Sxtz`UGMU%o~IabRoe5?l~U{fBI$SNP}B`|J0ix;t%$GQ=`PW*K(YdzRC>=WKqxFLFF^UFY6EV2CW&NX2-KZJ3RBj*mG` zya)jrh2%SMbR+Ig%!?wHX(UZvad54`01kRV&Lub%e>n!&C4G95M#!cJ^!Bf zyCa}v?=XWQ7cV<3iz==VxBGmBg*mjwjo>Xujbp9CYOluFE^B_>nHfLNUt?`Qr}U7k zzk6o7juQokvYMBvpQ0gdwWu2IcGMw;HiRLnuzfp)rWM_&X3d@m`eorAsyx`T^=hAq z+CCl1m<&Tlp)WGe9pRSidAaZNx@+D?uB)(?)mRjid91_kq9VLRL0Dg1^VXF-DqzJb zV*XVu)5@)%GJ72s^fIVPh0P(1`({-O$6VE7*w``3TCHAKz2_E!BgFZJT(+-|a68OB zTd^JwOvVRpnO@GTp<0Zm;CK`_eTuHHd>HOdg38{RMjKJXY|jg`&SSK3EUKDaG_Goj z@^41Ae&SE>Mq_ETb=yV4W|n+*$=1$S$LRuT6|+>!SAijPY}f6cVxMLz zsa)Q8?VV?xJQ=E@`go4>;;I&wC|$&)xNNSnFZR~@iK`yVc*Dr!=T42_6fqVXkBM$5 z7Z0!Itqpq`VBOWThDvHuwee8H3Ca4Zy^hCvh;md?e|TNr@3^t@T=$a<>RpZSre(e~ zIBsE@cMiSG*~Ysl{PM*OqG$^6$E1-MHeB|-lWbSjxM(~f;;@?4!n(XhR-%lpscfpP zb{+LPWVkVa;XW1L-ac)P`Fhteymb@~fA*_{htEdYzkTDOF67Yg)8#nEzzcTKp;655 zx8smqZ5rswdG^?;LbYmzrq5}q8_LrHH=OSGKJ>TfnAwfpU%uX{mfz1=e^B*=$@NtX zG|_sTg-%5`%DS;@Pcc6GPed3HmNVAb`@3h~`|#oIZ%h8dH{W~rchBl}-GA@Poj`f@ z%kNo&E9Rbu>AAmaRR60;i@bi{tjr?gPm9gA_v)nB{sNO2e~&0z8uuGL@oYb}7hqLS z_ttg#G~4=Py|_I`RPi}UByP7-bpszlYd(G3f3t1}?EY8js#+=a8e6;ZpQ^CwR#a&F zDl@Dp7pGX+$=gNQV23-Mt*Yp;Eh@|EH(RIvI#z!bEAM`L;k)l=Z+(90i~Segl==Ai z?|qs7<(EI4Kl5ef{^;u(!XJK%`}Fw_y{<+0>t`Q6|B=_cXW}3G68|UP;y--;v#)D) z|H51Rhqu3imgTR$=5hRMFMsO(^)K4|t+(rU-~U^0cppFi-8a1NzW?{%@;`q52d`^~ z>!;UWIm6@U-mc$$|L5QEK7Rg3uWMTWlUG0K^pC&TyO!|_Z+(7z`D6F(>#vx_;+wa> ziWZ|^dhN|J{WY?0Uh!7!7ry+I^dGbGl$t9kkAe0t&2?HAwp`73FybboyUPN`QNaNY>P6#)@yYu#Sedb9ued9g-@TX%D?qoeab*g6f zLHeto*P65*)4!g>9Inbmgl<-z?D`l#wZksb{a?K3+0Sx_v$amA({ObZPRRJ-2qF9` zdX0CyIyN7VuH$!@)uG#=xoGGF^4|MGR#%=*P^>&SX}^e(qvX(onN*~7%jR9Wv=ut=QMGi%(a zSe4A+#$b72>rTYYpGw(d*2hZ9mmA*tZKT6SeF|AE>#_dpU0!vI61n|c_LQC1b$r+3 zYE!d)c^-dhZ5)Igz-Mo%sQ)?<#a3)@4TmLI^DXLacg;TjbKAvUst1uv05I!-l4`x%wnf| ziZ#XyS6bIKeq!{rbJucOnfGg_wmOS2t4jNt4$p{n6KZ_6_T`61{nZ(V^b4h!+1~H- zr{{DkV|gKCf_E9yyLzWyo<*yt^VoTRTudMHxO!stp)+y3`dWy`S#cnO< z_(RUiKGs9Pm34dHouzi3L!(H!htu>4s)L|V65U3=lF?H<@tQJ ztMcv%6^?&FP+hubYov$9s+e1~#yhqq+s}B+dMkJ9TPB1>nPV_q*NdwYPbgVMZ?)B2 z=IrYSZubCXio2B!&03$<@mZ&|P>p^1gtsU>L$$u!JL_!EwBqiiHoRD2?2N(o3%qrR z{jg`1r^{+If*O`lIXE|;HN0cNv#47^dx;)mC>@U4VTA86qui?2PqC|AOo!bATXt)@ zxbStO6aD9RGP%HDn#|jPG#8;68mm$f78ji*7Z*2h$^;@NfU9FILUc!uSgA6Id= zhpk5yd$GUYm&-du{e;x0e#a7z@y@P;>^d}}zdmKpj>lMUwX&*LmwsLVZ;=pXkJTcq z$n$>Kd!+0=qhhOK%*v)qwsn|IU-upPILS*9d$Yc`yNbVMb;l-a2I>*=a^F7dObf zpS?oXV@SnSzZfdvrYmE6xX2C_PRA zUiG^R=i46k^#JxbPN!<9e=Hm6N^B^NcK4`?t$lQw4G)7>IV@_dV|~G1?OWfWyFaE$ zoIHh|U8jvo;;LoEXcFiADzjmjy?OB)H(!jtWahWC={Sa%gpfU4_fU2-we*ie=VI&5 zK7*_hKI2gx{e;tao-kzi9M#w=8TEBG{iZU`VN?}6XgV%>m}1j~zEioY&U~k&%=lFs z8@SC`bbj8`djHa6e2W>!t~;nRZ}_XX9lXl7V_`xVqw!pJ-r};?RlPS3#rN;yBU^4` z-ybTI%{{Ribbz~vup75xWiJ*x8K(gTtRmI1XUaZwdvSHLkByk^7F~okCc9E@I^Dk5 zE|vj#vE#sM57V(aS#`YiozC*8eDxbG+qIe@6^Yppp1s#8yS_x?3$c35&%ZjDZ%xN# zHMg!+Ywy|ntlJ|Yjd_)exoVC0iyx0?M&sqL-XiIgt`OO)(dha8Gl;r@80WHZ*4dO9 znh3eGb?-OswZkfAqx%!>*k_fU4Th&$IAtyt%FwZ1ec1Wfy{qbJte&w@hEaXhJyq?D z({-a5+zMW=H(D(`uoxpz&G6J$J&)Pps5DlshgY#%M|sQ9gN~`D&Q#m=6w0s8`+h?d zjhDMxovm{yVyszMo=sV))OXD5_A-mI&vC=x#+$>KGFjn35;awKO_hzs$$`Q{G2MFZ zq^3SjV>q45+DsoX@uNkxhHeD^#$zKlM91P{HKmO6RPXv-^^|QrI_51_^hV90yOVm~ zI5n$Pt}4ZPALw^0@`NG}i+%F4^NV-H4~DqT!#18WUE#9pYSIf@wJYB`{2{*hknjTeC@vs|pz}WMdZT!!>C^*yl zaP8OZ!(Er=st^5Hxf=8kc^K;j_PWYHEw^W^nK(UdN2S)DMXRdL*VgUXGLI7lvP?_- zF1yaWUs8Yl+eMv=Ra;gFs=;hlME&}n0bR4m6d})UfOqV0?!50qHr9(O&t0SksyD_5 z<|ZZ*c`v?&UU>0zd?F_PP? zRiI3^9ocwKsniU+nxS1c_^sa1)@!lZ%y}CR!Kd#0n84m1D}LWifUt8{&%ZQ`xobFI z?~823?>LTPd1sx1%fZXqjQ6_2n{^6QMK!&|tG%zMP*0IEaWA8>YFB6WEY`~!k1fB< z^_LzPOvh<8D~|ZRA74HFcMnaGP^~}wBGj5zv)Au&3Ugmwt!5c&LEL^Qt3LbP^8PYe zKkM!A*U4_oUre@G7SplVZ{K|Wx*1zu@x$(C1ld@(GIc?zaXhxERWJFgOuc%LRbtJdOThM*P(w{se0+cVcX4reG`vsH%;%WUyzriac&cyixo zk5ykc@~T{PRgD+7J*gh+^O=`D1;=K1%@>`Q7G2|cEX9a!+=vEdaEot#xwDVo7>Fpg zPP&&dUx&vEV)o&}fE-hOQAEtps&Z=!Gux0FbrjD|gZ#tWzNC%#de4so8&p`?X_57G znm)rWvxw6>7PKF4zG+mf`(v57Ke?2#br40{SY)a#ltP4 z=au}>!fWO%_f~A0jf?f48tPizB4$@L?3l7ve>`C)3Vh#h41kr2Ory#rNI=UA047rA1oFI@(bk zQM=-;+ib&F{W9&g#o#I~9;eH)cU^t|u1@~W<;N2~##p)|tE$FEi=JZac44s)!+`9G zYaVAiKd*InZnj9=FoH(A@fg++nqxk!IO&OJHSZq84T5|Ko*}-^99n&4E7HG3J8bq< za3{`I22G~4j^X)NAoc60hVLZcwSMI4W&I5K?sY7!$JiEi%vu#)&dNWPp4VqhXnDn_ z!i|S`>i}opqc_`gKs1%xuRF3^x2>MM{Ed1U53iY=(E9o!)rTzJ(_?#A=J6E${P|1~ zt<J(K(f^cw=_;r#G8C>SCgs5PiQrlpz%16SXMMk*BvBJ?FC7NA~XQU7rW$W11&k z@1IX&qY2J7;>9Cr1o>c`)Y7yB_mx|FIV9e#S0L`Rn<~XxP~r(`wJws>~x&1Y0|6SmLH2 zYZ*qZ4UHkjXso8;^p%x5ixIuML~T(|oQo9~XSK3w6`j)L; z(a%|9uRTGF8;5((Sez>OJF6T@F?Ve|>=1`ZwMA#o0*l_b(hTPGTZQ$j!m#a^YTnc6 zsk`jyUT&ObeeP~t;d!2v_3Z755<(Tb&Tf5=Us&@u%D>p`UMg;1vBl7HF0|)i?WgN` z^fXk=kJ;i>hYkZTT#C;c(^()cb~v)yw;jjH9W|7q$E2~k>slR^I#)w=dEst8KF>R4 zU5u%$(6|2gbf&JSU%JZCCtmCQScas(MpnCP2VV@V9u4f!XU7oOp+G8g_vtYGyRKjB zd7vLPDbiV=tYd`Rvo9*^3Rkfhup5`vaTxT=+fk3=@AGrj9h8t;6wc7Lw}*{A9>*!K z`i)c!Z@udDIPCtwuDGJ%QAzgD>Y!M4-&bH;|EDSJCxR*=8I{>c%(Fr&dA=-WHN~!` z>yw!t?b7kZDSYwo_ta_No^(fM#d5q{!|&MVfUVY0!dQ$*%sX!_Lw+A~46m1BsET>x z`no>K+S<9=1J#O0{;S!j${p9;c#FoB&B~|9;2!W$Gv_RrFbvt?yJBvM#KD z(fo_X#%z_dc|Fw|i)yQf-?7TN-W!!Ybq)!3O0P=St7i@N{g&+f`#wRq>!~~}tVfa9 zshrI?zukU2HX$sTy2e?)kTBTaPlU3Go;%E?*q+v`&~7 zyLkD{L||#fsHcX^YHcL5b3d7-pKgq&pWVB9;kQof@X71+t44k1Z6DYpu+6KC~JqR{q3dk4!P${-y^9)?*aOSR)(KzSjVi^ezDIL(k%pW zS(;-R2AuW4d;UhN(S5ahvi_dq@OGz!WhV~1nWty9f936a={m-T4xRx1eIo{2!+W1D zCiGwUau@x**S?I$Uwpm#KJFiT>6Zfk+3Vcj#`>{W{P$k=-}@H#-S>ar%NCRW=w+|h z|MYc@-5+}S;l?#sBGx{eOGe>oe>mAAZ4pZ}lNJe~S` zXhrXg~Avr$W~>`kA+=kDvSdXdOTMcK!7F z`)G9T@1@1Bd3Znn!i)dUzOGe-^WpPPzijz``iuSVzu|v;)z@!-pDjjRTi@cV|Bqhr zA%-8qFTU(~_V?zxvWNcZ<;SDHPZy8=PFwr5zt2`&e}^r5e?Kj~#j}U}OJCw<_jlKR z`1bei%4;6Kc!cQhm3?^qeY~po_t~o7ylVb_Sj>tm@0VWJJjJP}PxJhKAFjU}R-C=) z+B}>x;}YWbezP+A`)>7Belg`2gU>f_`7wp--Y&0uyxl$g{OWnu_h<(kB=q$TA-43%E4MnHJDyIfQ$$(L%gQSnKIJZ|QT?|6FqBc;^uPt8CrTWq zUQZZv)oC{vWw^pzs<)*(a{#@o8UZmjR) z43lbMjvtk#CQaiL21Z?>KX<@+L-6F*UFUD#a;pImqwrvzUCu=r)$h|*R4a(J)v2S~ z2g_5b_^0mPKjg88mYV8!ZtSS`7&cn}|LBk1)^xF9u3u}jDil*A zTdy(0StNDx)R*VzJr6>s)^f2aOa5^6-7Fk^i|Ed;ei@CXuO9f=Xo#z`l?#VPy}!f8 z%8Xwue6_N#V%RW5^d42lJ^xliXYHdgj{Dw2L!rgcR8c3qypY#V$a3(J={$Qg_x~`) z6Uwt1PZlaYkro{;ZHfh`wOWm?Q?MSwOdSffM{p6JcOAQ$yF2Vxk@JQ) z42*bG8s7L_C!rLXM_)r3-q`BD*r`Vs>t%fBbrV|SDx}i&+i1@kG2%p2r5wzmZ3eTP z?8T*s+3x*jV~XLTpV!cN>wUQJ;`?NUZ5V+6=SsvSq!0vn(o`!~R<&wpgV@hkDtHN+Fnwy&mQXnNDN0E>=g*dV1zT zl~*6TKa5wajCgf~S=RbhD~oE|!{%Ze_xWY{$CGwfM~!_gW#$|=9Y8xx^WU?p_r5H} zb`IMabM_(YBGvbOq~$^xPFEcby||6LrcZTz?UtpPD7?+A)H26rYKd8%Y#l68FRQJ} zc4^jU<)N+1Jt=(sVOGrX8|T%0q8S%qjd%aza{4W2@vfckSQo3^3S`sCv|NtpBDP;b zdOvQ)vS|ELq~m%VALycGUZm)Jj>T3ZcDVc~KfEZ?cy~>fv4e^Qd-wj{_x3)L|8gi} z4~(lB{#AmZhsGOOuh7#LY`&~-gvse|pE zd_`a9#}S6J9S3RSkn*-K;HcX;Jl~@jKM|`NMhAp3cFiVwwdbembyU5vVJ*)ZtdFjC zuCLE=d{)Aw{A1IevPWlIkK#fN33h99yK8+-Qw&ed)rQ#jR`YFrb$&{&!|@xR^}&DK ziwkc$+Da37{XE;IJ!SF`1*I34t-8#XzBaUH$C$I9E>@dr{JE-_6yqF^7(tMb%*w}xe$8h(g z)eKK;h-UDH#P7WITrJhhTIQ`j)B`h_)i*{Zr+8Bn3~tcP7;gtM;) zv3Z{f?Q*a&KZLDg(S84~wYLkb$Fq<0t!kcXSx+6vuQO|G4;A;!D5?X-lzr~2Ax~TU zrjyUl<*PrYFo(`Rq+-Np_bgxJ_{CDc5JQ)R2dput`!M!QE`HCKG>LgOaYKY#t-Z#R zVpFxayFaqx%8u>$bUpkcuvV)v4d`6#?waX`&A4JbjYGex^9@@i*18|Yjj+Rhyqm=# zX7OoV;sSw+tBSp-_SUmMyxVh>?hL!EMn&MXkw{k2VMD@|ReZkb7b0%@ScDjRC|oGc zbYQ!4U0=Uyk2l@*n`emQooCNsh()BQ@84HZo)JxG0IMuDLw95w+Ef;$?z0aWR&cel zsaGE%RAGqrS+Qf6jyM;YwdkRlAL3YEU!u1f>*l%$$&9ZV)m8(;=bd2xjrTOheGGIo z#*6Jr0oUuMy5q8br%O?^4o^p0r?D?)<9l{x8Hb^D9S`-pE5_UXu-NSO3+&|;y&M?w zZ^s?pb)|B6x9+jS5}q?__U392F%DT`9Twf_Q_S!hVOdmG-r+2^tEyeSOToCv5H70G zal%#Z;ixF9aXKE}&@O%`SmIQV)&{RVz1j_p*K_;jup1o;uIqhq;bo&9t8rYz#Vi{x z!=H|-n5`PbI_>+D>n-c*UYA4OdR>*{Vf~xGuWC=iQk%kItuFf*tx7y@H^i_A_uFOY z?KqoP<8mPugI{&yyAE|xrtB#?Caj)I`W%lkv(pd1qNiu0^|hG!X7{whjjwaa?|C<4 zGy1w(-RLVnZA0m2E<;>R9W~prJ;qbKL*{CS_r%C9Q}h^i#ic7W)vjjyx;09_uAwW1`djsN zWnKsSK7!6<*~yb9UNM()~4(G9;&Wh_mT)m*{jID&cx$0)O<%wt>!sf!#ui7I$I^UHl4gyECr&@* zds1{g4%w^G_ewX$B;M0~>r|{UK6=GlhmDt?cYB0RF{;kATx6XZ=i9pVyGwEY=F9IU z`+rgw+wZoA{u6KAe*FBuzCBexe*Pa`*LeS_FZTcLbq%rKRWIYuy{_f``7inZ``f3C zerMe}{luFxA3pz$FY!P4^6dTFuWR{#_ieu4P5GiwlI@)#r&+eaptJm** z)2shCcNzV^wZpsL>5g~5Yn^rReurCJ=l&ntows_QepMI0tG(|}`(54Eq2JBz@H^1? zoAo>8RqNjhP`&>*cntSD?0z@BICj57zTeIEJKx)N=^Ohx>vy^x;r6@T-Us>}@beV! zJtk}Sn0H0z^@sN}Yrk2jek%A)Lpysri=9q&nO8OZo7vm%b-}RsxOWyGQa?Az;tuMX zw^)&?8P8fgG`Z%j%JA!O4DI{A-x-hcQhxenFDu`!vZ2~NbcuzZhk5_dS6TKjUGsT` zFs9)=UvyfJ%ZZQrV;Z?uDP3D5NV?QNZehl;+;}%Wnnh)q#(1?~u+p(=;o0GO>N%i;?9F6Xb*d}^Te||Q z;~_q#MUPLI##!Un+&-RWGCF6s2XK|6ug3V?wOH}>5`$h@^cJRdEZevW#;(nWv#Sa! zLQ9v9*iXMa+1JOep?8GRHI6#l3dPe}6=B@Goc7r1XEmxrZ~ejCx#-iI2IlfYJ)L5t zn`}JeiOu0Q8g{YzYSh@h$Cf2qikF3xPMUq~6^j9HdcuE>;HoNB5Xi?cHJ zURgS(IaTT_7G7hL&)<2LC9fF##LGRV)~?Fpik(W3buybsSkqXX{P~B{>TgV0{p&KH zRpQ%Dnzh*c_9qT<>gzcl%09WB|H)`wbRQQnm5Vu^d-h)@z1DTJ>P=f~GzRZkS+}uK zr%I_h1R9wYQM8O^TmK>LuLX)GAyD{OIE zW?f;6tMNLWFRPxj&^ty$Ikx=SS7UK`;_1D<3?4P&(Fi7;?rFGa98|@Fr*YOXg6TXa z7muBau%72IrWtj%9;;zjTs0ihzP$21Q$#fPJI%{Kd)&qu|7NoocgDkW#Am(jBfX4& zx=r``b+S?y;`ESh)TeyiiH@7By76uX?oY(=`N5C<69u!ml5eKo6( zA)Y=I;TXIFLo#Uni&>cSkqF@jmI z9lqbL|MfzZ>uNlPjnkCUub6nBmg050T>6Aib!U~vVMxt&r-S$Y?SHw8JWM>wl$|!c zH~0P#($LCyzmKXI|dNUt>y+9ks z;!YpPomDNq_X8-i4q@DijfefBaxr?K-&Eq|Sp;0RVaMTXJn#@2ll`+sY-}W*sr*S?nT~k*^=k@B&mo=Ttin8kE%2@X-Rd{MzzxY{e zc+b7_y)W^r9!?CJ_qq}GKL5pI8AZUA=M$hYyY8StS#Gtw@TbNqPp4wm=lUDMt@;p( zNTu~!cKKoNXA}2cHt(`k61y(3vb%6w^pjN{HRn~=EZ=c%9LIf{uIh9z>WSmI^RyLv zXmY#X-rGH4LZjJ}0Z#adfG1MFV(M_%dBw$VJgd_#vv1`t&MslYk4Jy|-rm(?$3n+e zs;sQztryIzEw8oYp{0A}(Cniy_M}Lg%hyvFG_9U~&DqC7O`d7h6;FAcy=TB~XI|dw ztSi}BaWJo!Y?R=|!TS+i$FP3j)xD~?;6;P%KFRA5>*;5vhOEY3tg-M!VV9vU?nNvX z`|B$Evg4+wbt`KMG|R6mceY4b+jWaEzgpAHb$emo9em=IgR^IsJv7@smrUJ@Hj>%j z4@>vE7vo>m_*ubavTkj3qgvxJl?P?s;Y}O%XH2#1@vI%wPaUZ4&Y@Pb&c%1eWB%QN zs)~ang9W##WUpV;Fg|^L{@t_R`LF%9x4(P#;q_mcW1*64=ucf%Z%p&Wx%lI-@2*W z>=?0i&-yob{Yz!PmTuAN#WAzvpfK>GSXV za{Z6L`1|{4W&9Vfyej?IFMB=y$+w?{e*FC3zx?6-g*W@h&p-Y)|M>Z@zUJ+V|NAv> zKm6qD+Iw3+OD_HgZ+IU+_xH}S{M47c{=QhpuKi584*EN1RsNY*T#SD9mDkbFltbw6 zpQW##HGg>fduQ4E*>ZM&m#m*5+a>$iaX)iz9s5~yNL}NdZt3@r-s*&#_tOgx-~C;= z{;pUSUjy{L!1VC5=rVrzh5!Dp$LfpU&y@YWt}@doJU?T`x9=B-|L*(yJ74{5IeyJ! zzN~pryOaGLv3j+B=JBq&uW5>`Klt&2TZErsclG^@aI(9)FVnR>SzcKA z=&-Mu@S1;h;#qu$Ji65HJ|AVTUi0GXPkcP8YrW!^zu3LY z{ME5e`hz$7<*SKVR!5i{tKhxS(^I{kn4Y1Fgth%qFY$qeOQ`jhef_ul4&G?4lna4AJ>tub2#24>V!l;aDhO5VNXse1o zlnzhKTjXI`@d1tudi;%NA;%N|0`*~5t#vRHsp6hn8)3Ntd z`Q^%t6|Up5KE+_vd76gy?OQe6W2$@W0V5{o52ZY{o6%Cl*zrBnE43TT8#dOeVnWmG&wYcp^?(ewbj^GuCrGYlv0LcT7&7Y+ic?s9G=kx$+`h%MJPc5k~x~ zq)vE_tvh?TnCbt}@JJJDZI6Vvm~!c0#bzHK?9DLT%pi$Ud{J0 z&G0IQ#`sx{{Eg^voi+DtXf$*=&SK-a`-5uJC1mS9zUv*s&a_ZLpZeAdR-&ru{$VW> z4^KB$i%~7KRBdK`^I!{+9$2h)(Zygfo;R~5bc9`u)w`%{>s)WuqVsyV`FPmVDiqt^ zVN(e!PXZjRBR%3&uBfY?t^DvdUSHFvIn|8lbT*u!=v~}uT8aA%UiCcziqz98=w|1` z!*5l~!SC{5)uEnv(xQXD#q|C`r!j|G1v%o!%sy&1`{^F8&$!$5F(3P?b!_b+=(lt8 z@zYJ#I5fL@^7RD~24tMCN;|$;_8W~Cd!9z?NL5JA{4o)8@jb~}zdiqAq|S0ydEG-a z6T5ol^}bZUi!P#r24+@o_{%P1?~CiVnCVyU;Wnz?p_I)(9X5k(*16YoE&njCbN0h* zN9^nB;kV;_e)(EIJF=eJT~KL%+Qh0)6fMZN6f{~}k6j;|dK^v3eeePYA)nw0#_f|#UDzwjrSG@h!@5#rTvJ}xly4Gjk zPY!4NbzLRZ*Qwk+5B77eqVx3o`Plr{FKC{TdJ+@sc&Qhw<|^5jSjc&=c2S`WX^}7~ zgJF4bPZeYJ_IU!j-pVMpjF9N34?ed1`@M_pwyrX#fs8SNJd|O2l7~0di-^;*&BthY zvD~;FzuvY=({DZG&v*5kcVrv$5Y?u3-i~!NYjHl06kpW1tio*6&FeYuYus?`QuWL7 zg47IBwa1UbH^YBDq~EyWr|0Z?D!+Ro&FNmQcd;@c(PN?C&!y839wgP* zm-Q`Yoq0}#(~)%@Lov(ei5BzfE)wt6dRE3)&y6t^*_h{#?zYi@P0HMiF+T8U5y|YCB%;@ax=rVR7SEti75yk1Eq4r2C0$dq)Q`kg=WA z?0rA@LvM^%nW64k`CQ4>Rzrod*p2j&O_yHi%Pp70h)T3#;mhX5BGTDX)m-!|r}Me)FkV{<<1# zSx?oL9h0J5i&L3jKk=k&{zcri+~S9+8yqNfjPO>ojMdq=I;Vhoi{ARIUhGmnev2Gl zb*^??@q=+lMo+{;D8u*4^RI_pVd5}dT2GZi!AtH{eB!gZcPNA9*8Di@rJBdZezrzq zuue9|vRR(ZjI(0f&ZwsQquE8MSzKO>Vxv+|kXc#s-1FXhVKzT6>fd<6_HR=^zWxns z*dJd1rdB2YAEf?2O!lk)Khno9|NoW8js?_ zZ5=}~8;{;s8r#8q#WmNR49tu}nNAe}n4* zVs$=snukAs0?nVpQn9b6;7{A!9UNuI`Ru$hW@NC+R_>&<OD^a}F^$8<%ywnIoZr4-b*+UiNs4hMRxOOh) zc2RMA;XYsR$qi}X$m<$7(7ty;8zFx2_skDsnCKRdm!ig6jw?$vm5SS7vlOm()n z+s8CmKNQ=_>?%g(#_e8;yO+fc31>a%HjfIw7UHtEzr+^5V-eGSD9`&)?ACj#d1BBw zTiik!LKbU?sr!dT%WGc)^l--ZU1FY`>sXC zfA`@uUw?W!Bz>(~?01y0&o9$V_hC}u*kQl9p5nOYi_d)Nh5hWuI0SJ67t9iQ{~ zHKT}b$B%tBPgpkVj-PehiliN_^jKBVDzL)TiSsyMX%&{K&e%-LRXIlMXBg%A353tg z&8}Ker#k+tF@*Mo{*JNFd9cgh^TmqBN}Xq=Q1rA4i)$W&&lz_gh}$aSspG9j5$v)3 z8kfgD*oy3KyS!VI=P0c4gYEv%!TJ@YZhpGBf7>e*#W@rlclA{yMrxH2c1L*6d}9^E z3BTVh`S$Z~dHn`|f2FL?A6dfx<~9HJ?Kk_gHSSo3yk`BZrrq?62~Tv0-@bj#XRY;j z{AiSKt8jNne78e*ub=Yjcu%_K!@3;3!lpZwvf$9DG0hq;JI|CH`jD0{)@=CMtZu6r zKdVUb@QYM`wYr`ypXfM>w3f&3>xif4P(4R3HVNeEYphNV2$89?CEaKwy zvQ@fXR6QN9cU-AAJX);Vtm&~nXtSS#vtzr}!Gac$pJQINAQxjjrc##bK;JIWCtryA z*>0tj-4c$PA&A9WMNIR-I8O7(I}YLTVPT&iI#$)?pTa#w^XYe-dRO*rftlTIdDbY; zQ5^`dp1tTOKdX%0Z{cA+f>J3LsO$8YcY;oS4Z zx^~`5jLUR|C_>CotGKTvdfJGLYoCW#mqMY2xLg|O@H!Tyn`1N;PPgkW#LZkq(G5Qx zQ6lU{qSRQ`tTC!y{vwS-qtw>d{jtnp%R6i=R)4tXmuF>$vHIg!r6J&>1Km1f8@}FX zg8y>(E4@1B1Lqp zi@eYAa_Te`XZTgM+I}`L?|P?Z86vYEhVl0N)xn^+ty}x%$*KGI?zeF2d+25EP(%I3 z(+M8$G=lNWyzJt=M5~nz4_$PxlwZt#mIBYZOpj)m;L-fKzU8Frsx}%sNIQpOk2qg1 zaS0<_`eA10^(?ghUE$VXcjDG;tl;1jUiM>e&BM(a@_fdN-c@bB z&bR-{3}r`^>F#~xZ-rcyCCRy&(W zBliK!^zfVtW0CjuN0#wgS6vr--m1>Jh^vYdp4FQY*+qB0*Q^kyL)ScgM#Jp6e(LXi zE3A&Mcc9(eGZZ^`<1sClO`Xm~VADDOkm*-U);b%%=FOls&hoWNv%K%0vdh5L8mS|C zn7D<$ql_^u3Txf_Y1)+9de|*?rn>ruxHaI>)p?%kgm)DwqDQM$ET-;&=YGWR$$OQ` zq1-xjh1ob<>=#i^m9kwn!H@52q&s3t{);eT4n!8|(IikCN(#-1NzTra$1mHOpoU)0#@$67dxJpcP@>_t{X<(Rkk zJOkpUii+hAgMQeYjXz`=@a*2%D6yQ~t06(No9nb15Iqr2h2te=J&IQ05OugtFdu?C zRDO=P-XV`kQH|;1ITt4yI@51Gsw{8ZLe!6b4^`F>t%;b+RsGfrzl&N$_TsYWz0r11 zh^I&%N*?nf^q7Y>ykYNf|EdrRNLd>dt2Oefz z_OYrKjiFWDy5m@Gnc4STlkJmRV_%;aUv57U-Y3A-)KeMv&T{V=`l&{7tNYE{-#z>I z;lqdD|GR(rcm4RE_#KbGd-i_c;HZ{Lw8;LP>rgk?t~*ulw;|I61~yjYY>7@xt)WVo%NDPX>zrD5ztLzr z3$NwuNl`s4p7_heSZr)ypE~Zq_{GaTdN`~+V#1?NvHp_Rr`KN$lk*qfo-H3f|IydA zO8?21XU&g&x&EHlPL0Kny?qzx`;SZnx_?PRS{_>RlU*7UR zd=9_kue|v`z5b$^{J;KX{)1P1O#bFuTz|<-zx~UBbo&Qi;{M?m{GWfr|M;taq0Ic# z>o1yFrJw%Qc)0zgvv%yyeR&@A7s_Jr3t#H^mjr%8zl#0leti99vVOB)|9+$2cgaKC zy#LEqcV_dL`h%qxRPV{e?Dp>d5<*x33e!qE9&L;xV54?wM=-;?M8hqr9^4GV(7l_FF>5>C?Zs zxIDP_a=O%S`mv`-R{0cMop|)_3b)Aeigll{s}w&q!pn2It#3N`%WbPaJ-?10s@!pK3UUfznXq}s@l^*E_Eh|KydRga7 zZ=ABsSFS44b-w2LhMs-nkg9z==%@qUtrwJX^)dUQQN1%JVmGcAl|+OdhR+AqSL`&2 z#jrNgdow)5z;4H4mDT5y_GcZJSKVP_Lg(`46`Nfpi0~*3Pdvn7$z6B5FJiPV4sB|- zr$Q_SH?{4f?4j~cKk;=IwyG*rbGAIxct%jTIM};q)n}uXn%OZ}yyqfLI_D9&Gp%IS z<4}fe*OfVp?ZZ>Etn%_aF{VwCX`)JztMX()k9l{MQ*M5rGOFY=Ro+z2zqRYytiuXC znZ{%5n7vmheKzv<9;|fMRfV=$EaYq-;9#Hk95-4&@lXY)aE*30clJqk6;m|(R4rqw zis>w(F7m^V?R<@P-xez(Ye#Bifg8edi)@A&&#gfoJ&q-uX60d{9*)x;rWFk@lyX#( zrxQ5KD?*LD?hW%{Wv_AvOx?O8Sw&!kiLB>Y2O@O|XPwnmtYh|EXEk+z*}9wlMNr&m zxX+5~`WTHl-;$Y8z*XNJj3H%`(kI=5d z?9V>MXDM#`ChX~K1&YHXPx@g{RC7FsqYpWJF@b>lp3l(BOM|_?iNzq4qB_c&RVLqY zYd)Qd7_;nj6M+Sc;+yMl=i*wx0kT)VCj z9aia{8^vyKmf3;vs*Vf${8cP|*X&zknL4oY$8TJQE>Dd;gX8TJ2wcokiI;@-19BQ~_(9_j8)U6iA z`aQPpSH7(HhlkTT%br)fUWawv;0>eRVqs5FY5R*tPhGb{*TZw=Qb3nF#WP#)p3lzL zL%y+*L;q*LpcSd+9p$6YmVRzWFk1yU;$d`T9uO3}J zlX-_Mo{feqXMc|1%PogKDi%k_?!)UH3o-oFDcf4$KjwAM|I}J9hUq&KJ{l?&12q(b-t}5j9JId9u56grkb&~N31cOL=WE;yRmuNsHNkr&UG(i zJ4G+5VB=gjJFegDjOi?P`Ym5xGquLMzNYG8RwIl%%Io;iuC^xg7O6^>__YIBu%+X$ z^1r|LAZPHE*sO~z<+Q$Xamvc#I;QI(2JWb?^A`KumqQPE$L{rz#IBq0a0s(K zcyo1mL#UVWlTV-WaO+=s(cvP?i0iY9LxzrL*7A5U*{aSSyE?Q6?vUpAsYH=5PhptQ zj49}xChi(fpAd$n)8olwUiLlFSvUSGP&L85g^A4S6!(c6T?@jKz>=16J9O6c<_A)kleP-__9^WsDFQ853L7kz>yiZ4*Q|ea`Ql%ZT&zSgRU&oVg5xx!Z({&=Ud;g znI99ge0@r4HF_t>nr(H4oSnycSnff!7Bh{O;i>UHBb(Yqb%;t2e4$m1>a4Qxs}8G5 z8y|+9F(kZvUR%Z?;5U}*Rb1yCLxY_)3_8dfk7bybH)dAAY86$4sKx3nWc6HEyJ$*0 zGv}R0Z}l76aK@Bn3aK~7GVR;lrx%(1@V0WZ>EK6unw>|z?x5Wt*K51U{fohBz1Ij{ ztZw&Z>)!>Hp@*@eG7r>ZDdj3-p9JKEobr1LPhmR2nPy{W4tbiZPAU7jG2Wg-x+&f( z?`(FB8D2QSW3fs&tSjq;PaVvjWtGa%rA{I6s(VV76$&r*W@9S5a~8PuYwxUnSF7Fm z$+E2V-_^ky56JUi@bx+m+up(~9QLV=cO1iYtX|i!>lGjS1{UVUjEB62$F5sE8oM`&C^}`zrW0#bZ!`|idVc2x6aFU#z9Fc()%JDE z?FX#OF9ObTC_*c7BGioazCWbKSZr2r*;Zq_wfSCkP7Tr7w@cu~A`1<1sxs7Phje#e z9S1A0d-Ck{iv@gLvssVoZ=~8-G@EZ3aqLx$uOXj0)?Kx|${CaGsBzIz5j$waPZM=; zV5w@E^FR*)Bh2&Wxm`OJUH3$TSZ0;W!B%Wlwo`Gc%IPE)ca_Rl-#MS}-b2Ru>fl%m z_OSDB-|97<+t>DxpX=RzDiga?>G4ciS@MW10s?4aMM|z1g!HJ87s}*J9R*{4A?JMEaHM1(!b5 zC?c=Q;yS-aZ?+ZH%QEB-qq;Eku)f&TonmG7+K%Wdiw4(sR(0t2z88Gf* zr`kqc>8*!qQ~_VT;~eg>%yv5i+W!7ofAh@PUp>R?)9df3nSbx~oAVv-@mg1wy78{v z$oCqz?ij`ObSSeGqCz9ODC@W4>Xw}Q>iWBu`_ir0igHrY>xLhb^s}XO1 zePh2z>?eW4wxh~fO&w07JSugruDIFtas2bgkzc=NzPjl*HB$!au)qe?i^0nSfmLJRvGd-;bUu$FUoH?ULW>9 z)cV|-z}F9yRTS~O!=C8XS?!I+c6@1AP3v~+R3!*jCN;BM92OKPKWta1eF}}wYEVqf za@Dx%Rm8D#wWjhREyl`-z&6yoS7v*^4&gr4*sS}lNL@^yuI-2MScmw>Nfp<1x*E%) z4JB@uZ>6!;)z)v^4@t##1)SZ7_~VPaoDlNSkUvWt^*?OL#nx+9J8E(H%cSgh;Hw6I zXE{cyg^g35NU-!6bX61(*{*%S};NQ8rRohoVIO2AELtf=!H!rXJX{W~Y zeZL!v>0LgJ!^5C={^l~NP~Md2>Lp`wp^R%+M>y`iTl+lfsk6vzxbtJOvFm&NiVs8P zSn1M=mxY(BC(|;@E59h`VjIf|gMD#zTPHHrj??_v^*}S6h88wIh`Tqi`HakCV$ckn97U|mfa*NrHwhE_L4bjEfbGrq>_Y2$ zXna^jST`%aynD9kLT@rv?yMU9<5JYsfyrBD*kbamf-z)OhCfcT(kXAFA#D@_ z6rQsBd_NYl#&BJht>1ESDYDVopV;b)SvpE9wo$G3S$tu>d?<8-w_lr}~@1Up>RvenSL!h(sggsxQ zV#~^AAHg2hnBcU!I#ua?4QlFVT*kgDruW%ttnese^~ZAkWG{+;wGWX6&&D0Mw(=mT zk_DrzjUi;a=yiPiLe4r=|8~UJ?DRL*u;q*$MXs|r$0npzRr9jbW}I8M_kG!;n3Mx? zb63dr({Sm44?QRpm+>20o>Q#RY*Rzd&@mBH^>|RHJ8H*87XjaST&T0S=PrSVYyL)h zA8S_#jb+cfOuC1ripW^#k@{Gzj>u&+8|$H7q~4);;>HsG;glC1Ws0zG^hM*_Au5Z7 zY=@+DDy&DnAC@OTu}`J8r?yLEuRdPc@P-xx-H3}t=<3^P`O8yH+;F~DRmaD-Q8BA# zeTwqg(!6RS&5Nd@x>?0!$Etq3cjDK30@iAkDLN#xai=@&D4-6!MTaI&WO%UeTm?G= z-`LS4HhO&D3-sw!1?s{aPq^x>nmRK0i{9F#D5bMD?&_5tPpeBQ+1n4>m9$xI2)ekO zcpTfU*y&JidETeTHye#sS4`*ZDlP(s_cmyYX?ES4$zB{qx9_%J>~ko%ZdGFl6PM+) zj-N{Sg_U<2TlL`-x%FK(tVL{(;B7x|Y!>2js)_xRgHDRsZ?r;4o7nBH4yU85?;nIx zUa$4TcKois5kxuFbI(D6-M9l=UD(KO$pdHg_I2sF#bo`4CQeQ#-}hN-Rh5Dtz%O7s4Q+?uC$J&5#EytyL())C*850WirNr~Ac}~@C`rQ&af6z~ zBq|9CQPCJRR8mseR%KIV?UK}5-v9ZV#~RmsQ*tw}>paIf#xahuInR4D=W{>D&uqDj z|8~yd99E+}W08uX@%rV?MG?peyG49fJU-?0x8LMRCZEw{!4}W4jYVraVY83N^&j5r zj@FDJu!VjVYA$Ob>*8e2(neumxvM#EDgbq#eSG9S7I|4LVsD0h_Wh&*%gWP}=tEg1 zAjUf0>~IXZ2-pmB8s}v`Rk)0eVfXpLBFW(>I?!efl?F-+T6-{okK{^1Wx` z+Oi@FY=<~ZeL8>r#>u&qB-FA5=W4JsKn_}^xtwG}TR!nR&hX^#(DNm;>e3aWtn(`0 z_!fhFJnfQr1*P-wTW+rEjdp&=4U@F*)xdFR~f)9Zg$=l|Cq^ZftXYu+dBzw-VW?k~OY z>aV^}tEHht-}k-6yYIj2?t9nzzBlpsKDWN_ zExnzxzPBxn(6j7&%$ldaxqc$|eQ(y&@V#O`{xYy?1(E~p6h(S93I=J&GJoy-T1;;KFZ_Hii^8A@F|ndx-9(I zZQ-ZaBgw{cN@{OI%MVYq@e@bd@-u0jL0cqYsQ%$JPp6(24@Ro5-ixF4R_oK&!z(Yz z!?13}X)|W>kX?17pPf3)61u31GYo9_nE&+sR*c`~aY?s(+ObGd-W#dkJ_Ac4t2+6ySYb#EgY3lVyj?cr7+w@S6q}`KZ2|Wzhq|`C1&y@KDm2?bde33Db?)`3=l=@a@p$ zg!iIJe^E6{gLIy|PnwsQ^3u#sl&|DjpGKq2(i!rh80p0F$3Bck>NIbdgcsxEnQjkK zhwy7jHe=q122Ap?mjj+++baA$1eslQ6~&{c)Ts%yy?Gr$X~1DUoSl$#~Fv_ zW5W)+RX*Fi=;t(?h{;-;d@=A9+pX+*g=cs?H4bGRFUHkiNVB-eRDz{dT*hG@o5#ZH zqLlOEfT&_)I5lpz2=l)T zW^?|q$*zc3U%KPj%ujlaaU6PhLv^C4FT5;T#U|@khdrjNkGU+t>lf78ewm;aj3b}cj{9%q4U*78sQ3i3;trrtUagc-VGBmvF3_fGA{lUM}EI!Z2 zBAG8S#GSX~%Yz)qS*#CdRu?Njd6ogX&F~Nj)F>~RhzA^Xgdvx`BjPD$vZJ5J zWH!UfF1%1buH^&sV1fdd=-WhgZa`gEV}ytNVC%m z#UTf$ql(SLk-hFB#^`E|H70q5!!BM!SPa9H!938&u5k!S^OJ;}cWd)i?$*)jmcIA7 zytt0h*zif3hS9~!>RI0;vFt~LV~Qo&II`~=7a3-GyIx#0Mb$SqOpBLh*c~_7=be@w zhBSK>OqQRdd&b#*Sym5!6%CtRD3@1Kj8+xMnqw9WQTb}?YS?&>}t?wDq& zZg)3Y?s-qPdNzXAnsxC&qgU2F<7PYmXTgr{$DV+hhnS@ycOv4s46)TI%LHG%*{^cl zI;8F_>E>-2X=S;lGrM&42<^$cKTlDst8Xi~XFERgE*JVJJ8_Sv9v}PlSsjqiv2Hw{ zaopqb0}nowJbjF1>~J`oq32C3a+aRB@Ca|bNt)xOFRkuf`uw<8(W`c&FtTSguFass z-gUB8%W?8#P*i8{(6MeU?Pn&TEq0O97@m0aU+XM(GB%@$Pui31p5J3wT&;+Ye6jE! z26;PaD2uIC7*=MB=klIl>y?@z# z5%4*#GUfgJcI?)~#h)xE$-*AOVcM7ki)s0eMfT~#QL~ef z&vJT~QS0gN6iK22I5f{oeENItS-6j>IGgDkS*?aW(p@~O$Ev6jY20W&ycWWCp0itS z(<}e}I(t!$x9sHi`I8^`ol8X~+IZe`#<29mqR5hkC}1tZ{K(WiSoaC32zicAIxJ7S zzPmg*$D8-4=I3bzjr(ACwzkTwRhoLV9*<8f) z*&ISwIVXD}z@X`qW;nCHOu#6TlZAx22<=g}lhf8osun_=Ru3A@^qkl)^Wy#dT5Xh1 ze#{mD>wG64TJ!KdNMnH`#QMAye)0}^yi`>#F}I?($c<$uylQq9;@&Ezv%^LHLP_4k zs8yd%-SZ5b#T|3r$EP`l+rRQrWW2STX|bNg7}Do~?8$GIF%;RjVm{sZ$_IZ*8m${! z=_iZBz-cJ*NJ~`opD|al%V+3^$H!{COh8w0sPnM=!yhV!)0YA9wQ~Ier6`m0LK{Ns zX?M5IR&~{u1naEf%O0!7_+!o6 zkXX3ZT`|>V^Dt~)VBkitIMZpR$MTkhXQQy44j&n@xcu>(P4*DG-_I(R&Ahd`{ln&b zHRpxp=JP>%T=5HW84GLm@NClR^Ko30hKMn&R@Z4Hw8XTWF4MCwzl$$@j8<*lvvK;R zsRp~6LmiK0CF>#?)5i0+*VV(}Nj9)3SI)rZ(^HSJCvS~h#-?LtXNgTN&Z>TiQ+}*n zBv`|CUZjD?*dCAT=hn(!n*DfYiIbHfSiej^(U)bJfP>$xlP$CSu^;MkXs#kz3`I>p z<`ut>$b5G_&-^A?RLjR{_OCQ;Svot#rjtl!wqtOk5|wY+%WDIf1r3LAbcm6=^Fw6={{5*2-Mx16{nu z#54JL?U|4MG^{RvW-w$pjJ&2%mSWQ5uow0G3^BWDK}a*ne5V0Tq%m7}4{hkW=-uLp}?qE9~i-ImZ=lXgi4IZ*-bn&(lp4eOQ*xVYOn2HJ&%l8XnP>Zli-yw3By4o!AMlui-jGd3y> zVZ88!ktgp8@Mi)$6E>P(O!=tu^?hW0y@@#nZ~gWzMJTM>JJ{ z357&1>gB#WEzEQp^?)kw#&VX;d^{1!(#rO9&7gIC+S=>$t8ZXJNVlK!GXyx~>}a+l zNbf#Ii(D2@YBbjCY>K!+Jo>2~=l^$vJSf*gQF7K$Fv3F^t1bQP}f5t&cXO_(A{v(%<`4j_0)}qLN$e&+7$&bZ+z)9X?`s-@*?D9H$tE+>% zJ_{AHEP3}m+{N9R{DwH6yx@847DqfMjS1e#vd7*X*W`^ZzA;SxJjbR#-pfStbjuAa znwSi&waZ8GT9Gdq6YG;b*71F=Eyld{`CJys_S1a7cbG1utLyo7UZsbH?A&u8`SfL9 z#3##lUW;iyo`^cb!`3cV1~f6&n5VRFu&c$xhQ1dR{d=s8#P+2`S9s%8HuN#u5oOR zwH)EJ@uD<0TV&lu-+AD9mR^|2=0l&+mz&na0AbPLq(?)?FKy#t<|kd4NiQ~QXERUJ z4hh?#X1xkzC)29FN{c0oaXjYX9J>6tlCQpDh+rcO^v(Q+FCyCM_#SLNbhG&EUzsce z^3hcstxRr5gzkhH>okj%1!fSx8!4YpyT!T=wfn6BoE*9vrku9bP4C7lXuL^)AE^IG_#*1>2nMjLZ6n*YFe$>-PZ7=h5JRa{u5OQPkyATIgQ<80WE*| zVA*~33@@!A(2R+=v#>VV@x%AY+L)K@VzM2SU9$7HbyoG_BzUv7bMT+|G}CbAja@kTn`Kt`FQ(=vtEy~%^!lBAh_o9umo*k5 zVUa|p_&U@fU?4+0gl4rXX4uZBh{6&Xzl(g<7+?p5uW^70rLj}QUNFPQn!b*~_9nF3 z7tee;CDUGJ^JAVJR`8oQ3h9}LvltJaF<~|Q>{Qrj9dHYz@{tE^6M+ck6rRJ0_y#k)_Px!a7M_T6aH5sOgReYwY?v zU953i1jmdQIY|nQH_~j_secx&-0sUp?$TUuVvz2tG-kMa{?i}44nGumny*k;kK;Tp zuDta~vnaNMXUV?nG)bCeK`#cKNf!}0WWMsT_f5;*u+oN?L^jv87>y6a`Gu^P0>^y$BB1!h~eUpr(L1A zKI=1lY%$c0e6-Gw5pP3vPhZZ`OxBfM`emjFlgA(N$pM39G|3elJ-+x(k+I7$G58kd{y?#54 zMevwxNG5o>1zi_kYf9Qhap5Nrw!&k-pq}Tu9WxZ;A z`tnn6vv8W-=f*$vnx*k~y-D|ZPY8Ja^lMaR(z73WzWV%z1Gjj;dCNn3`OW$VulQs7 zgEzbQg%>Yf-#mM9{^(ot@)qyq^~c}hogLn-hmc((b?|;)-sQ#m)g}AlEKg+$ug|Z0 z`s8@C&reLAc`u&Jci!YZ&GA@%r`IPy*@d0OKJn^1yt4n<*S)>+U%c-5`(1DHufP0` zxA$Hz#&0L<*I)kF59_)gfBUch(6?;;&L959+sZ%sL*MH45C5=l0sHF9Kk}M)|Ht3% zpT7LFZ|h%u`Ile%`T6&L*tcu__}f4Dx_1u#Z$JE7uR8tc+h2T>|K_)!U*D$HH*5X9 zZ{Ml)8{htYuX*2m^$)y#2iV{I_8)w$e)HuwzWs;Z)_?Qcf9&lf|IKgzsW;w#``dr! zjrWhf{TJT!fAsCY^pf|@U;o;d7)RA|L~3V*I)jl*LwfL zrSEhrKmYaX9>O1f-OIoqe#80d%O8D>i{rn2&CBE;dXsIB|M7JX@qd2f`PG;I{eAwY-}U~__xqoD;ngR9?xh#M?jip_FM0Mq|E~A* z@9W(|{`0SEeE-tB-e3I5+{yHp-sV60w(pp$kN?UmjxzoWFE4$MS>G|&_ow~BORw); z`>U_@zx~qutFL+AWA;~HKUMG-U$XRm@ik`O`qy9n^1J-6yyU%l_=VTJye045N4W6| zFaLk-?cR6L#eUyC*LU_6=jZqDq9afLmtQ#9|G)40-Rn#9?$zVd+j{rmPJbix8F8unf znug!KIIDU3^+1`l0Yr>tXji7q7VURlYhk zroYn`l03rm3AfCpomGDH4hj4lH?J~vMcR4e3v%)>lB+_t`5t!b`>`^Q5Yo*<(oo`6 z&6Cxetf^(^I29-(8vSGrywwI{Lhd~KdTuiN(jM~Mj! zxhS@f%T0LWCWhHrPe%@yiRDNfdyNnhoYq4vPckNd_gbRg0mV} zd9dHaMXx-RA33`?vpTu_gs;Cgk8k$HslMWpr|iRtM{@ft&HUxr`-#@&>#0`+;-dfg zWs$!$m-qQkPkr+y?(Xs_Px!?r+`R97mG^nAsL%0EZ@jNxuYScR9{uEfAAa?v_h-w` z$*X_J-WTcyF@{x@&-o0p#_UY?q7y?pgP zn4G_#e#6s;$@Qc6twoSNe$84}vAu8K`_6ckzj!S!ezNnvy)&%1_&HuN@%~&~A%t5z zKl4KEe*W|se|T1X`N^KY^wZQI-9yn|2sPjHQ`06M1lMnUIU->J-_>@`e)qDK9fYRW>R$ilueT!JdmruOYDxSa7ZgnjK<4bSP z8}ZI-_IS&axb>6z+V}A+`tXwP`R%EnbbT}a@|)eAr{c38kK*OL$cuAf>-wWzC$HJd^W|Os@LN6bjZb>d zegDiu=;J33`IQfP@n+v$UiFE648QBnk^F_i@8XG<^G`iO!u#~=lk6_9Y2oqt4NqUl zD>>ZDySjwpeD3wSdW^~?HleL^pJUd7$L{Y1ZWM_l-K9slySeo5YZd5BFoW*LC zBCpLoKdw&sldpT;TmJGIPv<(`?4JFYynb@NwZ6KLZy)UZ`-rDbd3@#v-*DtFq}3_D z^z%CT#gSg?`gMI{pB9lg@mw70(=|Tp=e+j%wkoMxqvE9}ukzBmeyWbscWx%%dEa>` zKk02BXR&(r`hcJLU7x1E=c_$0j}QC3KFI&-(Z1=^va3_xdcK8cKj<%c&wBB!U+Irm z8MYt!$xdF@mpgax%is6kp7-F2cd!5C{puSUJNaq0`jtQLb?_f=&r^8Ea{0i2^6J*> z0C@^Ey{`Coo_qh3yyuT+|Ah($*(CRALVC^S$N3skdh)w|QQ!JFKla1kA9Ys`xZB_TUOp82hu!KCKDjlgc>I?8|fZ5FP6`dFXim%e<7v-5QMQTM8|eJJkM?f=dJ@44-p)z|sPPCq(FywZ9a-J6l{nf#~9gjT9$Id@_7H{!yKh~G!Ek1p|adr3n>wL*# z{5%gX-=|-G)Zy|R4{^lzx!<-gRzLBi@AU@$;rV>h>jR&^@Z3mGH}~?CpY^NtDpUTtmygR2{rs|Py=A z>OTB%##f!zx2v!G*=JdHPGoVP@34zk@@L$w=udwa*StF0hh@v_WO=Rr^4|(P`n^M0 zJnYkx*YNdgDD=y;IKo+7@teJUD8IAU4_%$tc(y7I>v_SCpYhI5Jlma~&(iGkzW$n` zbHhF=OX^sho-f2Be@T}oeVL?qw(rB$w|J13J#~TK?AZrd&5yjucUSnNQ@?@h-kRuFmQSr;~2{PM$ViJ4cepujh~D z&pGD2^7jY%&3b*Njxo{C>mxXQUdOLGiZAqVb{=$RC*JW}-1&RfSD(d09Cz+K^Wfb0 z$P0dU<2}E{ufF9=+^bXBr$Y~Fg0pLxl@|B}(q zPkPDu`6##k{g=g0y?)~Ebwl~7kIIXC_0_NPV10e2kE^i#z5ToO-6yY(y$(*ERrLv1 zpR1Go(|V7c!}_|s>woVT^ILc6)A49Wtq%4}dZCFk1l1lte9r&=Zhib(Z*_fpcF*TW zpF5;=`5QldSsq&D@A7*6Egw6Vw?DkzcK+Gl`K>bYv;8AK_G#D77jet?_-E(b(dT>J zTHfRxZ+VQb*Zc7Zb#mulj3z%nY2l|X;m-ee^P7Erkz9SR{&k1vBY9hXL$$xjoo}mi z{PS3RJ-QdM{I6fEd)*Z~b!~L}Kb-h=mtX5o9^QZBar|R+Jj8$bEiQQ3Ex+{1L-Krt ze+cUG#Kl9OCtn;{XXo>wdwn{7Wu-jGBfIrce(}wJ`_(!3^q-&S>#pVJ>>9~qxM_Re zbn%9l|Gh5}w|sY%*GB1)KkKYc@msx~@u+)N`4P8$c=_x3yOr|aD4zD2{K>ceYek;* ze~f$%U7qEmb$zDqI!7DjpIkqS=kkg_Uh!BTEbpx+x6kai7`KkMy02fZ&x$^NdGGw$ z>y+75m)6%8>bHC?@9T&0N}h%1xA=s&=RN12xWkh_`Qm5iGdz6|zv4`9e+Q;-%7@P~ z@o_GS3*W21JPr4rpT#@g;^XgL@7%c^p699X#3g_2xA+u49^$kQ^LzEv7vfIJE=%=U z->i@9$C$3p+rQ#D`Q;(p;dC#5y$|TFpRMaZ{huFokl*}|AO7o~)`yRGv*O4;fA{*J zeAyrIgf|}Yb$@?K&hN!*U-dWq^FN;QI{f8P|HVi?daV;*dV7BqZ|ljcM*KP#Pri8Y zTt7b7>w^50A2|69FMsl${_?l{>Sv$lFYo(%)%APv!oAlM%U@m=_v{w0bDIBl+4{$Q zyh65r>4)dM^7^2RbvhJ@SAG57-stn2_weio=gl(@_-&tgKXiXb1^3Rm;fS~MOTD}v z>wJ|zcwfI>zsAd%)jp*i@3_i;tIJ=%&kmur?Djg(`-J}9?c`|<&*ul~;FG?(WPktQ z_b1`iC(Z+r{oQX~^24j&zkG~~KD@nO8Q=OfKa8Rw z@5Imgs^`<9+4F<*h<|?ed7gNj%f;usxjeOA{_3AB?X&&;j5>%ne>;~v|I3%U;_rP% z`6!N%-Jj>j`0=;6)JZ+ET)n%OzxGr8Jbvv@^;LIyRmWEBI-#EzC1RP@9@(uKKJ#LKChq4R&jStFKw@18u43R-4GkL;J1lmS1r$UUe4F?B!#h zd&RyueyjSbd&ug(JYJmgpg*@i;LEeRm&fY2dOrK%_{PKjkl*r$zkaH-`O|;=WHo*J zL!YUSe%iiKr`D^hxa+3s6x#6je34#S*%jUR>Bl6_iPrI0zdZAwKmFUCp7s0p`*%(h zO?i%$yF9duc0ODk!nt^#bxC`?(x2b<`SMrZs(<|!N_A>BKk}M~@)O?r|L*MIj~Cu~ z6zA-g_u-b0)qnYm-|?OwaVDpaPdNFvAL3meiy*ywe#`FUc%_Y}`oi`8?Yq3g!%v;= z{KKd9cJ<=se>}YImcQ|R);Is_kHbq}e(-FrE;~<)P(S5Y9pTI0?6M3uetW*K-;<~1 z-e~9T_TfICoS)UB^-hfLJ@76s&s-~7eX z{%Dq;J&%d=&YSGEPq%+}o_c>YobZc>epkHnu>Gk{@y|~uYnbE7EtKT>j)Wo*(0?jxmkWM^a@H{_WEh{6t~x>vGF>`IayTl zDo?G3n_M5XUOe*K{&?~WFP`#^pT60CQTOYkDt!6N58jvG{rwL9J2%rCkNO$E{7%p7 z7kpR$X80|Rt%oOn`UQU1{C+n-TlYj3s(%$F0@&sr6iW_h8P&`kSm%Tr-KhFNn zk)mI|cYo$@ahC0^>)(sJcy9k?(ccl*ojV8WvzS)*aJDbH_dBKfa&;^M`z!sut}MDc zC*V3Cvhz6|e&W_=URRBuI_baVuPEy8@Ymn-GrP+#z5HYaZ+TFMq{rj-Rq}A07dsD! zCx7CVzw|tR6wl7L?VIfQY4yn?FXJ1YJan(p&Zm>dul|!y>)ESMxZ$^d)sMdSNA^wH zcW$ziA3VA`|CXoW$4Gti7jJo&r~KM)jan~WdOm-tlgelQx8I$!@lJowzn&kG#9!V* z&(8T*UgBq8#3PpC&p*8Gwa$&-uUxBesJu~O&+%IJ^S7#-+T7^{@C|^^1Wxp8t*iF;KY-0vNXzOqvu$L z(`#+lMu+6pj!(l>a+=wYlMI{fdDIv9SxfTt=$WBz?5AtEUO}=;`lHw5d?yd3$CEMc zxYTK5lh$IFvCC5P9+(bo$hbmWyw=#Y&dZ{5BEp>Jd=H)OG9k-D8rRMj@rYv)*JZNB z^S+J8ckuKbJ$d>3_T5fl{e{;&+yCxO{>_(v`|bYKmw*11)pGw&zOJqR6Yuih`F8*G z<=fZqf8+hHzMhFg{I}lpzxwhYyw=nI121_RfArn%e|q7h`MrkIqUR{HLz?tRx(k6(Su!;ioHX_AVcO-vt$uz5}Xm z-M5m^<|B>1&ntX=+db{gefLxAq|V3UQa|_n^xaV5_4#=9@?BBG%a1trolaG?&Z2ib z;3{Erf8ZVsdq4-HLV9h@bvT zw^iRMb-ebSQ~661UVh_MzGBxLuK9LLnB*4)KCEOsjgNMV55FQlziF->^B?mbp?2SU zuA-X1%K%PkjvuSjg%z(n6x;GHZ^`%AdG*YQb=UKQ-SWZv)e-NVr<0HU>T}lFCr#66 zp5!4*Yod#d2)klip6`4VH6E+S?kv=a=V@cO+3xeyT;_`&r(~C*)r?eU@iu0sFOqo- zZ&uUk3~Jqqz0%sMzjH!9X{8;D(DNMbv2wn&5>8ioc^V&g9M%WVXlKz{{2<()oD6@N(r?AL^;z<9dYIsjk2QJ6H;Fv1pUK0I>(Gpw z=dA}`Nmh@K7HM34(q?&mlMFjoXQ*oN$9_Ck=_e=tyME00=}w;ar7Ke3_68Jo0uG|$IIJjbydb?v?kXW6`!v)F4$l2(dt zGmIgH2BW!^`DT%oJXm*qMhzEEaC((s&zE>F>uI$z6imC4EXrq&t+uy4|E5Dfq<(rNmFCEUnJ`ZOxEQWLrnPH{bqRV ze36~Bmi4iKCK7lo)lMwXMGE6M;J$hOdc-x&s=hV$;=c3cb^^a?kImIIyo-PN;bV-l zmnrw;Z0NyHiXY}(S&H7;d@VY-dLeCb9@iN0GN03ZW+7QfW8x0)VwJDyguA-1=QW1y zJQ;4xKfCxfmnrv{uEto#;rJ`cWpg>fZ?i1oHBQMJ>w;$a(=Q=UZ#gFEY9$MKD672a z?`F-@4R2W)XK{tnXtvi;W2pwy;6W6t<21U5m(IKynwl2%g;rVBtIC2p+o8y@pkQ#jk6JB^F`h$1hUpcz4>y) z3vG-RFH0y}59jL9ntfcZM6xJ{YaSNgn`f(|tX%}Ua$Le$4borcpS^n;X{MnQ*={Va zXJ-^2_O8pzGuM}cR?B;~jpMV}$6~n}QWUew2xw@sFRbK50{&A6;;~FCwoxkQAvrOmWX)ToP4?HG2 zz2vdbfBZJ{!-M)=L`gq-hZp)r*J+D#E5}y!iy{j=iZt!eAd0`$F&e*F@glx?q~r8} z*GjeH*?7^Mbd2~Pvd<@b-WezOxb~Vr#~k-8LxpTc=QwRN6n&J%o<(DGby3m9Fl_65 zO?Ufq{O?>;fm=V0n3mJ4FaL{P&SEP|S=fnj8D^`?;&dV8TPNq?xWX7}8MZ&x=gav} z?>>xqyewoBBdCp%R3}_SE4w^;9hZgp<4Sk`>V&sq^88JcPcz=pJ=X=ZHldx`SBe-#_|_tkI82lcIeIfIWDZNcWrf= z&G6J0=??#V&?tuSoA<+R#CKYCMOne37&t2sy57xuzCq&pRhb^*2gadDS zWq5gd>Rw;uH6PfS=~-w=^p=q;7U{7QF|OH-UwU^kh#Nl|jb)v;^jmRW#md=`Oq3#e zvW*`fSgF{t4J9iW(^=oD0ZztQ%E;J_y082*LY#xb=BT@{*sULe9c={;hDo?cPHXF?0kOej@MYowBCu~6PYds$@O0& zh(=xgsQ1oO)t2on%pT+y&Hnb>BNNBpqp+-z+;7T5au zDQ`TlyW=i)d=G0n?9!1@8ESR;X48yTb2V=Soz9}^H12UI!=Be+4>fyipZf^6Y<4ot z+hT>+mAAw298o2|tJA#mYT0Q-XXxT0YpgR!)2-U+>cw!JFT?TOh=-ZQGb1p%%3tgA zW-Yv}g`dBAqA|PfVuoBtoyBQF7Qq;WMOz(=FAwurT$6T}%TRcV$?<4JavC?v2J_wX z%|2vx7dNlarg2E@Ft3i`@heB=X$Z^w?Kks*vYsSga-IJ8 zVGy=8SH2qWcVaPfMotrQ_C3^nxbjrq@a2C#WA5`hnLQ5ATw)@V^z7NNR8>U7zRJcT zJ9>1JiIR`B+h(OyU6_L1v+ zA8%1-KejxCGyGv3=hc5_)Si!K3(IxAyWGfH40H&at%^ikV$*-Lwu;$t`5`r?IT?OBQOnv6*~$$FP;w&sX!I zs{w63e4fB&th&z!>%5ZAmgI>Szv{G=kg=&&W87+)aJKL`eyyd)6Mm;LB7gt2E6 z`#-H#FY8IN+Ox@VIILroY*n3RvhCBw2F*E??D;5%u@Pa}XGMqCypShdJgc=;6`RMg zvBnA_e|v40Eboh#jtG_&Rer|b`7%CZ%cEJ>=6Wd($K!hDELOAK_gu9o!t=;$2p+?F za(#OoO(yJLlM} z`&M`CE)%e(J5TG+s~8PFi!9GoCdneD({=0PS6nh^|I!Q{KV2`L@ETbge)pv7OJ1u^ zD@p5$X+4?PajhI1_|vk6b9gu<6>0PR{q9f}A+||RvNMkCnVrU=;W|H6Lq5g0D8zQy z_^XZaKF@LfjobFep$;7vdRFJ_;)s3uOlv(pJIK~<|H7MhS%vO3Xyerh6L@rz811f( z_LkbHMb%dSGKd9ln+=EbVmf&|vi74=>mL4j9IMq}-qbG5acX=l^3=RlS+q7hy0`zv zbojHwDQTnrsz#UK&BOexI_4qtz|Z|wVy6Q?zcE$O;SC8Jb&!>5>~s2Xb~c8{>tf#w zj%x^VRb|syepuP3jeDq57HrZTLj1|cHw*FFr{;?-+u{YI z3^9hGHEXr3j48`_uv*U2>w(9#&TetjDre$+dJd7F@n|*PPwg~#$5Y(P2KzK%H5Z4| zz;k#k(&)igdizP5#;wAWhs%oy`2TL?{2t=+0yR8-^^UPlx;-^a_jJZ;=LgB68MBK? zR?g?y;Vx!z4x2W9v-Dh|Uzayo$`{LYF~Bt6>hF44P1AFRyk>WwoXEv9S}ft`tI_^m zcp(?#~P-hGwwRP^bT*C#Utxu4Qp{? zKX&#<$o9wb+xm7~Uc~vVL}QQTh3zsDUY?uBrH)~*cb0!q&Gz)uP5S&?7$=bpO>Xk? z-N!VZ&oH9D45l+Caz{HJt-*X|SLQ^X#oiy$WfP{@yIy{HIPaIg^+?*XEo)74Yfmv5*c%Ab2u`D;`i)+I$( z|M82x%*ZH|be3V=iiKLRR^3U;iQl$QB1(KNvf+=>N8YXOb!%RF6iMAHN*Jx_iOJR>$;s9`^NJ4!i*5Zm zUr@}_T;<{~+EuWe^Ke+0=?Z$YYUT2m2DI6RWsfh~SdRzXRz!BYF9xmlBP)%~lHB+* zmJEVBToQQc&Np0=yC&sTB-tsnPXojPSe&jMSaqbdqKV{UaY3*y#lf#oKs$nLql)AZC_b z#eV2C({lE=z78lB+_Ph|D7wq6xQ&yFgm&mXA1$tQVTE_vX1K|G_Vdnn+R#IDZbRm) zHCf2=_$1$h$KvXdzk9$=>Ve-_UOcf$1A=E8F;4E)(CSNXF~pmX-~Ky(+o!KS`QEeN z^Si(QlkYuCf4=j&%2pS-ZGC6yG}){VWNLg`BZ0Bi)mbcQhgNLU?@l7;V-`oBU&Ee7 zv-oBMgRjpoiTSuJ*;lXzVf!?$vOZ+EiTic1CK(KmI4{WsoUUHshpYlJ`Xc7}ZQ(?1eff`H@_hbRZ?9y3{Ouokt=CuCC;wmH=AXX&>G%7eeZT+w zYrWq7i|^;@Uw+Bs@r&=i9y!OmFw^W3uoKYWw#s z`^GtcjaQt$;p_fgOg@XRGoYUKOUicmTlOLJGqhVx(izLHdhAG^`)PIHku2-#X!x7W1^7M220f`ZTmW zsc$Iqm)FMgZa!&pR>KSBvi`KZ=(FaDRa&=t)rVu3O=nTEC!H5e#RE(|hi+3pcnNAhC=+tfcB50Mbb$^z# z;-UC>y;#Mp_IIk?`n+_~t)G{dJ@2jLcXhdw@z}{c`=s>Ev)oGP^BSvRJ$SwvWaMzx*~5OZU}ha=BF9;g9w5-sh0I56*Hpzx1z0 z=XG9^h?jpjm+j_u+EBuV^OUG^a_4h9P6V`em4zaY`{H_9lXaCzBe@E3{X{-(QSgX` zJeLs`;U!zY41GAqrrK3|2(5=;F1mD8W<3}7`bCCjKa?W3GMjmx-2ANddQ6slKjd3E8?4OXbnP7+%d?*jR`ANCzFoYm%k*MSvoYU0 zk0za+dDa`vPx0$-(X@_LsLLzq_91_K${!nY*&F6_eRv@IBX|O2b z^$mN7a-kM%MY>!quRP8V1UX#xZw)6I7Yjzt?#UMi~EcY*Z8e7=K1P(9avr=#$n8!{O}F)X_YQNY`V5y99CR0!aYCin)mP2 z`Pq5EGL7?;=2Zla>vmWk;B1us_$@ct$Q88Kmr2$%hIMhQGW2D87Tx6ywrF={F4MuoHkWF`4**=`_?w;wf$PZMQ&u+2;v;BdC++z9p&C7Y^lU*$H zh7TX(+bK%-G(uUPtYr&jbrR#w4iSW~Q5g8i!?L07w36X*R$<60tUSk|2MoJ)=N6vp z2=UHx)o17PgVX34d$qiXF)|;^;qi4l3{z3cFpK4G_aczLd6y{>&6oVsSk{NP_?~l7 zx$4#NEPu)6Xo%Q0d!ACVi~VYWZ@l6(mPUN+%;dce^t;-f$zzhYVO&f}vBEO6Sn+37 zy|b1po{WcX4Zm?8a%=0=^!aPliU*l&(RliLGEZ~+H_g0_OZR@xL#xf`$m4S_tm`f& zw&ZukR~{K7{!h&)^J(DmZ(3v&Hwx9U3MgTR)}S zlw}Ba26i^Vc-{=R-YVbyIPSkI(uf`tC=(| zBB=5=-t!by6FNx10_`hhfh{ zcwTGh#IEzi+c7&VJv?t?Clfj+UHaYAI2`)cF;h*?rsS({=ku@@|8kK3<4!C7ViNMSP;>URF$v)=2`Eogn zJDsvi|GQpT#G_F^*$k(wvD=LrY-v1oI$^?NDTA%^5ohI%CUB^A?+PyKLmQ$7M^EXu2Lt z&x_OOo<|tn`4`KqnoVOP@sZBcvv=?cE$Q;c*PUCl9&)CzB2Lxv&a&bG!yo6q#v<2+yNu%bnC{UR^CB)k58=1H|=bQ~`SM$ngo z#X=kRt}qU%2(lNKn4dPST~3RpK4K5Gv0f>PG?oFei(|UtOKojt@A2dw684Ay^Qnom~qgexXh zqHi+myUQB)@8bIgv$*&^v&owIF0*~VSu5#h(KUNkBq#m+7FV&Q5%*OvX5+KmT&%Zp zRaj1vh{&4E!)s-E&)X{U^oB>0M)-scmuC6foL|)=U5((UM;FSNsH&Kp4Xo3}(OP=W zrsn*F2*>^S@Rf}b&)GwRkte+9HOq#4GZw9cwcQXqIU0+nuX$d?tj8Pj$2gi5|FXj? zou_Xa_6l7QUiUf?@)5%j8uPvVN@{0?PGef#X~1rt)^anyR#z|n(o@G6)!8A%Lv)+R zt@0ES; zVB=~&otTE#v(dV!`{h23Fl8*HMY4PT!)t!0r1NO3tjbUfcz`-~>FBC?NpfTFbF%bf zRX3%zIN7ix9rvxU8E<~mAHT+VOMm-h=pin)*4Jk=d5{J9fHKc!%hqKu`D{a6FP^@5 z=nQ$$CB0ng%%PPnh<;;oaU3?^2N%VuoliWipocw!%B{1zo9bk|$# z*wQ?H7EpZ8VO}G1z{SGuc`U z)k$UYwys@vV9t(>lWyL~LJ-w?-{+cQ!o)d6r#RwLCUi^BN}+gm!jn!{_;TpF7{s}} zq&eQ=NxL8K?~R8G=@|_Uc}s`iC*II;um1eo^Wn{okHZ+>G(^nD$NZA%^*whDGfzXm zIGtBxL5EiTsn63c8=>=X_IM6?@}ybhyQqxCz!y2YU7s;x4L!NNB10czUKgJA`SGti zvs%v9&oN!T_u5Q7@{EyP_A!5TFiWwO4=k6VypyfImqpCjV-%01ALBDCZ^g>vGB!T2 zcw5J*&NSmSZ95O!##`Y%d)c^*i(oQ@JMQQ*;{q#@Jz3j&@N~7 zU-o<)kHwaS_}Gmdep}Ti&zQzR9lGL;HAMgV*f_3-9lzrUH$57AUb+knzk7N;JUhi& zY_eodLuT@X-Qi(#eLH-(=cR6nr%ZQU?Zd+0qpvLJJvDS?oTuF?KV6qSyv8=&F{7P* zKUiV6oI%W@hwie5PiXeMIq&5w-5!(U$op3LZwB3c_@U@CohE{G8ttry4_zH`RYCr* zR?9s3(`z_#Z%zLAoE~3fGS(OyHEcYF-Jh|sK1uP>msk3&FPdd@s9C_oj{W#%rT=;A zTD&n0l?~|-yZ7T^6b>)^>s8Y5wq90Y522OQTcly-o7Tm!jD=x5F00behP0~1FC4MV zwwdup(-VikPn#?@jl0K<&DalVE2|a1tgyy$cA>x}VJC8HdE$$dw*1pbQXKOwf2{6x z=F?LdtQw1H{O)gnW}Vgb3$C-ntgE^vUzY8S_FSv|Y-eKLHC=g&hw~ODsdIw2oqzFB z|78WnvV!lEGj92^tFs=5M&b0}$2EJbxAN3+x(tJE{BTI~{9lH*?zwP&uX9_cJ$t#p zHa@LRYvXW?bx!L=Xcofw$>v8NSd91X+rO|v52yO@kJ0LC=9zTt+%co4zPMx|uk$b4 z$9W$3b8QvF@nEg0jiK=R%pHGnF~l&|3AikOt;nApBJR}}v$Mpdc{VtbB}sdJ{r zq}CUQ2wD@V%<+$rEH`F3&3rUIDeu;G4mN4f8oTDt-hyrQ{`O{nzY#O2GC5xSg;k$* z>cAW`S!l&R=M@@XcqQ3M0W-XvBPx9UMZ$8YMf~ysb^hmLS<3PmN%A7!2{!Ae4nNf~ z=|{vdq2pPvadJ7*LCe~#TN71!B5SP&KP7# z*YlgrIz9hz#qjhodH1n%SKoP%aXLKRPB)^Nm1Gt&Q9-uI18wc8lV?g_2K?{Frs+l|~l# zNSh@6xODGZpD-wY?0l0Eo^~VN{LORvm^zhI1qb}XP0HJ}H)}qBA!j*Ba`EoG$co0t z>vAeOD9aSSP{jyizxTv=S#oE)?wHTm=o5_1kBK#>&VGN?_jtwb^Os+Kf9CqR_fzRl zyv=|7?H_p0;O~2zfBpKNGkN$=UwXy;U%t=(;9H%(`tm=#y_)*;+tg1%I#F&=SH_mS--#Q==;E8l$;m#eNUOa%u{}gENK?3;KaNfq`CZ< zrGN3>TH3?2!^4kX@$>^P`%v*eKQZAU^r|8c`H!`F<{^1~wATz52Or**z{^e*<~{jj zV}&9n>Vak@&RNvG}e(VF_qllzd$Pp5U6 zxO&ZlJ9)mI{`N1-Fx*P%Kk3Y%(}JvrUkg-2JP7Sl79t*1jz7o{`SAG0#wX?R|ZpV#rRkhR&y z>6sU^*oh14q|Y7JNyAE}LK_OZ@eN6YG=|*$&Octnmwi8nnD0F|j!*aHl=t~ROY6yb z!%1aNTU_E+gVu^q&c+H3jKzpUR(##+tQM~fF1GC`EEWlC7BrWaLq8U+@uHSGH7<)q z9`~EUSakR7UevP~_b1EC#F*inJWkJO`D{fs-1S6j&l=1!-*~4TCVTPXJBF>q z?HI6O$B&$rlWE-uzag_F!v>G|#FYIrN-MFzXzYfV{Z`#KPak_e;tC_C_~Wx|gh?Kc zepGqukjJsCKwkXWuQsiW&-dQO&Bi_^d~`L-Qr}ujjjQ1yEeyTTyz_3|JuUYA;)?q>t&SJF@w8E-LZ(re4KW8&i@$BE?;6y zTCa&cU-ay`W*aRF!{I{~FmO#S4Ko*wvQZ#~QMF{Z8YGubf-snvLorT)jGo{*o} zgybi^GU&7sDNpz<%H=O{wj0wsE*s(08aCML&c^)ZH=QSk*tPo1 z5k`j%ZE-iFVKnXZx3Ubimfb}>n>5;ui>!H?bzs`i+>d?It!0fh5810buk-Z8o2s`9K^X6G9L{o)4X^9cW{VR}Iz9(& zzNoggo<0AfEr01`0WX|I&hOY*VV6c$^{u*1EBP|N6K-+x#I9?)q0ZwlCR3T!m&g7E z*m<9CtY{c7ck`gz7FnA6nP&6W`|&_~5n)*2% zJp^eC@kyq>R;yfgtvXfkkq6#(zR2*p*X+<`C+o=?!O4p**(c%FT(@^8yAu}Yi*PZB zkjJdOr_bKLiGi444yQY-`D*TGD=cMPj9op3d%ZbE;l<<`yL!ObitJ7nN8{mi-|BH& zO=Op!aiHDR>R!Jzi^1VpKToZ)ibeAMq`7EXtA4Cm7!SWSmR6k;_nhCFPx3F?>*3?K zI+QCNeEg1^S7+<+n2gPL?>a6t4D;R|EV6sGwMc2Tw%WUA#eUUVw8iCou_x>w(&HsF zD!~Uv$GcJbG*3=C-?MEu(rgr$X5x{7B-^Fut2pN2q@DV!G%2(j#|v)W()E0Rot2Mu z%6IbRGQ=MIbjKqtD12r^*Qo1$AT;YCl4&=;JZu%RHC5XAD`Swl@?LbG-;lB?h9o?W zRhF!ilZLu?4AXDbnU|J)g*YDP8-96Rmb1VJcMOZ~xU^13M_a=hD@=CX`DpEl%NHMZ zY^#SKvN}Gk(x28ax5rz7XEdzE)qQzdPo%R<#9}tP)2|-s#i!Bwso8#0nCJB$hHPBZ zgaz5m>s>i4AJaMQ)lyuy9?B}=-du$0-VE2nZN$>rxIKGdxO%7AUMq#3byi(hwPqe7 zY%EH;`njxSDbDFn7p7>(QC<#f%#+B(bEnYbBed0OR+I4@i^Vdu{>nh5$Gg5(Yn<*= zg5L^dulVp2ZxO+N`kS?=Wi1bjO7xt5H|nVPQA)Y9Urr#MvLA3dLAdd7bX7Kxvq!PUUajOdn>fVNsFd< zTDg_x7sY)$uVi>vB)-$=jV4niz$DL z5`(m`JGltiG%l{}WVEviquIt?wC$4g()7cQ6as!CFY|2pnYG=9LHhhbgugS+>@pl4 zE@3$>!XAT-Vb4RW#(2=uFWIW=YTA9gTUCh=X15Lub6s+1X^M!&G-T$kvkpxJ^e=;< zSX;JlzKAf$2D@p7mF?u~C$jUwUPYdj_{f^Kbk9Bw)txW3N&3{={$+VFj@{|jFCxS? zT@{;duesAtx-}LeBDa2LK-Q;Ca}lL`=gV=y#9AIgUY|bCo#7tCkT<(~$WZd%sE2#V z*2hiMi>YUW?NK%GO=sElEoQEtzkL5SGW-7PZbTA(^B&}VOIqcxGKP~h|NJi9T3Wc@D8D@q>V52aOEa{+&z#TD^h-RFZWpF|zK&(` zk1?m0WO*c1%27VHBkx^-&WOMK@IBPy$D5ojPChW=qm`XDv|QmV zOIdh8aIP#~s~9wfUu}vmJom2C9bR`FvYYSA%hvhb`ZV`x7?1KL9{BUm>%5z#F^jRx z3oNWW=ixVuH0ZFJKBj7it@^aif<`PBF)#JV>g=4|^BfCWVJ?22hu3`>p`oJFx|3yi z?(4rrwz&Ag9`>D8r@Ksvbvq&bR_=9VEX2I$5Nu<*T!gXs>LY7ipV@0HzUj`J=(Ah? zVlRSK9p;n6SivK)^qRC>oUg!mQ5a+Jj)?cPHK>e6gKmu)p+w{xOyU_HMORH*S{gSXwV zxQe1NM!d4cD2es)!GbqB^da+yW2>{*SBG(#peuKKwVhRrdWF~e^R!RXzHVI{(_S1! zHDB0m7p&&;w{sMSIEt&+Ir4Tqx3+wSD{DOAEBjet(7e%@iL>i$he9^()#)M&5r-^0 zpINRGFT;F}kM0YHq#oyc7Wl!#dXoI{v}~$}Z1NLItgFREz2}eCupWN1UjNw*{ADSQ z)?$hwYdIK_Jjg{_D#WhqWhs>UW8Cwy$49Gmg*aI7SBHd&PuG4v`k98+vF&agk7e|p ze-CHgm%s34Grq7~*R|>R{BK%grvI=EZF@6Z==P0ldA3@1mM{G9)%2mfDJP~Z*vqiT1j_j&Z;mrw+i!cFmR6W`FgzAdZ+Jmorw{$C^aCw<5C`k7(-jpy z<2S8wJvoNWZKtQ$;B?x7$h4;qiNHF>$z{R-}#^;e-~?` z#nopnvbVUJ$wi~|_P7kTGH;=6788DwJY$sCk4)0!O*GkDT<~u%rP+D!nO0Vfc}ySg z@1l{mDu0l8Pm2BBTk$WS!`wS$nj)vWXym@@sxSu2a(%@M`=SzGIcmHdkI&^Vy>y=T z%K?n(h5?PuBI1iZ{HxQw6TP1Dss}ctjl~rPd8~{@ULPJ;YpwTVZ$eTD(#vSpGA52z zPlrEVFg}FUE!}*no?b{RtLqkVPu?1CUGD)a4tQ8;rUx)t z46S0-74}`#Xoz%|8C>O*uj4@KN*em{H5$iOuqxZfPwvgTmaSyV^H7du6-je>HuiT} zX~p??AKx2UH8);1vOe#N=kCX*{@Yn3&qWvxX_{%o)s9R4F+b`2e{|hTsBP<(<@J5e zJrRP6C2Q8LSrNs8C9#xXC98r3ODaNQMFf%9I}x;?2!bGJO-K|i_##P>OeM%f1Qkit zRKi!9VT49T#{0(W-iUi#|M^=j`dB;CJD6j9Uw^dLdjGyL=3Hy9GcQEFt&*oDg<(*) znV8Q0H3CBC-Pu>EoX+c#ew)M2lhw~*b|S`M%ANYGRcb|3vFK1{wUR~J>G^t5i*5DB zIn5ip#L$#hj2QYcU@1*ySqnCd{j)+_Mg9$(!XI8V=blv*Se5*o^)7aT~T@HqOsE0 zc`C-Qj;;Li(oH*_=~Ld!iIWvkEbjQEd6^I zWvSHjFs)oye7bRXSVRtc>swS^@alQr|ErgEj+^u7MAemxX9efgesbq8)v-*%5X zpXws~^s@c^?3EqWH&8#3s{H8CSAHDGU<}|(Uo738beUn;o)lj{@ zdFU03ze(LDAP zhFgX{rLWBWt`J^)?hakuUr|;Mo_({MS^2U1m+tWQO>6OoL6Ttp1dHQe|D=sLk$)7LUmF$<^+Wzx7D}vuoW~G!@;L zH-vhmV!er@xq3ZCQa$$loig@R#y0-t%^p^a@f7J_?&_{SLB?24bE@c&6~kh7#Tzp3 z_LKRl4O2DM(_yY=b+f{~=hFJOm0PTiwf+>=7b;!D_Yyf)Pj`FW8t756tC-Seu{Pt) zVm+)}$kS(C!jMN5MG#VuZ#?5=*B9FHg;?xX+*5fGwBM4bShQ#;n3-l4EbZ9Bqc6*9+TKwqJW8IHbZ)K! zRntgQ7NhtY=M4+qFd)s^>NU1Hv|cCj9Lf_jrR5Z>zRi02LR0&mL$nT?#&~1MdcE1c z7`yeU!|SARc2&}nk|J>E?DSXlaV$Q|t*^{I&t%M2MwYEt^Vn!pjn5zP&{@nyQD(=7 zDlUX7-+VhsE%U+Cr|r3X>x1!lF;)3}X5yn4b{eV)9){Sr2U9ewHF6GPIgO_Lu=8fm zk}~n)_);+cIMq@feZ@~5KK5y9<~2Uo`Mavd8mzJ@C>MSfY*(8dlE$Ii&8<~#5*&{cuFD4~xxewZx@j9hk*j*VxKvw20lKEY*=eoga4sY~6qXXLxGu z9P-C5Qaly6s_X6Z9@0PR(lI2;4k=IflK7(1(<->frXx={+jFa(`m&4A1zaEdZ;eHl zn~qgUfAd4bJDv8Mh+=wORgGir;H6goWZ|L=cUc`Vxyl-gm6ErpB52eLY+K>=>hSbq zN}BJd3i#v4juN1 z-m|AVi|uLYC!0FkO2g4rJ=hb2FXZ+TYgv0|Tc`VpOJBn(T1T#LtUTj$&9nZ+-dK;U zd=Aee(QDhlry53zIt1rY<>QG;&}QF=`j)@Cu$qf? z#=gH5JllGMRh23!27{PXS%adc7Vc^&N4C!T6xaTPruU(S9q!h2c`+|A^tRlV`JNg z^mcn(|E7AZuxCv-2DQYLB@POo_G!zT{UbA-*^7gd7CnGDw(;*?osQY#4g(I}#tz)- zY+Rg3}Jz2^p92T z(@bb0TvJK|9n=;f|A{(9*<^cqWgkl2OP4)p-2Us%S|zO*?XwPVxm|lM=-D(p>!oEl z)7pHR>?O}ac&q7R*vArPmUYy)tT3&p+EcPMy1%kt_HbyNHrDM&*3P<;efrow=J8Rg zzu_&*GgOC*R6%-*Sv~Yzb|VGgk~DaFJQ3NTT_2uZ4AttbYw%Y^Gj(5&v(Xl- zLr)gFr&cIptW3;TyW-$aR_#bZqgkBtkr9ss$aeIUA^iQy^7VHM^>2Ydizf`S=Z^yC@YSXY!9%($R}U@ zTT^WFKrS}qxQkXxR(&a#imutpD^7om#j9jhbj=cW9Oarfn|*v#S@+g?YrSl0DH%%F zu=5SO>$qTJ>a)J+&6}xbyM+H~t;UYk-krOjKQKRiy65wk3RFdrJn=DwefwOmswjP` zSr6EX?da<7E%_T4zfSFrWM5xk6xC>K)gOu-u(kFxpxS#rXNPXh_cK^E@bx4QE59x@ zU+-qeTFewIhORv?ThA0Z^7WTSt5R+=Kfle+Qg`f!u(vaIUEOto*3eoj>!KgcbZND? zs(zZ|&r&RI^Tz$G+5yiUWSn=aB}+Ven9#&rY}si_uUPM?MQ6>%W5%8@tA1{0=wQkZ z-|i~%D%u+8M)=g#_cGOmH(#Bk14HLH(o*JT&E2Dmc5nJDphgwRwWh|a3sZMPSSeYa z2>G!VG2LObE>|}NDJ!G1OxLN0SyZ_y;X9t$=~Qdz?9;HWtsD7Mn69v@Wyp19dZx2E ze+*a_ziV9c)w{+zq)J$w9cnNRBQ>k>xYiwees=~1%grjo`iyVCXMr5HD%i`p9!z=H z)$bYAE*AIH*9!0XQzbO`jMZ9G5_3G(Pt?s-o7KBG4cp&UN6U17-7(LQ^{rJ@AJ($N zF5A8@eq-J#NNun0-f}vu#_(pLsM^G(Cp>*w*S0G0o|2e~jMrLGuvypa#iThkEPAlY zLbq38m$P+ftk=t?X?>y}yVy{vv{S9nb{Vx-55?}8RXbg~KBLuJ4skXX{FBUl}W$;rM~Fyv~sJ}0b|c+InFxbDVF8y!}_wO zV?FHtC^u$nQ`L0rosMpGyNBq27Tfe=roXD>P^gaOR8Qm86}PqSylOR8`q=2`nwZ$7^#-gllgWAn{s zW$SWQ-*V=g(W)7qPYYFR4eXz-hrP00VpitaSEU|?SxxQ_V}0H_ZQofVs}R}{@ee_N zPE%20jVLn~wQ<)}sH?2`v*oeV=xQ9+(8V_|Rvm0x-B3hBYW~cJ`_VE4KH2LZb!x-9 zUW$XXF}B->?wjGO#csAP%X3|~i(4I5>~{0^y0wnoy+CJK?%r{hdDTMQnrE+?uGXD@ z`j@x+r|5FUW9-hpUHKfRVE5^A#!ua};hExF1$^0yu-f+Nuw(DAqm1>6x?#zpJ*-|n zN7-{MsnfqH>gu^DLhgE%EsN?_Q;77z7Q?$Sjm_lF9#+ScR`dOAoL9w|p>!?>!&J<6 z`WkgC61(@XMTa}To|;V`wCm>ZhTXh9e|iqjJ`)MAv$-xj?`Iw8v(eX4#nORYw~ABS z`ajF|M$tao(o|*TRE-=eip#TEY{p}-2G#iN#PGU`@7!y8%O8eOXYc9Rt-{^En4#De z#ndH;bnYD2J_kV45Ao$w=uAsFqQactHH+S;As&a^I+us)oy)qh+48#LD@N}+H{HU5|JDQNP*fALsOMQf)|D#pvkF8AG*umDtc}Z4%Mhj`t=2ow(6;hL)v-lS z=|}v{#Pw8P2X++^iciK=ob{pErDlsA34xp`4lRpz?ung2p7-tC0n#(d;Ezi%ysoE1e?j5rYXJ|#ww%?mjjD6}`8$D1Fji>bbLhb4f z{iDA9ZP(!&snye;I@}cMogLDCp`}dEhDKuc{LVsO>u5*bJRi-SaZ~O+x^Y%jcixDV zAEP|}DX;z__t~xSG_vvQJtbnGWe?pN+JDXI=A}edzB0a61c91Z)?d}p@XW#Ljy#2M z^{G7#CFb?^>WHH|Jr9J{Wo7m+Le%zYtRH0-{bCW!ey_H1g7 zqX?f7!`@SBan)YLdLUvp(d$gQ=wsPT<#fPPaoVe7d-%z(O3}qYOjTO$9%wyS%I1H@ zreV9W2>OOwE-!}8Q#b`|A?u~i7(?STt|Mn{tX89O!KQcT*;IJ!^wg!W>06!Sq{+Dz z8tYR@nTx=A)i#Pz-uB$Z!|6QR;$>~$S#=bsAV*pRvDri=i}EGj55m^Pt|%Zu77@pSp>%Q1nRm8XGmCa zQg!3BKzicNW(};qjy8rqRjYZug_gIYyTpi!)jmzIv%2fU)~hLZ_SIq zLFZ7mhxug;tv)x-I#0-p&2ztjdB)Jt8CKVOF2JfU?Uz+(=jhEkpHCbtcp|Ij$xzPt zR_Wnf9pUNOvrlY?-{{cGrb9h?QccCIHxyLoEJImUL%awIWfs+XOkvUYG^DvqYp`>< zz37WM1@;epQyzi}t%Xdie6TTXJyuJ(TMsy4!3)W_5nESU_P!+x>$>axG7qiU%M#m_ zvhYKE@`>efE?(sqJ&X`jq(fL_W3eZUF zw7|@hUA1-Qy0g(%IMl7u7^taJ8$Iuz>#4e|A>Ghr@-|*=i$9)pV%hV#>ej!M<;AWF zxvN6GIIahFN7_@>wNEb_4|Qr{d*%-FY#;sOR#keaG>5u1qBdK5q)0y(Z^zv4+I)T~ z&Z<$h{@i|^>eJ-uFctsMKm7N8`sS1GJ^L5`&cFSSzV}S`cHXlrw2&NizFO`nGVjpU zqu)~^zKFwt+gX1aSygpe?TezJxoY}JRqk^Y@@97*t0BDgHqR-=N7s~KR7IZl#F(I4 z#q}XuoK$$WwX6J#gWMrpSKt>dlalqg_$iq7>6;y2=P4YE3hb|<*OBacm*u;6#jI*_ zekuxc>oEoU7O%cFtk_?C-5uY5{%_u{@%^W-ef;U|+s@+q=F5NZcJ26&-~Ipjn?L){ zzT5w+m;KY1|L%SMKfZR@H(!44eg0S9=Rg0N$5-|@U;dwW|1Z5=Q}Qcs*VgM--gju< zf|lpkUe|BG{Q8@{`ER`AbWO<*-|>IzW&if|t!VY>cVG5TU$R%Hdim>mdF9K??{_%A z_a5K3mv#K;{r5Ke_OCy9=j+?gTHPPN>+`K?zU3_B{3-VDw9V}~-xB8A)Z*`3(L#ED zJ6iwxT3q?o3r?#kzi%bW+qb)UcC^kRRYm(xT=~}7U*qXnXWxESr}TOM-k8qexQYlb zqyYQV`t0ZI&5Kw(|M2&ImR50C zJC}9W)J+pcPYr$3_t@ao2}@o%uXPLc%lU7f}`b zVw%$lp}Zl&w@z|YtB>0U@M5Ay44iDMA%yf%eC$R&8CRWpSLHF!KaY8OjjX42#-E)o ze>H6-bi>Ty7xtUp>~@inDyhigoy7WdrfT@hO-a%0 z&#?-!t4JiqZ0ttI63_Yw(=1&>&%P?fOm+6+(+>imy zu@GAWqj|gP4wUKFqmQwBx>p-M*xi#MZ$GQG`3}`S(QeIGGeznZx%UM~S0C@{!tty@ zWO&8gi|(?wL;14Q>pjiP^z_-M=_pIg)s?Ls=fJ%_dA^({@AWS`l~6a!USF$Ej6D8q zQ=f8-t%P_MoSvCieLVB4snrt|4t1SlFbmc0afgjlKCO$*Mr8<%o=D9c;l)ceyZEVF zjrvno8RIFh$aQ4MG=-GvtVJ0u+PwVJ7_ROW)#vs-L+oz3&$AWKCD~JmjfXyr>)x0k z;5#LUDC=r&Zl(O(QOcFq`K#aXV`I#|rcRG3Xe(dF6O)43SP`}s0&csf2VIa$k6x%~nq z)qCGtexAKlVWswNt}B>UmpjGUP%vh^`jbtco{G}8?!`BrY{lCbSD)IBe;$2bMo}T( z@3Wh$XV)@yqmlZJo*bf9NBCKGX19~;q;(z^oM-Hi*@{n7R(GHL^}V0pC|ln!7q3sn z`yEIKFjW3zzyft0?W#6vb)pz?`sH&HL@2HGkoF#cOJ9a?>tQ8TnBL;n!J@;v>s9LM zyT~VA`EtBp9%48?*@QzM1pR8PQ_q#p$9h`UzYvcvt8PqZ*H9hqG(I)SUKQm&-&HUd z17~%Ovo$K_J{9N#RpnTX=5cqWalF~#FO$-2<&M{G81J(7Z@J~FO@wGYT9+wF>FhYl zqyYvUW1#u!H^*1L?n2-jR-W(P+1SSXQL7FXk!sr1z3zvLq5UqR>vVTr*FNeSquSNv zKGdfeI;MG5QZ zUdE7Ei#mPli6}fnC|-1P_`QlPPR{;&$@qJ*ch$M#hjsboikT0xXc;kkuF|-5g$sXteDJ%+ zXD_pH*YY6uyyzn$z&aL~j6bXCREJIig z)2`Cu+b`j79~GJI%Wk}V)tCyS&FqWKZl}=?QSXY0H(TTQpDOL7)melJ?Xj)M{MDl- zb*wMTq6B_9t4uz0^*vP-=ecg(sU5cXSgkMqVXH0VY3O>qJnJ5m)nC*p6SFfG*;@gq zAC<4KFvqO+Y*qnk6~U^z_Qd#Iu@+r!$BjKvAmmYb8RPh<@2XrC@F16CFAPz?rzhXX zgOZ`PURjFoP|bS3UG_2OGKw2gEHs7YPR9xHHxI zHXXFC=DLAZC-TyH{XPrtthiVXMq@>L)Aqbd%sJ2GEZw)aaDqMaqC?kRasMf}6teKD=+Tg~GsLp;xNyXxxIGp0IE zUlGR%OT2z8x9c;~jyQ%!R5qfm7z%j(wv1Y6)7F~2aBd2E`6~)f5U=7m#x3&vsJz|Shr}d z+C7JGVP-W;*R#7*nD?Hw)^6C%=v_3vav--B)v2fyR<-ZWU1!%-^O*ho zYpvEnXnD6|^<9s%kFRTry0!}L-|A@AF$EYPPMOM89g}&Taiq@YweZ)2b?LIpT|Z;S z-zaU{w^_3lZ4W~#zE`$9y{H+|)wllX^PU2_8H&E-WxI3t@9lKmh~@b-$5&2_>DJY7 zWei^}&hBAZ&mQsW-|B_a+3WPB&1}1-83p?E^sYV})Edvyb*ihp3`f>+scg0B5Nzke z{JM8jQ?9<#dpk_8#Hp@Msp)VJC#0J->NVwNJG-h!*7o1&JhT+*hc#{8r-1rc!sOxI zZd!I36se}YQ%t+H_3d6Mq8OG&+e4>I4;Bd>S7-HxCwKpraJ5pGH>75>G_o7*x?)te zecN@a@=}rIyO&3whRr*@^={9XXHV!@EIrG4B2|(5V9L8vlx`hT%g(EsR!@?Ty5qH$ zdpgPym3OtPJbNm#pND#xda(1N?cJ+xykk$BoERES2X*vZz0)`Q?wesO3(hL+Iz^{o zy2n~nHg!^1cd?6_S~2#^`YZGH$}<*r`0L(q*PHCB=(>HsK6$d!-WZO*zo(3L5!*3C z*&ZqDsjuiNk-N^1^Yj#R`Wn06%G06c9=^K7rO=BteYz8WXjUgB(^|aF(zEr$P$b=y z!JlQ%zvkgxm9j2wb86VfV5QR0QP-*FpIzmvD;+#tJw@ba)x#>GO8@du7*=D~;&lT; z=VAN&LRHqDq?#76P}#eac8I8x~o_Aa>|QwpYO9fV9Oj{2t^M=6{@kb zS9k9XY8Jn4ggS=1T9M|%j@SK>^{{Z^uQ%!zGj(Nd=UAa>#)!ih-gxJSyWXt&ysK|l zzVtn{z}c#$tGN2{5t$M_X^dg>Lu@q0S)cLc>Ff4imbwtHHH4n!V-Gj)y7%y{rQ9%{ z3aB26tIv^f*dd{r#XhawF?KY>Y2Lr~HPMpWB>m<#-Tg6M~h$n zdgZ!|X0xbhYvEcPy!9`;Z2ICT^WtGw>k-b7E^hT4&*5K{m^x!}zrd^Bo>R?Wr?I#pb$^UI`|ble)|(>Q zXHcGa<=F2jnuf7VrHad@q&WMDZrVf*V=CRDhrOuc7SrgvH+FT!V}IT%6}jgYKg+tZ z>l3q#)7Pxbs%@EZ>D`Xbzb70l z8J+iEB{xn-ajJz^4YaCr`NuZJ_UEdh7v9!~E?x6{aVLgQj2+ZSN7B^M`iD=R!nk=D@?~xnZ^wmFXS&`_UtUVo0*8`% zX!NxTI);{a`k-K8-&jQ4jr1ah&FE^Em4P`gl(@D_R0VJSn|?76I`7`3b!;Ee-5+>5 z7i&MR&RzTbtOD2Vvh|+Iab{gLaA_8`+IVKmiaQ3pVaUv86{lz(_f9C3WjE`3>-+SF zA!haF%^F)dDPdcGH|uJQkG{A<+zggDzM;d<;{Z!GG~zXR`bhu3F>KEG7I4pg(Qti~szI-%gq zdpxQb%iZ&7%}NcFt3fTXu7jc4dDoTk-0DqPs6L-U!lXv}tYzrBmNh&v)3!S3mpRSl zZM>ghpw%%rjlx*mw9D-N6<4>*bylgEG8%c+0Tp@bv`fm$JC1NVvdnsQi&#C-7m)^@DV5oJPbmz~D^*}+7q1&-P^0FlhQwP|jHgjus@H??Qx7rU@%s5lJOuvLP-Oc1m&W?8 z_o^yVjUm#qCzO1+-I3dW$E_-PSVZGk=gOP+GFVi#6>xuFAB&mJtpYE#c5M9BrPYzCP|MC& z|GKp5>>I1$-rXK9qP(BH{(qJmTN~(OsB;vk@VeLNR-CTpr=^ifJ3sAl?=CckHS}gW zHCAe`SLMUdk45WpebK+?{icqP$2omiaDH9!^>}xno&L?2-+8?^eEa3EzwP`m|H|wA z@|!RJ_1mYE=70X}+;id2zn3t~zuD`6>vvy%?@ezw zzx#%>YyJDZ*KhT|dAnx+{VMY&fdHTE7?5n-XFWx8UJ3p zZ!qhd&)SQgIOY0XgKtFZ|Ao&tllkT`JI8we_?;iF|A*7q|L~=+k@w2@(qaG5SD*W) zvaVs8H@f%8>PqeO`Ts-T-zxb3M=#zERj0~zr}*lrwvOVe?hoENq9%RDpX&PO{iBg@ za$6PV`DLZERr$#qUby9{Fzk53{pRiesgS;&Gcr3Dt2=B}6@Psyuiq!>N}aLK;pCIk zHSgy5=!0=_`U+wH%HzN93UBKZPl)p99fRCvDgDWtKE2Lf7Uizh*O5N;WQTkB^q03v z{K2X__yF`E}tf9!tu zPBE+AiaoVJdupH8^MQ)>spx0No9WZCR!_AYcF)m8da_fJ-YT5x^`%(2oj2RQV1qwj zNK>X$Jlhdf_#CTv88=(KeU3clVOx!Hx|1MNyYU~_u1Y*ZX;sz%+Qweo)^WYh*8QPJ z?l*XP2;plSz0wg?cm~i=epU1vibhX7duWy?2b*Yr$xtP*oV_PolV>z<{To}Oo(HL- za>_O@C%iKD++R%9E-Qtn0!O&+0@Z9B&h+)3>N-8KjrLoQqZQ5{Ik8E_v7gI#9 zVJ~yBA&aM~xJFexb%&=yXl07b|2+8X`&L7}d(XEbWvS-yJ|d;1K81~GcT@W0=lhto zSXsAnGM+li3%3IcG-JIjLJpRvwR$dAhr{Z#g1>|ijpshA4i9o(*v;8s$)mB~Y`Pml zwl@4$!HUsuW#HPa* z_q{t&^!5pk!-RaeAD_c1fG5spxYk;iV}=}pS)N|?=#;O=r@g%Vd(!05sq*s7;+n-8 z$=ePVCzl%MF!U8Sl&=|5p?}rs9eKJv8H<>*sS3+p(jOYct*-d9&;ip-v>HQ&8d?)uP8K5BVy`Q|7YuN_~11#`>f?qJ2JH53W;F0=vxpHf>s`KNiRR z2PI}=r)8DUcRNKNQyLF@nd{;eQNUl_WXRnOW(%!Uo-bYqp$J9n?Ej!MdjQ6n~!G| zxt8*C8T{p@%?YnQZ?rlgG`lq)XYt1QcPBhihFR{` zri|%oB);o-L-YA6izh#RF|fjr<*Wnl^`ce4y895DDjTn_(-!{jCpA+zv~rB&-pI4H zcuL?;YZ-8zsb8+n*nfGZNLQu-_I1(di7FCP*jtSvs|W&pd-leWWtE6IRQ__Is7nq@ z5yjI(LzY8=20`@D+_m^qRL;1c`PA`0c^b>ew{_ossgE(KwGn(-t9$yVQiaxdU9R27%6L;hu?xDF~h zJF=BM1~pTlDt+iZVLySWvly9WKk?N4tV?8e`#DzXD5{$26S4WN!!(KO97EA!msceY z3bJ36YW({L6`l3Z=To}$Lj;`Do3%Be0D3WDZ-uPm#ZWXncIT^bE7Go-;?t40ZzTw0 zHK+S#jnXmJDQ?c!h?U;BJF+fo`Ni>cUcKTLi{I}EsyHuXeD04d9oyUPLlJysT7yLv zyS%FUh~502T~jJAH$}dR@kRwI?EXQB4as>kNwM@ zuJ)h)(UEOg>(=3wqn^(5v*o+jvqIIEu`FE8Xtvhvzxa8rM*n_(`{ZgYMmEghtOv6W zZP95Mim^!CP&;SsrAt}Xr*xgi{jqxoO8Bu{U*XQu^~r5q%rmd3YEQxPH!8zDT!sjD zOA(>(@O<$M#46f&{jY1PQb93PhBF1rEO+CvPK64vpAKvx&Q`qN|E*`9X(HiU%VAAL z${L47_i5cuyV&)?b@9v3+BntLm!|GRvF)D}#zp~xtdaBeCONUsa5Q*|bleq*xu zCjyNahlWFRTwbzhZfs@5uHwbGC-^$6p316iq@JO;$Cfd_$n|kLtlZXb-f38F{;}L$ ziot4!cTxIR59*-zB#bG&&(B5hmpg=MyLF($^9pO3G;J@1I}EtZcfjr}Q}pgrkt%7t z-%HEB6)1PiR&81_P7|fa^sH<#uFKz*2Kz4C_Va36m3@A>U0P&#)U9rPKLqyePql?7 zH?MKH*=Lcr8qQvoL!ScZS)U!5((7>S%i(DGLAM_s8XZ^zJ6>ZR7~>x2EW&$BY8^y93*!1?a&?}iCB~iD+*+(hS!NBfJzQ-5-4)Lm_H`tzXYbZo zQS_~g&o0ZOxji7J^C7BzUVFx0>56IX8_BL-I>%StjZYI*S?~Vkjm2KP`ifbHr%?29 zjop2)zvfU!x%YE;=qaRK-bZzmvZ;Ok<;gBi{?>eTu2;`Bx##eh?GZV4g_^IbczfYB zYm9ZCV_D`?bx}oJr&CMAu=2~Hsfe=55tF^qWk5~wGjp?Pn-X)`ja#SI1uhi1#cYH# zCN`tad7jweO&_0rFQZuRRPHL3=uMvC8`U3LyH3&iQM?W=CN#BJ$I!-n)nutMzT?b_ zLtV#7C3I2hz%>SYK7W>!z#isU*Y9GsLqocs&vjyayHlok-ux;zx_W3RzKHl}oTBM- zbq)zyXSvTW&n)_8=S@1-_TbHd3zjGcdbQNqKKRjC4tCymzRc!WD ztFN7D8`qQVi4Ok|#yaG#*u)%O^Eieujl<%Hr!&vHH*XpGV%7DdsBl|h?;jsIZ%<4c zMwMfdVI{Yo?U`1FitC>~P3OmIQ=&#yjxihUt%%*YK0J3&wjsBASXslW#?y_7_KR$U zOP!(UUim|?7oHL2+}#wa-6J<|+$tKUe3~1ptDQAppHWptN%|bCbzX6usi0cDo~6}% z_b-)Vug0OxKK=ca`*jb~(fz>=o9<#&tDnu|3%!V~r}<*%gJJKeb=k{Ze)en-;WXC; zp2m4xsmQZT*;$IB`V@+M@?Q-_;RvhlhN?=ao!0@??cU!yc7F_!Zpx-4RJw-#wRZk+ zQy~v#=hf>zEP~?2naxY1y2MW3A<=i5L!i(u%TtzoeEMW;M>VF8f}6RQLg|3Bk#4fm zdY|t@8;`r2GWhyKJFbnxp0bq3FQ-|f&B}9EPk9#WzCOuKhbMRO_#oXnja8j0+}(?D zyi?kqnLgDnmon8`3stRqo+8%Vj!I`*)T2gKK^9v_d!?(ZgLPfPoh{1~gSx9?EXP`e z{$p4TTeGnks7~Uexb`EL&b?&Ok zqaQ`7ab4JodYWUSwQ&`m*6ex-@#C2S(Q@?t9a1^`va`4X*_M*p`?^)&i)Y@6YwC-hYCv4vh_xg8L(6ODiTFPh)`?;do__iL4 zl#|yJq%8N43iW^$c9!)(|4uocFzsU%uWJySK`>J1q1w-jt&@CszQkyY0T`!RGu#%-cM5U-u7}zd_jjJC*rDOU>myD}qNi-p05t zk41Mo7t?teAFCa{_rrETan;*zNy}Pou|LNjyHE#jJ;K<3eYIYwiV7OaX*5ss{Pkyh zi(gD$ok`!`yY$1~VV6y%y2^`RkEb7xwZMpVdfY3pmK%b9Nw}zxn;nL+b?pAdT@>B< z7qe?Tvl`O}wanqb4Q>6vUgS`^%JCc1x>PS01EZ)}^Mog6XAyZIwlAjZFzAMD=j^HF zd2793epGF*;7+kl;e+q@^%&@j9}2{xv9f0k>AGSh#{E{#*E?sdK7rvu4AcE_&Jva2gCj&ig5ERr4fFth0FeLh(3_Ttukbqrx~dZzwj z=G7n+eMYs{#M~F@%Qe)W!zC*m>p2=*}p=c#X5o-*~p)U-Gb%?Tc zKo2fkht`v##it5?_Xpdae`2bp_4r{Is_yR!=r2z$wbZ2@Q*%!Q^*`C`;_w?aR&O59i_=+zI_jm>TMw~NP3zO5 zmd^O_s8V#}tg=FFgptN(T|J#p*P_ICa}{{FPwEVmwwQ`+~Qef!Dxp8c&q_ji2y zXa4TD$=m;?IgIspl}*X{R;@kSOigE>?puX*O+DSq9eAm$qH3cw_Pw(5h=?zo{BXnS zXT@2Eq+7E0H)T}9hCChftk<-#eqH0me$+;_XdTPn$Y;Z0W^D&i9NPK|Pj%Uw>snWp z`?+{?`m3n;VqrjU2IH=x){(xGsjzyJL6@Am)lHUISG zUwS=HzWMSGzOJ9X{Kn7V`EzgAj(`1U=>F&4umAMR{{82F@@L}v{m=iz&$Q;h_xYcC zoA(W2f9hrb;pcz;ExvCY`&VD~-}?M#ey08Mo1cI7HUHt~zxu-YozLID_DfBvhlyiZ?#{-yJqFTe0^|HZd!9sGaa?Z5QO z|McaTUi0ri|KG3qPu{*OPTc?X%KPTa|M~h!;+rqcJAVGHd+Gbdx4iJeX}$l(JKnFp z&%5UNmG^7kG1u|Suetat`Q2bVavc)ag6vzW^>6y_y9a;&ExtSF_g^}`dHb$B&x0So>-H^dt$5vTCx`pZ+tst7 z@38CWzE7d=%qxzLz7?(&G56hg@$CtfFP-v&UwGlf>y9Zae~87<*Yg$* z{N{N)hl|Urhw}5Mi;mW(WAzp|O<{`lIQ>GrQ$9ed>#$u(rdvE{O#jkN=JpBB(-)G`>L@NRdnk?g7hgTsExWb6A{PxuCM{WR zpH3fz)0fq&=+Iyu|CGa@f3xE1cvrSY-G8%PzAo#g`1zV`97-DWRgU$us?#V(UUwVz zWjFtu$Cpw3v(H81gm>Lp71_h)pH_RN88vms{!@e9Qa_eKlbyB5{hpWt_lPQ?stNz| zTzt6lsNlz9UECQd@!Xrj@*t>-CKawup7fQ!U1c@+oK^SKk(~;iINhSw869+A$yg7c z^r+%X@r14Jv4rU!VXxm8Cu)7!8ccn0sfdRj9;=d`_{T(ForiON zb;ch~_Mz?fCv5R`2iqa5^wx2@=7(FZzK$nL$9FILX4bZuel$wW^?T#P6|*?~E`AYZ zEPwmTyDu!gIep8cCA+;Z(Q8&Hh4wGqa*rXEW7$v7j*T6 znT|bu7mu-7h}F0CX&gR#e*2`kKI2)v-Iry{P%{ki`1#|z5x+g@vxw^As~>puuYRnq z*wnTA?fR#_&hEGCb2)L-bBbrnjzOh5b3Eontsm`6es#&OFEB&P1Ft;F%X5D$zl_G_ zw3$;x^>A^fq)}?>gL&61UE^WzyuC9H*{VKmaod;0uOF);?5841i#wk1A*6$H&$o@K z?zil*?>^g4(|t-VviI!t`>FW{Z`V-!l;6Ji{&T-otA;*ZH_Bh0owQH?VNhXR?4$a# zJ)ZsadHzm!N{UR!e*XUS_H&87*zYew@AnpI+wV*IJwp7xi$A6C{M^#d2kG?P_~BFR zuEQuk-|q3eR>WGXHJ+k6v#YE5>?sWIY^nA{uuov9Qdf#LKirF|+v{IQ-rvd;lYh^% zDQv&9TaQykor-B}e4hZTL^Zk{N=)`m8S2@-?OFsxnyMxK+mW6x^y-^%Hr zJ7s!e4~(fCYqD+^@3ji16B-UaPiG8Mzq{z_6RXc#9XS;0OI7AA?s|}=dcvT?{m`6B zNcuGmUCY_Khib6Rpw3Uy!sPfb* zC+41~)7^aI%M3d^Bo*m}&o4AS6&9~1ohthBQ?(hKDfAn@bz#q{=Ebqggg>73PuEtp zdi5uSt$J8P!(aaNhQUA7;dS*q;7Q-Iwn|kd+ZruG*M_`()BTaY?Dn5dgrJ|W)IY50 zmtpN?#2Kc}6_-WdV89E#sI4^x?x4mxzUP4&hm&@e>s>ivVOvcp^So3Qf6w13(vRVZ zS|_@WXL03ali&J!4}|DG6Qj=T-apD4tB7I5%4dDIGp}E|DK6_1$6Y8NE_HIO?{=Wv zcA?c0qegYHAO7|%O#9jUS25*pzsa9Q@y&|swNC-Xr2t3P^_V4(c)Mtd;_g+xeU&!V z$AioBAVz3ex6kgr9mlON75Z_S)fDG!GCzJkz4vn}%5r?vL5q4sZr`mJt9|Z1>g+n3b&08P%w{NZ6G){Gy&-I`eQn>o=K7$DVW4%*gNBUj-O*>+-s`w zJmo2qKG){Z{^rlC)T?T%m^$kVam?FC>qj-vt^-qxZ`G>O`ijUu#t^*hKOLQy&2vS+ zR!ew#7}gF?z%+TDK&y(YF`QPHhS>8Jzuhv9uJUwwdw7{@hrU>m{!vdFf%@gGrCvP*bw! z;E+Vp&30?3GkE%2jdd^!M%Z-8j>qRFc_JF?`=ZjZeyNOZ{`D(eA<&0&^~FSeIexyR zgobQJWvG62?l}!T?~XK8!PYl>+V75wV-?^1i|y1~)An^9c-A>>%h2=9>*TG63aav0S7jLUueMNB zvXKrQBKx#gak=RWZ&zxv^z!~eyZhAhC{0x4)90|lfxtg4alve~+^sMKccUGZvN*Of za4|YhTQhieVm%k3Gt~vFxT&4SEYIgpnbYB4{zYyltsk%mf~gICVS{!|BKSRv4=FHmLEft6h!rzBfm5!I}Q z@}{nbj#?YE{~N?;mhPvR_t= zbf@WwB5Rm3cK=Rwou9tOpviz#~_<210 zcGhCp(y7Mg)TwLtP5$s=!B-Yhdh0vbv#@ADZKqOJi7I_ z9TO6cGK$AvUHaGPkN1y$D)_ep+0tTt>z4Z}?kR&E3Vb?ZA76N*V;u)DxUxWTDQey(fP9 z*5&-+$0)|<;{3zaqb$R$cYdN~DgQ8VHkadyCk(wj-Tr;6*r&S2!^o$<>qThWFGDPf zX8mg>KCAmLE!lcT(plDyydq{16E`ii=N%@FDWy4I$FQs~t3KDkr&n#-35B0*RAi?2u8WZO-olbKvD7Kv_9G3L6h6s$~G^; z`h2XLS_a&a8Bt((5w&5I_UX91r6}*Ok8`)=(rB>EQ-R=w?gsbx&8O`Gk^V|5%2QsF1p$u_K=mS z8lD&$<(;mnh@ZY&5B;Spf3cx04nA~md9?GpG^nT!#;gOtH0T{a(dsq z+P8Yx{k|CQI#UfSIuO?C3VF4LKwr`H#1ilAbUe7HnPU53wy>ZZ;SNhK9GS*NH=nH; zCH!{rcEs}Ue$OJ~BVPR3pI4eXQ#oHze*Yq8=MdW`X`lXf)iD``H#U3A^KZS_CyAo% zBj=B`-``N--jq|~_TZ(Lz{2p{3 z`9}6A77i=XcD2IK#D#T-~qvOXu%)?*xS**zE9&^1(_fzL^eZFc& ztvdCj{@H``x+}x02QYSyVfq#ivj|b4=~Ni(`e&?)vW(~!=~)1$?5d+qZ}S}A(6=J$ z-xH70W_Z@K5W|MwInQw}db$=ng}dqlPS_ZSmu|V;la0;-BW2xHdA+Kw{jbj{nGcd# z=Q38uaM|-1RTUqL&e6S?kUSr0SPfI;eIiwMVTjb-Jwg?QdGVM#>o4ZKQ)+$na9R6& zP-b}@a@G|yo?=9X3h$ox$8;K(M}xJ`Hk4Gx>o>cLUbXR22;2Tt=sFCA6W%}$ptZJg`@K2vT ze{+1(b%>4DA>(yny^g~^@vr>%d@eEuid>&sVjI&&Q*7_MN5sYV)TdLI7ZTe>^Tp}z zpmTBA=vmLKE7hV_?Q+6adD>P@8L?eOIN3L*=hWT2F4-@`@PvoDJAEu-r{g2D{22Al z3YVdKv7dtakqX=@;Jsd}a`#7GIy!H4VX~`s96Y+1C%!#bW$Rf!{KGBN6OBbK_T5k8 zckQqBpfqm>S>Ln|BahC6q{`+SO|Pi>(`sAs#T0LS@^?Hn525Jn{AoxJrPuY3x#8_K z%&z09J}XRLzI830?HZ_^F&Q<6n!VWBo8xW7+9UE*rMdL6QV_y7LaTXDstEO|~j_c9sn6js? zBG)Iigs@!(v-oy%6)!g?caAK|)v``gQbsSkcKNN2&o83BzAIK)an%hor8MxDDE*mx5osFcvR0kw?n^6HtUg&6E6w}K+PaC9i>euzGI7;&I;LxWm9U)hfcsZ+QH8vN&KHMCm zI)@owcviXyl~N&Uzh{CSZzGqA~|Ki&LQ`=;tl-%r(w{l?q1`hM-j^X-?u2dug8^YVRP#rHi~?U>?I=I`#m{iE-R zv7`HBn78kz!MpFL>A!?c-+jMKRs7`rzb`$U`S*P@zJ~^0%76TN7WrPC`m^u9%HGl6 z{ikr>XS46g@pq*$+N-Mc(|;LuQvW5c{oOT%`<|+Fg}?s}cK^k1c`E5#{gBmdUfu9~ z?^SX6>$AU?z3<&hXP)KnE^S}tNtF)c!|(5B^XhBm`_XJpOwd+w#t!0P4m7BhHMwYI{HtOoRBlhqhbj~Keaiiwr$h#+; z^`P~TR99}9Q)Z-7i=cTc972{SQ<3xY9*q_LVUOI_LQUC7fLZ;Haw@A_AC=k{MXYJ`92kmr>px^tPb^O%c$qBS03oU6|2 ztRH3b&{Yo1A?m~Uj+=e;6b+~B*1B0(Mes~1jAN-Lvti&`@^|iPJyR5pXf|xl*~?o* zd%2@L9?xy)<2L`Y7e5-F)93gg;7ther-jTXhCyuJPjf%om&U%dX zqU6HN=UI<|PC7OYYp87FEgMTQ^sS%iPgl4Y?a?94+7$!T^~7rM%At7LQZijPrmsGw zOTX^@H=Mn&Qis{6CdUMfMUQXU+>oNiQeJiG(bx$qlqKdO$S3&4iTvopIV=AHKFG4+yuD^{%;c2g&zG90g z*LCA8!@E)5eSTT)vn!!lSxR+rt3SM~@imVX5+(X~YUb6E-OFbBf+H0w^d!Kg3ePc^ zou7K*Z>|c;AnGcG&)(RV)SkNHRx`evk9pDJR=v+0V)-0v z5ob2q8;39(MsZ_ebGP|vCJ&um>RN0I5EH3VLjZ1rI5 z&U*6L?d9X7;^X~0#v-T?-8?q780qM&YsX)d_aoJXbXe4GovDF`gI}g`SVNc>dn#mo zjel|NXFGZ^Vd=&4^))1Vsvu;?ai5)EO#Y45A&m0buy;1fN5wNc{@vwasFQ-r8_Q`N zs+jCsm)n1`R^jtKXca#3R(tWPSWDwz`Z2gPO5;l6B6QP(Gjaj`|ZgVGX?T?K3F zHJxRYyUsmvJWss|ihpgcPR8KTIuKraXPuKQbn+b1!^TyDBL?){7B$tr^8 z@QbJt`qIxg%$ORBoz+||w%~nnjGY z{pX3LDq5glX2{K+FZi9e|H7oNI5T|mDWqikF#qy!n@vZY`~Ayoo;YK`c{Q)sDVdI4 zLns>p?)cn8i&}@Lcf789zBIE-Zhb}AJ*z8xv9~_%b9SAjr3m*D2*VItEQQ1b%Q1u`B!m@#XD0*Z#j!=9G)nZQ3`9Ssj)ALWuLXYWi^7B6;~Gj;)%yP zV3?L{VN8Q@@#<|f<*Hc^v-3VxSP^`CX6YZMvW8gHKErytUNvgQF%9_Td$yeC`Fx2< zY@OPQQ8B)uh{L=6H=B9Bb!of9`-Gn9r+2UQwv2s#xtb_|UPP~ER$yK=nTa$21RVEM4i}T^5G59=Dj-JPlUKFzJ9YeAh)D+ehv7W;;r~@_e?Dl|`2O^WG0) zTuh_t_WTpCBkUiwR`Zirw$FG&R4+ZWg_k#vwQsf>`8wZzFOmg9(YGJ;EzebWz26!X zHGSSc)Y3V;)&v4gVbS9GRrXVVUYXPtD`xv;YM#oA34dL)Zn{%86gYI8zVLXal>)jT zeynnMGU?Q(+tE5Jk5XNjl5p{6Q4%W34jG4Ab` zC)V;)w|%l}-JSX>5vztgx4wBchm^&BnQ#4}b=XCDUAc6sWLZ+fVYp_dF% z^o6^3r1JOt{1`*ubPnYzfNtIFm-1DVZ+)ND^FUvq=o^iqaH_ZX;#4R~w%&+c-6EYm z)5A-@$j-(PZ85rcFbPGerlz* zYzoCxYooG7JfBY1YC83=*woO`3{qz^8umQkAG-ZV!MbbR_q>C=dhN6{dtSL`DR$md ztcWbdb#AV%5TWLW$WLjO=8L*|b*m1IrGMw{yU=?5^xL^_M*Hcvv;1jDZ(R7*e(3qK z(eGNbuasTVafeiZT^tGR@GKq{&wSf62h>iYAV-3 zcv};k&@t8zJ+c3WqgT^-sKvsTpC=Xa^nLoa4`_fjz0d3$H|l^|y`Bdc+b=t&v&eXc zYcJ|!s_eSF#kAHvPvNnuXuNQqy*TW}WDyZV2iD!4`RySVJA%%`pn<;hhS^nSWAo`# zF*YdI*R5!(;K+7A7MGInI*Nccc6Q9iBa%$->{9d&-S6jQCw7?>e7 z+O=8Hu-WB_z+8;pd8!mmhdiqu7QA>D5n3qE`-7iuJmujnIzN2Y>dNklV_dpp|B2$s zUbnBB)^~Mot)EQR=I-kK2jBeSmL0VCVT5pQo1tx1OqP)fTlC zmZM%ZR_C5Jt1%w@EYz;LEDwR6)|!RWs|=k>C2R;}l;lYO7Z~82E8O z&E45KdkQUI%wsuccN3MHfu_a4&ZpMU6JC&L4DqF6ovil z;>I*TbvE7_T95nf!L!=%iYzue6@Jst$1i5l&8n*!W?RoxO-q>WS#zq!6<^VKud~C< zD^KK@LNxAtof-3Wr4DY*GfZ(=Im6S~n;&ndcGk>>fE4{iF~AE9F$CJkn)Yu&bX<1VVduUmb) zKRjE?duk|31)gMS3Q127gFPS3)^A$ufM)Dn#j2vQgEe%vaK&H<{}eVBi)np3p5cmX zHry0+gzjnb>=0X)_FA*fX3sl>9zJ-(G}}&ufIl2jQ&Yzqr-t^ft9V)KoeEY5b>d;{ z{+MDF;wo#{;fHy-V>&HazCPg9zunKUuc{C`L^fM(RND{sfT;F#X#CmqV%)IB4$m`g z5oLO1p8~7koEnPC!L+!LheT~NirR11k*Z;&xGXzl%BLOPo%dId`KNC=yTe1?d&ZPs z&C8^OZY5NT}n zi!xtq9Ciy0dADbA;U88w@zcs@pFu9ifA@7O5@pn5SQ=vI`k*f|JT+1>qwGSK^*RxoqaH#jD89%u&`MZ6BprOVImD`V@3vNzL>WEUN~_A=W;DFWv> z6qCwG={>|Uik5-Z&VFkDy7v8hy=vmO&P0aRr=@soEv&*ixX2Ld*ypQfZTxk% zJ>Hw^&Z-SfMc?1o_v|8`ofhA@yhgj%h1lOfSzmlqgg8yDggoJ36l$1WvYfH^zV7{Z z{4mHWy7Lf+YTn9LiH_KbY25cix`byn=HC{AEEekzCQq3nnvLdTx^=7z99Dr9v#av8 z0^_N-U8&chk?hbL;iRk1u`sf-trogoJ-WhzqUux#e|?0$dScUAXY6I|^>yS}7X3BX zbPV~azKT_bUd~g=(008;hH}w5Dkcw{=iTP?(UXd0g_kPoQ7~`Wd~&y+J{_kAtud=x z%0bLpES*)qJK?%IU5kA7^~@`(4GQ+x2@ka!x03Q=P)#Zge^sF7qu-)J(qk6r9r@Xw z<9Uiy?Wv$uiOW#OL@n+vQ}fm+>-)HdhXfJzWe6?&pjKvp={oFC1v6&ob&&6>;I?2d`eT71OJcW0~dXR$gbV;IMm{R{Eq`*$z<+xxFx>-+8f7ccwU`!7Eq+kXAZ|MdQw*ZO&T|LvFj z-@WW_?|*p3e|Z1n%m4BHPoM2|`{$SaKF{*Q z3;*rKw;uog#sAMQ$DUYLhQAQ*FNME-zOVfImH*BAzh1|;*OSuH;fL2ZWB>j6_h0z+ zgtRpL#|!V{>j`RU*b~);o3eE4NoRQO{Kqf-|L1dj{QFC|#rNc_&OPbO6SP8<-xJC7 zxhHyM@6%xC<@Y4Aw*7@&PyFih?DC$+p4`>BCx*#Szn+NI-jltmuyx=b(_hiCM(!{5 z#`4qaGg^2)tNF|pj(qjX^u(*ZqS&!@=5bL{=}H-2;1)T6OeYe|bK= zs)?fmzxS~9Ew3n5VhNXyI+vflxca%i#KXgUPhN9<(HC0Ti~s4B4SU`(s^589bB)b< zD-|PsEwh-i>ZDO|JIdXBIvc<8v+Nj-IfHX}@YU-RqIpsm*Qz%ko$ZxHPIaX(z&0vPnUR4wPtDj zRjbnaRACnCq^mk=nwOztGr#;r%-T5}UGLQs8H3oQ9P1D|y1&RQqiCxP;xLBi`-;xW zTz6QkB5q|C_hd?;@ZAsOiP-fEMJ8VB%-mYh;lfsD{9xf#l`$*&xGXnaR648>>Mn~M zzH}X09l(eoh1<)~W#j211`fr?^H_zRH9vg%!Lho==sdjDDTfMJid{8bs;bU$!?P?i z!y^_hl)U90=dGw>%hLIdR#Wy}E#}S&Eo!}$|76vT*m86mGZTh;hsA zYFZ8X`Nta$X7)o#+bV4Z9u`&jhM!m6Ec^Gfx~N(k#oB*8j>~-2qen6F++WsB(d$yA zy0O*O)7n^HYBr0F#&y>YPE%lvDBE6qXw$Civ^br?TxW~IM|QblAuJ>0-9htH7ekzN zHcmKTCR#_ZT~l~btg30+3tk9%>in)2Uh}?)i^JYtUwdC$XEBhsYj7){hlXjq{L}Tx zPt9rQtQvRy#&p+asKe_>6P$|4)^WOGC@UW|?D`=Pzs;?$&E6Qw! zE@Lxc=KMB`7OPpF^_69FyK(3BBl`YF-Gn@#Watsn@83>jc_#wS*#)qMQkm=u@>V8&-}(JPce0(>Nq;qYaX*O z78uA>&$y_3WwFyFWLg!6M>byjJXpAMhf|00x_;%c4{b*shJge0n268Qc1k$cQI&nx z7?=2O9LBnAwBBxwVo^N3TrbVXGMAra`5j@XMPpTqkL~6^#9|L~eHK^r@}8AKz-T&k z7Ur-z<9p^|nKnbkSxs8GFH%%4Zq^N^EMZh{9(;!#+Vrvl%4*{gy&gkZFYvl2H>*>6 z*|2v1sM@xv*m-&Cl)sr7mTJ}OC4Nk%o60Ez4VSEoZ)_8_$fvfrRj*f`UaDdS@%cWc zHz>n;uBV}dUFDF6Z(No5PLZvbbm)FMKILx39J?V76GJspM^!9BJU+$1X`lVc?>WEa zZS7PK(<1Ozo33VWRi-08SIxO@u(%rIdPn-`q-ga{1K+clDJr?bd>g*MKeKQ3ckH(W zW?;Wv=v)6be~+YZy+iZA0b|47x4ZJ7XZE*_=}(1Y zQnWf#1uFcXV&+pp6h=5VpW()999Y~3zx{u1ny)S`!z?cjjUg6A8=hf5>olG!(;n+E zXf~xVXZPEy#`u~c%8mc#8CzI=c01%Er*C#^dg?y=oDyYNNfaoiJ3*MoJ71P($JkGs zaITJc5!MSV`@Cwx+`el)Hj4@m=Gn?*+xlr$t#8*2?q8$qtUmPIF)K^mjuU>Nh%Lfv z8B@SD=?bZRjU4}el?)3ui3AbI_#L>HU0Fmd7E~N7lm2A;_htRioVJl zuiA9D2;ZwgGfNl4id9IPJAG8qH3ofGoYid|#}C(a;o8Xxg_bmfu+JMjW3CcBeGeC3 z>NI23&sKic#^aH#IX~`JfJhk_@7*fTvY;K;^lEco3|XBifRnwor0=SGL1$f^JY&*m z9k4oYth#=u5?p-cQG@D@=TiZuiDiezjDjCdlFQLu#a!C+1ggcokoS#$xGkMm^PGUPnYE! zZ#BkzYyI>ncM8`>neLnB17f!Ig0r)$}hEBaKS+vaU~;gm6ysZw4s zQ#oeFVreBt4fgUo*D=2ITaR@)FF%j@WocYBk&Bw|&c~ht>*H7z*=7aKPrGt3kIhEa z9TS>h7n1WS7r*&JoU*R5aa@iyQLee{XcXJwbnLuscG$Rw)(GDxr+Pe`@^}4SRM<47 G!2bYG&N=u1 literal 0 HcmV?d00001 From df2c0f61af2792484bb46a52171182c7e762b897 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Wed, 17 May 2023 13:02:45 +0200 Subject: [PATCH 10/20] Adjusting BiPoToRawSignal.rml for the validation chain --- pipeline/external/BiPo/BiPoToRawSignal.rml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pipeline/external/BiPo/BiPoToRawSignal.rml b/pipeline/external/BiPo/BiPoToRawSignal.rml index 84e00884..5ab66272 100644 --- a/pipeline/external/BiPo/BiPoToRawSignal.rml +++ b/pipeline/external/BiPo/BiPoToRawSignal.rml @@ -13,7 +13,7 @@ - + @@ -63,7 +63,7 @@ - + From e88b665667a3884e82b0b8b4840072819f17eba9 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Wed, 17 May 2023 15:32:00 +0200 Subject: [PATCH 11/20] TRestRawBiPoToSignalProcess::GetBiPoSettings method added --- inc/TRestRawBiPoToSignalProcess.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/inc/TRestRawBiPoToSignalProcess.h b/inc/TRestRawBiPoToSignalProcess.h index 5007fc63..cab27218 100644 --- a/inc/TRestRawBiPoToSignalProcess.h +++ b/inc/TRestRawBiPoToSignalProcess.h @@ -51,19 +51,13 @@ struct MatacqBoard { int32_t trg_ch[MATACQ_N_CH]; int32_t Trig_Type; - int32_t Threshold; - int32_t Nb_Acq; - int32_t Posttrig; - int32_t Time_Tag_On; - int32_t Sampling_GHz; int32_t ch_shifts[MATACQ_N_CH]; - int32_t nChannels; }; @@ -115,7 +109,8 @@ class TRestRawBiPoToSignalProcess : public TRestRawToSignalProcess { void PrintMetadata() override; - MatacqBoard GetMatacqBoard(Int_t n) { return fMatacqBoard[n]; } + MatacqBoard GetMatacqBoard(Int_t n) { return n > fNBoards ? (MatacqBoard){} : fMatacqBoard[n]; } + BiPoSettings GetBiPoSettings(Int_t n) { return n > fNBoards ? (BiPoSettings){} : fBiPoSettings[n]; } // Constructor TRestRawBiPoToSignalProcess(); From 234839b3d40d6a639d4e2c10adc0f14af2621e1d Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Wed, 17 May 2023 15:52:42 +0200 Subject: [PATCH 12/20] Adding validation macro --- pipeline/external/BiPo/Validate.C | 59 +++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 pipeline/external/BiPo/Validate.C diff --git a/pipeline/external/BiPo/Validate.C b/pipeline/external/BiPo/Validate.C new file mode 100644 index 00000000..9a160d9c --- /dev/null +++ b/pipeline/external/BiPo/Validate.C @@ -0,0 +1,59 @@ +Int_t Validate() { + TRestRun run("RawData_BiPo3Mod2_02600.root"); + + TRestRawBiPoToSignalProcess* bipo = + (TRestRawBiPoToSignalProcess*)run.GetMetadataClass("TRestRawBiPoToSignalProcess"); + + int checksum = bipo->GetMatacqBoard(9).address; + checksum += bipo->GetMatacqBoard(9).en_ch[0] + bipo->GetMatacqBoard(9).en_ch[1] + + bipo->GetMatacqBoard(9).en_ch[2] + bipo->GetMatacqBoard(9).en_ch[3]; + checksum += bipo->GetMatacqBoard(9).trg_ch[0] + bipo->GetMatacqBoard(9).trg_ch[1] + + bipo->GetMatacqBoard(9).trg_ch[2] + bipo->GetMatacqBoard(9).trg_ch[3]; + + checksum += bipo->GetMatacqBoard(9).Trig_Type; + checksum += bipo->GetMatacqBoard(9).Threshold; + checksum += bipo->GetMatacqBoard(9).Nb_Acq; + checksum += bipo->GetMatacqBoard(9).Posttrig; + checksum += bipo->GetMatacqBoard(9).Time_Tag_On; + checksum += bipo->GetMatacqBoard(9).Sampling_GHz; + + std::cout << "Checksum: " << checksum << std::endl; + if (checksum != 145) { + std::cout << "Error. Matacq settings of the latest board seem to be wrong!" << std::endl; + bipo->PrintMetadata(); + return 1; + } + + checksum = bipo->GetBiPoSettings(9).trigger_address; + checksum += bipo->GetBiPoSettings(9).Win1_Posttrig; + checksum += bipo->GetBiPoSettings(9).Timeout_200KHz; + checksum += bipo->GetBiPoSettings(9).Trig_Chan[0] + bipo->GetBiPoSettings(9).Trig_Chan[1] + + bipo->GetBiPoSettings(9).Trig_Chan[2] + bipo->GetBiPoSettings(9).Trig_Chan[3]; + checksum += bipo->GetBiPoSettings(9).Level1_mV[0] + bipo->GetBiPoSettings(9).Level1_mV[1] + + bipo->GetBiPoSettings(9).Level1_mV[2] + bipo->GetBiPoSettings(9).Level1_mV[3]; + checksum += bipo->GetBiPoSettings(9).Level2_mV[0] + bipo->GetBiPoSettings(9).Level2_mV[1] + + bipo->GetBiPoSettings(9).Level2_mV[2] + bipo->GetBiPoSettings(9).Level2_mV[3]; + + checksum += bipo->GetBiPoSettings(9).t1_window; + checksum += bipo->GetBiPoSettings(9).t2_window; + checksum += bipo->GetBiPoSettings(9).t1_t2_timeout; + + std::cout << "Checksum: " << checksum << std::endl; + if (checksum != 3748) { + std::cout << "Error. BiPo settings of the latest board seem to be wrong!" << std::endl; + bipo->PrintMetadata(); + return 2; + } + + TRestEvent* ev = (TRestEvent*)run.GetInputEvent(); + run.GetEntry(4); + + std::cout.precision(12); + std::cout << "Time stamp: " << round(100. * ev->GetTime()) / 100. << std::endl; + if (round(100. * ev->GetTime()) != 137550274597) { + std::cout << "A problem occurred reading the event time stamp!" << std::endl; + return 3; + } + + return 0; +} From 14efd4266bbec8ef6eb5468429554d80ca34fff2 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Wed, 17 May 2023 15:55:32 +0200 Subject: [PATCH 13/20] Adding new validation job --- .github/workflows/validation.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index 98a484c8..7220179e 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -144,3 +144,27 @@ jobs: cd ${{ env.RAW_LIB_PATH }}/pipeline/external/dream restManager --c dream.rml --f dummyDreamData.fdf restRoot -b -q dream.C + BiPoData: + name: Process BiPo data + runs-on: ubuntu-latest + container: + image: ghcr.io/lobis/root-geant4-garfield:rest-for-physics + needs: [ build-rawlib ] + steps: + - uses: rest-for-physics/framework/.github/actions/checkout@master + with: + branch: ${{ env.BRANCH_NAME }} + repository: rest-for-physics/rawlib + path: ${{ env.RAW_LIB_PATH }} + - name: Restore cache + uses: actions/cache@v3 + id: rawlib-install-cache + with: + key: ${{ env.BRANCH_NAME }}-${{ github.sha }} + path: ${{ env.REST_PATH }} + - name: BiPo data + run: | + source ${{ env.REST_PATH }}/thisREST.sh + cd ${{ env.RAW_LIB_PATH }}/pipeline/external/BiPo + restManager --c BiPoToRawSignal.rml --f BiPo3Mod2_run_2600.data + restRoot -b -q Validate.C From 289ab90c44d6e25a97d536af3902385ce328d6c9 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Thu, 18 May 2023 10:06:55 +0200 Subject: [PATCH 14/20] TRestRawBiPoToSignalProcess. Added method documentation --- inc/TRestRawBiPoToSignalProcess.h | 8 +++++--- src/TRestRawBiPoToSignalProcess.cxx | 13 ++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/inc/TRestRawBiPoToSignalProcess.h b/inc/TRestRawBiPoToSignalProcess.h index cab27218..5b4deed9 100644 --- a/inc/TRestRawBiPoToSignalProcess.h +++ b/inc/TRestRawBiPoToSignalProcess.h @@ -105,17 +105,19 @@ class TRestRawBiPoToSignalProcess : public TRestRawToSignalProcess { void InitProcess() override; void Initialize() override; TRestEvent* ProcessEvent(TRestEvent* inputEvent) override; + + /// Returs a given process name const char* GetProcessName() const override { return "BiPoToSignal"; } void PrintMetadata() override; + /// It gives access to a Matacq board confituration MatacqBoard GetMatacqBoard(Int_t n) { return n > fNBoards ? (MatacqBoard){} : fMatacqBoard[n]; } + + /// It gives access to confituration of BiPo settings BiPoSettings GetBiPoSettings(Int_t n) { return n > fNBoards ? (BiPoSettings){} : fBiPoSettings[n]; } - // Constructor TRestRawBiPoToSignalProcess(); - - // Destructor ~TRestRawBiPoToSignalProcess(); ClassDefOverride(TRestRawBiPoToSignalProcess, 1); diff --git a/src/TRestRawBiPoToSignalProcess.cxx b/src/TRestRawBiPoToSignalProcess.cxx index 3780494d..25e8724c 100644 --- a/src/TRestRawBiPoToSignalProcess.cxx +++ b/src/TRestRawBiPoToSignalProcess.cxx @@ -268,6 +268,9 @@ void TRestRawBiPoToSignalProcess::ReadHeader() { } } +/////////////////////////////////////////////// +/// \brief This method reads the settings of one of the Matacq boards. +/// void TRestRawBiPoToSignalProcess::ReadBoard() { MatacqBoard board; int32_t tmp; @@ -360,7 +363,7 @@ void TRestRawBiPoToSignalProcess::ReadBoard() { /////////////////////////////////////////////// /// \brief This method reads the header data corresponding to the -/// BiPo settings. +/// BiPo settings of one card. /// void TRestRawBiPoToSignalProcess::ReadBiPoSetup() { BiPoSettings bipo; @@ -512,6 +515,10 @@ Int_t TRestRawBiPoToSignalProcess::ReadBiPoEventData(uint16_t* mdata) { return boardAddress; } +/////////////////////////////////////////////// +/// \brief It returns the std::vector storage index using the hardware +/// address of the Matacq board. +/// UInt_t TRestRawBiPoToSignalProcess::GetBoardIndex(Int_t address) { for (unsigned int n = 0; n < fMatacqBoard.size(); n++) if (fMatacqBoard[n].address == address) return n; @@ -519,6 +526,10 @@ UInt_t TRestRawBiPoToSignalProcess::GetBoardIndex(Int_t address) { return -1; } +/////////////////////////////////////////////// +/// \brief It returns the ordered channel value from the Matacq memory buffer for a given +/// board, channel and time sample, or bin. +/// Int_t TRestRawBiPoToSignalProcess::GetBin(Int_t boardIndex, Int_t channel, Int_t bin) { MatacqBoard board = fMatacqBoard[boardIndex]; return board.ch_shifts[channel] + board.nChannels * bin; From a1815f530b9e3fb4f80a68c2cf39433df497200c Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Thu, 18 May 2023 10:29:52 +0200 Subject: [PATCH 15/20] TRestRawBiPoToSignalProcess. Adding documentation --- images/BiPo.png | Bin 0 -> 10171 bytes src/TRestRawBiPoToSignalProcess.cxx | 37 ++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 images/BiPo.png diff --git a/images/BiPo.png b/images/BiPo.png new file mode 100644 index 0000000000000000000000000000000000000000..68bef8e09ce360f770995a76bf2561a53a720a3a GIT binary patch literal 10171 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 Ay8r+H literal 0 HcmV?d00001 diff --git a/src/TRestRawBiPoToSignalProcess.cxx b/src/TRestRawBiPoToSignalProcess.cxx index 25e8724c..a1ce2e14 100644 --- a/src/TRestRawBiPoToSignalProcess.cxx +++ b/src/TRestRawBiPoToSignalProcess.cxx @@ -21,12 +21,39 @@ *************************************************************************/ /////////////////////////////////////////////////////////////////////// -// The TRestRawBiPoToSignalProcess ... +// The TRestRawBiPoToSignalProcess reads a binary file based on the BiPo +// acquisition. This acquisition consists of several Matacq boards that +// register waveforms coming from two different sources managed by the +// BiPo trigger configuration. // -// DOCUMENTATION TO BE WRITTEN (main description, methods, data members) +// This process reads the header of the input file placing the header +// information in two different c-structures MatacqBoard and BiPoSettings. +// +// For the moment the input file needs to be read uncompressed. If we got +// compressed data, we will need to uncompress it before start the processing +// with restManager, as follows: +// +// ``` +// gzip -d -c /path/to/binary/data/BiPo3Mod2_run_2600.data.gz > /tmp/BiPo3Mod2_run_2600.data +// restManager --c /path/to/rml/BiPoToRawSignal.rml --f /tmp/BiPo3Mod2_run_2600.data +// rm /tmp/BiPo3Mod2_run_2600.data +// ``` +// +// The file `BiPoToRawSignal.rml` can be found inside the `pipeline/external/BiPo`. +// +// Additional information might be found at the +// [following PR](https://github.com/rest-for-physics/rawlib/pull/106). +// +// The produced event consists of 4-channels, each channel being divided in two +// time windows, the first window goes from 1 to 1500 samples, and the second +// window goes from 1501 to 2460. +// +// +// \htmlonly +// \endhtmlonly +// +// ![Example of acquired event](BiPo.png) // -// TODO: This process requires optimization to improve the data processing -// rate. // //
// @@ -53,7 +80,7 @@ // \author Javier Galan // //
-///// +// #include "TRestRawBiPoToSignalProcess.h" using namespace std; From 77fd44ce272c4527eba90b199da8887d9ef2e5a9 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Thu, 18 May 2023 11:05:49 +0200 Subject: [PATCH 16/20] TRestRawBiPoToSignalProcess. Updating documentation --- src/TRestRawBiPoToSignalProcess.cxx | 120 ++++++++++++++-------------- 1 file changed, 59 insertions(+), 61 deletions(-) diff --git a/src/TRestRawBiPoToSignalProcess.cxx b/src/TRestRawBiPoToSignalProcess.cxx index a1ce2e14..f905a2d0 100644 --- a/src/TRestRawBiPoToSignalProcess.cxx +++ b/src/TRestRawBiPoToSignalProcess.cxx @@ -20,67 +20,65 @@ * For the list of contributors see $REST_PATH/CREDITS. * *************************************************************************/ -/////////////////////////////////////////////////////////////////////// -// The TRestRawBiPoToSignalProcess reads a binary file based on the BiPo -// acquisition. This acquisition consists of several Matacq boards that -// register waveforms coming from two different sources managed by the -// BiPo trigger configuration. -// -// This process reads the header of the input file placing the header -// information in two different c-structures MatacqBoard and BiPoSettings. -// -// For the moment the input file needs to be read uncompressed. If we got -// compressed data, we will need to uncompress it before start the processing -// with restManager, as follows: -// -// ``` -// gzip -d -c /path/to/binary/data/BiPo3Mod2_run_2600.data.gz > /tmp/BiPo3Mod2_run_2600.data -// restManager --c /path/to/rml/BiPoToRawSignal.rml --f /tmp/BiPo3Mod2_run_2600.data -// rm /tmp/BiPo3Mod2_run_2600.data -// ``` -// -// The file `BiPoToRawSignal.rml` can be found inside the `pipeline/external/BiPo`. -// -// Additional information might be found at the -// [following PR](https://github.com/rest-for-physics/rawlib/pull/106). -// -// The produced event consists of 4-channels, each channel being divided in two -// time windows, the first window goes from 1 to 1500 samples, and the second -// window goes from 1501 to 2460. -// -// -// \htmlonly -// \endhtmlonly -// -// ![Example of acquired event](BiPo.png) -// -// -//
-// -// \warning **⚠ REST is under continous development.** This documentation -// is offered to you by the REST community. Your HELP is needed to keep this -// code up to date. Your feedback will be worth to support this software, please -// report any problems/suggestions you may find will using it at [The REST Framework -// forum](http://ezpc10.unizar.es). You are welcome to contribute fixing typos, -// updating information or adding/proposing new contributions. See also our -// Contribution -// Guide. -// -// -//-------------------------------------------------------------------------- -// -// RESTsoft - Software for Rare Event Searches with TPCs -// -// History of developments: -// -// 2023-May: First implementation (from https://gitlab.in2p3.fr/bipo/matacqana.git) -// Javier Galan -// -// \class TRestRawBiPoToSignalProcess -// \author Javier Galan -// -//
-// +//////////////////////////////////////////////////////////////////////// +/// The TRestRawBiPoToSignalProcess reads a binary file based on the BiPo +/// acquisition. This acquisition consists of several Matacq boards that +/// register waveforms coming from two different sources managed by the +/// BiPo trigger configuration. +/// +/// This process reads the header of the input file placing the header +/// information in two different c-structures MatacqBoard and BiPoSettings. +/// +/// For the moment the input file needs to be read uncompressed. If we got +/// compressed data, we will need to uncompress it before start the processing +/// with restManager, as follows: +/// +/// \code +/// gzip -d -c /path/to/binary/data/BiPo3Mod2_run_2600.data.gz > /tmp/BiPo3Mod2_run_2600.data +/// restManager --c /path/to/rml/BiPoToRawSignal.rml --f /tmp/BiPo3Mod2_run_2600.data +/// rm /tmp/BiPo3Mod2_run_2600.data +/// \endcode +/// +/// The file `BiPoToRawSignal.rml` can be found inside the `pipeline/external/BiPo`. +/// +/// Additional information might be found at the +/// [following PR](https://github.com/rest-for-physics/rawlib/pull/106). +/// +/// The produced event consists of 4-channels, each channel being divided in two +/// time windows, the first window goes from 1 to 1500 samples, and the second +/// window goes from 1501 to 2460. +/// +/// \htmlonly +/// \endhtmlonly +/// +/// ![Example of acquired event](BiPo.png) +/// +///
+/// +/// \warning **⚠ REST is under continous development.** This documentation +/// is offered to you by the REST community. Your HELP is needed to keep this +/// code up to date. Your feedback will be worth to support this software, please +/// report any problems/suggestions you may find will using it at [The REST Framework +/// forum](http://ezpc10.unizar.es). You are welcome to contribute fixing typos, +/// updating information or adding/proposing new contributions. See also our +/// Contribution +/// Guide. +/// +/// +///-------------------------------------------------------------------------- +/// +/// RESTsoft - Software for Rare Event Searches with TPCs +/// +/// History of developments: +/// +/// 2023-May: First implementation (from https://gitlab.in2p3.fr/bipo/matacqana.git) +/// Javier Galan +/// +/// \class TRestRawBiPoToSignalProcess +/// \author Javier Galan +/// +///
+/// #include "TRestRawBiPoToSignalProcess.h" using namespace std; From 4a5b3b03601616f1b0c9cb992f253bc57f9bf00e Mon Sep 17 00:00:00 2001 From: juanan Date: Thu, 18 May 2023 12:44:54 +0200 Subject: [PATCH 17/20] Moving structs inside TRestTRestRawBiPoToSignalProcess class and using constexpr --- inc/TRestRawBiPoToSignalProcess.h | 96 +++++++++++++++-------------- src/TRestRawBiPoToSignalProcess.cxx | 23 +++---- 2 files changed, 61 insertions(+), 58 deletions(-) diff --git a/inc/TRestRawBiPoToSignalProcess.h b/inc/TRestRawBiPoToSignalProcess.h index 5b4deed9..614ede01 100644 --- a/inc/TRestRawBiPoToSignalProcess.h +++ b/inc/TRestRawBiPoToSignalProcess.h @@ -26,59 +26,61 @@ #include "TRestRawSignalEvent.h" #include "TRestRawToSignalProcess.h" -static const size_t CTAG_SZ = 4; - -const int MATACQ_N_CH = 4; // Number of channels -const int MATACQ_MAX_DATA_SAMP = 10240; // Max number of samples for -const int MATACQ_BIPO_TIMEOUT = 0; // BiPo mode timeout - -static const int MATACQ_UNDERFLOW = 0x0000; -static const int MATACQ_ZERO = 0x8000; -static const int MATACQ_OVERFLOW = 0xFFFF; - -const std::string TAG_RUN_START = "STA"; -const std::string TAG_RUN_BIPO = "ST2"; -const std::string TAG_RUN_STOP = "STO"; -const std::string TAG_ACQ = "ACQ"; -const std::string TAG_ACQ_2 = "AC2"; - -/// A structure to store the configuration settings of Matacq board -struct MatacqBoard { - /// The base memory address of the Matacq board - int32_t address; - - int32_t en_ch[MATACQ_N_CH]; - int32_t trg_ch[MATACQ_N_CH]; - - int32_t Trig_Type; - int32_t Threshold; - int32_t Nb_Acq; - int32_t Posttrig; - int32_t Time_Tag_On; - int32_t Sampling_GHz; - - int32_t ch_shifts[MATACQ_N_CH]; - int32_t nChannels; -}; +constexpr size_t CTAG_SZ = 4; -/// A structure to store the BiPo settings -struct BiPoSettings { - int32_t trigger_address; +constexpr int MATACQ_N_CH = 4; // Number of channels +constexpr int MATACQ_MAX_DATA_SAMP = 10240; // Max number of samples for +constexpr int MATACQ_BIPO_TIMEOUT = 0; // BiPo mode timeout - int32_t Win1_Posttrig; - int32_t Timeout_200KHz; +constexpr uint32_t MATACQ_UNDERFLOW = 0x0000; +constexpr uint32_t MATACQ_ZERO = 0x8000; +constexpr uint32_t MATACQ_OVERFLOW = 0xFFFF; - int32_t Trig_Chan[MATACQ_N_CH]; - int32_t Level1_mV[MATACQ_N_CH]; - int32_t Level2_mV[MATACQ_N_CH]; +constexpr char TAG_RUN_START[] = "STA"; +constexpr char TAG_RUN_BIPO[] = "ST2"; +constexpr char TAG_RUN_STOP[] = "STO"; +constexpr char TAG_ACQ[] = "ACQ"; +constexpr char TAG_ACQ_2[] = "AC2"; - int32_t t1_window; - int32_t t2_window; - int32_t t1_t2_timeout; -}; //! An process to read binary data from BiPo electronics class TRestRawBiPoToSignalProcess : public TRestRawToSignalProcess { + public: + /// A structure to store the configuration settings of Matacq board + struct MatacqBoard { + /// The base memory address of the Matacq board + int32_t address; + + std::array en_ch; + std::array trg_ch; + + int32_t Trig_Type; + int32_t Threshold; + int32_t Nb_Acq; + int32_t Posttrig; + int32_t Time_Tag_On; + int32_t Sampling_GHz; + + std::array ch_shifts; + int32_t nChannels; + }; + + /// A structure to store the BiPo settings + struct BiPoSettings { + int32_t trigger_address; + + int32_t Win1_Posttrig; + int32_t Timeout_200KHz; + + std::array Trig_Chan; + std::array Level1_mV; + std::array Level2_mV; + + int32_t t1_window; + int32_t t2_window; + int32_t t1_t2_timeout; + }; + protected: /// The number of Matacq boards present on the setup Int_t fNBoards = 0; ///< @@ -96,7 +98,7 @@ class TRestRawBiPoToSignalProcess : public TRestRawToSignalProcess { void ReadFooter(); void ReadBoard(); void ReadBiPoSetup(); - Int_t ReadBiPoEventData(uint16_t* mdata); + Int_t ReadBiPoEventData(std::vector &mdata); UInt_t GetBoardIndex(Int_t address); Int_t GetBin(Int_t boardIndex, Int_t channel, Int_t bin); diff --git a/src/TRestRawBiPoToSignalProcess.cxx b/src/TRestRawBiPoToSignalProcess.cxx index a1ce2e14..d686df3d 100644 --- a/src/TRestRawBiPoToSignalProcess.cxx +++ b/src/TRestRawBiPoToSignalProcess.cxx @@ -129,7 +129,7 @@ void TRestRawBiPoToSignalProcess::InitProcess() { } totalBytesReaded += CTAG_SZ * sizeof(char); - if (buffer != TAG_RUN_BIPO) { + if (strcmp(buffer, TAG_RUN_BIPO) != 0) { RESTError << "The file " << fInputFileNames[0] << " is not BiPo format" << RESTendl; exit(1); } @@ -160,17 +160,17 @@ TRestEvent* TRestRawBiPoToSignalProcess::ProcessEvent(TRestEvent* inputEvent) { } totalBytesReaded += CTAG_SZ * sizeof(char); - if (std::string(buffer) == TAG_RUN_STOP) { + if (strcmp(buffer, TAG_RUN_STOP) == 0) { RESTDebug << "The run ends" << RESTendl; ReadFooter(); // The processing thread finishes return nullptr; } - if (std::string(buffer) == TAG_ACQ || std::string(buffer) == TAG_ACQ_2) { + if (strcmp(buffer, TAG_ACQ) == 0 || strcmp(buffer, TAG_ACQ_2) == 0) { RESTDebug << "A new event comes" << RESTendl; - uint16_t data[MATACQ_MAX_DATA_SAMP]; + std::vector data; Int_t boardAddress = ReadBiPoEventData(data); Int_t bIndex = GetBoardIndex(boardAddress); @@ -308,7 +308,7 @@ void TRestRawBiPoToSignalProcess::ReadBoard() { totalBytesReaded += sizeof(int32_t); board.address = tmp; - if (fread(board.en_ch, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { + if (fread(&board.en_ch[0], sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { printf("Error: could not read base matacq en_ch.\n"); exit(1); } @@ -326,7 +326,7 @@ void TRestRawBiPoToSignalProcess::ReadBoard() { } } - if (fread(board.trg_ch, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { + if (fread(&board.trg_ch[0], sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { printf("Error: could not read base matacq trg_ch.\n"); exit(1); } @@ -417,19 +417,19 @@ void TRestRawBiPoToSignalProcess::ReadBiPoSetup() { totalBytesReaded += sizeof(int32_t); bipo.Timeout_200KHz = tmp; - if (fread(bipo.Trig_Chan, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { + if (fread(&bipo.Trig_Chan[0], sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { printf("Error: could not read Trig_Chan.\n"); exit(1); } totalBytesReaded += MATACQ_N_CH * sizeof(int32_t); - if (fread(bipo.Level1_mV, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { + if (fread(&bipo.Level1_mV[0], sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { printf("Error: could not read Level1_mV.\n"); exit(1); } totalBytesReaded += MATACQ_N_CH * sizeof(int32_t); - if (fread(bipo.Level2_mV, sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { + if (fread(&bipo.Level2_mV[0], sizeof(int32_t), MATACQ_N_CH, fInputBinFile) != MATACQ_N_CH) { printf("Error: could not read Level2_mV.\n"); exit(1); } @@ -485,7 +485,7 @@ void TRestRawBiPoToSignalProcess::ReadBiPoSetup() { /// the triggered board address will be returned and it will be used /// later on to generate a signal id. /// -Int_t TRestRawBiPoToSignalProcess::ReadBiPoEventData(uint16_t* mdata) { +Int_t TRestRawBiPoToSignalProcess::ReadBiPoEventData(std::vector &mdata) { int32_t tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read tmp .\n"); @@ -533,7 +533,8 @@ Int_t TRestRawBiPoToSignalProcess::ReadBiPoEventData(uint16_t* mdata) { totalBytesReaded += sizeof(int32_t); RESTDebug << " T1-T2 distance --> " << tmp << RESTendl; - if (fread(mdata, sizeof(uint16_t), data_size, fInputBinFile) != (size_t)data_size) { + mdata.resize(data_size); + if (fread(&mdata[0], sizeof(uint16_t), data_size, fInputBinFile) != (size_t)data_size) { printf("Error: could not read MATACQ data.\n"); exit(1); } From 0f46efe19eeae9478038d2c4ee78f98efe377545 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 10:45:11 +0000 Subject: [PATCH 18/20] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- inc/TRestRawBiPoToSignalProcess.h | 57 ++++++++++++++--------------- src/TRestRawBiPoToSignalProcess.cxx | 4 +- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/inc/TRestRawBiPoToSignalProcess.h b/inc/TRestRawBiPoToSignalProcess.h index 614ede01..c15f1666 100644 --- a/inc/TRestRawBiPoToSignalProcess.h +++ b/inc/TRestRawBiPoToSignalProcess.h @@ -42,44 +42,43 @@ constexpr char TAG_RUN_STOP[] = "STO"; constexpr char TAG_ACQ[] = "ACQ"; constexpr char TAG_ACQ_2[] = "AC2"; - //! An process to read binary data from BiPo electronics class TRestRawBiPoToSignalProcess : public TRestRawToSignalProcess { public: - /// A structure to store the configuration settings of Matacq board - struct MatacqBoard { - /// The base memory address of the Matacq board - int32_t address; + /// A structure to store the configuration settings of Matacq board + struct MatacqBoard { + /// The base memory address of the Matacq board + int32_t address; - std::array en_ch; - std::array trg_ch; + std::array en_ch; + std::array trg_ch; - int32_t Trig_Type; - int32_t Threshold; - int32_t Nb_Acq; - int32_t Posttrig; - int32_t Time_Tag_On; - int32_t Sampling_GHz; + int32_t Trig_Type; + int32_t Threshold; + int32_t Nb_Acq; + int32_t Posttrig; + int32_t Time_Tag_On; + int32_t Sampling_GHz; - std::array ch_shifts; - int32_t nChannels; - }; + std::array ch_shifts; + int32_t nChannels; + }; - /// A structure to store the BiPo settings - struct BiPoSettings { - int32_t trigger_address; + /// A structure to store the BiPo settings + struct BiPoSettings { + int32_t trigger_address; - int32_t Win1_Posttrig; - int32_t Timeout_200KHz; + int32_t Win1_Posttrig; + int32_t Timeout_200KHz; - std::array Trig_Chan; - std::array Level1_mV; - std::array Level2_mV; + std::array Trig_Chan; + std::array Level1_mV; + std::array Level2_mV; - int32_t t1_window; - int32_t t2_window; - int32_t t1_t2_timeout; - }; + int32_t t1_window; + int32_t t2_window; + int32_t t1_t2_timeout; + }; protected: /// The number of Matacq boards present on the setup @@ -98,7 +97,7 @@ class TRestRawBiPoToSignalProcess : public TRestRawToSignalProcess { void ReadFooter(); void ReadBoard(); void ReadBiPoSetup(); - Int_t ReadBiPoEventData(std::vector &mdata); + Int_t ReadBiPoEventData(std::vector& mdata); UInt_t GetBoardIndex(Int_t address); Int_t GetBin(Int_t boardIndex, Int_t channel, Int_t bin); diff --git a/src/TRestRawBiPoToSignalProcess.cxx b/src/TRestRawBiPoToSignalProcess.cxx index d686df3d..57b6a2ee 100644 --- a/src/TRestRawBiPoToSignalProcess.cxx +++ b/src/TRestRawBiPoToSignalProcess.cxx @@ -170,7 +170,7 @@ TRestEvent* TRestRawBiPoToSignalProcess::ProcessEvent(TRestEvent* inputEvent) { if (strcmp(buffer, TAG_ACQ) == 0 || strcmp(buffer, TAG_ACQ_2) == 0) { RESTDebug << "A new event comes" << RESTendl; - std::vector data; + std::vector data; Int_t boardAddress = ReadBiPoEventData(data); Int_t bIndex = GetBoardIndex(boardAddress); @@ -485,7 +485,7 @@ void TRestRawBiPoToSignalProcess::ReadBiPoSetup() { /// the triggered board address will be returned and it will be used /// later on to generate a signal id. /// -Int_t TRestRawBiPoToSignalProcess::ReadBiPoEventData(std::vector &mdata) { +Int_t TRestRawBiPoToSignalProcess::ReadBiPoEventData(std::vector& mdata) { int32_t tmp; if (fread(&tmp, sizeof(int32_t), 1, fInputBinFile) != 1) { printf("Error: could not read tmp .\n"); From 64a83dca51b4eec46cd74fe1081f02a4b21bd056 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Tue, 23 May 2023 10:45:51 +0200 Subject: [PATCH 19/20] TRestRawBiPoToSignalProcess. Fixing documentation issue --- src/TRestRawBiPoToSignalProcess.cxx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/TRestRawBiPoToSignalProcess.cxx b/src/TRestRawBiPoToSignalProcess.cxx index d4b686e2..ffa92cfd 100644 --- a/src/TRestRawBiPoToSignalProcess.cxx +++ b/src/TRestRawBiPoToSignalProcess.cxx @@ -48,10 +48,9 @@ /// time windows, the first window goes from 1 to 1500 samples, and the second /// window goes from 1501 to 2460. /// -/// \htmlonly -/// \endhtmlonly +/// \htmlonly \endhtmlonly /// -/// ![Example of acquired event](BiPo.png) +/// ![An example of the acquired event](BiPo.png) /// ///
/// From f312b2e022697f8d43ac6ed58f8a101b8c9731a9 Mon Sep 17 00:00:00 2001 From: Javier Galan Date: Tue, 20 Jun 2023 13:03:13 +0200 Subject: [PATCH 20/20] Adding a more complete BiPo example --- examples/01.BiPo/BiPoToRawSignal.rml | 73 +++++++++++++++++++++++++++ examples/01.BiPo/panel.xml | 17 +++++++ examples/01.BiPo/plots.rml | 75 ++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 examples/01.BiPo/BiPoToRawSignal.rml create mode 100644 examples/01.BiPo/panel.xml create mode 100644 examples/01.BiPo/plots.rml diff --git a/examples/01.BiPo/BiPoToRawSignal.rml b/examples/01.BiPo/BiPoToRawSignal.rml new file mode 100644 index 00000000..c3fa6f1d --- /dev/null +++ b/examples/01.BiPo/BiPoToRawSignal.rml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/01.BiPo/panel.xml b/examples/01.BiPo/panel.xml new file mode 100644 index 00000000..3b6a1ac2 --- /dev/null +++ b/examples/01.BiPo/panel.xml @@ -0,0 +1,17 @@ + + + diff --git a/examples/01.BiPo/plots.rml b/examples/01.BiPo/plots.rml new file mode 100644 index 00000000..06f8f9f7 --- /dev/null +++ b/examples/01.BiPo/plots.rml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +