Пример #1
0
class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(636, 590)
        self.gridLayout = QtWidgets.QGridLayout(Form)
        self.gridLayout.setContentsMargins(9, 9, 9, 9)
        self.gridLayout.setSpacing(6)
        self.gridLayout.setObjectName("gridLayout")
        self.settings_layout = QtWidgets.QVBoxLayout()
        self.settings_layout.setObjectName("settings_layout")
        self.verticalLayout_4 = QtWidgets.QVBoxLayout()
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.title_label = QtWidgets.QLabel(Form)
        self.title_label.setMaximumSize(QtCore.QSize(16777215, 30))
        font = QtGui.QFont()
        font.setFamily("Tahoma")
        font.setPointSize(14)
        font.setBold(True)
        font.setItalic(True)
        font.setWeight(75)
        self.title_label.setFont(font)
        self.title_label.setAlignment(QtCore.Qt.AlignCenter)
        self.title_label.setObjectName("title_label")
        self.verticalLayout_4.addWidget(self.title_label)
        self.command_widget = QtWidgets.QWidget(Form)
        self.command_widget.setMaximumSize(QtCore.QSize(16777215, 30))
        self.command_widget.setObjectName("command_widget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.command_widget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setSpacing(0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.grab_pb = QtWidgets.QPushButton(self.command_widget)
        self.grab_pb.setText("")
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/run2.png"),
                       QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.grab_pb.setIcon(icon)
        self.grab_pb.setCheckable(True)
        self.grab_pb.setObjectName("grab_pb")
        self.horizontalLayout_2.addWidget(self.grab_pb)
        self.single_pb = QtWidgets.QPushButton(self.command_widget)
        self.single_pb.setText("")
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/snap.png"),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.single_pb.setIcon(icon1)
        self.single_pb.setCheckable(False)
        self.single_pb.setObjectName("single_pb")
        self.horizontalLayout_2.addWidget(self.single_pb)
        self.stop_pb = QtWidgets.QPushButton(self.command_widget)
        self.stop_pb.setText("")
        icon2 = QtGui.QIcon()
        icon2.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/stop.png"),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.stop_pb.setIcon(icon2)
        self.stop_pb.setCheckable(False)
        self.stop_pb.setObjectName("stop_pb")
        self.horizontalLayout_2.addWidget(self.stop_pb)
        self.save_current_pb = QtWidgets.QPushButton(self.command_widget)
        self.save_current_pb.setText("")
        icon3 = QtGui.QIcon()
        icon3.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/SaveAs.png"),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.save_current_pb.setIcon(icon3)
        self.save_current_pb.setObjectName("save_current_pb")
        self.horizontalLayout_2.addWidget(self.save_current_pb)
        self.save_new_pb = QtWidgets.QPushButton(self.command_widget)
        self.save_new_pb.setText("")
        icon4 = QtGui.QIcon()
        icon4.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/Snap&Save.png"),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.save_new_pb.setIcon(icon4)
        self.save_new_pb.setObjectName("save_new_pb")
        self.horizontalLayout_2.addWidget(self.save_new_pb)
        self.load_data_pb = QtWidgets.QPushButton(self.command_widget)
        self.load_data_pb.setText("")
        icon5 = QtGui.QIcon()
        icon5.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/Open.png"),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.load_data_pb.setIcon(icon5)
        self.load_data_pb.setObjectName("load_data_pb")
        self.horizontalLayout_2.addWidget(self.load_data_pb)
        self.settings_pb = QtWidgets.QPushButton(self.command_widget)
        self.settings_pb.setText("")
        icon6 = QtGui.QIcon()
        icon6.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/HLM.ico"),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.settings_pb.setIcon(icon6)
        self.settings_pb.setCheckable(True)
        self.settings_pb.setObjectName("settings_pb")
        self.horizontalLayout_2.addWidget(self.settings_pb)
        self.update_com_pb = QtWidgets.QPushButton(self.command_widget)
        self.update_com_pb.setText("")
        icon7 = QtGui.QIcon()
        icon7.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/Refresh2.png"),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.update_com_pb.setIcon(icon7)
        self.update_com_pb.setCheckable(False)
        self.update_com_pb.setObjectName("update_com_pb")
        self.horizontalLayout_2.addWidget(self.update_com_pb)
        self.navigator_pb = QtWidgets.QPushButton(self.command_widget)
        self.navigator_pb.setText("")
        icon8 = QtGui.QIcon()
        icon8.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/Select_24.png"),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.navigator_pb.setIcon(icon8)
        self.navigator_pb.setObjectName("navigator_pb")
        self.horizontalLayout_2.addWidget(self.navigator_pb)
        self.log_pb = QtWidgets.QPushButton(self.command_widget)
        self.log_pb.setText("")
        icon9 = QtGui.QIcon()
        icon9.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/information2.png"),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.log_pb.setIcon(icon9)
        self.log_pb.setObjectName("log_pb")
        self.horizontalLayout_2.addWidget(self.log_pb)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.verticalLayout_4.addWidget(self.command_widget)
        self.settings_widget = QtWidgets.QWidget(Form)
        self.settings_widget.setObjectName("settings_widget")
        self.settings_layout_2 = QtWidgets.QVBoxLayout(self.settings_widget)
        self.settings_layout_2.setContentsMargins(0, 0, 0, 0)
        self.settings_layout_2.setSpacing(0)
        self.settings_layout_2.setObjectName("settings_layout_2")
        self.gridLayout_3 = QtWidgets.QGridLayout()
        self.gridLayout_3.setContentsMargins(-1, 0, -1, -1)
        self.gridLayout_3.setSpacing(6)
        self.gridLayout_3.setObjectName("gridLayout_3")
        self.label_3 = QtWidgets.QLabel(self.settings_widget)
        self.label_3.setAlignment(QtCore.Qt.AlignRight
                                  | QtCore.Qt.AlignTrailing
                                  | QtCore.Qt.AlignVCenter)
        self.label_3.setObjectName("label_3")
        self.gridLayout_3.addWidget(self.label_3, 1, 0, 1, 3)
        self.DAQ_type_combo = QtWidgets.QComboBox(self.settings_widget)
        self.DAQ_type_combo.setObjectName("DAQ_type_combo")
        self.DAQ_type_combo.addItem("")
        self.DAQ_type_combo.addItem("")
        self.DAQ_type_combo.addItem("")
        self.DAQ_type_combo.addItem("")
        self.gridLayout_3.addWidget(self.DAQ_type_combo, 0, 3, 1, 3)
        self.label_4 = QtWidgets.QLabel(self.settings_widget)
        self.label_4.setAlignment(QtCore.Qt.AlignRight
                                  | QtCore.Qt.AlignTrailing
                                  | QtCore.Qt.AlignVCenter)
        self.label_4.setObjectName("label_4")
        self.gridLayout_3.addWidget(self.label_4, 0, 0, 1, 3)
        self.Quit_pb = QtWidgets.QPushButton(self.settings_widget)
        icon10 = QtGui.QIcon()
        icon10.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/close2.png"),
                         QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.Quit_pb.setIcon(icon10)
        self.Quit_pb.setObjectName("Quit_pb")
        self.gridLayout_3.addWidget(self.Quit_pb, 4, 0, 1, 2)
        self.Detector_type_combo = QtWidgets.QComboBox(self.settings_widget)
        self.Detector_type_combo.setObjectName("Detector_type_combo")
        self.gridLayout_3.addWidget(self.Detector_type_combo, 1, 3, 1, 3)
        self.load_settings_pb = QtWidgets.QPushButton(self.settings_widget)
        self.load_settings_pb.setIcon(icon5)
        self.load_settings_pb.setObjectName("load_settings_pb")
        self.gridLayout_3.addWidget(self.load_settings_pb, 7, 0, 3, 3)
        self.save_settings_pb = QtWidgets.QPushButton(self.settings_widget)
        self.save_settings_pb.setIcon(icon3)
        self.save_settings_pb.setObjectName("save_settings_pb")
        self.gridLayout_3.addWidget(self.save_settings_pb, 7, 3, 3, 3)
        self.take_bkg_cb = QtWidgets.QCheckBox(self.settings_widget)
        self.take_bkg_cb.setObjectName("take_bkg_cb")
        self.gridLayout_3.addWidget(self.take_bkg_cb, 5, 3, 2, 3)
        self.do_bkg_cb = QtWidgets.QCheckBox(self.settings_widget)
        self.do_bkg_cb.setObjectName("do_bkg_cb")
        self.gridLayout_3.addWidget(self.do_bkg_cb, 5, 0, 2, 3)
        self.Ini_state_LED = QLED(self.settings_widget)
        self.Ini_state_LED.setObjectName("Ini_state_LED")
        self.gridLayout_3.addWidget(self.Ini_state_LED, 4, 4, 1, 1)
        self.data_ready_led = QLED(self.settings_widget)
        self.data_ready_led.setObjectName("data_ready_led")
        self.gridLayout_3.addWidget(self.data_ready_led, 4, 5, 1, 1)
        self.IniDet_pb = QtWidgets.QPushButton(self.settings_widget)
        self.IniDet_pb.setCheckable(True)
        self.IniDet_pb.setChecked(False)
        self.IniDet_pb.setObjectName("IniDet_pb")
        self.gridLayout_3.addWidget(self.IniDet_pb, 4, 2, 1, 2)
        self.settings_layout_2.addLayout(self.gridLayout_3)
        self.verticalLayout_4.addWidget(self.settings_widget)
        self.settings_layout.addLayout(self.verticalLayout_4)
        self.gridLayout.addLayout(self.settings_layout, 0, 0, 1, 1)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.title_label.setText(_translate("Form", "DAQ Title"))
        self.grab_pb.setToolTip(_translate("Form", "Grab"))
        self.single_pb.setToolTip(_translate("Form", "Single Grab"))
        self.stop_pb.setToolTip(_translate("Form", "Single Grab"))
        self.save_current_pb.setToolTip(_translate("Form",
                                                   "Save Current Data"))
        self.save_new_pb.setToolTip(_translate("Form", "Save New Data"))
        self.settings_pb.setToolTip(_translate("Form", "Open Settings"))
        self.update_com_pb.setToolTip(_translate("Form", "Refresh Hardware"))
        self.navigator_pb.setToolTip(
            _translate("Form", "Send current data to navigator"))
        self.log_pb.setToolTip(_translate("Form", "Show Current log file"))
        self.label_3.setText(_translate("Form", "Detector:"))
        self.DAQ_type_combo.setToolTip(_translate("Form", "Detector Type"))
        self.DAQ_type_combo.setItemText(0, _translate("Form", "DAQ0D"))
        self.DAQ_type_combo.setItemText(1, _translate("Form", "DAQ1D"))
        self.DAQ_type_combo.setItemText(2, _translate("Form", "DAQ2D"))
        self.DAQ_type_combo.setItemText(3, _translate("Form", "DAQND"))
        self.label_4.setText(_translate("Form", "DAQ type:"))
        self.Quit_pb.setToolTip(_translate("Form",
                                           "quit and close the viewer"))
        self.Quit_pb.setText(_translate("Form", "Quit"))
        self.Detector_type_combo.setToolTip(_translate("Form", "Stage Type"))
        self.load_settings_pb.setToolTip(_translate("Form", "Load settings"))
        self.load_settings_pb.setText(_translate("Form", "Sett."))
        self.save_settings_pb.setToolTip(_translate("Form", "save settings"))
        self.save_settings_pb.setText(_translate("Form", "Sett."))
        self.take_bkg_cb.setText(_translate("Form", "Take Bkg"))
        self.do_bkg_cb.setText(_translate("Form", "Do Bkg sub."))
        self.Ini_state_LED.setToolTip(
            _translate("Form", "Green when controller is initialized"))
        self.Ini_state_LED.setText(_translate("Form", "TextLabel"))
        self.data_ready_led.setToolTip(
            _translate("Form", "Green when data ready"))
        self.data_ready_led.setText(_translate("Form", "TextLabel"))
        self.IniDet_pb.setToolTip(
            _translate("Form", "To initialize the detector"))
        self.IniDet_pb.setText(_translate("Form", "Ini. Det."))
Пример #2
0
class DAQ_Logger(CustomApp):
    """
    Main class initializing a DAQ_Logger module
    """
    command_DAQ_signal = Signal(list)
    status_signal = Signal(str)

    params = [
        {
            'title': 'Log Type:',
            'name': 'log_type',
            'type': 'str',
            'value': '',
            'readonly': True
        },
    ]

    def __init__(self, dockarea=None, dashboard=None):
        """

        Parameters
        ----------
        dockarea: (dockarea) instance of the modified pyqtgraph Dockarea (see daq_utils)
        dashboard: (DashBoard) instance of the pymodaq dashboard
        """

        super().__init__(dockarea, dashboard)

        self.wait_time = 1000

        self.logger_thread = None
        self.logger = None  # should be a reference either to self.h5saver or self.dblogger depending the choice of the user

    def setup_actions(self):
        '''
        subclass method from ActionManager
        '''
        logger.debug('setting actions')
        self.add_action('quit',
                        'Quit',
                        'close2',
                        "Quit program",
                        toolbar=self.toolbar)
        self.toolbar.addSeparator()
        self.add_action('start',
                        'Start Logging',
                        'run2',
                        "Start the logging",
                        checkable=True,
                        toolbar=self.toolbar)
        self.add_action('stop',
                        'Stop',
                        'stop',
                        'Stop/pause logging',
                        checkable=False,
                        toolbar=self.toolbar)

        log_type_combo = QtWidgets.QComboBox()
        log_type_combo.addItems(LOG_TYPES)
        log_type_combo.currentTextChanged.connect(self.set_log_type)
        self._actions['log_type'] = self.toolbar.addWidget(log_type_combo)
        self.toolbar.addSeparator()
        self.add_action('grab_all',
                        'Grab All',
                        'run_all',
                        "Grab all selected detectors",
                        checkable=True,
                        toolbar=self.toolbar)
        self.add_action('infos',
                        'Log infos',
                        'information2',
                        "Show log file",
                        checkable=False,
                        toolbar=self.toolbar)

        logger.debug('actions set')

    def setup_docks(self):
        logger.debug('setting docks')
        self.docks['detectors'] = Dock("Detectors")
        splitter = QtWidgets.QSplitter(Qt.Vertical)
        self.docks['detectors'].addWidget(splitter)
        splitter.addWidget(self.settings_tree)
        splitter.addWidget(self.modules_manager.settings_tree)
        self.modules_manager.settings.child('modules', 'actuators').hide()
        self.modules_manager.settings.child('actuators_positions').hide()
        self.dockarea.addDock(self.docks['detectors'])

        self.docks['logger_settings'] = Dock("Logger Settings")
        self.dockarea.addDock(self.docks['logger_settings'], 'right',
                              self.docks['detectors'])

        self.statusbar.setMaximumHeight(25)
        self.status_widget = QtWidgets.QLabel('Initializing')
        self.statusbar.addPermanentWidget(self.status_widget)

        self.start_log_time = QtWidgets.QDateTimeEdit()
        self.start_log_time.setReadOnly(True)
        self.start_log_time.setToolTip('Logging started at:')
        self.statusbar.addPermanentWidget(self.start_log_time)

        self.logging_state = QLED()
        self.logging_state.setToolTip(
            'logging status: green (running), red (idle)')
        self.logging_state.clickable = False
        self.statusbar.addPermanentWidget(self.logging_state)

    def connect_things(self):
        self.status_signal[str].connect(self.dashboard.add_status)
        self._actions['quit'].connect(self.quit_fun)

        self._actions['start'].connect(self.start_logging)
        self._actions['stop'].connect(self.stop_logging)
        self._actions['grab_all'].connect(self.start_all)

        self._actions['infos'].connect(self.dashboard.show_log)

    def setup_menu(self):
        """
        """
        file_menu = self.mainwindow.menuBar().addMenu('File')
        self.affect_to('infos', file_menu)

    def value_changed(self, param):
        if param.name() == 'log_type':
            self.set_logger(param.value())

    def set_logger(self, logger_interface):
        if self.logger is not None:
            self.logger.close()
            self.docks['logger_settings'].removeWidgets()

        if logger_interface == 'H5 File':
            self.logger = H5Logger()
        elif logger_interface == 'SQL DataBase':
            self.logger = DataBaseLogger(self.dashboard.preset_file.stem)
        else:
            return

        self.docks['logger_settings'].addWidget(self.logger.settings_tree)

    def quit_fun(self):
        """
            Quit the current instance of DAQ_scan and close on cascade move and detector modules.

            See Also
            --------
            quit_fun
        """
        try:
            self.logger.close()
        except Exception as e:
            logger.exception(str(e))

        self.dockarea.close()

    def set_continuous_save(self):
        """
            Set a continous save file using the base path located file with
            a header-name containing date as a string.

            See Also
            --------
            daq_utils.set_current_scan_path
        """
        self.do_continuous_save = True
        self.logger.settings.child(('N_saved')).show()
        self.logger.settings.child(('N_saved')).setValue(0)

        settings_str = b'<All_settings>'
        settings_str += pymodaq.daq_utils.parameter.ioxml.parameter_to_xml_string(
            self.dashboard.settings)
        settings_str += pymodaq.daq_utils.parameter.ioxml.parameter_to_xml_string(
            self.dashboard.preset_manager.preset_params)
        if self.dashboard.settings.child('loaded_files',
                                         'overshoot_file').value() != '':
            settings_str += pymodaq.daq_utils.parameter.ioxml.parameter_to_xml_string(
                self.dashboard.overshoot_manager.overshoot_params)
        if self.dashboard.settings.child('loaded_files',
                                         'roi_file').value() != '':
            settings_str += pymodaq.daq_utils.parameter.ioxml.parameter_to_xml_string(
                self.dashboard.roi_saver.roi_presets)
        settings_str += pymodaq.daq_utils.parameter.ioxml.parameter_to_xml_string(
            self.settings)
        settings_str += pymodaq.daq_utils.parameter.ioxml.parameter_to_xml_string(
            self.logger.settings)
        settings_str += b'</All_settings>'

        if not self.logger.init_logger(settings_str):
            return False
        logger.addHandler(self.logger.get_handler())
        return True

    def set_logging(self):
        """

        """
        status = self.set_continuous_save()
        if status:
            det_modules_log = self.modules_manager.detectors_all
            if det_modules_log != []:
                # check if the modules are initialized
                for module in det_modules_log:
                    if not module.initialized_state:
                        logger.error(
                            f'module {module.title} is not initialized')
                        return False

                # create the detectors in the chosen logger
                for det in det_modules_log:
                    settings_str = b'<All_settings>'
                    settings_str += pymodaq.daq_utils.parameter.ioxml.parameter_to_xml_string(
                        det.settings)
                    for viewer in det.ui.viewers:
                        if hasattr(viewer, 'roi_manager'):
                            settings_str += pymodaq.daq_utils.parameter.ioxml.parameter_to_xml_string(
                                viewer.roi_manager.settings)
                    settings_str += b'</All_settings>'

                    self.logger.add_detector(det.title, settings_str)

                self._actions['start'].setEnabled(True)
                self._actions['stop'].setEnabled(True)
                return True
            else:
                self.update_status(
                    'Cannot start logging... No detectors selected')
                self._actions['start'].setEnabled(False)
                self._actions['stop'].setEnabled(True)
                return False

        else:
            self.update_status('Cannot start logging... check connections')
            self._actions['start'].setEnabled(False)
            self._actions['stop'].setEnabled(True)
            return False

    def start_all(self):
        preset_items_det = self.modules_manager.detectors
        for det in preset_items_det:
            det.ui.grab_pb.click()

    def set_log_type(self, log_type):
        self.settings.child('log_type').setValue(log_type)

    def start_logging(self):
        """
            Start a logging.
        """
        self.status_widget.setText('Starting logging')

        self.overshoot = False
        res = self.set_logging()

        # mandatory to deal with multithreads
        if self.logger_thread is not None:
            self.command_DAQ_signal.disconnect()
            if self.logger_thread.isRunning():
                self.logger_thread.exit()
                while not self.logger_thread.isFinished():
                    QThread.msleep(100)
                self.logger_thread = None

        self.logger_thread = QThread()

        log_acquisition = DAQ_Logging(self.settings, self.logger,
                                      self.modules_manager)

        log_acquisition.moveToThread(self.logger_thread)

        self.command_DAQ_signal[list].connect(log_acquisition.queue_command)
        log_acquisition.status_sig[list].connect(self.thread_status)

        self.logger_thread.log_acquisition = log_acquisition
        self.logger_thread.start()

        self._actions['start'].setEnabled(False)
        QtWidgets.QApplication.processEvents()
        self.logging_state.set_as_false()

        self.command_DAQ_signal.emit(["start_logging"])
        self.status_widget.setText('Running acquisition')

    def stop_logging(self):
        """
            Emit the command_DAQ signal "stop_acquisiion".

            See Also
            --------
            set_ini_positions
        """
        preset_items_det = self.modules_manager.detectors
        for det in preset_items_det:
            det.stop()
        self.command_DAQ_signal.emit(["stop_acquisition"])

        if not self.dashboard.overshoot:
            status = 'Data Logging has been stopped by user'
        else:
            status = 'Data Logging has been stopped due to overshoot'

        self.update_status(status)
        self._actions['start'].setEnabled(True)

    @Slot(list)
    def thread_status(
        self, status
    ):  # general function to get datas/infos from all threads back to the main
        """
            | General function to get datas/infos from all threads back to the main.
            |

            Switch the status with :
                * *"Update status"* : Update the status bar with the status attribute txt message
                * *"Update_scan_index"* : Set the value of the User Interface - indice_scan_sb attribute.
                * *"Scan_done"* : Save the scan and init the positions
                * *"Timeout"* : Set the "Timeout occured" in the User Interface-log message

            See Also
            --------
            update_status, save_scan, set_ini_positions
        """
        if status[0] == "Update_Status":
            self.update_status(status[1], wait_time=self.wait_time)

        elif status[0] == "Timeout":
            self.status_widget.setText('Timeout occurred')

    def update_status(self, txt, wait_time=0):
        """
            Show the txt message in the status bar with a delay of wait_time ms.

            =============== =========== =======================
            **Parameters**    **Type**    **Description**
            *txt*             string      The message to show
            *wait_time*       int         the delay of showing
            *log_type*        string      the type of the log
            =============== =========== =======================
        """
        try:
            self.statusbar.showMessage(txt, wait_time)
            logger.info(txt)
        except Exception as e:
            logger.exception(str(e))