__init__.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import numpy as np
  2. from view.python_core.utils.colors import interpret_flag_SO_MV_colortable
  3. import view.python_core.overviews.roi_marker as roi_markers
  4. import pandas as pd
  5. from .temporal import get_temporal_processor
  6. from .spatial import get_spatial_processor
  7. from .data_limit import get_data_limit_decider_3D
  8. from .write import get_writer
  9. from .borders_and_annotations import BordersAndAnnotations
  10. from .rotate import get_frame_rotator
  11. from .colorizer import get_colorizer_3D
  12. from .data_to_01 import get_normalizer
  13. from .excluder import Excluder3D
  14. import logging
  15. class MovieExporter(object):
  16. def __init__(self, flags, p1):
  17. self.data_sampling_period = pd.Timedelta(f"{p1.metadata.trial_ticks}ms")
  18. frame_size = (p1.metadata.format_x, p1.metadata.format_y)
  19. self.colormap, self.bg_color_mpl_compliant, self.fg_color_mpl_compliant = \
  20. interpret_flag_SO_MV_colortable(SO_MV_colortable=flags["SO_MV_colortable"],
  21. fg_color=flags["mv_fgColor"],
  22. bg_color=flags["mv_bgColor"])
  23. self.temporal_processor = get_temporal_processor(filter_time_flag=flags["Signal_FilterTimeFlag"],
  24. filter_time_size=flags["Signal_FilterTimeSize"])
  25. self.spatial_processor = get_spatial_processor(filter_space_flag=flags["Signal_FilterSpaceFlag"],
  26. filter_space_size=flags["Signal_FilterSpaceSize"])
  27. self.excluder = Excluder3D(mv_FirstFrame=flags["mv_FirstFrame"],
  28. mv_LastFrame=flags["mv_LastFrame"],
  29. cutborder_x=flags["mv_cutborder"],
  30. cutborder_y=flags["mv_cutborder"])
  31. area_mask_2D_excluded = self.excluder.exclude_from_frame(p1.area_mask)
  32. self.data_limit_decider = get_data_limit_decider_3D(flags, area_mask_2D_excluded)
  33. self.individual_scale = flags["mv_individualScale"]
  34. self.colorizer = get_colorizer_3D(flags=flags, p1=p1, colormap=self.colormap,
  35. area_mask_2D_excluded=area_mask_2D_excluded,
  36. excluder=self.excluder)
  37. revised_frame_size = self.excluder.revise_frame_size(frame_size)
  38. self.roi_marker = roi_markers.get_roi_marker_3D(
  39. flags=flags, measurement_label=p1.metadata.ex_name,
  40. fg_color=self.fg_color_mpl_compliant, unexcluded_frame_size=frame_size, excluder=self.excluder)
  41. self.frame_rotater = get_frame_rotator(rotate=flags["mv_rotateImage"],
  42. reverse=flags["mv_reverseIt"])
  43. modified_frame_size = self.frame_rotater.transform_frame_size(revised_frame_size)
  44. self.border_annotations_adder = BordersAndAnnotations(flags=flags,
  45. colormap=self.colormap,
  46. fg_color_for_mpl=self.fg_color_mpl_compliant,
  47. bg_color_for_mpl=self.bg_color_mpl_compliant,
  48. frame_size=modified_frame_size,
  49. data_sampling_period=self.data_sampling_period,
  50. pulsed_stimuli_handler=p1.pulsed_stimuli_handler,
  51. )
  52. self.writer = get_writer(flags)
  53. def preprocess(self, data: np.ndarray):
  54. time_filtered_data = self.temporal_processor.filter(data)
  55. time_space_filtered_data = self.spatial_processor.filter_3D(time_filtered_data)
  56. data_cropped = self.excluder.exclude_from_movie(time_space_filtered_data)
  57. first_frame_retained, last_frame_retained = self.excluder.revised_frame_start_end(data.shape)
  58. return data_cropped, first_frame_retained, last_frame_retained
  59. def get_normalizer(self, data: np.ndarray):
  60. vmin, vmax = self.data_limit_decider.get_data_limit(data)
  61. return get_normalizer(vmin=vmin, vmax=vmax, mv_individualScale=self.individual_scale)
  62. def colorize(self, data: np.ndarray, data_to_01_mapper):
  63. return self.colorizer.colorize(data=data, data_to_01_mapper=data_to_01_mapper)
  64. def rotate_frame(self, frame_data):
  65. return self.frame_rotater.transform(frame_data)
  66. def add_borders_annotations_to_frame(self, frame_data, frame_number, static_frame):
  67. return self.border_annotations_adder.add(frame_data, frame_number, static_frame)
  68. def write_to_file(self, data_numpy_list, full_filename_without_extension):
  69. return self.writer.write(data_numpy_list, self.data_sampling_period, full_filename_without_extension)
  70. def add_rois(self, frame_data):
  71. return self.roi_marker.draw(frame_data)
  72. def export_movie(flags, p1, full_filename_without_extension):
  73. movie_exporter = MovieExporter(flags=flags, p1=p1)
  74. preprocessed_data, first_frame_retained, last_frame_retained = movie_exporter.preprocess(p1.sig1)
  75. data_to_01_mapper = movie_exporter.get_normalizer(preprocessed_data)
  76. static_frame = movie_exporter.border_annotations_adder.static_border_adder.get_static_frame(data_to_01_mapper)
  77. colorized_data = movie_exporter.colorize(preprocessed_data, data_to_01_mapper)
  78. finalized_frame_data_list = []
  79. for frame_number in range(first_frame_retained, last_frame_retained + 1):
  80. frame_data = colorized_data[:, :, frame_number - first_frame_retained, :]
  81. frame_data_with_rois = movie_exporter.add_rois(frame_data)
  82. rotated_frame_data = movie_exporter.rotate_frame(frame_data_with_rois)
  83. finalized_frame_data = movie_exporter.add_borders_annotations_to_frame(rotated_frame_data,
  84. frame_number,
  85. static_frame)
  86. finalized_frame_data_list.append(finalized_frame_data)
  87. logging.getLogger("VIEW").info(f"mv_individualScale set to:{flags['mv_individualScale']}. Minimum and maximum are: "
  88. f"{data_to_01_mapper.get_data_limits()}")
  89. op_filename = movie_exporter.write_to_file(finalized_frame_data_list, full_filename_without_extension)
  90. return op_filename