def run_sensor_cal(self, sensor): if (self.cur_row < 0): msg = 'No Q330 has been seleceted' logging.info(msg) res = QtWidgets.QMessageBox().warning(self.app_win, 'PyCal', msg, QtWidgets.QMessageBox().Close, QtWidgets.QMessageBox().Close) else: wcfg = self.cfg[self.cur_row] if sensor not in ['A', 'B']: msg = 'Invalid sensor can not be calibrated:' + sensor logging.error(msg) raise Exception(msg) if sensor == 'A': seis_model = wcfg.data[WrapperCfg.WRAPPER_KEY_SENS_COMPNAME_A] sensor_descr = wcfg.data[WrapperCfg.WRAPPER_KEY_SENS_DESCR_A] chancodes = wcfg.data[WrapperCfg.WRAPPER_KEY_CHANNELS_A] loc = wcfg.data[WrapperCfg.WRAPPER_KEY_LOCATION_A] elif sensor == 'B': seis_model = wcfg.data[WrapperCfg.WRAPPER_KEY_SENS_COMPNAME_B] sensor_descr = wcfg.data[WrapperCfg.WRAPPER_KEY_SENS_DESCR_B] chancodes = wcfg.data[WrapperCfg.WRAPPER_KEY_CHANNELS_B] loc = wcfg.data[WrapperCfg.WRAPPER_KEY_LOCATION_B] # replace 'no LOC' underscores with spaces. loc = loc.replace('_', ' ') # lets just make sure sensor in CTBTO supported list # should never get here is cfg files deployed correctly if seis_model not in CTBTO_SEIS_MODELS: msg = 'PyCal UNSUPPORTED SENSOR MODEL: ' + seis_model logging.error(msg) QtWidgets.QMessageBox().critical(self.app_win, 'PyCal ERROR', msg, QtWidgets.QMessageBox().Close, QtWidgets.QMessageBox().Close) return lf_calib = self.cfg.find_calib(seis_model + '|' + CALTYPE_RBLF) hf_calib = self.cfg.find_calib(seis_model + '|' + CALTYPE_RBHF) if (not lf_calib) or (not hf_calib): msg = 'Calib Record missing for sensor [{}].'.format(seis_model) logging.error(msg) QtWidgets.QMessageBox().critical(self.app_win, 'PyCal ERROR', msg, QtWidgets.QMessageBox().Close, QtWidgets.QMessageBox().Close) return sta = wcfg.data[WrapperCfg.WRAPPER_KEY_STA] ip = wcfg.data[WrapperCfg.WRAPPER_KEY_IP] output_dir = os.path.join(pcgl.get_results_root(), '-'.join([sta, ip.replace('.', '_'), sensor, seis_model])) makedirs(output_dir, mode=0o744, exist_ok=True) cal_descr = '{:>11} : {:<6} at {}'.format('Q330 Tag#', wcfg.data[WrapperCfg.WRAPPER_KEY_TAGNO], ip) cal_descr += '\n{:>11} : {} (Sensor {})'.format('Sensor', sensor_descr, sensor) cal_descr += '\n{:>11} : {}'.format('Station', wcfg.data[WrapperCfg.WRAPPER_KEY_STA]) cal_descr += '\n{:>11} : {}'.format('Loc', loc) cal_descr += '\n{:>11} : {}'.format('Chan Codes', chancodes) tot_cal_time = lf_calib.cal_time_min() + hf_calib.cal_time_min() cal_info = { 'sta' : sta, 'loc' : loc, 'chancodes' : chancodes, 'ip' : ip, 'seis_model' : seis_model, 'cal_descr': cal_descr, 'cal_tot_time_mins': tot_cal_time, 'cal_time' : { CALTYPE_RBLF : lf_calib.cal_time_min(), CALTYPE_RBHF : hf_calib.cal_time_min(), }, 'cmd_line' : { CALTYPE_RBHF : wcfg.gen_qcal_cmdline(sensor, CALTYPE_RBHF) + ' root=' + self.cfg.root_dir, CALTYPE_RBLF : wcfg.gen_qcal_cmdline(sensor, CALTYPE_RBLF) + ' root=' + self.cfg.root_dir }, 'output_dir': output_dir } logging.debug('cal_info:' + str(cal_info)) success, lf_msfn = self.run_sensor_cal_type(sensor, CALTYPE_RBLF, cal_info) if success: lf_logfn = os.path.splitext(lf_msfn)[0] + '.log' logging.info('QCal RBLF Miniseed file saved: ' + os.path.join(output_dir, lf_msfn)) logging.info('QCal RBLF Log file saved: ' + os.path.join(output_dir, lf_logfn)) # need 5.5 minute "cooling off period" before starting HF run if not self.cool_off_q330(window_title='PyCal - Preparing for HF Stage', info_text='Preparing for HF calibration stage...', cooling_period_seconds=330): return success, hf_msfn = self.run_sensor_cal_type(sensor, CALTYPE_RBHF, cal_info) if success: chancodeslst = chancodes.split(',') channel_codes = ComponentsTpl(vertical=chancodeslst[0], north=chancodeslst[1], east=chancodeslst[2]) hf_logfn = os.path.splitext(hf_msfn)[0] + '.log' logging.info('QCal RBHF Miniseed file saved: ' + os.path.join(output_dir, hf_msfn)) logging.info('QCal RBHF Log file saved: ' + os.path.join(output_dir, hf_logfn)) # msg_box = QtWidgets.QMessageBox(self.app_win) # msg_box.setIcon(QtWidgets.QMessageBox.Information) # msg_box.setText('PyCal Analysis Phase Starting') # msg_box.setInformativeText( # 'Calibration data acquired successfully.\n\n' + # 'The data will now be analyzed.\n' + # 'This will take several minutes.') # btn = msg_box.addButton('Continue...', QtWidgets.QMessageBox.RejectRole) # msg_box.setDefaultButton(btn) # msg_box.exec() # if seis_model in SEISMOMETER_RESPONSES: if getattr(sys, 'frozen', False): bundle_dir = sys._MEIPASS full_paz_fn = os.path.abspath(os.path.join(bundle_dir, 'IDA', 'data', SEISMOMETER_RESPONSES[seis_model]['full_resp_file'])) else: full_paz_fn = os.path.abspath(os.path.join('.', 'data', SEISMOMETER_RESPONSES[seis_model]['full_resp_file'])) else: msg1 = 'PyCal does not have response information for SENSOR MODEL: ' + seis_model msg2 = 'Analysis can not be performed.' logging.error(msg1) logging.error(msg2) QtWidgets.QMessageBox().critical(self.app_win, 'PyCal ERROR', msg1 + '\n' + msg2, QtWidgets.QMessageBox().Close, QtWidgets.QMessageBox().Close) return logging.info('Analysis starting...') logging.debug('Using FULL response at: ' + full_paz_fn) retcode, \ ims_calres_txt_fn, \ cal_amp_plot_fn, \ cal_pha_plot_fn = self.run_analysis(process_qcal_data, sta, channel_codes, loc, output_dir, (lf_msfn, lf_logfn), (hf_msfn, hf_logfn), seis_model, full_paz_fn) if retcode == 0: logging.info('Analysis phase completed with return code: {}'.format(retcode)) logging.info('The following files have been saved in directory: ' + output_dir) logging.info(' {} {}'.format('CALIBRATE_RESULT Msg: ', os.path.basename(ims_calres_txt_fn))) logging.info(' {} {}'.format('Amplitude Response Plots: ', os.path.basename(cal_amp_plot_fn))) logging.info(' {} {}'.format('Phase Response Plots: ', os.path.basename(cal_pha_plot_fn))) msg_list = ['Result files saved in directory:\n\n{}\n\n'.format(output_dir), '{}\n{}\n\n'.format('IMS 2.0 MESSAGE TEMPLATE:', os.path.basename(ims_calres_txt_fn)), '{}\n{}\n\n'.format('AMP PLOTS:', os.path.basename(cal_amp_plot_fn)), '{}\n{}'.format('PHASE PLOTS:', os.path.basename(cal_pha_plot_fn))] res = QtWidgets.QMessageBox().information(self.app_win, 'PyCal', 'Calibration completed successfully!\n\n' + ''.join(msg_list), QtWidgets.QMessageBox().Close, QtWidgets.QMessageBox().Close) call(['open', output_dir]) call(['open', '-a', 'TextEdit', ims_calres_txt_fn]) call(['open', cal_amp_plot_fn]) call(['open', cal_pha_plot_fn]) else: logging.warning('Analysis phase completed with return code: {}'.format(retcode)) else: self.update_details(self.cur_row) # triggers comms check... else: self.update_details(self.cur_row) # triggers comms check... logging.error("Unable to complete calibration")
def run_test_analysis(self): QtWidgets.QMessageBox().information(self.app_win, 'PyCal Analysis', 'Calibration data acquired successfully.\n\n' 'The data will now be analyzed.\n' 'This could take several minutes.', QtWidgets.QMessageBox().Close, QtWidgets.QMessageBox().Close) channel_codes = ComponentsTpl(north='BHN', east='BHE', vertical='BHZ') sensor = 'A' seis_model = SEISTYPE_STS25 # sta = 'AS108' # loc = '10' # ip = '198.202.124.228' # hf_msfn = 'CAL-198.202.124.228-sts2.5-rbhf-2016-0511-1213.ms' # hf_logfn = 'CAL-198.202.124.228-sts2.5-rbhf-2016-0511-1213.log' # lf_msfn = 'CAL-198.202.124.228-sts2.5-rblf-2016-0511-1249.ms' # lf_logfn = 'CAL-198.202.124.228-sts2.5-rblf-2016-0511-1249.log' # # # XPFO "Fast" test # seis_model = 'sts2.5-F' # sta='XPFO' # ip = '172.23.34.108' # hf_msfn = 'CAL-172.23.34.108-sts2.5-F-rbhf-2016-0511-0838.ms' # hf_logfn = 'CAL-172.23.34.108-sts2.5-F-rbhf-2016-0511-0838.log' # lf_msfn = 'CAL-172.23.34.108-sts2.5-F-rblf-2016-0511-0836.ms' # lf_logfn = 'CAL-172.23.34.108-sts2.5-F-rblf-2016-0511-0836.log' # seis_model = self.test_set['seis_model'] sta = self.test_set['sta'] ip = self.test_set['ip'] loc = self.test_set['loc'] hf_msfn = self.test_set['hf_msfn'] hf_logfn = self.test_set['hf_logfn'] lf_msfn = self.test_set['lf_msfn'] lf_logfn = self.test_set['lf_logfn'] output_dir = os.path.join(pcgl.get_results_root(), '-'.join([sta, ip.replace('.','_'), sensor, seis_model])) if seis_model in SEISMOMETER_RESPONSES: if getattr(sys, 'frozen', False): bundle_dir = sys._MEIPASS full_paz_fn = os.path.abspath(os.path.join(bundle_dir, 'IDA', 'data', SEISMOMETER_RESPONSES[seis_model]['full_resp_file'])) else: full_paz_fn = os.path.abspath(os.path.join('.', 'data', SEISMOMETER_RESPONSES[seis_model]['full_resp_file'])) else: msg1 = 'PyCal does not have response information for SENSOR MODEL: ' + seis_model msg2 = 'Analysis can not be performed.' logging.error(msg1) logging.error(msg2) QtWidgets.QMessageBox().critical(self.app_win, 'PyCal ERROR', msg1 + '\n' + msg2, QtWidgets.QMessageBox().Close, QtWidgets.QMessageBox().Close) return logging.info('Analysis starting...') logging.debug('Using FULL response at: ' + full_paz_fn) retcode, \ ims_calres_txt_fn, \ cal_amp_plot_fn, \ cal_pha_plot_fn = self.run_analysis(process_qcal_data, sta, channel_codes, loc, output_dir, (lf_msfn, lf_logfn), (hf_msfn, hf_logfn), seis_model, full_paz_fn) if retcode == 0: call(['open', output_dir]) call(['open', '-a', 'TextEdit', ims_calres_txt_fn]) call(['open', cal_amp_plot_fn]) call(['open', cal_pha_plot_fn]) msg_list = ['Results can be found in directory:\n\n{}\n\n'.format(output_dir), '{}\n{}\n\n'.format('IMS 2.0 MESSAGE TEMPLATE:', os.path.basename(ims_calres_txt_fn)), '{}\n{}\n\n'.format('AMP PLOTS:', os.path.basename(cal_amp_plot_fn)), '{}\n{}'.format('PHASE PLOTS:', os.path.basename(cal_pha_plot_fn))] logging.info('The following files have been saved in directory: ' + output_dir) logging.info(' IMS 2.0 MESSAGE TEMPLATE: ' + os.path.basename(ims_calres_txt_fn)) logging.info(' Amplitude Response Plots: ' + os.path.basename(cal_amp_plot_fn)) logging.info(' Phase Response Plots: ' + os.path.basename(cal_pha_plot_fn)) res = QtWidgets.QMessageBox().information(self.app_win, 'PyCal', 'Calibration completed successfully!\n\n' + ''.join(msg_list), QtWidgets.QMessageBox().Close, QtWidgets.QMessageBox().Close)