//------------------------------------------------------------------------------ // DAQ application task -- // (C) Devis Contarato 2009, Berkeley Lab -- //------------------------------------------------------------------------------ //______________________________________________________________________________ // {Trace} // [File name] "task_DAQ.cpp" // [Author] "Devis Contarato" // [Version] "0.5" // [Modified by] "Devis Contarato" // [Last revision] "20 Jan 2009" // [Language] "C++" // [Compiler] "Visual C++ 8.x 9.x" // [Member of] "Cool SEAL" // [Project] "SEAL" // [Description] "DAQ application task" // [Key documentation] // "Visual C++ Reference Help" // {Trace} //______________________________________________________________________________ // Standard components #include // Application components #include "global.h" #include "cool.h" #include "task_DAQ.h" // Define some standard color #define kc_Desk cool::Gui->kc_blue_Dark #define kc_desk_Label cool::Gui->kc_White #define kc_Btn cool::Gui->kc_Blue #define kc_btn_Label cool::Gui->kc_White //______________________________________________________________________________ task_DAQ::task_DAQ() { // Standard constructor dbg_Print("task_DAQ::task_DAQ: constructor called", DBG_LVL_ZERO); // Set up the data container(s) data_Setup(); // Set up the communication comm_Setup(); // Set up the interface gui_Setup(); } //______________________________________________________________________________ task_DAQ::~task_DAQ() { // Standard destructor dbg_Print("task_DAQ::~task_DAQ: destructor called", DBG_LVL_ZERO); // Kills the interface gui objects gui_Delete(); // Removes the data containers data_Delete(); } //______________________________________________________________________________ UInt_t task_DAQ::run() { // Debug dbg_Print("task_DAQ::run: run called", DBG_LVL_MAKE); // Returns all ok return 0; } //______________________________________________________________________________ void task_DAQ::static_Evn(const int arg) { // Try the call to a static function dbg_Print("task_DAQ::static_Evn: it works!", DBG_LVL_FLOW); } //****************************************************************************** //* * //* GUI initialization and destruction * //* * //****************************************************************************** //______________________________________________________________________________ void task_DAQ::gui_Setup() { // Set up all the interface objects dbg_Print("task_DAQ::gui_Setup: defining interface!", DBG_LVL_FLOW); //////////////////////// // GENERAL APPEARANCE // //////////////////////// // Main window size cool::Gui->size_Set(1280, 960); // Main window color cool::Gui->color_Set(0x888888, 0x000060); // Palette and canvas style gStyle->SetPalette(1); gStyle->SetCanvasBorderMode(0); ////////////////// // MAIN BUTTONS // ////////////////// btn_Run = new gui_CoolButton("Go", 64, 64, gui_Const::btn_Width, gui_Const::btn_Height, kc_btn_Label, gui_CoolButton::kc_Green); btn_Run->btn_Mode(gui_CoolButton::km_Latch); btn_Run->btn_Status(false); btn_Run->task_Connect(this, &task_DAQ::btn_run_Evn); btn_Quit = new gui_CoolButton("Quit", 64, 120, gui_Const::btn_Width, gui_Const::btn_Height, kc_btn_Label, gui_CoolButton::kc_Purple); btn_Quit->btn_Mode(gui_CoolButton::km_Button); btn_Quit->btn_Status(false); btn_Quit->task_Connect(this, &task_DAQ::btn_quit_Evn); ///////////////////////////////// // DATA TAKING & FILE SETTINGS // ///////////////////////////////// // Current event number num_CurrEvt = new gui_Numeric(0, 64, 256, gui_Const::wdgt_Width, gui_Const::wdgt_Height); num_CurrEvt->label_Set("Event number", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // CDS option (CDS = frame(n+1) - frame(n) ) chk_CDS = new gui_Check("CDS", 248, 128, gui_Const::wdgt_Width, gui_Const::wdgt_Height); chk_CDS->color_Set(0xFFFFFF, 0x000060); // Write data option chk_Write = new gui_Check("Write data", 396, 128, gui_Const::wdgt_Width, gui_Const::wdgt_Height); chk_Write->color_Set(0xFFFFFF, 0x000060); // Auto number option; if checked, run number increase automatically +1 whenever GO is pressed chk_AutoNumber = new gui_Check("Auto Run #", 544, 128, gui_Const::wdgt_Width, gui_Const::wdgt_Height); chk_AutoNumber->color_Set(0xFFFFFF, 0x000060); // Number of events num_Evts = new gui_Numeric(1, 248, 192, gui_Const::wdgt_Width, gui_Const::wdgt_Height); num_Evts->label_Set("Number of events", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // Set ROOT file compression level; default = 1, maximum = 9 num_Compression = new gui_Numeric(1, 396, 192, gui_Const::wdgt_Width, gui_Const::wdgt_Height, 1, 9); num_Compression->label_Set("Compression level", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // Run number; string "_run#.root" will be attached at the end of file path num_RunNumber = new gui_Numeric(0, 544, 192, gui_Const::wdgt_Width, gui_Const::wdgt_Height, 0, 10000); num_RunNumber->label_Set("Run number", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // File path txt_File = new gui_Text("test.root", 248, 256, 244, gui_Const::wdgt_Height); txt_File->label_Set("File path", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); ////////////////////////// // ACQUISITION SETTINGS // ////////////////////////// // SET ACQUISITION SETTINGS btn_set_FPGA= new gui_CoolButton("Set FPGA", 700, 64, gui_Const::btn_Width, gui_Const::btn_Height, kc_btn_Label, gui_CoolButton::kc_Cyan); btn_set_FPGA->btn_Mode(gui_CoolButton::km_Button); btn_set_FPGA->btn_Status(false); btn_set_FPGA->task_Connect(this, &task_DAQ::btn_FPGA_Evn); btn_clear_Comm= new gui_CoolButton("Clear COMM", 848, 64, gui_Const::btn_Width, gui_Const::btn_Height, kc_btn_Label, gui_CoolButton::kc_Red); btn_clear_Comm->btn_Mode(gui_CoolButton::km_Button); btn_clear_Comm->btn_Status(false); btn_clear_Comm->task_Connect(this, &task_DAQ::btn_Comm_Evn); // TRIGGER MODE (software, hardware) cbox_Trigger = new gui_Combo(3, 700, 128, gui_Const::wdgt_Width, gui_Const::wdgt_Height); cbox_Trigger->label_Set("Trigger mode", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // define entries of the combo box TString entry_Trigger; entry_Trigger.Form("Software"); cbox_Trigger->cbox_Entry(entry_Trigger.Data(), 0); entry_Trigger.Form("Hardware"); cbox_Trigger->cbox_Entry(entry_Trigger.Data(), 1); // select hardware trigger by default cbox_Trigger->Root()->Select(1); // HARDWARE TRIGGER SOURCE cbox_TrgSource = new gui_Combo(4, 700, 192, gui_Const::wdgt_Width, gui_Const::wdgt_Height); cbox_TrgSource->label_Set("Trigger source", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // define entries of the combo box TString entry_TrgSource; entry_TrgSource.Form("Internal"); cbox_TrgSource->cbox_Entry(entry_TrgSource.Data(), 0); entry_TrgSource.Form("External"); cbox_TrgSource->cbox_Entry(entry_TrgSource.Data(), 1); // in case of hardware trigger, internal trigger by default cbox_TrgSource->Root()->Select(0); // INTERNAL HARDWARE TRIGGER FREQUENCY num_Trigger = new gui_Numeric(10, 700, 256, gui_Const::wdgt_Width, gui_Const::wdgt_Height, 1, 65536); num_Trigger->label_Set("Trigger freq. (Hz)", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // CHIP DRIVER SELECTION cbox_Driver = new gui_Combo(1, 848, 128, gui_Const::wdgt_Width, gui_Const::wdgt_Height); cbox_Driver->label_Set("Select chip", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // define entries of the combo box TString entry_Driver; entry_Driver.Form("0"); cbox_Driver->cbox_Entry(entry_Driver.Data(), 0); entry_Driver.Form("Dummy"); cbox_Driver->cbox_Entry(entry_Driver.Data(), 1); entry_Driver.Form("LDRD2"); cbox_Driver->cbox_Entry(entry_Driver.Data(), 2); entry_Driver.Form("SOI2 Analog"); cbox_Driver->cbox_Entry(entry_Driver.Data(), 3); entry_Driver.Form("SOI2 Digital"); cbox_Driver->cbox_Entry(entry_Driver.Data(), 4); entry_Driver.Form("SOI2 Analog + Digi"); cbox_Driver->cbox_Entry(entry_Driver.Data(), 5); entry_Driver.Form("TEAM"); cbox_Driver->cbox_Entry(entry_Driver.Data(), 6); // select "SOI2 frames" driver by default cbox_Driver->Root()->Select(2); // DRIVER DELAY (check coarse/fine) num_Dly = new gui_Numeric(0, 848, 192, gui_Const::wdgt_Width, gui_Const::wdgt_Height, 0, 256); num_Dly->label_Set("Delay", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // NUMBER OF FRAMES num_Frm = new gui_Numeric(1, 848, 256, gui_Const::wdgt_Width, gui_Const::wdgt_Height, 1, 4); num_Frm->label_Set("Nb. of frames", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); ////////////////// // ADC SETTINGS // ////////////////// // ADC CHANNELS chk_Adc.resize(5); for(int i = 0; i < chk_Adc.size(); i++){ TString chk_Adc_name; chk_Adc_name.Form("Channel %u", i+1); chk_Adc[i] = new gui_Check(chk_Adc_name.Data(), 1154, 124 + i*32, gui_Const::btn_Width, gui_Const::btn_Height); chk_Adc[i]->color_Set(0xFFFFFF, 0x000060); } // DATA SOURCE: 0=ADC data, 1=fake digital data (ramp), 2=chip digital data cbox_DataSource = new gui_Combo(5, 1006, 128, gui_Const::wdgt_Width, gui_Const::wdgt_Height); cbox_DataSource->label_Set("Data source", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // Define entries of the combo box TString entry_DataSource; entry_DataSource.Form("ADC data"); cbox_DataSource->cbox_Entry(entry_DataSource.Data(), 0); entry_DataSource.Form("Test data"); cbox_DataSource->cbox_Entry(entry_DataSource.Data(), 1); entry_DataSource.Form("Digital data"); cbox_DataSource->cbox_Entry(entry_DataSource.Data(), 2); entry_DataSource.Form("ADC & Digi (SOI2)"); cbox_DataSource->cbox_Entry(entry_DataSource.Data(), 3); // select ADC data by default cbox_DataSource->Root()->Select(0); // CLOCK DIVIDER num_Clk = new gui_Numeric(0, 1006, 192, gui_Const::wdgt_Width, gui_Const::wdgt_Height, 0, 12); num_Clk->label_Set("Clock divider", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // NUMBER OF AVERAGES num_Avg = new gui_Numeric(0, 1006, 256, gui_Const::wdgt_Width, gui_Const::wdgt_Height, 0, 7); num_Avg->label_Set("Nb. of averages", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // CHIP SETTINGS num_TEAM_Pre = new gui_Numeric(0, 700, 800, gui_Const::wdgt_Width, gui_Const::wdgt_Height, 0, 7); num_TEAM_Pre->label_Set("TEAM1K pre-burner", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); /////////////////////// // DAQ MODE SETTINGS // /////////////////////// // Combo box for data mode (raw, pedestal, pedestal subtraction) cbox_AcqMode = new gui_Combo(2, 64, 192, gui_Const::wdgt_Width, gui_Const::wdgt_Height); cbox_AcqMode->label_Set("Acquisition mode", gui_Const::align_Left | gui_Const::align_Top, 0xFFFFFF, 0x000060); // Write entries in the combo box TString entry_AcqMode; entry_AcqMode.Form("Raw data"); cbox_AcqMode->cbox_Entry(entry_AcqMode.Data(), 0); entry_AcqMode.Form("Pedestal run"); cbox_AcqMode->cbox_Entry(entry_AcqMode.Data(), 1); entry_AcqMode.Form("Subtract pedestals"); cbox_AcqMode->cbox_Entry(entry_AcqMode.Data(), 2); // select raw data by default cbox_AcqMode->Root()->Select(0); // Check buttons for activate/deactivate event display plots chk_plot1D = new gui_Check("Plot 1D", 524, 320, gui_Const::btn_Width, gui_Const::btn_Height); chk_plot1D->color_Set(0xFFFFFF, 0x000060); chk_plot2D = new gui_Check("Plot 2D", 524, 352, gui_Const::btn_Width, gui_Const::btn_Height); chk_plot2D->color_Set(0xFFFFFF, 0x000060); chk_plotHisto = new gui_Check("Plot histogram", 524, 384, gui_Const::btn_Width, gui_Const::btn_Height); chk_plotHisto->color_Set(0xFFFFFF, 0x000060); ///////////////////////////// // CANVAS FOR DATA DISPLAY // ///////////////////////////// gCanvas = new gui_Canvas(64, 320, 428, 300); gCanvas2 = new gui_Canvas(64, 644, 600, 250); gCanvas2->Root()->GetCanvas()->Divide(2,1); statCanvas = new gui_Canvas(700, 320, 550, 450); statCanvas->Root()->GetCanvas()->Divide(2,2); // Variables for plot initialization stat_Min = -16000; stat_Max = 16000; // Plots for event display eventPlot = new TH1D("", "", dp_Count*frm_Count, 0, dp_Count*frm_Count); eventMap = new TH2D("", "", col_Count , 0.5, col_Count + 0.5, row_Count*frm_Count, 0.5, row_Count*frm_Count + 0.5); eventMap->SetStats(0); // Histogram and plot for statistics distPlot = new TH1D("", "", 10*(stat_Max - stat_Min+1), stat_Min, stat_Max); // Plots for statistics pedestalPlot = new TH1D("Pedestal","Pedestals", stat_Max - stat_Min + 1, stat_Min, stat_Max); pedestalMap = new TH2D("PedestalMap","Pedestal map", col_Count, 0.5, col_Count + 0.5, row_Count*frm_Count, 0.5, row_Count*frm_Count + 0.5); pedestalMap->SetStats(0); noisePlot = new TH1D("Noise","Noise",200, 0, 20); noiseMap = new TH2D("NoiseMap","Noise map", col_Count, 0.5, col_Count + 0.5, row_Count*frm_Count, 0.5, row_Count*frm_Count + 0.5); noiseMap->SetStats(0); ////////// // Maps // ////////// // Prepare //data_Layer* sig = burst_Raw->frame(0)->layer(0); //data_Layer* ref = burst_Raw->frame(0)->layer(1); //UInt_t col[6] = {0xFF0000, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF}; // Signal //map_Signal = new gui_Map(sig->dp_Front(), sig->dp_col_Count(), sig->dp_row_Count(), 20, 180, 256, 256); //map_Signal->range_Color(col, 6); // Reference //map_Reference = new gui_Map(ref->dp_Front(), ref->dp_col_Count(), ref->dp_row_Count(), 420, 180, 256, 256); //map_Reference->color_Set(0xFFFFFF, 0x000000); //map_Reference->range_Color(col, 6); //map_Reference->range_Max(32); //map_Reference->range_Min(0); } //______________________________________________________________________________ void task_DAQ::gui_Delete() { // Delete all the interface objects dbg_Print("task_DAQ::gui_delete: closing interface objects!", DBG_LVL_FLOW); cool::Gui->delete_All(); } //****************************************************************************** //* * //* GUI Callback target functions * //* * //****************************************************************************** //______________________________________________________________________________ void task_DAQ::btn_run_Evn(const int arg) { // Play button events handler dbg_Print("task_DAQ::btn_run_Evn: run called", DBG_LVL_FLOW); // Acquire if( endFlag ) data_Acquire(); } //______________________________________________________________________________ void task_DAQ::btn_quit_Evn(const int arg) { // Quit button events handler dbg_Print("task_DAQ::btn_quit_Evn: quit called", DBG_LVL_FLOW); // Exits by self-quitting the class cool::Gui->Quit(); } //______________________________________________________________________________ void task_DAQ::btn_FPGA_Evn(const int arg) { // Set FPGA button event handler dbg_Print("task_DAQ::btn_FPGA_evn: button has been pressed!", DBG_LVL_FLOW); set_FPGA(); } //______________________________________________________________________________ void task_DAQ::btn_Comm_Evn(const int arg) { // Set Comm button event handler dbg_Print("task_DAQ::btn_Comm_evn: button has been pressed!", DBG_LVL_FLOW); cool::Comm->Clear(); } //______________________________________________________________________________ void task_DAQ::set_FPGA() { // Set FPGA settings. This function is called at the beginning of each // acquisition run. It can be called also by pressing the button "Set FPGA" // Set trigger mode (software, hardware) trigger_mode = cool::Reg->acq_Mode( cbox_Trigger->cbox_Val() ); if( trigger_mode ){ std::cout << "Hardware trigger: "; }else{ std::cout << "Software trigger\n"; } // Set trigger source trigger_source = cool::Reg->acq_trg_Mode( cbox_TrgSource->cbox_Val() ); if( trigger_mode ){ if( trigger_source ){ std::cout << "external\n"; }else{ std::cout << "internal\n"; } } // Set internal trigger frequency trigger_period = (unsigned int)(10000/num_Trigger->num_Val()); cool::Reg->acq_trg_Period( trigger_period ); if( trigger_mode==1 && trigger_source==0 ){ std::cout << "Internal trigger frequency " << num_Trigger->num_Val() << ", period " << trigger_period << "\n"; } // Set chip driver driver_number = cool::Reg->acq_drv_Sel( cbox_Driver->cbox_Val() ); std::cout << "Chip driver " << driver_number << "\n"; // Set driver delay driver_delay = cool::Reg->acq_drv_Delay( 256*(UInt_t)num_Dly->num_Val() ); std::cout << "Driver delay " << driver_delay << "\n"; // Set number of frames frames_number = cool::Reg->acq_frm_Count( (UInt_t)num_Frm->num_Val() ); std::cout << "Number of frames " << frames_number << "\n"; // Set data source data_source = cool::Reg->acq_data_Mode( cbox_DataSource->cbox_Val() ); // EXTREMELY IMPORTANT!!!! // Re-set data structures depending on chip driver selection and number of frames required if( cbox_AcqMode->cbox_Val() != 2 ) data_Reset(); // Re-set corresponding number of data points switch( driver_number ){ case 2: std::cout << "LDRD2 chip selected\n"; cool::Reg->acq_dp_Count(detector[0]->chip(0)->dp_Count()); break; case 3: std::cout << "SOI2 analog chip selected\n"; cool::Reg->acq_dp_Count(detector[1]->chip(0)->dp_Count()); break; case 4: std::cout << "SOI2 digital chip selected\n"; cool::Reg->acq_dp_Count(detector[2]->chip(0)->dp_Count()); break; case 5: std::cout << "SOI chip analog & digital selected\n"; std::cout << "WARNING!!! Detector geometry not yet implemented!!\n"; break; case 6: std::cout << "TEAM chip selected\n"; cool::Reg->acq_dp_Count(detector[3]->chip(0)->dp_Count()); cool::Reg->chp_tem_Pre((UInt_t)num_TEAM_Pre->num_Val()); std::cout << "TEAM1K pre-burner setting: " << (UInt_t)num_TEAM_Pre->num_Val() << std::endl; break; default: break; } ////////////////// // ADC SETTINGS // ////////////////// // reset counter of active ADC channels iadc = 0; int chn_Mask = 0; // Set ADC input channels for(int i=0; i<5; i++){ if( chk_Adc[i]->chk_Status() == true ){ std::cout << "ADC " << i+1 << " "; chn_Mask = chn_Mask + (int)pow((double)2, i); // count the number of channels which are active iadc++; } } std::cout << "selected\n"; // if the button is checked, activate the channel cool::Reg->acq_chn_Enable(chn_Mask); std::cout << "Channel mask " << chn_Mask << "\n"; // Warn if no ADC channel has been selected if( iadc == 0 ) std::cout << "No ADC channel selected!\n"; // set ADC Clock Divider adc_divider = cool::Reg->adc_clk_Div( (UInt_t)num_Clk->num_Val() ); std::cout << "Clock divider " << adc_divider << "\n"; // set ADC averages adc_averages = cool::Reg->adc_Avgs( (UInt_t)num_Avg->num_Val() ); std::cout << "Number of averages " << adc_averages << "\n"; } //****************************************************************************** //* * //* Data & Detector initialization and destruction * //* * //****************************************************************************** //______________________________________________________________________________ void task_DAQ::data_Setup() { // Set up the data dbg_Print("task_DAQ::data_Setup: defining data objects", DBG_LVL_FLOW); ///////////////////////////////// // LDRD-2 DETECTOR DESCRIPTION // ///////////////////////////////// detector.push_back( new geom_Frame() ); detector[0]->Name("LDRD2"); // Defines the hardware chips // LEFT LDRD2 sector detector[0]->chip(0)->Name("Left"); // LEFT side of LDRD2 detector[0]->chip(0)->col_Count(48); // 48 columns detector[0]->chip(0)->row_Count(96); // 96 rows detector[0]->chip(0)->col_Pitch(20); // Pixel column pitch detector[0]->chip(0)->row_Pitch(20); // Pixel row pitch // RIGHT LDRD2 sector detector[0]->chip_Add(); detector[0]->chip(1)->Name("Right"); // RIGHT side of LDRD2 detector[0]->chip(1)->col_Count(48); // 48 columns detector[0]->chip(1)->row_Count(96); // 96 rows detector[0]->chip(1)->col_Pitch(20); // Pixel column pitch detector[0]->chip(1)->row_Pitch(20); // Pixel row pitch // Defines the logic layers // First logical layer (SIGNAL) detector[0]->layer(0)->Name("Signal"); // The signal (abstracted) layer detector[0]->layer(0)->dp_col_Count(96); // Logical column count detector[0]->layer(0)->dp_row_Count(96); // Logical row count // Second logical layer (REFERENCE) detector[0]->layer_Add(); detector[0]->layer(1)->Name("Reference"); // The reference (abstracted) layer detector[0]->layer(1)->dp_col_Count(96); // 96 columns detector[0]->layer(1)->dp_row_Count(96); // 96 rows // Defines the chip/channel/layer connections // 1st output, left sector signal detector[0]->channel(0)->Name("Left signal"); // Chip/Layer connection detector[0]->channel(0)->chip_Idx(0); // Data are shaped as decribed by chip #0 detector[0]->channel(0)->layer_Idx(0); // Data are directed to layer #0 // 2nd output, left sector reference detector[0]->channel_Add(0, 1); // Chip #0 to layer #1 detector[0]->channel(1)->Name("Left reference"); // 3rd output, right sector signal detector[0]->channel_Add(1, 0); // Chip #1 to layer #0 detector[0]->channel(2)->Name("Right signal"); // 4th output, right sector reference detector[0]->channel_Add(1, 1); // Chip #1 to layer #1 detector[0]->channel(3)->Name("Right reference"); // Sets the chip geometry // Here we set the chip mapping respect to layer mapping. Basically, the // number of pixels contained into one chip is considered as a linear vector, // where for each pixel is stored the location where to place it into the // logical target layer defined by the channel association. // Chip #0 is on the left side of the logical frame, chip #1 (Right) // on the right side but mirrored, i.e. the first data to exit is the // last in the row. geom_Chip* ldrd2_Left = detector[0]->chip(0); geom_Chip* ldrd2_Right = detector[0]->chip(1); UInt_t l_Col = 0, r_Col = 0, lr_Row = 0; for (UInt_t i = 0; i < ldrd2_Left->dp_Count(); i++) { // Left l_Col = i % 48; r_Col = 95 - i % 48; lr_Row = (UInt_t)(i / 48); // Put the address in linear style ldrd2_Left->dp_Value(i, l_Col + lr_Row * 96); ldrd2_Right->dp_Value(i, r_Col + lr_Row * 96); } /////////////////////////////////////// // SOI-2 ANALOG DETECTOR DESCRIPTION // /////////////////////////////////////// detector.push_back( new geom_Frame() ); detector[1]->Name("SOI2 Analog"); // Defines the hardware chips // SOI2 analog sector detector[1]->chip(0)->Name("Analog"); // Analog pixel sector of SOI2 detector[1]->chip(0)->col_Count(40); // 40 columns detector[1]->chip(0)->row_Count(172); // 172 rows detector[1]->chip(0)->col_Pitch(20); // Pixel column pitch detector[1]->chip(0)->row_Pitch(20); // Pixel row pitch // Defines the logic layers // Just one logical layer detector[1]->layer(0)->Name("Signal"); // The signal (abstracted) layer detector[1]->layer(0)->dp_col_Count(40); // Logical column count detector[1]->layer(0)->dp_row_Count(172); // Logical row count // Defines the chip/channel/layer connections // Analog output detector[1]->channel(0)->Name("Analog output"); // Chip/Layer connection detector[1]->channel(0)->chip_Idx(0); // Data are shaped as decribed by chip #0 detector[1]->channel(0)->layer_Idx(0); // Data are directed to layer #0 // Sets the chip geometry // Simple 1-to-1 mapping geom_Chip* soi2_Analog = detector[1]->chip(0); soi2_Analog->dp_all_Range(0, 1); /////////////////////////////////////// // SOI-2 DIGITAL DETECTOR DESCRIPTION // /////////////////////////////////////// detector.push_back( new geom_Frame() ); detector[2]->Name("SOI2 Digital"); // Defines the hardware chips // SOI2 Digital sector detector[2]->chip(0)->Name("Digital"); // Analog pixel sector of SOI2 detector[2]->chip(0)->col_Count(128); // 128 columns detector[2]->chip(0)->row_Count(172); // 172 rows detector[2]->chip(0)->col_Pitch(20); // Pixel column pitch detector[2]->chip(0)->row_Pitch(20); // Pixel row pitch // Defines the logic layers // Just one logical layer detector[2]->layer(0)->Name("Signal"); // The signal (abstracted) layer detector[2]->layer(0)->dp_col_Count(128); // Logical column count detector[2]->layer(0)->dp_row_Count(172); // Logical row count // Defines the chip/channel/layer connections // Digital output detector[2]->channel(0)->Name("Digital output"); // Chip/Layer connection detector[2]->channel(0)->chip_Idx(0); // Data are shaped as decribed by chip #0 detector[2]->channel(0)->layer_Idx(0); // Data are directed to layer #0 // Sets the chip geometry // Simple 1-to-1 mapping geom_Chip* soi2_Digital = detector[2]->chip(0); soi2_Digital->dp_all_Range(0, 1); ///////////////////////////////// // TEAM1K DETECTOR DESCRIPTION // ///////////////////////////////// detector.push_back( new geom_Frame() ); detector[3]->Name("TEAM1K"); // First analog output detector[3]->chip(0)->Name("Analog"); // Analog pixel sector of SOI2 detector[3]->chip(0)->col_Count(64); // 40 columns detector[3]->chip(0)->row_Count(1024); // 172 rows detector[3]->chip(0)->col_Pitch(10); // Pixel column pitch detector[3]->chip(0)->row_Pitch(10); // Pixel row pitch /* // Add three analog outputs for(UInt_t i = 1; i < 4; i++){ detector[3]->chip_Add(); detector[3]->chip(i)->Name("Analog"); // Analog pixel sector of SOI2 detector[3]->chip(i)->col_Count(64); // 40 columns detector[3]->chip(i)->row_Count(1024); // 172 rows detector[3]->chip(i)->col_Pitch(10); // Pixel column pitch detector[3]->chip(i)->row_Pitch(10); // Pixel row pitch } */ // Define one logic layer detector[3]->layer(0)->Name("Signal"); // The signal (abstracted) layer detector[3]->layer(0)->dp_col_Count(64); // Logical column count (64 columns * 4 outputs) detector[3]->layer(0)->dp_row_Count(1024); // Logical row count // Chip/channel/layer connections detector[3]->channel(0)->Name("Analog output"); // Chip/Layer connection detector[3]->channel(0)->chip_Idx(0); // Data are shaped as decribed by chip #0 detector[3]->channel(0)->layer_Idx(0); // Data are directed to layer #0 /* for(UInt_t i = 1; i < 4; i++){ detector[3]->channel_Add(i, 0); // Add chip i to layer 0 detector[3]->channel(i)->Name("Analog output"); } */ // Sets the chip geometry geom_Chip* team_Analog = detector[3]->chip(0); team_Analog->dp_all_Range(0, 1); /* geom_Chip* team_Analog[4]; for(UInt_t i = 0; i < 4; i++){ team_Analog[i] = detector[3]->chip(i); team_Analog[i]->dp_all_Range(i*65536, 1); } */ ////////////////////////// // DATA OBJECT CREATION // ////////////////////////// // DEFAULT: LDRD2 detector, this will change depending on driver selection burst_Raw = new data_Burst(detector[0], 1); burst_Image = new data_Burst(detector[0], 1); burst_Pedestal = new data_Burst(detector[0], 1); burst_Pedestal2 = new data_Burst(detector[0], 1); burst_Noise = new data_Burst(detector[0], 1); burst_Mask = new data_Burst(detector[0], 1); common_Mode.push_back(0); common_ModeNoise.push_back(0); // Initialize pedestal available flag and statistics frames // It's good practice to re-do it after any data structures reinitialization pedFlag = 0; burst_Pedestal->frame(0)->dp_all_Set(0); burst_Pedestal2->frame(0)->dp_all_Set(0); burst_Noise->frame(0)->dp_all_Set(0); burst_Mask->frame(0)->dp_all_Set(0); // Variables for plot rescaling frm_Count = burst_Raw->frame_Count(); col_Count = burst_Raw->frame(0)->layer(0)->dp_col_Count(); row_Count = frm_Count * burst_Raw->frame(0)->layer(0)->dp_row_Count(); dp_Count = burst_Raw->frame(0)->layer(0)->dp_Count(); } //______________________________________________________________________________ void task_DAQ::data_Delete() { // Delete the data dbg_Print("task_DAQ::data_Delete: releasing data objects", DBG_LVL_FLOW); // Data delete burst_Raw; delete burst_Image; delete burst_Pedestal; delete burst_Pedestal2; delete burst_Noise; delete burst_Mask; // Detectors for(UInt_t i=0; i < detector.size(); i++){ delete detector[i]; } } //****************************************************************************** //* * //* USB Communication setup * //* * //****************************************************************************** //______________________________________________________________________________ void task_DAQ::comm_Setup() { // Comm setup dbg_Print("task_DAQ::comm_Setup: setting up communication", DBG_LVL_FLOW); // Open USB communication cool::Comm->Open(); if (!cool::Comm->isOpen()) { std::cout << "You need to open the communication before!\n"; return; } // Set the ADC registers (default values, to be overridden by user selected ones std::cout << "Setting the ADCs...\n"; cool::Reg->adc_clk_Chn(0); // Reference ADC clock cool::Reg->adc_clk_Div(1); // Clock divider cool::Reg->adc_Avgs(0); // No averages // Set the data trigger registers (default values) std::cout << "Setting the data trigger...\n"; cool::Reg->data_trg_Mode(0); // External triggering, i.e. no data trigger cool::Reg->data_trg_Count(burst_Raw->dp_Count()); // Number of data points cool::Reg->data_trg_Delay(0); // Trigger delay cool::Reg->data_trg_Slope(0); // Positive slope cool::Reg->data_trg_Chn(0); // Channel 0 cool::Reg->data_trg_Thr(9000); // Trigger threshold // Set the acquisition mode (default values, to be overridden by user selected ones) std::cout << "Setting the acquisition mode...\n"; cool::Reg->acq_Mode(0); // Software triggered cool::Reg->acq_chn_Enable(15); // Enables 4 channels cool::Reg->acq_drv_Sel(2); // Set the driver cool::Reg->acq_drv_Delay(0); // No driving delay cool::Reg->acq_data_Mode(0); // ADC mode (0), Fake data mode (1) cool::Reg->acq_frm_Count(burst_Raw->frame_Count()); // 1 Frame data count cool::Reg->acq_dp_Count(detector[0]->chip(0)->dp_Count()); // Total data count // Set data triggering mode (default values) std::cout << "Setting the acquisition triggering mode...\n"; cool::Reg->acq_trg_Mode(0); // Internal trigger cool::Reg->acq_trg_Period(1000); // 10 Hz trigger period } //****************************************************************************** //* * //* Data acquisition functions * //* * //****************************************************************************** //______________________________________________________________________________ void task_DAQ::data_Reset() { // Refit data structures depending on user selection of chip dbg_Print("task_DAQ::data_Reset: resetting data structures", DBG_LVL_FLOW); std::cout << "Driver #" << driver_number << " selected\n"; // Refit for number of frames std::cout << "Nb. of frames " << frames_number << std::endl; burst_Raw->frame_Count(frames_number); burst_Image->frame_Count(frames_number); burst_Pedestal->frame_Count(frames_number); burst_Pedestal2->frame_Count(frames_number); burst_Noise->frame_Count(frames_number); burst_Mask->frame_Count(frames_number); // Clean up common mode vectors common_Mode.clear(); common_ModeNoise.clear(); // Re-initialize common mode vectors for(UInt_t f = 0; f < burst_Image->frame_Count(); f++){ common_Mode.push_back(0); common_ModeNoise.push_back(0); } // Refit data structures depending on chip selection switch( driver_number ){ case 2: burst_Raw->frame_Fit(detector[0], frames_number); burst_Image->frame_Fit(detector[0], frames_number); burst_Pedestal->frame_Fit(detector[0], frames_number); burst_Pedestal2->frame_Fit(detector[0], frames_number); burst_Noise->frame_Fit(detector[0], frames_number); burst_Mask->frame_Fit(detector[0], frames_number); break; case 3: burst_Raw->frame_Fit(detector[1], frames_number); burst_Image->frame_Fit(detector[1], frames_number); burst_Pedestal->frame_Fit(detector[1], frames_number); burst_Pedestal2->frame_Fit(detector[1], frames_number); burst_Noise->frame_Fit(detector[1], frames_number); burst_Mask->frame_Fit(detector[1], frames_number); break; case 4: burst_Raw->frame_Fit(detector[2], frames_number); burst_Image->frame_Fit(detector[2], frames_number); burst_Pedestal->frame_Fit(detector[2], frames_number); burst_Pedestal2->frame_Fit(detector[2], frames_number); burst_Noise->frame_Fit(detector[2], frames_number); burst_Mask->frame_Fit(detector[2], frames_number); break; case 5: std::cout << "Under construction!\n"; case 6: burst_Raw->frame_Fit(detector[3], frames_number); burst_Image->frame_Fit(detector[3], frames_number); burst_Pedestal->frame_Fit(detector[3], frames_number); burst_Pedestal2->frame_Fit(detector[3], frames_number); burst_Noise->frame_Fit(detector[3], frames_number); burst_Mask->frame_Fit(detector[3], frames_number); break; default: // Do nothing break; } // Reset variables for plot rescaling frm_Count = burst_Raw->frame_Count(); col_Count = burst_Raw->frame(0)->layer(0)->dp_col_Count(); row_Count = burst_Raw->frame_Count()*burst_Raw->frame(0)->layer(0)->dp_row_Count(); dp_Count = burst_Raw->frame(0)->layer(0)->dp_Count(); } //______________________________________________________________________________ void task_DAQ::data_Acquire() { // MAIN DATA ACQUISITION FUNCTION dbg_Print("task_DAQ::data_Acquire: retrieving data from DAQ", DBG_LVL_FLOW); // Change button to run mode btn_Run->btn_Status( true ); btn_Run->backColor(0xFF0000); btn_Run->Text("Stop"); endFlag = 0; // Reset FPGA settings set_FPGA(); // Reset statistics array stats_Reset(); plots_Reset(); // Increase run number if write file and auto run # options are checked if( chk_Write->chk_Status() == true && chk_AutoNumber->chk_Status() == true ){ // Get current run number run_Number = (UInt_t)num_RunNumber->num_Val(); // Increase run number num_RunNumber->num_Val( run_Number + 1 ); } // If write file option checked, setup ntuple for data storage if( chk_Write->chk_Status() == true ) file_Setup(); // Date timestamp date = time ( NULL ); std::cout << "Acquisition started on " << ctime( &date ) << std::endl; tdate = (long)date; // Acquire as many burst as required by the user burst_Count = (UInt_t)num_Evts->num_Val(); std::cout << "Number of events " << burst_Count << "\n"; ////////////////////////// // LOOP OVER THE EVENTS // ////////////////////////// for (UInt_t i = 0 ; i < burst_Count; i++) { // Raise end flag if stop button is pressed if( btn_Run->btn_Status() == false ) endFlag = 1; if( endFlag ){ std::cout << "Stopping acquisition after " << i << " events\n"; break; } // Reset event display plots eventPlot->Reset(); eventMap->Reset(); event_Number = i + 1; std::cout << "\nEvent " << event_Number << std::endl; num_CurrEvt->num_Val( event_Number ); // shows current event number tstamp = 0; nspill = 0; ///////////////////////////// // ACQUISITION AND STORAGE // ///////////////////////////// // Acquire data from the firmware cool::Comm->burst_Read(burst_Raw, true, 10000); // Cast Burst (for the moment frame by frame) for(int f = 0; f< burst_Raw->frame_Count(); f++){ *(burst_Image->frame(f)) = *(burst_Raw->frame(f)); } ///////////////////// // DATA PROCESSING // ///////////////////// // Invert data //data_Invert(); // If CDS option checked, calculate CDS (add condition on number of frames!) if( chk_CDS->chk_Status() == true ) data_CDS(); // If pedestal subtract mode, subtract pedestals if( cbox_AcqMode->cbox_Val() == 2 ) pedestal_Subtract(); // Calculate common mode for the current event if( cbox_AcqMode->cbox_Val() == 1 || cbox_AcqMode->cbox_Val() == 2 ) data_CMode(); // Show data data_Display(); // If write data option selected, save data in data tree if( chk_Write->chk_Status() == true ) file_Fill(); // If pedestal run, update pedestal values if( cbox_AcqMode->cbox_Val() == 1 ) stats_Update(); // Raise end flag at the end of events if( i == burst_Count - 1 ){ std::cout << "\nEnd of " << burst_Count << " events\n"; endFlag = 1; btn_Run->btn_Status( false ); } } // End run over the events ///////////////////////// // PEDESTALS AND NOISE // ///////////////////////// //Calculate pedestals and noise values, in case, and fill corresponding plots if( cbox_AcqMode->cbox_Val() == 1 ){ stats_Calculate(); stats_Display(); // raise flag that pedestals are available pedFlag = 1; } //////////////////////////////////// // WRITE DATA TO OUTPUT ROOT FILE // //////////////////////////////////// if( chk_Write->chk_Status() == true ){ data_Write(); // close output file file_Close(); } // Wait mode std::cout << "Entering wait mode...\n"; btn_Run->backColor(gui_CoolButton::kc_Green); btn_Run->Text("GO"); // Setup maps //map_Signal->range_Auto(true); //map_Reference->range_Auto(true); } //______________________________________________________________________________ void task_DAQ::stats_Reset() { // Reset statistics arrays dbg_Print("task_DAQ::stats_Reset(): resetting statistics arrays", DBG_LVL_FLOW); if( cbox_AcqMode->cbox_Val() == 1 ){ std::cout << "Resetting pedestals\n"; pedFlag = 0; for(UInt_t i = 0; i < burst_Raw->frame_Count(); i++){ burst_Pedestal->frame(i)->dp_all_Set(0); burst_Pedestal2->frame(i)->dp_all_Set(0); burst_Noise->frame(i)->dp_all_Set(0); burst_Mask->frame(i)->dp_all_Set(0); } }else{ } } //______________________________________________________________________________ void task_DAQ::plots_Reset() { // Reset event display (always) and statistics plots (if in pedestal run mode dbg_Print("task_DAQ::stats_Reset(): resetting plots", DBG_LVL_FLOW); eventPlot->Reset(); eventMap->Reset(); distPlot->Reset(); // (Re)scale plots eventPlot->SetBins(dp_Count*frm_Count, 0, dp_Count*frm_Count); eventMap->SetBins(col_Count , 0.5, col_Count + 0.5, row_Count, 0.5, row_Count + 0.5); if( cbox_AcqMode->cbox_Val() == 1 ){ pedestalPlot->Reset(); noisePlot->Reset(); pedestalMap->Reset(); noiseMap->Reset(); pedestalMap->SetBins(col_Count, 0.5, col_Count + 0.5, row_Count, 0.5, row_Count + 0.5); noiseMap->SetBins(col_Count, 0.5, col_Count + 0.5, row_Count, 0.5, row_Count + 0.5); } } //______________________________________________________________________________ void task_DAQ::data_Invert() { // Invert analog data from DAQ, or offset digital data dbg_Print("task_DAQ::data_Invert: inverting data", DBG_LVL_FLOW); for(UInt_t i = 0; i < burst_Raw->frame_Count(); i++){ if( data_source == 0 ){ //Invert analog data *burst_Image->frame(i) *= -1; *burst_Image->frame(i) += 16384; }else if( data_source == 1 ){ // Dummy data, do nothing }else if( data_source == 2 ){ // Digital data: just add a level, so that S/N in data analysis is always high *burst_Image->frame(i) *= 1000; }//end if with conditions on data source }// end loop over frames in the burst } //______________________________________________________________________________ void task_DAQ::data_CDS() { // Calculate CDS dbg_Print("task_DAQ::data_CDS: calculating CDS", DBG_LVL_FLOW); for(UInt_t f = 1; f < burst_Raw->frame_Count(); f++){ *burst_Image->frame(f) -= *burst_Image->frame(f - 1); *burst_Image->frame(f - 1) = *burst_Image->frame(f); } } //______________________________________________________________________________ void task_DAQ::pedestal_Subtract() { // Subtract pedestals dbg_Print("task_DAQ::pedestal_Subtract: subtracting pedestals", DBG_LVL_FLOW); for(UInt_t f = 0; f < burst_Raw->frame_Count(); f++){ *burst_Image->frame(f) -= *burst_Pedestal->frame(f); } } //______________________________________________________________________________ void task_DAQ::data_CMode() { // Calculate common mode dbg_Print("task_DAQ::data_CMode: calculating common mode", DBG_LVL_FLOW); Double_t cmode, cmn; for(UInt_t f = 0; f < common_Mode.size(); f++){ common_Mode.at(f) = 0; common_ModeNoise.at(f) = 0; burst_Image->frame(f)->dp_all_Stat(cmode, cmn); common_Mode.at(f) = cmode; common_ModeNoise.at(f) = cmn; std::cout << "Common mode level " << common_Mode.at(f) << "\n"; } } //______________________________________________________________________________ void task_DAQ::data_Display() { // Show event display plots dbg_Print("task_DAQ::data_Display: showing event display plots", DBG_LVL_FLOW); UInt_t pix_Number = burst_Image->frame(0)->layer(0)->dp_Count(); UInt_t row_Offset = burst_Image->frame(0)->layer(0)->dp_row_Count(); for(UInt_t f = 0; f < burst_Image->frame_Count(); f++){ for (UInt_t i = 0; i< pix_Number; i++) { Double_t img_Val = burst_Image->frame(f)->layer(0)->dp_Value(i); UInt_t img_Row = burst_Image->frame(f)->layer(0)->dp_Row(i); UInt_t img_Col = burst_Image->frame(f)->layer(0)->dp_Col(i); Double_t noi_Val = burst_Noise->frame(f)->layer(0)->dp_Value(i); UShort_t msk_Val = burst_Mask->frame(f)->layer(0)->dp_Value(i); // Set range on plots if( img_Val > stat_Max ) stat_Max = (UInt_t)img_Val; if( img_Val < stat_Min ) stat_Min = (UInt_t)img_Val; // Set range on plots and fill event display plots if( cbox_AcqMode->cbox_Val() == 0 || cbox_AcqMode->cbox_Val() == 1 ){ eventPlot->SetBinContent(i + f*pix_Number + 1, img_Val); eventMap->SetBinContent(burst_Image->frame(f)->layer(0)->dp_Col(i) + 1, img_Row + f*row_Offset + 1, img_Val); }else{ eventPlot->SetBinContent(i + f*pix_Number + 1, img_Val - common_Mode[f]); eventMap->SetBinContent(burst_Image->frame(f)->layer(0)->dp_Col(i) + 1, img_Row + f*row_Offset + 1, img_Val - common_Mode[f]); // Online processing of data for distPlot if( noi_Val>0 && noi_Val<10 && (img_Val - common_Mode[f])/(noi_Val)>6 ){ // WARNING!!! Check usage of dp_Value() burst_Mask->frame(f)->layer(0)->dp_Value(i, msk_Val + 1); if( msk_Val<25 && event_Number>100 ) distPlot->Fill(img_Val - common_Mode[f]); } } } // End loop over array entries } // End loop over frames // DRAW the plots!!! if( chk_plot1D->chk_Status() == true ){ gCanvas2->Root()->GetCanvas()->cd(1); eventPlot->Draw(); } if( chk_plot2D->chk_Status() == true ){ gCanvas->Root()->GetCanvas()->cd(); eventMap->Draw("COLZ"); } if( chk_plotHisto->chk_Status() == true ){ gCanvas2->Root()->GetCanvas()->cd(2); distPlot->Draw(); } // Update canvas gCanvas->Root()->GetCanvas()->Update(); gCanvas2->Root()->GetCanvas()->Update(); } //______________________________________________________________________________ void task_DAQ::data_Write() { // Write data to output file dbg_Print("task_DAQ::data_Write: writing data to output file", DBG_LVL_FLOW); // Write info in the header header[0] = 7; // ChipId header[1] = (UInt_t)num_RunNumber->num_Val(); // Run number header[2] = (UInt_t)num_Frm->num_Val(); // Number of frames header[3] = burst_Raw->frame(0)->layer(0)->dp_row_Count(); header[4] = burst_Raw->frame(0)->layer(0)->dp_col_Count(); // header[5]: CDS data? if( chk_CDS->chk_Status() == true ){ // CDS = 1, NO CDS = 0 header[5] = 1; }else{ header[5] = 0; } // header[6]: ped subtracted? if(pedFlag){ header[6] = 1; // 1 if pedestal subtracted data, 0 otherwise }else{ header[6] = 0; } // header[7,8]: first row and column header[7] = 0; // First row header[8] = 0; // First column // header[9]: data source if( cbox_DataSource->cbox_Val() == 0 ){ header[9] = 0; // ADC data }else if( cbox_DataSource->cbox_Val() == 2){ header[9] = 0; // Digital data }else{ header[9] = 0; } // header[10]: date, which is long and is split over two integers header[10] = tdate; for(int h=12; h<50; h++){ header[h] = 0; } // Make physical copy of pedestals and noise arrays for(UInt_t f = 0; f < burst_Pedestal->frame_Count(); f++){ for(int i = 0; i < NPixels ; i++ ){ ped[i] = burst_Pedestal->frame(f)->layer(0)->dp_Value(i); noi[i] = burst_Noise->frame(f)->layer(0)->dp_Value(i); } } // Fill the header tree std::cout << "Filling headertree...\n"; headertree->Fill(); // Write header tree std::cout << "Writing headertree...\n"; headertree->Write(); headertree->Print(); // Write data tree std::cout << "Writing datatree...\n"; datatree->Write(); datatree->Print(); // Write plots pedestalPlot->Write(); pedestalMap->Write(); noisePlot->Write(); noiseMap->Write(); } //______________________________________________________________________________ void task_DAQ::stats_Update() { // Update statistics arrays dbg_Print("task_DAQ::stats_Update: updating statistics arrays", DBG_LVL_FLOW); for(UInt_t f = 0; f < burst_Pedestal->frame_Count(); f++){ *(burst_Pedestal->frame(f)) += *(burst_Image->frame(f)); *(burst_Pedestal2->frame(f)) += burst_Image->frame(f)->dp_all_Pow(2); } } //______________________________________________________________________________ void task_DAQ::stats_Calculate() { // Calculate pedestal and noise values dbg_Print("task_DAQ::stats_Calculate: calculating pedestals and noise", DBG_LVL_FLOW); for(UInt_t f = 0; f < burst_Pedestal->frame_Count(); f++){ Double_t *pedestal; Double_t *pedestal2; Double_t *noise; pedestal = burst_Pedestal->frame(f)->layer(0)->dp_Front(); pedestal2 = burst_Pedestal2->frame(f)->layer(0)->dp_Front(); noise = burst_Noise->frame(f)->layer(0)->dp_Front(); for(int i = 0; i frame(f)->layer(0)->dp_Count() ; i++ ){ pedestal[i] /= burst_Count; pedestal2[i] /= burst_Count; noise[i] = sqrt( pedestal2[i] - pedestal[i]*pedestal[i]); } /* // Calculate and *(burst_Pedestal->frame(f)) /= burst_Count; *(burst_Pedestal2->frame(f)) /= burst_Count; // Temporary container data_Frame* frame_Temp = new data_Frame; *frame_Temp = *(burst_Pedestal->frame(f)); frame_Temp->dp_all_Pow(2); *(burst_Pedestal2->frame(f)) -= *frame_Temp; *(burst_Noise->frame(f)) = *(burst_Pedestal2->frame(f)); burst_Noise->frame(0)->dp_all_Sqr(); delete frame_Temp; */ } } //______________________________________________________________________________ void task_DAQ::stats_Display() { // Display pedestals and noise maps/distributions dbg_Print("task_DAQ::stats_Display: displaying pedestals and noise", DBG_LVL_FLOW); UInt_t row_Offset = burst_Pedestal->frame(0)->layer(0)->dp_row_Count(); // Fill statistics plots for(UInt_t f = 0; f < burst_Pedestal->frame_Count(); f++){ for (UInt_t i = 0; i< burst_Pedestal->frame(0)->layer(0)->dp_Count(); i++) { Double_t ped_Val = burst_Pedestal->frame(f)->layer(0)->dp_Value(i); Double_t noi_Val = burst_Noise->frame(f)->layer(0)->dp_Value(i); Int_t ped_Row = burst_Pedestal->frame(f)->layer(0)->dp_Row(i); Int_t ped_Col = burst_Pedestal->frame(f)->layer(0)->dp_Col(i); pedestalPlot->Fill(ped_Val); noisePlot->Fill(noi_Val); pedestalMap->SetBinContent(ped_Col + 1 , ped_Row + f*row_Offset + 1, ped_Val); noiseMap->SetBinContent(ped_Col + 1, ped_Row + f*row_Offset + 1, noi_Val); } } // Draw statistics plots statCanvas->Root()->GetCanvas()->cd(1); pedestalPlot->Draw(); statCanvas->Root()->GetCanvas()->cd(2); pedestalMap->Draw("COLZ"); statCanvas->Root()->GetCanvas()->cd(3); noisePlot->Draw(); statCanvas->Root()->GetCanvas()->cd(4); noiseMap->Draw("COLZ"); // Update the canvas with statistics plots statCanvas->Root()->GetCanvas()->Update(); } //______________________________________________________________________________ void task_DAQ::file_Setup() { // Setup output ROOT file dbg_Print("task_DAQ::file_Setup: setting up output ROOT file", DBG_LVL_FLOW); NPixels = (burst_Raw->frame_Count())*(burst_Raw->frame(0)->layer(0)->dp_Count()); std::cout << "NPixels " << NPixels << std::endl; img_data = new Double_t[NPixels]; ped = new Double_t[NPixels]; noi = new Double_t[NPixels]; tstamp = 0; nspill = 0; filepath = txt_File->txt_Val(); sprintf(filename,"%s_run%u.root", filepath, (UInt_t)num_RunNumber->num_Val()); std::cout << "Save in file " << filename << "\n"; datafile = new TFile(filename,"RECREATE"); datafile->SetCompressionLevel((UInt_t)num_Compression->num_Val()); std::cout << "File compression level set to " << (UInt_t)num_Compression->num_Val() << "\n"; headertree = new TTree("headertree", "Header tree"); headertree->Branch("NPixels",&NPixels,"NPixels/I"); headertree->Branch("Header", &header, "header[50]/I"); headertree->Branch("Pedestal", (void*)ped, "ped[NPixels]/D"); headertree->Branch("Noise", (void*)noi, "noi[NPixels]/D"); headertree->SetDirectory(datafile); datatree = new TTree("datatree","Data tree"); datatree->Branch("NPixels",&NPixels,"NPixels/I"); datatree->Branch("Data",(void*)img_data,"img_data[NPixels]/D"); datatree->Branch("Event",&nevent,"nevent/I"); datatree->Branch("Timestamp",&tstamp,"tstamp/I"); datatree->Branch("Spill",&nspill,"nspill/I"); datatree->SetDirectory(datafile); } //______________________________________________________________________________ void task_DAQ::file_Fill() { // Fill ROOT file dbg_Print("task_DAQ::file_Fill: filling ROOT file", DBG_LVL_FLOW); // Make physical copy of the image_Array for( int f = 0; f < burst_Image->frame_Count(); f++ ){ for(int i = 0; i < NPixels ; i++ ) img_data[i + f*NPixels] = burst_Image->frame(f)->layer(0)->dp_Value(i); } nevent = event_Number; tstamp = 0; nspill = 0; // Fill the ntuple datatree->Fill(); } //______________________________________________________________________________ void task_DAQ::file_Close() { // Close output ROOT file dbg_Print("task_DAQ::file_Close: closing output ROOT file", DBG_LVL_FLOW); datafile->Close(); }