#include #include #include #include #include #include #include #include #include "midas.h" #include "mfe.h" #include // Include the header for rand() #include // Include for random number generation void trigger_update(INT, INT, void*); /*-- Globals -------------------------------------------------------*/ /* The frontend name (client name) as seen by other MIDAS clients */ const char *frontend_name = "DataSimulator"; /* The frontend file name, don't change it */ const char *frontend_file_name = __FILE__; /* frontend_loop is called periodically if this variable is TRUE */ BOOL frontend_call_loop = FALSE; /* a frontend status page is displayed with this frequency in ms */ INT display_period = 1000; /* maximum event size produced by this frontend */ INT max_event_size = 1024 * 1014; /* maximum event size for fragmented events (EQ_FRAGMENTED) */ INT max_event_size_frag = 5 * max_event_size; /* buffer size to hold events */ INT event_buffer_size = 5 * max_event_size; // Define a vector to store 16-bit words std::vector data; // Define a global vector to store 16-bit signed integers // Global variable to keep track of the last poll time std::chrono::steady_clock::time_point last_poll_time; const std::chrono::microseconds polling_interval(300); // Poll every 300 microsecond // Random number generator for generating data std::mt19937 generator; std::uniform_int_distribution distribution(-32768, 32767); // Define the range of random values (short range) // Global variable to hold the zero buffer std::vector zero_buffer; /*-- Function declarations -----------------------------------------*/ INT frontend_init(void); INT frontend_exit(void); INT begin_of_run(INT run_number, char *error); INT end_of_run(INT run_number, char *error); INT pause_run(INT run_number, char *error); INT resume_run(INT run_number, char *error); INT frontend_loop(void); INT read_trigger_event(char *pevent, INT off); INT read_periodic_event(char *pevent, INT off); INT poll_event(INT source, INT count, BOOL test); INT interrupt_configure(INT cmd, INT source, POINTER_T adr); /*-- Equipment list ------------------------------------------------*/ BOOL equipment_common_overwrite = TRUE; EQUIPMENT equipment[] = { {"Data Simulator", /* equipment name */ {2, 0, /* event ID, trigger mask */ "SYSTEM", /* event buffer */ EQ_POLLED, /* equipment type */ 0, /* event source */ "MIDAS", /* format */ TRUE, /* enabled */ RO_RUNNING | RO_TRANSITIONS | /* read when running and on transitions */ RO_ODB, /* and update ODB */ 10, /* read every sec */ 0, /* stop run after this event limit */ 0, /* number of sub events */ TRUE, /* log history */ "", "", "",}, read_trigger_event /* readout routine */ }, {""} }; /*-- Trigger Update ------------------------------------------------*/ void trigger_update(INT hDB, INT hkey,void*) { } /*-- Frontend Init -------------------------------------------------*/ int frontend_init() { // Open the file for reading std::ifstream inputFile("fake_data.txt"); if (!inputFile) { std::cerr << "Error opening the file." << std::endl; return 1; } std::cout << "Reading and converting data:" << std::endl; std::string line; while (std::getline(inputFile, line)) { std::istringstream iss(line); std::string token; while (std::getline(iss, token, ',')) { int16_t value; std::istringstream(token) >> value; data.push_back(value); } } // Print the converted data for (int i = 0; i < data.size(); i++) { std::cout << " " << data[i]; } // Close the file inputFile.close(); if (data.empty()) { std::cerr << "No data was converted." << std::endl; } else { std::cout << std::endl << "Conversion completed." << std::endl; } // Initialize random number generator std::random_device rd; // Obtain a random number from hardware generator = std::mt19937(rd()); // Seed the generator // Define the total number of zero data points const int total_data_size = 50000; // Adjust size as needed // Create and initialize the buffer of zeros zero_buffer.resize(total_data_size, 0); return SUCCESS; } /*-- Frontend Exit -------------------------------------------------*/ INT frontend_exit() { return SUCCESS; } /*-- Begin of Run --------------------------------------------------*/ INT begin_of_run(INT run_number, char *error) { return SUCCESS; } /*-- End of Run ----------------------------------------------------*/ INT end_of_run(INT run_number, char *error) { return SUCCESS; } /*-- Pause Run -----------------------------------------------------*/ INT pause_run(INT run_number, char *error) { return SUCCESS; } /*-- Resume Run ----------------------------------------------------*/ INT resume_run(INT run_number, char *error) { return SUCCESS; } /*-- Frontend Loop -------------------------------------------------*/ INT frontend_loop() { /* if frontend_call_loop is true, this routine gets called when the frontend is idle or once between every event */ return SUCCESS; } /*------------------------------------------------------------------*/ /********************************************************************\ Readout routines for different events \********************************************************************/ /*-- Trigger event routines ----------------------------------------*/ INT poll_event(INT source, INT count, BOOL test) { // Get the current time auto now = std::chrono::steady_clock::now(); // Check if enough time has passed since the last poll if (now - last_poll_time >= polling_interval) { // Update the last poll time last_poll_time = now; // Return TRUE to indicate that an event is available return TRUE; } // If test is TRUE, don't return anything if (test) { return FALSE; } // Otherwise, return FALSE to indicate no event available return FALSE; } /*-- Interrupt configuration ---------------------------------------*/ INT interrupt_configure(INT cmd, INT source, POINTER_T adr) { switch (cmd) { case CMD_INTERRUPT_ENABLE: break; case CMD_INTERRUPT_DISABLE: break; case CMD_INTERRUPT_ATTACH: break; case CMD_INTERRUPT_DETACH: break; } return SUCCESS; } /*-- Event readout -------------------------------------------------*/ INT read_trigger_event(char *pevent, INT off) { short *pdata; // Init bank structure bk_init32(pevent); // Create a bank named "CR00" and specify the data type as TID_SHORT bk_create(pevent, "CR00", TID_SHORT, (void **)&pdata); // Use memcpy to copy the buffer of zeros into the MIDAS bank memcpy(pdata, zero_buffer.data(), zero_buffer.size() * sizeof(short)); // Adjust pdata pointer pdata += zero_buffer.size(); // Move the pointer past the copied data // Close the bank bk_close(pevent, pdata); return bk_size(pevent); } /*-- Periodic event ------------------------------------------------*/ INT read_periodic_event(char *pevent, INT off) { short *pdata; // Change the data type to short // Init bank structure bk_init32(pevent); // Create a bank named "CR00" and specify the data type as TID_SHORT bk_create(pevent, "CR00", TID_SHORT, (void **)&pdata); // Repeat the loop 5000 times for (int repeat = 0; repeat < 400; repeat++) { for (int i = 0; i < data.size(); i++) { *pdata++ = data[i]; } } // Close the bank bk_close(pevent, pdata); return bk_size(pevent); }