def on_upload_file(self, event):
        """
        Write all data to appropriate er_* and pmag_* files.
        Then use those files to create a MagIC upload format file.
        Validate the upload file.
        """
        # coherence validations
        wait = wx.BusyInfo('Validating data, please wait...')
        wx.SafeYield()
        spec_warnings, samp_warnings, site_warnings, loc_warnings = self.er_magic.validate_data()
        result_warnings = self.er_magic.validate_results(self.er_magic.results)
        meas_warnings = self.er_magic.validate_measurements(self.er_magic.measurements)
        self.warn_dict = {'specimen': spec_warnings, 'sample': samp_warnings,
                          'site': site_warnings, 'location': loc_warnings,
                          'result': result_warnings, 'age': {}, 'measurement': meas_warnings}
        # done coherence validations
        del wait
        # write upload file and perform data validations
        wait = wx.BusyInfo('Making upload file, please wait...')
        wx.SafeYield()
        self.er_magic.write_files()
        upfile, error_message, errors = ipmag.upload_magic(dir_path=self.WD,
                                                           data_model=self.data_model)
        del wait
        if upfile:
            text = "You are ready to upload.\nYour file:\n{}\nwas generated in directory: \n{}\nDrag and drop this file in the MagIC database.".format(os.path.split(upfile)[1], self.WD)
            dlg = wx.MessageDialog(self, caption="Saved", message=text, style=wx.OK)
        else:
            text = "There were some problems with the creation of your upload file.\nError message: {}\nSee Terminal/Command Prompt for details".format(error_message)
            dlg = wx.MessageDialog(self, caption="Error", message=text, style=wx.OK)
        result = dlg.ShowModal()
        if result == wx.ID_OK:
            dlg.Destroy()
        self.edited = False
        ## add together data & coherence errors into one dictionary
        if errors:
            for item_type in errors:
                for item_name in errors[item_type]:
                    if item_name in self.warn_dict[item_type]:
                        self.warn_dict[item_type][item_name].update(errors[item_type][item_name])
                    else:
                        self.warn_dict[item_type][item_name] = errors[item_type][item_name]

        has_problems = []
        for item_type, warnings in list(self.warn_dict.items()):
            if warnings:
                has_problems.append(item_type)
        # for any dtypes with validation problems (data or coherence),
        # highlight the button to the corresponding grid
        # skip this step for Windows
        if sys.platform in ['win32', 'win62']:
            pass
        else:
            for dtype in self.warn_dict:
                wind = self.FindWindowByName(dtype + '_btn')
                if wind:
                    if dtype in has_problems:
                        wind.Bind(wx.EVT_PAINT, self.highlight_button)
                    else:
                        wind.Unbind(wx.EVT_PAINT, handler=self.highlight_button)
            self.Refresh()
        if has_problems:
            self.validation_mode = set(has_problems)
            if sys.platform in ['win32', 'win62']:
                self.message.SetLabel('The following grid(s) have incorrect or incomplete data:\n{}'.format(', '.join(self.validation_mode)))
            else:
                self.message.SetLabel('Highlighted grids have incorrect or incomplete data')
            self.bSizer_msg.ShowItems(True)
            self.hbox.Fit(self)
        if not has_problems:
            self.validation_mode = set()
            self.message.SetLabel('')
            self.bSizer_msg.ShowItems(False)
            self.hbox.Fit(self)