From fbb94d6611e65629b41f347fb14c254acc48d692 Mon Sep 17 00:00:00 2001 From: "Hadaq@CountingHouse" Date: Mon, 28 Oct 2013 18:29:45 +0100 Subject: [PATCH] added eventbuilder control, cts config and cts monitor --- control/ctsmon/mon_cts.pl | 2697 +++++++++++++++++ control/ctsmon/tables/.hsh | Bin 0 -> 19079 bytes .../tables/2012-03 RICH Pedestal Mode.hsh | Bin 0 -> 17632 bytes control/ctsmon/tables/2012-03-27_cosmics.hsh | Bin 0 -> 17654 bytes control/ctsmon/tables/2012-04 Beam 2.hsh | Bin 0 -> 19286 bytes control/ctsmon/tables/2012-04 Beam 3.hsh | Bin 0 -> 19286 bytes control/ctsmon/tables/2012-04 Beam 4.hsh | Bin 0 -> 19286 bytes control/ctsmon/tables/2012-04 Beam 5.hsh | Bin 0 -> 18999 bytes control/ctsmon/tables/2012-04 Beam 6.hsh | Bin 0 -> 19286 bytes control/ctsmon/tables/2012-04 Beam.hsh | Bin 0 -> 17799 bytes control/ctsmon/tables/2012-04 beam 10.hsh | Bin 0 -> 19286 bytes control/ctsmon/tables/2012-04 beam 11.hsh | Bin 0 -> 19286 bytes control/ctsmon/tables/2012-04 beam 12.hsh | Bin 0 -> 19286 bytes control/ctsmon/tables/2012-04 beam 8.hsh | Bin 0 -> 19286 bytes control/ctsmon/tables/2012-04 beam9.hsh | Bin 0 -> 19286 bytes control/ctsmon/tables/2012-04-baem 7.hsh | Bin 0 -> 19286 bytes control/ctsmon/tables/2012-10 beam-2.hsh | Bin 0 -> 19306 bytes control/ctsmon/tables/2012-10 beam-3.hsh | Bin 0 -> 19306 bytes .../ctsmon/tables/2012-10-25_test_mdc_a.hsh | Bin 0 -> 19292 bytes .../ctsmon/tables/2012_10-25_test_mdc_a.hsh | Bin 0 -> 19292 bytes control/ctsmon/tables/212-10 beam-1.hsh | Bin 0 -> 19300 bytes control/ctsmon/tables/BEAM5.hsh | Bin 0 -> 18999 bytes control/ctsmon/tables/FW cosmic.hsh | Bin 0 -> 19005 bytes .../ctsmon/tables/test_beam_25102012_a.hsh | Bin 0 -> 18995 bytes cts/.gitignore | 1 + cts/addresses_cts.db | 4 + cts/configure_blr.script | 3 + cts/cts_settings.trbcmd | 25 + cts/serials_cts.db | 8 + cts/startup.script | 27 + cts/trb.db | 4 + evtbuild/default_s.tcl | 0 evtbuild/eb.conf | 1 + evtbuild/eb.conf.oct12 | 210 ++ evtbuild/eb_logmonitor.pl | 297 ++ evtbuild/scan_active_ports.pl | 54 + evtbuild/start_daqmon_ioc.pl | 270 ++ evtbuild/start_eb.pl | 581 ++++ evtbuild/start_eb_gbe.pl | 1312 ++++++++ evtbuild/start_eb_gbe.sh | 1 + evtbuild/start_eb_iocs.sh | 7 + evtbuild/start_rdosoft.pl | 235 ++ 42 files changed, 5737 insertions(+) create mode 100755 control/ctsmon/mon_cts.pl create mode 100644 control/ctsmon/tables/.hsh create mode 100644 control/ctsmon/tables/2012-03 RICH Pedestal Mode.hsh create mode 100644 control/ctsmon/tables/2012-03-27_cosmics.hsh create mode 100644 control/ctsmon/tables/2012-04 Beam 2.hsh create mode 100644 control/ctsmon/tables/2012-04 Beam 3.hsh create mode 100644 control/ctsmon/tables/2012-04 Beam 4.hsh create mode 100644 control/ctsmon/tables/2012-04 Beam 5.hsh create mode 100644 control/ctsmon/tables/2012-04 Beam 6.hsh create mode 100644 control/ctsmon/tables/2012-04 Beam.hsh create mode 100644 control/ctsmon/tables/2012-04 beam 10.hsh create mode 100644 control/ctsmon/tables/2012-04 beam 11.hsh create mode 100644 control/ctsmon/tables/2012-04 beam 12.hsh create mode 100644 control/ctsmon/tables/2012-04 beam 8.hsh create mode 100644 control/ctsmon/tables/2012-04 beam9.hsh create mode 100644 control/ctsmon/tables/2012-04-baem 7.hsh create mode 100644 control/ctsmon/tables/2012-10 beam-2.hsh create mode 100644 control/ctsmon/tables/2012-10 beam-3.hsh create mode 100644 control/ctsmon/tables/2012-10-25_test_mdc_a.hsh create mode 100644 control/ctsmon/tables/2012_10-25_test_mdc_a.hsh create mode 100644 control/ctsmon/tables/212-10 beam-1.hsh create mode 100644 control/ctsmon/tables/BEAM5.hsh create mode 100644 control/ctsmon/tables/FW cosmic.hsh create mode 100644 control/ctsmon/tables/test_beam_25102012_a.hsh create mode 100644 cts/.gitignore create mode 100644 cts/addresses_cts.db create mode 100644 cts/configure_blr.script create mode 100644 cts/cts_settings.trbcmd create mode 100644 cts/serials_cts.db create mode 100644 cts/startup.script create mode 100644 cts/trb.db create mode 100644 evtbuild/default_s.tcl create mode 120000 evtbuild/eb.conf create mode 100644 evtbuild/eb.conf.oct12 create mode 100755 evtbuild/eb_logmonitor.pl create mode 100755 evtbuild/scan_active_ports.pl create mode 100755 evtbuild/start_daqmon_ioc.pl create mode 100755 evtbuild/start_eb.pl create mode 100755 evtbuild/start_eb_gbe.pl create mode 100755 evtbuild/start_eb_gbe.sh create mode 100755 evtbuild/start_eb_iocs.sh create mode 100755 evtbuild/start_rdosoft.pl diff --git a/control/ctsmon/mon_cts.pl b/control/ctsmon/mon_cts.pl new file mode 100755 index 0000000..07ea2c0 --- /dev/null +++ b/control/ctsmon/mon_cts.pl @@ -0,0 +1,2697 @@ +#!/usr/bin/perl -w + +use English; +use strict; +use Getopt::Long; +use Data::Dumper; +use List::MoreUtils qw(any apply); +use Scalar::Util qw(reftype); +use FileHandle; +use IO::Socket; +use Net::Ping; +use Storable; +use Time::HiRes; +use HADES::TrbNet; + + +use constant TRUE => 1; +use constant FALSE => 0; + +my $glob_trbnet_connected = FALSE; + +use Gtk2 '-init'; + +Gtk2::Rc->parse_string(<<__); +style "normal" { + font_name = "sans 7" + bg[NORMAL] = "#FFFFFF" + fg[NORMAL] = "#000000" +} + +style "yellow" { + font_name = "sans 7" + fg[NORMAL] = "#808000" +} + +style "green" { + font_name = "sans 7" + fg[NORMAL] = "#008000" +} + +style "red" { + font_name = "sans 7" + fg[NORMAL] = "#a00000" +} + +style "blue" { + font_name = "sans 7" + fg[NORMAL] = "#0000ff" +} + +widget "*" style "normal" +widget "*yellow*" style "yellow" +widget "*green*" style "green" +widget "*red*" style "red" +widget "*blue*" style "blue" +__ + + +Gtk2->init; + +my @layout1 = ( + {'INPUT_EN' => ['Start','Veto','TOF','RPC','PT']}, + {'DLY_LARGE' => ['Start','Veto','TOF','RPC','PT']}, + {'DLY_SMALL' => ['Start','Veto','TOF','RPC','PT']}, + {'SCALER_DLY' => ['Start','Veto','TOF','RPC','PT']}, + {'WIDTH' => [ '-', '-','TOF','RPC','PT']}, + {'WIDTH_SMALL' => ['Start','-','-','-','-']}, + {' ' => ['-','-','-','-','-']}, + {'DSC' => ['Start','Veto','Mult','-','PT']}, + + {'WIDTH_M' => [ '-', '-','Mult','-','-']}, + {'SCALER_DSC' => ['Start','Veto','Mult','-','PT']}, + {'GATING_DIS' => ['-' ,'-' ,'Mult','-','PT']}, + {'SCALER_C' => ['-' ,'-' ,'Mult','-','PT']}, + {'OUT_EN' => ['Start','Veto','Mult','-','PT']}, + {'SCALER_OUT' => ['Start','Veto','Mult','-','PT']} + ); + +my @layout2 = ( + {'CAL_TRIG' => ['CAL', 'TRIG']}, + {'BUSY' => ['BUSY_BOX']}, + {'BEAM' => ['BEAM_PROFILE']} + ); + +my @layout_set = ( + 'INPUT_EN', + 'DLY_LARGE', + 'DLY_SMALL', + 'WIDTH', + 'WIDTH_SMALL', + 'DSC', + 'WIDTH_M', + 'GATING_DIS', + 'OUT_EN' + ); + +my @layout2_set = ('CAL_TRIG', + 'BEAM'); +my @layout_cal_set = (); # unticoinsidence +my @layout_trig_set = ('TRIG_RATE'); # unticoinsidence +my @layout_beam_set = (); # unticoinsidence + +my %setup_names = ( 'INPUT_EN' => {'first' => 'INPUT', 'second' => 'ENABLE'}, + 'DLY_LARGE' => {'first' => 'DELAY', 'second' => 'LARGE'}, + 'DLY_SMALL' => {'first' => 'DELAY', 'second' => 'SMALL'}, + 'SCALER_DLY' => {'first' => 'SCALER', 'second' => 'DELAY'}, + 'WIDTH' => {'first' => 'WIDTH', 'second' => ''}, + 'WIDTH_SMALL' => {'first' => 'WIDTH', 'second' => 'SMALL'}, + 'DSC' => {'first' => 'DSC', 'second' => ''}, + 'WIDTH_M' => {'first' => 'WIDTH', 'second' => 'M'}, + 'SCALER_DSC' => {'first' => 'SCALER', 'second' => 'DSC'}, + 'GATING_DIS' => {'first' => 'GAITING', 'second' => 'DISABLE'}, + 'SCALER_C' => {'first' => 'SCALER', 'second' => 'C'}, + 'OUT_EN' => {'first' => 'OUTPUT', 'second' => 'ENABLE'}, + 'SCALER_OUT' => {'first' => 'SCALER', 'second' => 'OUT'}, + ); + +my %setup = ( +'INPUT_EN' => + { 'Start' => + { 'Start0' => { 'addr' => 'C3', 'mask' => '0' }, + 'Start1' => { 'addr' => 'C3', 'mask' => '1' }, + 'Start2' => { 'addr' => 'C3', 'mask' => '2' }, + 'Start3' => { 'addr' => 'C3', 'mask' => '3' }, + 'Start4' => { 'addr' => 'C3', 'mask' => '4' }, + 'Start5' => { 'addr' => 'C3', 'mask' => '5' }, + 'Start6' => { 'addr' => 'C3', 'mask' => '6' }, + 'Start7' => { 'addr' => 'C3', 'mask' => '7' }, + 'Start8' => { 'addr' => 'C4', 'mask' => '4' }, + 'Start9' => { 'addr' => 'C4', 'mask' => '5' }, + 'Starta' => { 'addr' => 'C4', 'mask' => '6' }, + 'Startb' => { 'addr' => 'C4', 'mask' => '7' }, + 'Startc' => { 'addr' => 'C4', 'mask' => '8' }, + 'Startd' => { 'addr' => 'C4', 'mask' => '9' }, + 'Starte' => { 'addr' => 'C4', 'mask' => '10' }, + 'Startf' => { 'addr' => 'C4', 'mask' => '11' }, + }, + + 'Veto' => + { 'Veto0' => { 'addr' => 'C3', 'mask' => '8' }, + 'Veto1' => { 'addr' => 'C3', 'mask' => '9' }, + 'Veto2' => { 'addr' => 'C3', 'mask' => '10' }, + 'Veto3' => { 'addr' => 'C3', 'mask' => '11' }, + 'Veto4' => { 'addr' => 'C3', 'mask' => '12' }, + 'Veto5' => { 'addr' => 'C3', 'mask' => '13' }, + 'Veto6' => { 'addr' => 'C3', 'mask' => '14' }, + 'Veto7' => { 'addr' => 'C3', 'mask' => '15' }, + }, + 'TOF' => + { + 'TOF1' => { 'addr' => 'C3', 'mask' => '16' }, + 'TOF2' => { 'addr' => 'C3', 'mask' => '17' }, + 'TOF3' => { 'addr' => 'C3', 'mask' => '18' }, + 'TOF4' => { 'addr' => 'C3', 'mask' => '19' }, + 'TOF5' => { 'addr' => 'C3', 'mask' => '20' }, + 'TOF6' => { 'addr' => 'C3', 'mask' => '21' }, + }, + 'RPC' => + { + 'RPC1' => { 'addr' => 'C3', 'mask' => '22' }, + 'RPC2' => { 'addr' => 'C3', 'mask' => '23' }, + 'RPC3' => { 'addr' => 'C3', 'mask' => '24' }, + 'RPC4' => { 'addr' => 'C3', 'mask' => '25' }, + 'RPC5' => { 'addr' => 'C3', 'mask' => '26' }, + 'RPC6' => { 'addr' => 'C3', 'mask' => '27' }, + }, + 'PT' => + { + 'PT1' => { 'addr' => 'C3', 'mask' => '28' }, + 'PT2' => { 'addr' => 'C3', 'mask' => '29' }, + 'PT3' => { 'addr' => 'C3', 'mask' => '30' }, + 'PT4' => { 'addr' => 'C3', 'mask' => '31' }, + 'PT5' => { 'addr' => 'C4', 'mask' => '0' }, + 'PT6' => { 'addr' => 'C4', 'mask' => '1' }, + 'PT7' => { 'addr' => 'C4', 'mask' => '2' }, + 'PT8' => { 'addr' => 'C4', 'mask' => '3' }, + + } + }, +'DLY_LARGE' => + { 'Start' => + { 'Start' => { 'addr' => 'DB', 'mask' => '7-0' }, + }, + 'Veto' => + { 'Veto' => { 'addr' => 'DB', 'mask' => '15-8' }, + }, + 'TOF' => + { + 'TOF' => { 'addr' => 'DB', 'mask' => '23-16' }, + }, + 'RPC' => + { + 'RPC' => { 'addr' => 'DB', 'mask' => '31-24' }, + }, + 'PT' => + { + 'PT1' => { 'addr' => 'DC', 'mask' => '7-0' }, + 'PT2' => { 'addr' => 'DC', 'mask' => '15-8' }, + 'PT3' => { 'addr' => 'DC', 'mask' => '23-16' }, + 'PT4' => { 'addr' => 'DC', 'mask' => '31-24' }, + 'PT5' => { 'addr' => 'DD', 'mask' => '7-0' }, + 'PT6' => { 'addr' => 'DD', 'mask' => '15-8' }, + 'PT7' => { 'addr' => 'DD', 'mask' => '23-16' }, + 'PT8' => { 'addr' => 'DD', 'mask' => '31-24' }, + + } + }, +'DLY_SMALL' => + { 'Start' => + { 'Start0' => { 'addr' => 'D1', 'mask' => '3-0' }, + 'Start1' => { 'addr' => 'D1', 'mask' => '7-4' }, + 'Start2' => { 'addr' => 'D1', 'mask' => '11-8' }, + 'Start3' => { 'addr' => 'D1', 'mask' => '15-12' }, + 'Start4' => { 'addr' => 'D1', 'mask' => '19-16' }, + 'Start5' => { 'addr' => 'D1', 'mask' => '23-20' }, + 'Start6' => { 'addr' => 'D1', 'mask' => '27-24' }, + 'Start7' => { 'addr' => 'D1', 'mask' => '31-28' }, + 'Start8' => { 'addr' => 'D6', 'mask' => '3-0' }, + 'Start9' => { 'addr' => 'D6', 'mask' => '7-4' }, + 'Starta' => { 'addr' => 'D6', 'mask' => '11-8' }, + 'Startb' => { 'addr' => 'D6', 'mask' => '15-12' }, + 'Startc' => { 'addr' => 'D6', 'mask' => '19-16'}, + 'Startd' => { 'addr' => 'D6', 'mask' => '23-20'}, + 'Starte' => { 'addr' => 'D6', 'mask' => '27-24'}, + 'Startf' => { 'addr' => 'D6', 'mask' => '31-28'}, + }, + 'Veto' => + { 'Veto0' => { 'addr' => 'D2', 'mask' => '3-0' }, + 'Veto1' => { 'addr' => 'D2', 'mask' => '7-4' }, + 'Veto2' => { 'addr' => 'D2', 'mask' => '11-8' }, + 'Veto3' => { 'addr' => 'D2', 'mask' => '15-12' }, + 'Veto4' => { 'addr' => 'D2', 'mask' => '19-16' }, + 'Veto5' => { 'addr' => 'D2', 'mask' => '23-20' }, + 'Veto6' => { 'addr' => 'D2', 'mask' => '27-24' }, + 'Veto7' => { 'addr' => 'D2', 'mask' => '31-28' }, + }, + 'TOF' => + { 'TOF1' => { 'addr' => 'D3', 'mask' => '3-0' }, + 'TOF2' => { 'addr' => 'D3', 'mask' => '7-4' }, + 'TOF3' => { 'addr' => 'D3', 'mask' => '11-8' }, + 'TOF4' => { 'addr' => 'D3', 'mask' => '15-12' }, + 'TOF5' => { 'addr' => 'D3', 'mask' => '19-16' }, + 'TOF6' => { 'addr' => 'D3', 'mask' => '23-20' }, + }, + 'RPC' => + { 'RPC1' => { 'addr' => 'D3', 'mask' => '27-24' }, + 'RPC2' => { 'addr' => 'D3', 'mask' => '31-28' }, + 'RPC3' => { 'addr' => 'D4', 'mask' => '3-0' }, + 'RPC4' => { 'addr' => 'D4', 'mask' => '7-4' }, + 'RPC5' => { 'addr' => 'D4', 'mask' => '11-8' }, + 'RPC6' => { 'addr' => 'D4', 'mask' => '15-12' }, + }, + 'PT' => + { + 'PT1' => { 'addr' => 'D4', 'mask' => '19-16' }, + 'PT2' => { 'addr' => 'D4', 'mask' => '23-20' }, + 'PT3' => { 'addr' => 'D4', 'mask' => '27-24' }, + 'PT4' => { 'addr' => 'D4', 'mask' => '31-28' }, + 'PT5' => { 'addr' => 'D5', 'mask' => '3-0' }, + 'PT6' => { 'addr' => 'D5', 'mask' => '7-4' }, + 'PT7' => { 'addr' => 'D5', 'mask' => '11-8' }, + 'PT8' => { 'addr' => 'D5', 'mask' => '15-12' }, + }, + }, +'SCALER_DLY' => + { 'Start' => + { 'Start0' => { 'addr' => '08', 'mask' => '31-0' }, + 'Start1' => { 'addr' => '09', 'mask' => '31-0' }, + 'Start2' => { 'addr' => '0A', 'mask' => '31-0' }, + 'Start3' => { 'addr' => '0B', 'mask' => '31-0' }, + 'Start4' => { 'addr' => '0C', 'mask' => '31-0' }, + 'Start5' => { 'addr' => '0D', 'mask' => '31-0' }, + 'Start6' => { 'addr' => '0E', 'mask' => '31-0' }, + 'Start7' => { 'addr' => '0F', 'mask' => '31-0' }, + + 'Start8' => { 'addr' => '67', 'mask' => '31-0' }, + 'Start9' => { 'addr' => '68', 'mask' => '31-0' }, + 'Starta' => { 'addr' => '69', 'mask' => '31-0' }, + 'Startb' => { 'addr' => '6a', 'mask' => '31-0' }, + 'Startc' => { 'addr' => '6b', 'mask' => '31-0' }, + 'Startd' => { 'addr' => '6c', 'mask' => '31-0' }, + 'Starte' => { 'addr' => '6d', 'mask' => '31-0' }, + 'Startf' => { 'addr' => '6e', 'mask' => '31-0' }, + }, + 'Veto' => + { 'Veto0' => { 'addr' => '10', 'mask' => '31-0' }, + 'Veto1' => { 'addr' => '11', 'mask' => '31-0' }, + 'Veto2' => { 'addr' => '12', 'mask' => '31-0' }, + 'Veto3' => { 'addr' => '13', 'mask' => '31-0' }, + 'Veto4' => { 'addr' => '14', 'mask' => '31-0' }, + 'Veto5' => { 'addr' => '15', 'mask' => '31-0' }, + 'Veto6' => { 'addr' => '16', 'mask' => '31-0' }, + 'Veto7' => { 'addr' => '17', 'mask' => '31-0' }, + }, + 'TOF' => + { 'TOF0' => { 'addr' => '18', 'mask' => '31-0' }, + 'TOF1' => { 'addr' => '19', 'mask' => '31-0' }, + 'TOF2' => { 'addr' => '1A', 'mask' => '31-0' }, + 'TOF3' => { 'addr' => '1B', 'mask' => '31-0' }, + 'TOF4' => { 'addr' => '1C', 'mask' => '31-0' }, + 'TOF5' => { 'addr' => '1D', 'mask' => '31-0' }, + }, + 'RPC' => + { 'RPC0' => { 'addr' => '1E', 'mask' => '31-0' }, + 'RPC1' => { 'addr' => '1F', 'mask' => '31-0' }, + 'RPC2' => { 'addr' => '20', 'mask' => '31-0' }, + 'RPC3' => { 'addr' => '21', 'mask' => '31-0' }, + 'RPC4' => { 'addr' => '22', 'mask' => '31-0' }, + 'RPC5' => { 'addr' => '23', 'mask' => '31-0' }, + }, + 'PT' => + { + 'PT0' => { 'addr' => '24', 'mask' => '31-0' }, + 'PT1' => { 'addr' => '25', 'mask' => '31-0' }, + 'PT2' => { 'addr' => '26', 'mask' => '31-0' }, + 'PT3' => { 'addr' => '27', 'mask' => '31-0' }, + 'PT4' => { 'addr' => '28', 'mask' => '31-0' }, + 'PT5' => { 'addr' => '29', 'mask' => '31-0' }, + 'PT6' => { 'addr' => '2a', 'mask' => '31-0' }, + 'PT7' => { 'addr' => '2b', 'mask' => '31-0' }, + + }, + }, + +'WIDTH' => + { + 'TOF' => + { 'TOF1' => { 'addr' => 'E0', 'mask' => '3-0' }, + 'TOF2' => { 'addr' => 'E0', 'mask' => '7-4' }, + 'TOF3' => { 'addr' => 'E0', 'mask' => '11-8' }, + 'TOF4' => { 'addr' => 'E0', 'mask' => '15-12' }, + 'TOF5' => { 'addr' => 'E0', 'mask' => '19-16' }, + 'TOF6' => { 'addr' => 'E0', 'mask' => '23-20' }, + }, + 'RPC' => + { 'RPC1' => { 'addr' => 'E0', 'mask' => '27-24' }, + 'RPC2' => { 'addr' => 'E0', 'mask' => '31-28' }, + 'RPC3' => { 'addr' => 'E1', 'mask' => '3-0' }, + 'RPC4' => { 'addr' => 'E1', 'mask' => '7-4' }, + 'RPC5' => { 'addr' => 'E1', 'mask' => '11-8' }, + 'RPC6' => { 'addr' => 'E1', 'mask' => '15-12' }, + }, + 'PT' => + { + 'PT1' => { 'addr' => 'E1', 'mask' => '19-16' }, + 'PT2' => { 'addr' => 'E1', 'mask' => '23-20' }, + 'PT3' => { 'addr' => 'E1', 'mask' => '27-24' }, + 'PT4' => { 'addr' => 'E1', 'mask' => '31-28' }, + 'PT5' => { 'addr' => 'E2', 'mask' => '3-0' }, + 'PT6' => { 'addr' => 'E2', 'mask' => '7-4' }, + 'PT7' => { 'addr' => 'E2', 'mask' => '11-8' }, + 'PT8' => { 'addr' => 'E2', 'mask' => '15-12' }, + + }, + }, + +'WIDTH_SMALL' => + { 'Start' => { 'Veto_all' => { 'addr' => 'C0', 'mask' => '23-20' } + } + }, + +'DSC' => + { 'Start' => + { 'Start' => { 'addr' => 'C9', 'mask' => '3-0' } + }, + 'Veto' => + { 'Veto' => { 'addr' => 'C9', 'mask' => '7-4' } + }, + 'Mult' => + { 'Mult1' => { 'addr' => 'C9', 'mask' => '11-8' }, + 'Mult2' => { 'addr' => 'C9', 'mask' => '15-12' }, + 'Mult3' => { 'addr' => 'C9', 'mask' => '19-16' }, + 'Mult4' => { 'addr' => 'C9', 'mask' => '23-20' }, + 'Mult5' => { 'addr' => 'C9', 'mask' => '27-24' }, + 'Mult6' => { 'addr' => 'C9', 'mask' => '31-28' }, + 'Mult7' => { 'addr' => 'CA', 'mask' => '3-0' }, + 'Mult8' => { 'addr' => 'CA', 'mask' => '7-4' }, + 'Mult9' => { 'addr' => 'CA', 'mask' => '11-8' }, + }, + 'PT' => + { + 'PT1' => { 'addr' => 'CA', 'mask' => '15-12' }, + 'PT2' => { 'addr' => 'CA', 'mask' => '19-16' }, + 'PT3' => { 'addr' => 'CA', 'mask' => '23-20' }, + 'PT4' => { 'addr' => 'CA', 'mask' => '27-24' }, + 'PT5' => { 'addr' => 'CA', 'mask' => '31-28' }, + 'PT6' => { 'addr' => 'CB', 'mask' => '3-0' }, + 'PT7' => { 'addr' => 'CB', 'mask' => '7-4' }, + 'PT8' => { 'addr' => 'CB', 'mask' => '11-8' }, + } + }, +'WIDTH_M' => + { 'Mult' => + { 'Mult1' => { 'addr' => 'DE', 'mask' => '3-0' }, + 'Mult2' => { 'addr' => 'DE', 'mask' => '7-4' }, + 'Mult3' => { 'addr' => 'DE', 'mask' => '11-8' }, + 'Mult4' => { 'addr' => 'DE', 'mask' => '15-12' }, + 'Mult5' => { 'addr' => 'DE', 'mask' => '19-16' }, + 'Mult6' => { 'addr' => 'DE', 'mask' => '23-20' }, + 'Mult7' => { 'addr' => 'DE', 'mask' => '27-24' }, + 'Mult8' => { 'addr' => 'DE', 'mask' => '31-28' }, + 'Mult9' => { 'addr' => 'DF', 'mask' => '3-0' } + }, + }, +'SCALER_DSC' => + { 'Start' => + { 'Start' => { 'addr' => '2C', 'mask' => '31-0' }, + }, + 'Veto' => + { 'Veto' => { 'addr' => '2D', 'mask' => '31-0' }, + }, + 'Mult' => + { 'Mult1' => { 'addr' => '2E', 'mask' => '31-0'}, + 'Mult2' => { 'addr' => '2F', 'mask' => '31-0'}, + 'Mult3' => { 'addr' => '30', 'mask' => '31-0'}, + 'Mult4' => { 'addr' => '31', 'mask' => '31-0'}, + 'Mult5' => { 'addr' => '32', 'mask' => '31-0'}, + 'Mult6' => { 'addr' => '33', 'mask' => '31-0'}, + 'Mult7' => { 'addr' => '34', 'mask' => '31-0'}, + 'Mult8' => { 'addr' => '35', 'mask' => '31-0'}, + 'Mult9' => { 'addr' => '36', 'mask' => '31-0'}, + }, + + 'PT' => + { + 'PT0' => { 'addr' => '37', 'mask' => '31-0' }, + 'PT1' => { 'addr' => '38', 'mask' => '31-0' }, + 'PT2' => { 'addr' => '39', 'mask' => '31-0' }, + 'PT3' => { 'addr' => '3A', 'mask' => '31-0' }, + 'PT4' => { 'addr' => '3B', 'mask' => '31-0' }, + 'PT5' => { 'addr' => '3C', 'mask' => '31-0' }, + 'PT6' => { 'addr' => '3D', 'mask' => '31-0' }, + 'PT7' => { 'addr' => '3E', 'mask' => '31-0' }, + }, + }, +'GATING_DIS' => + { + 'Mult' => + { 'Mult1' => { 'addr' => 'C5', 'mask' => '0'}, + 'Mult2' => { 'addr' => 'C5', 'mask' => '1'}, + 'Mult3' => { 'addr' => 'C5', 'mask' => '2'}, + 'Mult4' => { 'addr' => 'C5', 'mask' => '3'}, + 'Mult5' => { 'addr' => 'C5', 'mask' => '4'}, + 'Mult6' => { 'addr' => 'C5', 'mask' => '5'}, + 'Mult7' => { 'addr' => 'C5', 'mask' => '6'}, + 'Mult8' => { 'addr' => 'C5', 'mask' => '7'}, + 'Mult9' => { 'addr' => 'C5', 'mask' => '8'}, + }, + 'PT' => + { + 'PT0' => { 'addr' => 'C5', 'mask' => '9' }, + 'PT1' => { 'addr' => 'C5', 'mask' => '10' }, + 'PT2' => { 'addr' => 'C5', 'mask' => '11' }, + 'PT3' => { 'addr' => 'C5', 'mask' => '12' }, + 'PT4' => { 'addr' => 'C5', 'mask' => '13' }, + 'PT5' => { 'addr' => 'C5', 'mask' => '14' }, + 'PT6' => { 'addr' => 'C5', 'mask' => '15' }, + 'PT7' => { 'addr' => 'C5', 'mask' => '16' }, + }, + }, + +'OUT_EN' => + { 'Start' => + { 'Start' => { 'addr' => 'C7', 'mask' => '0' }, + }, + 'Veto' => + { 'Veto' => { 'addr' => 'C7', 'mask' => '1' }, + }, + 'Mult' => + { 'Mult1' => { 'addr' => 'C7', 'mask' => '2'}, + 'Mult2' => { 'addr' => 'C7', 'mask' => '3'}, + 'Mult3' => { 'addr' => 'C7', 'mask' => '4'}, + 'Mult4' => { 'addr' => 'C7', 'mask' => '5'}, + 'Mult5' => { 'addr' => 'C7', 'mask' => '6'}, + 'Mult6' => { 'addr' => 'C7', 'mask' => '7'}, + 'Mult7' => { 'addr' => 'C7', 'mask' => '8'}, + 'Mult8' => { 'addr' => 'C7', 'mask' => '9'}, + 'Mult9' => { 'addr' => 'C7', 'mask' => '10'}, + }, + 'PT' => + { + 'PT0' => { 'addr' => 'C7', 'mask' => '11' }, + 'PT1' => { 'addr' => 'C7', 'mask' => '12' }, + 'PT2' => { 'addr' => 'C7', 'mask' => '13' }, + 'PT3' => { 'addr' => 'C7', 'mask' => '14' }, + 'PT4' => { 'addr' => 'C7', 'mask' => '15' }, + 'PT5' => { 'addr' => 'C7', 'mask' => '16' }, + 'PT6' => { 'addr' => 'C7', 'mask' => '17' }, + 'PT7' => { 'addr' => 'C7', 'mask' => '18' }, + + }, + }, +'SCALER_C' => + { 'Mult' => + { 'Mult1' => { 'addr' => '52', 'mask' => '31-0'}, + 'Mult2' => { 'addr' => '53', 'mask' => '31-0'}, + 'Mult3' => { 'addr' => '54', 'mask' => '31-0'}, + 'Mult4' => { 'addr' => '55', 'mask' => '31-0'}, + 'Mult5' => { 'addr' => '56', 'mask' => '31-0'}, + 'Mult6' => { 'addr' => '57', 'mask' => '31-0'}, + 'Mult7' => { 'addr' => '58', 'mask' => '31-0'}, + 'Mult8' => { 'addr' => '59', 'mask' => '31-0'}, + 'Mult9' => { 'addr' => '5A', 'mask' => '31-0'}, + }, + 'PT' => + { + 'PT0' => { 'addr' => '5B', 'mask' => '31-0' }, + 'PT1' => { 'addr' => '5C', 'mask' => '31-0' }, + 'PT2' => { 'addr' => '5D', 'mask' => '31-0' }, + 'PT3' => { 'addr' => '5E', 'mask' => '31-0' }, + 'PT4' => { 'addr' => '5F', 'mask' => '31-0' }, + 'PT5' => { 'addr' => '60', 'mask' => '31-0' }, + 'PT6' => { 'addr' => '61', 'mask' => '31-0' }, + 'PT7' => { 'addr' => '62', 'mask' => '31-0' }, + }, + }, + +'SCALER_OUT' => + { 'Start' => + { 'Start' => { 'addr' => '3F', 'mask' => '31-0' }, + }, + 'Veto' => + { 'Veto' => { 'addr' => '40', 'mask' => '31-0' }, + }, + 'Mult' => + { 'Mult1' => { 'addr' => '41', 'mask' => '31-0'}, + 'Mult2' => { 'addr' => '42', 'mask' => '31-0'}, + 'Mult3' => { 'addr' => '43', 'mask' => '31-0'}, + 'Mult4' => { 'addr' => '44', 'mask' => '31-0'}, + 'Mult5' => { 'addr' => '45', 'mask' => '31-0'}, + 'Mult6' => { 'addr' => '46', 'mask' => '31-0'}, + 'Mult7' => { 'addr' => '47', 'mask' => '31-0'}, + 'Mult8' => { 'addr' => '48', 'mask' => '31-0'}, + 'Mult9' => { 'addr' => '49', 'mask' => '31-0'}, + }, + 'PT' => + { + 'PT0' => { 'addr' => '4A', 'mask' => '31-0' }, + 'PT1' => { 'addr' => '4B', 'mask' => '31-0' }, + 'PT2' => { 'addr' => '4C', 'mask' => '31-0' }, + 'PT3' => { 'addr' => '4D', 'mask' => '31-0' }, + 'PT4' => { 'addr' => '4E', 'mask' => '31-0' }, + 'PT5' => { 'addr' => '4F', 'mask' => '31-0' }, + 'PT6' => { 'addr' => '50', 'mask' => '31-0' }, + 'PT7' => { 'addr' => '51', 'mask' => '31-0' }, + }, + }, + +'CAL_TRIG' => + { + 'CAL' => + { + 'MDC_CAL_EN' => { 'addr' => 'C0', 'mask' => '5'}, + 'SHW_CAL_EN' => { 'addr' => 'C0', 'mask' => '8'}, + 'SHW_PED_DIS' => { 'addr' => 'C0', 'mask' => '7'}, + 'DEBUG_EN' => { 'addr' => 'C0', 'mask' => '9'}, + 'BEAM_INH_EN' => { 'addr' => 'C0', 'mask' => '14'}, + + }, + 'TRIG' => + { + 'PULSER' => { 'addr' => 'E3', 'mask' => '27-0'}, + 'OWN_TYPE_EN' => { 'addr' => 'C0', 'mask' => '4'}, + 'OWN_TYPE' => { 'addr' => 'C0', 'mask' => '3-0'}, + 'MDCA_DELAY' => { 'addr' => 'C1', 'mask' => '21-17'}, + 'MDCB_DELAY' => { 'addr' => 'C1', 'mask' => '16-12'}, + 'MULT_SAMPLE' => { 'addr' => 'C1', 'mask' => '3-0'}, + 'TRIG_WIDTH' => { 'addr' => 'C1', 'mask' => '31-28'}, + 'TRIG_RATE' => { 'addr' => '01', 'mask' => '19-0'}, + 'LVL1_INFO' => { 'addr' => 'e4', 'mask' => '13-0'}, + 'EB_LUT' => { 'addr' => 'f0', 'mask' => '15-0'}, + 'EB_EVENTS' => { 'addr' => 'f1', 'mask' => '24-0'}, + 'START_SEL_X' => { 'addr' => 'da', 'mask' => '7-6'}, + 'START_SEL_Y' => { 'addr' => 'da', 'mask' => '9-8'}, + 'ANTI_COINC' => { 'addr' => 'c0', 'mask' => '17-16'}, + }, + }, +'BUSY' => + { + 'BUSY_BOX' => + { + 'LVL1_CTS' => { 'addr' => '00', 'mask' => '20'}, + 'LVL1_TRBENT' => { 'addr' => '00', 'mask' => '21'}, + 'LVL1_LOCAL' => { 'addr' => '00', 'mask' => '22'}, + 'LVL2_CTS' => { 'addr' => '01', 'mask' => '20'}, + 'LVL2_TRBNET' => { 'addr' => '01', 'mask' => '21'}, + 'LVL2_LOCAL' => { 'addr' => '01', 'mask' => '22'}, + 'LVL1-LVL2' => { 'addr' => '01', 'mask' => '31-24'}, + 'LVL1_NUMBER' => { 'addr' => '00', 'mask' => '15-0'}, + 'LVL1_RND' => { 'addr' => '00', 'mask' => '31-24'}, + }, + }, +'BEAM' => + { + 'BEAM_PROFILE' => + { + 'SAMPLE_OFFSET' => { 'addr' => 'C6', 'mask' => '31-0'}, + 'SAMPLE_PERIOD' => { 'addr' => 'C8', 'mask' => '31-0'}, + 'BEAM_LENGTH' => { 'addr' => 'D9', 'mask' => '31-0'}, + 'MULTIPLEX_A' => { 'addr' => 'C2', 'mask' => '7-0'}, + 'MULTIPLEX_B' => { 'addr' => 'C2', 'mask' => '15-8'}, + 'START_V_SEL' => { 'addr' => 'da', 'mask' => '1-0'}, + 'START_H_SEL' => { 'addr' => 'da', 'mask' => '3-2'}, + + }, + }, +); + +my $opt_help = 0; +my $opt_etrax = "etraxp058"; +my $opt_log = 1; +my $opt_mode = "mon"; +my $opt_access = "trbcmd"; # access method: trbcmd/command_server +my $errorType = ""; + +GetOptions ('h|help' => \$opt_help, + 'e|etrax=s' => \$opt_etrax, + 'l|log' => \$opt_log, + 'm|mode=s' => \$opt_mode, + 'a|access=s' => \$opt_access); + +if( $opt_help ) { + &help(); + exit(0); +} + +my $names_href = \%setup_names; +my $setup_href = \%setup; +my @regs2read; +my $regs2read_aref = \@regs2read; +my %regsVals; +my $regsVals_href = \%regsVals; + +my $cmd_base = "rw_trbv2 --addon r 0"; +my $cmd_base_w = "rw_trbv2 --addon w 0"; +my $trb_cmd1 = "/home/hadaq/bin/trbcmd rm 0x0003 0xa000 111 0"; +my $trb_cmd2 = "/home/hadaq/bin/trbcmd rm 0x0003 0xa0c0 52 0"; # read 52 registers starting from a0c0 +#my $cmd_base = "rwv2_addon r 0"; +my $opt_verb = 0; + +my $cmd_server_port = 4712; +my $cmd_server_prtcl = 'tcp'; +my $cmd_server_answer = ""; + +my $log = "/tmp/log_mon_cts.txt"; + +#--- graphics +my $Gtk2_window = Gtk2::Window->new('toplevel'); + +my $Gtk2_table = Gtk2::Table->new( 34, 11, TRUE ); # Rows, Columns +my $Gtk2_table_cal = Gtk2::Table->new( 34, 2, TRUE ); # Rows, Columns +my $Gtk2_table_trig = Gtk2::Table->new( 12, 2, TRUE ); # Rows, Columns +my $Gtk2_table_busy = Gtk2::Table->new( 10, 2, TRUE ); # Rows, Columns +my $Gtk2_table_msg = Gtk2::Table->new( 1, 1, TRUE ); # Rows, Columns +my $Gtk2_table_beam = Gtk2::Table->new( 9, 2, TRUE ); # Rows, Columns + +my $Gtk2_vbox_all = Gtk2::VBox->new(FALSE, 5); +my $Gtk2_hbox = Gtk2::HBox->new(FALSE, 5); +my $Gtk2_hbox2 = Gtk2::HBox->new(FALSE, 5); +my $Gtk2_vbox = Gtk2::VBox->new(FALSE, 5); + +my $Gtk2_frame_main = Gtk2::Frame->new('Main'); +my $Gtk2_frame_cal = Gtk2::Frame->new('Calib'); +my $Gtk2_frame_trig = Gtk2::Frame->new('Trigger'); +my $Gtk2_frame_busy = Gtk2::Frame->new('Busy'); +my $Gtk2_frame_msg = Gtk2::Frame->new('Message'); +my $Gtk2_frame_beam = Gtk2::Frame->new('Beam profile'); + +my $Gtk2_errmsg_lbl; + +my $button_set = Gtk2::Widget->new("Gtk2::Button", + label=>"SET REG"); +$button_set->signal_connect(clicked=>\&set_window, [$regsVals_href]); + +my $button_ctrl = Gtk2::Button->new("SAVE/LOAD"); +$button_ctrl->signal_connect(pressed => \&ctrlWindow); + +my $button_startup = Gtk2::Button->new("\@STARTUP"); +$button_startup->signal_connect(pressed => \&cp2startup); + +if( $opt_mode eq "mon" ){ + &Gtk2_init(); + &Gtk2_setRowTitles(); + &Gtk2_makeTable_main(); + &Gtk2_makeTable_cal(); + &Gtk2_makeTable_trig(); + &Gtk2_makeTable_busy(); + &Gtk2_makeTable_msg(); + &Gtk2_makeTable_beam(); +} +elsif( $opt_mode eq "set" ){ + &Gtk2_init(); + &Gtk2_setRowTitles(); + &Gtk2_makeTable_main_set(); + &Gtk2_makeTable_cal_set(); + &Gtk2_makeTable_trig_set(); + &Gtk2_makeTable_msg(); + &Gtk2_makeTable_beam_set(); + #&Gtk2_button_ctrl(); +} +else{ + print "Unknown option $opt_mode. Exit.\n" if( defined $opt_mode ); + print "Undefined option opt_mode. Exit.\n" unless( defined $opt_mode ); + exit(1); +} + +$Gtk2_frame_main->add($Gtk2_table); +$Gtk2_frame_cal->add($Gtk2_table_cal); +$Gtk2_frame_trig->add($Gtk2_table_trig); +$Gtk2_frame_busy->add($Gtk2_table_busy); +$Gtk2_frame_msg->add($Gtk2_table_msg); +$Gtk2_frame_beam->add($Gtk2_table_beam); + +$Gtk2_vbox->pack_start($Gtk2_frame_cal, FALSE, FALSE, 0); +$Gtk2_vbox->pack_start($Gtk2_frame_trig, FALSE, FALSE, 0); +$Gtk2_vbox->pack_start($Gtk2_frame_busy, FALSE, FALSE, 0) if($opt_mode eq "mon"); +$Gtk2_vbox->pack_start($Gtk2_frame_beam, FALSE, FALSE, 0); + +$Gtk2_hbox->pack_start($Gtk2_frame_main, FALSE, FALSE, 0); +$Gtk2_hbox->pack_start($Gtk2_vbox, FALSE, FALSE, 0); + +$Gtk2_hbox2->pack_start($Gtk2_frame_msg, FALSE, FALSE, 0); +$Gtk2_hbox2->pack_start($button_set, FALSE, FALSE, 0); +$Gtk2_hbox2->pack_start($button_ctrl, FALSE, FALSE, 0) if($opt_mode eq "set"); +$Gtk2_hbox2->pack_start($button_startup, FALSE, FALSE, 0) if($opt_mode eq "set"); + +$Gtk2_vbox_all->pack_start($Gtk2_hbox, FALSE, FALSE, 0); +$Gtk2_vbox_all->pack_start($Gtk2_hbox2, FALSE, FALSE, 0); +#$Gtk2_vbox_all->pack_start($Gtk2_frame_msg, FALSE, FALSE, 0); + +$Gtk2_window->add($Gtk2_vbox_all); +$Gtk2_window->show_all; + +my @regs_array = (); +my $shellScriptName = "read_regs_" . $$ . ".sh"; + +if($opt_access eq "cmdsrv"){ + &getRegs2read($regs2read_aref); + &writeShellScript($regs2read_aref); +} + +if($opt_mode eq "set"){ + if($opt_access eq "cmdsrv"){ + &connectCmdServer2("/home/hadaq/tmp/$shellScriptName", + $opt_etrax, $cmd_server_port, $cmd_server_prtcl, \@regs_array); + &readArray(\@regs_array); + } + elsif($opt_access eq "trbcmd"){ + &readRegs_trbcmd(); + } + else{ + print "Wrong option -a|--access: $opt_access. Exit.\n"; + exit(0); + } +} + +while(1) { + if($opt_mode eq "mon"){ + if($opt_access eq "cmdsrv"){ + if($opt_log){ + &connectCmdServer("/home/hadaq/tmp/$shellScriptName", + $opt_etrax, $cmd_server_port, $cmd_server_prtcl, $log); + &readLog($log); + } + else{ + &connectCmdServer2("/home/hadaq/tmp/$shellScriptName", + $opt_etrax, $cmd_server_port, $cmd_server_prtcl, \@regs_array); + &readArray(\@regs_array); + } + } + elsif($opt_access eq "trbcmd"){ + &readRegs_trbcmd(); + } + else{ + print "Wrong option -a|--access: $opt_access. Exit.\n"; + exit(0); + } + + &fillVals2hash(); + } + + + if($opt_mode eq "mon") { + for (1..2) { + while (Gtk2->events_pending) { + Gtk2->main_iteration; + } + Gtk2::Gdk->flush; + select (undef,undef,undef,0.45); + } + } + else { # faster for interactive input + for (1..20) { + while (Gtk2->events_pending) { + Gtk2->main_iteration; + } + Gtk2::Gdk->flush; + select (undef,undef,undef,0.05); + } + } + + + } + +exit(0); + +###################### END OF MAIN #################### + +sub help() +{ + print "\n"; + print << 'EOF'; +mon_cts.pl + + This script connects to the CTS via command_server ot trbcmd and + reads the content of the registers specified in the hash at the beginning + of this script. + +Usage: + + Command line: mon_cts.pl + [-h|--help] : Show this help. + [-e|--etrax name] : CTS Etrax name (default: etraxp058). + [-l|--log] : Store the output of command_server in log file, + works only with --access cmdsrv + (default: read directly to an array). + [-a|--access ] : Access method (default: trbcmd). + +Example: + + Monitor local CTS which runs on etrax109: + mon_cts.pl -e etrax109 + +EOF +} + +sub Gtk2_init() +{ + #- Make window + $Gtk2_window->signal_connect(destroy => sub { Gtk2->main_quit; }); + $Gtk2_window->signal_connect(delete_event => sub { exit; }); + $Gtk2_window->set_title("CTS Monitor"); + $Gtk2_window->set_border_width(5); +} + +sub Gtk2_makeTable_main() +{ + my $lable; + my $l = 2; + my $r = 3; + my $t = 0; + my $b = 1; + + foreach my $href (@layout1){ + + #- Loop over Columns + foreach my $var ( sort keys %$href ) { + + $t = 0; + $b = 1; + + if( $var eq "WIDTH_SMALL"){ + $l++; + $r++; + } + + my $ext = $l . $r . $t . $b; + + $lable = Gtk2::Label->new($names_href->{$var}->{'first'}); + $lable->set_name("green".$ext); + $Gtk2_table->attach($lable, $l, $r, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $t++; + $b++; + + $lable = Gtk2::Label->new($names_href->{$var}->{'second'}); + $lable->set_name("green".$ext); + $Gtk2_table->attach($lable, $l, $r, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + foreach my $sys (@{$href->{$var}}){ + + &shiftIndex($var, $sys, \$t, \$b); + + #- Loop over Rows + foreach my $subsys (sort keys %{$setup_href->{$var}->{$sys}}){ + $setup_href->{$var}->{$sys}->{$subsys}->{'lbl'} = Gtk2::Label->new(); + + $t++; + $b++; + $Gtk2_table->attach($setup_href->{$var}->{$sys}->{$subsys}->{'lbl'}, + $l, $r, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + + my $addr = lc($setup_href->{$var}->{$sys}->{$subsys}->{'addr'}); + } + } + + $l++; + $r++; + } + } + +# foreach my $href (@layout2){ +# foreach my $var ( sort keys %$href ) { +# foreach my $sys (@{$href->{$var}}){ +# foreach my $subsys (sort keys %{$setup_href->{$var}->{$sys}}){ +# $setup_href->{$var}->{$sys}->{$subsys}->{'lbl'} = Gtk2::Label->new(); +# } +# } +# } +# } + + $Gtk2_table->set_col_spacings(1); + $Gtk2_table->set_homogeneous(0); +} + +sub Gtk2_setRowTitles() +{ + my $lable; + + $lable = Gtk2::Label->new('Start X'); + $lable->set_name("blue".1); + $Gtk2_table->attach($lable, 0, 1, 2, 3, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $lable = Gtk2::Label->new('Start Y'); + $lable->set_name("blue".1); + $Gtk2_table->attach($lable, 0, 1, 10, 11, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $lable = Gtk2::Label->new('Veto'); + $lable->set_name("blue".2); + $Gtk2_table->attach($lable, 0, 1, 18, 19, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $lable = Gtk2::Label->new('TOF'); + $lable->set_name("blue".3); + $Gtk2_table->attach($lable, 0, 1, 26, 27, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $lable = Gtk2::Label->new('RPC'); + $lable->set_name("blue".4); + $Gtk2_table->attach($lable, 0, 1, 32, 33, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $lable = Gtk2::Label->new('PT'); + $lable->set_name("blue".5); + $Gtk2_table->attach($lable, 0, 1, 38, 39, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + foreach my $i (1..8){ + $lable = Gtk2::Label->new($i); + my $ext = 1 . $i; $lable->set_name("blue".$ext); + $Gtk2_table->attach($lable, 1, 2, $i+1, $i+2, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + } + + foreach my $i (1..8){ + $lable = Gtk2::Label->new($i); + my $ext = 1 . $i; $lable->set_name("blue".$ext); + $Gtk2_table->attach($lable, 1, 2, $i+9, $i+10, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + } + + foreach my $i (1..8){ + $lable = Gtk2::Label->new($i); + my $ext = 2 . $i; $lable->set_name("blue".$ext); + $Gtk2_table->attach($lable, 1, 2, $i+17, $i+18, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + } + foreach my $i (1..6){ + $lable = Gtk2::Label->new($i); + my $ext = 3 . $i; $lable->set_name("blue".$ext); + $Gtk2_table->attach($lable, 1, 2, $i+25, $i+26, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + } + foreach my $i (1..6){ + $lable = Gtk2::Label->new($i); + my $ext = 4 . $i; $lable->set_name("blue".$ext); + $Gtk2_table->attach($lable, 1, 2, $i+31, $i+32, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + } + foreach my $i (1..8){ + $lable = Gtk2::Label->new($i); + my $ext = 5 . $i; $lable->set_name("blue".$ext); + $Gtk2_table->attach($lable, 1, 2, $i+37, $i+38, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + } + + #--- Another column with row titles before 'DSC' + + my $l = 9; + my $r = 10; + + if( $opt_mode eq "set" ){ + $l = 6; + $r = 7; + } + + $lable = Gtk2::Label->new('Start all'); + $lable->set_name("blue".1); + $Gtk2_table->attach($lable, $l, $r, 2, 3, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $lable = Gtk2::Label->new('Veto width'); + $lable->set_name("blue".1); + $Gtk2_table->attach($lable, $l, $r, 5, 6, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $lable = Gtk2::Label->new('for Start'); + $lable->set_name("blue".1); + $Gtk2_table->attach($lable, $l, $r, 6, 7, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $lable = Gtk2::Label->new('Veto all'); + $lable->set_name("blue".2); + $Gtk2_table->attach($lable, $l, $r, 18, 19, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + foreach my $i (18..23){ + my $multNr = $i - 17; + my $mult = "mult " . $multNr; + $lable = Gtk2::Label->new($mult); + $lable->set_name("blue".3); + $Gtk2_table->attach($lable, $l, $r, $i+8, $i+1+8, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + } + + $lable = Gtk2::Label->new('m2 no neigh'); + $lable->set_name("blue".3); + $Gtk2_table->attach($lable, $l, $r, 32, 33, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $lable = Gtk2::Label->new('m3 no neigh'); + $lable->set_name("blue".3); + $Gtk2_table->attach($lable, $l, $r, 33, 34, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $lable = Gtk2::Label->new('m2 opp sect'); + $lable->set_name("blue".3); + $Gtk2_table->attach($lable, $l, $r, 34, 35, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); +} + +sub shiftIndex() +{ + my ($var, $sys, $t, $b) = @_; + + if($var eq "DLY_LARGE" && ($sys eq "Veto")){ + $$t = $$t + 16 - 1; + $$b = $$b + 16 - 1; + } + elsif($var eq "DLY_LARGE" && ($sys eq "TOF")){ + $$t = $$t + 8 - 1; + $$b = $$b + 8 - 1; + } + + elsif($var eq "DLY_LARGE" && ($sys eq "RPC" || $sys eq "PT")){ + $$t = $$t + 6 - 1; + $$b = $$b + 6 - 1; + } + elsif( ($var eq "DSC" || $var eq "SCALER_DSC" || $var eq "OUT_EN" || $var eq "SCALER_OUT" ) && + ($sys eq "Veto")){ + $$t = $$t + 16 - 1; + $$b = $$b + 16 - 1; + } + elsif( ($var eq "DSC" || $var eq "SCALER_DSC" || $var eq "OUT_EN" || $var eq "SCALER_OUT" ) && + ($sys eq "Mult")){ + $$t = $$t + 8 - 1; + $$b = $$b + 8 - 1; + } + + + elsif( ($var eq "DSC" || $var eq "SCALER_DSC" || $var eq "OUT_EN" || + $var eq "SCALER_OUT" || $var eq "GATING_DIS" || $var eq "SCALER_C") && $sys eq "PT"){ + $$t = $$t + 3; + $$b = $$b + 3; + } + elsif( ($var eq "GATING_DIS" || $var eq "WIDTH_M" || $var eq "WIDTH" || $var eq "SCALER_C") && + ($sys eq "Mult" || $sys eq "TOF")){ + $$t = $$t + 24; + $$b = $$b + 24; + } + elsif( $var eq "WIDTH_SMALL" ){ + $$t = $$t + 4; + $$b = $$b + 4; + } +} + +sub Gtk2_makeTable_cal() +{ + my $lable; + my $entry; + my $l = 0; + my $r = 1; + my $t = 0; + my $b = 1; + + #$lable = Gtk2::Label->new('CAL'); + #$lable->set_name("green".1); + #$Gtk2_table_cal->attach($lable, $l+1, $r+1, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + foreach my $subsys (sort keys %{$setup_href->{'CAL_TRIG'}->{'CAL'}}){ + my $ext = $l . $r . $t . $b; + + $lable = Gtk2::Label->new($subsys); + $lable->set_name("blue".$ext); + $Gtk2_table_cal->attach($lable, $l, $r, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $setup_href->{'CAL_TRIG'}->{'CAL'}->{$subsys}->{'lbl'} = Gtk2::Label->new(); + + $Gtk2_table_cal->attach($setup_href->{'CAL_TRIG'}->{'CAL'}->{$subsys}->{'lbl'}, + $l+1, $r+1, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + + $t++; + $b++; + } + + $Gtk2_table_cal->set_col_spacings(1); + $Gtk2_table_cal->set_homogeneous(0); +} + +sub Gtk2_makeTable_trig() +{ + my $lable; + my $l = 0; + my $r = 1; + my $t = 0; + my $b = 1; + + #$lable = Gtk2::Label->new('TRIG'); + #$lable->set_name("green".1); + #$Gtk2_table_trig->attach($lable, $l+1, $r+1, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + foreach my $subsys (sort keys %{$setup_href->{'CAL_TRIG'}->{'TRIG'}}){ + $lable = Gtk2::Label->new($subsys); + my $ext = $l . $r . $t . $b; + $lable->set_name("blue".$ext); + $Gtk2_table_trig->attach($lable, $l, $r, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $setup_href->{'CAL_TRIG'}->{'TRIG'}->{$subsys}->{'lbl'} = Gtk2::Label->new(); + $Gtk2_table_trig->attach($setup_href->{'CAL_TRIG'}->{'TRIG'}->{$subsys}->{'lbl'}, + $l+1, $r+1, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + $t++; + $b++; + } + + $Gtk2_table_trig->set_col_spacings(1); + $Gtk2_table_trig->set_homogeneous(0); +} + +sub Gtk2_makeTable_busy() +{ + my $lable; + my $l = 0; + my $r = 1; + my $t = 0; + my $b = 1; + + #$lable = Gtk2::Label->new('BUSY'); + #$lable->set_name("green".1); + #$Gtk2_table_busy->attach($lable, $l+1, $r+1, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + foreach my $subsys (sort keys %{$setup_href->{'BUSY'}->{'BUSY_BOX'}}){ + $lable = Gtk2::Label->new($subsys); + my $ext = $l . $r . $t . $b; + $lable->set_name("blue".$ext); + $Gtk2_table_busy->attach($lable, $l, $r, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $setup_href->{'BUSY'}->{'BUSY_BOX'}->{$subsys}->{'lbl'} = Gtk2::Label->new(); + $Gtk2_table_busy->attach($setup_href->{'BUSY'}->{'BUSY_BOX'}->{$subsys}->{'lbl'}, + $l+1, $r+1, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + $t++; + $b++; + } + + $Gtk2_table_busy->set_col_spacings(1); + $Gtk2_table_busy->set_homogeneous(0); +} + +sub Gtk2_makeTable_msg() +{ + $Gtk2_errmsg_lbl = Gtk2::Label->new(); + $Gtk2_errmsg_lbl->set_name("red".1); + $Gtk2_table_msg->attach($Gtk2_errmsg_lbl, 0, 1, 0, 1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); +} + +sub Gtk2_makeTable_beam() +{ + my $lable; + my $l = 0; + my $r = 1; + my $t = 0; + my $b = 1; + + #$lable = Gtk2::Label->new('BUSY'); + #$lable->set_name("green".1); + #$Gtk2_table_busy->attach($lable, $l+1, $r+1, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + foreach my $subsys (sort keys %{$setup_href->{'BEAM'}->{'BEAM_PROFILE'}}){ + $lable = Gtk2::Label->new($subsys); + my $ext = $l . $r . $t . $b; + $lable->set_name("blue".$ext); + $Gtk2_table_beam->attach($lable, $l, $r, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $setup_href->{'BEAM'}->{'BEAM_PROFILE'}->{$subsys}->{'lbl'} = Gtk2::Label->new(); + $Gtk2_table_beam->attach($setup_href->{'BEAM'}->{'BEAM_PROFILE'}->{$subsys}->{'lbl'}, + $l+1, $r+1, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + $t++; + $b++; + } + + $Gtk2_table_beam->set_col_spacings(1); + $Gtk2_table_beam->set_homogeneous(0); +} + +sub getRegs2read() +{ + my ($regs2read_aref) = @_; + + foreach my $var (sort keys %$setup_href){ + foreach my $sys (sort keys %{$setup_href->{$var}}){ + foreach my $subsys (sort keys %{$setup_href->{$var}->{$sys}}){ + my $addr = $setup_href->{$var}->{$sys}->{$subsys}->{'addr'}; + $addr = lc($addr); + push(@$regs2read_aref, $addr) unless(any {$_ eq $addr} @$regs2read_aref); + } + } + } +} + +sub writeShellScript() +{ + my ($regs2read_aref) = @_; + + my $shell_script = "/var/diskless/etrax_fs/tmp/$shellScriptName"; + + my $fh = new FileHandle(">$shell_script"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$shell_script\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + print $fh "# This script is automatically generated by mon_cts.pl\n"; + print $fh "# Do not edit, the changes will be lost.\n\n"; + + foreach my $addr (@$regs2read_aref){ + $addr =~ s/0x//; + print $fh "echo regaddr: $addr; $cmd_base $addr\n"; + } + + $fh->close(); + + system("chmod 755 $shell_script"); +} + +sub getShellScriptName() +{ + + +} + +sub readArray() +{ + my ($aref) = @_; + + my $raddr; + my $readval = 0; + + foreach (@$aref){ + if($_ =~ /regaddr:\s+(\w+)/){ + $raddr = $1; + $readval = 1; + next; + } + + if($readval){ + chomp($_); + #$_ =~ s/0x//; + $regsVals_href->{$raddr} = $_; + $readval = 0; + } + } + + unless( defined $raddr ){ + print "Failed to read registers.\n"; + $Gtk2_errmsg_lbl->set_text("Failed to read registers"); + $Gtk2_errmsg_lbl->set_name("red".1); + #exit(1); + } +} + +sub readLog() +{ + my ($log) = @_; + + my $fh = new FileHandle("$log", "r"); + &isItDefined($fh, $log); + + my $raddr; + my $readval = 0; + + while(<$fh>){ + if($_ =~ /regaddr:\s+(\w+)/){ + $raddr = $1; + $readval = 1; + next; + } + + if($readval){ + chomp($_); + #$_ =~ s/0x//; + $regsVals_href->{$raddr} = $_; + $readval = 0; + } + } + + $fh->close; + + unless( defined $raddr ){ + print "Failed to read registers.\n"; + $Gtk2_errmsg_lbl->set_text("Failed to read registers"); + $Gtk2_errmsg_lbl->set_name("red".1); + #exit(1); + } +} + +sub fillVals2hash() +{ + foreach my $var (sort keys %$setup_href){ + foreach my $sys (sort keys %{$setup_href->{$var}}){ + foreach my $subsys (sort keys %{$setup_href->{$var}->{$sys}}){ + my $addr = lc($setup_href->{$var}->{$sys}->{$subsys}->{'addr'}); + + if( defined $regsVals_href->{$addr} ){ + my $mask = $setup_href->{$var}->{$sys}->{$subsys}->{'mask'}; + my $cont = $regsVals_href->{$addr}; + + my $val = &applyMask( $cont, &getMask($mask) ); + + unless( defined $val ){ + print "Value is undef, cont: $cont, mask: $mask\n"; + } + + #if( $subsys eq "TRIG_RATE" ){ + # print "content: $cont, addr: $addr, mask: $mask val: $val\n"; + # &getMask_debug($mask); + #} + + &Gtk2_setValAndColor($setup_href->{$var}->{$sys}->{$subsys}->{'lbl'} ,$var, $subsys, $val); + #$setup_href->{$var}->{$sys}->{$subsys}->{'val'} = $val; + #$setup_href->{$var}->{$sys}->{$subsys}->{'lbl'}->set_text($val); + } + } + } + } +} + +sub Gtk2_setValAndColor() +{ + my ($lvl_ref, $var, $subsys, $val) = @_; + + if($var eq "INPUT_EN" || $var eq "OUT_EN" || $subsys =~ /_EN$/){ + if( $val == 0 ){ + $lvl_ref->set_text("off"); + $lvl_ref->set_name("red".1); + } + elsif( $val == 1 ){ + $lvl_ref->set_text("on"); + $lvl_ref->set_name("green".1); + } + else{ + $lvl_ref->set_text("undef"); + } + } + elsif($var eq "GATING_DIS" || $subsys =~ /_DIS$/){ + if( $val == 0 ){ + $lvl_ref->set_text("off"); + $lvl_ref->set_name("green".1); + } + elsif( $val == 1 ){ + $lvl_ref->set_text("on"); + $lvl_ref->set_name("red".1); + } + else{ + $lvl_ref->set_text("undef"); + } + } + elsif($var eq "DSC"){ + $val = 2 ** $val; + $lvl_ref->set_text($val); + } + elsif($var eq "DLY_LARGE"){ + if($val){ + $val = $val * 5.; + $val = $val . " ns"; + } + $lvl_ref->set_text($val); + } + elsif($var eq "DLY_SMALL"){ + if($val){ + $val = $val * 1.25; + $val = $val . " ns"; + } + $lvl_ref->set_text($val); + } + elsif($var eq "WIDTH_SMALL"){ + if($val){ + $val = $val * 1.25; + $val = $val . " ns"; + } + $lvl_ref->set_text($val); + } + elsif($var eq "WIDTH" || $var eq "WIDTH_M"){ + if($val){ + $val = $val * 5; + $val = $val . " ns"; + } + $lvl_ref->set_text($val); + } + elsif($subsys eq "MULTIPLEX_A"){ + if($val){ + $val = $val; + } + $lvl_ref->set_text($val); + } + elsif($subsys eq "MULTIPLEX_B"){ + if($val){ + $val = $val; + } + $lvl_ref->set_text($val); + } + elsif($subsys eq "MDCA_DELAY"){ + if($val){ + $val = $val * 20; + $val = $val . " ns"; + } + $lvl_ref->set_text($val); + } + elsif($subsys eq "MDCB_DELAY"){ + if($val){ + $val = $val * 20; + $val = $val . " ns"; + } + $lvl_ref->set_text($val); + } + elsif($subsys eq "PULSER"){ + if($val){ + $val = sprintf("%.2f", 1000000000 / ($val * 5 + 10)); + $val = $val . " Hz"; + } + $lvl_ref->set_text($val); + } + elsif($subsys eq "MULT_SAMPLE"){ + $val = sprintf("%.2f", ($val*5 + 30)); + $val = $val . " ns"; + $lvl_ref->set_text($val); + } + elsif($subsys eq "EB_LUT"){ + $lvl_ref->set_text(&dec2hex($val)); + } + elsif($subsys eq "LVL1_INFO"){ + $lvl_ref->set_text(&dec2hex($val)); + } + elsif($subsys eq "OWN_TYPE"){ + $lvl_ref->set_text(&dec2hex($val)); + } + elsif($var eq "BEAM" && ( $subsys eq "SAMPLE_OFFSET" || $subsys eq "SAMPLE_PERIOD" + ) ){ + if($val){ + #- to convert to time in nanoseconds = 'val' * 100 ns + # therefore to get time in miliseconds = 'val' / 10000 + $val = sprintf("%.4f", $val / 10000); + $val = $val . " ms"; + } + $lvl_ref->set_text($val); + } + elsif($var eq "BEAM" && $subsys eq "BEAM_LENGTH"){ + if($val){ + #- to convert to time in nanoseconds = 'val' * 100 ns + # therefore to get time in seconds = 'val' / 10000000 + $val = sprintf("%.1f", $val / 10000000); + $val = $val . " s"; + } + $lvl_ref->set_text($val); + } + else{ + $lvl_ref->set_text($val); + } +} + +sub getMask() +{ + my ($bits) = @_; + + # The bits can be in two formats: + # 1. As a single digit + # 2. As two digits separated by '-': 5-3 + # which means a range of bits: 3,4,5 + + my $bit_max = $bits; + my $bit_min = $bits; + + if( $bits =~ /(\d+)-(\d+)/ ){ + $bit_max = $1; + $bit_min = $2; + } + + my $one = 1; + my $res = 0; + + foreach my $bit ($bit_min..$bit_max){ + my $val = $one << $bit; + $res = $res | $val; + } + + return $res; +} + +sub getShift() +{ + my ($bits) = @_; + + my $shift = $bits; + + if( $bits =~ /(\d+)-(\d+)/ ){ + $shift = $2; + } + + return $shift; +} + +sub getMask_debug() +{ + my ($bits) = @_; + + # The bits can be in two formats: + # 1. As a single digit + # 2. As two digits separated by '-': 5-3 + # which means a range of bits: 3,4,5 + + my $bit_max = $bits; + my $bit_min = $bits; + + if( $bits =~ /(\d+)-(\d+)/ ){ + $bit_max = $1; + $bit_min = $2; + } + + my $one = 1; + my $res = 0; + + foreach my $bit ($bit_min..$bit_max){ + my $val = $one << $bit; + $res = $res | $val; + } + + return $res; +} + +sub applyMask() +{ + my ($content, $mask) = @_; + + my $nrOfZeros = &count0(0xffffffff & $mask); + + my $val = hex($content) & $mask; + $val = $val >> $nrOfZeros; + + return $val; +} + +sub dec2hex() +{ + my ($foo) = @_; + + return sprintf("%x", $foo); +} + +sub bin2dec { + return unpack("N", pack("B32", substr("0" x 32 . shift, -32))); +} + +sub dec2bin() +{ + my ($dec) = @_; + + #my $str = unpack("B32", pack("C", $dec)); + + my $bin = sprintf("%b", $dec); + + return $bin; +} + +sub count0() +{ + my ($dec) = @_; + + my $bin = &dec2bin($dec); + + my $nrOfZeros = $bin =~ tr/0//; + + return $nrOfZeros; +} + +sub isVarDefined() +{ + my ($var, $name) = @_; + + unless( defined $var ){ + print "$name is not defined! Exit.\n"; + exit(1); + } +} + +sub isItDefined() +{ + my ($fh, $name) = @_; + + if(!$fh) { + my $txt = "\nError! Could not open file \'$name\'. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + return 0; +} + +sub print2file() +{ + my ($fh, $toprint) = @_; + + if( defined $toprint ){ + print $fh $toprint; + + if( $opt_verb || $toprint =~ /ERROR/){ + print "$toprint\n"; + } + } +} + +#################################################################### +# +# The connectCmdServer() will write the answer of command_server +# (running on the Etrax) to the file $log. Then readLog($log) will +# read this file. +# +sub connectCmdServer() +{ + my ($cmd, $remote_host, $remote_port, $protocol, $log) = @_; + + # '$cmd' can be a reference to an array of commands + # or just single command. In the first case, the commands + # from the array will be executed one after another. + + &isVarDefined( $cmd, "connectCmdServer(): cmd" ); + &isVarDefined( $remote_host, "connectCmdServer(): remote_host" ); + + my $fh = new FileHandle(">$log"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$log\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + my $answer; + my $retval = 1; + + my $socket = IO::Socket::INET->new(PeerAddr => $remote_host, + PeerPort => $remote_port, + Proto => $protocol, + Type => SOCK_STREAM) + or $answer = "ERROR: No response from Cmd Server at $remote_host:$remote_port\n"; + + unless( defined $answer ){ + $socket->autoflush(1); + print $socket "iamfromhadesdaq\n"; + $answer = <$socket>; + + &print2file($fh, $answer); + + my $reftype = reftype \$cmd; + + if( $reftype =~ /REF/ ){ + #- Loop over commands to be executed on etrax + foreach my $command ( @{$cmd} ){ + + $command = &cmdParam( $command, $remote_host ); + + print $socket "$command\n"; + + &print2file( $fh, "===> $command\n" ); + + while ( <$socket> ) { + &print2file( $fh, $_ ); + + if( $_ =~ /- END OF OUTPUT -/ ){ + last; + } + } + } + } + else{ + print $socket "$cmd\n"; + + &print2file( $fh, "===> $cmd\n" ); + + while ( <$socket> ) { + &print2file( $fh, $_ ); + + if( $_ =~ /- END OF OUTPUT -/ ){ + last; + } + } + } + + close($socket); + } + else{ + $Gtk2_errmsg_lbl->set_text("No response from Cmd Server at $remote_host:$remote_port"); + $Gtk2_errmsg_lbl->set_name("red".1); + } + + if( $answer =~ /Connection accepted/ ){ + $Gtk2_errmsg_lbl->set_text("Connection to command_server is accepted"); + $Gtk2_errmsg_lbl->set_name("green".1); + $retval = 0; + } + else{ + &print2file( $fh, $answer ); + $Gtk2_errmsg_lbl->set_text("Connection to command_server is NOT accepted"); + $Gtk2_errmsg_lbl->set_name("red".1); + } + + $fh->close(); + +# close LOG_FILE; # gk 28.03.12 + + return $retval; +} + +#################################################################### +# +# The connectCmdServer2() will write the answer of command_server +# (running on the Etrax) to the array. Then readArray() will +# read this array. +# +sub connectCmdServer2() +{ + my ($cmd, $remote_host, $remote_port, $protocol, $aref) = @_; + + # '$cmd' can be a reference to an array of commands + # or just single command. In the first case, the commands + # from the array will be executed one after another. + + &isVarDefined( $cmd, "connectCmdServer(): cmd" ); + &isVarDefined( $remote_host, "connectCmdServer(): remote_host" ); + + my $answer; + my $retval = 1; + + my $socket = IO::Socket::INET->new(PeerAddr => $remote_host, + PeerPort => $remote_port, + Proto => $protocol, + Type => SOCK_STREAM) + or $answer = "ERROR: No response from Cmd Server at $remote_host:$remote_port\n"; + + unless( defined $answer ){ + $socket->autoflush(1); + print $socket "iamfromhadesdaq\n"; + $answer = <$socket>; + + push(@$aref, $answer); + + my $reftype = reftype \$cmd; + + if( $reftype =~ /REF/ ){ + #- Loop over commands to be executed on etrax + foreach my $command ( @{$cmd} ){ + + $command = &cmdParam( $command, $remote_host ); + + print $socket "$command\n"; + push(@$aref, "===> $command"); + + while ( <$socket> ) { + push(@$aref, $_); + + if( $_ =~ /- END OF OUTPUT -/ ){ + last; + } + } + } + } + else{ + print $socket "$cmd\n"; + push(@$aref, "===> $cmd"); + + while ( <$socket> ) { + push(@$aref, $_); + + if( $_ =~ /- END OF OUTPUT -/ ){ + last; + } + } + } + + close($socket); + } + else{ + $Gtk2_errmsg_lbl->set_text("No response from Cmd Server at $remote_host:$remote_port"); + $Gtk2_errmsg_lbl->set_name("red".1); + } + + if( $answer =~ /Connection accepted/ ){ + $Gtk2_errmsg_lbl->set_text("Connection to command_server is accepted"); + $Gtk2_errmsg_lbl->set_name("green".1); + $retval = 0; + } + else{ + push(@$aref, $answer); + + $Gtk2_errmsg_lbl->set_text("Connection to command_server is NOT accepted"); + $Gtk2_errmsg_lbl->set_name("red".1); + } + + return $retval; +} + +sub readRegs_trbcmd() +{ + my $msg = "TRB-Net: OK"; + + + #my $trb_cmd1 = "/home/hadaq/bin/trbcmd rm 0x0003 0xa000 99 0"; + #my $trb_cmd2 = "/home/hadaq/bin/trbcmd rm 0x0003 0xa0c0 52 0"; # read 52 registers starting from a0c0 + + # will put HADES::TrbNet access in here... MT + + if($glob_trbnet_connected == FALSE) { + my $res = trb_init_ports(); + if($res) { + $glob_trbnet_connected = TRUE; + } + else { + $glob_trbnet_connected = FALSE; + return; + } + } + + + my $rh1=trb_register_read_mem(0x3,0xa000, 0, 111); + my $rh2=trb_register_read_mem(0x3,0xa0c0, 0, 52); + + if(!$rh1 || !$rh2) { + $msg = trb_strerror(); + $Gtk2_errmsg_lbl->set_text("$msg"); + $Gtk2_errmsg_lbl->set_name("red".1); + return; + } + + my $addr; + $addr = 0x00; + foreach my $i (0..110) { + $regsVals_href->{sprintf "%02x", $addr+$i} = sprintf "0x%08x", $rh1->{3}->[$i]; + } + + $addr = 0xc0; + foreach my $i (0..51) { + $regsVals_href->{sprintf"%02x",$addr+$i} = sprintf "0x%08x",$rh2->{3}->[$i]; + } + + #print Dumper $rh1; + #print Dumper $rh2; + #print Dumper $regsVals_href; + + $Gtk2_errmsg_lbl->set_text("$msg"); + $Gtk2_errmsg_lbl->set_name("green".1); + + return; + + + #old stuff only for reference, can be deleted as soon as the stuff above is approved to be correct, mt + + my @reg_list1 = `$trb_cmd1 2>&1`; + my @reg_list2 = `$trb_cmd2 2>&1`; + + my $mon_status1 = 0; + my $mon_status2 = 0; + + + foreach my $line (@reg_list1){ + if($line =~ /^0xa0(\w+)\s+(\w+)/){ + my $raddr = $1; + my $rval = $2; + $regsVals_href->{$raddr} = $rval; + $mon_status1 = 1; + } + elsif($line =~ /TX BUSY/){ + $msg = "TRB-Net: TX BUSY"; + } + elsif($line =~ /endpoint not reached/){ + $msg = "TRB-Net: endpoint not reached"; + } + else{ + $msg = "TRB-Net: failed to read CTS regs"; + } + } + + foreach my $line (@reg_list2){ + if($line =~ /^0xa0(\w+)\s+(\w+)/){ + my $raddr = $1; + my $rval = $2; + $regsVals_href->{$raddr} = $rval; + $mon_status2 = 1; + } + elsif($line =~ /TX BUSY/){ + $msg = "TRB-Net: TX BUSY"; + } + elsif($line =~ /endpoint not reached/){ + $msg = "TRB-Net: endpoint not reached"; + } + else{ + $msg = "TRB-Net: failed to read CTS regs"; + } + } + + if($mon_status1 == 1 && $mon_status2 == 1){ + $msg = "TRB-Net: OK"; + } + + print Dumper $regsVals_href; + + $Gtk2_errmsg_lbl->set_text("$msg"); + unless( $msg eq "TRB-Net: OK"){ + $Gtk2_errmsg_lbl->set_name("red".1); + } + else{ + $Gtk2_errmsg_lbl->set_name("green".1); + } +} + +#----------------------------------------------------------------------------------- +#---------------------- Functions for the window in 'SET' mode --------------------- +#----------------------------------------------------------------------------------- + +sub set_window() +{ + if( $opt_mode eq "mon" ){ + system("/home/hadaq/trbsoft/daq/evtbuild/mon_cts.pl -m set -e $opt_etrax -a $opt_access &"); + } + elsif( $opt_mode eq "set" ){ + $errorType = ""; + &set_registers(); # the settings with trbcmd are done inside this function + } + else{ + print "Unknown option $opt_mode. Exit.\n" if( defined $opt_mode ); + print "Undefined option opt_mode. Exit.\n" unless( defined $opt_mode ); + exit(1); + } + + if( $opt_mode eq "set" && $errorType eq "" && $opt_access eq "cmdsrv"){ + &connectCmdServer("/home/hadaq/tmp/set_cts_registers.sh", + $opt_etrax, $cmd_server_port, $cmd_server_prtcl, "/tmp/log_mon_cts_set.txt"); + } +} + +sub convertRegVal() +{ + my ($regs2write_href) = @_; + + my $errorFound = 0; + + foreach my $var (keys %$setup_href){ + + #- Skip all Vars which do not participate in setting regs + next unless( (any { $var eq $_ } @layout_set) || + (any { $var eq $_ } @layout2_set) ); + + foreach my $sys (keys %{$setup_href->{$var}}){ + + #- Loop over Rows + foreach my $subsys (sort keys %{$setup_href->{$var}->{$sys}}){ + + next if( (any { $subsys eq $_ } @layout_cal_set) || + (any { $subsys eq $_ } @layout_trig_set) || + (any { $subsys eq $_ } @layout_beam_set)); + + my $txt = $setup_href->{$var}->{$sys}->{$subsys}->{'lbl'}->get_text(); + + unless( $txt eq "" ){ + my $dec = &set_any2dec($var, $sys, $subsys, $txt); + + #print "txt: $txt dec: $dec\n"; + + $errorFound = 1 if($errorType ne "" || $dec eq "undef"); + + next unless($errorType eq ""); + + if( $dec eq "undef"){ + print "ERROR: Do not know what to do with \"$txt\" for $var $sys $subsys !\n"; + next; + } + + &set_calcRegVal($regs2write_href, $setup_href->{$var}->{$sys}->{$subsys}, $dec); + } + } + } + } + + #- Print STATUS: OK, if no error was detected + &printOkMsg("OK") if( $errorFound == 0); + +} + +sub set_registers() +{ + my %regs2write; + my $regs2write_href = \%regs2write; + + &convertRegVal($regs2write_href); + + if($opt_access eq "cmdsrv"){ + my $shell_script = "/var/diskless/etrax_fs/tmp/set_cts_registers.sh"; + + my $fh = new FileHandle(">$shell_script"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$shell_script\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + print $fh "# This script is automatically generated by mon_cts.pl\n"; + print $fh "# Do not edit, the changes will be lost.\n\n"; + + foreach my $addr (sort keys %$regs2write_href){ + my $val = &dec2hex($regs2write_href->{$addr}); + print $fh "$cmd_base_w $addr $val\n"; + } + + $fh->close(); + + system("chmod 755 $shell_script"); + } + elsif($opt_access eq "trbcmd"){ + foreach my $addr (sort keys %$regs2write_href){ + my $val = &dec2hex($regs2write_href->{$addr}); + + my $trbcmd = "/home/hadaq/bin/trbcmd w 0x0003 0xa0" . $addr . " 0x" . $val; + print "trbcmd: $trbcmd\n"; + + my @t = split("trbcmd w ", $trbcmd); # gk 28.03.12 + system("logger -p local1.info -t DAQ 'CTSMon Setting register: $t[1]'"); # gk 28.03.12 + + system($trbcmd); + } + } +} + +sub set_calcRegVal() +{ + my ($regs2write_href, $href, $dec) = @_; + + my $addr = lc($href->{'addr'}); + my $mask = &getMask($href->{'mask'}); + my $shift = &getShift($href->{'mask'}); + + #- Get reverse Mask + my $mask2 = 0xffffffff ^ $mask; + + my $regval = $regsVals_href->{$addr}; + + unless( defined $regval ){ + print "ERROR: Register content is not defined for address $addr !!!\n"; + next; + } + + #- Apply reverse mask + my $rest = hex($regval) & $mask2; + + #- Shift the new value + $dec = $dec << $shift; + + #- Remove possible overflow + $dec = &set_rmOverflow($dec, $href->{'mask'}); + + #- Final value: combine with the rest of bits + $dec = $dec | $rest; + + $regsVals_href->{$addr} = &dec2hex($dec); + $regs2write_href->{$addr} = $dec; +} + +sub set_rmOverflow() +{ + my ($val, $bits) = @_; + + my $bit_max = $bits; + if( $bits =~ /(\d+)-(\d+)/ ){ + $bit_max = $1; + } + + my $shift = 31 - $bit_max; + #print "Overflow shift: $shift bitmax: $bit_max\n"; + + $val = $val << $shift; + $val = $val >> $shift; + + return $val; +} + +sub set_any2dec() +{ + my ($var, $sys, $subsys, $txt) = @_; + + # Make here reverse calculation from any value to decimal + + my $retval = "undef"; + + if($var eq "DLY_LARGE"){ + if($txt =~ /\d+/){ + $retval = int($txt / 5.); + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed"); + } + } + elsif($var eq "DLY_SMALL" || $var eq "WIDTH_SMALL"){ + if($txt =~ /\d+/){ + if($txt > 10){ + $retval = int(10 / 1.25); + } + else{ + $retval = int($txt / 1.25); + } + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed"); + } + } + elsif($var eq "WIDTH" || $var eq "WIDTH_M"){ + if($txt =~ /\d+/){ + $retval = int($txt / 5); + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed"); + } + } + elsif($var eq "DSC"){ + if($txt =~ /\d+/){ + $retval = int(&log2($txt)); + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed"); + } + } + elsif($var eq "INPUT_EN" || $var eq "GATING_DIS" || $var eq "OUT_EN"){ + if( $txt eq "off" ){ + $retval = 0; + } + elsif( $txt eq "on" ){ + $retval = 1; + } + else{ + &printErrorMsg($var, $sys, $subsys, "only on/off are allowed"); + } + } + elsif($var eq "SCALER_OUT"){ + if($txt =~ /\d+/){ + $retval = $txt; + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed"); + } + } + elsif( $sys eq "CAL" && ($subsys =~ /_DIS$/ || $subsys =~ /_EN$/) ){ + if( $txt eq "off" ){ + $retval = 0; + } + elsif( $txt eq "on" ){ + $retval = 1; + } + } + elsif($sys eq "BEAM_PROFILE" && ( $subsys eq "MULTIPLEX_A" || $subsys eq "MULTIPLEX_B") ){ + if($txt =~ /\d+/){ + $retval = $txt; + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed or defined names: start, veto, tof, rpc, pt, delay, width, dsc, 1 ... 8"); + } + } + elsif($sys eq "TRIG" && ( $subsys eq "MDCA_DELAY" || $subsys eq "MDCB_DELAY") ){ + if($txt =~ /\d+/){ + $retval = int($txt / 20); + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed"); + } + } + elsif($sys eq "TRIG" && ( $subsys eq "START_SEL_X") ){ + if($txt =~ /\d+/){ + if($txt<3) + { + $retval = $txt; + } + else + { + &printErrorMsg($var, $sys, $subsys, "value should be 0 (1-8), 1(5-12), 2(9-16)"); + } + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed"); + } + } + + elsif($sys eq "TRIG" && ( $subsys eq "START_SEL_Y") ){ + if($txt =~ /\d+/){ + if($txt<3) + { + $retval = $txt; + } + else + { + &printErrorMsg($var, $sys, $subsys, "value should be 0 (1-8), 1(5-12), 2(9-16)"); + } + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed"); + } + } + + elsif($sys eq "TRIG" && ( $subsys eq "ANTI_COINC") ){ + if($txt =~ /\d+/){ + $retval = $txt; + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed, value should be 0(start coinc.), 1(start-veto anticoinc) or 2(TOF/RPC used as SATRT in trigg logic)"); + } + } + + elsif($sys eq "TRIG" && $subsys eq "PULSER"){ + if($txt =~ /\d+/){ + if($txt == 0){ + $retval = $txt; + } + else{ + $retval = int((1000000000/$txt - 10)/5); + } + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed"); + } + } + elsif($sys eq "TRIG" && $subsys eq "MULT_SAMPLE"){ + if($txt =~ /\d+/){ + if($txt >= int(30)) { + $retval = int($txt/5-6);} + else{ + &printErrorMsg($var, $sys, $subsys, "the lowest possible value is 30ns"); + } + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed"); + } + } + elsif($sys eq "TRIG" && $subsys eq "EB_LUT"){ + $retval = hex($txt); + } + elsif($sys eq "TRIG" && $subsys eq "LVL1_INFO"){ + $retval = hex($txt); + } + elsif($sys eq "BEAM_PROFILE" && ($subsys eq "START_V_SEL" || + $subsys eq "START_H_SEL") ){ + if($txt =~ /\d+/){ + $retval = $txt; + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed"); + } + } + + elsif($sys eq "TRIG" && ($subsys eq "EB_EVENTS" || + $subsys eq "TRIG_WIDTH") ){ + if($txt =~ /\d+/){ + $retval = $txt; + } + else{ + &printErrorMsg($var, $sys, $subsys, "only numeric values are allowed"); + } + } + elsif($sys eq "TRIG" && ($subsys eq "OWN_TYPE") ){ + $retval = hex($txt); + } + elsif($sys eq "TRIG" && $subsys eq "OWN_TYPE_EN"){ + if( $txt eq "off" ){ + $retval = 0; + } + elsif( $txt eq "on" ){ + $retval = 1; + } + else{ + &printErrorMsg($var, $sys, $subsys, "only on/off are allowed"); + } + } + + elsif($sys eq "BEAM_PROFILE" && ( $subsys eq "SAMPLE_OFFSET" || $subsys eq "SAMPLE_PERIOD" + ) ){ + if($txt){ + #- 'txt' = time in miliseconds + # the target time = 'val' (* 100 ns) + # therefore 'val' = 'txt' * 10000 + $retval = $txt * 10000; + } + } + elsif($var eq "BEAM" && $subsys eq "BEAM_LENGTH"){ + if($txt){ + #- 'txt' = time in seconds + # the target time = 'val' (* 100 ns) + # therefore 'val' = 'txt' * 10000000 + $retval = $txt * 10000000; + } + } + + return $retval; +} + +sub printErrorMsg(){ + + my ($var, $sys, $subsys, $txt) = @_; + + $errorType = "WARNING"; + + my $msg = "ERROR: For $var $sys $subsys: $txt"; + print "$msg\n"; + $Gtk2_errmsg_lbl->set_text("$msg"); + $Gtk2_errmsg_lbl->set_name("red".1); +} + +sub printOkMsg(){ + + my ($txt) = @_; + + $errorType = ""; + my $msg = "STATUS: $txt"; + + $Gtk2_errmsg_lbl->set_text("$msg"); + $Gtk2_errmsg_lbl->set_name("green".1); +} + +sub log2 { + my $n = shift; + return log($n)/log(2); +} + +sub set_writeShellScript() +{ + + +} + +sub Gtk2_makeTable_main_set() +{ + my $lable; + my $l = 2; + my $r = 3; + my $t = 0; + my $b = 1; + + foreach my $href (@layout1){ + + #- Loop over Columns + foreach my $var ( sort keys %$href ) { + + $t = 0; + $b = 1; + + next unless( any{ $var eq $_ } @layout_set); + + if( $var eq "WIDTH_SMALL"){ + $l++; + $r++; + } + + my $ext = $l . $r . $t . $b; + + $lable = Gtk2::Label->new($names_href->{$var}->{'first'}); + $lable->set_name("green".$ext); + $Gtk2_table->attach($lable, $l, $r, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $t++; + $b++; + + $lable = Gtk2::Label->new($names_href->{$var}->{'second'}); + $lable->set_name("green".$ext); + $Gtk2_table->attach($lable, $l, $r, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + foreach my $sys (@{$href->{$var}}){ + + &shiftIndex($var, $sys, \$t, \$b); + + #- Loop over Rows + foreach my $subsys (sort keys %{$setup_href->{$var}->{$sys}}){ + $setup_href->{$var}->{$sys}->{$subsys}->{'lbl'} = Gtk2::Entry->new(); + &set_entryWidth($setup_href->{$var}->{$sys}->{$subsys}->{'lbl'}, $var, $sys, $subsys); + + $t++; + $b++; + $Gtk2_table->attach($setup_href->{$var}->{$sys}->{$subsys}->{'lbl'}, + $l, $r, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + + my $addr = lc($setup_href->{$var}->{$sys}->{$subsys}->{'addr'}); + } + } + + $l++; + $r++; + } + } + +# foreach my $href (@layout2){ +# foreach my $var ( sort keys %$href ) { + +# next unless( any{ $var eq $_ } @layout_set); +# foreach my $sys (@{$href->{$var}}){ +# foreach my $subsys (sort keys %{$setup_href->{$var}->{$sys}}){ +# $setup_href->{$var}->{$sys}->{$subsys}->{'lbl'} = Gtk2::Entry->new(); +# } +# } +# } +# } + + $Gtk2_table->set_col_spacings(1); + $Gtk2_table->set_homogeneous(0); +} + +sub Gtk2_makeTable_cal_set() +{ + my $lable; + my $entry; + my $l = 0; + my $r = 1; + my $t = 0; + my $b = 1; + + #$lable = Gtk2::Label->new('CAL'); + #$lable->set_name("green".1); + #$Gtk2_table_cal->attach($lable, $l+1, $r+1, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + foreach my $subsys (sort keys %{$setup_href->{'CAL_TRIG'}->{'CAL'}}){ + + next if( any{ $subsys eq $_ } @layout_cal_set); + + my $ext = $l . $r . $t . $b; + + $lable = Gtk2::Label->new($subsys); + $lable->set_name("blue".$ext); + $Gtk2_table_cal->attach($lable, $l, $r, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $setup_href->{'CAL_TRIG'}->{'CAL'}->{$subsys}->{'lbl'} = Gtk2::Entry->new(); + &set_entryWidth($setup_href->{'CAL_TRIG'}->{'CAL'}->{$subsys}->{'lbl'}, 'CAL_TRIG', 'CAL', $subsys); + $Gtk2_table_cal->attach($setup_href->{'CAL_TRIG'}->{'CAL'}->{$subsys}->{'lbl'}, + $l+1, $r+1, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + + $t++; + $b++; + } + + $Gtk2_table_cal->set_col_spacings(1); + $Gtk2_table_cal->set_homogeneous(0); +} + +sub Gtk2_makeTable_trig_set() +{ + my $lable; + my $l = 0; + my $r = 1; + my $t = 0; + my $b = 1; + + #$lable = Gtk2::Label->new('TRIG'); + #$lable->set_name("green".1); + #$Gtk2_table_trig->attach($lable, $l+1, $r+1, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + foreach my $subsys (sort keys %{$setup_href->{'CAL_TRIG'}->{'TRIG'}}){ + + next if( any{ $subsys eq $_ } @layout_trig_set); + + $lable = Gtk2::Label->new($subsys); + my $ext = $l . $r . $t . $b; + $lable->set_name("blue".$ext); + $Gtk2_table_trig->attach($lable, $l, $r, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $setup_href->{'CAL_TRIG'}->{'TRIG'}->{$subsys}->{'lbl'} = Gtk2::Entry->new(); + &set_entryWidth($setup_href->{'CAL_TRIG'}->{'TRIG'}->{$subsys}->{'lbl'}, 'CAL_TRIG', 'TRIG', $subsys); + $Gtk2_table_trig->attach($setup_href->{'CAL_TRIG'}->{'TRIG'}->{$subsys}->{'lbl'}, + $l+1, $r+1, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + $t++; + $b++; + } + + $Gtk2_table_trig->set_col_spacings(1); + $Gtk2_table_trig->set_homogeneous(0); +} + +sub Gtk2_makeTable_beam_set() +{ + my $lable; + my $l = 0; + my $r = 1; + my $t = 0; + my $b = 1; + + #$lable = Gtk2::Label->new('TRIG'); + #$lable->set_name("green".1); + #$Gtk2_table_trig->attach($lable, $l+1, $r+1, $t, $b, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + foreach my $subsys (sort keys %{$setup_href->{'BEAM'}->{'BEAM_PROFILE'}}){ + + next if( any{ $subsys eq $_ } @layout_beam_set); + + $lable = Gtk2::Label->new($subsys); + my $ext = $l . $r . $t . $b; + $lable->set_name("blue".$ext); + $Gtk2_table_beam->attach($lable, $l, $r, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + + $setup_href->{'BEAM'}->{'BEAM_PROFILE'}->{$subsys}->{'lbl'} = Gtk2::Entry->new(); + &set_entryWidth($setup_href->{'BEAM'}->{'BEAM_PROFILE'}->{$subsys}->{'lbl'}, 'BEAM', 'BEAM_PROFILE', $subsys); + $Gtk2_table_beam->attach($setup_href->{'BEAM'}->{'BEAM_PROFILE'}->{$subsys}->{'lbl'}, + $l+1, $r+1, $t+1, $b+1, 'GTK_SHRINK', 'GTK_SHRINK', 4, 3); + $t++; + $b++; + } + + $Gtk2_table_beam->set_col_spacings(1); + $Gtk2_table_beam->set_homogeneous(0); +} + +sub set_entryWidth() +{ + my ($entry, $var, $sys, $subsys) = @_; + + my $width = 35; + my $hight = 14; + + if( $sys eq 'CAL' ){ + $entry->set_size_request($width, $hight); + } + elsif( any {$var eq $_} @layout_set ){ + $entry->set_size_request($width, $hight); + } + else{ + $entry->set_size_request(70, 14); + } +} + +sub Gtk2_button_ctrl() +{ + my $button_ctrl = Gtk2::Button->new("Save/Load"); + $button_ctrl->signal_connect(pressed => \&ctrlWindow); + + $Gtk2_hbox2->pack_start($button_ctrl, FALSE, FALSE, 0); +} + +sub cp2startup() +{ + my %regs2write; + my $regs2write_href = \%regs2write; + + &convertRegVal($regs2write_href); + + my $cts_conf = "/home/hadaq/trbsoft/daq/cts/cts_settings_mon.trbcmd"; + + my $fh = new FileHandle(">$cts_conf"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$cts_conf\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + foreach my $addr (sort keys %$regs2write_href){ + my $val = &dec2hex($regs2write_href->{$addr}); + my $cmd = "w 0x0003 0xa0" . $addr . " 0x" . $val; + print $fh "$cmd\n"; + } + + $fh->close(); +} + +sub ctrlWindow() +{ + my $loadTableListBox = Gtk2::ComboBox->new_text(); + + &populateTableList($loadTableListBox); + + my $window_ctrl = Gtk2::Window->new('toplevel'); + $window_ctrl->set_title("Ctrl"); + $window_ctrl->set_border_width(5); + $window_ctrl->resize(200,170); + my $vbox_ctrl = Gtk2::VBox->new(FALSE, 5); + + #------------------ Save frame ---------------- + my $saveFrame = Gtk2::Frame->new("Save current settings"); + my $save_vbox_ctrl = Gtk2::VBox->new(FALSE, 5); + + my $lbl_save = Gtk2::Label->new("Table name: "); + my $saveEntry = Gtk2::Entry->new; + my $saveBtn = Gtk2::Button->new("Save settings"); + $saveBtn->signal_connect(pressed => \&saveSettings, [$saveEntry, $loadTableListBox]); + + $save_vbox_ctrl->pack_start($lbl_save, FALSE, FALSE, 0); + $save_vbox_ctrl->pack_start($saveEntry, FALSE, FALSE, 0); + $save_vbox_ctrl->pack_start($saveBtn, FALSE, FALSE, 0); + + $saveFrame->add($save_vbox_ctrl); + + #------------------ Load frame ---------------- + + my $loadFrame = Gtk2::Frame->new("Load saved settings"); + + my $load_vbox_ctrl = Gtk2::VBox->new(FALSE, 5); + + my $lbl_load = Gtk2::Label->new("Table name: "); + + my $loadBtn = Gtk2::Button->new("Load"); + $loadBtn->signal_connect(pressed => \&loadSettings, [$loadTableListBox]); + + $load_vbox_ctrl->pack_start($lbl_load, FALSE, FALSE, 0); + $load_vbox_ctrl->pack_start($loadTableListBox, FALSE, FALSE, 0); + $load_vbox_ctrl->pack_start($loadBtn, FALSE, FALSE, 0); + + $loadFrame->add($load_vbox_ctrl); + + $vbox_ctrl->pack_start($saveFrame, FALSE, FALSE, 0); + $vbox_ctrl->pack_start($loadFrame, FALSE, FALSE, 0); + + $window_ctrl->add($vbox_ctrl); + $window_ctrl->show_all; +} + +sub saveSettings() +{ + my ($btn, @args) = @_; + + my $saveEntry = ${$args[0]}[0]; + my $loadTableListBox = ${$args[0]}[1]; + + my $tablePath = "./tables/" . $saveEntry->get_text . ".hsh"; + + foreach my $var (keys %$setup_href){ + foreach my $sys (keys %{$setup_href->{$var}}){ + foreach my $subsys (keys %{$setup_href->{$var}->{$sys}}){ + + if( defined $setup_href->{$var}->{$sys}->{$subsys}->{'lbl'} ){ + $setup_href->{$var}->{$sys}->{$subsys}->{'val'} = + $setup_href->{$var}->{$sys}->{$subsys}->{'lbl'}->get_text; + } + } + } + } + + store($setup_href, $tablePath); + + &populateTableList($loadTableListBox); +} + +sub loadSettings() +{ + my ($btn, @args) = @_; + + my $loadTableListBox = ${$args[0]}[0]; + + my $table = "./tables/" . $loadTableListBox->get_active_text . ".hsh"; + + my $table_href = retrieve($table); + + foreach my $var (keys %$setup_href){ + foreach my $sys (keys %{$setup_href->{$var}}){ + foreach my $subsys (keys %{$setup_href->{$var}->{$sys}}){ + + if(defined $setup_href->{$var}->{$sys}->{$subsys}->{'lbl'}){ + $setup_href->{$var}->{$sys}->{$subsys}->{'lbl'}->set_text($table_href->{$var}->{$sys}->{$subsys}->{'val'}); + } + } + } + } +} + +sub populateTableList() +{ + my ($loadTableListBox) = @_; + + for (my $i = 0; $i < 500; $i++) { + $loadTableListBox->remove_text(0); + } + + opendir(my $dir, "./tables") or die "Cannot open directory with tables!"; + my @files = grep(/\.hsh$/,readdir($dir)); + closedir($dir); + + foreach my $s (sort (@files)) { + $s =~ s/\.hsh//g; + $loadTableListBox->append_text($s); + } +} diff --git a/control/ctsmon/tables/.hsh b/control/ctsmon/tables/.hsh new file mode 100644 index 0000000000000000000000000000000000000000..795c48ae5d59bbd1a37c0a04aaaab15306f8006a GIT binary patch literal 19079 zcmb7L+j1kh4YgWwGMP|dsye>u~{QcLb-+y@xe{SAy%6hX~&NqWT*_O)I;n4P#w;k2X;~`;rIWDh8 zlR%6^Bk>jd7_qhZ5L**r*Vlpr5 z?c@ET+9%AL++_{i)mFH5+)iUW@-fD#E*=k`>c#FO1`B`pgAMxlcVXaZ#cMEt$g-b( zuz5I+*=*Hj#*v>%P8n+vAz^9qHhoL!^QFf5PIqcJUyWu;I z=(OE%!iMkK4PBTqpeW!26q0IRFR2K zc>etSPxs4zpPpYAU!QoezS4bx33@or_s9BueW;*TImUlDV1j0;769_xxrk-K@!UUd zj_Zd_^|4-?6B}P~c~BF(>o~FgwbX@^dCe_vmYLkp z^LnWE>m3y2_Ia%`>Tn({s`-7rskXPryFWv~+;tqAh9r~^QF<`NHAW_TfixJ*-gF)5T6>Gho9ChoHR%$;2Nvv?;)p7-BgezQxkVu(^D zFxdGj43RKracw?RW@0)&vpQx>f{{u8F|TcOlR#O7Icx z?GQ*jD6cl3>cjnf1E(omtpWbk1>PN9otMN*b#&J|zi;WxU3)1f)i_ihZ!WdQM}^Jf z&GgmyXs7geQz;rBt(3=`Qc>a4O7mz_CmO9`a#jqH90P+b2}!8rB+R~T zsa%Nq=-`4`e6$vnDg)k~)No0|9rfADI8~PGHISB?4u9o+KAmz7L2iShKQRSX2RQv8 zeW--~YJ8Nrh4WbhOH5|cawV=lL5yT3;ZB%=>d8#b?FlnbCYj02S;7p&LuQ|GzRep) zE*xYgC&UCBU(5P)e2$IFh~N2%Idd6}Zu!Hzw<|MO;AF=xl$o1hvXl78z8KAj>?GXM z?56Bwk)`uV*_|Gu{iKE}MIp)g0*Tvs7RM|jHMWHP)pO3i;1rr`z?N|MrP0-fogAGf zH_QZ;IbnyP(KE7ROE|HTAKCe1yQY|P0*nOT-_awJa6 zPZsGg^H9U1v;2ljV@6PeDN314W==TQk)N4VV$0_7%>(@%V^dmK8R?WphMD9FhAb?9 zXPaka{g;`l7Z^EUWu~44LtcY2lTpEtC0%AJKrm#bl$jzK3>#-33RWf!apC||OQ36dQPu*?)QvI|EId}XF*Avke(O-5&pbDGSRNI2ajnk}zp zh>i=mT4%MHib0>O0^V#gHC|mP1w6zbBbRTq6+YSDL6V(K5TCe$3ucSCl6~Q{Bf}7y z9j2N>e9am>Fgr}mkZhB=$HbS%59`(Ou7*b@%&16oXElscTH<)&ODER9`sw)@J$Fqg zK2iGd=uqv(d~@+vH*{)cdL?#U?%ngd3>AHtP+*O&7WL-wXsxb(VZ6R_Ehs;E`lnNP zIITaXX^L_vzNq>)nn;sUV4{LA)qD8r;gIG@zvRA?_agP+iS9r>NJXaq+xPG6&r)Ke zMOWY|>^^Mk+UWHYP8FH_>+6E@LNLw_9$3ry^&cd&K$F%5fPury*WRwQF+0EiwIaO!ddB0;+*1DQX4a$4+|r{*$8wK1vrCVzF7-XyOfH3vj?^A*=9YFoI*fWe z=N6tYtRhoM4Uao(6so@%Z1WfB@w)fkoElx z!R11}<7zaf;_v8?Hh)*6S2L0|!hpbzg)GKtEC6mVg}~#h3mU(Z7#eB<56p`i6@k;$ z0C>0@#A;6m#`BwzrL=jV?%F|%Dow5qf zNyl*W(_Za7i-+M|!r0>r6NcMKpqy{Q&ChvN{uTaR3dPIAo8R&(e2+E2aPz)i!QqA& zMG_4UudC+^hbsUNZ>Nt69%m23%`bTM$~T>ddy?~=Z^o`m_R4)LJ8$lvD)c?B_zX9{ z+0}DzhOYVGdv++)9VYJB^bFhq&N>M2E-9!~7~ppKQAN1q3J~C(){z$?pu32u@Ne3f zK>==;5Aj{@d;{9fA3+!LucZRqC6~J%I_uM1rKqChK;XhdKi6pu#9%d$&18qi&|E*()o zcTtV($^mV+Q)=GPMuaP7mlB2MN)pC)1sQ4Zj{kOkTyJmvOCB1WSxw>xJ~xDWCsSL# zmuV)*c|1?n<1+%u<5}JwpOI%C&xaO|&qyqf=Wu&`MkaYYZz$M?FY8A3W%o5ORBr90hL+{yltGk!1jREHynf2}3DH*s>Osj_nb15Q@0q>T+}5!H@$qYIzvPO%E!7A9|FTdtj7UI=$tGmX($UJ~3`qF zE*8M@4u{(pN{;Yh@#6y)yUYChkJsts&6~2C%@>zf@7=F&#(z6IJDZG0{`1fNvv8kp zi|KUYem;Ns^6hO=Rq*@2p8xput^2wCxGkIQ!)m#mj8V1}vK|MrZ-Q*qtd55c$@5ux zQO%=bSQ->xxQ~jY*@jdaRhP|vx9$)ws#7CM#fYNvrh~cPM{|$+>s@{9P&+9X7o-@) z%Vzgd#_6titXszIG{#kkF}QmDboks{Kl}v2g5SeplQH})E_}(lCN8pM z=h(?S9xtQVqNY@Jh|NfB-6uu~y7WeSl5}XhirOwYj~!x*D7LunTXafdt3I)k#BTb; z=D^%XmkG)F#rtl^xs$#B&&w-0w7BdSWS3_Bf)vSx63MtUyX8x!9r7s1DZJ`mnkljD z7yLjGUGxjiN$^9zpbs+y6bO89jilZ;D{MmV&c1X1aWV!ClfQp|`}%A3^UK@f%QG!D7Q8Q@Ko7^|{@8qM4z=r5UgHlQ*r8@665#6Gn+R>e z>$!j09ygEM`lsgF)T2*am3t#`M_yT7=A`F}p{A8s~V-?-r4lQD2Tc0Xe+ zrmSwF4Q#n{nDWLC?ouUVpdiO=w68Hfpd5!Wxo-iwbO#vV!v@vQdK_ zSk@qGHsWoDF+OEj)L;{gHOMN7c)Lg#f1VIDYVex`WOOnHwwP??MxG=EIDUM%v6IU9 z)E-n|r-T*Alpx%W2g6fNpaPrMLP5f7RAARTE07sQcm<8z1rkn0>+R>}aKGHT(HXKe zfj^zWMZv|eB3|)vPKGLM-=?Dion$(|&CzSchnh6d0dEpT;uGQqyjlFhd>Q6|Hp@<~ z-ZA@_ES30#C1HJ&rV^iY^njqlG25HLrlsDHzJxP)wQzh{vNgQo6TNfPa*D+pkloh0dc2KugCIg=!% zV5+2^B-_Ugo9|c>pItELjA|yV{ThN3l7xO=EEM?|S18BifxgT^AEL5`>qZw^HgFD^hL-o+mxrw@h# z-#L%CA{(qAo$;dy=18>WK6W}mKnTr=NVt&RLq!YBiAZYb9P4N%f@hIWoAvRoaW~*l zQ3>e=4LICd(s;o$4D`R|`Q-&H_d^rBpM>@B5a`!@cLwhm-I*Dcu&?_^nXkN5@@iT@ zkFKwq?bFfLA^KJ|=lkaZ3e4%KKf0&XL${jo?_a-?F)KDkX1M^jA3p7xrT&Eoe0qG^9^e(YpRw{u=jwuP#Jxx1t!lta)j!#t^YThutQXLlmb>Go zSv_oaZbI!hX2tPM!UBnh2d^f)R?+^<;uF_!$o(@&$8o>8ZT8Ef5=VZm6S)}q{e<4w zVkVk;mtlE&ujM1)ZSlmPR}*!!H`ehok6{JtJP|t2>Uz*-oLSJc6VyvHAN%8 z0ed}AO6&Ui={8@9A7jXv!`-Lmv0gXpO=e|}e50h8gC6&=oNtbw(@2dAIjVs+;1q(R zpchDnVNbq>vEbrN=5m0GuVKuU87GL*csXAIU)tkk5ToI8!Sw4`lm@{$?{*zxG*``) zIVdbjW7=F9`+^uvUvr*xIu@lPU>KUhpg8ZDY++kwhkAx;9Dz`yau|!-G(~c*L^2Ap zTVgYiC$%WZDeO6OfQ@u3FjvOesL>50=!|GtT}#tIJ68tosF6mCc-<28&lH*ftovRC z?NX=@6qXk#Vt{^tF#z<&dzAk6xE598F7l}21Lf>#kKumXp#3M{%{%2aS0l_%r!U$r z<%ao;hoR`ie0$y&=65V_pBNbL=6%|~gY&NX2OHl;+p|8q-W7Uk14G8xH8-BNE_X!) z4*9p}Ol8t7o$E%F*tR6afRZ&3D{ip1HsRdS8ax$`HQVL>HV$C$r<}){nmeRC3iro0TPvPfqdyZ`PK? zCr8MDr`m#JidE$`_waPG2BL=R*M7=MW0JQPRA5s{SdctDp@N)nB)LRWnc<1`iyZl{9b>4gKXpGAfio16va^@@nV zX*L`@Ug<%%#{=W=VPwT)*vPjpI5dQkGyRfSKS(mx?3F8?Jd2qRFoR8YN^nKTw_vr| zC8gDVyWoY*7AdhOMw={5j6Ru~Ob$x$>?BWFtx+nfC}~*NcI-sfDmwBa+UAQyQ|J+$ z6@rQ`oe-TDeHxh&okuu2TO*pgAsnl%y-6fsL@|Ii>JKG385mLe2%h5zmpj38axfzP z6WkrDAtZVym%bBw2yRy&^M`NU2yS*!xjN;L;5iH$5&a0>eykfD3UQMKeH)+fGT_t? zB0Pr%MR=-%CK%y4BrHl|VT5Nzk{V$|=a8rf?~&5>EE3Vy5f{%XfP%kBAK|{Q_yf|Q zuK@}|79|A&67P2PtQ_)p>JgojgMzOB5SUnHiW~21fn+_qn?O_SB04L2l=FzTJF-}t zHs*-V2_VlT5uHQVkvAjuW4st19yRKLac%SIT4szgAJKLz5mBRgB%-}B-~!zA-Y$=u z-EDZ!0fB+tBz<$@2LaKz0!@{kspE-Y0k0%U$5XHZULlx{r&I;J(phx;NoP{ZL&sBz zg!PpMqvKC{vQi>Co`@dSAJAqrUHs%1nU@*NcB{&aCLbiC1(|ecH;v4A@;DzY$RzZr zRleC3)oPnc^HK9il!!hk{YOpJaB+n0|22+i=0q-5ufKTZ;7D2hW;cKmdsjN_N6amGhia6kXzeirca zZ808?;LqnTU%tOBstW)9@8>^$eG7kXK5oip^SGREMnkeKm94{}?Hg}fHOu26VR<JTgUA*#+8pTE_LyA_}nZWf5Kql-~Go%L;P>y!`H$!g2=L; zL$KK$uY=jF=2RujCTzAkXT}M-c1}ByB-m~O+qL8|VKxh9v&FfOj@fK^&a7m!+jC}9 zRPGKkp*25ypN3q5?ZbawUU@;Y>+^=Pq{(?hj^xaUWcai!%au$!KB8mBV z!w($M*?Ge$8-6%%=)#NvMFAh6k<|NUNlob8#h>9{j)urE`o|Al#L433X^)Ch0=_iLM6YgF@7Iseo0F@Xu}>>QDbA@yJ%4C6_4e*~|5u2c z`^Vk>@pip&O$`5eG(_EpPMG?b%e2$UO5_Xc=bZr%Iu z)s5QuJRZt6^L>p6A)GXLXe1fDtbSCMqHX_q=xm+g!-G9mm|K!Aw;gXi@h6?6F*nS5+pocS&5{LjAYj+PKDG))Qa74Kze4lja zWD>lO6m=mHe2O`NICd;bHMVG3VkQr-&);A3=@5pvFqtC1AfeC;VuE}^6oIM^CV<%m zqcb|$d{lQ3f>@MHk*`oi5!Dz|!2aCbi%RzxrpQZ6c@b%wDXy_&yVQ16h-}Jn<3yg1 zzr23S*PCL93N|q01tJVl!3Bc6NQK}sifmxW2UZw#%?5m4VSJQDsFti+rIANTL5&|DZ}UkNeC!VqLllkRLq40r5Q#AmOHwoI(uYpy??fxPl}OxqL4wH4xTW#M1xg?@<3hokfo935ow0xSjRIFK9PJ{ua5T(+<;?6MWX98;7DtU)c%N zeYjhWf3z~6tct0GWhr5a)`JPd2dl{ojsV+@4yctU%eo^~XsXCAgsQZnD_4fABAgbOA zk@l%7ul&yHR);=4td{d;Rd43d>{A&YR!Xy)s=QWDMs9gPwIC{5?C9MER$Q97`1V^W z`i0-9IsERCY`wiV!*B2m+y?4suohPJ;_1%hFs0ze5ccJ8|Eby4t7f$}3e)6qjgEtk zJn%?tx??TLjakeB@g^3GBki1?m$4zCkO8CZO(bO1YJR470Q)6oLW;{GiWl%|cluvMe=J9jh^vqz2 zyQ(bc%uGxZ3^5vKsj$m(B&S9sgP|--wR0WvU??d(b7Vjt`A|PKrqRF%vjiakY6NII&MaVBh`Y2(2|DopJN8H7cH(Z0H+M{~#QdI-@a9r?S za`|CR;BM#OJ;>v;SHdf)MjU@mAEY7W8TSQ`GtG(n`EgmfpZI)!;1@iM>%5Ko#Y6RX zcD{|ykLt4YROq=4beTd|(s#tH%;*BVjL($6#Q5d3%D3lk`QxZ`aL5V2Dizuta&@VAMu|&{Mn7XuxKrVB8 zXQs6ve`AKkr#B~2NK{lKr6CX~y2L~%PGbTDUD6^1@pS_E&{G^OeSsIo^@$OQ)64)t zxU|FFfR2^9c_lho$gDPSBE*x0FGgc^GVLrC)=is&wR)*O?#X~!OkAJ^Zt2y4SA5L# zo@cwL_S|hL^66{~)z}laElpZ(pA1-rBIEO!J{_e`znx6<%E}pi3jrZR;DURLOI|_V5fD*86y{II46?f z#!}L7mK4K{Or+sl5DbUoIELi3)u-XCB8KP7QH73^$Z(^*roYZPWVoTCG@K>K@b)WR z=TN8{Fl^`acGm;Wi45>QGJxNU$4_Bb4Ddc8EJ{{kfcJ_d_r-wjBcj4TL~7rAiHP@- z@bNwcP{?o42e=cZJ6E0g{XeU(l^hDp2W8rue*}@f;|RH)LjfoU`P?T^f!4HW!(P8zo}<&PC$!Mys*$EOL)GO2k+@E8K(o z_8N)9fTI|+)-R6jUS$L_sulHpmO%KvAp$Fqa=ZxyMkFlm41w-JJNx9iev6rLxd5CHBr=PvBcd_>JZ{d$(_#U>xu8KU%a0-lQCIZfWXqi5-f zy!|9zVWG{@)8E;rUyuTsxgceqr6*^fexb66P2PqQzCi(znItJ;1`UVIT)r&dpc=?b zz0&AM)MN)Ch^vh@a}bIw$Tc(Dke5`Qd1*!IL-G4hS4Jemr)61AZ}z7pg|5@sh9U{K vGuVdwEIo13v<;ySDUPzYM~MuJX%!sBz>o>T(uGAhL;9x$q@JbWxAXrGJut;} literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/2012-04 Beam 2.hsh b/control/ctsmon/tables/2012-04 Beam 2.hsh new file mode 100644 index 0000000000000000000000000000000000000000..64433f2b5c751a831bbf8d4cab4d0503da9ee1e4 GIT binary patch literal 19286 zcmb7LOLH5^4Hkz~;&_u(l1s`zLMhJhA$xBWNy)6DC>2Thahj4}m({LQUL{re_W`=m z0D9P%p1Jr5e2oS^pn>kuzkh!ok6yeetI2dWzkCgUd@=mn+1c4>IB>uI$^BZuuP=-7 zcm%&ce);m_Wl>f5=U*Rx|K%n8zJ0eX>+Rigu^kObwp6lC4`p9?*{WV14++WhNqJFC z128U)z!&gK#nNI!EKSg5z2B`8!bR0IqBM*sDrY*H`%^IYxWC%1j|tdOIlEwB5-;oB z!|m02pAbLAE^EME?*v=>t?A>+`xv)+^>FxDU)_B`XW^gyVxuAcUs!l9SR?Q(+c^Z8 z`{O)_&DI>MgxG||R&8P&pt&>JktBh38PMhu$As7{h|R9r79F$LvQ4aHvFkRmDKhsS zBB41yd!1G}2ie>IJU#P=b$Jk!5MH(~EtFWa3%+5G z&e{d1Ecm8f(772MiUdADAzAP1B^9ApXMco$91Rg+^!J}`o`0!+{(1e|^N;@_lh5#% zr%zA+9F+K{|2{swEWSMQYC}c*0yFe*TT*uhLM1u>cwTDE@*rEp7p(zPr9YV3|o-W$bQp!9_yt?rq!ds!K6S zb~n6~0@2vqB5e_rQ~@&5MDOl?z2DqHZBFfORF?mmG1|%?i?i!$y|}Hn>)p-q?VrJQ z?yvXzyX(!?)iM10Xo%Dg#W1y=3$~-mN*D|-;KK)PaW%5D_Bqg_=D(AzH$#jUgYa3cKi+EDQ_+RFIy%|+=l1e43_ zLw)P6kDUW2r`P9t{s%{f43<=7*HK2Vgdm`ZS8JBLa35>)k2 zIzbr0AjZ(zi%Jv5Fv^65abD?6XOu7Ly;vv_M;PQW4U%+7T=5tp&lK@#GPHT7D}a zmm&H@WOvN*aCbGJ;|VWKPFw{L=iS%m@A=ZK5Te>15b~54gedO#n#CorO;A+jY)H97O6pkSsP@2>Mf z75zB>2_PR50ni~K^}IhsJ>~=fZdrYLYE&eN;y$NF%)*uu<( z(HdbpaE4b*7u}M0DHj3SRld{9Zd7SUk@o7w@vA1TrOd;zr#*ndl!0q{+?1gKBIv{itb}F z`Z8Odo(71J_l81~sw)|)=G!7Juq?_UJ58*PqGc%gZa@_`+MQw+_8}AOMj6)@NMA7e<0;>beMF<~i zp}#|~RxCl@e*#AKjKpaEw|>=RmedYS0apwy6<@F#%=IYeSI;wQxT z{3&2wnVr8T`jRcM43W6M3e;;cj zGFMBZ00l&LLuu5LAjk|T4fY2?CO~OafFQ{1D~(zj1W%?Pa+Z+@7*0Rskeoqol9P=Y zlp#6sl#x~>C)+Z}N^(rq(kMJ67lsXdj;8k`m^nNrqiLf{lerQKr<=rV%dHWjh99HV zsm)Xfy5$f0*(Ou#t4p$=5B^8b*^Rc+Pxg0^WSs%xp(&Vesx8EK zmBE5+hp7>gZL&)mGzOn2-)~mOw>3OJVMaxy>(nqxX^H)XPoh}=>c^)iwA?kJ_>}3_ zqp{kp`ReSiZs}BHif`YrQF8O>H(4wCgrUG9y}qiq565(P)ljS-SuZd6@kTvE!V_!# zA&sLS55K7jSWTt-D=<~TnDsmOK;n?bG3WG4o*Fm~>V|4KS!}fsRhhz--EQXwym+F12z#_NU9XIvzZnJ~gAq7-S)$^=) zINB1D2p_R){{YP=xQLISc(L(k7?9(Bb5rjZN5coh?}}zi*}=daPyBQq99ge-Y4deJ z#GLqT&iTRF<1!%)G`t*(BfhFLv{Y5mQO$kDwAo$X89>!*0a_}Xs`A30_HK6=o7>fL zQLon9g~7IArQgmKR5@2~$ZmT8bwyC*{L!m3tO98xi|@a2k}K~QzIkBxyI1qg?yc#5 z183k4bq9m#uv%X|-1Nq9oe`UIc>BJ-U$5%b#z=9KQLgr~&k+Z{8|iJ0>--o6+)XIx zM!>^uA}rF3TpoR7H4}PYpv=D?rst7_^5j_|ZgyED3Lad0QN(lV|qXSC-7BO{di3vKj2tcmvdq?JE zL;fBQft&X^kxP_UBc`DuKy>kmKs0><0A0c&0P!UU+0c_5(fcbw7?(PRCz_FgZG@{t zJP>HG%(X1hxFqe`z%c-a3!jX}?&1kYsk@$2)U9%=XFh3Di;45Ks9TgZ)GMC#yzxdM zHH~)%i>z)GQd7NQyhTpS_(rp3P%~a#`>qkWE@jj*g`@T44A7-8$R6YphXIUlhb;@35e#5_Hyi;dA8<-A zKtEDQVP$}RtR8TAVF0-3=o3cHN(L}0T;u~41+GvGV0Qo@Q28DBdqG86wiEmcJ2khCr1G2M{QMM0zjAg zAWf_}f`F68I10)XS38^v2b4K_Gd zlj>$G4jV7mH@o|X zqr0`oHZyuP#s5whWw|U_%9XI8J4U@Y=Y4CtY%I=Y%qtuDVlU36 z-0K?zv-G7S@ajgsTk5K0d3}SQ#@@MHd1Y?3?JqT=M3oo}*o&C<^m2fdYwZq|K6^3f z8-BFbX9@)UE|puY&rM0tHymlL&lC>&28k_wXG*Bs=)W$7LfOxCGOXXFxmNnjgrMK0 z&?tTGh=RT|2seUn5I2kCW_RNs8d0EQt%+IhmT(Vrs;qh98qTuynQmUcOR)6v>@BZu zaLrzxqviEG)f~M(XPehIa>ZVsv&HKhMJM8_UY^PB)s0lKmuIqj{SIZv!ipQFmbzmC zuqy*`dpdK#TnGR?*&tJC0O;vYnMwnIL1)tkF18(tj|HGkp4;st=|zqu_82iXiV4!X+&aDITB(}dPvO0%d!npg2d#7E`iplB&6bs{V8%F zifqW$HCvFkRJAfZfrrJgez>eAb;a9an!U0ArZ-s ha@z(ZzhoX#sPks=l?c>*Pj3Y literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/2012-04 Beam 3.hsh b/control/ctsmon/tables/2012-04 Beam 3.hsh new file mode 100644 index 0000000000000000000000000000000000000000..f681cc04ceadb5bfb4ee5ab3f192de216624992a GIT binary patch literal 19286 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 literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/2012-04 Beam 4.hsh b/control/ctsmon/tables/2012-04 Beam 4.hsh new file mode 100644 index 0000000000000000000000000000000000000000..7b3a7a712a1e94d8ec370427692c02c0b77d1394 GIT binary patch literal 19286 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 literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/2012-04 Beam.hsh b/control/ctsmon/tables/2012-04 Beam.hsh new file mode 100644 index 0000000000000000000000000000000000000000..34862a70eba01404b6c6b6fd4966303c7922d9bd GIT binary patch literal 17799 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 qm^f4MQN7?S9&^_vBxzHxw`=J`LyYuBa# literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/2012-04 beam 11.hsh b/control/ctsmon/tables/2012-04 beam 11.hsh new file mode 100644 index 0000000000000000000000000000000000000000..0ff56391a48004702d0fd89eb9ca3fb5f18ad410 GIT binary patch literal 19286 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 literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/2012-04 beam 12.hsh b/control/ctsmon/tables/2012-04 beam 12.hsh new file mode 100644 index 0000000000000000000000000000000000000000..bbde18e9090633f82ad0eaa096ebf8921d50103f GIT binary patch literal 19286 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 literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/2012-04 beam 8.hsh b/control/ctsmon/tables/2012-04 beam 8.hsh new file mode 100644 index 0000000000000000000000000000000000000000..c23360389bf18f8ab003da0894ac1ae172f75ad3 GIT binary patch literal 19286 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 literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/2012-04-baem 7.hsh b/control/ctsmon/tables/2012-04-baem 7.hsh new file mode 100644 index 0000000000000000000000000000000000000000..23290a348226020ffb08ad45a4ed885769f2853c GIT binary patch literal 19286 zcmb7LS#ul74Hkz~;&_u(l9!Z!gi@U0A$#8_l9E|PQ7V%1@iZl0FRNXryh^I_?*nwB z0rapjJ@eud_!`FtG`f5A@86%tqZcpAYBHV8FJHqSUkv|tc6K%z4&1MQa=#Yv>&s$1 z9>MRAU%vc!SyUDN`Pawae|ZVNZ{KapdV9BAY)3vEc~-yY&69G3k%N$YXp&HJBJ{1 zf1C%g*_u<85Sy^rs!fa&GcbkEm4p0;gJ7ItIToa)N&?inGZR~b zgSvg#9yj;f^@sW@4K*0ENlSwt#b3~-#Vx?pch}bkY%?jV4DTiv+$5BDZ`-`9F2yME zZg?pTqT$>kZ4opx0W!)&dw0LyZ|;3-jdb4$X4F5hFBK1QvOs(gV?WnR6215vV^Fdo&kL;{{4)iEF8D9T&+FP}{lvMh;m8#ebS+m zN$P#5s0)eIr@)x{`Z(@6gd`bIap+p>EkjFGgG9YosV~9LcB&NyK=9#VlQt^bj zFvX3u6H(`2Cydr-1@k=WUySlOZHSGcw-848ltxLrlQsnAu&GPD}adC1d#6<0-!rNsk>7Y1QO5FtL?}7aJ$&TnG3Tu z!g1gXub3{n74cFo0(7YSq?dJ6X-Ap%>c;jvP{$iN566-A00vVAukpX#DPySsBI=xGz8 zkt3LpZ9kd|jSU4e>CSNYhj5wQnHf!HxoHERx7Z)&r#NZ`$@&PXGSOevEIv-#w9q(v8APPg-mi{s_cxB<0K~m zlA}yYPO>MnPfD(Ny!KAbjd<}W&G)$TFKF0l)>#q`${us9%3i06C7DTcgO@A``!3n} zIkP$(ZAsFg9b>}zmF$#(Aqp5va%jgnOit=J7f+_i*q{lo&V@8L>WwAg3`xEl?SLiW zoJhVeGx3DZN|MH-4r4M==U+3JaIzyzqm&r)^Z@4-{RQAD39&QMIgJF3;tGPCT7MsF zBQjS@qX7j(4nt}5lOV_pC=K=pK_)?@648U#;HKNKvZ5HOwoltXd`xk*kO zGblrH5-FpsNKV``$Vzfd)zWA@Bo_`F_#92|M{wrwoQzHzU53n+P&hp#W=C#~5Dom8 ztxjX6LeL|B(9aH;T3=m~1$~G=M$R6zm40%*gCgq;5FeU?3E2^IC0(>Rkzok46Q*(@ zzN-utWG76GkQ|d;(V#K-MEQQRI=-#p`3Wm3B3-9}QCdqJFMJZk{#QRfJ)z}p2*syN zzaAZ{-I}k?{_2)aWv2M{4F@H69{nb3MV~Mf*reB2_4eVIPOtF{d3nK)H|iM@o>=P- zX&m?-LyS=!u$s#BS751vG3$5mfy5z=W7zXXp0XPDKubskN59lcY&7c%OvBy#U48s` zzs`cJ)fNRuUI*#kjWNLY58DHNACfWTvlwz-UaI%80-M}ocihy=yUh;H4k@5wDiK~v zgd>-bMEHnZ`v+*=!9{!o&5Mmc!-O37o11#SI2th+epfVGiU$L?J@M0d2xPt9rOnp~ z5p&|VITr_KkE?_<(C~6Bf%vNS&{B0pM>Y2q(`I*lX8={N1xQ8oyecpJZtuLq+}y5~ zi+Z)*E)2E}D@A_|RnFBLvU3lht_X^PKYDeBT_9~_@%=ZhD;5314-XuE_iDb`y*0yc z;0)ZR?qIMSR_m*Wo8B01GGbE>Z{OGV>s7tl7$t5p%Jp83IpV-~BfYJ0lOLl%xCsTr z2zclw!XnKmRG2m`+0#AsWZ!u<>&wr$!`$ zptz+Px<2;?K}n%;&k_Xr-ezhH$UzXs8*)Z9t<=&yB2SGGJ|Ob25-!9%{=}dOs-hZ^-Uf;O)SIbK^;zZW` zKm}5sF<dHD)ih2x(voEX*{P` zaEXTwxlc=Muwiv6d$+>Vp4oIy1!`ESu|gq6iAF_T38C&%fQoj?-;=zY=tT9_=M&4jSADF=~^0aeAM;`MvWCS<$*@fU&eTZ zY?&z^qJyqi&sLdI*R!?PHmWR2fHFV2Dewr{O49+1j;LOrD-91G>6(wMk)9sU+DKV{ zVV)vy1fd<$AG8pJL8=HsSrI)L5`+I-)RG;}|Of4oZ)}n4v)=;nbtmln4 z8mVc#+gN0Eqmi2G4dX3xTE;hqErXiz>N<9f%yns_mMNS?Bxp+yweDez>Hu3b(cz*Ps4Q@YVgTcFVGH2Y0^>{J2tZ}Q852?2 z+Bz>e3q|28Dn8j7%`T5Vm|crQ+%Ha*wpCi&EV4>Djp#0Ph?DpdYnWhY0{( z`h#SpD7m@^!v4mLS9EmKTOzoxxU%m zKOEhyJ&u{tt113>x+%+L$x^O_74KTdZ9|#&Wv^^hZ9FmR#kuZV$7N%2Zew2As26*2 zZslIzAef~u6MfKUTEz9d0{4{*$cIB0M)V9CWhzeD5FyJU++0)AbQm%D6RQepn zpl`&{TAwKp^t*I!wLT9eLEi|ZwLVig=o=)q^qnc8Z)5zrGzw)u_sOt+m*HCJGZTV- zmqw%Xc_Iq>&LDII-ym)l$Ib4>KQy91$6gb&-YwxC=u}(t#5ICt>oeWFewSqFtx<(0nWawF?CkjP_$8444uD!010F z01rw5fE!TT(~k)k?FZ?n*wprB;&H{HmVTJRBPhJh%EuGYHx3hdNK8EGL))WwQ@lZVEHZBRxeCY>W82Caw0T)r&Zpd?64Ug#2NjZQ);uGya= z2cn2WuCLjG>{8Y8Y>zz%I)GogG9nq47PlPV?4>1zuHD#zLJ8N{Y(f6UVdAK13qm1M i9A&$YLLZztDL9IOK@(I<7Z&Lm)NdA$`o;l%n&BqgzmqEsa1$7xEo?8|D`DX)^M{QCgi zXaGHIOwU~87w|P6AJFLT@xOn68INAQDy#F!bawF;e*0?px092T(Qx2?{>l9;;OFaN zJRZTXk55lOUKdq`zyI~|_g`MaubcOqvfkV+=9|%wWJ@LM^icMdm#yl>VV{sZJulCy zNdU&B5%>&#R4gqv#L@&^*1PR8AzV~VBTB=FqH?CAxjzMS54+3l>X3jPmD4i@Ch@Y~ zKHOfeb_wxg?6L;z)mE@|+?p}2e2mf6%ZL4^`tt501`B`h7aI-n-@?K(!5Tqi+0G%z z+#hB^Y`Wr9CB)8IY}qEp37R>h9Z3>s7XfW1c}$2+gV^-4ZP77{E!xCN7Q1Q_n;>)V zArqSO)3<4rQ;@y=&+`jAG@Z2zic9D1f*i@I5y`N$xaCUbIOIW4Qh3q6v`}K+F8Gck zI&Bx6u;9CPK^JBWC=z%Njbyc}7u1B_ocs~~ax_GQ(cgc%e)*;P`RCPdFF*c=Og_OM z&!3g+x_Elz)rN}r1y<<(Fy9^O_w{}S&B{Uk!$C04upC#6v`|TaT6bn* zYj9Av51YgKezW>mU#6jyNehD?#b3~-`7OZIcUMWdE|2!HZ^+PjEt>=>MsIn9WLkM{DL0epp?5uqX^e8zQUjJ>{TeZ5B z?rC+QHb1Wqm77^#>jM`WJsx^VMqj*#6bQZj^3dEms}IkGKVBO;UPfCPU%oplU4>wA zd41?_-Su&D;NtZ9+|U2u$dJL3uI%Ot#zM8-Jrqh0VV2rF3yIVxm=lQOh^9;Y>ru1uR=NjBztnJ;%l*saj~Cd2`e4M>#VB9XD5^l! z45bT%5e#AsEnifbFow}4ER54iS309SrG2qbB91V~V;UqGkhtS9M4l-U(`0J%OjiJ@ zc*0zm;zrtusB^FrM(eYJc^dUEM){I9#75Cu2%~&XqomzQ8v=7!_lTtFW%Lizmvmge z^)f{7h#Za?ZtkuJbll-(gp0cX;=KR*@;%?06++b8145qif)LeR05H0UO0fXM_(wlLWrUfY{+L*5F$DTfP6p&AnrT?!C<5cqe6%%5fJhHBfhvIpoF%c(XyNf?qDO;PLt?_81RB&3iOCT^ zA;$N&mAZxiHa2cCpd1LzxMgaz5x@77igC}3PWofLmn)4+aFSz7OXCWeNpoqrpef#39rtDG&AarCE*N7z8md; zCE=V%zArNIgw9Hm#-k2nGErw=GnjC)BTS=|81wi5=N0`0;4ulYGtxPY1dZYff}C1^ zA8R8rS4*P-1w;-*Y4npI$P6eA_6I>GKxuS5RLvj)+qpV0y+%m{Ya!l3IXgnkr4jcF!P47o==J1@1P8(f@%%xB`JtSsFZjBHP z{FtpyW2QpTBY)7(4w+hCU6KWTh(AWo9<-Hya=wEi>kJSdnt}=05pyYBv^kMs2(uHW zav{E}3>IW3OpTBnlU>oEG5AFJVZA)u)bRX-6%~=L)4(XLC5{(9iDLh&AD^GmayNwH zQ>I^!j@53>Hz$8}OQ$kZeEWujk~@!nleMBx7z%9CtIK-xa7d?Dy=dxZ$cr<6yiw1P z@WfhwOyj`!7-Ed-fYn5%zXD4Yj9I;h4mlYek~+6nso)H z;qJq>K76`gWkFVIi-IGsgLLo47~uPd%^trG$r$oQ3^^??)caV0O>VwDtn0caQNM; z`FeX}hTp&$xJ})`U^y&Tmk-yyG2CRtrtEJ%)c31py<8h5ZZgXCUXD59z;`3Pt#Okd zqd>R`1;Yq<=qAD<%_!v2M^;lQ(&(Il>gpq_i7_>KF&}== z=SWVBNCrW1OEq+T?hS&HLgSt#2=cwn#2Ao+AdENUjA~k`rFlf27$bZ@S@Q!GNO{J5(Z?yPVSavsSLP>{&!0g=A5IXwi+ksx`a2tcternSi0i4)a~tR~ z7%!#q9Am*H9y;VcEwRCd)rIWc3Qv1x(>)caVWq|jg%~9o6?G+qx=R5n+9`jJ@(xFK z^jAHrZRWe{FpS|p<)77xnFM1col+k&JxQ_^rnKV|me)5bOpm53X~6MO+ank?R!o%# z8bN;<;}NoDrhJGFx?Vk7WlCMo)?VAFvM2${{OG2@BV;R02QWIKdVQ`mJb0vQKC(u7 zdOT|*W&MSDio6koc1VBFLJ$V2A_!$g^k7I3Mo=OMu_DSUA@oa(PAmaf#MGrFCg{>4 z0J*a7otYzt{5>85H}7+zkf^9eOhZM0=n@lwXvPEpx}-$_;!6&)p(i<__g8{2E_IAZ zG&2KkgsVi{5a?i;8(E^`l8kEu#{fKB_+m7?i%&R8-OZe$ZnaZ==94kCICrrYb&Ilw zdc|iwZ@ke+P2=6hBC8vX)KqU6Z;{h7zAfTPZ-iuJzy-nxeM^jk$_Pe_u-uUQ97eD{BaZI%R4ADlj9`32 z9NVDcz~#XRJ;@<$mJxaqe8Am?5#ZjVS2npu8KG~- z1^}a3m;hX60l>(M0We^C27RMK4E@5tv13{TfKea@fb^=MZxp$qU&#N?3IL9D?ttF% z!LSL(0YM_PjNsOY!Wkv~e)%ZmI*RmrhC}|JGwB;sh3P-fhookw`z^Cs<;yHu@So6Ej+hBnsbF6Nbua*3Ou zUYwh`*EjfO=}WzN^)BVES7&;Ab%ULT>)fooGLPT(*BcSd#Et<65sRK)6OeGtS<%wx zAO?LSjFvt#An14L+sb|pW6(DOX|2x$4*LBlJaDFju8r~Q(k7Js+$F>M#-wf8&rAsV zUD}LVpSw)ZcLt#&_%3lhKdiUc{_zn7I(C}4X513)(XNn(U{72lShhaX&FgnbmR_Et z<<$+Y*~@dbynd&aqu1wZ^ZG`u*z0q(c>OLtM=#H0_v%Ke*vm87y?%$bV`0VPQcK@4 z0XUR_xIKe8U@ioJo@|fX;r(FxroWaNPfl{$m30 zm=rAF2GsT(WWq)JLHc<%wY`~mTydzSAFJ>b3h%Y@K}Gc4!?`>zCZ74B?a|wE>$e3! z2NE;h!hIP6Z%M56+X84-BqooK3EQBINK86MLJV3DiMf1P-()~ZkeIyMCD0n3gj8I! zKSmBj5r1zuHD#zLJ8N{Y(f6+;oMQv7KB2i jILdY(g+4fQRB&FcGH8No>B1sCgZj+^Qr|tm|M2-gh=AV? literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/2012-10 beam-3.hsh b/control/ctsmon/tables/2012-10 beam-3.hsh new file mode 100644 index 0000000000000000000000000000000000000000..26fde7d4d7f0f976f12744613c8aa8997d62790d GIT binary patch literal 19306 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 UTDq=C&!B#@fYj#?@E?8t5Bx>lI{*Lx literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/2012_10-25_test_mdc_a.hsh b/control/ctsmon/tables/2012_10-25_test_mdc_a.hsh new file mode 100644 index 0000000000000000000000000000000000000000..6e2a2270095982b7ec4db07cf7a008020d4b74e4 GIT binary patch literal 19292 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 UTDq=C&!B#@fYj#?@E?8t5Bx>lI{*Lx literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/212-10 beam-1.hsh b/control/ctsmon/tables/212-10 beam-1.hsh new file mode 100644 index 0000000000000000000000000000000000000000..40002e995789be131280166bcca2bcc6f99e095e GIT binary patch literal 19300 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 literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/BEAM5.hsh b/control/ctsmon/tables/BEAM5.hsh new file mode 100644 index 0000000000000000000000000000000000000000..326f974ccdbde171078435701e178edf50d981f3 GIT binary patch literal 18999 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 LQlA9C|8Ds|bsKgs literal 0 HcmV?d00001 diff --git a/control/ctsmon/tables/test_beam_25102012_a.hsh b/control/ctsmon/tables/test_beam_25102012_a.hsh new file mode 100644 index 0000000000000000000000000000000000000000..359f6a830d6c4bdbfe1623512e01b266b7bc786d GIT binary patch literal 18995 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 shower pedestals trigger +w 0x0003 0xA0c1 0x001CB000; #16-12:MDC34 delay, 21-17: MDC12 delay + +# can you give more details about the bits in the multiplexer here? What do you mean - more details ? +w 0x0003 0xA0c2 0x10005c6f; #Multiplexer + +w 0x0003 0xA0c3 0xffffffff; #All inputs on for monitor +w 0x0003 0xA0c5 0xffff; #fff00000; #anticoincidence +w 0x0003 0xA0c7 0x4000; # pt4 mdc temp trigger 3800; #Output enable +w 0x0003 0xA0ca 0x4000; #PT1 downscaling +w 0x0003 0xA0d1 0x22222222; #fine delay start +w 0x0003 0xA0db 0x000186a0; #sample period 10ms A plot +w 0x0003 0xA0dc 0x000186a0; #sample period 10ms B plot +w 0x0003 0xA0c8 0x000186a0; #sample period 10ms Start plot +w 0x0003 0xA0DD 0x03938700; #beam length 5s \ No newline at end of file diff --git a/cts/serials_cts.db b/cts/serials_cts.db new file mode 100644 index 0000000..6245821 --- /dev/null +++ b/cts/serials_cts.db @@ -0,0 +1,8 @@ +#Serial numbers of central trbs and their unique ids + +# s/n # unique id +########################### + 037 0x3c000001241ee028 + 058 0x3c00000123f5a328 + 900 0x9300000270e8dd28 + diff --git a/cts/startup.script b/cts/startup.script new file mode 100644 index 0000000..661fb34 --- /dev/null +++ b/cts/startup.script @@ -0,0 +1,27 @@ +#Start-up CTS + +#Assign addresses +!ifndef RESTART + set_addresses serials_cts.db addresses_cts.db #addresses for central boards +!endif + + +trbcmd clearbit 0x0003 0xa0c0 0x20000000 #set profile B to start +trbcmd w 0x0003 0xA0E0 0xcccccccc +trbcmd w 0x0003 0xA0E1 0xcc +trbcmd loadbit 0x003 0xA0C1 0x0000000F 0x00000004 +trbcmd setbit 0x0003 0xA0C2 0x01000000 + +!ifndef MON_CTS + trbcmd -f cts_settings.trbcmd +!endif + +!ifdef MON_CTS + trbcmd -f cts_settings_mon.trbcmd +!endif + +trbcmd loadbit 0x0003 0xa0f0 0xffff0000 0xfff0000 + +#Default LVL1 pattern +trbcmd w 0x0003 0xa0e4 0x700 + diff --git a/cts/trb.db b/cts/trb.db new file mode 100644 index 0000000..88b3e40 --- /dev/null +++ b/cts/trb.db @@ -0,0 +1,4 @@ +scs etraxp023 +blr etraxp107 +cts etraxp119 +pexor hadesp31 diff --git a/evtbuild/default_s.tcl b/evtbuild/default_s.tcl new file mode 100644 index 0000000..e69de29 diff --git a/evtbuild/eb.conf b/evtbuild/eb.conf new file mode 120000 index 0000000..175fb1c --- /dev/null +++ b/evtbuild/eb.conf @@ -0,0 +1 @@ +eb.conf.oct12 \ No newline at end of file diff --git a/evtbuild/eb.conf.oct12 b/evtbuild/eb.conf.oct12 new file mode 100644 index 0000000..d330ce8 --- /dev/null +++ b/evtbuild/eb.conf.oct12 @@ -0,0 +1,210 @@ +# +# #Install: Run CPAN and install +# perl -MCPAN -e shell +# +# #At CPAN shell prompt +# install Config::Std + +#---------------------------------------------- +[Main] + +PORT_BASE: 11000 +WMARK: 60000 + +EB_IP: 192.168.100.12 +EB_OUTDIR: /data/lxhadesdaq/tof_test + +# file/null +EB_OUTDEV: null + +EB_EXT: te + +# file size in MBytes +EB_FSIZE: 1500 + +EB_EVTID: 1 +SHMEMNAME: test + +QUEUESIZE: 4000000 + +# enable online server: --online +# disable online server: +ONLINESERVER: --online + +# buffer sizes for evtbuild and netmem (MB) +BUF_SIZE_LOW: 8 +BUF_SIZE_MID: 16 +BUF_SIZE_HIGH: 32 + +#---------------------------------------------- +[Parallel] + +# EB IPS NOT USED IF CONF_FROM_DB + +EB_IP_1: 192.168.100.15 +EB_IP_2: 192.168.100.12 +EB_IP_3: 192.168.100.13 +EB_IP_4: 192.168.100.14 +EB_IP_5: 192.168.100.11 + +# Number of EB processes per server NOT USED IF CONF_FROM_DB +EB_NUM_1: 1 +EB_NUM_2: 1 +EB_NUM_3: 1 +EB_NUM_4: 1 +EB_NUM_5: 1 + +BASE_PORT: 20100 +SHIFT_PORT: 100 +NUM_OF_SOURCES: 1 + +QUEUESIZE: 32 + +# EB Nr 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +#EB_LIST: 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 +EB_LIST: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +# Switch multiple disk ctrl via daq_disks (1=on,0=off) +MULTIDISK: 1 +WRITE_TO_DISK: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +#WRITE_TO_DISK: 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 0 + + +# Log the output of EB processes (log=1/dev-null=0) +EB_LOG: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +NM_LOG: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +# Switch (on=1/off=0) EPICS Control of EB processes +# IOC Master is by default the IOC for EB process 1 +EPICS_CTRL: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +# RFIO switch (on=1/off=0) for 16 EB processes +# EB Nr 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +#RFIO: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +RFIO: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +# RFIO default options for all EB processes +RFIO_PATH: rfiodaq:gstore:/hadesoct12raw/prod01 +RFIO_pcOptions: wb +#### if LUSTRE fails, switch the following RFIO_iCopyMode to 0: ##### +# 0 no copy to Lustre +# 1 copy to Lustre after the file is in the write cash, +# 2 copy in parallel to Lustre +RFIO_iCopyMode: 1 +RFIO_pcCopyPath: /lustre/hades/oct12 +RFIO_iCopyFraction: 1 +# Maxfile 100, pathconvention 1 to create new subfolder on lustre after 100 events +RFIO_iMaxFile: 0 +RFIO_iPathConvention: 0 + +# Configure EBs based on info in DB files (1=yes,0=no) +CONF_FROM_DB: 1 + +# Table with active data sources +DATA_SOURCES: ../main/data_sources.db +GBE_CONF: ../hub/register_configgbe_ip.db +CTS_CONF: ../cts/register_cts.db + +# +# The following is the individual configuration of EBs +# +#---------------------------------------------- +[EB_PROC_1] + +OUTDIR: /data01/data/ +MULTIDISK: 1 +#RESDOWNSCALE: 20 +#RESNUMEVENTS: 2000 +#RESPATH: /data22/data/res +#RESPATH: /data.local1/data/res +#RESSIZELIMIT: 80 + +#RFIO_pcFile: +#RFIO_pcOptions: + +#---------------------------------------------- +[EB_PROC_2] + +ONLINESERVER: on + +OUTDIR: /data10/data/ + +RESDOWNSCALE: 20 +RESNUMEVENTS: 2000 +RESPATH: /data.local1/data/res +RESSIZELIMIT: 80 + +#RFIO_pcFile: +#RFIO_pcOptions: + +#MULTIDISK: 18 + +#---------------------------------------------- +[EB_PROC_3] + +OUTDIR: /data10/data/ + +#---------------------------------------------- +[EB_PROC_4] + +OUTDIR: /data10/data/ +MULTIDISK: 5 + +#---------------------------------------------- +[EB_PROC_5] + +OUTDIR: /data02/data/ +MULTIDISK: 2 +#---------------------------------------------- +[EB_PROC_6] + +OUTDIR: /data11/data/ + +#---------------------------------------------- +[EB_PROC_7] + +OUTDIR: /data11/data/ + +#---------------------------------------------- +[EB_PROC_8] +OUTDIR: /data11/data/ + +#---------------------------------------------- +[EB_PROC_9] + +OUTDIR: /data03/data/ +MULTIDISK: 3 +#---------------------------------------------- +[EB_PROC_10] + +OUTDIR: /data.local1/data + +#---------------------------------------------- +[EB_PROC_11] + +OUTDIR: /data12/data/ + +#---------------------------------------------- +[EB_PROC_12] + +OUTDIR: /data12/data/ + +#---------------------------------------------- +[EB_PROC_13] + +OUTDIR: /data04/data/ +MULTIDISK: 4 +#---------------------------------------------- +[EB_PROC_14] + +OUTDIR: /data13/data/ + +#---------------------------------------------- +[EB_PROC_15] + +OUTDIR: /data.local1/data + +#---------------------------------------------- +[EB_PROC_16] + +OUTDIR: /data.local1/data diff --git a/evtbuild/eb_logmonitor.pl b/evtbuild/eb_logmonitor.pl new file mode 100755 index 0000000..33af989 --- /dev/null +++ b/evtbuild/eb_logmonitor.pl @@ -0,0 +1,297 @@ +#!/usr/bin/perl -w + +#JAM: changed oper_1 to oper_5 after moving EB server + +use strict; +use Data::Dumper; +use Tie::File; +use Fcntl; +use IO::Handle; +use IO::Socket; +use IO::Select; +use Getopt::Long; +use List::MoreUtils qw(any apply); +use Tie::File; +use threads; +use threads::shared; + +my $opt_help = 0; +my $opt_dir = "/home/hadaq/oper"; +my $opt_sleep = 5; # seconds +my $thread_sleep = 5; # seconds +my $opt_verb = 0; +my $opt_daemon = 0; + +GetOptions ('d|dir=s' => \$opt_dir, + 's|sleep=i' => \$opt_sleep, + 't|thsleep=i' => \$thread_sleep, + 'v|verb' => \$opt_verb, + 'b|daemon' => \$opt_daemon, + 'h|help' => \$opt_help); + +if( $opt_help ) { + &help(); + exit(0); +} + +my $central_log = "$opt_dir/eb_all_log.txt"; +my @tied_files; + +my $opt_sport = 50994; # open this port for status server +my $ExitCode : shared = -1; +my $status : shared = "OK"; + +# POSIX signal handlers: see signal(7) or kill(1) for available signals +foreach my $signal ( qw(HUP INT QUIT ILL ABRT FPE SEGV TERM USR1 USR2) ){ + $SIG{$signal} = sub { &exitProgram( $signal ); }; +} + +my $app_logfile = "/home/hadaq/log/daq/eb_logmonitor.log"; + +#- Daemonize +if($opt_daemon){ + open(STDIN, '>/dev/null'); + open(STDOUT, ">$app_logfile") || die "Cannot redirect STDOUT"; + open(STDERR, ">&STDOUT") || die "Cannot dup STDERR"; + select STDERR; $| = 1; # make unbuffered + select STDOUT; $| = 1; # make unbuffered +} + +#-------- Start status server thread +threads->new( \&statusServer ); + +while(1){ + &findLogFiles(); + + sleep($opt_sleep); +} + +######################## END OF MAIN ############################## + +sub help() +{ + print "\n"; + print << 'EOF'; +eb_logmonitor.pl + + This script reads log files of parallel Event Building processes. + The script starts a new thread for each log file. After processing + the log files the script writes out the formatted output with time stamp + and other information on all EBs to a separate log file. + +Usage: + + Command line: eb_logmonitor.pl + [-h|--help] : Show this help. + [-s|--sleep ] : Sleep time in sec (default: 5). + [-t|--thsleep ] : Sleep time of threads in sec (default: 5). + [-v|--verb] : More verbouse. + [-d|--dir ] : Directory with log files (default: /home/hadaq/oper). + [-b|--daemon] : Execute as a daemon. + +EOF +} + +sub exitProgram() +{ + # don't allow nested signal handling + return if ($ExitCode ne "-1"); + + # this will stop the treads, too + $ExitCode = shift; + + print "eb_logmonitor.pl exited (signal/exit code: $ExitCode).\n"; + + # wait until all threads ended - don't join the main thread or ourselves + foreach my $thread (threads->list()) + { + $thread->join() + if ($thread->tid() && !threads::equal( $thread, threads->self() )); + } + + close(STDOUT); + close(STDERR); + + # exit with code 0 in case a signal was caught + exit( $ExitCode !~ /^\d+$/ ? 0 : $ExitCode ); +} + +sub findLogFiles() +{ + opendir(DIR, $opt_dir) or die "Could not open $opt_dir: $!"; + my @log_dirs = grep(/^oper_[5|2|3|4]/, readdir(DIR)); + closedir(DIR); + + my $message = " check if mounted:"; + + $message = $message . " $opt_dir/oper_5" unless(any {$_ =~ /^oper_5$/} @log_dirs); + $message = $message . ", $opt_dir/oper_2" unless(any {$_ =~ /^oper_2$/} @log_dirs); + $message = $message . ", $opt_dir/oper_3" unless(any {$_ =~ /^oper_3$/} @log_dirs); + $message = $message . ", $opt_dir/oper_4" unless(any {$_ =~ /^oper_4$/} @log_dirs); + + unless($message eq " check if mounted:"){ + &write2log($message); + } + + #- Add full path to a dir name + my @log_list = apply{ s/oper/$opt_dir\/oper/gxms } @log_dirs; + + &checkMount(\@log_list); + + foreach my $log_dir (@log_list){ + my $log_aref = &getLogFilesFromDir($log_dir); + + foreach my $log_file (@$log_aref){ + + unless( any {$_ eq $log_file} @tied_files ){ + threads->new( \&readLogFile, $log_file ); + push(@tied_files, $log_file); + } + } + } +} + +sub write2log() +{ + my ($msg) = @_; + + my $message = sprintf("%s %10s %19s %s\n", &getTimeStamp(), "lxhadesdaq", "eb_logmonitor.pl:", $msg); + + $| = 1; + print "$message" if($opt_verb); + + open (LOGFILE, ">>$central_log") or die "Can't open $central_log : $!"; + print LOGFILE $message; + close (LOGFILE); +} + +sub getTimeStamp() +{ + my @abbr = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ); + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + $year += 1900; + + my $timestamp = sprintf("%s %02d %02d:%02d:%02d", $abbr[$mon], $mday, $hour, $min, $sec); + + return $timestamp; +} + +sub getLogFilesFromDir() +{ + my ($log_dir) = @_; + + opendir(DIR, $log_dir) or die "Could not open $opt_dir: $!"; + my @log_files = grep(/^eb\d+_log\.txt$/, readdir(DIR)); + closedir(DIR); + + #- Add full path to a dir name + my @logpath_files = apply{ s/eb/$log_dir\/eb/gxms } @log_files; + + return \@logpath_files; +} + +sub readLogFile() +{ + my ($file2read) = @_; + + print "Start new thread, read log file: $file2read\n" if($opt_verb); + + my $lastline_old = -1; + my @lines; + my $i; + + while(1){ + + tie(@lines, 'Tie::File', $file2read, mode => O_RDONLY, memory => 50000) + or die "Cannot tie file $file2read: $!\n"; + + #--- if new lines appeared in the file2read + if( $#lines > $lastline_old ){ + + open (LOGFILE, ">>$central_log") or die "Can't open $central_log : $!"; + + #--- loop over all new lines in the file2read + for( $i=$lastline_old+1; $i < (1 + $#lines); $i++ ){ + + my $line = $lines[$i]; # extract a line with index i + $| = 1; + print "$line\n" if($opt_verb); + print LOGFILE "$line\n"; + } + + close (LOGFILE); + } + + $lastline_old = (1 + $#lines) - 1; #set index of the last line to lastline_old + + if( $ExitCode ne "-1" ){ + untie(@lines); + print "Exit thread, log file: $file2read\n"; + return; + } + + sleep $thread_sleep; + } +} + +sub checkMount() +{ + my ($mdir_aref) = @_; + + my @mount_list = `mount`; + + foreach my $mdir (@$mdir_aref){ + unless(any {$_ =~ /$mdir/} @mount_list){ + my $message = " check if mounted: $mdir"; + &write2log($message); + } + } +} + +sub statusServer() +{ + my $server_socket; + my $client_socket; + my $selector; + + unless (defined( $server_socket = + IO::Socket::INET->new( LocalPort => $opt_sport, + Proto => 'tcp', + Listen => SOMAXCONN ) )) + { + print "ERROR: Cannot start status server!\n"; + } + + $selector = new IO::Select( $server_socket ); + + while(1) { + + # wait 5 seconds for connections + while (my @file_handles = $selector->can_read( 5 )) { + + foreach my $file_handle (@file_handles) { + + if($file_handle == $server_socket) { + + # create a new socket for this transaction + unless (defined( $client_socket = $server_socket->accept() )) + { + print "ERROR: Cannot open socket to send status!\n"; + &exitProgram( 2 ); + } + + print $client_socket $status; + + close( $client_socket ); + } + } + } + + if( $ExitCode ne "-1" ){ + print "Exit status server thread.\n"; + close( $server_socket ); + return; + } + } +} + diff --git a/evtbuild/scan_active_ports.pl b/evtbuild/scan_active_ports.pl new file mode 100755 index 0000000..01e5952 --- /dev/null +++ b/evtbuild/scan_active_ports.pl @@ -0,0 +1,54 @@ +#!/usr/bin/perl -w + +use English; +use strict; +use Getopt::Long; +use Getopt::Long; +use IO::Socket; + + +#perl -e 'foreach (qw(50000 50003 50004 50005 50006 50007 50009 50010 50016 50017 50018 50019 50020 50021 50022 50023 50024 50025 50026 50027 50032 50033 50034 50035 50036 50037)) {$r=qx(netcat -w1 -u -l -p $_ | hexdump | head -n 1); chomp $r; print "$_ $r\n"; }' | grep -v "0000000" + +&listen2port(50000); + +######################### END OF PERL ########################## + +sub listen2port() +{ + my ($port) = @_; + + my $socket = new IO::Socket::INET ( LocalPort => '5000', + Proto => 'udp' ) + or die "ERROR in Socket Creation : $!\n"; + + my $peer_address; + my $peer_port; + my $recieved_data; + + while(1) + { + # read operation on the socket + $socket->recv($recieved_data,1024); + + #get the peerhost and peerport at which the recent data received. + $peer_address = $socket->peerhost(); + $peer_port = $socket->peerport(); + print "\n($peer_address , $peer_port) said : $recieved_data"; + } + + $socket->close(); + + +# my $sock = new IO::Socket::INET ( LocalHost => 'lxhadesdaq', +# LocalPort => '$port', +# Proto => 'udp' +# Listen => 1, +# Reuse => 1 ) +# die "Could not create socket: $!\n" unless $sock; + +# my $new_sock = $sock->accept(); + +# while(<$new_sock>) { print $_; } +# close($sock); + +} diff --git a/evtbuild/start_daqmon_ioc.pl b/evtbuild/start_daqmon_ioc.pl new file mode 100755 index 0000000..a241eaf --- /dev/null +++ b/evtbuild/start_daqmon_ioc.pl @@ -0,0 +1,270 @@ +#!/usr/bin/perl -w + +use English; +use strict; +use Getopt::Long; +use Data::Dumper; +use FileHandle; +use List::MoreUtils qw(any apply first_index); +use File::Basename; + +#- the command line option flags +my $opt_help = 0; +my $opt_server = "192.168.100.12"; +my $opt_ioc = ""; +my $opt_test = 0; +my $opt_verb = 0; + +GetOptions ('h|help' => \$opt_help, + 's|server=s' => \$opt_server, + 'i|ioc=s' => \$opt_ioc, + 't|test' => \$opt_test, + 'v|verb' => \$opt_verb); + +if( $opt_help ) { + &help(); + exit(0); +} + +my $expect_ioc_script = "/tmp/ioc_mon_exit.exp"; +my $log_path = "/tmp/log"; + +if($opt_ioc eq "start"){ + &killIOC(); + &startIOC(); +} +elsif($opt_ioc eq "stop"){ + &killIOC(); +} + +exit(0); + +################### END OF MAIN #################### + +sub help() +{ + print "\n"; + print << 'EOF'; +start_daqmon_ioc.pl + + This script starts IOC to monitor DAQ via TRB-Net. + +Usage: + + Command line: start_eb_gbe.pl + [-h|--help] : Show this help. + [-s|--server ] : Server name where IOC will run. + [-i|--ioc ] : Start or stop IOC (default: start). + [-t|--test] : Run script in test mode (without IOC execution). + [-v|--verb] : Verbose mode. + +EOF +} + +sub startIOC() +{ + my $ioc_dir = "/home/scs/ebctrl/ioc/iocBoot/iocebctrl"; + + &writeIOC_stcmd( $ioc_dir ); + + print "Starting IOC...\n" if($opt_verb); + + my $stcmd = sprintf("st_mon%02d.cmd", 1); + my $screen_name = sprintf("ioc_mon%02d", 1); + + my $cmd = "bash; . /home/scs/.bashrc; cd $ioc_dir; screen -dmS $screen_name ../../bin/linux-x86_64/ebctrl $stcmd"; + + my $exe = "ssh -n $opt_server -l scs \"$cmd\""; + + print "Exec: $exe\n" if($opt_verb); + system($exe) unless($opt_test); +} + +sub writeIOC_stcmd() +{ + my ($ioc_dir) = @_; + + print "Copying st.cmd files to server...\n" if($opt_verb); + + my $ioc_stcmd = <$outfile"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$outfile\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + print $fh $ioc_stcmd; + $fh->close(); + + my $cmd = "scp $outfile scs\@$opt_server:$ioc_dir/."; + + print "Exec: $cmd\n" if($opt_verb); + system($cmd) unless($opt_test); +} + +sub killIOC() +{ + my %ioc; + my $ioc_href = \%ioc; + + print "Looking for running IOCs...\n" if($opt_verb); + + &findRunningIOC($ioc_href); + + &writeExpectIOC() if( defined %$ioc_href ); + + if($opt_verb){ + print "Killing running IOCs...\n"; + print "No IOCs found - nothing to kill, continue...\n" unless( defined %$ioc_href ); + } + + my (@process_list); + + foreach my $ip ( %$ioc_href ){ + foreach my $ioc ( @{$ioc_href->{$ip}} ){ + + my $cmd = $expect_ioc_script . " " . $ip . " " . $ioc; + my $log = $log_path . "/log_" . $ip . "_" . $ioc . ".txt"; + + &forkMe($cmd, $log, \@process_list); + } + } + + #- Wait for children + foreach my $cur_child_pid (@process_list) { + waitpid($cur_child_pid,0); + } +} + +sub forkMe() +{ + my ($cmd, $log, $proc_list) = @_; + + my $child = fork(); + + if( $child ){ # parent + push( @$proc_list, $child ); + } + elsif( $child == 0 ) { # child + system("$cmd > $log"); + exit(0); + } + else{ + print "Could not fork: $!\n"; + exit(1); + } +} + +sub findRunningIOC() +{ + my ($ioc_href) = @_; + + my $exe = "ssh -n $opt_server -l scs \"screen -ls\""; + + my @output = `$exe`; + + foreach my $line (@output){ + if($line =~ /\d+\.(ioc_mon\d{2})\s+/){ + my $name = $1; + push( @{$ioc_href->{$opt_server}}, $name ); + print "Found IOC: $name on $opt_server\n" if($opt_verb); + } + } +} + +sub writeExpectIOC() +{ + # This expect script can be executed to exit IOC. + + #! Look if /tmp dir exists + my $tmp_dir = dirname("/tmp"); + if ( !(-d $tmp_dir) ){ + print "\nCannot access /tmp directory!\nExit.\n"; + exit(1); + } + + my $expect_script_my = <0} { + set ip [lindex \$argv 0] + set iocname [lindex \$argv 1] +} else { + send_user "Usage: \$argv0 ip iocname\\n" +} + +spawn ssh scs@\$ip + +#expect { +# "error" { exit; } +# "login:" { exit; } +# "Password:" { exit; } +#} + +set timeout 240 + +expect "~\$ " +send "screen -r \$iocname\\r" +expect "epics> " +send "exit\\r" +expect "~\$ " + +EOF + + my $fh = new FileHandle(">$expect_ioc_script"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$expect_ioc_script\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + print $fh $expect_script_my; + $fh->close(); + + #- open permissions + system("chmod 755 $expect_ioc_script"); +} diff --git a/evtbuild/start_eb.pl b/evtbuild/start_eb.pl new file mode 100755 index 0000000..d24af1f --- /dev/null +++ b/evtbuild/start_eb.pl @@ -0,0 +1,581 @@ +#!/usr/bin/perl -w + +use English; +use strict; +use Getopt::Long; +use Data::Dumper; +use Config::Std; +use FileHandle; +use List::MoreUtils qw(any apply); +use File::Basename; + +#- the command line option flags +my $opt_help = 0; +my $opt_ebconf = "../evtbuild/eb.conf"; +my $opt_ioc = 0; +my $opt_test = 0; +my $opt_verb = 0; +my $opt_eb = "start"; + +GetOptions ('h|help' => \$opt_help, + 'c|conf=s' => \$opt_ebconf, + 'e|eb=s' => \$opt_eb, + 'i|ioc' => \$opt_ioc, + 't|test' => \$opt_test, + 'v|verb' => \$opt_verb); + +if( $opt_help ) { + &help(); + exit(0); +} + +my $expect_ioc_script = "/tmp/ioc_exit.exp"; +my $log_path = "/tmp/log"; + +my $numOfEBProcs = 0; +my @EB_Args; +my $EB_Args_aref = \@EB_Args; + +my @EB_IP_list; + +&getEBArgs( $EB_Args_aref ); + +if($opt_ioc){ + &killIOC(); + &startIOC(); +} +elsif($opt_eb eq "start"){ + &stopEvtBuilders(); + &startEvtBuilders(); +} +elsif($opt_eb eq "stop"){ + &stopEvtBuilders(); +} + +exit(0); + +################### END OF MAIN #################### + +sub help() +{ + print "\n"; + print << 'EOF'; +start_eb.pl + + This script starts parallel Event Building processes. + The script also starts IOC processes for the run control. + +Usage: + + Command line: startup.pl + [-h|--help] : Show this help. + [-c|--conf ] : Path to the config file (default: ../evtbuild/eb.conf). + [-e|--eb ] : Start or stop Event Builders (default: start). + [-i|--ioc] : Start IOC. + [-t|--test] : Test without execution. + [-v|--verb] : More verbouse. + +EOF +} + +sub getEBArgs() +{ + + my ($aref) = @_; + + my %temp_args; + my $temp_args_href = \%temp_args; + + read_config $opt_ebconf => %$temp_args_href; + + my $prefix = $temp_args_href->{'Main'}->{'EB_EXT'}; + + my $base_port = $temp_args_href->{'Parallel'}->{'BASE_PORT'}; + my $shift_port = $temp_args_href->{'Parallel'}->{'SHIFT_PORT'}; + my $source_num = $temp_args_href->{'Parallel'}->{'NUM_OF_SOURCES'}; + + #- Number of EB process + my $ebproc = 0; + + #- Default RFIO settings + my $rfio = $temp_args_href->{'Parallel'}->{'RFIO'}; + my $rfio_path = $temp_args_href->{'Parallel'}->{'RFIO_PATH'}; + my $rfio_pcOptions = $temp_args_href->{'Parallel'}->{'RFIO_pcOptions'}; + my $rfio_iCopyMode = $temp_args_href->{'Parallel'}->{'RFIO_iCopyMode'}; + my $rfio_pcCopyPath = $temp_args_href->{'Parallel'}->{'RFIO_pcCopyPath'}; + my $rfio_iCopyFrac = $temp_args_href->{'Parallel'}->{'RFIO_iCopyFraction'}; + my $rfio_iMaxFile = $temp_args_href->{'Parallel'}->{'RFIO_iMaxFile'}; + my $rfio_iPathConv = $temp_args_href->{'Parallel'}->{'RFIO_iPathConvention'}; + + my @rfio_list = split(/ /, $rfio); + + #- EPICS Controled + my $epics_ctrl = $temp_args_href->{'Parallel'}->{'EPICS_CTRL'}; + + my @epics_list = split(/ /, $epics_ctrl); + + #- Logging the output of EBs + my $eb_log = $temp_args_href->{'Parallel'}->{'EB_LOG'}; + my $nm_log = $temp_args_href->{'Parallel'}->{'NM_LOG'}; + my @eblog_list = split(/ /, $eb_log); + my @nmlog_list = split(/ /, $nm_log); + + #- Write to disk + my $write2disk = $temp_args_href->{'Parallel'}->{'WRITE_TO_DISK'}; + my @write2disk_list = split(/ /, $write2disk); + + #--- Loop over servers + foreach my $num (1..4){ + + my $ip_name = 'EB_IP_' . $num; + next unless( defined $temp_args_href->{'Parallel'}->{$ip_name} ); + + my $num_name = 'EB_NUM_' . $num; + unless( defined $temp_args_href->{'Parallel'}->{$num_name} ){ + print "\nNumber of EBs per server ($num_name) is not defined in $opt_ebconf!\n"; + print "Exit.\n"; + exit(1); + } + + my $eb_ip = $temp_args_href->{'Parallel'}->{$ip_name}; + my $eb_num = $temp_args_href->{'Parallel'}->{$num_name}; + + push(@EB_IP_list, $eb_ip); + + #--- Loop over EB processes on a given server + foreach my $ebnum (1..$eb_num){ + + #- Increment index of EB process + $ebproc++; + + #- Some checks on number of EB processes + die "Number of EB processes exceeds the number in RFIO setting! Exit." if($ebproc > 1 + $#rfio_list); + die "Number of EB processes exceeds the number in EPICS_CTRL setting! Exit." if($ebproc > 1 + $#epics_list); + + #- Here we can overwrite default rfio settings with individual settings per EB processes + # my $procname = sprintf("EB_PROC_%d", $ebproc); + # $rfio_iCopyMode = $temp_args_href->{$procname}->{'RFIO_iCopyMode'}; + + #- Calculate base port for given EB process + my $baseport = ($ebnum - 1) * $shift_port + $base_port; + + $aref->[$ebproc-1]->{'IP'} = $eb_ip; + $aref->[$ebproc-1]->{'EBNUM'} = $ebproc; + $aref->[$ebproc-1]->{'BASEPORT'} = $baseport; + $aref->[$ebproc-1]->{'SOURCENUM'} = $source_num; + $aref->[$ebproc-1]->{'PREFIX'} = $prefix; + + $aref->[$ebproc-1]->{'RFIO'} = $rfio_list[$ebproc-1]; + $aref->[$ebproc-1]->{'RFIO_PATH'} = $rfio_path; + $aref->[$ebproc-1]->{'RFIO_pcOptions'} = $rfio_pcOptions; + $aref->[$ebproc-1]->{'RFIO_iCopyMode'} = $rfio_iCopyMode; + $aref->[$ebproc-1]->{'RFIO_pcCopyPath'} = $rfio_pcCopyPath; + $aref->[$ebproc-1]->{'RFIO_iCopyFrac'} = $rfio_iCopyFrac; + $aref->[$ebproc-1]->{'RFIO_iMaxFile'} = $rfio_iMaxFile; + $aref->[$ebproc-1]->{'RFIO_iPathConv'} = $rfio_iPathConv; + + $aref->[$ebproc-1]->{'EPICS_CTRL'} = $epics_list[$ebproc-1]; + + $aref->[$ebproc-1]->{'EB_LOG'} = $eblog_list[$ebproc-1]; + $aref->[$ebproc-1]->{'NM_LOG'} = $nmlog_list[$ebproc-1]; + + if( $write2disk_list[$ebproc-1] ){ + my $eb_proc_name = "EB_PROC_" . $ebproc; + $aref->[$ebproc-1]->{'OUTDIR'} = $temp_args_href->{$eb_proc_name}->{'OUTDIR'}; + } + } + } + + $numOfEBProcs = $ebproc; +} + +sub startEvtBuilders() +{ + + my $username = "hadaq"; + + my (@process_list); + + foreach my $ebproc (1..$numOfEBProcs){ + + #--- Prepare execution of daq_evtbuild + my $cmd_eb = "/home/hadaq/bin/daq_evtbuild" . + " -m " . $EB_Args_aref->[$ebproc-1]->{'SOURCENUM'} . + " -q 16000000 " . + " -S " . $EB_Args_aref->[$ebproc-1]->{'EBNUM'} . + " --ebnum " . $EB_Args_aref->[$ebproc-1]->{'EBNUM'} . + " -x " . $EB_Args_aref->[$ebproc-1]->{'PREFIX'}; + + + if( defined $EB_Args_aref->[$ebproc-1]->{'OUTDIR'}){ + $cmd_eb = $cmd_eb . " -d file -o " . $EB_Args_aref->[$ebproc-1]->{'OUTDIR'}; + } + else{ + $cmd_eb = $cmd_eb . " -d null"; + } + + my $cpu = $EB_Args_aref->[$ebproc-1]->{'IP'}; + + #- add rfio args + my $rfio; + if( $EB_Args_aref->[$ebproc-1]->{'RFIO'} ){ + $rfio = " --rfio " . $EB_Args_aref->[$ebproc-1]->{'RFIO_PATH'} . + " --rfiolustre " . $EB_Args_aref->[$ebproc-1]->{'RFIO_pcCopyPath'} . + " --rfio_pcoption " . $EB_Args_aref->[$ebproc-1]->{'RFIO_pcOptions'} . + " --rfio_icopymode " . $EB_Args_aref->[$ebproc-1]->{'RFIO_iCopyMode'} . + " --rfio_icopyfrac " . $EB_Args_aref->[$ebproc-1]->{'RFIO_iCopyFrac'} . + " --rfio_imaxfile " . $EB_Args_aref->[$ebproc-1]->{'RFIO_iMaxFile'} . + " --rfio_ipathconv " . $EB_Args_aref->[$ebproc-1]->{'RFIO_iPathConv'}; + } + + $cmd_eb = $cmd_eb . $rfio if( defined $rfio ); + + #- add epics controlled + $cmd_eb = $cmd_eb . " --epicsctrl " if( $EB_Args_aref->[$ebproc-1]->{'EPICS_CTRL'} ); + + #- logging the output + my $eblog_file = "/tmp/log_eb_" . $EB_Args_aref->[$ebproc-1]->{'EBNUM'} . ".txt"; + my $eb_log = "1>$eblog_file 2>$eblog_file"; + $eb_log = "1>/dev/null 2>/dev/null" unless( $EB_Args_aref->[$ebproc-1]->{'EB_LOG'} ); + + my $exe_eb = "ssh -n $cpu -l $username \"bash; cd /home/hadaq/oper; export DAQ_SETUP=/home/hadaq/oper/eb; $cmd_eb $eb_log &\""; + + + #--- Prepare execution of daq_netmem + my $base_port = $EB_Args_aref->[$ebproc-1]->{'BASEPORT'}; + my $source_num = $EB_Args_aref->[$ebproc-1]->{'SOURCENUM'}; + + my $cmd_nm = "/home/hadaq/bin/daq_netmem" . + " -m " . $source_num . + " -q 16000000 " . + " -S " . $EB_Args_aref->[$ebproc-1]->{'EBNUM'}; + + #--- Loop over data sources + foreach my $source (1..$source_num){ + my $port = $base_port + $source - 1; + + $cmd_nm = $cmd_nm . " -i UDP:0.0.0.0:" . $port; + } + + #- logging the output + my $nmlog_file = "/tmp/log_nm_" . $EB_Args_aref->[$ebproc-1]->{'EBNUM'} . ".txt"; + my $nm_log = "1>$nmlog_file 2>$nmlog_file"; + $nm_log = "1>/dev/null 2>/dev/null" unless( $EB_Args_aref->[$ebproc-1]->{'NM_LOG'} ); + + my $exe_nm = "ssh -n $cpu -l $username \"bash; cd /home/hadaq/oper; $cmd_nm $nm_log &\""; + + #--- Open permissions for shared memory + my $eb_shmem = "daq_evtbuild" . $EB_Args_aref->[$ebproc-1]->{'EBNUM'} . ".shm"; + my $nm_shmem = "daq_netmem" . $EB_Args_aref->[$ebproc-1]->{'EBNUM'} . ".shm"; + my $exe_open_eb = "ssh -n $cpu -l $username \"chmod 775 /dev/shm/$eb_shmem\""; + my $exe_open_nm = "ssh -n $cpu -l $username \"chmod 775 /dev/shm/$nm_shmem\""; + + &forkEB($exe_eb, $exe_nm, $exe_open_eb, $exe_open_nm, \@process_list); + } + + #- Wait for children + foreach my $cur_child_pid (@process_list) { + waitpid($cur_child_pid,0); + } +} + +sub stopEvtBuilders() +{ + my $username = "hadaq"; + + #--- Loop over server IPs + foreach my $ip (@EB_IP_list){ + + my $exe = "ssh -n $ip -l $username \"killall daq_netmem 1>/dev/null 2>/dev/null; killall daq_evtbuild 1>/dev/null 2>/dev/null\""; + + if($opt_verb){ + print "Killing running EBs...\n"; + print "Exec: $exe\n"; + } + + system("$exe") unless($opt_test); + } +} + +sub startIOC() +{ + my $ioc_dir = "/home/scs/ebctrl/ioc/iocBoot/iocebctrl"; + + &writeIOC_stcmd( $ioc_dir ); + + print "Starting IOCs...\n" if($opt_verb); + + foreach my $ebproc (1..$numOfEBProcs){ + + my $stcmd = sprintf("st_eb%02d.cmd", $ebproc); + my $screen_name = sprintf("ioc_eb%02d", $ebproc); + + my $cmd = "bash; . /home/scs/.bashrc; cd $ioc_dir; screen -dmS $screen_name ../../bin/linux-x86_64/ebctrl $stcmd"; + my $cpu = $EB_Args_aref->[$ebproc-1]->{'IP'}; + + my $exe = "ssh -n $cpu -l scs \"$cmd\""; + + print "Exec: $exe\n" if($opt_verb); + system($exe) unless($opt_test); + } +} + +sub writeIOC_stcmd() +{ + my ($ioc_dir) = @_; + + print "Copying st.cmd files to servers...\n" if($opt_verb); + + foreach my $ebproc (1..$numOfEBProcs){ + + my $ebnum = sprintf("eb%02d", $ebproc); + + my $ebtype = "slave"; + my $comment_genrunid = "#"; + + if($ebproc == 1){ + $ebtype = "master"; + $comment_genrunid = ""; + } + + my $ioc_stcmd = <$outfile"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$outfile\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + print $fh $ioc_stcmd; + $fh->close(); + + my $ip = $EB_Args_aref->[$ebproc-1]->{'IP'}; + my $cmd = "scp $outfile scs\@$ip:$ioc_dir/."; + + print "Exec: $cmd\n" if($opt_verb); + system($cmd) unless($opt_test); + } +} + +sub killIOC() +{ + my %ioc; + my $ioc_href = \%ioc; + + print "Looking for running IOCs...\n" if($opt_verb); + + #--- Loop over server IPs + foreach my $ip (@EB_IP_list){ + + &findRunningIOC($ip, $ioc_href); + } + + &writeExpectIOC() if( defined %$ioc_href ); + + if($opt_verb){ + print "Killing running IOCs...\n"; + print "No IOCs found - nothing to kill, continue...\n" unless( defined %$ioc_href ); + } + + my (@process_list); + + foreach my $ip ( %$ioc_href ){ + foreach my $ioc ( @{$ioc_href->{$ip}} ){ + + my $cmd = $expect_ioc_script . " " . $ip . " " . $ioc; + my $log = $log_path . "/log_" . $ip . "_" . $ioc . ".txt"; + + &forkMe($cmd, $log, \@process_list); + } + } + + #- Wait for children + foreach my $cur_child_pid (@process_list) { + waitpid($cur_child_pid,0); + } +} + +sub forkMe() +{ + my ($cmd, $log, $proc_list) = @_; + + my $child = fork(); + + if( $child ){ # parent + push( @$proc_list, $child ); + } + elsif( $child == 0 ) { # child + system("$cmd > $log"); + exit(0); + } + else{ + print "Could not fork: $!\n"; + exit(1); + } +} + +sub forkEB() +{ + my ($exe_eb, $exe_nm, $exe_open_eb, $exe_open_nm, $proc_list) = @_; + + my $child = fork(); + + if( $child ){ # parent + push( @$proc_list, $child ); + } + elsif( $child == 0 ) { # child + #--- Execute Event Builder + print "Exec: $exe_eb\n" if($opt_verb); + system($exe_eb) unless($opt_test); + + sleep(1); + + #--- Open permissions for EB shared memory + print "Exec: $exe_open_eb\n" if($opt_verb); + system($exe_open_eb) unless($opt_test); + + sleep(2); + + #--- Execute Net-2-Memory + print "Exec: $exe_nm\n" if($opt_verb); + system($exe_nm) unless($opt_test); + + sleep(1); + + #--- Open permissions for NM shared memory + print "Exec: $exe_open_nm\n" if($opt_verb); + system($exe_open_nm) unless($opt_test); + + exit(0); + } + else{ + print "Could not fork: $!\n"; + exit(1); + } +} + +sub findRunningIOC() +{ + my ($cpu, $ioc_href) = @_; + + my $exe = "ssh -n $cpu -l scs \"screen -ls\""; + + my @output = `$exe`; + + foreach my $line (@output){ + if($line =~ /\d+\.(ioc_eb\d{2})\s+/){ + my $name = $1; + push( @{$ioc_href->{$cpu}}, $name ); + print "Found IOC: $name on $cpu\n" if($opt_verb); + } + } +} + +sub writeExpectIOC() +{ + # This expect script can be executed to exit IOC. + + #! Look if /tmp dir exists + my $tmp_dir = dirname("/tmp"); + if ( !(-d $tmp_dir) ){ + print "\nCannot access /tmp directory!\nExit.\n"; + exit(1); + } + + my $expect_script_my = <0} { + set ip [lindex \$argv 0] + set iocname [lindex \$argv 1] +} else { + send_user "Usage: \$argv0 ip iocname\\n" +} + +spawn ssh scs@\$ip + +#expect { +# "error" { exit; } +# "login:" { exit; } +# "Password:" { exit; } +#} + +set timeout 240 + +expect "~\$ " +send "screen -r \$iocname\\r" +expect "epics> " +send "exit\\r" +expect "~\$ " + +EOF + + my $fh = new FileHandle(">$expect_ioc_script"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$expect_ioc_script\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + print $fh $expect_script_my; + $fh->close(); + + #- open permissions + system("chmod 755 $expect_ioc_script"); +} + diff --git a/evtbuild/start_eb_gbe.pl b/evtbuild/start_eb_gbe.pl new file mode 100755 index 0000000..2d22772 --- /dev/null +++ b/evtbuild/start_eb_gbe.pl @@ -0,0 +1,1312 @@ +#!/usr/bin/perl -w + +use English; +use strict; +use Getopt::Long; +use Data::Dumper; +use Config::Std; +use FileHandle; +use List::MoreUtils qw(any apply first_index); +use File::Basename; +use Cwd; + +#- Copy all the arguments because +# later on the @ARGV becomes empty +my @arg_list = @ARGV; + +#- the command line option flags +my $opt_help = 0; +my $opt_ebconf = "/home/hadaq/trbsoft/daq/evtbuild/eb.conf"; +my $opt_ioc = ""; +my $opt_test = 0; +my $opt_verb = 0; +my $opt_eb = ""; +my @opt_ebrange = (); +my $opt_rfio = 'undef'; +my $opt_disk = 'undef'; +my $opt_online = 'undef'; +my $opt_prefix; + +GetOptions ('h|help' => \$opt_help, + 'c|conf=s' => \$opt_ebconf, + 'e|eb=s' => \$opt_eb, + 'i|ioc=s' => \$opt_ioc, + 't|test' => \$opt_test, + 'n|nr=s' => \@opt_ebrange, + 'd|disk=s' => \$opt_disk, + 'r|rfio=s' => \$opt_rfio, + 'p|prefix=s' => \$opt_prefix, + 'o|online=s' => \$opt_online, + 'v|verb' => \$opt_verb); + +if( $opt_help ) { + &help(); + exit(0); +} + +#- List of EBs provided via command line options +my $active_EBs_aref = &setArgs(); + +#- Hash with status of CPU cores of EBs (used for 'taskset') +my %EB_CPU_status; +my $EB_CPU_status_href = \%EB_CPU_status; +&init_CPU_status($EB_CPU_status_href); + +my $expect_ioc_script = "/tmp/ioc_exit.exp"; +my $log_path = "/tmp/log"; + +my %temp_args; +my $temp_args_href = \%temp_args; +read_config $opt_ebconf => %$temp_args_href; +#print Dumper $temp_args_href; +#exit; + +my $numOfEBProcs = 0; +my %EB_Args; +my $EB_Args_href = \%EB_Args; + +my @EB_IP_list; + +&getEBArgs( $EB_Args_href ); + +if($opt_ioc eq "start"){ + &killIOC(); + &startIOC(); +} +elsif($opt_ioc eq "stop"){ + &killIOC(); +} +elsif($opt_eb eq "start"){ + &writeArgs2file(); + &startEvtBuilders(); +} +elsif($opt_eb eq "stop"){ + &stopEvtBuilders(); +} +elsif($opt_eb eq "restart"){ + &stopEvtBuilders(); + sleep 1; + &writeArgs2file(); + &startEvtBuilders(); +} + +exit(0); + +################### END OF MAIN #################### + +sub help() +{ + print "\n"; + print << 'EOF'; +start_eb_gbe.pl + + This script starts parallel Event Building processes. + The script also starts IOC processes for the run control. + +Usage: + + Command line: start_eb_gbe.pl + [-h|--help] : Show this help. + [-c|--conf ] : Path to the config file (default: ../evtbuild/eb.conf). + [-e|--eb ] : Start or stop Event Builders (default: start). + [-i|--ioc ] : Start or stop IOCs (default: start). + [-n|--nr ] : Range of numbers of Event Bulders to be started. + [-d|--disk ] : Switch writing to disk on|off. + [-r|--rfio ] : Switch writing to tape on|off. + [-p|--prefix ] : Prefix of hld file. + [-o|--online ] : Switch RPC server on|off. + [-t|--test] : Test without execution. + [-v|--verb] : More verbouse. + +Examples: + + Start 6 EBs with the numbers 1,2,3,5,7 and prefix 'md': + start_eb_gbe.pl -e start -n 1-3 -n 5 -n 7 -p md + + Start EBs and enable writing to disks but disable writing to tape for all EBs: + start_eb_gbe.pl -e start --disk on --rfio off + +EOF +} + +sub init_CPU_status() +{ + my ($EB_CPU_status_href) = @_; + + # CPU affinity with 'taskset' + # + # CPU dec bin hex + # 0 1 1 + # 1 10 2 + # 2 100 4 + # 3 1000 8 + # 4 10000 10 + + #cores 0/1 reserved for system 02-05 + #cores 2/3 reserved for interrupts on 02-05 + + foreach my $core (0..7){ + if($core == 1){ + $EB_CPU_status_href->{'192.168.100.11'}->{$core} = "res"; #reserved + } + else{ + $EB_CPU_status_href->{'192.168.100.11'}->{$core} = "free"; + } + } + + foreach my $core (0..11){ + if($core < 4){ + $EB_CPU_status_href->{'192.168.100.12'}->{$core} = "res"; #reserved + $EB_CPU_status_href->{'192.168.100.13'}->{$core} = "res"; #reserved + $EB_CPU_status_href->{'192.168.100.14'}->{$core} = "res"; #reserved + } + else{ + $EB_CPU_status_href->{'192.168.100.12'}->{$core} = "free"; + $EB_CPU_status_href->{'192.168.100.13'}->{$core} = "free"; + $EB_CPU_status_href->{'192.168.100.14'}->{$core} = "free"; + } + } + + foreach my $core (0..23){ + if($core < 4){ + $EB_CPU_status_href->{'192.168.100.15'}->{$core} = "res"; #reserved + } + else{ + $EB_CPU_status_href->{'192.168.100.15'}->{$core} = "free"; + } + } +} + +sub getCoreNr() +{ + my ($ip) = @_; + + my $core_nr; + + foreach my $eb_ip (sort keys %$EB_CPU_status_href){ + next unless($ip eq $eb_ip); + + foreach my $core ( sort {$a <=> $b} keys %{$EB_CPU_status_href->{$eb_ip}} ){ + my $core_status = $EB_CPU_status_href->{$eb_ip}->{$core}; + + next unless(lc($core_status) eq "free"); + + $core_nr = $core; + $EB_CPU_status_href->{$eb_ip}->{$core} = "busy"; + last; + } + } + + #- If no free cores left - take reserved cores + unless( defined $core_nr ){ + foreach my $eb_ip (sort keys %$EB_CPU_status_href){ + next unless($ip eq $eb_ip); + + foreach my $core ( sort {$a <=> $b} keys %{$EB_CPU_status_href->{$eb_ip}} ){ + my $core_status = $EB_CPU_status_href->{$eb_ip}->{$core}; + + if(lc($core_status) eq "res"){ + $core_nr = $core; + $EB_CPU_status_href->{$eb_ip}->{$core} = "busy"; + last; + } + } + } + } + + unless( defined $core_nr ){ + print "No free cores left on CPU $ip. Exit.\n"; + exit(0); + } + + return $core_nr; +} + +sub setArgs() +{ + my @active_EBs; + + if(@opt_ebrange){ + foreach my $range (@opt_ebrange){ + if($range =~ /(\d+)-(\d+)/){ + my $max = $1; + my $min = $2; + + foreach my $eb ($max..$min){ + #- 1 must be subtracted to match + # EB numbering in the register_configgbe_ip.db + # which starts from zero + &checkEB_nr($eb); + push(@active_EBs, $eb-1); + } + } + elsif($range =~ /(\d+)/){ + &checkEB_nr($1); + push(@active_EBs, $1-1); + } + } + } + + return \@active_EBs; +} + +sub checkEB_nr() +{ + my ($eb_nr) = @_; + + if( $eb_nr < 1 || $eb_nr > 16 ){ + print "ERROR: EB number should be in the range 1-16. Exit."; + exit(0); + } +} + +sub getEBArgs() +{ + my ($href) = @_; + + my $prefix = $temp_args_href->{'Main'}->{'EB_EXT'}; + $prefix = $opt_prefix if( defined $opt_prefix ); + my $filesize = $temp_args_href->{'Main'}->{'EB_FSIZE'}; + + my $base_port = $temp_args_href->{'Parallel'}->{'BASE_PORT'}; + my $shift_port = $temp_args_href->{'Parallel'}->{'SHIFT_PORT'}; + my $source_num = $temp_args_href->{'Parallel'}->{'NUM_OF_SOURCES'}; + my $queuesize = $temp_args_href->{'Parallel'}->{'QUEUESIZE'}; + + my $multidisk = $temp_args_href->{'Parallel'}->{'MULTIDISK'}; + + #- Number of EB process + my $ebproc = 0; + + #- List of BEs + my $listOfEBs = $temp_args_href->{'Parallel'}->{'EB_LIST'}; + my @eb_list = split(/\s+/, $listOfEBs); + + #- Default RFIO settings + my $rfio = $temp_args_href->{'Parallel'}->{'RFIO'}; + my $rfio_path = $temp_args_href->{'Parallel'}->{'RFIO_PATH'}; + my $rfio_pcOptions = $temp_args_href->{'Parallel'}->{'RFIO_pcOptions'}; + my $rfio_iCopyMode = $temp_args_href->{'Parallel'}->{'RFIO_iCopyMode'}; + my $rfio_pcCopyPath = $temp_args_href->{'Parallel'}->{'RFIO_pcCopyPath'}; + my $rfio_iCopyFrac = $temp_args_href->{'Parallel'}->{'RFIO_iCopyFraction'}; + my $rfio_iMaxFile = $temp_args_href->{'Parallel'}->{'RFIO_iMaxFile'}; + my $rfio_iPathConv = $temp_args_href->{'Parallel'}->{'RFIO_iPathConvention'}; + + my @rfio_list = split(/\s+/, $rfio); + + #- EPICS Controled + my $epics_ctrl = $temp_args_href->{'Parallel'}->{'EPICS_CTRL'}; + + my @epics_list = split(/\s+/, $epics_ctrl); + + #- Logging the output of EBs + my $eb_log = $temp_args_href->{'Parallel'}->{'EB_LOG'}; + my $nm_log = $temp_args_href->{'Parallel'}->{'NM_LOG'}; + my @eblog_list = split(/\s+/, $eb_log); + my @nmlog_list = split(/\s+/, $nm_log); + + #- Write to disk + my $write2disk = $temp_args_href->{'Parallel'}->{'WRITE_TO_DISK'}; + my @write2disk_list = split(/\s+/, $write2disk); + + #--- Read GbE configuration + my %eb_ids_gbe_hash; + my $eb_ids_gbe_href = \%eb_ids_gbe_hash; + + &getGbEconfig($eb_ids_gbe_href); + + #--- Loop over all EB processes + #print Dumper $eb_ids_gbe_href; + #exit; + foreach my $ebproc ( sort keys %{$eb_ids_gbe_href} ){ + + #- If there was a list of EBs provided via command line options + # go to the next $ebproc if the current $ebproc is not in this list. + #print "active EBs:\n"; + #print Dumper $active_EBs_aref; + + if(@$active_EBs_aref){ + next unless( any {$_ == $ebproc} @$active_EBs_aref ); #from command line args + } + else{ + next unless( $eb_list[$ebproc] ); #from eb.conf + } + + + my $eb_ip = $eb_ids_gbe_href->{$ebproc}->{'IP'}; + + #- Save IP needed by other function to stop EBs. + push(@EB_IP_list, $eb_ip) unless( any {$_ eq $eb_ip} @EB_IP_list ); + + #- Some checks on number of EB processes + die "Number of EB processes exceeds the number in RFIO setting! Exit." if($ebproc > $#rfio_list); + die "Number of EB processes exceeds the number in EPICS_CTRL setting! Exit." if($ebproc > $#epics_list); + + #- Here we can overwrite default rfio settings with individual settings per EB processes + my $procname = sprintf("EB_PROC_%d", 1+$ebproc); + # $rfio_iCopyMode = $temp_args_href->{$procname}->{'RFIO_iCopyMode'}; + + $href->{$ebproc}->{'IP'} = $eb_ip; + $href->{$ebproc}->{'EBNUM'} = $ebproc+1; + $href->{$ebproc}->{'BASEPORT'} = $base_port; + $href->{$ebproc}->{'PORT_LIST'} = $eb_ids_gbe_href->{$ebproc}->{'port_list'}; + $href->{$ebproc}->{'SOURCENUM'} = scalar @{$eb_ids_gbe_href->{$ebproc}->{'port_list'}}; + $href->{$ebproc}->{'BUFSIZE_LIST'} = $eb_ids_gbe_href->{$ebproc}->{'bufsize_list'}; + $href->{$ebproc}->{'PREFIX'} = $prefix; + $href->{$ebproc}->{'QUEUESIZE'} = $queuesize; + $href->{$ebproc}->{'MULTIDISK'} = $multidisk; + $href->{$ebproc}->{'FILESIZE'} = $filesize; + + if( defined $temp_args_href->{$procname}->{'MULTIDISK'} ){ + $href->{$ebproc}->{'MULTIDISK'} = $temp_args_href->{$procname}->{'MULTIDISK'}; + } + elsif($multidisk){ + $href->{$ebproc}->{'MULTIDISK'} = $href->{$ebproc}->{'EBNUM'}; + } + else{ + $href->{$ebproc}->{'MULTIDISK'} = $multidisk; + } + + if( defined $temp_args_href->{$procname}->{'RESDOWNSCALE'} ){ + $href->{$ebproc}->{'RESDOWNSCALE'} = $temp_args_href->{$procname}->{'RESDOWNSCALE'}; + $href->{$ebproc}->{'RESNUMEVENTS'} = $temp_args_href->{$procname}->{'RESNUMEVENTS'}; + $href->{$ebproc}->{'RESPATH'} = $temp_args_href->{$procname}->{'RESPATH'}; + $href->{$ebproc}->{'RESSIZELIMIT'} = $temp_args_href->{$procname}->{'RESSIZELIMIT'}; + } + + if( defined $temp_args_href->{$procname}->{'ONLINESERVER'} ){ + if($opt_online eq "on"){ + $href->{$ebproc}->{'ONLINESERVER'} = "on"; + } + elsif($opt_online eq "off"){ + $href->{$ebproc}->{'ONLINESERVER'} = "off"; + } + else{ + $href->{$ebproc}->{'ONLINESERVER'} = $temp_args_href->{$procname}->{'ONLINESERVER'}; + } + } + else{ + $href->{$ebproc}->{'ONLINESERVER'} = "off"; + } + + $href->{$ebproc}->{'RFIO'} = $rfio_list[$ebproc] if(lc($opt_rfio) eq 'undef'); # 0|1 + $href->{$ebproc}->{'RFIO'} = 1 if(lc($opt_rfio) eq 'on'); # 0|1 + $href->{$ebproc}->{'RFIO'} = 0 if(lc($opt_rfio) eq 'off'); # 0|1 + $href->{$ebproc}->{'RFIO_PATH'} = $rfio_path; + $href->{$ebproc}->{'RFIO_pcOptions'} = $rfio_pcOptions; + $href->{$ebproc}->{'RFIO_iCopyMode'} = $rfio_iCopyMode; + $href->{$ebproc}->{'RFIO_pcCopyPath'} = $rfio_pcCopyPath; + $href->{$ebproc}->{'RFIO_iCopyFrac'} = $rfio_iCopyFrac; + $href->{$ebproc}->{'RFIO_iMaxFile'} = $rfio_iMaxFile; + $href->{$ebproc}->{'RFIO_iPathConv'} = $rfio_iPathConv; + + $href->{$ebproc}->{'EPICS_CTRL'} = $epics_list[$ebproc]; # 0|1 + + $href->{$ebproc}->{'EB_LOG'} = $eblog_list[$ebproc]; # 0|1 + $href->{$ebproc}->{'NM_LOG'} = $nmlog_list[$ebproc]; # 0|1 + + if( $write2disk_list[$ebproc] && lc($opt_disk) eq 'undef' ){ + if(&isVarDefined($temp_args_href->{$procname}->{'OUTDIR'}, "OUTDIR for $procname")){ + $href->{$ebproc}->{'OUTDIR'} = $temp_args_href->{$procname}->{'OUTDIR'}; + } + } + elsif( lc($opt_disk) eq 'on' ){ + if(&isVarDefined($temp_args_href->{$procname}->{'OUTDIR'}, "OUTDIR for $procname")){ + $href->{$ebproc}->{'OUTDIR'} = $temp_args_href->{$procname}->{'OUTDIR'}; + } + } + elsif( lc($opt_disk) eq 'off' ){ + #- do not do anything. If $href->{$ebproc}->{'OUTDIR'} is undefined, + # the data will go to /dev/null + } + } + + $numOfEBProcs = $ebproc; +} + +sub isVarDefined() +{ + my ($var, $msg) = @_; + + my $retval = 1; + + unless( defined $var ){ + print "Undefined variable found: $msg\n"; + $retval = 0; + } + + return $retval; +} + +sub getVarSizeArg() +{ + my ($ebproc) = @_; + + my $i = 0; + my $arg = " "; + + foreach my $size (@{$EB_Args_href->{$ebproc}->{'BUFSIZE_LIST'}}){ + + if($EB_Args_href->{$ebproc}->{'BUFSIZE_LIST'}->[$i] == + $EB_Args_href->{$ebproc}->{'QUEUESIZE'}){ + $i++; + next; + } + + $arg = $arg . " -Q " . $i . ":" . $EB_Args_href->{$ebproc}->{'BUFSIZE_LIST'}->[$i]; + $i++; + } + + return $arg; +} + +sub startEvtBuilders() +{ + + my $username = "hadaq"; + + my (@process_list); + + foreach my $ebproc (sort {$a <=> $b} keys %$EB_Args_href){ + + my $ebnum2print = $ebproc+1; + print "EB process: $ebnum2print\n"; + + #--- Prepare execution of daq_evtbuild + my $cmd_eb = "/home/hadaq/bin/daq_evtbuild" . + " -m " . $EB_Args_href->{$ebproc}->{'SOURCENUM'} . + " -q " . $EB_Args_href->{$ebproc}->{'QUEUESIZE'} . + " -S " . $EB_Args_href->{$ebproc}->{'EBNUM'} . + " --ebnum " . $EB_Args_href->{$ebproc}->{'EBNUM'} . + " -x " . $EB_Args_href->{$ebproc}->{'PREFIX'}; + + #- add queue variable size args + my $varsize_arg = &getVarSizeArg($ebproc); + $cmd_eb = $cmd_eb . $varsize_arg; + + #- add output type + if( defined $EB_Args_href->{$ebproc}->{'OUTDIR'} ){ + if($EB_Args_href->{$ebproc}->{'MULTIDISK'}){ + $cmd_eb = $cmd_eb . " -d file -o " . "/data01/data"; + } + else{ + $cmd_eb = $cmd_eb . " -d file -o " . $EB_Args_href->{$ebproc}->{'OUTDIR'}; + } + } + else{ + $cmd_eb = $cmd_eb . " -d null"; + } + + #- add file size + $cmd_eb = $cmd_eb . " --filesize " . $EB_Args_href->{$ebproc}->{'FILESIZE'}; + + #- add second output with small hdl files + if( defined $EB_Args_href->{$ebproc}->{'RESDOWNSCALE'} ){ + $cmd_eb = $cmd_eb . " --resdownscale " . $EB_Args_href->{$ebproc}->{'RESDOWNSCALE'} . + " --resnumevents " . $EB_Args_href->{$ebproc}->{'RESNUMEVENTS'} . + " --respath " . $EB_Args_href->{$ebproc}->{'RESPATH'} . + " --ressizelimit " . $EB_Args_href->{$ebproc}->{'RESSIZELIMIT'}; + } + + my $cpu = $EB_Args_href->{$ebproc}->{'IP'}; + + #- add rfio args + my $rfio; + if( $EB_Args_href->{$ebproc}->{'RFIO'} ){ + $rfio = " --rfio " . $EB_Args_href->{$ebproc}->{'RFIO_PATH'} . + " --rfiolustre " . $EB_Args_href->{$ebproc}->{'RFIO_pcCopyPath'} . + " --rfio_pcoption " . $EB_Args_href->{$ebproc}->{'RFIO_pcOptions'} . + " --rfio_icopymode " . $EB_Args_href->{$ebproc}->{'RFIO_iCopyMode'} . + " --rfio_icopyfrac " . $EB_Args_href->{$ebproc}->{'RFIO_iCopyFrac'} . + " --rfio_imaxfile " . $EB_Args_href->{$ebproc}->{'RFIO_iMaxFile'} . + " --rfio_ipathconv " . $EB_Args_href->{$ebproc}->{'RFIO_iPathConv'}; + } + + $cmd_eb = $cmd_eb . $rfio if( defined $rfio ); + + #- add multiple disk arg (ctrl via daq_disks) + if($EB_Args_href->{$ebproc}->{'MULTIDISK'} && + defined $EB_Args_href->{$ebproc}->{'OUTDIR'}){ + $cmd_eb = $cmd_eb . " --multidisk " . $EB_Args_href->{$ebproc}->{'MULTIDISK'}; + } + + #- add online RPC server + if( $EB_Args_href->{$ebproc}->{'ONLINESERVER'} eq "on" ){ + $cmd_eb = $cmd_eb . " --online"; + } + + #- add epics controlled + $cmd_eb = $cmd_eb . " --epicsctrl " if( $EB_Args_href->{$ebproc}->{'EPICS_CTRL'} ); + + #- logging the output + my $eblog_file = "/tmp/log_eb_" . $EB_Args_href->{$ebproc}->{'EBNUM'} . ".txt"; + my $eb_log = "1>$eblog_file 2>$eblog_file"; + $eb_log = "1>/dev/null 2>/dev/null" unless( $EB_Args_href->{$ebproc}->{'EB_LOG'} ); + + my $time = 1. * $ebproc; + my $sleep_cmd = "sleep " . $time; + + my $core_nr = &getCoreNr($cpu); + + my $exe_eb = "ssh -n $cpu -l $username \"cd /home/hadaq/oper; export DAQ_SETUP=/home/hadaq/oper/eb; taskset -c $core_nr $cmd_eb $eb_log &\""; + + #print "exec: $exe_eb\n"; + + #--- Prepare execution of daq_netmem + my $cmd_nm = "/home/hadaq/bin/daq_netmem" . + " -m " . $EB_Args_href->{$ebproc}->{'SOURCENUM'} . + " -q " . $EB_Args_href->{$ebproc}->{'QUEUESIZE'} . + " -S " . $EB_Args_href->{$ebproc}->{'EBNUM'}; + + #- add queue variable size args + $cmd_nm = $cmd_nm . $varsize_arg; + + my @port_list = (); + + #- add ports + foreach my $port (@{$EB_Args_href->{$ebproc}->{'PORT_LIST'}}){ + #$cmd_nm = $cmd_nm . " -i UDP:0.0.0.0:" . $port; + $cmd_nm = $cmd_nm . " -i " . $port; + + push(@port_list, $port); + } + + &cpPortList2EB(\@port_list, $EB_Args_href->{$ebproc}->{'EBNUM'}, $cpu); + + #- logging the output + my $nmlog_file = "/tmp/log_nm_" . $EB_Args_href->{$ebproc}->{'EBNUM'} . ".txt"; + my $nm_log = "1>$nmlog_file 2>$nmlog_file"; + $nm_log = "1>/dev/null 2>/dev/null" unless( $EB_Args_href->{$ebproc}->{'NM_LOG'} ); + + $core_nr = &getCoreNr($cpu); + + my $exe_nm = "ssh -n $cpu -l $username \"cd /home/hadaq/oper; export DAQ_SETUP=/home/hadaq/oper/eb; taskset -c $core_nr $cmd_nm $nm_log &\""; + + #print "exec: $exe_nm\n"; + + #--- Open permissions for shared memory + my $eb_shmem = "daq_evtbuild" . $EB_Args_href->{$ebproc}->{'EBNUM'} . ".shm"; + my $nm_shmem = "daq_netmem" . $EB_Args_href->{$ebproc}->{'EBNUM'} . ".shm"; + my $exe_open_eb = "ssh -n $cpu -l $username \"chmod 775 /dev/shm/$eb_shmem\""; + my $exe_open_nm = "ssh -n $cpu -l $username \"chmod 775 /dev/shm/$nm_shmem\""; + + &forkEB($exe_eb, $exe_nm, $exe_open_eb, $exe_open_nm, \@process_list); + } + + #- Wait for children + foreach my $cur_child_pid (@process_list) { + waitpid($cur_child_pid,0); + } +} + +sub stopEvtBuilders() +{ + my $username = "hadaq"; + + my @process_list = (); + + #--- Loop over server IPs + foreach my $ip (@EB_IP_list){ + + my $exe = "ssh -n $ip -l $username \"/home/hadaq/bin/cleanup_evtbuild.pl; /home/hadaq/bin/ipcrm.pl\""; + + if($opt_verb){ + print "Killing running EBs...\n"; + print "Exec: $exe\n"; + } + + my $log = $log_path . "/log_" . $ip . "_" . "stopEB.txt"; + + forkMe($exe, $log, \@process_list) unless($opt_test); + } + + #- Wait for children + foreach my $cur_child_pid (@process_list) { + print "wait for $cur_child_pid\n"; + waitpid($cur_child_pid,0); + } +} + +sub cpPortList2EB() +{ + my ($port_list_aref, $ebnr, $cpu) = @_; + + my $tmpfile = "/tmp/eb" . $ebnr . "_" . $cpu . ".txt"; + + #- First write ports to tmp file + my $fh = new FileHandle(">$tmpfile"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$tmpfile\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + foreach my $port (@$port_list_aref){ + print $fh "$port\n"; + } + + $fh->close(); + + #- Copy this tmp file to EB + my $exe_cp = "scp $tmpfile hadaq\@$cpu:/tmp/ 1>/dev/null 2>/dev/null"; + system($exe_cp); +} + +sub startIOC() +{ + my $ioc_dir = "/home/scs/ebctrl/ioc/iocBoot/iocebctrl"; + + &writeIOC_stcmd( $ioc_dir ); + + print "Starting IOCs...\n" if($opt_verb); + + foreach my $ebproc (keys %$EB_Args_href){ + + my $stcmd = sprintf("st_eb%02d.cmd", 1 + $ebproc); + my $screen_name = sprintf("ioc_eb%02d", 1 + $ebproc); + + my $cmd = "bash; . /home/scs/.bashrc; cd $ioc_dir; screen -dmS $screen_name ../../bin/linux-x86_64/ebctrl $stcmd"; + my $cpu = $EB_Args_href->{$ebproc}->{'IP'}; + + my $exe = "ssh -n $cpu -l scs \"$cmd\""; + + print "Exec: $exe\n" if($opt_verb); + system($exe) unless($opt_test); + } +} + +sub smallestEBProcNum() +{ + my $smallest = 1000; + + foreach my $ebproc (keys %$EB_Args_href){ + $smallest = $ebproc if($smallest > $ebproc); + } + + return $smallest; +} + +sub writeIOC_stcmd() +{ + my ($ioc_dir) = @_; + + print "Copying st.cmd files to servers...\n" if($opt_verb); + + my $smallest_ebproc = &smallestEBProcNum(); + + foreach my $ebproc (keys %$EB_Args_href){ + + my $ebNr = 1 + $ebproc; + my $ebnum = sprintf("eb%02d", $ebNr); + + #- in MBytes + my $maxFileSize = $EB_Args_href->{$ebproc}->{'FILESIZE'}; + + my $ebtype = "slave"; + my $comment_genrunid = "#"; + my $comment_totalevt = "#"; + + if($ebproc == $smallest_ebproc){ + $ebtype = "master"; + $comment_genrunid = ""; + $comment_totalevt = ""; + } + +# if($ebNr == 1){ +# $comment_totalevt = ""; +# } + + my $ioc_stcmd = < \${TOP}/iocBoot/\${IOC}/$ebnum.dbl + +EOF + + my $outfile = "/tmp/st_" . $ebnum . ".cmd"; + my $fh = new FileHandle(">$outfile"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$outfile\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + print $fh $ioc_stcmd; + $fh->close(); + + my $ip = $EB_Args_href->{$ebproc}->{'IP'}; + my $cmd = "scp $outfile scs\@$ip:$ioc_dir/."; + + print "Exec: $cmd\n" if($opt_verb); + system($cmd) unless($opt_test); + } +} + +sub killIOC() +{ + my %ioc; + my $ioc_href = \%ioc; + + print "Looking for running IOCs...\n" if($opt_verb); + + #--- Loop over server IPs + foreach my $ip (@EB_IP_list){ + + &findRunningIOC($ip, $ioc_href); + } + + #print Dumper \%$ioc_href; + + &writeExpectIOC() if( defined %$ioc_href ); + + if($opt_verb){ + print "Killing running IOCs...\n"; + print "No IOCs found - nothing to kill, continue...\n" unless( defined %$ioc_href ); + } + + my (@process_list); + + foreach my $ip ( %$ioc_href ){ + foreach my $ioc ( @{$ioc_href->{$ip}} ){ + + my $cmd = $expect_ioc_script . " " . $ip . " " . $ioc; + my $log = $log_path . "/log_" . $ip . "_" . $ioc . ".txt"; + print "cmd: $cmd\n" if($opt_verb); + &forkMe($cmd, $log, \@process_list); + } + } + + #- Wait for children + foreach my $cur_child_pid (@process_list) { + waitpid($cur_child_pid,0); + } +} + +sub forkMe() +{ + my ($cmd, $log, $proc_list) = @_; + + my $child = fork(); + + if( $child ){ # parent + push( @$proc_list, $child ); + } + elsif( $child == 0 ) { # child + system("$cmd > $log"); + exit(0); + } + else{ + print "Could not fork: $!\n"; + exit(1); + } +} + +sub forkEB() +{ + my ($exe_eb, $exe_nm, $exe_open_eb, $exe_open_nm, $proc_list) = @_; + + my $child = fork(); + + if( $child ){ # parent + push( @$proc_list, $child ); + } + elsif( $child == 0 ) { # child + #--- Execute Event Builder + print "Exec: $exe_eb\n" if($opt_verb); + system($exe_eb) unless($opt_test); + + sleep(1); + + #--- Open permissions for EB shared memory + # ! Permissions should be opened by EB process + #print "Exec: $exe_open_eb\n" if($opt_verb); + #system($exe_open_eb) unless($opt_test); + + sleep(2); + + #--- Execute Net-2-Memory + print "Exec: $exe_nm\n" if($opt_verb); + system($exe_nm) unless($opt_test); + + sleep(1); + + #--- Open permissions for NM shared memory + # ! Permissions should be opened by EB process + #print "Exec: $exe_open_nm\n" if($opt_verb); + #system($exe_open_nm) unless($opt_test); + + exit(0); + } + else{ + print "Could not fork: $!\n"; + exit(1); + } +} + +sub findRunningIOC() +{ + my ($cpu, $ioc_href) = @_; + + `ssh -n $cpu -l scs \"screen -wipe\"`; + my $exe = "ssh -n $cpu -l scs \"screen -ls\""; + + my @output = `$exe`; + + foreach my $line (@output){ + if($line =~ /\d+\.(ioc_eb\d{2})\s+/){ + my $name = $1; + push( @{$ioc_href->{$cpu}}, $name ); + print "Found IOC: $name on $cpu\n" if($opt_verb); + } + } +} + +sub writeExpectIOC() +{ + # This expect script can be executed to exit IOC. + + #! Look if /tmp dir exists + my $tmp_dir = dirname("/tmp"); + if ( !(-d $tmp_dir) ){ + print "\nCannot access /tmp directory!\nExit.\n"; + exit(1); + } + + my $expect_script_my = <0} { + set ip [lindex \$argv 0] + set iocname [lindex \$argv 1] +} else { + send_user "Usage: \$argv0 ip iocname\\n" +} + +spawn ssh scs@\$ip + +#expect { +# "error" { exit; } +# "login:" { exit; } +# "Password:" { exit; } +#} + +set timeout 20 +#240 + +expect "~\$ " +send "screen -r \$iocname\\r" +expect "epics> " +send "exit\\r" +expect "~\$ " + +EOF + + my $fh = new FileHandle(">$expect_ioc_script"); + + if(!$fh) { + my $txt = "\nError! Could not open file \"$expect_ioc_script\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + print $fh $expect_script_my; + $fh->close(); + + #- open permissions + system("chmod 755 $expect_ioc_script"); +} + +sub getGbEconfig() +{ + # + # Read DB configurations of GbE and CTS, + # look for active data sources as well as + # for EB IPs and ports. + # + + my ($eb_ids_href) = @_; + + my $data_sources = $temp_args_href->{'Parallel'}->{'DATA_SOURCES'}; + my $gbe_conf = $temp_args_href->{'Parallel'}->{'GBE_CONF'}; + my $cts_conf = $temp_args_href->{'Parallel'}->{'CTS_CONF'}; + + my %activeSources_hash; + my $activeSources_href = \%activeSources_hash; + + &readActiveSources($data_sources, $activeSources_href); + + my @id_list; + my $id_list_aref = \@id_list; + + #&readEBids($cts_conf, $id_list_aref); + + #- Overwrite array with EB numbers + @id_list = (0 .. 15); + #print Dumper $id_list_aref; + + &readEBports($gbe_conf, $activeSources_href, $id_list_aref, $eb_ids_href); +} + +sub readEBids() +{ + # + # Read EB Ids + # + + my ($file, $id_list_aref) = @_; + + my $nnn_table = 0; + my $val_table = 0; + + my $SPACE = ""; + + my $fh = new FileHandle("$file", "r"); + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + if(/^(\s+)?!Value\stable/){ + $val_table = 1; + $nnn_table = 0; + next; + } + elsif(/^(\s+)?!\w+/){ + $val_table = 0; + $nnn_table = 1; + } + + if($val_table){ + my (@vals) = split(" ", $_); + my @id_list1 = split("", $vals[12]); + my @id_list2 = split("", $vals[13]); + foreach my $id (@id_list1){ + push(@$id_list_aref, hex($id)); + } + foreach my $id (@id_list2){ + push(@$id_list_aref, hex($id)); + } + } + elsif($nnn_table){ + } + } + + $fh->close; +} + +sub readEBports() +{ + # + # Read EB IPs and ports accoring to EB Id (type) + # and TRB-Net addresses of active data sources. + # + + my ($file, $activeSources_href, $id_list_aref, $ports_href) = @_; + + my $nnn_table = 0; + my $val_table = 0; + + my $fh = new FileHandle("$file", "r"); + + &isFileDefined($fh, $file); + + my %tmp; + my $tmp_href = \%tmp; + + my $SPACE = ""; + + while(<$fh>){ + + #print $_; + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + #print $_; + if(/^(\s+)?!Value\stable/){ + $val_table = 1; + $nnn_table = 0; + next; + } + elsif(/^(\s+)?!\w+/){ + $nnn_table = 1; + $val_table = 0; + } + + if($val_table){ + my (@vals) = split(" ", $_); + my $id = $vals[1]; + + #if($id <0 or $id >15) { + # print "error: in $file there is a line with an eventbuilder number different than 0..15, the number given in the file is $id. please correct the config file.\n"; + # exit(128); + #} + + + #- Accept only EB Ids from CTS config file + #print "value: $_"; + next unless( any {$_ eq $id} @$id_list_aref ); + + #print Dumper \@vals; + #print "active sources: "; print Dumper $activeSources_href->{'addr_list'}; + #exit; + + my $ip = &getIP_hex2dec($vals[6]); + my $port = &getPort_hex2dec($vals[2]); + my $addr = $vals[0]; + + #print "got: ip: $ip, port: $port, addr: $addr\n"; + #- Accept only sources from active source list + if( any {hex($_) == hex($addr)} @{$activeSources_href->{'addr_list'}} ){ + $tmp_href->{$id}->{'IP'} = $ip; + push( @{$tmp_href->{$id}->{'port_list'}}, $port ); + push( @{$tmp_href->{$id}->{'addr_list'}}, $addr ); + } + } + } + + $fh->close; + + #print Dumper $tmp_href; + + #- Sort hash according to active data source list + foreach my $id (keys %tmp){ + $ports_href->{$id}->{'IP'} = $tmp_href->{$id}->{'IP'}; + + foreach my $addr (@{$activeSources_href->{'addr_list'}}){ + + my $ind1 = first_index {$_ eq $addr} @{$tmp_href->{$id}->{'addr_list'}}; + my $ind2 = first_index {$_ eq $addr} @{$activeSources_href->{'addr_list'}}; + + next if($ind1 == -1); + + push( @{$ports_href->{$id}->{'port_list'}}, $tmp_href->{$id}->{'port_list'}->[$ind1]); + push( @{$ports_href->{$id}->{'addr_list'}}, $addr); + push( @{$ports_href->{$id}->{'bufsize_list'}}, $activeSources_href->{'bufsize_list'}->[$ind2]); + } + } + + #print Dumper $ports_href; +} + +sub readActiveSources() +{ + # + # Read TRB-Net addresses of active data sources + # + + my ($file, $activeSources_href) = @_; + + my $fh = new FileHandle("$file", "r"); + + &isFileDefined($fh, $file); + + my $SPACE = ""; + + while(<$fh>){ + + #- Remove all comments + $_ =~ s{ # Substitue... + \# # ...a literal octothorpe + [^\n]* # ...followed by any number of non-newlines + } + {$SPACE}gxms; # Raplace it with a single space + + #- Skip line if it contains only whitespaces + next unless(/\S/); + + my ($addr, $astat, $sys, $size) = split(" ", $_); + + next if($astat == 0); + + push( @{$activeSources_href->{'addr_list'}}, $addr); + push( @{$activeSources_href->{'bufsize_list'}}, &getBufSize($size)); + } + + $fh->close; +} + +sub getBufSize() +{ + my ($bufSize) = @_; + + if(lc($bufSize) eq "low"){ + return $temp_args_href->{'Main'}->{'BUF_SIZE_LOW'}; + } + elsif(lc($bufSize) eq "mid"){ + return $temp_args_href->{'Main'}->{'BUF_SIZE_MID'}; + } + elsif(lc($bufSize) eq "high"){ + return $temp_args_href->{'Main'}->{'BUF_SIZE_HIGH'}; + } + else{ + print "Cannot understand $bufSize from data_sources.db.\n"; + exit(0); + } +} + +sub getIP_hex2dec() +{ + my ($ip_hex) = @_; + + my $ip_dec; + + if( $ip_hex =~ /0x(\w{2})(\w{2})(\w{2})(\w{2})/ ){ + $ip_dec = hex($1) . "." . hex($2) . "." . hex($3) . "." . hex($4); + } + else{ + print "getIP_hex2dec(): cannot extract ip address because of diferent format! Exit."; + exit(0); + } + + return $ip_dec; +} + +sub getPort_hex2dec() +{ + my ($port_hex) = @_; + + my $port_dec; + + if( $port_hex =~ /0x(\w+)/ ){ + $port_dec = hex($1); + } + else{ + print "getPort_hex2dec(): cannot extract port number because of diferent format! Exit."; + exit(0); + } + + return $port_dec; +} + +sub isFileDefined() +{ + my ($fh, $name) = @_; + + if(!$fh) { + my $txt = "\nError! Could not open file \'$name\'. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + return 0; +} + +sub writeArgs2file() +{ + my $fileName = $0; + + #- Replace .pl with .sh + $fileName =~ s/\.pl/\.sh/; + + my $fh = new FileHandle(">./$fileName"); + if(!$fh) { + my $txt = "\nError! Could not open file \"$fileName\" for output. Exit.\n"; + print STDERR $txt; + print $txt; + exit(128); + } + + my $current_dir = cwd(); + my $ptogName = $0; + + + #- Write to the file the script name itself + print $fh $0; + + #- Write to the file the arguments + foreach my $arg (@arg_list){ + print $fh " $arg"; + } + print $fh "\n"; + + $fh->close(); + + system("chmod 755 ./$fileName"); +} + diff --git a/evtbuild/start_eb_gbe.sh b/evtbuild/start_eb_gbe.sh new file mode 100755 index 0000000..02a0ba8 --- /dev/null +++ b/evtbuild/start_eb_gbe.sh @@ -0,0 +1 @@ +./start_eb_gbe.pl -v -e restart -n 1-16 -d on -p ri -r off diff --git a/evtbuild/start_eb_iocs.sh b/evtbuild/start_eb_iocs.sh new file mode 100755 index 0000000..716e321 --- /dev/null +++ b/evtbuild/start_eb_iocs.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# JAM 2-2012 +# restart epics iocs for all eventbuilders +# will kill all previous iocs +# need to set environment with this script due to relative paths in config files +cd /home/hadaq/trbsoft/daq/evtbuild +./start_eb_gbe.pl -i start -n 1-16 diff --git a/evtbuild/start_rdosoft.pl b/evtbuild/start_rdosoft.pl new file mode 100755 index 0000000..3df3916 --- /dev/null +++ b/evtbuild/start_rdosoft.pl @@ -0,0 +1,235 @@ +#!/usr/bin/perl -w + +use English; +use strict; +use Getopt::Long; +use Data::Dumper; +use Config::Std; +use FileHandle; +use List::MoreUtils qw(any apply); +use File::Basename; + +#- the command line option flags +my $opt_help = 0; +my $opt_ebconf = "../evtbuild/eb.conf"; +my $opt_test = 0; +my $opt_verb = 0; + +GetOptions ('h|help' => \$opt_help, + 'c|conf=s' => \$opt_ebconf, + 't|test' => \$opt_test, + 'v|verb' => \$opt_verb); + +if( $opt_help ) { + &help(); + exit(0); +} + +my $numOfEBProcs = 0; +my @EB_Args; +my $EB_Args_aref = \@EB_Args; + +&getEBArgs( $EB_Args_aref ); + +my $exedir = "/home/hadaq/test_eb"; + +my @iplist = ("192.168.100.52"); #hades27 + + +&prepareRemotePC(); +&startRdosoft(); +&startUDPMaster(); + +exit(0); + +################### END OF MAIN #################### + +sub help() +{ + print "\n"; + print << 'EOF'; +start_eb.pl + + This script starts soft-readout processes. + +Usage: + + Command line: startup.pl + [-h|--help] : Show this help. + [-c|--conf ] : Path to the config file (default: $opt_ebconf). + [-t|--test] : Test without execution. + [-v|--verb] : More verbouse. + +EOF +} + +sub getEBArgs() +{ + + my ($aref) = @_; + + my %temp_args; + my $temp_args_href = \%temp_args; + + read_config $opt_ebconf => %$temp_args_href; + + my $base_port = $temp_args_href->{'Parallel'}->{'BASE_PORT'}; + my $shift_port = $temp_args_href->{'Parallel'}->{'SHIFT_PORT'}; + my $source_num = $temp_args_href->{'Parallel'}->{'NUM_OF_SOURCES'}; + + #- Number of EB process + my $ebproc = 0; + + #--- Loop over servers + foreach my $num (1..4){ + + my $ip_name = 'EB_IP_' . $num; + next unless( defined $temp_args_href->{'Parallel'}->{$ip_name} ); + + my $num_name = 'EB_NUM_' . $num; + unless( defined $temp_args_href->{'Parallel'}->{$num_name} ){ + print "\nNumber of EBs per server ($num_name) is not defined in $opt_ebconf!\n"; + print "Exit.\n"; + exit(1); + } + + my $eb_ip = $temp_args_href->{'Parallel'}->{$ip_name}; + my $eb_num = $temp_args_href->{'Parallel'}->{$num_name}; + + #--- Loop over EB processes on a given server + foreach my $ebnum (1..$eb_num){ + + #- Increment index of EB process + $ebproc++; + + #- Calculate base port for given EB process + my $baseport = ($ebnum - 1) * $shift_port + $base_port; + + $aref->[$ebproc-1]->{'IP'} = $eb_ip; + $aref->[$ebproc-1]->{'EBNUM'} = $ebproc; + $aref->[$ebproc-1]->{'BASEPORT'} = $baseport; + $aref->[$ebproc-1]->{'SOURCENUM'} = $source_num; + } + } + + $numOfEBProcs = $ebproc; +} + +sub prepareRemotePC() +{ + my $username = "hadaq"; + + foreach my $ip (@iplist){ + my $cmd = "ssh -n $ip -l $username \"mkdir $exedir 1>/dev/null 2>/dev/null\""; + + print "Exec: $cmd\n" if($opt_verb); + system($cmd) unless($opt_test); + + #my $cmd_rs = "scp /home/hadaq/yurevich/newtcpsynch/hwreadout/hwsoft/daq_rdosoft $username\@$ip:$exedir/"; + #my $cmd_mn = "scp /home/hadaq/yurevich/roundrobin/bin/daq_memnet $username\@$ip:$exedir/"; + + my $cmd_rs = "scp /home/hadaq/yurevich/udpctrl_roundrobin/bin/daq_rdosoft $username\@$ip:$exedir/"; + my $cmd_mn = "scp /home/hadaq/yurevich/udpctrl_roundrobin/bin/daq_memnet $username\@$ip:$exedir/"; + + print "Exec: $cmd_rs\n" if($opt_verb); + system($cmd_rs) unless($opt_test); + + print "Exec: $cmd_mn\n" if($opt_verb); + system($cmd_mn) unless($opt_test); + } +} + +sub startRdosoft() +{ + my @process_list = (); + + my $portshift = 0; + + foreach my $ip (@iplist){ + my $child = fork(); + + if( $child ) { + #print "Parent: push child to process_list\n"; + push( @process_list, $child ); + } + elsif ( $child == 0 ) { + #print "Child: execute SoftReadout\n"; + &execSoftReadoutMult( $ip, $portshift ); + exit(0); + } + else { + die "startSoftReadout: Could not fork!\n"; + } + + $portshift++; + } + + foreach my $child_pid (@process_list) { + waitpid( $child_pid, 0); + } +} + +sub execSoftReadoutMult() +{ + my ($rdo_ip, $portshift) = @_; + + my $udpsynch = "UDP:0.0.0.0:19999"; + my $username = "hadaq"; + + #-------- DAQ MEMORY 2 NETWORK + my $daq_mn = "cd /home/hadaq/test_eb/; ./daq_memnet -q 16000000 --shmnum $portshift -E $numOfEBProcs"; + + foreach my $ebproc (1..$numOfEBProcs){ + my $ip = $EB_Args_aref->[$ebproc-1]->{'IP'}; + my $port = $EB_Args_aref->[$ebproc-1]->{'BASEPORT'}; # base port + + $port = $port + $portshift; + + $daq_mn = $daq_mn . " -o UDP:$ip:$port"; + } + + $daq_mn = $daq_mn . " < /dev/null > /dev/null 2>&1 \&"; + + #-------- DAQ READOUT SOFT + my $daq_rs = "cd /home/hadaq/test_eb/; ./daq_rdosoft -w 1000 --synch $udpsynch --spilltime 20 --evtrate 15000 --evtsize 1000 -q 16000000 --shmnum $portshift -E $numOfEBProcs"; + $daq_rs = $daq_rs . " < /dev/null > /dev/null 2>&1 \&"; + + #my $eb_sh_script = </dev/null 2>/dev/null & + + + my $exe_mn = "ssh -n $rdo_ip -l $username \"$daq_mn\""; + my $exe_rs = "ssh -n $rdo_ip -l $username \"$daq_rs\""; + + print "Exec: $exe_mn\n" if($opt_verb); + system($exe_mn) unless($opt_test); + + print "Exec: $exe_rs\n" if($opt_verb); + system($exe_rs) unless($opt_test); + +} + +sub startUDPMaster() +{ + my $udp = ""; + + foreach my $ip (@iplist){ + $udp = "$udp -o $ip -p 19999 -m 1"; + } + + #- separate window + my $term_name = "-T \"UDP Master\""; + my $term_geom = "-geometry 80x13+20+810"; + my $term_opt = "-fn 10x20 -fg DarkOliveGreen3 -bg black -cr red -ms green"; + my $exec_command = "/home/hadaq/yurevich/test/oper/bin/client -t 30 $udp"; #time interval of 30 seconds + + system("xterm $term_name $term_geom $term_opt -e '$exec_command' &") unless($opt_test); + + print "exec command: $exec_command\n"; +} -- 2.43.0