コード例 #1
0
 def check_if_loop_and_row_size_fit_together(self, gemmi_loop, row):
     if gemmi_loop.width() == len(row):
         gemmi_loop.add_row(row)
     else:
         show_general_warning(
             'An author loop with different size is already in the CIF. Can not proceed.'
         )
コード例 #2
0
ファイル: equipment.py プロジェクト: dkratzert/FinalCif
 def import_equipment_from_file(self, filename='') -> None:
     """
     Import an equipment entry from a cif file.
     """
     if not filename:
         filename = cif_file_open_dialog(
             filter="CIF file (*.cif  *.cif_od *.cfx)")
     if not filename:
         print('No file given')
         return
     try:
         doc = cif.read_file(filename)
     except RuntimeError as e:
         show_general_warning(str(e))
         return
     block = doc.sole_block()
     table_data = []
     for item in block:
         if item.pair is not None:
             key, value = item.pair
             if filename.endswith(
                     '.cif_od') and key not in include_equipment_imports:
                 continue
             table_data.append([
                 key,
                 retranslate_delimiter(
                     cif.as_string(value).strip('\n\r ;'))
             ])
     if filename.endswith('.cif_od'):
         name = Path(filename).stem
     else:
         name = block.name.replace('__', ' ')
     self.settings.save_settings_list('equipment', name, table_data)
     self.show_equipment()
コード例 #3
0
ファイル: equipment.py プロジェクト: dkratzert/FinalCif
    def export_equipment_template(self, filename: str = None) -> None:
        """
        Exports the currently selected equipment entry to a file.

        In order to export, we have to run self.edit_equipment_template() first!
        """
        selected_template, table_data = self.get_equipment_entry_data()
        if not selected_template:
            return
        blockname = '__'.join(selected_template.split())
        if not filename:
            filename = cif_file_save_dialog(
                blockname.replace('__', '_') + '.cif')
        if not filename.strip():
            return
        equipment_cif = CifContainer(filename, new_block=blockname)
        for key, value in table_data:
            equipment_cif[key] = value.strip('\n\r ')
        try:
            equipment_cif.save(filename)
            # Path(filename).write_text(doc.as_string(cif.Style.Indent35))
        except PermissionError:
            if Path(filename).is_dir():
                return
            show_general_warning('No permission to write file to {}'.format(
                Path(filename).resolve()))
コード例 #4
0
ファイル: deposit.py プロジェクト: dkratzert/FinalCif
 def _set_external_hkl_file(self) -> None:
     file = cif_file_open_dialog(filter="HKL file (*.hkl *.fcf)")
     if file.endswith('.hkl'):
         if self.cif.res_file_data:
             hklf = self.cif.hklf_number_from_shelxl_file()
         else:
             hklf = 4
         self.hkl_file = io.StringIO(
             HKL(file, self.cif.block.name, hklf_type=hklf).hkl_as_cif)
         self.hkl_file.name = Path(file).name
     elif file.endswith('.fcf'):
         cif = CifContainer(file)
         list_code = cif['_shelx_refln_list_code']
         if list_code != '4':
             show_general_warning(
                 'Only plain hkl or fcf (LIST 4 style) files should be uploaded.'
             )
             return
         self.hkl_file = io.StringIO(Path(file).read_text())
         self.hkl_file.name = Path(file).name
     elif file == '':
         self.hkl_file = None
     else:
         show_general_warning(
             'Only plain hkl or fcf (LIST 4 style) files should be uploaded.'
         )
コード例 #5
0
 def import_author(self, filename=''):
     """
     Import an author from a cif file.
     """
     cif_auth_to_str = {
         '_publ_contact_author_name': 'name',
         '_publ_contact_author_address': 'address',
         '_publ_contact_author_email': 'email',
         '_publ_contact_author_phone': 'phone',
         '_publ_contact_author_id_orcid': 'orcid',
         #
         '_publ_author_name': 'name',
         '_publ_author_address': 'address',
         '_publ_author_email': 'email',
         '_publ_author_phone': 'phone',
         '_publ_author_id_orcid': 'orcid',
         '_publ_author_footnote': 'footnote',
     }
     if not filename:
         filename = cif_file_open_dialog(filter="CIF file (*.cif)")
     if not filename:
         return
     try:
         doc = read_file(filename)
     except RuntimeError as e:
         show_general_warning(str(e))
         return
     block = doc.sole_block()
     table_data = {}
     for item in block:
         if item.pair is not None:
             key, value = item.pair
             if key not in cif_auth_to_str:
                 continue
             key = cif_auth_to_str.get(key)
             table_data.update({
                 key:
                 retranslate_delimiter(as_string(value).strip('\n\r ;'))
             })
     name = block.name.replace('__', ' ')
     if 'contact author' in name:
         table_data.update({'contact': True})
     if not table_data.get('name'):
         return None
     self.general_author_save(table_data)
     self.show_author_loops()
コード例 #6
0
 def import_property_from_file(self, filename: str = '') -> None:
     """
     Imports a cif file as entry of the property templates list.
     """
     if not filename:
         filename = cif_file_open_dialog(filter="CIF file (*.cif)")
     if not filename:
         return
     try:
         doc = cif.read_file(filename)
     except RuntimeError as e:
         show_general_warning(str(e))
         return
     property_list = self.settings.settings.value('property_list')
     if not property_list:
         property_list = ['']
     block = doc.sole_block()
     template_list = []
     loop_column_name = ''
     for i in block:
         if i.loop is not None:
             if len(i.loop.tags) > 0:
                 loop_column_name = i.loop.tags[0]
             for n in range(i.loop.length()):
                 value = i.loop.val(n, 0)
                 template_list.append(
                     retranslate_delimiter(
                         cif.as_string(value).strip("\n\r ;")))
     block_name = block.name.replace('__', ' ')
     # This is the list shown in the Main menu:
     property_list.append(block_name)
     table = self.app.ui.PropertiesEditTableWidget
     table.setRowCount(0)
     self.app.ui.cifKeywordLineEdit.setText(loop_column_name)
     newlist = [x for x in list(set(property_list)) if x]
     newlist.sort()
     # this list keeps track of the property items:
     self.settings.save_template_list('property_list', newlist)
     template_list.insert(0, '')
     template_list = list(set(template_list))
     # save as dictionary for properties to have "_cif_key : itemlist"
     # for a table item as dropdown menu in the main table.
     table_data = [loop_column_name, template_list]
     self.settings.save_template_list('property/' + block_name, table_data)
     self.show_properties()
コード例 #7
0
 def export_property_template(self, filename: str = '') -> None:
     """
     Exports the currently selected property entry to a file.
     """
     selected_row_text = self.app.ui.PropertiesTemplatesListWidget.currentIndex(
     ).data()
     if not selected_row_text:
         return
     prop_data = self.settings.load_settings_list('property',
                                                  selected_row_text)
     table_data = []
     cif_key = ''
     if prop_data:
         cif_key = prop_data[0]
         with suppress(Exception):
             table_data = prop_data[1]
     if not cif_key:
         return
     doc = cif.Document()
     blockname = '__'.join(selected_row_text.split())
     block = doc.add_new_block(blockname)
     try:
         loop = block.init_loop(cif_key, [''])
     except RuntimeError:
         # Not a valid loop key
         show_general_warning(
             '"{}" is not a valid cif keyword.'.format(cif_key))
         return
     for value in table_data:
         if value:
             loop.add_row([cif.quote(utf8_to_str(value))])
     if not filename:
         filename = cif_file_save_dialog(
             blockname.replace('__', '_') + '.cif')
     if not filename.strip():
         return
     try:
         doc.write_file(filename, style=cif.Style.Indent35)
         # Path(filename).write_text(doc.as_string(cif.Style.Indent35))
     except PermissionError:
         if Path(filename).is_dir():
             return
         show_general_warning('No permission to write file to {}'.format(
             Path(filename).resolve()))
コード例 #8
0
ファイル: equipment.py プロジェクト: dkratzert/FinalCif
 def save_equipment_template(self) -> None:
     """
     Saves the currently selected equipment template to the config file.
     """
     selected_template_text, table_data = self.get_equipment_entry_data()
     # warn if key is not official:
     for key, _ in table_data:
         if key not in cif_all_dict:
             if not key.startswith('_'):
                 show_general_warning(
                     '"{}" is not a valid keyword! '
                     '\nChange the name in order to save.\n'
                     'Keys must start with an underscore.'.format(key))
                 return
             show_general_warning(
                 '"{}" is not an official CIF keyword!'.format(key))
     self.settings.save_settings_list('equipment', selected_template_text,
                                      table_data)
     self.app.ui.EquipmentTemplatesStackedWidget.setCurrentIndex(0)
     print('saved')
コード例 #9
0
 def export_author_template(self, filename: str = None) -> None:
     """
     Exports the currently selected author to a file.
     """
     author = self.get_author_info()
     selected_template = self.ui.LoopTemplatesListWidget.currentIndex(
     ).data()
     if not selected_template:
         return
     blockname = '__'.join(selected_template.split())
     if not filename:
         filename = cif_file_save_dialog(
             blockname.replace('__', '_') + '.cif')
     if not filename.strip():
         return
     author_cif = CifContainer(filename, new_block=blockname)
     contact_author: bool = author.get('contact')
     loop = self.get_author_loop(contact_author)
     data = [
         author.get('name'),
         author.get('address'),
         author.get('email'),
         author.get('phone'),
         author.get('orcid'),
         author.get('footnote')
     ]
     if contact_author:
         del data[-1]
     for key, value in zip(loop, data):
         author_cif.set_pair_delimited(key, as_string(value))
     try:
         author_cif.save(filename)
     except PermissionError:
         if Path(filename).is_dir():
             return
         show_general_warning('No permission to write file to {}'.format(
             Path(filename).resolve()))
コード例 #10
0
    def __init__(self, app, cif: CifContainer):
        super(BrukerData, self).__init__()
        self.cif = cif
        self.app = app
        self.basename = cif.fileobj.stem.split('_0m')[0]
        self.saint_data = SaintListFile(name_patt='*_0*m._ls')
        # This is only in this list file, not in the global:
        saint_first_ls = SaintListFile(name_patt='*_01._ls')
        sol = SolutionProgram(cif)
        solution_program = None
        if 'shelx' in self.cif.block.find_value('_audit_creation_method').lower():
            shelx = 'Sheldrick, G.M. (2015). Acta Cryst. A71, 3-8.\nSheldrick, G.M. (2015). Acta Cryst. C71, 3-8.\n'
        else:
            shelx = ''
        if cif.res_file_data:
            if cif.dsr_used:
                dsr = 'The program DSR was used for model building:\n' \
                      'D. Kratzert, I. Krossing, J. Appl. Cryst. 2018, 51, 928-934. doi: 10.1107/S1600576718004508'
                shelx += dsr
        abstype = '?'
        t_min = '?'
        t_max = '?'
        # Going back from last dataset:
        for n in range(1, len(self.sadabs.datasets) + 1):
            try:
                abstype = 'numerical' if self.sadabs.dataset(-n).numerical else 'multi-scan'
                t_min = min(self.sadabs.dataset(-n).transmission)
                t_max = max(self.sadabs.dataset(-n).transmission)
                if all([abstype, t_min, t_max]):
                    break
            except (KeyError, AttributeError, TypeError):
                pass
                # print('No .abs file found.')
                # no abs file found
        # the lower temp is more likely:
        try:
            temp1 = self.frame_header.temperature
        except (AttributeError, KeyError, FileNotFoundError):
            temp1 = 293
        try:
            kilovolt = self.frame_header.kilovolts
        except (AttributeError, KeyError, FileNotFoundError):
            kilovolt = ''
        try:
            milliamps = self.frame_header.milliamps
        except (AttributeError, KeyError, FileNotFoundError):
            milliamps = ''
        try:
            frame_name = self.frame_header.filename.name
        except FileNotFoundError:
            frame_name = ''
        if self.cif.solution_program_details:
            solution_program = (self.cif.solution_program_details, self.cif.fileobj.name)
        if self.cif['_computing_structure_solution']:
            solution_program = (gcif.as_string(self.cif['_computing_structure_solution']), self.cif.fileobj.name)
        if not solution_program:
            solution_program = (sol.program.version, Path(sol.program.filename).name)
        if self.cif.absorpt_process_details:
            absdetails = (self.cif.absorpt_process_details, self.cif.fileobj.name)
        else:
            absdetails = (self.sadabs.version, self.sadabs.filename.name)
        if self.cif.absorpt_correction_type:
            abscorrtype = (self.cif.absorpt_correction_type, self.cif.fileobj.name)
        else:
            abscorrtype = (abstype, self.sadabs.filename.name)
        if self.cif.absorpt_correction_t_max:
            abs_tmax = (self.cif.absorpt_correction_t_max, self.cif.fileobj.name)
        else:
            abs_tmax = (str(t_max), self.sadabs.filename.name)
        if self.cif.absorpt_correction_t_min:
            abs_tmin = (self.cif.absorpt_correction_t_min, self.cif.fileobj.name)
        else:
            abs_tmin = (str(t_min), self.sadabs.filename.name)

        if self.sadabs.Rint:
            rint = (self.sadabs.Rint, self.sadabs.filename.name)
            self.sources['_diffrn_reflns_av_R_equivalents'] = rint
        temp2 = self.p4p.temperature
        temperature = round(min([temp1, temp2]), 1)
        if temperature < 0.01:
            temperature = ''
        if (self.cif['_diffrn_ambient_temperature'].split('(')[0] or
            self.cif['_cell_measurement_temperature']).split('(')[0] == '0':
            show_general_warning('<b>Warning of impossible temperature specification</b>:<br>'
                                 'You probably entered &minus;273.15 °C instead '
                                 'of &minus;173.15 °C into the SHELX instruction file.<br>'
                                 'A temperature of 0 K is likely to be wrong.')
        try:
            if abs(int(self.cif['_diffrn_ambient_temperature'].split('(')[0]) - int(temperature)) >= 2 and \
                    not self.app.temperature_warning_displayed:
                self.app.temperature_warning_displayed = True
                show_general_warning('<b>Warning</b>: The temperature from the measurement and '
                                     'from SHELX differ. Please double-check for correctness.<br><br>'
                                     'SHELX says: {} K<br>'
                                     'The P4P file says: {} K<br>'
                                     'Frame header says: {} K<br><br>'
                                     'You may add a '
                                     '<a href="http://shelx.uni-goettingen.de/shelxl_html.php#TEMP">TEMP</a> '
                                     'instruction to your SHELX file (in °C).'
                                     .format(self.cif['_diffrn_ambient_temperature'].split('(')[0],
                                             round(temp2, 1),
                                             round(temp1, 1)))
        except ValueError:
            # most probably one value is '?'
            pass
        if not self.cif['_space_group_name_H-M_alt']:
            try:
                self.sources['_space_group_name_H-M_alt'] = (
                self.cif.space_group, 'Calculated by gemmi: https://gemmi.readthedocs.io')
            except AttributeError:
                pass
        if not self.cif['_space_group_name_Hall']:
            with suppress(AttributeError):
                self.sources['_space_group_name_Hall'] = (
                self.cif.hall_symbol, 'Calculated by gemmi: https://gemmi.readthedocs.io')
        if not self.cif['_space_group_IT_number']:
            with suppress(AttributeError):
                self.sources['_space_group_IT_number'] = (
                self.cif.spgr_number_from_symmops, 'Calculated by gemmi: https://gemmi.readthedocs.io')
        if not self.cif['_space_group_crystal_system']:
            with suppress(AttributeError):
                csystem = self.cif.crystal_system
                self.sources['_space_group_crystal_system'] = (
                    csystem, 'calculated by gemmi: https://gemmi.readthedocs.io')
        if not self.cif.symmops and self.cif.symmops_from_spgr:
            loop = self.cif.block.init_loop('_space_group_symop_operation_', ['xyz'])
            for symmop in reversed(self.cif.symmops_from_spgr):
                loop.add_row([gcif.quote(symmop)])
        # All sources that are not filled with data will be yellow in the main table
        #                          data                         tooltip
        self.sources['_cell_measurement_reflns_used'] = (
            self.saint_data.cell_reflections, self.saint_data.filename.name)
        self.sources['_cell_measurement_theta_min'] = (
            self.saint_data.cell_res_min_theta or '', self.saint_data.filename.name)
        self.sources['_cell_measurement_theta_max'] = (
            self.saint_data.cell_res_max_theta or '', self.saint_data.filename.name)
        self.sources['_computing_data_collection'] = (saint_first_ls.aquire_software, saint_first_ls.filename.name)
        self.sources['_computing_cell_refinement'] = (self.saint_data.version, self.saint_data.filename.name)
        self.sources['_computing_data_reduction'] = (self.saint_data.version, self.saint_data.filename.name)
        self.sources['_exptl_absorpt_correction_type'] = abscorrtype
        self.sources['_exptl_absorpt_correction_T_min'] = abs_tmin
        self.sources['_exptl_absorpt_correction_T_max'] = abs_tmax
        self.sources['_exptl_absorpt_process_details'] = absdetails
        self.sources['_cell_measurement_temperature'] = (temperature, self.p4p.filename.name)
        self.sources['_diffrn_ambient_temperature'] = (temperature, self.p4p.filename.name)
        self.sources['_exptl_crystal_colour'] = (self.p4p.crystal_color, self.p4p.filename.name)
        self.sources['_exptl_crystal_description'] = (self.p4p.morphology, self.p4p.filename.name)
        self.sources['_exptl_crystal_size_min'] = (self.p4p.crystal_size[0] or '', self.p4p.filename.name)
        self.sources['_exptl_crystal_size_mid'] = (self.p4p.crystal_size[1] or '', self.p4p.filename.name)
        self.sources['_exptl_crystal_size_max'] = (self.p4p.crystal_size[2] or '', self.p4p.filename.name)
        self.sources['_computing_structure_solution'] = solution_program
        self.sources['_atom_sites_solution_primary'] = (sol.method, 'Inherited from solution program.')
        self.sources['_diffrn_source_voltage'] = (kilovolt or '', frame_name)
        self.sources['_diffrn_source_current'] = (milliamps or '', frame_name)
        self.sources['_chemical_formula_moiety'] = ('', '')
        self.sources['_publ_section_references'] = (shelx, '')
        self.sources['_refine_special_details'] = ('', '')
        self.sources['_exptl_crystal_recrystallization_method'] = ('', '')
        if not self.cif.is_centrosymm:
            self.sources['_chemical_absolute_configuration'] = ('', '')
        if self.saint_data.is_twin and self.saint_data.components_firstsample == 2:
            with suppress(Exception):
                law = self.saint_data.twinlaw[list(self.saint_data.twinlaw.keys())[0]]
                self.sources['_twin_individual_twin_matrix_11'] = (str(law[0][1]), self.saint_data.filename.name)
                self.sources['_twin_individual_twin_matrix_12'] = (str(law[0][2]), self.saint_data.filename.name)
                self.sources['_twin_individual_twin_matrix_13'] = (str(law[0][0]), self.saint_data.filename.name)
                self.sources['_twin_individual_twin_matrix_21'] = (str(law[1][1]), self.saint_data.filename.name)
                self.sources['_twin_individual_twin_matrix_22'] = (str(law[1][2]), self.saint_data.filename.name)
                self.sources['_twin_individual_twin_matrix_23'] = (str(law[1][0]), self.saint_data.filename.name)
                self.sources['_twin_individual_twin_matrix_31'] = (str(law[2][1]), self.saint_data.filename.name)
                self.sources['_twin_individual_twin_matrix_32'] = (str(law[2][2]), self.saint_data.filename.name)
                self.sources['_twin_individual_twin_matrix_33'] = (str(law[2][0]), self.saint_data.filename.name)
                self.sources['_twin_individual_id'] = (
                    str(self.saint_data.components_firstsample), self.saint_data.filename.name)
                self.sources['_twin_special_details'] = (
                    'The data was integrated as a 2-component twin.', self.saint_data.filename.name)