Spaces:
Running
Running
kartikmandar
commited on
Commit
·
0955096
1
Parent(s):
9cc56a6
data read is more robust
Browse files- explorer.py +1 -0
- modules/DataLoading/DataIngestion.py +108 -24
explorer.py
CHANGED
@@ -17,6 +17,7 @@ from utils.sidebar import create_sidebar
|
|
17 |
|
18 |
# Initialize panel extension
|
19 |
pn.extension('floatpanel', 'mathjax')
|
|
|
20 |
hv.extension('bokeh')
|
21 |
|
22 |
# Create a boolean status indicator
|
|
|
17 |
|
18 |
# Initialize panel extension
|
19 |
pn.extension('floatpanel', 'mathjax')
|
20 |
+
pn.extension('filedropper')
|
21 |
hv.extension('bokeh')
|
22 |
|
23 |
# Create a boolean status indicator
|
modules/DataLoading/DataIngestion.py
CHANGED
@@ -137,12 +137,14 @@ def create_loadingdata_warning_box(content):
|
|
137 |
return WarningBox(warning_content=content)
|
138 |
|
139 |
|
140 |
-
def
|
141 |
event,
|
142 |
file_selector,
|
143 |
filename_input,
|
144 |
format_input,
|
145 |
format_checkbox,
|
|
|
|
|
146 |
output_box_container,
|
147 |
warning_box_container,
|
148 |
warning_handler,
|
@@ -171,7 +173,7 @@ def load_event_data(
|
|
171 |
- Requires that the number of formats matches the number of files unless default format is used.
|
172 |
|
173 |
Example:
|
174 |
-
>>>
|
175 |
>>> len(loaded_event_data)
|
176 |
1 # Assuming one file was loaded
|
177 |
"""
|
@@ -213,6 +215,63 @@ def load_event_data(
|
|
213 |
]
|
214 |
return
|
215 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
216 |
try:
|
217 |
loaded_files = []
|
218 |
for file_path, file_name, file_format in zip(file_paths, filenames, formats):
|
@@ -224,7 +283,7 @@ def load_event_data(
|
|
224 |
]
|
225 |
return
|
226 |
|
227 |
-
event_list = EventList.read(file_path, file_format)
|
228 |
loaded_event_data.append((file_name, event_list))
|
229 |
loaded_files.append(
|
230 |
f"File '{file_path}' loaded successfully as '{file_name}' with format '{file_format}'."
|
@@ -404,7 +463,7 @@ def delete_selected_files(
|
|
404 |
# Define allowed extensions for deletion
|
405 |
allowed_extensions = {
|
406 |
".pkl", ".pickle", ".fits", ".evt", ".h5", ".hdf5",
|
407 |
-
".ecsv", ".txt", ".dat", ".csv", ".vot", ".tex", ".html"
|
408 |
}
|
409 |
if not file_selector.value:
|
410 |
output_box_container[:] = [
|
@@ -416,12 +475,12 @@ def delete_selected_files(
|
|
416 |
|
417 |
file_paths = file_selector.value
|
418 |
deleted_files = []
|
419 |
-
restricted_files = []
|
420 |
for file_path in file_paths:
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
|
|
425 |
continue
|
426 |
|
427 |
try:
|
@@ -431,17 +490,6 @@ def delete_selected_files(
|
|
431 |
deleted_files.append(f"File '{file_path}' deleted successfully.")
|
432 |
except Exception as e:
|
433 |
deleted_files.append(f"An error occurred while deleting '{file_path}': {e}")
|
434 |
-
|
435 |
-
# Create messages for deleted and restricted files
|
436 |
-
messages = []
|
437 |
-
if deleted_files:
|
438 |
-
messages.append("\n".join(deleted_files))
|
439 |
-
if restricted_files:
|
440 |
-
messages.append(
|
441 |
-
"The following files were not deleted because their extensions are not allowed:\n" +
|
442 |
-
"\n".join(restricted_files)
|
443 |
-
)
|
444 |
-
|
445 |
output_box_container[:] = [create_loadingdata_output_box("\n".join(deleted_files))]
|
446 |
if warning_handler.warnings:
|
447 |
warning_box_container[:] = [
|
@@ -796,8 +844,12 @@ def create_loading_tab(output_box_container, warning_box_container, warning_hand
|
|
796 |
>>> isinstance(tab, pn.Column)
|
797 |
True
|
798 |
"""
|
|
|
|
|
|
|
|
|
799 |
file_selector = pn.widgets.FileSelector(
|
800 |
-
|
801 |
)
|
802 |
filename_input = pn.widgets.TextInput(
|
803 |
name="Enter File Names",
|
@@ -810,7 +862,7 @@ def create_loading_tab(output_box_container, warning_box_container, warning_hand
|
|
810 |
width=400,
|
811 |
)
|
812 |
format_checkbox = pn.widgets.Checkbox(
|
813 |
-
name="Use default format (ogip for
|
814 |
)
|
815 |
load_button = pn.widgets.Button(name="Load Event Data", button_type="primary")
|
816 |
save_button = pn.widgets.Button(name="Save Loaded Data", button_type="success")
|
@@ -835,6 +887,34 @@ def create_loading_tab(output_box_container, warning_box_container, warning_hand
|
|
835 |
position="bottom",
|
836 |
)
|
837 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
838 |
|
839 |
def on_load_click(event):
|
840 |
# Clear previous outputs and warnings
|
@@ -843,12 +923,14 @@ def create_loading_tab(output_box_container, warning_box_container, warning_hand
|
|
843 |
warning_handler.warnings.clear()
|
844 |
warnings.resetwarnings()
|
845 |
|
846 |
-
|
847 |
event,
|
848 |
file_selector,
|
849 |
filename_input,
|
850 |
format_input,
|
851 |
format_checkbox,
|
|
|
|
|
852 |
output_box_container,
|
853 |
warning_box_container,
|
854 |
warning_handler,
|
@@ -912,11 +994,13 @@ def create_loading_tab(output_box_container, warning_box_container, warning_hand
|
|
912 |
clear_button.on_click(on_clear_click)
|
913 |
|
914 |
first_column = pn.Column(
|
915 |
-
pn.Row(pn.pane.Markdown("<h2> Read an EventList object from File</h2>"),pn.widgets.TooltipIcon(value=Tooltip(content="Supported Formats: pickle, hea or ogip, any other astropy.table.Table", position="
|
916 |
file_selector,
|
917 |
pn.Row(filename_input, tooltip_file),
|
918 |
pn.Row(format_input, tooltip_format),
|
919 |
format_checkbox,
|
|
|
|
|
920 |
pn.Row(load_button, save_button, delete_button, preview_button, clear_button),
|
921 |
pn.pane.Markdown("<br/>"),
|
922 |
width_policy="min",
|
|
|
137 |
return WarningBox(warning_content=content)
|
138 |
|
139 |
|
140 |
+
def read_event_data(
|
141 |
event,
|
142 |
file_selector,
|
143 |
filename_input,
|
144 |
format_input,
|
145 |
format_checkbox,
|
146 |
+
rmf_file_dropper,
|
147 |
+
additional_columns_input,
|
148 |
output_box_container,
|
149 |
warning_box_container,
|
150 |
warning_handler,
|
|
|
173 |
- Requires that the number of formats matches the number of files unless default format is used.
|
174 |
|
175 |
Example:
|
176 |
+
>>> read_event_data(event, file_selector, filename_input, format_input, format_checkbox, ...)
|
177 |
>>> len(loaded_event_data)
|
178 |
1 # Assuming one file was loaded
|
179 |
"""
|
|
|
215 |
]
|
216 |
return
|
217 |
|
218 |
+
def read_event_data(
|
219 |
+
event,
|
220 |
+
file_selector,
|
221 |
+
filename_input,
|
222 |
+
format_input,
|
223 |
+
format_checkbox,
|
224 |
+
rmf_file_dropper,
|
225 |
+
additional_columns_input,
|
226 |
+
output_box_container,
|
227 |
+
warning_box_container,
|
228 |
+
warning_handler,
|
229 |
+
):
|
230 |
+
"""
|
231 |
+
Load event data from selected files with extended EventList.read functionality,
|
232 |
+
supporting FileDropper for RMF files and additional columns.
|
233 |
+
"""
|
234 |
+
# Validation for required inputs
|
235 |
+
if not file_selector.value:
|
236 |
+
output_box_container[:] = [
|
237 |
+
create_loadingdata_output_box(
|
238 |
+
"No file selected. Please select a file to upload."
|
239 |
+
)
|
240 |
+
]
|
241 |
+
return
|
242 |
+
|
243 |
+
file_paths = file_selector.value
|
244 |
+
filenames = (
|
245 |
+
[name.strip() for name in filename_input.value.split(",")]
|
246 |
+
if filename_input.value
|
247 |
+
else []
|
248 |
+
)
|
249 |
+
formats = (
|
250 |
+
[fmt.strip() for fmt in format_input.value.split(",")]
|
251 |
+
if format_input.value
|
252 |
+
else []
|
253 |
+
)
|
254 |
+
|
255 |
+
if format_checkbox.value:
|
256 |
+
formats = ["ogip" for _ in range(len(file_paths))]
|
257 |
+
|
258 |
+
# Parse optional RMF file from FileDropper
|
259 |
+
rmf_file = None
|
260 |
+
if rmf_file_dropper.value:
|
261 |
+
# Retrieve the uploaded RMF file
|
262 |
+
rmf_file_name, rmf_file_bytes = list(rmf_file_dropper.value.items())[0]
|
263 |
+
rmf_file_path = os.path.join(loaded_data_path, rmf_file_name)
|
264 |
+
with open(rmf_file_path, "wb") as f:
|
265 |
+
f.write(rmf_file_bytes)
|
266 |
+
rmf_file = rmf_file_path
|
267 |
+
|
268 |
+
# Parse additional columns
|
269 |
+
additional_columns = (
|
270 |
+
[col.strip() for col in additional_columns_input.value.split(",")]
|
271 |
+
if additional_columns_input.value
|
272 |
+
else None
|
273 |
+
)
|
274 |
+
|
275 |
try:
|
276 |
loaded_files = []
|
277 |
for file_path, file_name, file_format in zip(file_paths, filenames, formats):
|
|
|
283 |
]
|
284 |
return
|
285 |
|
286 |
+
event_list = EventList.read(file_path, fmt=file_format, rmf_file=rmf_file, additional_columns=additional_columns)
|
287 |
loaded_event_data.append((file_name, event_list))
|
288 |
loaded_files.append(
|
289 |
f"File '{file_path}' loaded successfully as '{file_name}' with format '{file_format}'."
|
|
|
463 |
# Define allowed extensions for deletion
|
464 |
allowed_extensions = {
|
465 |
".pkl", ".pickle", ".fits", ".evt", ".h5", ".hdf5",
|
466 |
+
".ecsv", ".txt", ".dat", ".csv", ".vot", ".tex", ".html", ".gz"
|
467 |
}
|
468 |
if not file_selector.value:
|
469 |
output_box_container[:] = [
|
|
|
475 |
|
476 |
file_paths = file_selector.value
|
477 |
deleted_files = []
|
|
|
478 |
for file_path in file_paths:
|
479 |
+
|
480 |
+
if not any(file_path.endswith(ext) for ext in allowed_extensions):
|
481 |
+
deleted_files.append(
|
482 |
+
f"Cannot delete file '{file_path}': File type is not allowed for deletion."
|
483 |
+
)
|
484 |
continue
|
485 |
|
486 |
try:
|
|
|
490 |
deleted_files.append(f"File '{file_path}' deleted successfully.")
|
491 |
except Exception as e:
|
492 |
deleted_files.append(f"An error occurred while deleting '{file_path}': {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
493 |
output_box_container[:] = [create_loadingdata_output_box("\n".join(deleted_files))]
|
494 |
if warning_handler.warnings:
|
495 |
warning_box_container[:] = [
|
|
|
844 |
>>> isinstance(tab, pn.Column)
|
845 |
True
|
846 |
"""
|
847 |
+
|
848 |
+
# Get the user's home directory
|
849 |
+
home_directory = os.path.expanduser("~")
|
850 |
+
|
851 |
file_selector = pn.widgets.FileSelector(
|
852 |
+
home_directory, only_files=True, name="Select File", show_hidden=True
|
853 |
)
|
854 |
filename_input = pn.widgets.TextInput(
|
855 |
name="Enter File Names",
|
|
|
862 |
width=400,
|
863 |
)
|
864 |
format_checkbox = pn.widgets.Checkbox(
|
865 |
+
name="Use default format (\"ogip\" for reading, \"hdf5\" for writing/saving)", value=False
|
866 |
)
|
867 |
load_button = pn.widgets.Button(name="Load Event Data", button_type="primary")
|
868 |
save_button = pn.widgets.Button(name="Save Loaded Data", button_type="success")
|
|
|
887 |
position="bottom",
|
888 |
)
|
889 |
)
|
890 |
+
|
891 |
+
tooltip_rmf = pn.widgets.TooltipIcon(
|
892 |
+
value=Tooltip(
|
893 |
+
content="""for energy calibration""",
|
894 |
+
position="bottom",
|
895 |
+
)
|
896 |
+
)
|
897 |
+
|
898 |
+
tooltip_additional_columns = pn.widgets.TooltipIcon(
|
899 |
+
value=Tooltip(
|
900 |
+
content="""further keyword arguments to be passed to OGIP/HEASOFT format""",
|
901 |
+
position="bottom",
|
902 |
+
)
|
903 |
+
)
|
904 |
+
|
905 |
+
# FileDropper for RMF file
|
906 |
+
rmf_file_dropper = pn.widgets.FileDropper(
|
907 |
+
accepted_filetypes=[".rmf", ".fits"], # Accept RMF files or compatible FITS files
|
908 |
+
multiple=False, # Only allow a single file
|
909 |
+
name="Upload RMF File (optional)",
|
910 |
+
max_file_size="1000MB", # Limit file size
|
911 |
+
layout="integrated", # Layout style
|
912 |
+
)
|
913 |
+
|
914 |
+
additional_columns_input = pn.widgets.TextInput(
|
915 |
+
name="Additional Columns (optional)", placeholder="Comma-separated column names"
|
916 |
+
)
|
917 |
+
|
918 |
|
919 |
def on_load_click(event):
|
920 |
# Clear previous outputs and warnings
|
|
|
923 |
warning_handler.warnings.clear()
|
924 |
warnings.resetwarnings()
|
925 |
|
926 |
+
read_event_data(
|
927 |
event,
|
928 |
file_selector,
|
929 |
filename_input,
|
930 |
format_input,
|
931 |
format_checkbox,
|
932 |
+
rmf_file_dropper,
|
933 |
+
additional_columns_input,
|
934 |
output_box_container,
|
935 |
warning_box_container,
|
936 |
warning_handler,
|
|
|
994 |
clear_button.on_click(on_clear_click)
|
995 |
|
996 |
first_column = pn.Column(
|
997 |
+
pn.Row(pn.pane.Markdown("<h2> Read an EventList object from File</h2>"),pn.widgets.TooltipIcon(value=Tooltip(content="Supported Formats: pickle, hea or ogip, any other astropy.table.Table", position="bottom"))),
|
998 |
file_selector,
|
999 |
pn.Row(filename_input, tooltip_file),
|
1000 |
pn.Row(format_input, tooltip_format),
|
1001 |
format_checkbox,
|
1002 |
+
pn.Row(rmf_file_dropper, tooltip_rmf),
|
1003 |
+
pn.Row(additional_columns_input, tooltip_additional_columns),
|
1004 |
pn.Row(load_button, save_button, delete_button, preview_button, clear_button),
|
1005 |
pn.pane.Markdown("<br/>"),
|
1006 |
width_policy="min",
|