def __init__(self, cif: CifContainer, paragraph: Paragraph): self.cif = cif self.crytsalization_method = gstr( self.cif['_exptl_crystal_recrystallization_method']) if not self.crytsalization_method: self.crytsalization_method = '[No crystallization method was given]' sentence = "{}. " self.text = sentence.format( remove_line_endings( retranslate_delimiter(self.crytsalization_method))) paragraph.add_run(retranslate_delimiter(self.text))
def load_equipment_to_edit(self) -> None: """ Load/Edit the key/value list of an equipment entry. """ table = self.app.ui.EquipmentEditTableWidget listwidget = self.app.ui.EquipmentTemplatesListWidget table.blockSignals(True) table.clearContents() table.setRowCount(0) index = listwidget.currentIndex() if index.row() == -1: # nothing selected return selected_row_text = listwidget.currentIndex().data() table_data = self.settings.load_settings_list( property='equipment', item_name=selected_row_text) # first load the previous values: if table_data: for key, value in table_data: if not key or not value: continue table.add_equipment_row(key, retranslate_delimiter(value)) else: # new empty equipment: for _ in range(8): table.add_equipment_row('', '') table.add_equipment_row('', '') table.add_equipment_row('', '') self.app.ui.EquipmentTemplatesStackedWidget.setCurrentIndex(1) table.resizeRowsToContents() table.blockSignals(False)
def format_radiation(radiation_type: str) -> list: radtype = list(radiation_type.partition("K")) if len(radtype) > 2: radtype[2] = retranslate_delimiter(radtype[2]) return radtype else: return radtype
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()
def data(self, index: QModelIndex, role: int = None): row, col = index.row(), index.column() value = self._data[row][col] if role == Qt.SizeHintRole: return QSize(120, 50) if role == Qt.TextAlignmentRole: pass # if isnumeric(value): # return Qt.AlignVCenter + Qt.AlignVertical_Mask if role == Qt.BackgroundColorRole: if (row, col) in [(x['row'], x['column']) for x in self.modified]: return QVariant(QColor("#facaca")) if role == Qt.EditRole: return retranslate_delimiter(value) if role == Qt.DisplayRole: return retranslate_delimiter(value)
def __init__(self, cif: CifContainer, paragraph: Paragraph): self.cif = cif self.difftype = gstr(self.cif['_diffrn_measurement_device_type']) \ or '[No measurement device type given]' self.device = gstr(self.cif['_diffrn_measurement_device']) \ or '[No measurement device given]' self.source = gstr(self.cif['_diffrn_source']).strip('\n\r') \ or '[No radiation source given]' self.monochrom = gstr(self.cif['_diffrn_radiation_monochromator']) \ or '[No monochromator type given]' if not self.monochrom: self.monochrom = '?' self.cooling = gstr(self.cif['_olex2_diffrn_ambient_temperature_device']) \ or '' self.rad_type = gstr(self.cif['_diffrn_radiation_type']) \ or '[No radiation type given]' radtype = format_radiation(self.rad_type) self.wavelen = gstr(self.cif['_diffrn_radiation_wavelength']) \ or '[No wavelength given]' self.detector_type = '' detector_type = gstr(self.cif['_diffrn_detector_type']) \ or '[No detector type given]' if detector_type: self.detector_type = " and a {} detector".format(detector_type) sentence1 = "on {0} {1} {2} with {3} {4} using {5} as monochromator{6}. " \ "The diffractometer was equipped with {7} {8} low temperature device and used " sentence2 = " radiation (λ = {}" + protected_space + "{}). ".format( angstrom) txt = sentence1.format(get_inf_article(self.difftype), self.difftype, self.device, get_inf_article(self.source), self.source, self.monochrom, self.detector_type, get_inf_article(self.cooling), self.cooling) paragraph.add_run(retranslate_delimiter(txt)) # radiation type e.g. Mo: paragraph.add_run(retranslate_delimiter(radtype[0])) # K line: radrunita = paragraph.add_run(radtype[1]) radrunita.font.italic = True alpha = paragraph.add_run(retranslate_delimiter(radtype[2])) alpha.font.italic = True alpha.font.subscript = True txt2 = sentence2.format(self.wavelen) paragraph.add_run(txt2)
def __init__(self, cif: CifContainer, paragraph: Paragraph): self.cif = cif self.temperature = gstr(self.cif['_diffrn_ambient_temperature']) self._name = cif.fileobj.name method = 'shock-cooled ' sentence = "The data for {} were collected from a {}single crystal at {}{}K " try: if float(self.temperature.split('(')[0]) > 200: method = '' except ValueError: method = '' self.txt = sentence.format(self.cif.block.name, method, self.temperature, protected_space) paragraph.add_run(retranslate_delimiter(self.txt))
def general_author_save(self, author: dict): if not author.get('name'): return if author.get('contact'): itemtext = '{} (contact author)'.format( retranslate_delimiter(as_string(author.get('name')))) else: itemtext = as_string(author.get('name')) authors = self.settings.list_saved_items(property='authors_list') if itemtext not in authors: self.settings.save_settings_dict(property='authors_list', name=itemtext, items=author) if not itemtext: return self.show_author_loops()
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()
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()
def add_equipment_row(self, key_text: str = '', value_text: str = ''): """ Add a new row with content to the table (Equipment or Property). """ if not isinstance(value_text, str): return if not isinstance(key_text, str): return # Create a empty row at bottom of table row_num = self.rowCount() self.insertRow(row_num) key_item = MyQPlainTextEdit(parent=self) key_item.row = row_num key_item.setPlainText(key_text) # This is critical, because otherwise the add_row_if_needed does not work as expected: key_item.textChanged.connect(self.add_row_if_needed) self.setCellWidget(row_num, 0, key_item) # if len(value) > 38: tab_item = MyQPlainTextEdit(self) tab_item.setPlainText(retranslate_delimiter(value_text)) self.setCellWidget(row_num, 1, tab_item)
def setText(self, key: str, column: int, txt: str, row: int = None, color=None): """ Set text in current table cell regardless of the containing item. """ txt = retranslate_delimiter(txt) if row is None: row = self.vheaderitems.index(key) if isinstance(self.cellWidget(row, column), MyComboBox): # noinspection PyUnresolvedReferences self.cellWidget(row, column).setText(txt) return item = MyTableWidgetItem(txt) self.setItem(row, column, item) lentext = max( [len(txt), len(self.getText(0, row)), len(self.getText(1, row))]) # This is a regular table cell: if not (key in text_field_keys) and (lentext < 35): item.setText(txt) if (column == COL_CIF) or (column == COL_DATA): # noinspection PyUnresolvedReferences item.setUneditable() if color: item.setBackground(color) else: # This is a text field: textedit = MyQPlainTextEdit(self) self.setCellWidget(row, column, textedit) textedit.setText(txt, color=color) if (column == COL_CIF) or (column == COL_DATA): textedit.setUneditable() self.resizeRowToContents(row) if color: textedit.setBackground(color)
def __init__(self, cif: CifContainer, paragraph: Paragraph, ref: ReferenceList): self.cif = cif integration = gstr(self.cif['_computing_data_reduction']) or '??' abstype = gstr(self.cif['_exptl_absorpt_correction_type']) or '??' abs_details = gstr(self.cif['_exptl_absorpt_process_details']) or '??' data_reduct_ref = DummyReference() absorpt_ref = DummyReference() integration_prog = '[unknown integration program]' scale_prog = '[unknown program]' if 'SAINT' in integration: data_reduct_ref, integration_prog = self.add_saint_reference( integration) if 'CrysAlisPro'.lower() in integration.lower(): data_reduct_ref, absorpt_ref, integration_prog = self.add_crysalispro_reference( integration) absdetails = cif['_exptl_absorpt_process_details'].replace('-', ' ') if 'SADABS' in absdetails.upper() or 'TWINABS' in absdetails.upper(): if len(absdetails.split()) > 1: version = absdetails.split()[1] else: version = 'unknown version' if 'SADABS' in absdetails: scale_prog = 'SADABS' else: scale_prog = 'TWINABS' # absorpt_ref = SAINTReference(scale_prog, version) absorpt_ref = SadabsTwinabsReference() if 'SORTAV' in absdetails.upper(): scale_prog = 'SORTAV' absorpt_ref = SORTAVReference() if 'crysalis' in abs_details.lower(): scale_prog = 'SCALE3 ABSPACK' sentence = 'All data were integrated with {} and {} {} absorption correction using {} was applied.' txt = sentence.format(integration_prog, get_inf_article(abstype), abstype, scale_prog) paragraph.add_run(retranslate_delimiter(txt)) ref.append([data_reduct_ref, absorpt_ref])
def load_property_from_settings(self) -> None: """ Load/Edit the value list of a property entry. """ table = self.app.ui.PropertiesEditTableWidget listwidget = self.app.ui.PropertiesTemplatesListWidget table.blockSignals(True) table.clearContents() table.setRowCount(0) index = listwidget.currentIndex() if index.row() == -1: # nothing selected # self.app.ui.PropertiesEditTableWidget.blockSignals(False) return selected_row_text = listwidget.currentIndex().data() table_data = self.settings.load_settings_list('property', selected_row_text) if table_data: cif_key = table_data[0] with suppress(Exception): table_data = table_data[1] self.app.ui.cifKeywordLineEdit.setText(cif_key) if not table_data: table_data = ['', '', ''] for value in table_data: try: self.add_propeties_row(table, retranslate_delimiter(str(value))) except TypeError: print('Bad value in property table') continue self.add_propeties_row(table, '') self.app.ui.PropertiesTemplatesStackedWidget.setCurrentIndex(1) table.blockSignals(False) # table.setWordWrap(False) table.resizeRowsToContents()
def __init__(self, cif: CifContainer, paragraph: Paragraph, ref: ReferenceList): self.cif = cif refineref = DummyReference() solveref = DummyReference() solution_prog = gstr(self.cif['_computing_structure_solution']) or '??' solution_method = gstr( self.cif['_atom_sites_solution_primary']) or '??' if solution_prog.upper().startswith(('SHELXT', 'XT')): solveref = SHELXTReference() if 'SHELXS' in solution_prog.upper(): solveref = SHELXSReference() if 'SHELXD' in solution_prog.upper(): solveref = SHELXDReference() refined = gstr(self.cif['_computing_structure_refinement']) or '??' if refined.upper().startswith(('SHELXL', 'XL')): refineref = SHELXLReference() if 'OLEX' in refined.upper(): refineref = Olex2Reference() refine_coef = gstr(self.cif['_refine_ls_structure_factor_coef']) sentence = r"The structure were solved by {} methods using {} and refined by full-matrix " \ "least-squares methods against " txt = sentence.format(solution_method.strip('\n\r'), solution_prog.split()[0]) paragraph.add_run(retranslate_delimiter(txt)) paragraph.add_run('F').font.italic = True if refine_coef.lower() == 'fsqd': paragraph.add_run('2').font.superscript = True paragraph.add_run(' by {}'.format(refined.split()[0])) shelxle = None if 'shelxle' in refined.lower( ) or 'shelxle' in self.cif['_computing_molecular_graphics'].lower(): paragraph.add_run(' using ShelXle') shelxle = ShelXleReference() paragraph.add_run('.') ref.append([solveref, refineref, shelxle])
def set_author_info(self, author: Dict[str, Union[str, None]]): if not author: return if author.get('name'): self.ui.FullNameLineEdit.setText( retranslate_delimiter(as_string(author.get('name')))) if author.get('address'): self.ui.AddressTextedit.setText( retranslate_delimiter(as_string(author.get('address')))) if author.get('email'): self.ui.EMailLineEdit.setText( retranslate_delimiter(as_string(author.get('email')))) if author.get('footnote'): self.ui.FootNoteLineEdit.setText( retranslate_delimiter(as_string(author.get('footnote')))) if author.get('orcid'): self.ui.ORCIDLineEdit.setText( retranslate_delimiter(as_string(author.get('orcid')))) if author.get('phone'): self.ui.PhoneLineEdit.setText( retranslate_delimiter(as_string(author.get('phone')))) self.ui.ContactAuthorCheckBox.setChecked( author.get('contact') or False)
def test_cif_str_to_utf8(self): r = retranslate_delimiter(r'100 \%C') self.assertEqual('100 °C', r)
def test__backwards_delimit_umlaut(self): self.assertEqual('äöüç', retranslate_delimiter(r'a\"o\"u\"\,c'))
def get_loop_column(self, key_in_loop: str) -> List: return [ retranslate_delimiter(as_string(x)) for x in self.block.find_loop(key_in_loop) ]
def make_templated_report(self, options: Options, file_obj: Path, output_filename: str, picfile: Path, template_path: Path): cif = CifContainer(file_obj) tpl_doc = DocxTemplate(Path(__file__).parent.parent.joinpath(template_path)) ba = BondsAndAngles(cif, without_h=options.without_h) t = TorsionAngles(cif, without_h=options.without_h) h = HydrogenBonds(cif) context = {'options' : options, # {'without_h': True, 'atoms_table': True, 'text': True, 'bonds_table': True}, 'cif' : cif, 'space_group' : self.space_group_subdoc(tpl_doc, cif), 'structure_figure' : self.make_picture(options, picfile, tpl_doc), 'crystallization_method': remove_line_endings(retranslate_delimiter( cif['_exptl_crystal_recrystallization_method'])) or '[No crystallization method given!]', 'sum_formula' : self.format_sum_formula(cif['_chemical_formula_sum'].replace(" ", "")), 'itnum' : cif['_space_group_IT_number'], 'crystal_size' : this_or_quest(cif['_exptl_crystal_size_min']) + timessym + this_or_quest(cif['_exptl_crystal_size_mid']) + timessym + this_or_quest(cif['_exptl_crystal_size_max']), 'crystal_colour' : this_or_quest(cif['_exptl_crystal_colour']), 'crystal_shape' : this_or_quest(cif['_exptl_crystal_description']), 'radiation' : self.get_radiation(cif), 'wavelength' : cif['_diffrn_radiation_wavelength'], 'theta_range' : self.get_from_to_theta_range(cif), 'diffr_type' : gstr(cif['_diffrn_measurement_device_type']) or '[No measurement device type given]', 'diffr_device' : gstr(cif['_diffrn_measurement_device']) or '[No measurement device given]', 'diffr_source' : gstr(cif['_diffrn_source']).strip('\n\r') or '[No radiation source given]', 'monochromator' : gstr(cif['_diffrn_radiation_monochromator']) \ or '[No monochromator type given]', 'detector' : gstr(cif['_diffrn_detector_type']) \ or '[No detector type given]', 'lowtemp_dev' : gstr(cif['_olex2_diffrn_ambient_temperature_device']) \ or '', 'index_ranges' : self.hkl_index_limits(cif), 'indepentent_refl' : this_or_quest(cif['_reflns_number_total']), 'r_int' : this_or_quest(cif['_diffrn_reflns_av_R_equivalents']), 'r_sigma' : this_or_quest(cif['_diffrn_reflns_av_unetI/netI']), 'completeness' : self.get_completeness(cif), 'theta_full' : cif['_diffrn_reflns_theta_full'], 'data' : this_or_quest(cif['_refine_ls_number_reflns']), 'restraints' : this_or_quest(cif['_refine_ls_number_restraints']), 'parameters' : this_or_quest(cif['_refine_ls_number_parameters']), 'goof' : this_or_quest(cif['_refine_ls_goodness_of_fit_ref']), 'ls_R_factor_gt' : this_or_quest(cif['_refine_ls_R_factor_gt']), 'ls_wR_factor_gt' : this_or_quest(cif['_refine_ls_wR_factor_gt']), 'ls_R_factor_all' : this_or_quest(cif['_refine_ls_R_factor_all']), 'ls_wR_factor_ref' : this_or_quest(cif['_refine_ls_wR_factor_ref']), 'diff_dens_min' : self.get_diff_density_min(cif).replace('-', minus_sign), 'diff_dens_max' : self.get_diff_density_max(cif).replace('-', minus_sign), 'exti' : self.get_exti(cif), 'flack_x' : self.get_flackx(cif), 'integration_progr' : self.get_integration_program(cif), 'abstype' : gstr(cif['_exptl_absorpt_correction_type']) or '??', 'abs_details' : self.get_absortion_correction_program(cif), 'solution_method' : self.solution_method(cif), 'solution_program' : self.solution_program(cif), 'refinement_prog' : self.refinement_prog(cif), 'atomic_coordinates' : self.get_atomic_coordinates(cif), 'bonds' : ba.bonds, 'angles' : ba.angles, 'ba_symminfo' : ba.symminfo, 'torsions' : t.torsion_angles, 'torsion_symminfo' : t.symminfo, 'hydrogen_bonds' : h.hydrogen_bonds, 'hydrogen_symminfo' : h.symminfo, 'literature' : self.literature } # Filter definition for {{foobar|filter}} things: jinja_env = jinja2.Environment() jinja_env.filters['inv_article'] = get_inf_article tpl_doc.render(context, jinja_env=jinja_env, autoescape=True) tpl_doc.save(output_filename)
def test_retranslate_all(self): for char in charcters: if char in ('Å', 'Å'): continue self.assertEqual(char, retranslate_delimiter(delimit_string(char)))
def test_encode_and_decode_utf8(self): # Test for quote and immediate decode to utf-8 again: self.assertEqual(self.txt, retranslate_delimiter(utf8_to_str(self.txt)))
def test_retranslate_sentence(self): r = retranslate_delimiter("Crystals were grown from thf at -20 \%C.") self.assertEqual('Crystals were grown from thf at -20 °C.', r)