hugpv commited on
Commit
fa21f5b
·
1 Parent(s): 61370db

json serial fixes

Browse files
Files changed (4) hide show
  1. app.py +21 -18
  2. multi_proc_funcs.py +30 -6
  3. process_asc_files_in_multi_p.py +25 -3
  4. utils.py +50 -0
app.py CHANGED
@@ -552,6 +552,8 @@ def make_json_serializable(obj, _stats=None):
552
  elif isinstance(obj, pd.Series):
553
  _stats['pandas_series'] += 1
554
  result = make_json_serializable(obj.tolist(), _stats)
 
 
555
  elif isinstance(obj, pd.DataFrame):
556
  _stats['pandas_dataframe'] += 1
557
  result = make_json_serializable(obj.to_dict(orient='records'), _stats)
@@ -596,7 +598,7 @@ def call_subprocess(script_path, data):
596
  f"{conversion_stats['fallback_none']} to None"
597
  )
598
 
599
- json_data_in = json.dumps(serializable_data)
600
 
601
  result = subprocess.run(["python", script_path], input=json_data_in, capture_output=True, text=True)
602
  ic(result.stderr)
@@ -2099,6 +2101,7 @@ def main():
2099
  "trial_start_keyword_single_asc",
2100
  "trial_end_keyword_single_asc",
2101
  "close_gap_between_words_single_asc",
 
2102
  "paragraph_trials_only_single_asc",
2103
  "discard_fixations_without_sfix_single_asc",
2104
  "discard_far_out_of_text_fix_single_asc",
@@ -2123,7 +2126,7 @@ def main():
2123
  if len(settings_to_save) > 0:
2124
  single_file_tab_asc_tab.download_button(
2125
  "⏬ Download all single .asc file settings as JSON",
2126
- json.dumps(settings_to_save),
2127
  "settings_to_save.json",
2128
  "json",
2129
  key="download_settings_to_save",
@@ -2268,7 +2271,7 @@ def main():
2268
  for k, v in st.session_state["trials_dict_single_asc"].items():
2269
  if not isinstance(v, dict):
2270
  trials_dict_for_showing[k] = v
2271
- single_file_tab_asc_tab.json(trials_dict_for_showing, expanded=False)
2272
  if "trial_choices_single_asc" in st.session_state:
2273
  single_file_tab_asc_tab.markdown("### Trial and algorithm selection")
2274
  with single_file_tab_asc_tab.form(key="single_file_tab_asc_tab_trial_select_form"):
@@ -2314,7 +2317,7 @@ def main():
2314
  f'### Result dataframes for trial {st.session_state["trial_single_asc"]["trial_id"]}'
2315
  )
2316
  trial_expander_single = single_file_tab_asc_tab.expander("Show Trial Information", False)
2317
- trial_expander_single.json(filtered_trial, expanded=False)
2318
  events_df_expander_single = single_file_tab_asc_tab.expander("Show fixations and saccades before cleaning")
2319
  events_df = st.session_state["events_df"].set_index("num").copy()
2320
  events_df_expander_single.markdown("## Events before cleaning")
@@ -2390,7 +2393,7 @@ def main():
2390
  filtered_trial = filter_trial_for_export(copy.deepcopy(trial))
2391
  trial_expander_single = single_file_tab_asc_tab.expander("Show Trial Information", False)
2392
  trial_expander_single.markdown(f'### Metadata for trial {trial["trial_id"]}')
2393
- trial_expander_single.json(filtered_trial, expanded=False)
2394
  if "saccade_df" not in st.session_state:
2395
  if st.session_state["dffix_single_asc"].shape[0] > 1:
2396
  saccade_df = get_saccade_df(
@@ -2464,7 +2467,7 @@ def main():
2464
  )
2465
  trial_expander_single.download_button(
2466
  "⏬ Download trial info as JSON",
2467
- json.dumps(filtered_trial),
2468
  f'{filtered_trial["subject"]}_{filtered_trial["trial_id"]}.json',
2469
  "json",
2470
  key="download-trial_single_asc",
@@ -2791,7 +2794,7 @@ def main():
2791
  "r",
2792
  ) as f:
2793
  fixation_sequence_json = json.load(f)
2794
- fixation_sequence_json_str = json.dumps(fixation_sequence_json)
2795
 
2796
  st.download_button(
2797
  "⏬ Download fixations in eyekits format",
@@ -2804,7 +2807,7 @@ def main():
2804
 
2805
  with open(f"results/textblock_eyekit_{subject}_{trial_id}.json", "r") as f:
2806
  textblock_json = json.load(f)
2807
- textblock_json_str = json.dumps(textblock_json)
2808
 
2809
  st.download_button(
2810
  "⏬ Download stimulus in eyekits format",
@@ -2969,7 +2972,7 @@ def main():
2969
  )
2970
  if in_st_nn("stimdf_single_csv"):
2971
  if ".json" in st.session_state["single_csv_file_stim"].name:
2972
- st.json(st.session_state["stimdf_single_csv"], expanded=False)
2973
  else:
2974
  st.dataframe(
2975
  st.session_state["stimdf_single_csv"],
@@ -3268,7 +3271,7 @@ def main():
3268
 
3269
  with open(f'results/fixation_sequence_eyekit_{trial["trial_id"]}.json', "r") as f:
3270
  fixation_sequence_json = json.load(f)
3271
- fixation_sequence_json_str = json.dumps(fixation_sequence_json)
3272
 
3273
  st.download_button(
3274
  "⏬ Download fixations in eyekits format",
@@ -3281,7 +3284,7 @@ def main():
3281
 
3282
  with open(f'results/textblock_eyekit_{trial["trial_id"]}.json', "r") as f:
3283
  textblock_json = json.load(f)
3284
- textblock_json_str = json.dumps(textblock_json)
3285
 
3286
  st.download_button(
3287
  "⏬ Download stimulus in eyekits format",
@@ -3397,7 +3400,7 @@ def main():
3397
  if len(settings_to_save) > 0:
3398
  st.download_button(
3399
  "⏬ Download all multi .asc file settings as JSON",
3400
- json.dumps(settings_to_save),
3401
  "settings_to_save_multi_asc.json",
3402
  "json",
3403
  key="download_settings_to_save_multi_asc",
@@ -3756,7 +3759,7 @@ def main():
3756
  if in_st_nn("all_fix_dfs_concat_multi_asc"):
3757
  if "all_trials_by_subj" in st.session_state:
3758
  multi_file_tab.markdown("### All meta data by subject and trial")
3759
- multi_file_tab.json(st.session_state["all_trials_by_subj"], expanded=False)
3760
  multi_file_tab.markdown("### Item level stimulus overview")
3761
  with multi_file_tab.popover("Column names definitions", help="Show column names and their definitions."):
3762
  item_colnames_markdown = read_item_col_names()
@@ -4112,7 +4115,7 @@ def main():
4112
  if in_st_nn("all_fix_dfs_concat_multi_csv"):
4113
  if "all_trials_by_subj_csv" in st.session_state:
4114
  multi_file_tab.markdown("### All meta data by subject and trial (CSV)")
4115
- multi_file_tab.json(st.session_state["all_trials_by_subj_csv"], expanded=False)
4116
  multi_file_tab.markdown("### Item level stimulus overview (CSV)")
4117
  with multi_file_tab.popover("Column names definitions", help="Show column names and their definitions."):
4118
  item_colnames_markdown = read_item_col_names()
@@ -4484,7 +4487,7 @@ def render_multi_trial_section(
4484
  df_stim_expander.info("No stimulus information available for this trial.")
4485
 
4486
  filtered_trial = filter_trial_for_export(trial)
4487
- trial_info_expander.json(filtered_trial)
4488
 
4489
  plot_expander = container.expander(f"Show corrected fixation plots{info_suffix}", True)
4490
  show_plots_key = f"show_fix_sacc_plots_{suffix}"
@@ -4602,7 +4605,7 @@ def render_multi_trial_section(
4602
 
4603
  with open(f'results/fixation_sequence_eyekit_{trial["trial_id"]}.json', "r") as f:
4604
  fixation_sequence_json = json.load(f)
4605
- fixation_sequence_json_str = json.dumps(fixation_sequence_json)
4606
 
4607
  st.download_button(
4608
  "⏬ Download fixations in eyekits format",
@@ -4615,7 +4618,7 @@ def render_multi_trial_section(
4615
 
4616
  with open(f'results/textblock_eyekit_{trial["trial_id"]}.json', "r") as f:
4617
  textblock_json = json.load(f)
4618
- textblock_json_str = json.dumps(textblock_json)
4619
 
4620
  st.download_button(
4621
  "⏬ Download stimulus in eyekits format",
@@ -5141,7 +5144,7 @@ def show_cleaning_results(
5141
  st.pyplot(dffix_clean_fig)
5142
  st.markdown("#### Fixations comparison before and after cleaning")
5143
  if "Fixation Cleaning Stats" in trial:
5144
- st.json(trial["Fixation Cleaning Stats"])
5145
  st.markdown("#### Cleaned fixations dataframe")
5146
 
5147
  st.dataframe(dffix_cleaned, height=200)
 
552
  elif isinstance(obj, pd.Series):
553
  _stats['pandas_series'] += 1
554
  result = make_json_serializable(obj.tolist(), _stats)
555
+ elif isinstance(obj, pl.Path):
556
+ result = str(obj)
557
  elif isinstance(obj, pd.DataFrame):
558
  _stats['pandas_dataframe'] += 1
559
  result = make_json_serializable(obj.to_dict(orient='records'), _stats)
 
598
  f"{conversion_stats['fallback_none']} to None"
599
  )
600
 
601
+ json_data_in = json.dumps(serializable_data, cls=ut.NpEncoder)
602
 
603
  result = subprocess.run(["python", script_path], input=json_data_in, capture_output=True, text=True)
604
  ic(result.stderr)
 
2101
  "trial_start_keyword_single_asc",
2102
  "trial_end_keyword_single_asc",
2103
  "close_gap_between_words_single_asc",
2104
+ "close_gap_between_lines_single_asc",
2105
  "paragraph_trials_only_single_asc",
2106
  "discard_fixations_without_sfix_single_asc",
2107
  "discard_far_out_of_text_fix_single_asc",
 
2126
  if len(settings_to_save) > 0:
2127
  single_file_tab_asc_tab.download_button(
2128
  "⏬ Download all single .asc file settings as JSON",
2129
+ json.dumps(settings_to_save, cls=ut.NpEncoder),
2130
  "settings_to_save.json",
2131
  "json",
2132
  key="download_settings_to_save",
 
2271
  for k, v in st.session_state["trials_dict_single_asc"].items():
2272
  if not isinstance(v, dict):
2273
  trials_dict_for_showing[k] = v
2274
+ single_file_tab_asc_tab.json(ut.make_json_serializable(trials_dict_for_showing), expanded=False)
2275
  if "trial_choices_single_asc" in st.session_state:
2276
  single_file_tab_asc_tab.markdown("### Trial and algorithm selection")
2277
  with single_file_tab_asc_tab.form(key="single_file_tab_asc_tab_trial_select_form"):
 
2317
  f'### Result dataframes for trial {st.session_state["trial_single_asc"]["trial_id"]}'
2318
  )
2319
  trial_expander_single = single_file_tab_asc_tab.expander("Show Trial Information", False)
2320
+ trial_expander_single.json(ut.make_json_serializable(filtered_trial), expanded=False)
2321
  events_df_expander_single = single_file_tab_asc_tab.expander("Show fixations and saccades before cleaning")
2322
  events_df = st.session_state["events_df"].set_index("num").copy()
2323
  events_df_expander_single.markdown("## Events before cleaning")
 
2393
  filtered_trial = filter_trial_for_export(copy.deepcopy(trial))
2394
  trial_expander_single = single_file_tab_asc_tab.expander("Show Trial Information", False)
2395
  trial_expander_single.markdown(f'### Metadata for trial {trial["trial_id"]}')
2396
+ trial_expander_single.json(ut.make_json_serializable(filtered_trial), expanded=False)
2397
  if "saccade_df" not in st.session_state:
2398
  if st.session_state["dffix_single_asc"].shape[0] > 1:
2399
  saccade_df = get_saccade_df(
 
2467
  )
2468
  trial_expander_single.download_button(
2469
  "⏬ Download trial info as JSON",
2470
+ json.dumps(filtered_trial, cls=ut.NpEncoder),
2471
  f'{filtered_trial["subject"]}_{filtered_trial["trial_id"]}.json',
2472
  "json",
2473
  key="download-trial_single_asc",
 
2794
  "r",
2795
  ) as f:
2796
  fixation_sequence_json = json.load(f)
2797
+ fixation_sequence_json_str = json.dumps(fixation_sequence_json, cls=ut.NpEncoder)
2798
 
2799
  st.download_button(
2800
  "⏬ Download fixations in eyekits format",
 
2807
 
2808
  with open(f"results/textblock_eyekit_{subject}_{trial_id}.json", "r") as f:
2809
  textblock_json = json.load(f)
2810
+ textblock_json_str = json.dumps(textblock_json, cls=ut.NpEncoder)
2811
 
2812
  st.download_button(
2813
  "⏬ Download stimulus in eyekits format",
 
2972
  )
2973
  if in_st_nn("stimdf_single_csv"):
2974
  if ".json" in st.session_state["single_csv_file_stim"].name:
2975
+ st.json(ut.make_json_serializable(st.session_state["stimdf_single_csv"]), expanded=False)
2976
  else:
2977
  st.dataframe(
2978
  st.session_state["stimdf_single_csv"],
 
3271
 
3272
  with open(f'results/fixation_sequence_eyekit_{trial["trial_id"]}.json', "r") as f:
3273
  fixation_sequence_json = json.load(f)
3274
+ fixation_sequence_json_str = json.dumps(fixation_sequence_json, cls=ut.NpEncoder)
3275
 
3276
  st.download_button(
3277
  "⏬ Download fixations in eyekits format",
 
3284
 
3285
  with open(f'results/textblock_eyekit_{trial["trial_id"]}.json', "r") as f:
3286
  textblock_json = json.load(f)
3287
+ textblock_json_str = json.dumps(textblock_json, cls=ut.NpEncoder)
3288
 
3289
  st.download_button(
3290
  "⏬ Download stimulus in eyekits format",
 
3400
  if len(settings_to_save) > 0:
3401
  st.download_button(
3402
  "⏬ Download all multi .asc file settings as JSON",
3403
+ json.dumps(settings_to_save, cls=ut.NpEncoder),
3404
  "settings_to_save_multi_asc.json",
3405
  "json",
3406
  key="download_settings_to_save_multi_asc",
 
3759
  if in_st_nn("all_fix_dfs_concat_multi_asc"):
3760
  if "all_trials_by_subj" in st.session_state:
3761
  multi_file_tab.markdown("### All meta data by subject and trial")
3762
+ multi_file_tab.json(ut.make_json_serializable(st.session_state["all_trials_by_subj"]), expanded=False)
3763
  multi_file_tab.markdown("### Item level stimulus overview")
3764
  with multi_file_tab.popover("Column names definitions", help="Show column names and their definitions."):
3765
  item_colnames_markdown = read_item_col_names()
 
4115
  if in_st_nn("all_fix_dfs_concat_multi_csv"):
4116
  if "all_trials_by_subj_csv" in st.session_state:
4117
  multi_file_tab.markdown("### All meta data by subject and trial (CSV)")
4118
+ multi_file_tab.json(ut.make_json_serializable(st.session_state["all_trials_by_subj_csv"]), expanded=False)
4119
  multi_file_tab.markdown("### Item level stimulus overview (CSV)")
4120
  with multi_file_tab.popover("Column names definitions", help="Show column names and their definitions."):
4121
  item_colnames_markdown = read_item_col_names()
 
4487
  df_stim_expander.info("No stimulus information available for this trial.")
4488
 
4489
  filtered_trial = filter_trial_for_export(trial)
4490
+ trial_info_expander.json(ut.make_json_serializable(filtered_trial))
4491
 
4492
  plot_expander = container.expander(f"Show corrected fixation plots{info_suffix}", True)
4493
  show_plots_key = f"show_fix_sacc_plots_{suffix}"
 
4605
 
4606
  with open(f'results/fixation_sequence_eyekit_{trial["trial_id"]}.json', "r") as f:
4607
  fixation_sequence_json = json.load(f)
4608
+ fixation_sequence_json_str = json.dumps(fixation_sequence_json, cls=ut.NpEncoder)
4609
 
4610
  st.download_button(
4611
  "⏬ Download fixations in eyekits format",
 
4618
 
4619
  with open(f'results/textblock_eyekit_{trial["trial_id"]}.json', "r") as f:
4620
  textblock_json = json.load(f)
4621
+ textblock_json_str = json.dumps(textblock_json, cls=ut.NpEncoder)
4622
 
4623
  st.download_button(
4624
  "⏬ Download stimulus in eyekits format",
 
5144
  st.pyplot(dffix_clean_fig)
5145
  st.markdown("#### Fixations comparison before and after cleaning")
5146
  if "Fixation Cleaning Stats" in trial:
5147
+ st.json(ut.make_json_serializable(trial["Fixation Cleaning Stats"]))
5148
  st.markdown("#### Cleaned fixations dataframe")
5149
 
5150
  st.dataframe(dffix_cleaned, height=200)
multi_proc_funcs.py CHANGED
@@ -2093,11 +2093,17 @@ def _convert_to_json(obj):
2093
  if isinstance(obj, (int, float, str, bool)):
2094
  return obj
2095
  elif isinstance(obj, dict):
2096
- return {k: _convert_to_json(v) for k, v in obj.items()}
2097
- elif isinstance(obj, list) or isinstance(obj, tuple):
2098
  return [_convert_to_json(item) for item in obj]
2099
- elif isinstance(obj, dict):
2100
- return {k: _convert_to_json(val) for k, val in obj.items()}
 
 
 
 
 
 
2101
  elif hasattr(obj, "to_dict"):
2102
  return _convert_to_json(obj.to_dict())
2103
  elif hasattr(obj, "tolist"):
@@ -2105,7 +2111,25 @@ def _convert_to_json(obj):
2105
  elif obj is None:
2106
  return None
2107
  else:
2108
- raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2109
 
2110
 
2111
  def save_trial_to_json(trial, savename):
@@ -2117,7 +2141,7 @@ def save_trial_to_json(trial, savename):
2117
  ic(f"Warning: Skipping non-serializable value for key '{key}' due to error: {e}")
2118
 
2119
  with open(savename, "w", encoding="utf-8") as f:
2120
- json.dump(filtered_trial, f, ensure_ascii=False, indent=4)
2121
 
2122
 
2123
  def export_trial(trial: dict):
 
2093
  if isinstance(obj, (int, float, str, bool)):
2094
  return obj
2095
  elif isinstance(obj, dict):
2096
+ return {str(k): _convert_to_json(v) for k, v in obj.items()}
2097
+ elif isinstance(obj, (list, tuple)):
2098
  return [_convert_to_json(item) for item in obj]
2099
+ elif isinstance(obj, np.integer):
2100
+ return int(obj)
2101
+ elif isinstance(obj, np.floating):
2102
+ return float(obj)
2103
+ elif isinstance(obj, np.ndarray):
2104
+ return _convert_to_json(obj.tolist())
2105
+ elif isinstance(obj, (np.bool_, bool)):
2106
+ return bool(obj)
2107
  elif hasattr(obj, "to_dict"):
2108
  return _convert_to_json(obj.to_dict())
2109
  elif hasattr(obj, "tolist"):
 
2111
  elif obj is None:
2112
  return None
2113
  else:
2114
+ try:
2115
+ return str(obj)
2116
+ except:
2117
+ raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
2118
+
2119
+
2120
+ class NpEncoder(json.JSONEncoder):
2121
+ def default(self, obj):
2122
+ if isinstance(obj, np.integer):
2123
+ return int(obj)
2124
+ if isinstance(obj, np.floating):
2125
+ return float(obj)
2126
+ if isinstance(obj, np.ndarray):
2127
+ return obj.tolist()
2128
+ if isinstance(obj, (np.bool_, bool)):
2129
+ return bool(obj)
2130
+ if isinstance(obj, pl.Path):
2131
+ return str(obj)
2132
+ return super(NpEncoder, self).default(obj)
2133
 
2134
 
2135
  def save_trial_to_json(trial, savename):
 
2141
  ic(f"Warning: Skipping non-serializable value for key '{key}' due to error: {e}")
2142
 
2143
  with open(savename, "w", encoding="utf-8") as f:
2144
+ json.dump(filtered_trial, f, ensure_ascii=False, indent=4, cls=NpEncoder)
2145
 
2146
 
2147
  def export_trial(trial: dict):
process_asc_files_in_multi_p.py CHANGED
@@ -6,6 +6,7 @@ import os
6
  from multi_proc_funcs import DIST_MODELS_FOLDER, process_trial_choice, set_up_models
7
  import sys
8
  import pandas as pd
 
9
 
10
 
11
  logger = logging.getLogger('multiproc')
@@ -78,16 +79,37 @@ def process_asc_files_in_multi_proc(
78
  def make_json_compatible(obj):
79
  if isinstance(obj, dict):
80
  return {k: make_json_compatible(v) for k, v in obj.items()}
81
- elif isinstance(obj, list):
82
  return [make_json_compatible(v) for v in obj]
83
  elif isinstance(obj, pd.DataFrame):
84
  return obj.to_dict(orient="records")
85
  elif isinstance(obj, pd.Series):
86
  return obj.to_dict()
 
 
 
 
 
 
 
 
87
  else:
88
  return obj
89
 
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  def main():
92
  try:
93
  input_data = sys.stdin.buffer.read()
@@ -149,13 +171,13 @@ def main():
149
  dffix = dffix.to_dict("records")
150
  trial = make_json_compatible(trial)
151
  out2.append((dffix, trial))
152
- json_data_out = json.dumps(out2)
153
  logger.info("Finished appending")
154
  sys.stdout.flush()
155
  print(json_data_out)
156
  except Exception as e:
157
  logger.warning(e)
158
- print(json.dumps({"error": str(e)}))
159
  with open("MULTI_ERROR.log",'w') as f:
160
  f.write(e)
161
 
 
6
  from multi_proc_funcs import DIST_MODELS_FOLDER, process_trial_choice, set_up_models
7
  import sys
8
  import pandas as pd
9
+ import numpy as np
10
 
11
 
12
  logger = logging.getLogger('multiproc')
 
79
  def make_json_compatible(obj):
80
  if isinstance(obj, dict):
81
  return {k: make_json_compatible(v) for k, v in obj.items()}
82
+ elif isinstance(obj, (list, tuple)):
83
  return [make_json_compatible(v) for v in obj]
84
  elif isinstance(obj, pd.DataFrame):
85
  return obj.to_dict(orient="records")
86
  elif isinstance(obj, pd.Series):
87
  return obj.to_dict()
88
+ elif isinstance(obj, np.integer):
89
+ return int(obj)
90
+ elif isinstance(obj, np.floating):
91
+ return float(obj)
92
+ elif isinstance(obj, np.ndarray):
93
+ return make_json_compatible(obj.tolist())
94
+ elif isinstance(obj, (np.bool_, bool)):
95
+ return bool(obj)
96
  else:
97
  return obj
98
 
99
 
100
+ class NpEncoder(json.JSONEncoder):
101
+ def default(self, obj):
102
+ if isinstance(obj, np.integer):
103
+ return int(obj)
104
+ if isinstance(obj, np.floating):
105
+ return float(obj)
106
+ if isinstance(obj, np.ndarray):
107
+ return obj.tolist()
108
+ if isinstance(obj, (np.bool_, bool)):
109
+ return bool(obj)
110
+ return super(NpEncoder, self).default(obj)
111
+
112
+
113
  def main():
114
  try:
115
  input_data = sys.stdin.buffer.read()
 
171
  dffix = dffix.to_dict("records")
172
  trial = make_json_compatible(trial)
173
  out2.append((dffix, trial))
174
+ json_data_out = json.dumps(out2, cls=NpEncoder)
175
  logger.info("Finished appending")
176
  sys.stdout.flush()
177
  print(json_data_out)
178
  except Exception as e:
179
  logger.warning(e)
180
+ print(json.dumps({"error": str(e)}, cls=NpEncoder))
181
  with open("MULTI_ERROR.log",'w') as f:
182
  f.write(e)
183
 
utils.py CHANGED
@@ -102,6 +102,56 @@ def download_url(url, target_filename):
102
  return -1
103
 
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  def asc_to_trial_ids(
106
  asc_file, close_gap_between_words,close_gap_between_lines, paragraph_trials_only, ias_files, trial_start_keyword, end_trial_at_keyword
107
  ):
 
102
  return -1
103
 
104
 
105
+ def make_json_serializable(obj):
106
+ """
107
+ Recursively convert non-JSON-serializable objects to serializable types.
108
+ """
109
+ if isinstance(obj, dict):
110
+ return {str(key): make_json_serializable(value) for key, value in obj.items()}
111
+ elif isinstance(obj, (list, tuple)):
112
+ return [make_json_serializable(item) for item in obj]
113
+ elif isinstance(obj, set):
114
+ return [make_json_serializable(item) for item in obj]
115
+ elif isinstance(obj, np.integer):
116
+ return int(obj)
117
+ elif isinstance(obj, np.floating):
118
+ return float(obj)
119
+ elif isinstance(obj, np.ndarray):
120
+ return make_json_serializable(obj.tolist())
121
+ elif isinstance(obj, (np.bool_, bool)):
122
+ return bool(obj)
123
+ elif isinstance(obj, pd.Series):
124
+ return make_json_serializable(obj.tolist())
125
+ elif isinstance(obj, pd.DataFrame):
126
+ return make_json_serializable(obj.to_dict(orient="records"))
127
+ elif isinstance(obj, bytes):
128
+ return obj.decode("utf-8", errors="replace")
129
+ elif isinstance(obj, pl.Path):
130
+ return str(obj)
131
+ elif isinstance(obj, (str, int, float, type(None))):
132
+ return obj
133
+ else:
134
+ try:
135
+ return str(obj)
136
+ except:
137
+ return None
138
+
139
+
140
+ class NpEncoder(json.JSONEncoder):
141
+ def default(self, obj):
142
+ if isinstance(obj, np.integer):
143
+ return int(obj)
144
+ if isinstance(obj, np.floating):
145
+ return float(obj)
146
+ if isinstance(obj, np.ndarray):
147
+ return obj.tolist()
148
+ if isinstance(obj, (np.bool_, bool)):
149
+ return bool(obj)
150
+ if isinstance(obj, pl.Path):
151
+ return str(obj)
152
+ return super(NpEncoder, self).default(obj)
153
+
154
+
155
  def asc_to_trial_ids(
156
  asc_file, close_gap_between_words,close_gap_between_lines, paragraph_trials_only, ias_files, trial_start_keyword, end_trial_at_keyword
157
  ):