PyDIET 0.9.3__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.
- pydiet/__init__.py +12 -0
- pydiet/api_client/__init__.py +6 -0
- pydiet/api_client/client.py +57 -0
- pydiet/cmd/__init__.py +9 -0
- pydiet/cmd/start.py +107 -0
- pydiet/data/data_config.toml +242 -0
- pydiet/data/description.txt +1 -0
- pydiet/data/instruments/description.txt +1 -0
- pydiet/data/instruments/megacam/default +0 -0
- pydiet/data/instruments/megacam/description.txt +1 -0
- pydiet/data/instruments/megacam/detector/description.txt +1 -0
- pydiet/data/instruments/megacam/detector/qe/MegaCam_QE.average.fits +0 -0
- pydiet/data/instruments/megacam/detector/qe/description.txt +2 -0
- pydiet/data/instruments/megacam/filters/CaHK.MP9303.fits +0 -0
- pydiet/data/instruments/megacam/filters/Ha.MP9603.fits +0 -0
- pydiet/data/instruments/megacam/filters/HaOFF.MP9604.fits +0 -0
- pydiet/data/instruments/megacam/filters/M4112.MP9403.fits +0 -0
- pydiet/data/instruments/megacam/filters/M4376.MP9404.fits +0 -0
- pydiet/data/instruments/megacam/filters/OIII.MP9501.fits +0 -0
- pydiet/data/instruments/megacam/filters/OIIIOFF.MP9502.fits +0 -0
- pydiet/data/instruments/megacam/filters/description.txt +1 -0
- pydiet/data/instruments/megacam/filters/g.MP9402.fits +0 -0
- pydiet/data/instruments/megacam/filters/gri.MP9605.fits +0 -0
- pydiet/data/instruments/megacam/filters/i.MP9703.fits +0 -0
- pydiet/data/instruments/megacam/filters/r.MP9602.fits +0 -0
- pydiet/data/instruments/megacam/filters/u.MP9302.fits +0 -0
- pydiet/data/instruments/megacam/filters/z.MP9901.fits +0 -0
- pydiet/data/instruments/megacam/optics/description.txt +2 -0
- pydiet/data/instruments/megacam/optics/transmission/MegaPrime_transmission.fits +0 -0
- pydiet/data/instruments/megacam/optics/transmission/description.txt +2 -0
- pydiet/data/instruments/wircam/description.txt +1 -0
- pydiet/data/instruments/wircam/detector/description.txt +1 -0
- pydiet/data/instruments/wircam/detector/qe/WIRCam_QE.average.fits +0 -0
- pydiet/data/instruments/wircam/detector/qe/description.txt +2 -0
- pydiet/data/instruments/wircam/filters/BrG.WC8305.fits +0 -0
- pydiet/data/instruments/wircam/filters/CH4Off.WC8204.fits +0 -0
- pydiet/data/instruments/wircam/filters/CH4On.WC8203.fits +0 -0
- pydiet/data/instruments/wircam/filters/CO.WC8306.fits +0 -0
- pydiet/data/instruments/wircam/filters/H.WC8201.fits +0 -0
- pydiet/data/instruments/wircam/filters/H.WC8202.fits +0 -0
- pydiet/data/instruments/wircam/filters/H2.WC8304.fits +0 -0
- pydiet/data/instruments/wircam/filters/J.WC8101.fits +0 -0
- pydiet/data/instruments/wircam/filters/J.WC8103.fits +0 -0
- pydiet/data/instruments/wircam/filters/Kcont.WC8303.fits +0 -0
- pydiet/data/instruments/wircam/filters/Ks.WC8301.fits +0 -0
- pydiet/data/instruments/wircam/filters/Ks.WC8302.fits +0 -0
- pydiet/data/instruments/wircam/filters/LowOH1.WC8104.fits +0 -0
- pydiet/data/instruments/wircam/filters/LowOH2.WC8102.fits +0 -0
- pydiet/data/instruments/wircam/filters/W.WC8105.fits +0 -0
- pydiet/data/instruments/wircam/filters/Y.WC8002.fits +0 -0
- pydiet/data/instruments/wircam/filters/description.txt +1 -0
- pydiet/data/instruments/wircam/optics/description.txt +2 -0
- pydiet/data/instruments/wircam/optics/transmission/WIRCam_transmission.fits +0 -0
- pydiet/data/instruments/wircam/optics/transmission/description.txt +2 -0
- pydiet/data/sites/description.txt +1 -0
- pydiet/data/sites/mko/default +0 -0
- pydiet/data/sites/mko/description.txt +2 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.0.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.1.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.2.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.3.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.4.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.5.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.6.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.7.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.8.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.9.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM2.0.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM2.5.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.bright.AM3.0.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.0.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.1.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.2.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.3.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.4.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.5.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.6.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.7.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.8.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.9.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM2.0.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM2.5.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.dark.AM3.0.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.0.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.1.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.2.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.3.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.4.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.5.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.6.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.7.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.8.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.9.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM2.0.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM2.5.fits +0 -0
- pydiet/data/sites/mko/emission/MKO_emission.grey.AM3.0.fits +0 -0
- pydiet/data/sites/mko/emission/description.txt +5 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM1.0.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM1.1.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM1.2.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM1.3.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM1.4.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM1.5.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM1.6.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM1.7.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM1.8.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM1.9.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM2.0.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM2.5.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM3.0.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM3.5.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM4.0.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM4.5.fits +0 -0
- pydiet/data/sites/mko/transmission/MKO_transmission.AM5.0.fits +0 -0
- pydiet/data/sites/mko/transmission/description.txt +5 -0
- pydiet/data/telescopes/cfht/default +0 -0
- pydiet/data/telescopes/cfht/description.txt +1 -0
- pydiet/data/telescopes/cfht/emission/description.txt +2 -0
- pydiet/data/telescopes/cfht/transmission/CFHT_M1_transmission.fits +0 -0
- pydiet/data/telescopes/cfht/transmission/description.txt +1 -0
- pydiet/data/telescopes/description.txt +1 -0
- pydiet/package.py +55 -0
- pydiet/py.typed +0 -0
- pydiet/server/__init__.py +9 -0
- pydiet/server/app.py +369 -0
- pydiet/server/config/__init__.py +51 -0
- pydiet/server/config/config.py +330 -0
- pydiet/server/config/fields.py +49 -0
- pydiet/server/config/settings.py +166 -0
- pydiet/server/data.py +31 -0
- pydiet/server/datafiles.py +367 -0
- pydiet/server/image.py +342 -0
- pydiet/server/models/__init__.py +34 -0
- pydiet/server/models/dataconfig.py +195 -0
- pydiet/server/models/default.py +9 -0
- pydiet/server/models/exceptions.py +9 -0
- pydiet/server/models/instrument.py +314 -0
- pydiet/server/models/query.py +172 -0
- pydiet/server/models/response.py +97 -0
- pydiet/server/models/types.py +35 -0
- pydiet/server/photsys.py +71 -0
- pydiet/server/response.py +237 -0
- pydiet/server/types/__init__.py +8 -0
- pydiet/server/types/quantity.py +532 -0
- pydiet/server/types/string.py +318 -0
- pydiet/templates/common/base.html +80 -0
- pydiet/templates/common/plot_filter.html +17 -0
- pydiet/templates/common/privacy.html +132 -0
- pydiet/templates/common/settings.html +23 -0
- pydiet/templates/common/terms.html +101 -0
- pydiet/templates/megacam/etc_form.html +319 -0
- pydiet/templates/megacam/etc_results.html +190 -0
- pydiet/templates/wircam/etc_form.html +319 -0
- pydiet/templates/wircam/etc_results.html +190 -0
- pydiet/web_client/css/style.css +221 -0
- pydiet/web_client/dist/pydiet.js +31 -0
- pydiet/web_client/images/logo.svg +6 -0
- pydiet/web_client/images/megacam/background.jpg +0 -0
- pydiet/web_client/images/megacam/logo.png +0 -0
- pydiet/web_client/images/wircam/background.jpg +0 -0
- pydiet/web_client/images/wircam/logo.png +0 -0
- pydiet/web_client/js/dom.js +51 -0
- pydiet/web_client/js/etc.js +63 -0
- pydiet/web_client/js/fetch.js +49 -0
- pydiet/web_client/js/instrument.js +62 -0
- pydiet/web_client/js/main.js +15 -0
- pydiet/web_client/js/plot.js +88 -0
- pydiet/web_client/js/settings.js +57 -0
- pydiet/web_client/js/theme.js +43 -0
- pydiet/web_client/js/url.js +12 -0
- pydiet/web_client/jsdoc.json +20 -0
- pydiet/web_client/package.json +83 -0
- pydiet-0.9.3.dist-info/METADATA +118 -0
- pydiet-0.9.3.dist-info/RECORD +177 -0
- pydiet-0.9.3.dist-info/WHEEL +4 -0
- pydiet-0.9.3.dist-info/entry_points.txt +5 -0
- pydiet-0.9.3.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg width="108.1mm" height="127.5mm" version="1.1" viewBox="0 0 408.7 482" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<g transform="translate(-381.2 -371.7)">
|
|
4
|
+
<path d="m397.6 853.4-0.626-0.2547v-190.1l1.584-0.608h113.2l1.937 1.037v67.99l-0.304 0.7921-0.304 0.7922h-40.35l-0.3192-1.272-0.3192-1.272 0.0462-12.82 0.0462-12.82-0.4393-0.4393-0.4394-0.4394-32.99 0.2644v107.7l33.8 0.2638 5e-3 -0.6326 5e-3 -0.6327 0.1203-13.67 0.1202-13.67 1.502-0.9493 38.24-0.018 0.787 0.7869 0.787 0.787v68.5l-1.906 1.02-113.5-0.0583-0.626-0.2548zm149.9-0.1624-19.53-0.2593-0.1265-94.6-0.1265-94.6 1.127-1.358 113.3 0.018 2.254 0.604v40.33l-2.254 0.6039-72.17 0.018-1.202 1.202v31.23l1.347 1.118 74.02 0.2569v40.57l-74.02 0.2569-1.347 1.118v72.79l-1.202 1.202-0.5509-0.2327zm130.8 0.1104-19.4-0.1311-0.1278-94.02-0.1278-94.02 0.7307-2.265 40.34 0.2618 0.2585 37.06 0.2585 37.06 0.1171 0.1252 0.1171 0.1251h32.99l0.8103-1.252 0.2504-36.56 0.2504-36.56h40.57v189.8h-40.57l-0.2504-35.81-0.2504-35.81-0.8103-1.252h-32.89l-0.608 1.584v71.42l-2.254 0.3672zm-282.9-206.6-0.6296-1.128-1.311-3.506-4.862-15.02-1.569-6.01-1.507-6.51-1.466-7.011-1.559-10.52-1.277-10.52v-29.55l1.311-11.52 1.474-9.515 1.621-8.013 0.8759-3.756 0.8759-3.756 1.076-3.957 1.076-3.957 3.898-11.62 1.912-5.008 4.25-10.02 5.772-11.52 2.255-4.006 5.102-8.514 7.479-11.02 6.229-8.013 7.728-9.014 8.709-9.014 8.971-8.112 2.934-2.405 3.577-3.083 10.02-7.454 7.011-4.599 4.507-2.872 1.671-1.022 2.836-1.601 13.52-7.102 12.02-5.17 8.013-2.949 10.52-3.347 5.509-1.506 6.01-1.629 4.507-0.2346v275.9l-148.5 0.2537zm231.2 0.4992-0.2377-0.626 0.2565-274.9 4.507 0.2346 6.01 1.629 5.509 1.506 10.52 3.347 8.013 2.953 7.512 3.216 6.51 3.008 3.506 1.688 8.013 4.369 3.736 2.339h0.4499l6.331 4.132 5.509 3.629 10.02 7.435 3.579 3.083 5.436 4.471 16.63 16.56 7.406 9.059 3.506 4.341 3.947 5.631 4.486 6.51 5.479 9.014 3.023 5.509 5.257 10.52 4.168 10.02 1.308 3.005 1.735 5.008 0.8162 2.003 3.034 10.02 2.083 8.514 0.9399 3.506 1.115 5.509 1.42 8.514 1.724 15.52 0.015 13.52 0.0151 13.52-1.324 13.52-1.472 9.014-0.7641 3.756-0.7641 3.756-0.7305 3.255-0.7306 3.255-0.7277 2.632-0.7277 2.632-1.637 5.753-1.483 4.507-1.483 4.507-0.8614 2.003-2.012 4.758h-148.3l-0.2377-0.626z" fill="#234290" stroke-width=".5008"/>
|
|
5
|
+
</g>
|
|
6
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// DOM manipulation routines
|
|
2
|
+
// Copyright 2024,2025 CFHT/CNRS/OSUPS/CEA/UParisSaclay
|
|
3
|
+
// Licensed under GPL v3
|
|
4
|
+
|
|
5
|
+
// Inject HTML in the selected node.
|
|
6
|
+
export function inject_html(selector, html) {
|
|
7
|
+
parent = document.querySelector(selector)
|
|
8
|
+
if (parent.firstElementChild) {
|
|
9
|
+
parent.firstElementChild.remove();
|
|
10
|
+
parent.innerHTML = "";
|
|
11
|
+
}
|
|
12
|
+
parent.insertAdjacentHTML("beforeend", html);
|
|
13
|
+
|
|
14
|
+
// Now find scripts inside what was inserted and re-insert them
|
|
15
|
+
const scripts = parent.querySelectorAll('script');
|
|
16
|
+
scripts.forEach(oldScript => {
|
|
17
|
+
// Only re-run scripts that came from our insertion:
|
|
18
|
+
// (If needed, scope this by inserting into a wrapper element and querying inside it.)
|
|
19
|
+
const newScript = document.createElement('script');
|
|
20
|
+
|
|
21
|
+
// Copy attributes (type, src, nonce, etc.)
|
|
22
|
+
for (const { name, value } of oldScript.attributes) {
|
|
23
|
+
newScript.setAttribute(name, value);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (oldScript.src) {
|
|
27
|
+
// External script
|
|
28
|
+
newScript.src = oldScript.src;
|
|
29
|
+
// Optional: preserve async/defer behavior if you set it
|
|
30
|
+
} else {
|
|
31
|
+
// Inline script
|
|
32
|
+
newScript.textContent = oldScript.textContent;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
oldScript.replaceWith(newScript);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
export function inject_node(selector, node) {
|
|
41
|
+
parent = document.querySelector(selector)
|
|
42
|
+
if (parent.firstElementChild) {
|
|
43
|
+
parent.firstElementChild.remove();
|
|
44
|
+
parent.innerHTML = "";
|
|
45
|
+
}
|
|
46
|
+
if (node) {
|
|
47
|
+
parent.appendChild(node);
|
|
48
|
+
}
|
|
49
|
+
return node;
|
|
50
|
+
}
|
|
51
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Manage web interface settings
|
|
2
|
+
// Copyright 2024,2025 CFHT/CNRS/OSUPS/CEA/UParisSaclay
|
|
3
|
+
// Licensed under GPL v3
|
|
4
|
+
|
|
5
|
+
import {inject_node} from "./dom";
|
|
6
|
+
import {fetch_data, fetch_html} from "./fetch";
|
|
7
|
+
import {get_filterID, update_filter} from "./instrument";
|
|
8
|
+
import {plot_filter} from "./plot";
|
|
9
|
+
import {etc_url, ui_url} from "./url";
|
|
10
|
+
|
|
11
|
+
export async function update_etcform(instrument) {
|
|
12
|
+
fetch_html(
|
|
13
|
+
"#content-slot",
|
|
14
|
+
ui_url + "/" + instrument.id + "/etc_form"
|
|
15
|
+
).then( (result) => {
|
|
16
|
+
const etc_form = document.querySelector('#etc-form');
|
|
17
|
+
update_filters(instrument);
|
|
18
|
+
etc_form.addEventListener('submit', async function (e){
|
|
19
|
+
// Prevent default behavior on submit
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
const data = new FormData(this),
|
|
22
|
+
datao = Object.fromEntries(data),
|
|
23
|
+
upload = (datao.filter_upload && datao.filter_upload.size > 0);
|
|
24
|
+
fetch_html(
|
|
25
|
+
'#modal-slot',
|
|
26
|
+
ui_url + '/' + instrument.id + '/etc_results/query',
|
|
27
|
+
upload ? {method: 'post', data: data} : {data: data}
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
function update_filters(instrument) {
|
|
35
|
+
if ((select_filters = document.querySelector("#select-filters"))) {
|
|
36
|
+
while (select_filters.firstChild) {
|
|
37
|
+
select_filters.lastChild.remove()
|
|
38
|
+
}
|
|
39
|
+
const instrumentID = instrument.id,
|
|
40
|
+
filters = instrument.filters.transmissions;
|
|
41
|
+
let f_default = get_filterID(instrumentID);
|
|
42
|
+
for (f in filters) {
|
|
43
|
+
let option = document.createElement("ion-select-option");
|
|
44
|
+
option.value = f;
|
|
45
|
+
filter = filters[f]
|
|
46
|
+
option.innerHTML = filter.name;
|
|
47
|
+
select_filters.appendChild(option);
|
|
48
|
+
// Identify default instrument (or first in the dictionary instead)
|
|
49
|
+
if (!f_default && (filter.default || !f_default)) {
|
|
50
|
+
f_default = f;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
option = document.createElement("ion-select-option");
|
|
54
|
+
option.value = 'upload';
|
|
55
|
+
option.innerHTML = "upload";
|
|
56
|
+
select_filters.appendChild(option);
|
|
57
|
+
select_filters.value = f_default;
|
|
58
|
+
update_filter(instrumentID, f_default);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Fetch HTML components
|
|
2
|
+
// Copyright 2024,2025 CFHT/CNRS/OSUPS/CEA/UParisSaclay
|
|
3
|
+
// Licensed under GPL v3
|
|
4
|
+
|
|
5
|
+
import {inject_html} from "./dom";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export async function fetch_data(url) {
|
|
9
|
+
return await fetch(url, {credentials: "include"})
|
|
10
|
+
.then( (response) => {
|
|
11
|
+
// The API call was successful!
|
|
12
|
+
if (!response.ok) {
|
|
13
|
+
throw new Error("Unauthorized API endpoint:" + response.url);
|
|
14
|
+
}
|
|
15
|
+
return response.json();
|
|
16
|
+
}).catch( (err) => {
|
|
17
|
+
// There was an error
|
|
18
|
+
return false;
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export async function fetch_html(selector, url, {method='get', data} = {}) {
|
|
24
|
+
return await (method=='get' ?
|
|
25
|
+
fetch(
|
|
26
|
+
data ? url + '?' + new URLSearchParams(data) : url,
|
|
27
|
+
{credentials: 'include'}
|
|
28
|
+
) : fetch(url,
|
|
29
|
+
{
|
|
30
|
+
method: 'post',
|
|
31
|
+
body: data,
|
|
32
|
+
credentials: "include"})
|
|
33
|
+
).then( (response) => {
|
|
34
|
+
// The API call was successful!
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
throw new Error("Unauthorized API endpoint:" + response.url);
|
|
37
|
+
}
|
|
38
|
+
return response.text();
|
|
39
|
+
}).then( (html) => {
|
|
40
|
+
// Remove possible remaining modal
|
|
41
|
+
// Insert the HTML string into the current element
|
|
42
|
+
inject_html(selector, html);
|
|
43
|
+
return true;
|
|
44
|
+
}).catch( (err) => {
|
|
45
|
+
// There was an error
|
|
46
|
+
return false;
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Manage instruments
|
|
2
|
+
// Copyright 2024,2025 CFHT/CNRS/OSUPS/CEA/UParisSaclay
|
|
3
|
+
// Licensed under MIT
|
|
4
|
+
|
|
5
|
+
import { loadingController } from '@ionic/core';
|
|
6
|
+
import { etc_url } from "./url";
|
|
7
|
+
import {update_etcform} from "./etc";
|
|
8
|
+
import { fetch_data} from "./fetch";
|
|
9
|
+
|
|
10
|
+
let instruments_cache = null;
|
|
11
|
+
|
|
12
|
+
export async function get_instruments() {
|
|
13
|
+
if (!instruments_cache) {
|
|
14
|
+
const loading = await loadingController.create({
|
|
15
|
+
message: 'Loading instruments ...',
|
|
16
|
+
duration: 10000
|
|
17
|
+
});
|
|
18
|
+
loading.present();
|
|
19
|
+
instruments_cache = fetch_data(etc_url + "/instruments");
|
|
20
|
+
loading.dismiss();
|
|
21
|
+
}
|
|
22
|
+
return instruments_cache;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
// Get previously stored instrument
|
|
27
|
+
export function get_instrumentID() {
|
|
28
|
+
return localStorage.getItem('pyDIETDefaultInstrument');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
// Update stored instrument setting
|
|
33
|
+
export function update_instrument(instrumentID) {
|
|
34
|
+
get_instruments().then( (instruments) => {
|
|
35
|
+
instrument = instruments[instrumentID];
|
|
36
|
+
update_etcform(instrument);
|
|
37
|
+
// Store new instrument setting in local storage
|
|
38
|
+
localStorage.setItem('pyDIETDefaultInstrument', instrumentID);
|
|
39
|
+
return instrumentID;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
// Get previously stored filter
|
|
45
|
+
export function get_filterID(instrumentID) {
|
|
46
|
+
return localStorage.getItem('pyDIETDefaultFilter_' + instrumentID);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
// Update stored filter setting
|
|
51
|
+
export function update_filter(instrumentID, filterID) {
|
|
52
|
+
if (filterID) {
|
|
53
|
+
// Store new filter setting in local storage
|
|
54
|
+
localStorage.setItem('pyDIETDefaultFilter_' + instrumentID, filterID);
|
|
55
|
+
return filterID;
|
|
56
|
+
} else {
|
|
57
|
+
// Return previously stored filter
|
|
58
|
+
return get_filterID(instrumentID);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Javascript code entry point
|
|
2
|
+
// Copyright 2024,2025 CFHT/CNRS/OSUPS/CEA/UParisSaclay
|
|
3
|
+
// Licensed under MIT
|
|
4
|
+
import {get_instruments} from "./instrument"
|
|
5
|
+
import {setup_instrument_settings, setup_theme_settings} from "./settings";
|
|
6
|
+
|
|
7
|
+
// Set up theme section of settings
|
|
8
|
+
setup_theme_settings();
|
|
9
|
+
|
|
10
|
+
get_instruments().then( (instruments) => {
|
|
11
|
+
// Set up instrument section of settings
|
|
12
|
+
setup_instrument_settings(instruments);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Manage web interface settings
|
|
2
|
+
// Copyright 2024,2025 CFHT/CNRS/OSUPS/CEA/UParisSaclay
|
|
3
|
+
// Licensed under GPL v3
|
|
4
|
+
|
|
5
|
+
import Chart from 'chart.js/auto';
|
|
6
|
+
import zoomPlugin from 'chartjs-plugin-zoom';
|
|
7
|
+
|
|
8
|
+
Chart.register(zoomPlugin);
|
|
9
|
+
|
|
10
|
+
export function plot_filter(filter, atmosphere, canvas, wave_min, wave_max) {
|
|
11
|
+
const fwave = filter.wave.value,
|
|
12
|
+
fresponse = filter.response.value,
|
|
13
|
+
awave = atmosphere.wave.value,
|
|
14
|
+
aresponse = atmosphere.response.value,
|
|
15
|
+
unit = filter.wave.unit,
|
|
16
|
+
chart = new Chart(
|
|
17
|
+
canvas,
|
|
18
|
+
{
|
|
19
|
+
type: 'line',
|
|
20
|
+
data: {
|
|
21
|
+
datasets: [
|
|
22
|
+
{
|
|
23
|
+
label: 'Atmosphere',
|
|
24
|
+
data: awave.map((x, i) => ({ x, y: aresponse[i] })),
|
|
25
|
+
fill: true
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: 'Instrument',
|
|
29
|
+
data: fwave.map((x, i) => ({ x, y: fresponse[i] })),
|
|
30
|
+
fill: true
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
options: {
|
|
35
|
+
pointRadius: 0,
|
|
36
|
+
maintainAspectRatio: false,
|
|
37
|
+
interaction: {
|
|
38
|
+
mode: 'nearest',
|
|
39
|
+
intersect: true
|
|
40
|
+
},
|
|
41
|
+
scales: {
|
|
42
|
+
x: {
|
|
43
|
+
type: 'linear',
|
|
44
|
+
title: {
|
|
45
|
+
display: true,
|
|
46
|
+
text: 'Wavelength [' + unit + ']'
|
|
47
|
+
},
|
|
48
|
+
min: filter.wave_range.value[0],
|
|
49
|
+
max: filter.wave_range.value[1]
|
|
50
|
+
|
|
51
|
+
},
|
|
52
|
+
y: {
|
|
53
|
+
title: {
|
|
54
|
+
display: true,
|
|
55
|
+
text: 'Transmission',
|
|
56
|
+
},
|
|
57
|
+
min: 0.,
|
|
58
|
+
max: 1.
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
plugins: {
|
|
62
|
+
title: {
|
|
63
|
+
display: false,
|
|
64
|
+
text: filter.name + ' filter',
|
|
65
|
+
},
|
|
66
|
+
legend: {display: false},
|
|
67
|
+
zoom: {
|
|
68
|
+
zoom: {
|
|
69
|
+
wheel: {enabled: true},
|
|
70
|
+
pinch: {enabled: true},
|
|
71
|
+
drag: {enabled: true, modifierKey: 'shift'},
|
|
72
|
+
scaleMode: 'xy',
|
|
73
|
+
mode: 'xy'},
|
|
74
|
+
pan: {enabled: true, scaleMode: 'xy'},
|
|
75
|
+
limits: {
|
|
76
|
+
x: {min: 'original', max: 'original'},
|
|
77
|
+
y: {min: 'original', max: 'original'}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
window.plot_filter = plot_filter;
|
|
88
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Manage web interface settings
|
|
2
|
+
// Copyright 2024,2025 CFHT/CNRS/OSUPS/CEA/UParisSaclay
|
|
3
|
+
// Licensed under GPL v3
|
|
4
|
+
import {get_instrumentID, update_instrument} from "./instrument";
|
|
5
|
+
import {get_theme, update_theme, themes, theme_icons} from "./theme";
|
|
6
|
+
|
|
7
|
+
// Manage theme changes
|
|
8
|
+
export function setup_theme_settings() {
|
|
9
|
+
const theme_segment = document.querySelector("#theme-segment");
|
|
10
|
+
if ((theme_segment)) {
|
|
11
|
+
for (var t in themes) {
|
|
12
|
+
let button = document.createElement("ion-segment-button"),
|
|
13
|
+
icon = document.createElement("ion-icon"),
|
|
14
|
+
label = document.createElement("ion-label");
|
|
15
|
+
button.value = themes[t].toLowerCase();
|
|
16
|
+
label.innerHTML = themes[t];
|
|
17
|
+
button.appendChild(label);
|
|
18
|
+
icon.name = theme_icons[t];
|
|
19
|
+
button.appendChild(icon);
|
|
20
|
+
theme_segment.appendChild(button);
|
|
21
|
+
}
|
|
22
|
+
const theme = theme_segment.value = get_theme();
|
|
23
|
+
update_theme(theme);
|
|
24
|
+
theme_segment.addEventListener('ionChange', (event) => {
|
|
25
|
+
update_theme(event.detail.value);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Manage instrument changes
|
|
31
|
+
export function setup_instrument_settings(instruments) {
|
|
32
|
+
if ((instrument_segment = document.querySelector("#instrument-segment"))) {
|
|
33
|
+
let i_default = get_instrumentID();
|
|
34
|
+
for (i in instruments) {
|
|
35
|
+
let button = document.createElement("ion-segment-button"),
|
|
36
|
+
icon = document.createElement("ion-icon"),
|
|
37
|
+
label = document.createElement("ion-label");
|
|
38
|
+
button.value = i;
|
|
39
|
+
instrument = instruments[i]
|
|
40
|
+
label.innerHTML = instrument.name;
|
|
41
|
+
button.appendChild(label);
|
|
42
|
+
icon.name = "videocam";
|
|
43
|
+
button.appendChild(icon);
|
|
44
|
+
instrument_segment.appendChild(button);
|
|
45
|
+
// Identify default instrument (or first in the dictionary instead)
|
|
46
|
+
if (!i_default && (instrument.default || !i_default)) {
|
|
47
|
+
i_default = i;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
instrument_segment.value = i_default;
|
|
51
|
+
update_instrument(i_default);
|
|
52
|
+
instrument_segment.addEventListener('ionChange', (event) => {
|
|
53
|
+
update_instrument(event.detail.value);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Manage web interface settings
|
|
2
|
+
// Copyright 2024,2025 CFHT/CNRS/OSUPS/CEA/UParisSaclay
|
|
3
|
+
// Licensed under MIT
|
|
4
|
+
|
|
5
|
+
export const themes = ["Light", "Dark", "Auto"],
|
|
6
|
+
theme_icons = ["sunny", "moon", "contrast"];
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
// Use matchMedia to check the user preference for dark/light themes
|
|
10
|
+
const prefersdark = window.matchMedia('(prefers-color-scheme: dark)');
|
|
11
|
+
|
|
12
|
+
// Add or remove the "dark" class based on if the media query matches
|
|
13
|
+
function toggle_dark_theme(isdark) {
|
|
14
|
+
document.body.classList.toggle('dark', isdark);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
// Get previously stored theme
|
|
19
|
+
export function get_theme() {
|
|
20
|
+
return localStorage.getItem('pyDIETDefaultTheme');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
// Add or remove the "dark" class based on if the media query matches
|
|
25
|
+
export function update_theme(theme) {
|
|
26
|
+
if (theme) {
|
|
27
|
+
// Store new theme choice in local storage
|
|
28
|
+
localStorage.setItem('pyDIETDefaultTheme', theme);
|
|
29
|
+
} else {
|
|
30
|
+
// Get previously stored theme
|
|
31
|
+
theme = get_theme();
|
|
32
|
+
}
|
|
33
|
+
// Toggle theme if necessary
|
|
34
|
+
toggle_dark_theme(
|
|
35
|
+
(typeof(theme) === "string" && theme.includes("dark"))
|
|
36
|
+
|| (
|
|
37
|
+
!(typeof(theme) === "string" && theme.includes("light"))
|
|
38
|
+
&& prefersdark.matches
|
|
39
|
+
)
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Root URLs for APIs
|
|
2
|
+
// Copyright 2024,2025 CFHT/CNRS/OSUPS/CEA/UParisSaclay
|
|
3
|
+
// Licensed under GPL v3
|
|
4
|
+
|
|
5
|
+
const root_path = document.querySelector('#root_path').content;
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export const root_url = root_path, // Root URL
|
|
9
|
+
etc_url = root_url + "/api",
|
|
10
|
+
ui_url = root_url + "/ui", // Root URL for UI components
|
|
11
|
+
ui_auth_url = ui_url + "/auth";
|
|
12
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"opts": {
|
|
3
|
+
"destination": "doc",
|
|
4
|
+
"pedantic": true,
|
|
5
|
+
"private": true,
|
|
6
|
+
"recurse": true,
|
|
7
|
+
"template": "./node_modules/tidy-jsdoc"
|
|
8
|
+
},
|
|
9
|
+
"templates": {
|
|
10
|
+
"cleverLinks": true,
|
|
11
|
+
"monospaceLinks": false
|
|
12
|
+
},
|
|
13
|
+
"plugins": [
|
|
14
|
+
"plugins/markdown"
|
|
15
|
+
],
|
|
16
|
+
"metadata": {
|
|
17
|
+
"title": "PyDIET web client"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "PyDIET",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CFHT's Direct Imaging Exposure Time calculator",
|
|
5
|
+
"homepage": "https://github.com/astromatic/pydiet",
|
|
6
|
+
"author": "Emmanuel Bertin (CEA/CFHT/CNRS/UParisSaclay)",
|
|
7
|
+
"contributors": [
|
|
8
|
+
"Emmanuel Bertin <bertin@cfht.hawaii.edu> (https://github.com/ebertin)"
|
|
9
|
+
],
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"astronomy",
|
|
13
|
+
"CFHT",
|
|
14
|
+
"calculator",
|
|
15
|
+
"imaging"
|
|
16
|
+
],
|
|
17
|
+
"private": true,
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/astromatic/pydiet.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/astromatic/pydiet/issues"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@ionic/core": "^8.0",
|
|
27
|
+
"npm": "^10.8.1",
|
|
28
|
+
"tidy-jsdoc": "^1.4.1"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"chart.js": "=4.3.0",
|
|
32
|
+
"chartjs-plugin-zoom": "^2.0.1",
|
|
33
|
+
"esbuild": "^0.14.53",
|
|
34
|
+
"eslint": "^8.23.1",
|
|
35
|
+
"jsdoc": "^4.0"
|
|
36
|
+
},
|
|
37
|
+
"main": "dist/visiomatic.js",
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "esbuild js/main.js --bundle --minify --outfile=dist/pydiet.js --watch",
|
|
40
|
+
"build-pretty": "esbuild js/main.js --bundle --outfile=dist/pydiet.js --watch",
|
|
41
|
+
"docs": "jsdoc -c jsdoc.json js",
|
|
42
|
+
"lint": "eslint js",
|
|
43
|
+
"test": "npm run unit"
|
|
44
|
+
},
|
|
45
|
+
"eslintConfig": {
|
|
46
|
+
"ignorePatterns": [
|
|
47
|
+
"dist"
|
|
48
|
+
],
|
|
49
|
+
"parserOptions": {
|
|
50
|
+
"ecmaVersion": "latest",
|
|
51
|
+
"sourceType": "module"
|
|
52
|
+
},
|
|
53
|
+
"env": {
|
|
54
|
+
"node": true,
|
|
55
|
+
"es6": true
|
|
56
|
+
},
|
|
57
|
+
"rules": {
|
|
58
|
+
"curly": "error",
|
|
59
|
+
"indent": [
|
|
60
|
+
"error",
|
|
61
|
+
"tab"
|
|
62
|
+
],
|
|
63
|
+
"key-spacing": "off",
|
|
64
|
+
"linebreak-style": [
|
|
65
|
+
"off",
|
|
66
|
+
"unix"
|
|
67
|
+
],
|
|
68
|
+
"no-mixed-spaces-and-tabs": [
|
|
69
|
+
"error",
|
|
70
|
+
"smart-tabs"
|
|
71
|
+
],
|
|
72
|
+
"no-unused-expressions": [
|
|
73
|
+
"error"
|
|
74
|
+
],
|
|
75
|
+
"spaced-comment": "error",
|
|
76
|
+
"strict": "off",
|
|
77
|
+
"wrap-iife": "off",
|
|
78
|
+
"no-invalid-this": "off",
|
|
79
|
+
"prefer-object-has-own": "error",
|
|
80
|
+
"prefer-spread": "off"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|