Пример #1
0
    def __init__(self, raw_cfg_path, log_file=None, do_analysis=False):
        # load configuration
        print(raw_cfg_path)
        self._raw_settings = RAWSettings.RawGuiSettings()
        success = RAWSettings.loadSettings(self._raw_settings, raw_cfg_path)
        if success:
            self._raw_settings.set('CurrentCfg', raw_cfg_path)
        else:
            raise IOError('Load failed, config file might be corrupted.')

        # set ATSAS package
        find_atsas = self._raw_settings.get('autoFindATSAS')
        if find_atsas:
            atsas_dir = findATSASDirectory()
            self._raw_settings.set('ATSASDir', atsas_dir)

        # print to log file
        if log_file is None:
            self._stdout = sys.stdout
        else:
            self._stdout = open(log_file, mode='w')
        self.error_printer = ErrorPrinter(self._raw_settings, self._stdout)

        # create mask
        self._createMasks()

        if do_analysis:
            self.analysis_simulator = RAWAnalysisSimulator(
                self._raw_settings, self._stdout)
Пример #2
0
    def _calcGNOM(self, dmax):
        start = int(self.spinctrlIDs['qstart'])
        end = int(self.spinctrlIDs['qend'])
        self.gnom_settings['npts'] = 0

        path = self.raw_settings.get('GnomFilePath')  # TODO: temp path
        cwd = os.getcwd()
        savename = 't_dat.dat'

        while os.path.isfile(os.path.join(path, savename)):
            savename = 't' + savename

        outname = 't_out.out'
        while os.path.isfile(os.path.join(path, outname)):
            outname = 't' + outname

        save_sasm = SASM.SASM(
            copy.deepcopy(self.curr_sasm.i), copy.deepcopy(self.curr_sasm.q),
            copy.deepcopy(self.curr_sasm.err),
            copy.deepcopy(self.curr_sasm.getAllParameters()))
        save_sasm.setParameter('filename', savename)
        save_sasm.setQrange((start, end))

        try:
            SASFileIO.saveMeasurement(
                save_sasm, path, self.raw_settings, filetype='.dat')
        except SASExceptions.HeaderSaveError as error:
            printer = ErrorPrinter(self.raw_settings, self._stdout)
            printer.showSaveError('header')

        os.chdir(path)
        try:
            iftm = SASCalc.runGnom(
                savename,
                outname,
                dmax,
                self.gnom_settings,
                new_gnom=self.new_gnom,
                raw_settings=self.raw_settings)
        except SASExceptions.NoATSASError as error:
            print('Error running GNOM/DATGNOM:', str(error), file=self._stdout)
            self.cleanupGNOM(path, savename, outname)
            os.chdir(cwd)
            return None

        os.chdir(cwd)
        # self.cleanupGNOM(path, savename, outname)

        return iftm
Пример #3
0
    def saveIFTM(self, iftm, save_path):
        """Save IFTM object to file."""
        if iftm.getParameter('algorithm') == 'GNOM':
            newext = '.out'
        else:
            newext = '.ift'

        filename = iftm.getParameter('filename')
        check_filename, ext = os.path.splitext(filename)
        check_filename = check_filename + newext

        filepath = os.path.join(save_path, check_filename)
        # file_exists = os.path.isfile(filepath)
        filepath = save_path

        try:
            SASFileIO.saveMeasurement(
                iftm, filepath, self.raw_settings, filetype=newext)
        except SASExceptions.HeaderSaveError:
            printer = ErrorPrinter(self.raw_settings, self._stdout)
            printer.showSaveError('header')
Пример #4
0
    def _initGNOM(self, sasm):
        analysis_dict = sasm.getParameter('analysis')
        if 'GNOM' in analysis_dict:
            iftm = self._initGnomValues(sasm)
            assert False
        else:
            path = self.raw_settings.get('GnomFilePath')  # TODO: temp files?
            cwd = os.getcwd()
            savename = 't_dat.dat'

            while os.path.isfile(os.path.join(path, savename)):
                savename = 't' + savename

            save_sasm = SASM.SASM(
                copy.deepcopy(sasm.i), copy.deepcopy(sasm.q),
                copy.deepcopy(sasm.err),
                copy.deepcopy(sasm.getAllParameters()))
            save_sasm.setParameter('filename', savename)
            save_sasm.setQrange(sasm.getQrange())

            try:
                SASFileIO.saveMeasurement(
                    save_sasm, path, self.raw_settings, filetype='.dat')
            except SASExceptions.HeaderSaveError as error:
                printer = ErrorPrinter(self.raw_settings, self._stdout)
                printer.showSaveError('header')

            os.chdir(path)
            try:
                init_iftm = SASCalc.runDatgnom(savename, sasm,
                                               self.raw_settings)
            except SASExceptions.NoATSASError as error:
                print(
                    'Error running GNOM/DATGNOM:',
                    str(error),
                    file=self._stdout)
                self.cleanupGNOM(path, savename=savename)
                os.chdir(cwd)
                return None
            os.chdir(cwd)

            if init_iftm is None:
                outname = 't_datgnom.out'
                while os.path.isfile(outname):
                    outname = 't' + outname

                if 'guinier' in analysis_dict:
                    rg = float(analysis_dict['guinier']['Rg'][0])  # TODO: [0]?
                    dmax = int(rg * 3.)  #Mostly arbitrary guess at Dmax
                    print("????:", rg)
                else:
                    print(
                        'No DMAX found warning:',
                        'No Guinier analysis found, arbirary value 80 will be set to DMAX.',
                        file=self._stdout)
                    dmax = 80  #Completely arbitrary default setting for Dmax

                os.chdir(path)
                try:
                    init_iftm = SASCalc.runGnom(
                        savename,
                        outname,
                        dmax,
                        self.gnom_settings,
                        new_gnom=self.new_gnom,
                        raw_settings=self.raw_settings)
                except SASExceptions.NoATSASError as error:
                    print(
                        'Error running GNOM/DATGNOM',
                        str(error),
                        file=self._stdout)
                    self.cleanupGNOM(path, savename=savename, outname=outname)
                    os.chdir(cwd)
                    return None
                os.chdir(cwd)

                self.cleanupGNOM(path, outname=outname)

            self.cleanupGNOM(path, savename=savename)

            iftm = self._initDatgnomValues(sasm, init_iftm)

        # plotPanel.plotPr(iftm)
        return iftm
Пример #5
0
class RAWSimulator():
    """ RAW operator """
    def __init__(self, raw_cfg_path, log_file=None, do_analysis=False):
        # load configuration
        print(raw_cfg_path)
        self._raw_settings = RAWSettings.RawGuiSettings()
        success = RAWSettings.loadSettings(self._raw_settings, raw_cfg_path)
        if success:
            self._raw_settings.set('CurrentCfg', raw_cfg_path)
        else:
            raise IOError('Load failed, config file might be corrupted.')

        # set ATSAS package
        find_atsas = self._raw_settings.get('autoFindATSAS')
        if find_atsas:
            atsas_dir = findATSASDirectory()
            self._raw_settings.set('ATSASDir', atsas_dir)

        # print to log file
        if log_file is None:
            self._stdout = sys.stdout
        else:
            self._stdout = open(log_file, mode='w')
        self.error_printer = ErrorPrinter(self._raw_settings, self._stdout)

        # create mask
        self._createMasks()

        if do_analysis:
            self.analysis_simulator = RAWAnalysisSimulator(
                self._raw_settings, self._stdout)

    # def __exit__():
    # close file
    #    self._stdout.close()

    def _createMasks(self, overwrite_cached=False):
        """Create mask from mask objects."""
        print('Please wait while creating masks...', file=self._stdout)
        mask_dict = self._raw_settings.get('Masks')
        img_dim = self._raw_settings.get('MaskDimension')

        cfg_path = self._raw_settings.get('CurrentCfg')
        cfg_name, _ = os.path.splitext(cfg_path)

        # mask path: /where/is/the/cfgfile/cfgname-BeamStopMask.npy
        cached_path = glob.glob('{0}-{1}'.format(cfg_name, '*Mask*.npy'))
        cached_masks = {
            os.path.splitext(mask_path.split('-')[-1])[0]: mask_path
            for mask_path in cached_path
        }

        for each_key in mask_dict.keys():
            # each_key: 'TransparentBSMask', 'BeamStopMask', 'ReadOutNoiseMask'
            # mask_dict[key] = [mask_matrix, mask_object]
            masks = mask_dict[each_key][1]
            if masks is not None:
                if each_key in cached_masks:
                    mask_img = np.load(cached_masks[each_key])
                else:
                    mask_img = SASImage.createMaskMatrix(img_dim, masks)
                mask_param = mask_dict[each_key]
                self._raw_settings.set(each_key, mask_img)
                mask_param[0] = mask_img
                mask_param[1] = masks

                if overwrite_cached:
                    np.save('{0}-{1}'.format(cfg_name, each_key), mask_img)
                elif each_key not in cached_masks:
                    np.save('{0}-{1}'.format(cfg_name, each_key), mask_img)

    def get_raw_settings(self):
        return self._raw_settings

    def get_raw_settings_value(self, key):
        return self._raw_settings.get(key)

    def get_stdout(self):
        return self._stdout

    def set_raw_settings(self, **kwargs):
        for key, val in kwargs.items():
            self._raw_settings.set(key, val)

    def analyse(self, sasm):
        """
        sasm is SASM object instead of a list object
        """
        self.analysis_simulator.analyse(sasm)

    def alignSASMs(self, marked_sasm, selected_sasms, qrange):
        """Align selected sasms in-place with marked sasm.

        Parameters
        ----------
        marked_sasm : SASM object
            Reference sasm for alignment.
        selected_sasms : SASM object
            Scale selected sasm to align with reference.
        qrange : (qmin, qmax), float
            Q range for alignment and scaling. 

        Returns
        -------
        None
        """
        print('Please wait while aligning and plotting...', file=self._stdout)

        if marked_sasm is None:
            self.error_printer.showPleaseMarkItemError('align')
            return None
        elif not selected_sasms:
            self.error_printer.showPleaseSelectItemsError('align')
            return None

        qmin, qmax = qrange

        ref_sasm = copy.deepcopy(marked_sasm)
        ref_q = ref_sasm.q
        ref_i = ref_sasm.i
        if qmax < 0:
            ref_indices = ref_q >= qmin
        else:
            ref_indices = np.logical_and(ref_q >= qmin, ref_q < qmax)

        # TODO: Improve this is rough scaling method that assumes curves are parallel.
        stat_func = np.mean
        for each_sasm in selected_sasms:
            curve_q = each_sasm.q
            curve_i = each_sasm.i

            if qmax < 0:
                curve_indices = curve_q >= qmin
            else:
                curve_indices = np.logical_and(curve_q >= qmin, curve_q < qmax)

            scaling_factor = stat_func(ref_i[ref_indices]) / stat_func(
                curve_i[curve_indices])
            print('For {}, scaling factor is {}.'.format(
                each_sasm.getParameter('filename'), scaling_factor),
                  file=self._stdout)
            each_sasm.scale(scaling_factor)

    def scaleSASMs(self, selected_sasms, scaling_factors):
        """Scale selected sasms in-place by give scaling factors.

        Parameters
        ----------
        selected_sasms : SASM object
            Scale selected sasm to scale.
        scaling_factor : iterable float numbers
            Scaling fator for sasm. Must be the same size of selected sasm.

        Returns
        -------
        None
        """
        print('Please wait while aligning and plotting...', file=self._stdout)

        if not selected_sasms:
            self.error_printer.showPleaseSelectItemsError('scale')
            return None
        if len(selected_sasms) != len(scaling_factors):
            raise ValueError(
                'Scaling factors should be the same size with selected sasms.')

        for each_sasm, factor in zip(selected_sasms, scaling_factors):
            each_sasm.scale(float(factor))

    def calibrateSASM(self, sasm):
        pass
        # sd_distance = self._raw_settings.get('SampleDistance')
        # pixel_size = self._raw_settings.get('DetectorPixelSize')
        # wavelength = self._raw_settings.get('WaveLength')
        # sasm.calibrateQ(sd_distance, pixel_size, wavelength)

    def loadSASMs(self, filename_list):
        """Load image or dat files."""
        print('Please wait while loading files...', file=self._stdout)
        sasm_list = []
        do_auto_save = self._raw_settings.get('AutoSaveOnImageFiles')

        try:
            for each_filename in filename_list:
                # file_ext = os.path.splitext(each_filename)[1]
                sasm, img = SASFileIO.loadFile(each_filename,
                                               self._raw_settings)

                if img is not None:
                    # qrange = sasm.getQrange()
                    start_point = self._raw_settings.get('StartPoint')
                    end_point = self._raw_settings.get('EndPoint')

                    if isinstance(sasm, list):
                        qrange = (start_point,
                                  len(sasm[0].getBinnedQ()) - end_point)
                        for each_sasm in sasm:
                            each_sasm.setQrange(qrange)
                    else:
                        qrange = (start_point,
                                  len(sasm.getBinnedQ()) - end_point)
                        sasm.setQrange(qrange)

                    if do_auto_save:
                        save_path = self._raw_settings.get('ProcessedFilePath')
                        try:
                            if isinstance(sasm, list):
                                for each in sasm:
                                    self.saveSASM(each, '.dat', save_path)
                            else:
                                self.saveSASM(sasm, '.dat', save_path)
                        except IOError as error:
                            self._raw_settings.set('AutoSaveOnImageFiles',
                                                   False)
                            do_auto_save = False

                if isinstance(sasm, list):
                    sasm_list.extend(sasm)
                else:
                    sasm_list.append(sasm)

        except (SASExceptions.UnrecognizedDataFormat,
                SASExceptions.WrongImageFormat) as error:
            self.error_printer.showDataFormatError(
                os.path.split(each_filename)[1])
            raise error
        except SASExceptions.HeaderLoadError as error:
            print(
                str(error), 'Error Loading Headerfile:'
                'Please check that the header file is in the directory with the data.',
                file=self._stdout)
            raise error
        except SASExceptions.MaskSizeError as error:
            print(str(error),
                  'Saved mask does not fit loaded image',
                  file=self._stdout)
            raise error
        except SASExceptions.HeaderMaskLoadError as error:
            print(str(error),
                  'Mask information was not found in header',
                  file=self._stdout)
            raise error

        return sasm_list

    def loadIFTMs(self, filename_list):
        """Load GNOM .ift/.out files."""
        print('Please wait while loading files...', file=self._stdout)
        iftm_list = []

        try:
            for each_filename in filename_list:
                file_ext = os.path.splitext(each_filename)[1]
                if file_ext == '.ift' or file_ext == '.out':
                    iftm, _ = SASFileIO.loadFile(each_filename,
                                                 self._raw_settings)
                    if isinstance(iftm, list):
                        iftm_list.extend(iftm)
                    else:
                        iftm_list.append(iftm)

        except (SASExceptions.UnrecognizedDataFormat,
                SASExceptions.WrongImageFormat) as error:
            self.error_printer.showDataFormatError(
                os.path.split(each_filename)[1])
            raise error
        except SASExceptions.HeaderLoadError as error:
            print(
                str(error), 'Error Loading Headerfile:'
                'Please check that the header file is in the directory with the data.',
                file=self._stdout)
            raise error
        except SASExceptions.MaskSizeError as error:
            print(str(error),
                  'Saved mask does not fit loaded image',
                  file=self._stdout)
            raise error
        except SASExceptions.HeaderMaskLoadError as error:
            print(str(error),
                  'Mask information was not found in header',
                  file=self._stdout)
            raise error

        return iftm_list

    def superimposeSASMs(self, marked_sasm, selected_sasms):
        """Superimpose seleceted sasms with marked sasm."""
        superimposed_sasms = copy.deepcopy(selected_sasms)
        if marked_sasm in selected_sasms:
            superimposed_sasms.remove(marked_sasm)

        if marked_sasm is None:
            self.error_printer.showPleaseMarkItemError('superimpose')
            return None

        if not selected_sasms:
            self.error_printer.showPleaseSelectItemsError('superimpose')
            return None

        SASM.superimpose(marked_sasm, superimposed_sasms)
        return superimposed_sasms

    def subtractSASMs(self, marked_sasm, selected_sasms, yes_to_all=False):
        """Subtracts the marked sasm from other selected sasms in
        the manipulation list.

        Parameters
        ----------
        marked_sasm : SASM object
            Minuend in subtraction.
        selected_sasms: list of SASM object
            Subtrahend in subtraction.
        yes_to_all : bool, optional
            Whether to force subtraction for all sasms, if q vectors are not equal.
            Default is False.

        Returns
        -------
        subtracted_list : list of SASM object
        """
        print('Please wait while subtracting and plotting...',
              file=self._stdout)
        do_auto_save = self._raw_settings.get('AutoSaveOnSub')

        if marked_sasm in selected_sasms:
            selected_sasms.remove(marked_sasm)

        if marked_sasm is None:
            self.error_printer.showPleaseMarkItemError('subtract')
            return None
        elif not selected_sasms:
            self.error_printer.showPleaseSelectItemsError('subtract')
            return None

        sub_sasm = marked_sasm
        sub_qmin, sub_qmax = sub_sasm.getQrange()
        subtracted_list = []

        for sasm in selected_sasms:
            print(sasm.getParameter('filename'))
            qmin, qmax = sasm.getQrange()

            if np.all(
                    np.round(sasm.q[qmin:qmax], 5) == np.round(
                        sub_sasm.q[sub_qmin:sub_qmax], 5)) is False:
                self.error_printer.showQvectorsNotEqualWarning(sasm, sub_sasm)
                if not yes_to_all:
                    raise SASExceptions.DataNotCompatible

            try:
                subtracted_sasm = SASM.subtract(sasm,
                                                sub_sasm,
                                                forced=yes_to_all)
                self.insertSasmFilenamePrefix(subtracted_sasm, 'S_')
                subtracted_list.append(subtracted_sasm)

                if do_auto_save:
                    save_path = self._raw_settings.get('SubtractedFilePath')
                    try:
                        self.saveSASM(subtracted_sasm, '.dat', save_path)
                    except IOError as error:
                        self._raw_settings.set('AutoSaveOnSub', False)
                        do_auto_save = False
                        print(
                            str(error) +
                            '\n\nAutosave of subtracted images has been disabled. If you are using a config file from a different computer please go into Advanced Options/Autosave to change the save folders, or save you config file to avoid this message next time.',
                            'Autosave Error')

            except SASExceptions.DataNotCompatible:
                self.error_printer.showSubtractionError(sasm, sub_sasm)
                return None

        return subtracted_list

    def averageSASMs(self, selected_sasms, yes_to_all=False):
        """ average selected sasms in the manipulation list.
        
        Parameters
        ----------
        selected_sasms: list of SASM object
            Sasm list for averaging
        yes_to_all : bool, optional
            Whether to force subtraction for all sasms, if q vectors are not equal.
            Default is False.

        Returns
        -------
        average_sasm : SASM object
            Return average sasm.
        """
        print('Please wait while averaging and plotting...', file=self._stdout)
        do_auto_save = self._raw_settings.get('AutoSaveOnAvgFiles')

        if len(selected_sasms) < 2:
            self.error_printer.showAverageError(2)
            return None

        try:
            avg_sasm = SASM.average(selected_sasms, forced=yes_to_all)
        except SASExceptions.DataNotCompatible:
            self.error_printer.showAverageError(3)
            return None

        self.insertSasmFilenamePrefix(avg_sasm, 'A_')

        if do_auto_save:
            save_path = self._raw_settings.get('AveragedFilePath')
            try:
                self.saveSASM(avg_sasm, '.dat', save_path)
            except IOError as error:
                self._raw_settings.set('AutoSaveOnAvgFiles', False)
                print(
                    str(error) +
                    '\n\nAutosave of averaged images has been disabled. If you are using a config file from a different computer please go into Advanced Options/Autosave to change the save folders, or save you config file to avoid this message next time.',
                    'Autosave Error')

        return avg_sasm

    def weightedAverageSASMs(self, selected_sasms, yes_to_all=False):
        """Average selected sasms with weights in the manipulation list.
       
        Parameters
        ----------
        selected_sasms: list of SASM object
            Sasm list for averaging
        yes_to_all : bool, optional
            Whether to force subtraction for all sasms, if q vectors are not equal.
            Default is False.

        Returns
        -------
        average_sasm : SASM object
            Return average sasm.
        """
        print('Please wait while averaging and plotting...', file=self._stdout)
        do_auto_save = self._raw_settings.get('AutoSaveOnAvgFiles')

        if len(selected_sasms) < 2:
            self.error_printer.showAverageError(2)
            return None

        weightByError = self._raw_settings.get('weightByError')
        weightCounter = self._raw_settings.get('weightCounter')

        if not weightByError and weightCounter == '':
            print(
                'Weighted Average Error:\n',
                '  An appropriate counter to weight the data is not selected and error weighting is not enabled. Weighted average aborted.',
                file=self._stdout)
            return

        if not weightByError:
            has_header = []
            for each_sasm in selected_sasms:
                header_keys = []
                if each_sasm.getAllParameters().has_key('counters'):
                    file_hdr = each_sasm.getParameter('counters')
                    header_keys = header_keys + file_hdr.keys()
                if each_sasm.getAllParameters().has_key('imageHeader'):
                    img_hdr = each_sasm.getParameter('imageHeader')
                    header_keys = header_keys + img_hdr.keys()

                if weightCounter in header_keys:
                    has_header.append(True)
                else:
                    has_header.append(False)
            if not np.all(has_header):
                print(
                    'Weighted Average Error:',
                    'Not all selected items had the counter value selected as the weight. Weighted average aborted.',
                    file=self._stdout)
                return None

        try:
            avg_sasm = SASM.weightedAverage(selected_sasms,
                                            weightByError,
                                            weightCounter,
                                            forced=yes_to_all)
        except SASExceptions.DataNotCompatible:
            self.error_printer.showAverageError(3)
            return

        self.insertSasmFilenamePrefix(avg_sasm, 'A_')

        if do_auto_save:
            save_path = self._raw_settings.get('AveragedFilePath')
            try:
                self.saveSASM(avg_sasm, '.dat', save_path)
            except IOError as error:
                self._raw_settings.set('AutoSaveOnAvgFiles', False)
                print(
                    str(error) +
                    '\n\nAutosave of averaged images has been disabled. If you are using a config file from a different computer please go into Advanced Options/Autosave to change the save folders, or save you config file to avoid this message next time.',
                    'Autosave Error')

        return avg_sasm

    def rebinSASMs(self, selected_sasms, rebin_factor, log_rebin):
        rebinned_list = []
        for sasm in selected_sasms:
            points = np.floor(len(sasm.q) / rebin_factor)
            if log_rebin:
                rebin_sasm = SASM.logBinning(sasm, points)
            else:
                rebin_sasm = SASM.rebin(sasm, rebin_factor)
            self.insertSasmFilenamePrefix(rebin_sasm, 'R_')
            rebinned_list.append(rebin_sasm)
        return rebinned_list

    def mergeSASMs(self, marked_sasm, selected_sasms):
        """Merge selected sasms with marked sasm."""
        if marked_sasm in selected_sasms:
            selected_sasms.remove(marked_sasm)

        if marked_sasm is None:
            self.error_printer.showPleaseMarkItemError('merge')
            return None

        merged_sasm = SASM.merge(marked_sasm, selected_sasms)
        filename = marked_sasm.getParameter('filename')
        merged_sasm.setParameter('filename', filename)
        self.insertSasmFilenamePrefix(merged_sasm, 'M_')

        return merged_sasm

    def interpolateItems(self, marked_sasm, selected_sasms):
        """Interpolate sasms with marked sasm."""
        if marked_sasm in selected_sasms:
            selected_sasms.remove(marked_sasm)

        if marked_sasm is None:
            self.error_printer.showPleaseMarkItemError('interpolate')
            return None

        interpolated_list = []
        for sasm in selected_sasms:
            interpolate_sasm = SASM.interpolateToFit(marked_sasm, sasm)
            filename = sasm.getParameter('filename')
            interpolate_sasm.setParameter('filename', filename)
            self.insertSasmFilenamePrefix(interpolate_sasm, 'I_')
            interpolated_list.append(interpolate_sasm)

        return interpolated_list

    def insertSasmFilenamePrefix(self, sasm, prefix='', extension=''):
        filename = sasm.getParameter('filename')
        new_filename, _ = os.path.splitext(filename)
        sasm.setParameter('filename', prefix + new_filename + extension)

    def saveSASM(self, sasm, filetype='dat', save_path=''):
        """Save SASM object to file."""
        newext = filetype

        filename = sasm.getParameter('filename')
        check_filename, _ = os.path.splitext(filename)
        check_filename = check_filename + newext

        filepath = os.path.join(save_path, check_filename)
        # file_exists = os.path.isfile(filepath)
        filepath = save_path

        try:
            SASFileIO.saveMeasurement(sasm,
                                      filepath,
                                      self._raw_settings,
                                      filetype=newext)
        except SASExceptions.HeaderSaveError:
            self.error_printer.showSaveError('header')