From 2f2af40855f7918d17f9c2dca8cb3b4e0afd5c56 Mon Sep 17 00:00:00 2001 From: chrin Date: Tue, 7 Jan 2025 12:01:05 +0100 Subject: [PATCH] added peak search parameters to expert panel --- .gitignore | 2 +- src/analysis.py | 94 +++++++++++++++++++++++++++++++++++++------------ src/gui.py | 30 ++++++++++++++-- tina.json | 23 +++++++++--- tina.py | 8 ++--- tina.sh | 4 +-- tina_office.sh | 2 +- 7 files changed, 125 insertions(+), 38 deletions(-) diff --git a/.gitignore b/.gitignore index 165edad..c81f4b9 100644 --- a/.gitignore +++ b/.gitignore @@ -15,5 +15,5 @@ help/*.*~ help/*.*-* help/*.*+* - +*.html diff --git a/src/analysis.py b/src/analysis.py index a25238e..e41bd6c 100644 --- a/src/analysis.py +++ b/src/analysis.py @@ -75,7 +75,7 @@ class AnalysisProcedure(QObject): self.ring_cyclotron = self.parent.ring_cyclotron # Declare input parameters - + self.input_parameters = self.parent.input_parameters self.input_data = None self.debug = False self.log_level = logging.INFO @@ -93,7 +93,10 @@ class AnalysisProcedure(QObject): self.t_interval = math.ceil(self.pulse_stepsize/self.t_stepsize) self.correlation_peak_diff = 0.0 - + self.signal_min_peak_height = 50 + self.signal_min_peak_distance = 10 + self.correlation_min_peak_diff = 0.01 + self.dt_cable = 44 # ns self.dn_pickup = -1 self.mod_freq = 500 # GHz @@ -125,13 +128,19 @@ class AnalysisProcedure(QObject): #########INITIALIZE THE INPUTS FOM THE GUI####################### - def initialize_input_parameters(self, input_data: dict): + def initialize_input_parameters(self, input_data: dict, reanalysis=False): self.input_data = input_data self.all_data['Input data'] = self.input_data - print(self.input_data) - + print(f'init input parameters {self.input_data}') + if reanalysis: + self.loglevel = self.input_parameters['loggingLevel'] + else: + self.loglevel = self.input_data['loggingLevel'] + + self.logger.setLevel(self.logging.getLevelName(self.loglevel)) + if 'debug' in self.input_data.keys(): self.debug = self.input_data['debug'] @@ -139,7 +148,6 @@ class AnalysisProcedure(QObject): self.logger.debug(f'INPUT DATA to LOG:{self.input_data}') self.simulation = bool(self.input_data['simulation']) - self.rf_freq = float(self.input_data['freqrf']) # 2.5 MHz if oscilloscpe @@ -165,10 +173,7 @@ class AnalysisProcedure(QObject): self.input_data[self.accelerator]['freqmod']) # * 10**9 GHz self.duty_cycle = float( self.input_data[self.accelerator]['dutycycle']) # * 0.01 - - self.loglevel = self.input_data['loggingLevel'] - self.logger.setLevel(self.logging.getLevelName(self.loglevel)) - + self.logger.info('INPUT PARAMETERS') self.logger.info(f'Accelerator: {self.accelerator}') @@ -180,12 +185,47 @@ class AnalysisProcedure(QObject): self.logger.info(f'Harmonic No. {self.harmonic_no}') self.logger.info(f'dT Cable {self.dt_cable}') self.logger.info(f'dN Pickup {self.dn_pickup}') - + except KeyError as ex: self.logger.error(f'KeyError {ex}') except ValueError as ex: self.logger.error(f'ValueError {ex}') + try: + self.correlation_min_peak_diff = float( + self.input_data[self.accelerator]['correlationPeakDifference']) + self.signal_min_peak_height = round( + self.input_data[self.accelerator]['peakHeight']) + self.signal_min_peak_distance = round( + self.input_data[self.accelerator]['peakDistance']) + + + except KeyError as ex: + self.logger.error(f'KeyError {ex}') + except ValueError as ex: + self.logger.error(f'ValueError {ex}') + + #Overide peak search parameters with those given in gui + if reanalysis: + self.correlation_min_peak_diff = float(self.input_parameters[ + self.accelerator]['correlationPeakDifference']) + self.signal_min_peak_height = int( + self.input_parameters[self.accelerator]['peakHeight']) + self.signal_min_peak_distance = int( + self.input_parameters[self.accelerator]['peakDistance']) + + + print(f'self.input_parameters={self.input_parameters}') + print((f'Reanalysis: self.correlation_min_peak_diff= ' + \ + '{self.correlation_min_peak_diff}')) + + + self.logger.info(f'Corr Min Peak Diff {self.correlation_min_peak_diff}') + self.logger.info(f'Min Peak Height {self.signal_min_peak_height}') + self.logger.info(f'Min Peak Distance {self.signal_min_peak_distance}') + + + def measure_and_analyze(self, input_data=None): '''This method is initiated by the START button in Procedure panel ''' @@ -197,7 +237,12 @@ class AnalysisProcedure(QObject): # Read the input parameters from the GUI self.initialize_input_parameters(input_data) - + self.logger.info( + f'Corr Min Peak Diff {self.correlation_min_peak_diff}') + self.logger.info(f'Min Peak Height {self.signal_min_peak_height}') + self.logger.info( + f'Min Peak Distance {self.signal_min_peak_distance}') + # Step 1 - Collect ambient data relate to the machine self.all_data['Ambient data'] = self.collect_ambient_data() self.trigger_progressbar.emit(int(PROGRESS_THREAD_START)) @@ -221,7 +266,7 @@ class AnalysisProcedure(QObject): def load_hdf_file(self, hdf_filename_loaded): print(f'load_hdf_file==> {hdf_filename_loaded}', flush=True) - + raw_data = h5_storage.loadH5Recursive(hdf_filename_loaded) self.raw_data = raw_data @@ -232,12 +277,13 @@ class AnalysisProcedure(QObject): '''Reanalysis ''' print('Reanalyze', flush=True) - print(all_data) + print(all_data, flush=True) input_data = all_data['Input_data'] # Read the input parameters - self.initialize_input_parameters(input_data) - + self.initialize_input_parameters(input_data=input_data, reanalysis=True) + + ambient_data = all_data['Ambient_data'] self.raw_data = all_data['Raw_data'] self.all_data['Raw data'] = self.raw_data @@ -301,9 +347,7 @@ class AnalysisProcedure(QObject): self.trigger_progressbar.emit(PROGRESS_THREAD_ERROR) return {} - - - + pv_list = [] for key, value in self.settings.data['PV'][self.accelerator].items(): @@ -328,8 +372,6 @@ class AnalysisProcedure(QObject): if status != self.cyca.ICAFE_NORMAL: self.check_status_list(_pymodule, 'getScalarList', pv_list, status_list, utils.line_no()) - - # Retrieve pv_entry_current = self.settings.data['PV'][self.accelerator]['IEntry'] @@ -653,6 +695,9 @@ class AnalysisProcedure(QObject): print('rf freq', self.rf_freq, flush=True) print('harmonic', self.harmonic_no, flush=True) print('dN pickup', self.dn_pickup, flush=True) + print(f'Correlation Peak Diff {self.correlation_peak_diff}') + print(f'Min Peak Height {self.signal_min_peak_height}') + print(f'Min Peak Distance {self.signal_min_peak_distance}') self.n_turns = ( ((self.delay-self.dt_cable*10**(-9))*self.rf_freq*10**6) @@ -674,7 +719,10 @@ class AnalysisProcedure(QObject): 'lag': self.lag_full, 'delay': self.delay, 'nturns': self.n_turns, - 'peak_diff': self.correlation_peak_diff + 'correlation_peak_diff': self.correlation_peak_diff, + 'correlation_min_peak_diff': self.correlation_min_peak_diff, + 'min_peak_height': self.signal_min_peak_height, + 'min_peak_distance': self.signal_min_peak_distance } return proc_data @@ -683,7 +731,7 @@ class AnalysisProcedure(QObject): ''' Figure construction with matplotlib ''' is_suspect = True if self.correlation_peak_diff < \ - self.parent.correlation_peak_diff_min_value else False + self.correlation_min_peak_diff else False if is_suspect: fontweight_main='normal' diff --git a/src/gui.py b/src/gui.py index 12ff99d..cc34526 100644 --- a/src/gui.py +++ b/src/gui.py @@ -40,13 +40,13 @@ class AppGui(QWidget): self.input_labels = self.parent.input_labels self.expert_parameters = self.parent.expert_parameters self.gui_frame.expert_parameters_group.setFixedWidth(310) - self.gui_frame.expert_parameters_group.setFixedHeight(130) + self.gui_frame.expert_parameters_group.setFixedHeight(340) self.gui_frame.operator_parameters_group.setFixedWidth(260) self.gui_frame.operator_parameters_group.setFixedHeight(380) self.gui_frame.measurement_tab_wgt.setFixedWidth(496) self.gui_frame.measurement_tab_wgt.setFixedHeight(460) self.gui_frame.operator_wgt.setFixedHeight(640) - self.gui_frame.expert_wgt.setFixedHeight(240) + #self.gui_frame.expert_wgt.setFixedHeight(240) #DAQ self.daq_wgt = self.daq_group_qtabwidget(widget_type='QStackedWidget') @@ -65,14 +65,38 @@ class AppGui(QWidget): self.current_wgt.setCurrentIndex(self.parent.default_idx) self.current_wgt.currentChanged.emit(self.parent.default_idx) + choice_wgt = self.gui_frame.line_sender_dict['signalPeakSearch'] + choice_wgt.name = "Expert" + self.gui_frame.line_sender_dict['signalSearch'] = choice_wgt + choice_wgt = self.gui_frame.line_sender_dict['accelerator'] + choice_wgt.name = "Operator" + self.gui_frame.line_sender_dict['accelerator'] = choice_wgt + #On change Injector/Cyclotron self.gui_frame.line_sender_dict[ 'accelerator'].currentChanged.connect(self.cb_accelerator) - + self.gui_frame.line_sender_dict[ + 'signalPeakSearch'].currentChanged.connect(self.cb_accelerator) def cb_accelerator(self, idx): self.daq_wgt.setCurrentIndex(idx) self.current_wgt.setCurrentIndex(idx) + _sender = self.sender().name + #print(_sender, flush=True) + if "Expert" in _sender: + self.gui_frame.line_sender_dict[ + 'signalPeakSearch'].blockSignals(True) + self.gui_frame.line_sender_dict['accelerator'].setCurrentIndex(idx) + self.gui_frame.line_sender_dict[ + 'signalPeakSearch'].blockSignals(False) + + else: + self.gui_frame.line_sender_dict[ + 'accelerator'].blockSignals(True) + self.gui_frame.line_sender_dict[ + 'signalPeakSearch'].setCurrentIndex(idx) + self.gui_frame.line_sender_dict[ + 'accelerator'].blockSignals(False) def daq_group_qtabwidget(self, widget_type='QStackedWidget'): accel_wgt_dict = {} diff --git a/tina.json b/tina.json index 0e614b3..eaaed24 100755 --- a/tina.json +++ b/tina.json @@ -41,17 +41,29 @@ "deltaTcable" : {"data":{ "widget": "QLineRead", "text" : "dT Cable (ns):", "value": 6.9 }}, "deltaNpickup" : {"data":{ "widget": "QLineEdit", "text" : "dN Pickup:", "value": 4 }}, "freqmod" : {"data":{ "widget": "QLineRead", "text" :"Mod. Freq (GHz):", "value" : 500}}, - "dutycycle" : {"data":{ "widget": "QLineRead", "text" :"Duty Cycle (%):", "value" : 1}} + "dutycycle" : {"data":{ "widget": "QLineRead", "text" :"Duty Cycle (%):", "value" : 1}} }, "Cyclotron": { "harmonic" : {"data":{ "widget": "QLineRead", "text" :"Harmonic No: ", "value" : 6}}, "deltaTcable" : {"data":{ "widget": "QLineRead", "text" : "dT Cable (ns):", "value": 44 }}, - "deltaNpickup" : {"data":{ "widget": "QLineEdit", "text" : "dN Pickup:", "value": -1 }} + "deltaNpickup" : {"data":{ "widget": "QLineEdit", "text" : "dN Pickup:", "value": -1 }} } }, + "QTabSignalPeakSearch":{ + "Injector": { + "peakHeight": {"flag": 1, "data":{ "widget": "QLineEdit", "text" :"Min peak height:", "value" : 50 }}, + "peakDistance": {"flag": 1, "data":{ "widget": "QLineEdit", "text" :"Min peak distance: ", "value" : 10 }}, + "correlationPeakDifference": {"flag": 1, "data":{ "widget": "QLineEdit", "text" :"Min d(corr):", "value" : 0.01}} + }, + "Cyclotron": { + "peakHeight": {"flag": 1, "data":{ "widget": "QLineEdit", "text" :"Min peak height:", "value" : 50 }}, + "peakDistance": {"flag": 1, "data":{ "widget": "QLineEdit", "text" :"Min peak distance: ", "value" : 10 }}, + "correlationPeakDifference": {"flag": 1, "data":{ "widget": "QLineEdit", "text" :"Min d(corr):", "value" : 0.01 }} + } + }, + + "Parameters":{ - "facility": {"flag": 0, "data" : {"widget": "QComboBox", "text" : "Facility:", - "link": ["HIPA"],"layout" : "Horizontal"}}, "freqrf" : {"flag": 1, "data":{ "widget": "QLineEdit", "text" :"RF Freq (10^6/s):", "value" : 50.6328 }}, "freqsampling" : {"flag": 1, "data":{ "widget": "QLineRead", "text" :"Sampling Freq (GHz):", "value" : 3.0 }}, @@ -63,6 +75,9 @@ }, "Expert":{ + "signalPeakSearch" : {"flag" : 1, "data":{ "widget": "QTabWidget", "text" : "Accelerator: ", + "link" : "QTabSignalPeakSearch", "value" : 1, + "color" : ["#008b8b", "#0047ab" ]}}, "debug": {"flag" : 1, "data":{ "widget": "None", "text" : "Debug", "value" : 0}}, "simulation": {"flag" : 1, "data":{ "widget": "None", "text" : "Oscilloscope", "value" : 0}} }, diff --git a/tina.py b/tina.py index 516d6fb..e685423 100644 --- a/tina.py +++ b/tina.py @@ -63,7 +63,6 @@ class StartMain(BaseWindow): self.injector_2 # self.from_hdf = False in base class self.message = '' - self.correlation_peak_diff_min_value = 0.010 self.gui = AppGui(self) @@ -74,7 +73,8 @@ class StartMain(BaseWindow): self.no_turns = self.all_data['Processed data']['nturns'] lag_full = self.all_data['Processed data']['lag'] delay = self.all_data['Processed data']['delay'] - self.peak_diff = self.all_data['Processed data']['peak_diff'] + self.correlation_peak_diff = self.all_data['Processed data']['correlation_peak_diff'] + self.correlation_min_peak_diff = self.all_data['Processed data']['correlation_min_peak_diff'] except KeyError: self.message = '' self.message_elog = '' @@ -324,11 +324,11 @@ class StartMain(BaseWindow): QApplication.processEvents() return False - if self.peak_diff < self.correlation_peak_diff_min_value: + if self.correlation_peak_diff < self.correlation_min_peak_diff: mess = (f'Measurement is suspect as difference in top two peak \n' + 'values of ' + f'{self.peak_diff:0.3f} is less than accepted minimum ' + - f'of {self.correlation_peak_diff_min_value:0.3f}. \n' + + f'of {self.correlation_min_peak_diff:0.3f}. \n' + f'Analysis result is not saved to EPICS!') QMessageBox.information(self, 'EPICS', mess, QMessageBox.Ok) diff --git a/tina.sh b/tina.sh index d877e75..243c5d3 100755 --- a/tina.sh +++ b/tina.sh @@ -1,5 +1,5 @@ #!/bin/bash -cd /hipa/bd/applications/tina/devl +cd /hipa/bd/applications/tina/0.0.2 # For use if script is sourced rather than executed appNameDefault="tina.sh" @@ -24,7 +24,7 @@ _EPICS_BASE=base-7.0.8 # Select Python Version here. Currently one of 3.5, 3.7, 3.8 and 3.10 PYTHON_VERSION=3.10 #cafe-1.20.0-gcc-7.5.0 -PYTHON_PATH=.:/opt/gfa/cafe/python/pycafe/cafe-1.21.0-0/lib/${_EPICS_HOST_ARCH}:/hipa/bd/applications/deps/apps4ops/v1.12.0 +PYTHON_PATH=.:/opt/gfa/cafe/python/pycafe/cafe-1.21.0/lib/${_EPICS_HOST_ARCH}:/hipa/bd/applications/deps/apps4ops/v1.12.0 if [ "$1" ]; then diff --git a/tina_office.sh b/tina_office.sh index 978da05..6f127aa 100755 --- a/tina_office.sh +++ b/tina_office.sh @@ -1,5 +1,5 @@ #!/bin/bash -cd /hipa/bd/applications/tina/devl +cd /hipa/bd/applications/tina/0.0.2 # For use if script is sourced rather than executed appNameDefault="tina.sh"