finalcif 141__tar.gz → 142__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {finalcif-141 → finalcif-142}/.gitignore +1 -0
- {finalcif-141 → finalcif-142}/PKG-INFO +1 -2
- finalcif-142/finalcif/__init__.py +2 -0
- {finalcif-141 → finalcif-142}/finalcif/appwindow.py +38 -32
- {finalcif-141 → finalcif-142}/finalcif/cif/cif_file_io.py +38 -14
- {finalcif-141 → finalcif-142}/finalcif/gui/finalcif_gui_ui.py +6 -10
- {finalcif-141 → finalcif-142}/finalcif/gui/finalcif_gui_ui.ui +10 -11
- {finalcif-141 → finalcif-142}/finalcif/report/references.py +0 -1
- finalcif-142/finalcif/report/report_text.py +150 -0
- {finalcif-141 → finalcif-142}/finalcif/report/tables.py +0 -2
- {finalcif-141 → finalcif-142}/finalcif/report/templated_report.py +143 -19
- finalcif-142/finalcif/template/report_default.docx +0 -0
- finalcif-142/finalcif/template/template_text.docx +0 -0
- finalcif-142/finalcif/template/template_without_text.docx +0 -0
- {finalcif-141 → finalcif-142}/finalcif/template/templates.py +6 -1
- {finalcif-141 → finalcif-142}/finalcif/tools/misc.py +58 -4
- {finalcif-141 → finalcif-142}/finalcif/tools/options.py +17 -8
- {finalcif-141 → finalcif-142}/requirements.txt +0 -1
- finalcif-141/finalcif/__init__.py +0 -2
- finalcif-141/finalcif/report/report_text.py +0 -573
- finalcif-141/finalcif/template/template_text.docx +0 -0
- finalcif-141/finalcif/template/template_without_text.docx +0 -0
- {finalcif-141 → finalcif-142}/.gitattributes +0 -0
- {finalcif-141 → finalcif-142}/.run/Make Documentation MAC.run.xml +0 -0
- {finalcif-141 → finalcif-142}/.run/compile_ui_files.run.xml +0 -0
- {finalcif-141 → finalcif-142}/.run/make documentation Windows.run.xml +0 -0
- {finalcif-141 → finalcif-142}/CODE_OF_CONDUCT.md +0 -0
- {finalcif-141 → finalcif-142}/CONTRIBUTING.md +0 -0
- {finalcif-141 → finalcif-142}/Finalcif_installer_win.spec +0 -0
- {finalcif-141 → finalcif-142}/Finalcif_linux_onefile.spec +0 -0
- {finalcif-141 → finalcif-142}/Finalcif_mac.spec +0 -0
- {finalcif-141 → finalcif-142}/Hydrogen_solution_type.cif +0 -0
- {finalcif-141 → finalcif-142}/LICENSE +0 -0
- {finalcif-141 → finalcif-142}/README.md +0 -0
- {finalcif-141 → finalcif-142}/finalcif/app_path.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/__init__.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/all_cif_dicts.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/atoms.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/checkcif/__init__.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/checkcif/checkcif.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/cif_dict_foo.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/cif_order.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/cod/__init__.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/cod/deposit.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/cod/deposit_check.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/cod/deposition_list.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/cod/doi.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/cod/upload.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/cod/website_parser.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/core_dict.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/hkl.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/modulation_dict.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/powder_dict.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/reference.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/restraints_dict.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/text.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/cif/twin_dict.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/datafiles/__init__.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/datafiles/bruker_data.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/datafiles/bruker_frame.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/datafiles/ccdc_mail.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/datafiles/data.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/datafiles/p4p_reader.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/datafiles/sadabs.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/datafiles/saint.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/datafiles/shelx_lst.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/datafiles/utils.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/displaymol/__init__.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/displaymol/molecule2D.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/displaymol/sdm.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/displaymol/vtk_molecule.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/equip_property/__init__.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/equip_property/author_loop_templates.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/equip_property/equipment.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/equip_property/properties.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/equip_property/tools.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/finalcif_start.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/__init__.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/block_combobox.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/combobox.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/custom_classes.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/dialogs.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/edit_button.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/equipmenttable.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/file_editor.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/import_selector.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/import_selector_ui.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/import_selector_ui.ui +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/loop_creator.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/loop_creator_ui.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/loop_creator_ui.ui +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/loops.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/mainstackwidget.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/mixins.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/new_key_dialog.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/new_key_dialog_ui.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/new_key_dialog_ui.ui +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/plaintextedit.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/playground.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/propertytable.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/spell_check_edit.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/text_templates_ui.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/text_templates_ui.ui +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/text_value_editor.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/validators.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/gui/vrf_classes.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/icon/__init__.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/icon/finalcif.png +0 -0
- {finalcif-141 → finalcif-142}/finalcif/icon/finalcif2.ico +0 -0
- {finalcif-141 → finalcif-142}/finalcif/icon/finalcif2.png +0 -0
- {finalcif-141 → finalcif-142}/finalcif/icon/multitable.ico +0 -0
- {finalcif-141 → finalcif-142}/finalcif/icon/multitable.png +0 -0
- {finalcif-141 → finalcif-142}/finalcif/icon/multitable.xcf +0 -0
- {finalcif-141 → finalcif-142}/finalcif/report/__init__.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/report/archive_report.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/report/gui/__init__.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/report/gui/mainwindow.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/report/gui/mainwindow.ui +0 -0
- {finalcif-141 → finalcif-142}/finalcif/report/mtools.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/report/symm.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/template/__init__.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/template/bootstrap/bootstrap.min.css +0 -0
- {finalcif-141 → finalcif-142}/finalcif/template/machines/D8_VENTURE.cif +0 -0
- {finalcif-141 → finalcif-142}/finalcif/template/mathml2omml.xsl +0 -0
- {finalcif-141 → finalcif-142}/finalcif/template/report.tmpl +0 -0
- {finalcif-141 → finalcif-142}/finalcif/template/template1.docx +0 -0
- {finalcif-141 → finalcif-142}/finalcif/template/template_for_multitable.docx +0 -0
- {finalcif-141 → finalcif-142}/finalcif/template/xsl/convert.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/template/xsl/xmltohtml.xsl +0 -0
- {finalcif-141 → finalcif-142}/finalcif/tools/__init__.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/tools/chemparse.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/tools/download.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/tools/dsrmath.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/tools/platon.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/tools/pupdate.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/tools/settings.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/tools/shred.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/tools/space_groups.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/tools/spgr_format.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/tools/statusbar.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif/tools/sumformula.py +0 -0
- {finalcif-141 → finalcif-142}/finalcif.exe +0 -0
- {finalcif-141 → finalcif-142}/install_requirements +0 -0
- {finalcif-141 → finalcif-142}/install_requirements.bat +0 -0
- {finalcif-141 → finalcif-142}/pyproject.toml +0 -0
- {finalcif-141 → finalcif-142}/requirements_devel.txt +0 -0
- {finalcif-141 → finalcif-142}/requirements_doku.txt +0 -0
- {finalcif-141 → finalcif-142}/run_finalcif +0 -0
- {finalcif-141 → finalcif-142}/run_finalcif.bat +0 -0
- {finalcif-141 → finalcif-142}/screenshots/finalcif_checkcif.png +0 -0
- {finalcif-141 → finalcif-142}/screenshots/finalcif_details.png +0 -0
- {finalcif-141 → finalcif-142}/screenshots/finalcif_loops.png +0 -0
- {finalcif-141 → finalcif-142}/screenshots/finalcif_loops2.png +0 -0
- {finalcif-141 → finalcif-142}/screenshots/finalcif_main.png +0 -0
- {finalcif-141 → finalcif-142}/screenshots/finalcif_report.png +0 -0
- {finalcif-141 → finalcif-142}/screenshots/finalcif_responses.png +0 -0
- {finalcif-141 → finalcif-142}/update.exe +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: finalcif
|
|
3
|
-
Version:
|
|
3
|
+
Version: 142
|
|
4
4
|
Summary: CIF file editor
|
|
5
5
|
Project-URL: Homepage, https://dkratzert.de/finalcif.html
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/dkratzert/FinalCif/issues
|
|
@@ -12,7 +12,6 @@ Classifier: Operating System :: OS Independent
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
14
14
|
Requires-Python: >=3.10
|
|
15
|
-
Requires-Dist: altgraph
|
|
16
15
|
Requires-Dist: certifi
|
|
17
16
|
Requires-Dist: chardet
|
|
18
17
|
Requires-Dist: crossrefapi
|
|
@@ -1103,7 +1103,10 @@ class AppWindow(QMainWindow):
|
|
|
1103
1103
|
for index in range(self.ui.docxTemplatesListWidget.count()):
|
|
1104
1104
|
item = self.ui.docxTemplatesListWidget.item(index)
|
|
1105
1105
|
if item.checkState() == Qt.Checked:
|
|
1106
|
-
|
|
1106
|
+
if self.templates.report_from_default_template():
|
|
1107
|
+
return 'finalcif/template/report_default.docx'
|
|
1108
|
+
else:
|
|
1109
|
+
return item.text()
|
|
1107
1110
|
|
|
1108
1111
|
def make_report_tables(self) -> None:
|
|
1109
1112
|
"""
|
|
@@ -1122,36 +1125,32 @@ class AppWindow(QMainWindow):
|
|
|
1122
1125
|
self.load_cif_file(self.cif.finalcif_file, block=current_block, load_changes=False)
|
|
1123
1126
|
report_filename = self.cif.finalcif_file_prefixed(prefix='report_', suffix='-finalcif.docx')
|
|
1124
1127
|
multi_table_document = self.cif.finalcif_file_prefixed(prefix='', suffix='-multitable.docx')
|
|
1128
|
+
self.cif.picometer = self.options.use_picometers
|
|
1125
1129
|
# The picture after the header:
|
|
1126
1130
|
if self.report_picture_path:
|
|
1127
1131
|
picfile = self.report_picture_path
|
|
1128
1132
|
else:
|
|
1129
1133
|
picfile = self.cif.finalcif_file.with_suffix('.gif')
|
|
1130
1134
|
try:
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
+
print('Report with templates')
|
|
1136
|
+
template_path = Path(self.get_checked_templates_list_text())
|
|
1137
|
+
ok = False
|
|
1138
|
+
if template_path.suffix in ('.docx',):
|
|
1139
|
+
t = TemplatedReport(format=ReportFormat.RICHTEXT, options=self.options, cif=self.cif)
|
|
1140
|
+
ok = t.make_templated_docx_report(output_filename=str(report_filename),
|
|
1141
|
+
picfile=picfile,
|
|
1142
|
+
template_path=Path(self.get_checked_templates_list_text()))
|
|
1135
1143
|
if self.cif.is_multi_cif and self.cif.doc[0].name != 'global':
|
|
1136
1144
|
make_multi_tables(cif=self.cif, output_filename=str(multi_table_document))
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
ok =
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
elif template_path.suffix in ('.html', '.tmpl'):
|
|
1147
|
-
t = TemplatedReport(format=ReportFormat.HTML, options=self.options, cif=self.cif)
|
|
1148
|
-
report_filename = report_filename.with_suffix('.html')
|
|
1149
|
-
ok = t.make_templated_html_report(output_filename=str(report_filename),
|
|
1150
|
-
picfile=picfile,
|
|
1151
|
-
template_path=template_path.parent,
|
|
1152
|
-
template_file=template_path.name)
|
|
1153
|
-
if not ok:
|
|
1154
|
-
return None
|
|
1145
|
+
elif template_path.suffix in ('.html', '.tmpl'):
|
|
1146
|
+
t = TemplatedReport(format=ReportFormat.HTML, options=self.options, cif=self.cif)
|
|
1147
|
+
report_filename = report_filename.with_suffix('.html')
|
|
1148
|
+
ok = t.make_templated_html_report(output_filename=str(report_filename),
|
|
1149
|
+
picfile=picfile,
|
|
1150
|
+
template_path=template_path.parent,
|
|
1151
|
+
template_file=template_path.name)
|
|
1152
|
+
if not ok:
|
|
1153
|
+
return None
|
|
1155
1154
|
except FileNotFoundError as e:
|
|
1156
1155
|
if DEBUG:
|
|
1157
1156
|
raise
|
|
@@ -1171,11 +1170,6 @@ class AppWindow(QMainWindow):
|
|
|
1171
1170
|
# Save report and other files to a zip file:
|
|
1172
1171
|
self.zip_report(report_filename)
|
|
1173
1172
|
|
|
1174
|
-
def report_without_template(self) -> bool:
|
|
1175
|
-
"""Check whether the report is generated from a template or hard-coded"""
|
|
1176
|
-
return self.ui.docxTemplatesListWidget.item(0).checkState() == Qt.CheckState.Checked \
|
|
1177
|
-
or not self.ui.docxTemplatesListWidget.currentItem()
|
|
1178
|
-
|
|
1179
1173
|
def zip_report(self, report_filename: Path) -> None:
|
|
1180
1174
|
from finalcif.report.archive_report import ArchiveReport
|
|
1181
1175
|
zipfile = self.cif.finalcif_file.with_suffix('.zip')
|
|
@@ -1196,7 +1190,7 @@ class AppWindow(QMainWindow):
|
|
|
1196
1190
|
arc.zip.write(filename=multitable, arcname=multitable.name)
|
|
1197
1191
|
|
|
1198
1192
|
def open_report_document(self, report_filename: Path, multi_table_document: Path) -> None:
|
|
1199
|
-
if self.cif.is_multi_cif
|
|
1193
|
+
if self.cif.is_multi_cif:
|
|
1200
1194
|
open_file(multi_table_document)
|
|
1201
1195
|
open_file(report_filename)
|
|
1202
1196
|
|
|
@@ -1437,8 +1431,6 @@ class AppWindow(QMainWindow):
|
|
|
1437
1431
|
Opens the cif file and fills information into the main table.
|
|
1438
1432
|
"""
|
|
1439
1433
|
self.ui.datanameComboBox.blockSignals(True)
|
|
1440
|
-
# Is also done in block load method
|
|
1441
|
-
self._clear_state_before_block_load()
|
|
1442
1434
|
if not filepath:
|
|
1443
1435
|
filepath = Path(cif_file_open_dialog(last_dir=self.get_last_workdir()))
|
|
1444
1436
|
if not filepath.is_file():
|
|
@@ -1464,7 +1456,11 @@ class AppWindow(QMainWindow):
|
|
|
1464
1456
|
not_ok = e
|
|
1465
1457
|
if not_ok:
|
|
1466
1458
|
unable_to_open_message(self, filepath, not_ok)
|
|
1467
|
-
return
|
|
1459
|
+
return None
|
|
1460
|
+
if not self.cif.is_valid_structure_cif:
|
|
1461
|
+
show_general_warning(self, "The CIF file you are about to open contains no structure.\n\n"
|
|
1462
|
+
"Use the Import button below to import metadata.")
|
|
1463
|
+
return None
|
|
1468
1464
|
if not self.cif.chars_ok:
|
|
1469
1465
|
self.warn_about_bad_cif()
|
|
1470
1466
|
# Do this only when sure we can load the file:
|
|
@@ -1476,6 +1472,16 @@ class AppWindow(QMainWindow):
|
|
|
1476
1472
|
self.ui.datanameComboBox.blockSignals(False)
|
|
1477
1473
|
if self.cif.is_multi_cif:
|
|
1478
1474
|
self._flash_block_combobox()
|
|
1475
|
+
# Enable to find widgets without parent:
|
|
1476
|
+
# QtCore.QTimer(self).singleShot(1000, self.find_widgets_without_parent)
|
|
1477
|
+
|
|
1478
|
+
def find_widgets_without_parent(self) -> None:
|
|
1479
|
+
print('Finding parents...')
|
|
1480
|
+
all_widgets = app.allWidgets()
|
|
1481
|
+
no_parent_widgets = [widget for widget in all_widgets if widget.parent is None]
|
|
1482
|
+
print(f"Found {len(no_parent_widgets)} widget(s) out of {len(all_widgets)} without parent:")
|
|
1483
|
+
for widget in no_parent_widgets:
|
|
1484
|
+
print(widget, widget.objectName())
|
|
1479
1485
|
|
|
1480
1486
|
def _flash_block_combobox(self):
|
|
1481
1487
|
orig_pal = self.ui.datanameComboBox.palette()
|
|
@@ -20,7 +20,8 @@ from finalcif.cif.cif_order import order, special_keys
|
|
|
20
20
|
from finalcif.cif.hkl import HKL, Limit
|
|
21
21
|
from finalcif.cif.text import utf8_to_str, quote, retranslate_delimiter
|
|
22
22
|
from finalcif.datafiles.utils import DSRFind
|
|
23
|
-
from finalcif.tools.misc import essential_keys, non_centrosymm_keys, isnumeric, grouper, strip_finalcif_of_name
|
|
23
|
+
from finalcif.tools.misc import essential_keys, non_centrosymm_keys, isnumeric, grouper, strip_finalcif_of_name, \
|
|
24
|
+
_angstrom_to_x
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class GemmiError(Exception):
|
|
@@ -40,6 +41,7 @@ class CifContainer():
|
|
|
40
41
|
new_block: Create a new block (new file) if a name is given. Otherwise, just
|
|
41
42
|
the existing document is opened.
|
|
42
43
|
"""
|
|
44
|
+
self.picometer: bool = False
|
|
43
45
|
self._hkl_file: str = ''
|
|
44
46
|
self._abs_hkl_details: Dict[str, str] = {}
|
|
45
47
|
if isinstance(file, str):
|
|
@@ -146,6 +148,13 @@ class CifContainer():
|
|
|
146
148
|
[x.upper() for x in self.block.find_loop('_atom_site_type_symbol')]))
|
|
147
149
|
self.check_hkl_min_max()
|
|
148
150
|
|
|
151
|
+
@property
|
|
152
|
+
def is_valid_structure_cif(self):
|
|
153
|
+
"""
|
|
154
|
+
Checkl wether this CIF contains a structure or just metadata.
|
|
155
|
+
"""
|
|
156
|
+
return len(self.atomic_struct.sites) > 0 and self.cell.a
|
|
157
|
+
|
|
149
158
|
@property
|
|
150
159
|
def hkl_extra_info(self):
|
|
151
160
|
if not self._abs_hkl_details:
|
|
@@ -665,10 +674,7 @@ class CifContainer():
|
|
|
665
674
|
# Do not crash without symmops
|
|
666
675
|
return False
|
|
667
676
|
ops = gemmi.GroupOps([gemmi.Op(o) for o in self.symmops])
|
|
668
|
-
|
|
669
|
-
return ops.is_centric()
|
|
670
|
-
except AttributeError:
|
|
671
|
-
return ops.is_centrosymmetric()
|
|
677
|
+
return ops.is_centrosymmetric()
|
|
672
678
|
|
|
673
679
|
def atoms(self, without_h: bool = False) -> Generator:
|
|
674
680
|
"""
|
|
@@ -689,6 +695,8 @@ class CifContainer():
|
|
|
689
695
|
u_eq):
|
|
690
696
|
if without_h and self.ishydrogen(label):
|
|
691
697
|
continue
|
|
698
|
+
if self.picometer:
|
|
699
|
+
u_eq = _angstrom_to_x(u_eq, factor=100 ** 2)
|
|
692
700
|
# 0 1 2 3 4 5 6 7
|
|
693
701
|
# yield label, type, x, y, z, part, occ, ueq
|
|
694
702
|
yield atom(label=label, type=type, x=x, y=y, z=z, part=part, occ=occ, u_eq=u_eq)
|
|
@@ -721,6 +729,13 @@ class CifContainer():
|
|
|
721
729
|
u12 = self.block.find_loop('_atom_site_aniso_U_12')
|
|
722
730
|
adp = namedtuple('adp', ('label', 'U11', 'U22', 'U33', 'U23', 'U13', 'U12'))
|
|
723
731
|
for label, u11, u22, u33, u23, u13, u12 in zip(labels, u11, u22, u33, u23, u13, u12):
|
|
732
|
+
if self.picometer:
|
|
733
|
+
u11 = _angstrom_to_x(u11, factor=100 ** 2)
|
|
734
|
+
u22 = _angstrom_to_x(u22, factor=100 ** 2)
|
|
735
|
+
u33 = _angstrom_to_x(u33, factor=100 ** 2)
|
|
736
|
+
u23 = _angstrom_to_x(u23, factor=100 ** 2)
|
|
737
|
+
u13 = _angstrom_to_x(u13, factor=100 ** 2)
|
|
738
|
+
u12 = _angstrom_to_x(u12, factor=100 ** 2)
|
|
724
739
|
yield adp(label=label, U11=u11, U22=u22, U33=u33, U12=u12, U13=u13, U23=u23)
|
|
725
740
|
|
|
726
741
|
@property
|
|
@@ -770,24 +785,29 @@ class CifContainer():
|
|
|
770
785
|
publ_loop = self.block.find_loop('_geom_bond_publ_flag')
|
|
771
786
|
bond = namedtuple('bond', ('label1', 'label2', 'dist', 'symm'))
|
|
772
787
|
for label1, label2, dist, symm, publ in zip(label1, label2, dist, symm, publ_loop):
|
|
773
|
-
if
|
|
788
|
+
if without_h and (self.ishydrogen(label1) or self.ishydrogen(label2)) or self.yes_not_set(publ):
|
|
774
789
|
continue
|
|
775
790
|
else:
|
|
791
|
+
if self.picometer:
|
|
792
|
+
dist = _angstrom_to_x(dist)
|
|
776
793
|
yield bond(label1=label1, label2=label2, dist=dist, symm=self.checksymm(symm))
|
|
777
794
|
|
|
778
|
-
def bond_dist(self, pair: str) -> Union[
|
|
795
|
+
def bond_dist(self, pair: str) -> Union[str, None]:
|
|
779
796
|
for p in self.bonds():
|
|
780
797
|
if f'{p.label1}-{p.label2}' == pair:
|
|
781
|
-
|
|
798
|
+
if self.picometer:
|
|
799
|
+
return _angstrom_to_x(p.dist)
|
|
800
|
+
else:
|
|
801
|
+
return p.dist
|
|
782
802
|
return None
|
|
783
803
|
|
|
784
|
-
def angle(self, atoms: str) -> Union[
|
|
804
|
+
def angle(self, atoms: str) -> Union[str, None]:
|
|
785
805
|
for p in self.angles():
|
|
786
806
|
if f'{p.label1}-{p.label2}-{p.label3}' == atoms:
|
|
787
807
|
return p.angle_val
|
|
788
808
|
return None
|
|
789
809
|
|
|
790
|
-
def torsion(self, atoms: str) -> Union[
|
|
810
|
+
def torsion(self, atoms: str) -> Union[str, None]:
|
|
791
811
|
for p in self.torsion_angles():
|
|
792
812
|
if f'{p.label1}-{p.label2}-{p.label3}-{p.label4}' == atoms:
|
|
793
813
|
return p.torsang
|
|
@@ -803,9 +823,9 @@ class CifContainer():
|
|
|
803
823
|
publ_loop = self.block.find_loop('_geom_angle_publ_flag')
|
|
804
824
|
angle = namedtuple('angle', ('label1', 'label2', 'label3', 'angle_val', 'symm1', 'symm2'))
|
|
805
825
|
for label1, label2, label3, angle_val, symm1, symm2, publ in \
|
|
806
|
-
|
|
826
|
+
zip(label1, label2, label3, angle_val, symm1, symm2, publ_loop):
|
|
807
827
|
if (without_H and (self.ishydrogen(label1) or self.ishydrogen(label2) or
|
|
808
|
-
|
|
828
|
+
self.ishydrogen(label3)) or (self.yes_not_set(publ))):
|
|
809
829
|
continue
|
|
810
830
|
else:
|
|
811
831
|
yield angle(label1=label1, label2=label2, label3=label3, angle_val=angle_val,
|
|
@@ -854,7 +874,7 @@ class CifContainer():
|
|
|
854
874
|
symm3,
|
|
855
875
|
symm4, publ_loop):
|
|
856
876
|
if (without_h and (self.ishydrogen(label1) or self.ishydrogen(label2)
|
|
857
|
-
|
|
877
|
+
or self.ishydrogen(label3) or self.ishydrogen(label3)) or self.yes_not_set(publ)):
|
|
858
878
|
continue
|
|
859
879
|
yield tors(label1=label1, label2=label2, label3=label3, label4=label4, torsang=torsang,
|
|
860
880
|
symm1=self.checksymm(symm1),
|
|
@@ -875,9 +895,13 @@ class CifContainer():
|
|
|
875
895
|
hydr = namedtuple('HydrogenBond', ('label_d', 'label_h', 'label_a', 'dist_dh', 'dist_ha', 'dist_da',
|
|
876
896
|
'angle_dha', 'symm'))
|
|
877
897
|
for label_d, label_h, label_a, dist_dh, dist_ha, dist_da, angle_dha, symm, publ in (
|
|
878
|
-
|
|
898
|
+
zip(label_d, label_h, label_a, dist_dh, dist_ha, dist_da, angle_dha, symm, publ_loop)):
|
|
879
899
|
if self.yes_not_set(publ):
|
|
880
900
|
continue
|
|
901
|
+
if self.picometer:
|
|
902
|
+
dist_dh = _angstrom_to_x(dist_dh)
|
|
903
|
+
dist_ha = _angstrom_to_x(dist_ha)
|
|
904
|
+
dist_da = _angstrom_to_x(dist_da)
|
|
881
905
|
yield hydr(label_d, label_h, label_a, dist_dh, dist_ha, dist_da, angle_dha, self.checksymm(symm))
|
|
882
906
|
|
|
883
907
|
def yes_not_set(self, publ: str):
|
|
@@ -13,7 +13,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
|
|
13
13
|
class Ui_FinalCifWindow(object):
|
|
14
14
|
def setupUi(self, FinalCifWindow):
|
|
15
15
|
FinalCifWindow.setObjectName("FinalCifWindow")
|
|
16
|
-
FinalCifWindow.resize(1596,
|
|
16
|
+
FinalCifWindow.resize(1596, 860)
|
|
17
17
|
self.Mainwidget = QtWidgets.QWidget(FinalCifWindow)
|
|
18
18
|
self.Mainwidget.setObjectName("Mainwidget")
|
|
19
19
|
self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.Mainwidget)
|
|
@@ -242,6 +242,9 @@ class Ui_FinalCifWindow(object):
|
|
|
242
242
|
self.HAtomsCheckBox = QtWidgets.QCheckBox(self.groupBox_5)
|
|
243
243
|
self.HAtomsCheckBox.setObjectName("HAtomsCheckBox")
|
|
244
244
|
self.gridLayout_26.addWidget(self.HAtomsCheckBox, 1, 0, 1, 2)
|
|
245
|
+
self.UsePicometersCheckBox = QtWidgets.QCheckBox(self.groupBox_5)
|
|
246
|
+
self.UsePicometersCheckBox.setObjectName("UsePicometersCheckBox")
|
|
247
|
+
self.gridLayout_26.addWidget(self.UsePicometersCheckBox, 2, 1, 1, 1)
|
|
245
248
|
self.verticalLayout_35.addLayout(self.gridLayout_26)
|
|
246
249
|
self.groupBox_6 = QtWidgets.QGroupBox(self.groupBox_5)
|
|
247
250
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
|
|
@@ -551,7 +554,6 @@ class Ui_FinalCifWindow(object):
|
|
|
551
554
|
font.setFamily("Courier New")
|
|
552
555
|
font.setPointSize(11)
|
|
553
556
|
font.setBold(True)
|
|
554
|
-
font.setWeight(75)
|
|
555
557
|
self.shelx_warn_TextEdit.setFont(font)
|
|
556
558
|
self.shelx_warn_TextEdit.setUndoRedoEnabled(False)
|
|
557
559
|
self.shelx_warn_TextEdit.setLineWrapMode(QtWidgets.QPlainTextEdit.NoWrap)
|
|
@@ -589,7 +591,6 @@ class Ui_FinalCifWindow(object):
|
|
|
589
591
|
font = QtGui.QFont()
|
|
590
592
|
font.setBold(False)
|
|
591
593
|
font.setItalic(False)
|
|
592
|
-
font.setWeight(50)
|
|
593
594
|
self.wR2Label.setFont(font)
|
|
594
595
|
self.wR2Label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
|
595
596
|
self.wR2Label.setObjectName("wR2Label")
|
|
@@ -602,7 +603,6 @@ class Ui_FinalCifWindow(object):
|
|
|
602
603
|
font = QtGui.QFont()
|
|
603
604
|
font.setBold(False)
|
|
604
605
|
font.setItalic(False)
|
|
605
|
-
font.setWeight(50)
|
|
606
606
|
self.r1Label.setFont(font)
|
|
607
607
|
self.r1Label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
|
608
608
|
self.r1Label.setObjectName("r1Label")
|
|
@@ -630,7 +630,6 @@ class Ui_FinalCifWindow(object):
|
|
|
630
630
|
self.completeLabel = QtWidgets.QLabel(self.groupBox_3)
|
|
631
631
|
font = QtGui.QFont()
|
|
632
632
|
font.setBold(False)
|
|
633
|
-
font.setWeight(50)
|
|
634
633
|
self.completeLabel.setFont(font)
|
|
635
634
|
self.completeLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
|
636
635
|
self.completeLabel.setObjectName("completeLabel")
|
|
@@ -678,7 +677,6 @@ class Ui_FinalCifWindow(object):
|
|
|
678
677
|
self.dataReflnsLabel = QtWidgets.QLabel(self.groupBox_3)
|
|
679
678
|
font = QtGui.QFont()
|
|
680
679
|
font.setBold(False)
|
|
681
|
-
font.setWeight(50)
|
|
682
680
|
self.dataReflnsLabel.setFont(font)
|
|
683
681
|
self.dataReflnsLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
|
684
682
|
self.dataReflnsLabel.setObjectName("dataReflnsLabel")
|
|
@@ -745,7 +743,6 @@ class Ui_FinalCifWindow(object):
|
|
|
745
743
|
self.rintLabel = QtWidgets.QLabel(self.groupBox_3)
|
|
746
744
|
font = QtGui.QFont()
|
|
747
745
|
font.setBold(False)
|
|
748
|
-
font.setWeight(50)
|
|
749
746
|
self.rintLabel.setFont(font)
|
|
750
747
|
self.rintLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
|
751
748
|
self.rintLabel.setObjectName("rintLabel")
|
|
@@ -757,7 +754,6 @@ class Ui_FinalCifWindow(object):
|
|
|
757
754
|
self.rsigmaLabel = QtWidgets.QLabel(self.groupBox_3)
|
|
758
755
|
font = QtGui.QFont()
|
|
759
756
|
font.setBold(False)
|
|
760
|
-
font.setWeight(50)
|
|
761
757
|
self.rsigmaLabel.setFont(font)
|
|
762
758
|
self.rsigmaLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
|
763
759
|
self.rsigmaLabel.setObjectName("rsigmaLabel")
|
|
@@ -793,7 +789,6 @@ class Ui_FinalCifWindow(object):
|
|
|
793
789
|
self.dLabel = QtWidgets.QLabel(self.groupBox_3)
|
|
794
790
|
font = QtGui.QFont()
|
|
795
791
|
font.setBold(False)
|
|
796
|
-
font.setWeight(50)
|
|
797
792
|
self.dLabel.setFont(font)
|
|
798
793
|
self.dLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
|
799
794
|
self.dLabel.setObjectName("dLabel")
|
|
@@ -1971,7 +1966,7 @@ class Ui_FinalCifWindow(object):
|
|
|
1971
1966
|
self.EquipmentTemplatesListWidget.setToolTip(_translate("FinalCifWindow", "<html><head/><body><p>Each entry can have a list of key/value pairs. For example a Diffractometer model can have a list of features.</p></body></html>"))
|
|
1972
1967
|
self.NewEquipmentTemplateButton.setText(_translate("FinalCifWindow", "New Template"))
|
|
1973
1968
|
self.EditEquipmentTemplateButton.setText(_translate("FinalCifWindow", "Edit Template"))
|
|
1974
|
-
self.ImportEquipmentTemplateButton.setText(_translate("FinalCifWindow", "Import"))
|
|
1969
|
+
self.ImportEquipmentTemplateButton.setText(_translate("FinalCifWindow", "Import Template"))
|
|
1975
1970
|
self.EquipmentEditTableWidget.setSortingEnabled(True)
|
|
1976
1971
|
item = self.EquipmentEditTableWidget.horizontalHeaderItem(0)
|
|
1977
1972
|
item.setText(_translate("FinalCifWindow", "key"))
|
|
@@ -1987,6 +1982,7 @@ class Ui_FinalCifWindow(object):
|
|
|
1987
1982
|
self.ReportTextCheckBox.setText(_translate("FinalCifWindow", "No report text in structure report"))
|
|
1988
1983
|
self.PictureWidthLabel.setText(_translate("FinalCifWindow", "Picture width [cm]"))
|
|
1989
1984
|
self.HAtomsCheckBox.setText(_translate("FinalCifWindow", "No bonds and angles to hydrogen atoms"))
|
|
1985
|
+
self.UsePicometersCheckBox.setText(_translate("FinalCifWindow", "Use picometers"))
|
|
1990
1986
|
self.groupBox_6.setTitle(_translate("FinalCifWindow", "Report Templates:"))
|
|
1991
1987
|
__sortingEnabled = self.docxTemplatesListWidget.isSortingEnabled()
|
|
1992
1988
|
self.docxTemplatesListWidget.setSortingEnabled(False)
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<x>0</x>
|
|
9
9
|
<y>0</y>
|
|
10
10
|
<width>1596</width>
|
|
11
|
-
<height>
|
|
11
|
+
<height>860</height>
|
|
12
12
|
</rect>
|
|
13
13
|
</property>
|
|
14
14
|
<property name="windowTitle">
|
|
@@ -282,7 +282,7 @@
|
|
|
282
282
|
<item>
|
|
283
283
|
<widget class="QPushButton" name="ImportEquipmentTemplateButton">
|
|
284
284
|
<property name="text">
|
|
285
|
-
<string>Import</string>
|
|
285
|
+
<string>Import Template</string>
|
|
286
286
|
</property>
|
|
287
287
|
</widget>
|
|
288
288
|
</item>
|
|
@@ -554,6 +554,13 @@
|
|
|
554
554
|
</property>
|
|
555
555
|
</widget>
|
|
556
556
|
</item>
|
|
557
|
+
<item row="2" column="1">
|
|
558
|
+
<widget class="QCheckBox" name="UsePicometersCheckBox">
|
|
559
|
+
<property name="text">
|
|
560
|
+
<string>Use picometers</string>
|
|
561
|
+
</property>
|
|
562
|
+
</widget>
|
|
563
|
+
</item>
|
|
557
564
|
</layout>
|
|
558
565
|
</item>
|
|
559
566
|
<item>
|
|
@@ -1357,7 +1364,6 @@
|
|
|
1357
1364
|
<font>
|
|
1358
1365
|
<family>Courier New</family>
|
|
1359
1366
|
<pointsize>11</pointsize>
|
|
1360
|
-
<weight>75</weight>
|
|
1361
1367
|
<bold>true</bold>
|
|
1362
1368
|
</font>
|
|
1363
1369
|
</property>
|
|
@@ -1424,7 +1430,6 @@
|
|
|
1424
1430
|
<widget class="QLabel" name="wR2Label">
|
|
1425
1431
|
<property name="font">
|
|
1426
1432
|
<font>
|
|
1427
|
-
<weight>50</weight>
|
|
1428
1433
|
<italic>false</italic>
|
|
1429
1434
|
<bold>false</bold>
|
|
1430
1435
|
</font>
|
|
@@ -1448,7 +1453,6 @@
|
|
|
1448
1453
|
<widget class="QLabel" name="r1Label">
|
|
1449
1454
|
<property name="font">
|
|
1450
1455
|
<font>
|
|
1451
|
-
<weight>50</weight>
|
|
1452
1456
|
<italic>false</italic>
|
|
1453
1457
|
<bold>false</bold>
|
|
1454
1458
|
</font>
|
|
@@ -1506,7 +1510,6 @@
|
|
|
1506
1510
|
<widget class="QLabel" name="completeLabel">
|
|
1507
1511
|
<property name="font">
|
|
1508
1512
|
<font>
|
|
1509
|
-
<weight>50</weight>
|
|
1510
1513
|
<bold>false</bold>
|
|
1511
1514
|
</font>
|
|
1512
1515
|
</property>
|
|
@@ -1622,7 +1625,6 @@
|
|
|
1622
1625
|
<widget class="QLabel" name="dataReflnsLabel">
|
|
1623
1626
|
<property name="font">
|
|
1624
1627
|
<font>
|
|
1625
|
-
<weight>50</weight>
|
|
1626
1628
|
<bold>false</bold>
|
|
1627
1629
|
</font>
|
|
1628
1630
|
</property>
|
|
@@ -1770,7 +1772,6 @@
|
|
|
1770
1772
|
<widget class="QLabel" name="rintLabel">
|
|
1771
1773
|
<property name="font">
|
|
1772
1774
|
<font>
|
|
1773
|
-
<weight>50</weight>
|
|
1774
1775
|
<bold>false</bold>
|
|
1775
1776
|
</font>
|
|
1776
1777
|
</property>
|
|
@@ -1793,7 +1794,6 @@
|
|
|
1793
1794
|
<widget class="QLabel" name="rsigmaLabel">
|
|
1794
1795
|
<property name="font">
|
|
1795
1796
|
<font>
|
|
1796
|
-
<weight>50</weight>
|
|
1797
1797
|
<bold>false</bold>
|
|
1798
1798
|
</font>
|
|
1799
1799
|
</property>
|
|
@@ -1867,7 +1867,6 @@
|
|
|
1867
1867
|
<widget class="QLabel" name="dLabel">
|
|
1868
1868
|
<property name="font">
|
|
1869
1869
|
<font>
|
|
1870
|
-
<weight>50</weight>
|
|
1871
1870
|
<bold>false</bold>
|
|
1872
1871
|
</font>
|
|
1873
1872
|
</property>
|
|
@@ -4294,7 +4293,7 @@ please add a publication author:</string>
|
|
|
4294
4293
|
<extends>QPlainTextEdit</extends>
|
|
4295
4294
|
<header>finalcif.gui.file_editor.h</header>
|
|
4296
4295
|
</customwidget>
|
|
4297
|
-
|
|
4296
|
+
<customwidget>
|
|
4298
4297
|
<class>ComboBoxWithContextMenu</class>
|
|
4299
4298
|
<extends>QComboBox</extends>
|
|
4300
4299
|
<header>finalcif.gui.block_combobox.h</header>
|
|
@@ -121,7 +121,6 @@ class ReferenceList():
|
|
|
121
121
|
paragraph_reflist = document.add_paragraph('', template)
|
|
122
122
|
paragraph_reflist.add_run(f'[{str(num)}] \t')
|
|
123
123
|
ref.add_reference(paragraph_reflist)
|
|
124
|
-
# paragraph_reflist.add_run('\n')
|
|
125
124
|
|
|
126
125
|
def __repr__(self):
|
|
127
126
|
return '\n'.join([f'[{num}] {x}' for num, x in enumerate(self._references)])
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from builtins import str
|
|
3
|
+
from typing import Union, List, Tuple
|
|
4
|
+
|
|
5
|
+
import gemmi
|
|
6
|
+
from docx import Document
|
|
7
|
+
from docx.oxml.xmlchemy import BaseOxmlElement
|
|
8
|
+
from docx.text.paragraph import Paragraph
|
|
9
|
+
from docx.text.run import Run
|
|
10
|
+
from lxml import etree
|
|
11
|
+
from lxml.etree import XSLTAccessControl
|
|
12
|
+
from shelxfile.atoms.atoms import Atom as SHXAtom
|
|
13
|
+
|
|
14
|
+
from finalcif.app_path import application_path
|
|
15
|
+
from finalcif.cif.cif_file_io import CifContainer
|
|
16
|
+
from finalcif.cif.text import retranslate_delimiter, string_to_utf8
|
|
17
|
+
from finalcif.report import references
|
|
18
|
+
from finalcif.tools.misc import (protected_space, angstrom, zero_width_space, remove_line_endings,
|
|
19
|
+
flatten)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def math_to_word(eq: str) -> BaseOxmlElement:
|
|
23
|
+
"""Transform a sympy equation to be printed in word document."""
|
|
24
|
+
tree = etree.fromstring(eq)
|
|
25
|
+
xslt = etree.parse(os.path.join(application_path, 'template/mathml2omml.xsl'))
|
|
26
|
+
acess_control = XSLTAccessControl(read_network=False, write_network=False)
|
|
27
|
+
transform = etree.XSLT(xslt, access_control=acess_control)
|
|
28
|
+
new_dom = transform(tree)
|
|
29
|
+
return new_dom.getroot()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def clean_string(string: str) -> str:
|
|
33
|
+
"""
|
|
34
|
+
Removes control characters from a string.
|
|
35
|
+
"""
|
|
36
|
+
repl = string.replace('\t', ' ') \
|
|
37
|
+
.replace('\f', ' ') \
|
|
38
|
+
.replace('\0', ' ') \
|
|
39
|
+
.strip(' ') \
|
|
40
|
+
.strip('.')
|
|
41
|
+
return remove_line_endings(repl)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def gstr(string: str) -> str:
|
|
45
|
+
"""
|
|
46
|
+
Turn a string into a gemmi string and remove control characters.
|
|
47
|
+
"""
|
|
48
|
+
return clean_string(gemmi.cif.as_string(string))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _get_cooling_device(cif: CifContainer) -> str:
|
|
52
|
+
olx = gstr(cif['_olex2_diffrn_ambient_temperature_device'])
|
|
53
|
+
iucr = gstr(cif['_diffrn_measurement_ambient_temperature_device_make'])
|
|
54
|
+
if olx and iucr:
|
|
55
|
+
return iucr
|
|
56
|
+
if olx:
|
|
57
|
+
return olx
|
|
58
|
+
elif iucr:
|
|
59
|
+
return iucr
|
|
60
|
+
else:
|
|
61
|
+
return ''
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class FormatMixin():
|
|
65
|
+
|
|
66
|
+
def bold(self, run: Run):
|
|
67
|
+
r = run.bold = True
|
|
68
|
+
return r
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class SpaceChar():
|
|
73
|
+
def __init__(self, paragraph: Paragraph):
|
|
74
|
+
self.p = paragraph
|
|
75
|
+
|
|
76
|
+
def regular(self) -> None:
|
|
77
|
+
self.p.add_run(' ')
|
|
78
|
+
|
|
79
|
+
def protected(self):
|
|
80
|
+
self.p.add_run(protected_space)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class RefinementDetails():
|
|
84
|
+
def __init__(self, cif: CifContainer, document: Document):
|
|
85
|
+
ph = document.add_paragraph(style='Heading 2')
|
|
86
|
+
ph.add_run(text=fr"Refinement details for {cif.block.name}")
|
|
87
|
+
p = document.add_paragraph()
|
|
88
|
+
try:
|
|
89
|
+
p.style = document.styles['fliesstext']
|
|
90
|
+
except KeyError:
|
|
91
|
+
print('DBG> Text style not found')
|
|
92
|
+
text = ' '.join(cif['_refine_special_details'].splitlines(keepends=False))
|
|
93
|
+
if cif['_olex2_refine_details']:
|
|
94
|
+
text += ' '.join(cif['_olex2_refine_details'].splitlines(keepends=False))
|
|
95
|
+
# Replacing semicolon, because it can damage the CIF:
|
|
96
|
+
text = text.replace(';', '.')
|
|
97
|
+
p.add_run(string_to_utf8(text).strip())
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def get_inf_article(next_word: str) -> str:
|
|
101
|
+
if not next_word:
|
|
102
|
+
return 'a'
|
|
103
|
+
voc = 'aeiou'
|
|
104
|
+
return 'an' if next_word[0].lower() in voc else 'a'
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def get_distance_unit(picometers: bool) -> str:
|
|
108
|
+
if picometers:
|
|
109
|
+
return 'pm'
|
|
110
|
+
else:
|
|
111
|
+
return angstrom
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def get_volume_unit(picometers: bool) -> str:
|
|
115
|
+
if picometers:
|
|
116
|
+
return 'nm'
|
|
117
|
+
else:
|
|
118
|
+
return angstrom
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def format_float_with_decimal_places(number: float, places=2) -> str:
|
|
122
|
+
try:
|
|
123
|
+
fnum = float(number)
|
|
124
|
+
return f'{fnum:.{places}f}'
|
|
125
|
+
except ValueError:
|
|
126
|
+
return f'{number}'
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def utf8(text: str) -> str:
|
|
130
|
+
"""A Jinja2 filter for CIF to utf8"""
|
|
131
|
+
return string_to_utf8(text)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def format_radiation(radiation_type: str) -> list:
|
|
135
|
+
radtype = list(radiation_type.partition("K"))
|
|
136
|
+
if len(radtype) > 2:
|
|
137
|
+
radtype[2] = retranslate_delimiter(radtype[2])
|
|
138
|
+
return radtype
|
|
139
|
+
else:
|
|
140
|
+
return radtype
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def make_report_text(cif, document: Document) -> references.ReferenceList:
|
|
144
|
+
paragr = document.add_paragraph()
|
|
145
|
+
try:
|
|
146
|
+
paragr.style = document.styles['fliesstext']
|
|
147
|
+
except KeyError:
|
|
148
|
+
print('DBG> Text style not found')
|
|
149
|
+
ref = references.ReferenceList(paragr)
|
|
150
|
+
return ref
|
|
@@ -628,8 +628,6 @@ def add_sum_formula(formula_paragraph: Paragraph, sum_formula: str) -> None:
|
|
|
628
628
|
def add_decimal_tab(num_string: str) -> str:
|
|
629
629
|
"""
|
|
630
630
|
Adds a tab character in front of the decimal point in order to get proper alignment of the tabstops.
|
|
631
|
-
>>> add_decimal_tab('-0.123')
|
|
632
|
-
'-0\\t.123'
|
|
633
631
|
"""
|
|
634
632
|
return '\t.'.join(num_string.split('.'))
|
|
635
633
|
|