matfile.py 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. from scipy.io import savemat
  2. from view.python_core.get_internal_files import get_gdm_doc_df
  3. from view.python_core.p1_class import P1SingleWavelengthTIF
  4. from view.python_core.flags import FlagsManager
  5. from view.python_core.gdm_generation.glomeruli_managers import get_gdm_row_boiler_plate_sans_glo
  6. import numpy as np
  7. def export_processed_data_as_mat_file(view_object, analyze_values_to_use):
  8. # initialize measus to use
  9. measus = view_object.get_measus_for_current_animal(analyze_values_to_use=analyze_values_to_use)
  10. metadatas = []
  11. response_frames = []
  12. signal_movies = []
  13. # iterate over measurements of the animal
  14. for measu in measus:
  15. # load a measurement for the animal
  16. view_object.load_measurement_data_from_current_animal(measu)
  17. # calculate signals
  18. view_object.calculate_signals()
  19. # accumulate metadata
  20. metadatas.append(get_gdm_row_boiler_plate_sans_glo(flags=view_object.flags, p1=view_object.p1))
  21. # accumulate CTV overview
  22. response_frames.append(view_object.generate_ctv_response_frame_for_current_measurement())
  23. # accumulate signal
  24. signal_movies.append(view_object.p1.sig1)
  25. # convert accumulated data in an numpy array mimicking a MATLAB cell array
  26. if metadatas:
  27. n_metadata = len(metadatas[0])
  28. cell_array = np.empty((len(measus), n_metadata + 2), dtype=object)
  29. doc_string_cell_array = create_mat_file_doc_string(
  30. columns=metadatas[0].keys(),
  31. extra_doc=[
  32. "response frame as a 2D array. Format XY. "
  33. "Pixel value indicates response strength as indicated by CTV flags",
  34. "movie of calcium estimate (ratio or dff) as a 3D array. Format XYT"
  35. ])
  36. doc_string = "Variable 'area_mask': 2D logical array, with pixels to be excluded set to False. " \
  37. "Will be NaN if an area mask (.AREA file) was not created for this animal\n\n" \
  38. "Variable 'GDM': 2D cell array of metadata and data. Column are described below:\n\n" \
  39. + doc_string_cell_array
  40. for measu_ind, measu in enumerate(measus):
  41. for ind, metadata_val in enumerate(metadatas[measu_ind].values):
  42. cell_array[measu_ind, ind] = metadata_val
  43. # flip Y axis as it is output format that is more common
  44. cell_array[measu_ind, n_metadata] = np.flip(response_frames[measu_ind], axis=1)
  45. cell_array[measu_ind, n_metadata + 1] = np.flip(signal_movies[measu_ind], axis=1)
  46. else:
  47. doc_string = "This file contains no data!"
  48. cell_array = np.array([])
  49. area_mask = view_object.p1.area_mask
  50. op_dir = view_object.flags.get_processed_data_op_path(format_name="MAT")
  51. op_dir.mkdir(exist_ok=True, parents=True)
  52. op_file = op_dir / f"{view_object.get_current_animal()}.mat"
  53. savemat(
  54. file_name=op_file,
  55. mdict={
  56. "doc_string": doc_string,
  57. "GDM": cell_array,
  58. "area_mask": area_mask
  59. },
  60. do_compression=True)
  61. def create_mat_file_doc_string(columns, extra_doc):
  62. """
  63. Creates a string explaining how to interpret data in the cell array of a mat file
  64. :param Sequence columns: columns of GDM used
  65. :param Sequence extra_doc: documentation of non-GDM columns in cell array
  66. :return: str
  67. """
  68. gdm_doc_df = get_gdm_doc_df().set_index("Column name")
  69. doc_str = "\n".join(
  70. f"Column {ind + 1}: {gdm_doc_df.loc[col_name, 'Description']}" for ind, col_name in enumerate(columns))
  71. doc_str += "\n" + "\n".join(f"Column {len(columns) + ind + 1}: {val}" for ind, val in enumerate(extra_doc))
  72. return doc_str