psdi-data-conversion 0.0.23__py3-none-any.whl
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.
- psdi_data_conversion/__init__.py +11 -0
- psdi_data_conversion/app.py +242 -0
- psdi_data_conversion/bin/linux/atomsk +0 -0
- psdi_data_conversion/bin/linux/c2x +0 -0
- psdi_data_conversion/bin/mac/atomsk +0 -0
- psdi_data_conversion/bin/mac/c2x +0 -0
- psdi_data_conversion/constants.py +185 -0
- psdi_data_conversion/converter.py +459 -0
- psdi_data_conversion/converters/__init__.py +6 -0
- psdi_data_conversion/converters/atomsk.py +32 -0
- psdi_data_conversion/converters/base.py +702 -0
- psdi_data_conversion/converters/c2x.py +32 -0
- psdi_data_conversion/converters/openbabel.py +239 -0
- psdi_data_conversion/database.py +1064 -0
- psdi_data_conversion/dist.py +87 -0
- psdi_data_conversion/file_io.py +216 -0
- psdi_data_conversion/log_utility.py +241 -0
- psdi_data_conversion/main.py +776 -0
- psdi_data_conversion/scripts/atomsk.sh +32 -0
- psdi_data_conversion/scripts/c2x.sh +26 -0
- psdi_data_conversion/security.py +38 -0
- psdi_data_conversion/static/content/accessibility.htm +254 -0
- psdi_data_conversion/static/content/convert.htm +121 -0
- psdi_data_conversion/static/content/convertato.htm +65 -0
- psdi_data_conversion/static/content/convertc2x.htm +65 -0
- psdi_data_conversion/static/content/documentation.htm +94 -0
- psdi_data_conversion/static/content/feedback.htm +53 -0
- psdi_data_conversion/static/content/header-links.html +8 -0
- psdi_data_conversion/static/content/index-versions/header-links.html +8 -0
- psdi_data_conversion/static/content/index-versions/psdi-common-footer.html +99 -0
- psdi_data_conversion/static/content/index-versions/psdi-common-header.html +28 -0
- psdi_data_conversion/static/content/psdi-common-footer.html +99 -0
- psdi_data_conversion/static/content/psdi-common-header.html +28 -0
- psdi_data_conversion/static/content/report.htm +103 -0
- psdi_data_conversion/static/data/data.json +143940 -0
- psdi_data_conversion/static/img/colormode-toggle-dm.svg +3 -0
- psdi_data_conversion/static/img/colormode-toggle-lm.svg +3 -0
- psdi_data_conversion/static/img/psdi-icon-dark.svg +136 -0
- psdi_data_conversion/static/img/psdi-icon-light.svg +208 -0
- psdi_data_conversion/static/img/psdi-logo-darktext.png +0 -0
- psdi_data_conversion/static/img/psdi-logo-lighttext.png +0 -0
- psdi_data_conversion/static/img/social-logo-bluesky-black.svg +4 -0
- psdi_data_conversion/static/img/social-logo-bluesky-white.svg +4 -0
- psdi_data_conversion/static/img/social-logo-instagram-black.svg +1 -0
- psdi_data_conversion/static/img/social-logo-instagram-white.svg +1 -0
- psdi_data_conversion/static/img/social-logo-linkedin-black.png +0 -0
- psdi_data_conversion/static/img/social-logo-linkedin-white.png +0 -0
- psdi_data_conversion/static/img/social-logo-mastodon-black.svg +4 -0
- psdi_data_conversion/static/img/social-logo-mastodon-white.svg +4 -0
- psdi_data_conversion/static/img/social-logo-x-black.svg +3 -0
- psdi_data_conversion/static/img/social-logo-x-white.svg +3 -0
- psdi_data_conversion/static/img/social-logo-youtube-black.png +0 -0
- psdi_data_conversion/static/img/social-logo-youtube-white.png +0 -0
- psdi_data_conversion/static/img/ukri-epsr-logo-darktext.png +0 -0
- psdi_data_conversion/static/img/ukri-epsr-logo-lighttext.png +0 -0
- psdi_data_conversion/static/img/ukri-logo-darktext.png +0 -0
- psdi_data_conversion/static/img/ukri-logo-lighttext.png +0 -0
- psdi_data_conversion/static/javascript/accessibility.js +196 -0
- psdi_data_conversion/static/javascript/common.js +42 -0
- psdi_data_conversion/static/javascript/convert.js +296 -0
- psdi_data_conversion/static/javascript/convert_common.js +252 -0
- psdi_data_conversion/static/javascript/convertato.js +107 -0
- psdi_data_conversion/static/javascript/convertc2x.js +107 -0
- psdi_data_conversion/static/javascript/data.js +176 -0
- psdi_data_conversion/static/javascript/format.js +611 -0
- psdi_data_conversion/static/javascript/load_accessibility.js +89 -0
- psdi_data_conversion/static/javascript/psdi-common.js +177 -0
- psdi_data_conversion/static/javascript/report.js +381 -0
- psdi_data_conversion/static/styles/format.css +147 -0
- psdi_data_conversion/static/styles/psdi-common.css +705 -0
- psdi_data_conversion/templates/index.htm +114 -0
- psdi_data_conversion/testing/__init__.py +5 -0
- psdi_data_conversion/testing/constants.py +12 -0
- psdi_data_conversion/testing/conversion_callbacks.py +394 -0
- psdi_data_conversion/testing/conversion_test_specs.py +208 -0
- psdi_data_conversion/testing/utils.py +522 -0
- psdi_data_conversion-0.0.23.dist-info/METADATA +663 -0
- psdi_data_conversion-0.0.23.dist-info/RECORD +81 -0
- psdi_data_conversion-0.0.23.dist-info/WHEEL +4 -0
- psdi_data_conversion-0.0.23.dist-info/entry_points.txt +2 -0
- psdi_data_conversion-0.0.23.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,611 @@
|
|
1
|
+
/*
|
2
|
+
format.js
|
3
|
+
Version 1.0, 27th November 2024
|
4
|
+
|
5
|
+
This is the JavaScript which makes the Format and Converter Selection gui work.
|
6
|
+
*/
|
7
|
+
|
8
|
+
import {
|
9
|
+
getInputFormats, getOutputFormats, getOutputFormatsForInputFormat,
|
10
|
+
getInputFormatsForOutputFormat, getConverters, getConverterByName, getLevelChemInfo
|
11
|
+
} from "./data.js";
|
12
|
+
import { loadProductionMode } from "./common.js";
|
13
|
+
|
14
|
+
var fromList = new Array(),
|
15
|
+
toList = new Array(),
|
16
|
+
qualityCriteriaCount = 0,
|
17
|
+
qualityMeasureSum = 0;
|
18
|
+
|
19
|
+
$(document).ready(function () {
|
20
|
+
|
21
|
+
// Populates the "Convert from" selection list
|
22
|
+
getInputFormats().then((formats) => {
|
23
|
+
populateList(formats, "from");
|
24
|
+
});
|
25
|
+
|
26
|
+
// Populates the "Convert to" selection list
|
27
|
+
getOutputFormats().then((formats) => {
|
28
|
+
populateList(formats, "to");
|
29
|
+
});
|
30
|
+
|
31
|
+
sessionStorage.setItem("token", token);
|
32
|
+
sessionStorage.setItem("max_file_size", max_file_size);
|
33
|
+
sessionStorage.setItem("service_mode", service_mode);
|
34
|
+
sessionStorage.setItem("production_mode", production_mode);
|
35
|
+
sessionStorage.setItem("in_str", "");
|
36
|
+
sessionStorage.setItem("out_str", "");
|
37
|
+
sessionStorage.setItem("success", "");
|
38
|
+
|
39
|
+
// Set the production mode variable for this page so that only appropriate elements are shown
|
40
|
+
loadProductionMode();
|
41
|
+
|
42
|
+
$("#fromList").click(populateConversionSuccess);
|
43
|
+
$("#toList").click(populateConversionSuccess);
|
44
|
+
$("#searchTo").keyup(filterOptions);
|
45
|
+
$("#searchFrom").keyup(filterOptions);
|
46
|
+
$("#yesButton").click(goToConversionPage);
|
47
|
+
$("#success").click(showConverterDetails);
|
48
|
+
$("#resetButton").click(resetAll);
|
49
|
+
$("#showButton").click(showQualityDetails);
|
50
|
+
});
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Gets the input and output extensions and their notes from what's currently selected in the search boxes.
|
54
|
+
* @returns {Array<str>} Input extension, Input note, Output extension, Output note
|
55
|
+
*/
|
56
|
+
function getExtAndNotes() {
|
57
|
+
const in_str = $("#searchFrom").val(), // e.g. "ins: ShelX"
|
58
|
+
in_str_array = in_str.split(": "),
|
59
|
+
in_ext = in_str_array[0], // e.g. "ins"
|
60
|
+
in_note = in_str_array[1]; // e.g. "ShelX"
|
61
|
+
|
62
|
+
const out_str = $("#searchTo").val(),
|
63
|
+
out_str_array = out_str.split(": "),
|
64
|
+
out_ext = out_str_array[0],
|
65
|
+
out_note = out_str_array[1];
|
66
|
+
|
67
|
+
return [in_ext, in_note, out_ext, out_note];
|
68
|
+
}
|
69
|
+
|
70
|
+
// Selects a file format; populates the "Conversion success" selection list given input and output IDs;
|
71
|
+
// filters the output format list when an input format is selected, and vice versa (formats not convertible
|
72
|
+
// to/from the selected format are removed); and removes converter details and text input (if showing)
|
73
|
+
function populateConversionSuccess(event) {
|
74
|
+
const selectedText = getSelectedText(this);
|
75
|
+
let filterQuery = ``;
|
76
|
+
|
77
|
+
if (this.id == "fromList") {
|
78
|
+
$("#searchFrom").val(selectedText);
|
79
|
+
}
|
80
|
+
else {
|
81
|
+
$("#searchTo").val(selectedText);
|
82
|
+
}
|
83
|
+
|
84
|
+
const from_text = $("#searchFrom").val(),
|
85
|
+
to_text = $("#searchTo").val();
|
86
|
+
|
87
|
+
sessionStorage.setItem("in_str", from_text);
|
88
|
+
sessionStorage.setItem("out_str", to_text);
|
89
|
+
|
90
|
+
this.selectionStart = -1;
|
91
|
+
this.selectionEnd = -1;
|
92
|
+
this.blur();
|
93
|
+
|
94
|
+
emptySuccess();
|
95
|
+
hideConverterDetails();
|
96
|
+
hideOffer();
|
97
|
+
|
98
|
+
try {
|
99
|
+
const [in_ext, in_note, out_ext, out_note] = getExtAndNotes();
|
100
|
+
|
101
|
+
if (this.id == "fromList") {
|
102
|
+
toList = [];
|
103
|
+
$("#toList").children().remove();
|
104
|
+
getOutputFormatsForInputFormat(in_ext, in_note).then(formats => populateList(formats, "to"));
|
105
|
+
}
|
106
|
+
else if (this.id == "toList") {
|
107
|
+
fromList = [];
|
108
|
+
$("#fromList").children().remove();
|
109
|
+
getInputFormatsForOutputFormat(out_ext, out_note).then(formats => populateList(formats, "from"));
|
110
|
+
}
|
111
|
+
|
112
|
+
getConverters(in_ext, in_note, out_ext, out_note).then((converters) => {
|
113
|
+
populateList(converters, "success");
|
114
|
+
});
|
115
|
+
}
|
116
|
+
catch (e) {
|
117
|
+
// Can do without an error message if the 'Conversion options' box remains empty;
|
118
|
+
// however, consider a greyed-out message inside the box (using some of the commented out code below).
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
// Shows how the conversion quality was determined for the selected conversion/converter combination
|
123
|
+
function showQualityDetails(event) {
|
124
|
+
const [in_ext, in_note, out_ext, out_note] = getExtAndNotes();
|
125
|
+
const converter = sessionStorage.getItem("success").split(": ")[0]
|
126
|
+
|
127
|
+
getLevelChemInfo(in_ext, in_note, out_ext, out_note).then(entries => displayLevelChemInfo(entries));
|
128
|
+
}
|
129
|
+
|
130
|
+
/**
|
131
|
+
* Compiles details on quality issues for a conversion between two formats
|
132
|
+
* @param {*} entries
|
133
|
+
* @param {bool} format
|
134
|
+
* @returns {Array<str>} A long description of quality issues, the percent rating of the conversion, a short description
|
135
|
+
* of the quality
|
136
|
+
*/
|
137
|
+
function getQualityDetails(entries, format = false) {
|
138
|
+
var composition_in = entries[0].composition,
|
139
|
+
composition_out = entries[1].composition,
|
140
|
+
connections_in = entries[0].connections,
|
141
|
+
connections_out = entries[1].connections,
|
142
|
+
two_dim_in = entries[0].two_dim,
|
143
|
+
two_dim_out = entries[1].two_dim,
|
144
|
+
three_dim_in = entries[0].three_dim,
|
145
|
+
three_dim_out = entries[1].three_dim;
|
146
|
+
|
147
|
+
qualityCriteriaCount = 0;
|
148
|
+
qualityMeasureSum = 0;
|
149
|
+
|
150
|
+
var quality = qualityDetail(composition_in, composition_out, 'Composition') +
|
151
|
+
qualityDetail(connections_in, connections_out, 'Connections') +
|
152
|
+
qualityDetail(two_dim_in, two_dim_out, '2D coordinates') +
|
153
|
+
qualityDetail(three_dim_in, three_dim_out, '3D coordinates');
|
154
|
+
let percent, qualityText;
|
155
|
+
|
156
|
+
if (qualityCriteriaCount == 0) {
|
157
|
+
quality = 'Conversion quality details not available for this converter/conversion combination.';
|
158
|
+
percent = "N/A";
|
159
|
+
qualityText = "N/A";
|
160
|
+
}
|
161
|
+
else {
|
162
|
+
qualityText = 'very poor';
|
163
|
+
percent = qualityMeasureSum * 20 / qualityCriteriaCount;
|
164
|
+
|
165
|
+
percent = (Math.round(percent * 100) / 100);
|
166
|
+
|
167
|
+
if (percent >= 80.0) {
|
168
|
+
qualityText = 'very good';
|
169
|
+
}
|
170
|
+
else if (percent >= 60.0) {
|
171
|
+
qualityText = 'good';
|
172
|
+
}
|
173
|
+
else if (percent >= 40.0) {
|
174
|
+
qualityText = 'okay';
|
175
|
+
}
|
176
|
+
else if (percent >= 20.0) {
|
177
|
+
qualityText = 'poor';
|
178
|
+
}
|
179
|
+
|
180
|
+
if (quality != '') {
|
181
|
+
quality = "<strong>WARNING:</strong> Potential data loss or extrapolation in conversion due to a " +
|
182
|
+
"mismatch in representation between input and output formats:\n<ul>" + quality + "</ul>";
|
183
|
+
}
|
184
|
+
}
|
185
|
+
|
186
|
+
// Strip the HTML formatting from the output if it isn't desired
|
187
|
+
if (!format) {
|
188
|
+
quality = quality.replaceAll(/<.*?>/g, "");
|
189
|
+
}
|
190
|
+
|
191
|
+
return [quality, percent, qualityText];
|
192
|
+
}
|
193
|
+
|
194
|
+
// Assemble quality information based on level of chemical information and display it.
|
195
|
+
function displayLevelChemInfo(entries) {
|
196
|
+
var [quality, percent, qualityText] = getQualityDetails(entries);
|
197
|
+
|
198
|
+
if (percent != "N/A") {
|
199
|
+
|
200
|
+
quality += '-----------------------------\n' +
|
201
|
+
'Total score: ' + percent + '%\n' +
|
202
|
+
'Conversion quality: ' + qualityText + '\n' +
|
203
|
+
'-----------------------------\n';
|
204
|
+
|
205
|
+
}
|
206
|
+
|
207
|
+
alert(quality);
|
208
|
+
}
|
209
|
+
|
210
|
+
// Determine a statement of quality based on level of chemical information and populate the converter select box.
|
211
|
+
function getQuality(entries, rows) {
|
212
|
+
var composition_in = entries[0].composition,
|
213
|
+
composition_out = entries[1].composition,
|
214
|
+
connections_in = entries[0].connections,
|
215
|
+
connections_out = entries[1].connections,
|
216
|
+
two_dim_in = entries[0].two_dim,
|
217
|
+
two_dim_out = entries[1].two_dim,
|
218
|
+
three_dim_in = entries[0].three_dim,
|
219
|
+
three_dim_out = entries[1].three_dim,
|
220
|
+
qualityText = ' Conversion quality is very poor.';
|
221
|
+
|
222
|
+
qualityCriteriaCount = 0;
|
223
|
+
qualityMeasureSum = 0;
|
224
|
+
|
225
|
+
qualityDetail(composition_in, composition_out, 'Composition') +
|
226
|
+
qualityDetail(connections_in, connections_out, 'Connections') +
|
227
|
+
qualityDetail(two_dim_in, two_dim_out, '2D coordinates') +
|
228
|
+
qualityDetail(three_dim_in, three_dim_out, '3D coordinates');
|
229
|
+
|
230
|
+
if (qualityCriteriaCount == 0) {
|
231
|
+
qualityText = ' Conversion quality not tested.';
|
232
|
+
}
|
233
|
+
else {
|
234
|
+
var percent = qualityMeasureSum * 20 / qualityCriteriaCount;
|
235
|
+
|
236
|
+
percent = (Math.round(percent * 100) / 100);
|
237
|
+
|
238
|
+
if (percent >= 80.0) {
|
239
|
+
qualityText = ' Conversion quality is very good.';
|
240
|
+
}
|
241
|
+
else if (percent >= 60.0) {
|
242
|
+
qualityText = ' Conversion quality is good.';
|
243
|
+
}
|
244
|
+
else if (percent >= 40.0) {
|
245
|
+
qualityText = ' Conversion quality is okay.';
|
246
|
+
}
|
247
|
+
else if (percent >= 20.0) {
|
248
|
+
qualityText = ' Conversion quality is poor.';
|
249
|
+
}
|
250
|
+
}
|
251
|
+
|
252
|
+
rows.sort(function (a, b) {
|
253
|
+
return a.toLowerCase().localeCompare(b.toLowerCase());
|
254
|
+
});
|
255
|
+
|
256
|
+
for (var i = 0; i < rows.length; i++) {
|
257
|
+
const support = rows[i].substring(0, 10) == "Open Babel" ||
|
258
|
+
rows[i].substring(0, 6) == "Atomsk" ||
|
259
|
+
rows[i].substring(0, 3) == "c2x" ? " supported on this site." : " not supported on this site." //" (supported)" : " (unsupported)";
|
260
|
+
|
261
|
+
$("#success").append($('<option>', { text: rows[i] + support + qualityText }));
|
262
|
+
}
|
263
|
+
}
|
264
|
+
|
265
|
+
// Returns 'true' if textbox text is exactly the same as a select box option
|
266
|
+
function isOption(str, boxId) {
|
267
|
+
var isOption = false;
|
268
|
+
|
269
|
+
$("#" + boxId + " > option").each(function () {
|
270
|
+
if (str == this.text) {
|
271
|
+
isOption = true;
|
272
|
+
}
|
273
|
+
});
|
274
|
+
|
275
|
+
return isOption;
|
276
|
+
}
|
277
|
+
|
278
|
+
// Retrieve selected text from the "Conversion success" textarea
|
279
|
+
// $$$$$$$$$$ Can delete this PROVIDED the mobile 'phone select box issue can be solved without it? BUT NEED TO DO IT ANOTHER WAY!! $$$$$$$$$$
|
280
|
+
function getSelectedText(el) {
|
281
|
+
const text = el.value,
|
282
|
+
before = text.substring(0, el.selectionStart),
|
283
|
+
after = text.substring(el.selectionEnd, text.length);
|
284
|
+
|
285
|
+
el.selectionStart = before.lastIndexOf("\n") >= 0 ? before.lastIndexOf("\n") + 1 : 0;
|
286
|
+
el.selectionEnd = after.indexOf("\n") >= 0 ? el.selectionEnd + after.indexOf("\n") : text.length;
|
287
|
+
|
288
|
+
return el.value.substring(el.selectionStart, el.selectionEnd);
|
289
|
+
}
|
290
|
+
|
291
|
+
// Hides converter details
|
292
|
+
function hideConverterDetails() {
|
293
|
+
$("#converter").css({ display: "none" });
|
294
|
+
$("h3").css({ display: "none" });
|
295
|
+
}
|
296
|
+
|
297
|
+
// Show conversion offer
|
298
|
+
function showOffer() {
|
299
|
+
|
300
|
+
const [in_ext, in_note, out_ext, out_note] = getExtAndNotes();
|
301
|
+
|
302
|
+
const quest = " like to convert a file from '" + in_ext + "' to '" + out_ext + "' on this site";
|
303
|
+
|
304
|
+
if ($("#name").html() == "Open Babel" || $("#name").html() == "Atomsk" || $("#name").html() == "c2x") {
|
305
|
+
$("#info").html("");
|
306
|
+
$("#visit").html("visit website");
|
307
|
+
$("#question").html("Would you" + quest + " using " + $("#name").html() + "?");
|
308
|
+
$("#yesButton").css({ display: "inline" });
|
309
|
+
|
310
|
+
// Check for any warnings about this conversion
|
311
|
+
getLevelChemInfo(in_ext, in_note, out_ext, out_note).then(function (entries) {
|
312
|
+
const [quality, _percent, _qualityText] = getQualityDetails(entries, true);
|
313
|
+
if (quality != "") {
|
314
|
+
$("#formatWarning").html(quality);
|
315
|
+
$("#formatWarning").css({ display: "block" });
|
316
|
+
}
|
317
|
+
});
|
318
|
+
|
319
|
+
}
|
320
|
+
else {
|
321
|
+
$("#info").html("This converter is not supported on our website; however, you can find out how to use it at");
|
322
|
+
$("#visit").html("this website.");
|
323
|
+
$("#question").html("As an alternative, if you would" + quest + ", please select a supported converter above (if available).");
|
324
|
+
$("#yesButton").css({ display: "none" });
|
325
|
+
}
|
326
|
+
|
327
|
+
$("#question").css({ display: "inline" });
|
328
|
+
$("#offer").css({ display: "inline" });
|
329
|
+
}
|
330
|
+
|
331
|
+
// Hide conversion offer
|
332
|
+
function hideOffer() {
|
333
|
+
$("#converter").css({ display: "none" });
|
334
|
+
$("#question").css({ display: "none" });
|
335
|
+
$("#offer").css({ display: "none" });
|
336
|
+
$("#formatWarning").css({ display: "none" });
|
337
|
+
}
|
338
|
+
|
339
|
+
// Displays converter details given its name
|
340
|
+
function showConverterDetails(event) {
|
341
|
+
var selectedText = getSelectedText(this);
|
342
|
+
|
343
|
+
if (selectedText != "") {
|
344
|
+
sessionStorage.setItem("success", selectedText);
|
345
|
+
|
346
|
+
const str_array = selectedText.split(": ", 1),
|
347
|
+
conv_name = str_array[0]; // e.g. "Open Babel"
|
348
|
+
|
349
|
+
getConverterByName(conv_name).then((converter) => {
|
350
|
+
if (converter) {
|
351
|
+
$("#name").html(converter.name);
|
352
|
+
$("#description").html(converter.description);
|
353
|
+
$("#url").html(converter.url);
|
354
|
+
$("#visit").attr("href", converter.url);
|
355
|
+
$("#converter").css({ display: "block" });
|
356
|
+
$("h3").css({ display: "block" });
|
357
|
+
}
|
358
|
+
|
359
|
+
const el = this;
|
360
|
+
|
361
|
+
// Search textarea for "Open Babel" $$$$$ textarea? $$$$$
|
362
|
+
const text = el.value;
|
363
|
+
|
364
|
+
el.selectionStart = 0;
|
365
|
+
el.selectionEnd = 0;
|
366
|
+
|
367
|
+
while (el.selectionStart < text.length) {
|
368
|
+
const selectedText = getSelectedText(el),
|
369
|
+
name = selectedText.split(": ")[0];
|
370
|
+
|
371
|
+
showOffer();
|
372
|
+
|
373
|
+
el.selectionEnd += 1;
|
374
|
+
el.selectionStart = el.selectionEnd;
|
375
|
+
}
|
376
|
+
|
377
|
+
el.selectionStart = -1;
|
378
|
+
el.selectionEnd = -1;
|
379
|
+
el.blur();
|
380
|
+
});
|
381
|
+
}
|
382
|
+
}
|
383
|
+
|
384
|
+
// Create content for conversion quality details based on level of chemical information
|
385
|
+
function qualityDetail(input, output, type) {
|
386
|
+
|
387
|
+
let label;
|
388
|
+
if (type.includes("2D")) {
|
389
|
+
label = "2D atomic coordinates are"
|
390
|
+
} else if (type.includes("3D")) {
|
391
|
+
label = "3D atomic coordinates are"
|
392
|
+
} else if (type.includes("Composition")) {
|
393
|
+
label = "Atomic composition is"
|
394
|
+
} else if (type.includes("Connections")) {
|
395
|
+
label = "Atomic connections are"
|
396
|
+
} else {
|
397
|
+
label = "The '" + type + "' property is"
|
398
|
+
}
|
399
|
+
|
400
|
+
if (input == true && output == true) {
|
401
|
+
qualityCriteriaCount += 1;
|
402
|
+
qualityMeasureSum += 5;
|
403
|
+
return '';
|
404
|
+
}
|
405
|
+
else if (input == true && output == false) {
|
406
|
+
return '<li><strong>Potential data loss:</strong> ' + label +
|
407
|
+
' represented in the input format but not the output format.</li>\n';
|
408
|
+
}
|
409
|
+
else if (input == false && output == true) {
|
410
|
+
// We penalize the quality if the output format contains information that the input doesn't, as this might
|
411
|
+
// result in info being extrapolated
|
412
|
+
qualityCriteriaCount += 1;
|
413
|
+
return '<li><strong>Potential data extrapolation:</strong> ' + label +
|
414
|
+
' represented in the output format but not the input format.</li>\n';
|
415
|
+
}
|
416
|
+
else {
|
417
|
+
return '';
|
418
|
+
}
|
419
|
+
}
|
420
|
+
|
421
|
+
// Only options having user filter input as a substring (case insensitive) are included in the selection list $$$$$$$$$$ REVISE $$$$$$$$$$
|
422
|
+
function filterOptions(event) {
|
423
|
+
const str = event.target.value.toLowerCase();
|
424
|
+
var box, list,
|
425
|
+
count = 0,
|
426
|
+
text = "";
|
427
|
+
|
428
|
+
if (event.target.id == "searchFrom") {
|
429
|
+
toList = [];
|
430
|
+
$("#toList").children().remove();
|
431
|
+
getOutputFormats().then(formats => populateList(formats, "to"));
|
432
|
+
box = $("#fromList");
|
433
|
+
list = fromList;
|
434
|
+
}
|
435
|
+
else {
|
436
|
+
fromList = [];
|
437
|
+
$("#fromList").children().remove();
|
438
|
+
getInputFormats().then(formats => populateList(formats, "from"));
|
439
|
+
box = $("#toList");
|
440
|
+
list = toList;
|
441
|
+
}
|
442
|
+
|
443
|
+
box.children().remove();
|
444
|
+
|
445
|
+
for (var i = 0; i < list.length; i++) {
|
446
|
+
if (list[i].toLowerCase().includes(str)) {
|
447
|
+
box.append($('<option>', { text: list[i] }));
|
448
|
+
count += 1;
|
449
|
+
}
|
450
|
+
}
|
451
|
+
|
452
|
+
if (event.target.id == "searchFrom") {
|
453
|
+
$("#fromLabel").html("Select format to convert from (" + count + "):");
|
454
|
+
}
|
455
|
+
else {
|
456
|
+
$("#toLabel").html("Select format to convert to (" + count + "):");
|
457
|
+
}
|
458
|
+
|
459
|
+
emptySuccess();
|
460
|
+
hideConverterDetails();
|
461
|
+
hideOffer();
|
462
|
+
}
|
463
|
+
|
464
|
+
// Only options having user filter input as a substring (case insensitive) are included in the slection list
|
465
|
+
function filter(id) {
|
466
|
+
try {
|
467
|
+
const str = $("#" + id).val().toLowerCase();
|
468
|
+
var box, list,
|
469
|
+
count = 0,
|
470
|
+
text = "";
|
471
|
+
|
472
|
+
if (id == "searchFrom") {
|
473
|
+
box = $("#fromList");
|
474
|
+
list = fromList;
|
475
|
+
}
|
476
|
+
else {
|
477
|
+
box = $("#toList");
|
478
|
+
list = toList;
|
479
|
+
}
|
480
|
+
|
481
|
+
box.children().remove();
|
482
|
+
|
483
|
+
for (var i = 0; i < list.length; i++) {
|
484
|
+
if (list[i].toLowerCase().includes(str)) {
|
485
|
+
box.append($('<option>', { text: list[i] }));
|
486
|
+
count += 1;
|
487
|
+
}
|
488
|
+
}
|
489
|
+
|
490
|
+
if (id == "searchFrom") {
|
491
|
+
$("#fromLabel").html("Select format to convert from (" + count + "):");
|
492
|
+
}
|
493
|
+
else {
|
494
|
+
$("#toLabel").html("Select format to convert to (" + count + "):");
|
495
|
+
}
|
496
|
+
|
497
|
+
emptySuccess();
|
498
|
+
hideConverterDetails();
|
499
|
+
hideOffer();
|
500
|
+
}
|
501
|
+
catch (e) {
|
502
|
+
// No need for an error message here. No need to filter if text box is empty.
|
503
|
+
}
|
504
|
+
}
|
505
|
+
|
506
|
+
// Empties the "Conversion success" textarea $$$$$ textarea? $$$$$
|
507
|
+
function emptySuccess() {
|
508
|
+
$("#success").html("");
|
509
|
+
}
|
510
|
+
|
511
|
+
// Retrieves a file format from a string (e.g. "ins: ShelX") from a selection list
|
512
|
+
function getFormat(str) {
|
513
|
+
const str_array = str.split(": ");
|
514
|
+
return str_array[0]; // e.g. "ins"
|
515
|
+
}
|
516
|
+
|
517
|
+
// Stores chosen formats and switches to the Conversion page
|
518
|
+
function goToConversionPage(event) {
|
519
|
+
var path = ``;
|
520
|
+
|
521
|
+
if ($("#name").html() == "Open Babel") {
|
522
|
+
path = `static/content/convert.htm`;
|
523
|
+
}
|
524
|
+
else if ($("#name").html() == "Atomsk") {
|
525
|
+
path = `static/content/convertato.htm`;
|
526
|
+
}
|
527
|
+
else if ($("#name").html() == "c2x") {
|
528
|
+
path = `static/content/convertc2x.htm`;
|
529
|
+
}
|
530
|
+
|
531
|
+
const a = $("<a>")
|
532
|
+
.attr("href", path)
|
533
|
+
.appendTo("body");
|
534
|
+
|
535
|
+
a[0].click();
|
536
|
+
a.remove();
|
537
|
+
}
|
538
|
+
|
539
|
+
// Populates a selection list
|
540
|
+
function populateList(entries, sel) {
|
541
|
+
const [in_ext, in_note, out_ext, out_note] = getExtAndNotes();
|
542
|
+
|
543
|
+
let rows;
|
544
|
+
|
545
|
+
if ((sel === "from") || (sel === "to")) {
|
546
|
+
|
547
|
+
rows = entries.map(entry => `${entry.extension}: ${entry.note}`);
|
548
|
+
|
549
|
+
} else if (sel === "success") {
|
550
|
+
|
551
|
+
rows = entries.map(entry => `${entry.name}:`);
|
552
|
+
|
553
|
+
if (in_ext != "" && out_ext != "") {
|
554
|
+
const quality = getLevelChemInfo(in_ext, in_note, out_ext, out_note).then(formats => getQuality(formats, rows));
|
555
|
+
}
|
556
|
+
}
|
557
|
+
|
558
|
+
if (sel !== "success") {
|
559
|
+
rows.sort(function (a, b) {
|
560
|
+
return a.toLowerCase().localeCompare(b.toLowerCase());
|
561
|
+
});
|
562
|
+
|
563
|
+
for (var i = 0; i < rows.length; i++) {
|
564
|
+
const support = rows[i].substring(0, 10) == "Open Babel" || rows[i].substring(0, 6) == "Atomsk" ? " (supported)" : " (unsupported)";
|
565
|
+
|
566
|
+
if (sel == "from") {
|
567
|
+
$("#fromList").append($('<option>', { value: rows[i], text: rows[i] }));
|
568
|
+
fromList[i] = rows[i] + "\n";
|
569
|
+
}
|
570
|
+
else if (sel == "to") {
|
571
|
+
$("#toList").append($('<option>', { value: rows[i], text: rows[i] }));
|
572
|
+
toList[i] = rows[i] + "\n";
|
573
|
+
}
|
574
|
+
}
|
575
|
+
}
|
576
|
+
|
577
|
+
const in_str = in_ext + ": " + in_note;
|
578
|
+
const out_str = out_ext + ": " + out_note;
|
579
|
+
if (sel == "from" && !isOption(in_str, "toList")) {
|
580
|
+
filter("searchFrom");
|
581
|
+
}
|
582
|
+
else if (sel == "to" && !isOption(out_str, "fromList")) {
|
583
|
+
filter("searchTo");
|
584
|
+
}
|
585
|
+
|
586
|
+
if (sel == "from") {
|
587
|
+
$("#fromLabel").html("Select format to convert from (" + $("#fromList").children('option').length + "):");
|
588
|
+
$("#fromList option[value='" + in_str + "']").prop('selected', 'selected');
|
589
|
+
$("#fromList").hide().show();
|
590
|
+
}
|
591
|
+
else if (sel == "to") {
|
592
|
+
$("#toLabel").html("Select format to convert to (" + $("#toList").children('option').length + "):");
|
593
|
+
$("#toList option[value='" + out_str + "']").prop('selected', 'selected');
|
594
|
+
$("#toList").hide().show();
|
595
|
+
}
|
596
|
+
}
|
597
|
+
|
598
|
+
// Resets the filtering, format list and converter list boxes
|
599
|
+
function resetAll() {
|
600
|
+
$("#fromList").children().remove();
|
601
|
+
$("#toList").children().remove();
|
602
|
+
|
603
|
+
$("#searchFrom").val("");
|
604
|
+
$("#searchTo").val("");
|
605
|
+
|
606
|
+
// Populates the "Convert from" selection list
|
607
|
+
getInputFormats().then(formats => populateList(formats, "from"));
|
608
|
+
|
609
|
+
// Populates the "Convert to" selection list
|
610
|
+
getOutputFormats().then(formats => populateList(formats, "to"));
|
611
|
+
}
|
@@ -0,0 +1,89 @@
|
|
1
|
+
const r = document.querySelector(':root');
|
2
|
+
const s = getComputedStyle(document.documentElement);
|
3
|
+
|
4
|
+
function setDefault(default_varname, current_varname) {
|
5
|
+
if (s.getPropertyValue('--' + default_varname) == "") {
|
6
|
+
r.style.setProperty('--' + default_varname, s.getPropertyValue('--' + current_varname))
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
setDefault("psdi-default-font", "ifm-font-family-base");
|
11
|
+
setDefault("psdi-default-heading-font", "ifm-heading-font-family");
|
12
|
+
|
13
|
+
setDefault("psdi-default-font-size", "ifm-font-size-base");
|
14
|
+
|
15
|
+
setDefault("psdi-default-font-weight", "ifm-font-weight-base");
|
16
|
+
|
17
|
+
setDefault("psdi-default-letter-spacing", "psdi-letter-spacing-base");
|
18
|
+
|
19
|
+
setDefault("psdi-default-dark-text-color-body", "psdi-dark-text-color-body");
|
20
|
+
setDefault("psdi-default-dark-text-color-heading", "psdi-dark-text-color-heading");
|
21
|
+
setDefault("psdi-default-light-text-color-body", "psdi-light-text-color-body");
|
22
|
+
setDefault("psdi-default-light-text-color-heading", "psdi-light-text-color-heading");
|
23
|
+
|
24
|
+
setDefault("psdi-default-line-height", "ifm-line-height-base");
|
25
|
+
|
26
|
+
setDefault("psdi-default-background-color", "ifm-background-color");
|
27
|
+
setDefault("psdi-default-color-primary", "ifm-color-primary");
|
28
|
+
|
29
|
+
// Load values from session storage
|
30
|
+
const font = sessionStorage.getItem("font"),
|
31
|
+
hfont = sessionStorage.getItem("hfont"),
|
32
|
+
size = sessionStorage.getItem("size"),
|
33
|
+
weight = sessionStorage.getItem("weight"),
|
34
|
+
letter = sessionStorage.getItem("letter"),
|
35
|
+
line = sessionStorage.getItem("line"),
|
36
|
+
darkColour = sessionStorage.getItem("darkColour"),
|
37
|
+
lightColour = sessionStorage.getItem("lightColour"),
|
38
|
+
lightBack = sessionStorage.getItem("lightBack"),
|
39
|
+
darkBack = sessionStorage.getItem("darkBack"),
|
40
|
+
mode = sessionStorage.getItem("mode");
|
41
|
+
|
42
|
+
function loadProperty(current_varname, value) {
|
43
|
+
if (value != null) {
|
44
|
+
r.style.setProperty('--' + current_varname, value);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
loadProperty("ifm-font-family-base", font);
|
49
|
+
loadProperty("ifm-heading-font-family", hfont);
|
50
|
+
|
51
|
+
loadProperty("ifm-font-size-base", size);
|
52
|
+
|
53
|
+
loadProperty("ifm-font-weight-base", weight);
|
54
|
+
|
55
|
+
loadProperty("psdi-letter-spacing-base", letter);
|
56
|
+
|
57
|
+
loadProperty("psdi-dark-text-color-body", darkColour);
|
58
|
+
loadProperty("psdi-dark-text-color-heading", darkColour);
|
59
|
+
loadProperty("psdi-light-text-color-body", lightColour);
|
60
|
+
loadProperty("psdi-light-text-color-heading", lightColour);
|
61
|
+
|
62
|
+
loadProperty("ifm-line-height-base", line);
|
63
|
+
|
64
|
+
loadProperty("ifm-background-color", lightBack);
|
65
|
+
loadProperty("ifm-color-primary", darkBack);
|
66
|
+
|
67
|
+
if (font != null) {
|
68
|
+
|
69
|
+
r.style.setProperty('--ifm-font-family-base', font);
|
70
|
+
r.style.setProperty('--ifm-heading-font-family', hfont);
|
71
|
+
|
72
|
+
r.style.setProperty('--ifm-font-size-base', size);
|
73
|
+
|
74
|
+
r.style.setProperty('--ifm-font-weight-base', weight);
|
75
|
+
|
76
|
+
r.style.setProperty('--psdi-letter-spacing-base', letter);
|
77
|
+
|
78
|
+
r.style.setProperty('--psdi-dark-text-color-body', darkColour);
|
79
|
+
r.style.setProperty('--psdi-dark-text-color-heading', darkColour);
|
80
|
+
r.style.setProperty('--psdi-light-text-color-body', lightColour);
|
81
|
+
r.style.setProperty('--psdi-light-text-color-heading', lightColour);
|
82
|
+
|
83
|
+
r.style.setProperty('--ifm-line-height-base', line);
|
84
|
+
|
85
|
+
r.style.setProperty('--ifm-background-color', lightBack);
|
86
|
+
r.style.setProperty('--ifm-color-primary', darkBack);
|
87
|
+
}
|
88
|
+
|
89
|
+
document.documentElement.setAttribute("data-theme", mode);
|