Example #1
0
def add_corrected_fluorescence_traces(nwbfile, corrected_fluorescence_traces):
    corrected_fluorescence_traces = corrected_fluorescence_traces.reset_index(
    ).set_index('cell_roi_id')[['corrected_fluorescence']]

    # Create/Add corrected_fluorescence_traces modules and interfaces:
    assert corrected_fluorescence_traces.index.name == 'cell_roi_id'
    twop_module = nwbfile.modules['two_photon_imaging']
    roi_table_region = nwbfile.modules['two_photon_imaging'].data_interfaces[
        'dff'].roi_response_series['traces'].rois
    ophys_timestamps = twop_module.get_data_interface(
        'dff').roi_response_series['traces'].timestamps
    f_interface = Fluorescence(name='corrected_fluorescence')
    twop_module.add_data_interface(f_interface)
    f_interface.create_roi_response_series(
        name='traces',
        data=np.array([
            corrected_fluorescence_traces.loc[cell_roi_id].
            corrected_fluorescence
            for cell_roi_id in corrected_fluorescence_traces.index.values
        ]),
        unit='NA',
        rois=roi_table_region,
        timestamps=ophys_timestamps)

    return nwbfile
Example #2
0
    def to_nwb(self, nwbfile: NWBFile) -> NWBFile:
        corrected_fluorescence_traces = self.value['corrected_fluorescence']

        # Convert from Series of lists to numpy array
        # of shape ROIs x timepoints
        traces = np.stack([x for x in corrected_fluorescence_traces])

        # Create/Add corrected_fluorescence_traces modules and interfaces:
        ophys_module = nwbfile.processing['ophys']

        roi_table_region = \
            nwbfile.processing['ophys'].data_interfaces[
                'dff'].roi_response_series[
                'traces'].rois  # noqa: E501
        ophys_timestamps = ophys_module.get_data_interface(
            'dff').roi_response_series['traces'].timestamps
        f_interface = Fluorescence(name='corrected_fluorescence')
        ophys_module.add_data_interface(f_interface)

        f_interface.create_roi_response_series(
            name='traces',
            data=traces.T,  # Should be stored as timepoints x rois
            unit='NA',
            rois=roi_table_region,
            timestamps=ophys_timestamps)
        return nwbfile
Example #3
0
def add_corrected_fluorescence_traces(nwbfile, corrected_fluorescence_traces):
    corrected_fluorescence_traces = \
        corrected_fluorescence_traces.reset_index().set_index(
                'cell_roi_id')[['corrected_fluorescence']]

    # Create/Add corrected_fluorescence_traces modules and interfaces:
    assert corrected_fluorescence_traces.index.name == 'cell_roi_id'
    ophys_module = nwbfile.processing['ophys']
    # trace data in the form of rois x timepoints
    f_trace_data = np.array([
        corrected_fluorescence_traces.loc[cell_roi_id].corrected_fluorescence
        for cell_roi_id in corrected_fluorescence_traces.index.values
    ])

    roi_table_region = nwbfile.processing['ophys'].data_interfaces[
        'dff'].roi_response_series['traces'].rois  # noqa: E501
    ophys_timestamps = ophys_module.get_data_interface(
        'dff').roi_response_series['traces'].timestamps
    f_interface = Fluorescence(name='corrected_fluorescence')
    ophys_module.add_data_interface(f_interface)

    f_interface.create_roi_response_series(
        name='traces',
        data=f_trace_data.T,  # Should be stored as timepoints x rois
        unit='NA',
        rois=roi_table_region,
        timestamps=ophys_timestamps)

    return nwbfile
Example #4
0
    def add_ophys_processed(self):
        """Add Fluorescence data"""
        imaging_plane = self._get_imaging_plane()
        with h5py.File(self.source_paths['path_processed'], 'r') as f:
            # Stores segmented data
            ophys_module = self.nwbfile.create_processing_module(
                name='ophys',
                description='contains optical physiology processed data')

            meta_imgseg = self.metadata['Ophys']['ImageSegmentation']
            img_seg = ImageSegmentation(name=meta_imgseg['name'])
            ophys_module.add(img_seg)

            meta_planeseg = meta_imgseg['plane_segmentations'][0]
            if meta_planeseg['reference_images'] in self.nwbfile.acquisition:
                reference_images = self.nwbfile.acquisition[
                    meta_planeseg['reference_images']]
            else:
                reference_images = None
            plane_segmentation = img_seg.create_plane_segmentation(
                name=meta_planeseg['name'],
                description=meta_planeseg['description'],
                imaging_plane=imaging_plane,
                reference_images=reference_images,
            )

            # ROIs
            n_rows = int(f['linesPerFrame'][0])
            n_cols = int(f['pixelsPerLine'][0][0])
            pixel_mask = []
            for pi in np.squeeze(f['pixel_list'][:]):
                row = int(pi // n_rows)
                col = int(pi % n_rows)
                pixel_mask.append([col, row, 1])
            plane_segmentation.add_roi(pixel_mask=pixel_mask)

            # Fluorescene data
            meta_fluorescence = self.metadata['Ophys']['Fluorescence']
            fl = Fluorescence(name=meta_fluorescence['name'])
            ophys_module.add(fl)

            with h5py.File(self.source_paths['path_calibration'], 'r') as fc:
                fluorescence_mean_trace = np.squeeze(fc['dff'])
                rt_region = plane_segmentation.create_roi_table_region(
                    description='unique cell ROI', region=[0])

                imaging_rate = 1 / np.array(fc['dto'])
                fl.create_roi_response_series(
                    name=meta_fluorescence['roi_response_series'][0]['name'],
                    data=fluorescence_mean_trace,
                    rois=rt_region,
                    rate=imaging_rate,
                    starting_time=0.,
                    unit='no unit')
Example #5
0
    def cicada_create_fluorescence(self):
        """   class pynwb.ophys.Fluorescence(roi_response_series={}, name='Fluorescence')
        """

        # Nom du module où récupérer les infos de métadonnée
        name_module = "fluorescence_"

        roi_response_series = {}

        self.fluorescence = Fluorescence(
            roi_response_series=roi_response_series, name="Fluorescence")

        self.mod.add_data_interface(self.fluorescence)
Example #6
0
def add_signals(module, expt, rt_region):

    fs = 1 / expt.frame_period()

    fluor = Fluorescence()
    sigs = expt.imagingData(dFOverF=None)
    fluor.create_roi_response_series(name='Fluorescence',
                                     data=sigs.squeeze(),
                                     rate=fs,
                                     unit='NA',
                                     rois=rt_region)

    module.add_data_interface(fluor)
Example #7
0
    def test_init(self):
        ip = CreatePlaneSegmentation()

        rt_region = ip.create_roi_table_region('the second ROI', region=[1])

        ts = RoiResponseSeries('test_ts', list(), rt_region, unit='unit', timestamps=list())

        ff = Fluorescence(ts)
        self.assertEqual(ff.roi_response_series['test_ts'], ts)
        self.assertEqual(ff.roi_response_series['test_ts'], ts)
Example #8
0
    def add_fluorescence_traces(self, roi_ids=None, region_label=None):
        if roi_ids is None:
            roi_ids = list(range(len(self.ps)))
            region_label = 'all ROIs'

        rt_region = self.ps.create_roi_table_region(region_label,
                                                    region=roi_ids)

        frame_rate = self.get_frame_rate()

        with File(self.from_path, 'r') as f:
            data = f['emAnalysisOutput/cellTraces'][:]

        fl = Fluorescence()
        self.ophys_mod.add_data_interface(fl)
        fl.create_roi_response_series('RoiResponseSeries',
                                      data,
                                      'lumens',
                                      rt_region,
                                      rate=frame_rate)
Example #9
0
    def test_init(self):
        ps = create_plane_segmentation()
        rt_region = ps.create_roi_table_region(description='the second ROI',
                                               region=[1])

        ts = RoiResponseSeries(name='test_ts',
                               data=[1, 2, 3],
                               rois=rt_region,
                               unit='unit',
                               timestamps=[0.1, 0.2, 0.3])

        ff = Fluorescence(ts)
        self.assertEqual(ff.roi_response_series['test_ts'], ts)
Example #10
0
    def test_init(self):
        ip = CreatePlaneSegmentation()
        iS = ImageSegmentation('test source', ip, name='test_iS')

        ts = RoiResponseSeries('test_ts',
                               'a hypothetical source',
                               list(),
                               'unit', ['name1'],
                               iS,
                               timestamps=list())

        ff = Fluorescence('test_ff', ts)
        self.assertEqual(ff.source, 'test_ff')
        self.assertEqual(ff.roi_response_series, ts)
Example #11
0
    def test_init(self):
        ip = CreatePlaneSegmentation()

        rt_region = ip.create_roi_table_region([1], 'the second ROI')

        ts = RoiResponseSeries('test_ts',
                               'a hypothetical source',
                               list(),
                               'unit',
                               rt_region,
                               timestamps=list())

        ff = Fluorescence('test_ff', ts)
        self.assertEqual(ff.source, 'test_ff')
        self.assertEqual(ff.roi_response_series['test_ts'], ts)
        self.assertEqual(ff.roi_response_series['test_ts'], ts)
Example #12
0
    def write_segmentation(
        segext_obj: SegmentationExtractor,
        save_path: PathType = None,
        plane_num=0,
        metadata: dict = None,
        overwrite: bool = True,
        buffer_size: int = 10,
        nwbfile=None,
    ):
        assert (
            save_path is None or nwbfile is None
        ), "Either pass a save_path location, or nwbfile object, but not both!"

        # parse metadata correctly:
        if isinstance(segext_obj, MultiSegmentationExtractor):
            segext_objs = segext_obj.segmentations
            if metadata is not None:
                assert isinstance(metadata, list), (
                    "For MultiSegmentationExtractor enter 'metadata' as a list of "
                    "SegmentationExtractor metadata")
                assert len(metadata) == len(segext_objs), (
                    "The 'metadata' argument should be a list with the same "
                    "number of elements as the segmentations in the "
                    "MultiSegmentationExtractor")
        else:
            segext_objs = [segext_obj]
            if metadata is not None and not isinstance(metadata, list):
                metadata = [metadata]
        metadata_base_list = [
            NwbSegmentationExtractor.get_nwb_metadata(sgobj)
            for sgobj in segext_objs
        ]
        print(f"writing nwb for {segext_obj.extractor_name}\n")
        # updating base metadata with new:
        for num, data in enumerate(metadata_base_list):
            metadata_input = metadata[num] if metadata else {}
            metadata_base_list[num] = dict_recursive_update(
                metadata_base_list[num], metadata_input)
        metadata_base_common = metadata_base_list[0]

        # build/retrieve nwbfile:
        if nwbfile is not None:
            assert isinstance(
                nwbfile, NWBFile), "'nwbfile' should be of type pynwb.NWBFile"
            write = False
        else:
            write = True
            save_path = Path(save_path)
            assert save_path.suffix == ".nwb"
            if save_path.is_file() and not overwrite:
                nwbfile_exist = True
                file_mode = "r+"
            else:
                if save_path.is_file():
                    os.remove(save_path)
                if not save_path.parent.is_dir():
                    save_path.parent.mkdir(parents=True)
                nwbfile_exist = False
                file_mode = "w"
            io = NWBHDF5IO(str(save_path), file_mode)
            if nwbfile_exist:
                nwbfile = io.read()
            else:
                nwbfile = NWBFile(**metadata_base_common["NWBFile"])

        # Subject:
        if metadata_base_common.get("Subject") and nwbfile.subject is None:
            nwbfile.subject = Subject(**metadata_base_common["Subject"])

        # Processing Module:
        if "ophys" not in nwbfile.processing:
            ophys = nwbfile.create_processing_module(
                "ophys", "contains optical physiology processed data")
        else:
            ophys = nwbfile.get_processing_module("ophys")

        for plane_no_loop, (segext_obj, metadata) in enumerate(
                zip(segext_objs, metadata_base_list)):
            # Device:
            if metadata["Ophys"]["Device"][0]["name"] not in nwbfile.devices:
                nwbfile.create_device(**metadata["Ophys"]["Device"][0])

            # ImageSegmentation:
            image_segmentation_name = (
                "ImageSegmentation" if plane_no_loop == 0 else
                f"ImageSegmentation_Plane{plane_no_loop}")
            if image_segmentation_name not in ophys.data_interfaces:
                image_segmentation = ImageSegmentation(
                    name=image_segmentation_name)
                ophys.add(image_segmentation)
            else:
                image_segmentation = ophys.data_interfaces.get(
                    image_segmentation_name)

            # OpticalChannel:
            optical_channels = [
                OpticalChannel(**i) for i in metadata["Ophys"]["ImagingPlane"]
                [0]["optical_channel"]
            ]

            # ImagingPlane:
            image_plane_name = ("ImagingPlane" if plane_no_loop == 0 else
                                f"ImagePlane_{plane_no_loop}")
            if image_plane_name not in nwbfile.imaging_planes.keys():
                input_kwargs = dict(
                    name=image_plane_name,
                    device=nwbfile.get_device(
                        metadata_base_common["Ophys"]["Device"][0]["name"]),
                )
                metadata["Ophys"]["ImagingPlane"][0][
                    "optical_channel"] = optical_channels
                input_kwargs.update(**metadata["Ophys"]["ImagingPlane"][0])
                if "imaging_rate" in input_kwargs:
                    input_kwargs["imaging_rate"] = float(
                        input_kwargs["imaging_rate"])
                imaging_plane = nwbfile.create_imaging_plane(**input_kwargs)
            else:
                imaging_plane = nwbfile.imaging_planes[image_plane_name]

            # PlaneSegmentation:
            input_kwargs = dict(
                description="output from segmenting imaging plane",
                imaging_plane=imaging_plane,
            )
            ps_metadata = metadata["Ophys"]["ImageSegmentation"][
                "plane_segmentations"][0]
            if ps_metadata[
                    "name"] not in image_segmentation.plane_segmentations:
                ps_exist = False
            else:
                ps = image_segmentation.get_plane_segmentation(
                    ps_metadata["name"])
                ps_exist = True

            roi_ids = segext_obj.get_roi_ids()
            accepted_list = segext_obj.get_accepted_list()
            accepted_list = [] if accepted_list is None else accepted_list
            rejected_list = segext_obj.get_rejected_list()
            rejected_list = [] if rejected_list is None else rejected_list
            accepted_ids = [1 if k in accepted_list else 0 for k in roi_ids]
            rejected_ids = [1 if k in rejected_list else 0 for k in roi_ids]
            roi_locations = np.array(segext_obj.get_roi_locations()).T

            def image_mask_iterator():
                for id in segext_obj.get_roi_ids():
                    img_msks = segext_obj.get_roi_image_masks(
                        roi_ids=[id]).T.squeeze()
                    yield img_msks

            if not ps_exist:
                input_kwargs.update(
                    **ps_metadata,
                    columns=[
                        VectorData(
                            data=H5DataIO(
                                DataChunkIterator(image_mask_iterator(),
                                                  buffer_size=buffer_size),
                                compression=True,
                                compression_opts=9,
                            ),
                            name="image_mask",
                            description="image masks",
                        ),
                        VectorData(
                            data=roi_locations,
                            name="RoiCentroid",
                            description=
                            "x,y location of centroid of the roi in image_mask",
                        ),
                        VectorData(
                            data=accepted_ids,
                            name="Accepted",
                            description=
                            "1 if ROi was accepted or 0 if rejected as a cell during segmentation operation",
                        ),
                        VectorData(
                            data=rejected_ids,
                            name="Rejected",
                            description=
                            "1 if ROi was rejected or 0 if accepted as a cell during segmentation operation",
                        ),
                    ],
                    id=roi_ids,
                )

                ps = image_segmentation.create_plane_segmentation(
                    **input_kwargs)

            # Fluorescence Traces:
            if "Flourescence" not in ophys.data_interfaces:
                fluorescence = Fluorescence()
                ophys.add(fluorescence)
            else:
                fluorescence = ophys.data_interfaces["Fluorescence"]
            roi_response_dict = segext_obj.get_traces_dict()
            roi_table_region = ps.create_roi_table_region(
                description=f"region for Imaging plane{plane_no_loop}",
                region=list(range(segext_obj.get_num_rois())),
            )
            rate = (np.float("NaN")
                    if segext_obj.get_sampling_frequency() is None else
                    segext_obj.get_sampling_frequency())
            for i, j in roi_response_dict.items():
                data = getattr(segext_obj, f"_roi_response_{i}")
                if data is not None:
                    data = np.asarray(data)
                    trace_name = "RoiResponseSeries" if i == "raw" else i.capitalize(
                    )
                    trace_name = (trace_name if plane_no_loop == 0 else
                                  trace_name + f"_Plane{plane_no_loop}")
                    input_kwargs = dict(
                        name=trace_name,
                        data=data.T,
                        rois=roi_table_region,
                        rate=rate,
                        unit="n.a.",
                    )
                    if trace_name not in fluorescence.roi_response_series:
                        fluorescence.create_roi_response_series(**input_kwargs)

            # create Two Photon Series:
            if "TwoPhotonSeries" not in nwbfile.acquisition:
                warn(
                    "could not find TwoPhotonSeries, using ImagingExtractor to create an nwbfile"
                )

            # adding images:
            images_dict = segext_obj.get_images_dict()
            if any([image is not None for image in images_dict.values()]):
                images_name = ("SegmentationImages" if plane_no_loop == 0 else
                               f"SegmentationImages_Plane{plane_no_loop}")
                if images_name not in ophys.data_interfaces:
                    images = Images(images_name)
                    for img_name, img_no in images_dict.items():
                        if img_no is not None:
                            images.add_image(
                                GrayscaleImage(name=img_name, data=img_no.T))
                    ophys.add(images)

            # saving NWB file:
            if write:
                io.write(nwbfile)
                io.close()
                # test read
                with NWBHDF5IO(str(save_path), "r") as io:
                    io.read()
Example #13
0
class Preprocessing:
    def load_yaml(self):
        # Open YAML file with metadata if existing then dump all data in a dict
        if os.path.isfile("data.yaml"):
            with open("data.yaml", 'r') as stream:
                self.data = yaml.safe_load(stream)
        # Same but with .yml extension
        elif os.path.isfile("data.yml"):
            with open("data.yml", 'r') as stream:
                self.data = yaml.safe_load(stream)
        else:
            self.data = dict()
        if self.data is None:
            self.data = dict()
        # Dump the dict in the YAML file to save what the user inputted for future use
        with open('data.yaml', 'w') as outfile:
            yaml.dump(self.data,
                      outfile,
                      default_flow_style=False,
                      allow_unicode=True)

    def add_required_metadata(self, data, key, metadata_type):
        # Prompt user to give required metadata
        # Need to be wary of the type (put " " for string and datetime.datetime(%Y, %m, %d) for datetime)
        print("Missing required " + metadata_type + " metadata : " + key +
              "\n")
        metadata_value = input("Type the value (with respect of the type) : ")
        data[key] = eval(metadata_value)
        # Dump the dict in the YAML file to save what the user inputted for future use
        with open('data.yaml', 'w') as outfile:
            yaml.dump(self.data,
                      outfile,
                      default_flow_style=False,
                      allow_unicode=True)
        return data

    def add_optional_metadata(self, data):
        # Allow user to add as much metadata as he wants with the key he wants
        # Need to refer to documentation if he wants to fill existing attributes but he can create new ones and use
        # them in his own code
        keyboard_input = False
        while not keyboard_input:
            # Prompt user to give optional metadata
            # Need to be wary of the type (put " " for string and datetime.datetime(%Y, %m, %d) for datetime)
            metadata_key = input(
                "Type the name of the metadata you want to add ? ")
            metadata_key.replace(" ", "").lower().replace("", "_")
            metadata_value = input(
                "Type the value (with respect of the type) : ")
            data[metadata_key] = eval(metadata_value)
            go = input("Continue ? (yes/no)")
            # Prevent errors if other input than yes/np
            while go.replace(" ", "").lower() != "no" and go.replace(
                    " ", "").lower() != "yes":
                go = input("Continue ? (yes/no)")
            if go.replace(" ", "").lower() == "no":
                keyboard_input = True
            # Dump the dict in the YAML file to save what the user inputted for future use
            with open('data.yaml', 'w') as outfile:
                yaml.dump(self.data,
                          outfile,
                          default_flow_style=False,
                          allow_unicode=True)
        return data

    def ophys_metadata_acquisition(self):

        # TODO: Peut être faire un dictionnaire de sous-dictionnaires correspondant à chaque classe à remplir
        #         Points positifs : Plus grand lisibilité dans le YAML, gestion simple des ambiguités de nom
        #         tout en gardant la notation de NWB.
        #         Points négatifs : Plus dur à rentrer en input pour l'utilisateur (il faut lui demander à quelle classe
        #         correspond sa valeur).

        # List of the required metadata

        # TODO : maybe better implementation is possible ?

        required_metadata = [
            "session_description", "identifier", "session_start_time"
        ]

        if self.data.get('ophys_metadata') is None:
            self.data['ophys_metadata'] = dict()
            for i in required_metadata:
                self.data["ophys_metadata"] = self.add_required_metadata(
                    self.data["ophys_metadata"], i, "ophys")
        else:
            # Check if YAML file doesn't have all the required attributes and ask them the missing ones
            metadata_to_add = list(
                set(required_metadata) -
                set(list(self.data['ophys_metadata'].keys())))
            for i in metadata_to_add:
                self.data["ophys_metadata"] = self.add_required_metadata(
                    self.data["ophys_metadata"], i, "ophys")

        print("Found ophys metadata : " +
              str(list(self.data['ophys_metadata'].keys())))
        add_metadata = input(
            "Do you want to add more ophys metadata ? (yes/no) ")
        # Prevent errors if other input than yes/np
        while add_metadata.replace(
                " ", "").lower() != "no" and add_metadata.replace(
                    " ", "").lower() != "yes":
            add_metadata = input(
                "Do you want to add more ophys metadata ? (yes/no) ")
        if add_metadata.replace(" ", "").lower() == "yes":
            self.data["ophys_metadata"] = self.add_optional_metadata(
                self.data["ophys_metadata"])

        # Create new NWB file with all known attributes
        self.nwbfile = NWBFile(
            session_description=self.data['ophys_metadata'].get(
                "session_description"),
            identifier=self.data['ophys_metadata'].get("identifier"),
            session_start_time=self.data['ophys_metadata'].get(
                "session_start_time"),
            file_create_date=self.data['ophys_metadata'].get(
                "file_create_date"),
            timestamps_reference_time=self.data['ophys_metadata'].get(
                "timestamps_reference_time"),
            experimenter=self.data['ophys_metadata'].get("experimenter"),
            experiment_description=self.data['ophys_metadata'].get(
                "experiment_description"),
            session_id=self.data['ophys_metadata'].get("session_id"),
            institution=self.data['ophys_metadata'].get("institution"),
            keywords=self.data['ophys_metadata'].get("keywords"),
            notes=self.data['ophys_metadata'].get("notes"),
            pharmacology=self.data['ophys_metadata'].get("pharmacology"),
            protocol=self.data['ophys_metadata'].get("protocol"),
            related_publications=self.data['ophys_metadata'].get(
                "related_publications"),
            slices=self.data['ophys_metadata'].get("slices"),
            source_script=self.data['ophys_metadata'].get("source_script"),
            source_script_file_name=self.data['ophys_metadata'].get(
                "source_script_file_name"),
            data_collection=self.data['ophys_metadata'].get(
                "self.data['ophys_metadata']_collection"),
            surgery=self.data['ophys_metadata'].get("surgery"),
            virus=self.data['ophys_metadata'].get("virus"),
            stimulus_notes=self.data['ophys_metadata'].get("stimulus_notes"),
            lab=self.data['ophys_metadata'].get("lab"),
            subject=self.subject)

    def subject_metadata_acquisition(self):
        # Check if metadata about the subject exists and prompt the user if he wants to add some
        if self.data.get('subject_metadata') is None:
            print("No subject metadata found \n ")
            self.data['subject_metadata'] = dict()
        elif len(self.data['subject_metadata']) == 0:
            print("No subject metadata found \n ")
        else:
            print("Found subject metadata : " +
                  str(list(self.data['subject_metadata'].keys())))
        add_metadata = input(
            "Do you want to add more subject metadata ? (yes/no) ")
        # Prevent errors if other input than yes/np
        while add_metadata.replace(
                " ", "").lower() != "no" and add_metadata.replace(
                    " ", "").lower() != "yes":
            add_metadata = input(
                "Do you want to add more subject metadata ? (yes/no) ")
        if add_metadata.replace(" ", "").lower() == "yes":
            self.data['subject_metadata'] = self.add_optional_metadata(
                self.data['subject_metadata'])

        self.subject = Subject(
            age=self.data['subject_metadata'].get("age"),
            description=self.data['subject_metadata'].get("description"),
            genotype=self.data['subject_metadata'].get("genotype"),
            sex=self.data['subject_metadata'].get("sex"),
            species=self.data['subject_metadata'].get("species"),
            subject_id=self.data['subject_metadata'].get("subject_id"),
            weight=self.data['subject_metadata'].get("weight"),
            date_of_birth=self.data['subject_metadata'].get("date_of_birth"))

    def cicada_create_device(self):
        """
        class pynwb.device.Device(name, parent=None)
        """
        required_metadata = ["device_name"]

        metadata_to_add = list(
            set(required_metadata) -
            set(list(self.data['ophys_metadata'].keys())))
        for i in metadata_to_add:
            self.data["ophys_metadata"] = self.add_required_metadata(
                self.data["ophys_metadata"], i, "ophys")

        self.device = Device(
            name=self.data['ophys_metadata'].get("device_name"))

        self.nwbfile.add_device(self.device)

    def cicada_create_optical_channel(self):
        required_metadata = [
            "optical_channel_name", "optical_channel_description",
            "optical_channel_emission_lambda"
        ]

        metadata_to_add = list(
            set(required_metadata) -
            set(list(self.data['ophys_metadata'].keys())))
        for i in metadata_to_add:
            self.data["ophys_metadata"] = self.add_required_metadata(
                self.data["ophys_metadata"], i, "ophys")

        self.optical_channel = OpticalChannel(
            name=self.data['ophys_metadata'].get("optical_channel_name"),
            description=self.data['ophys_metadata'].get(
                "optical_channel_description"),
            emission_lambda=self.data['ophys_metadata'].get(
                "optical_channel_emission_lambda"))

    def cicada_create_module(self):

        required_metadata = [
            "processing_module_name", "processing_module_description"
        ]

        metadata_to_add = list(
            set(required_metadata) -
            set(list(self.data['ophys_metadata'].keys())))
        for i in metadata_to_add:
            self.data["ophys_metadata"] = self.add_required_metadata(
                self.data["ophys_metadata"], i, "ophys")

        self.mod = self.nwbfile.create_processing_module(
            name=self.data['ophys_metadata'].get("processing_module_name"),
            description=self.data['ophys_metadata'].get(
                "processing_module_description"))

    def cicada_create_imaging_plane(self):
        """ class pynwb.ophys.ImagingPlane(name, optical_channel, description, device, excitation_lambda,
            imaging_rate, indicator, location,
            manifold=None, conversion=None, unit=None, reference_frame=None, parent=None)
        """

        required_metadata = [
            "imaging_plane_name", "imaging_plane_description",
            "imaging_plane_excitation_lambda", "imaging_plane_imaging_rate",
            "imaging_plane_indicator", "imaging_plane_location"
        ]
        metadata_to_add = list(
            set(required_metadata) -
            set(list(self.data['ophys_metadata'].keys())))
        for i in metadata_to_add:
            self.data["ophys_metadata"] = self.add_required_metadata(
                self.data["ophys_metadata"], i, "ophys")
        # Nom du module où récupérer les infos de métadonnée
        name_module = "imaging_plane_"

        self.imaging_plane = self.nwbfile.create_imaging_plane(
            name=self.data['ophys_metadata'].get(name_module + "name"),
            optical_channel=self.optical_channel,
            description=self.data['ophys_metadata'].get(name_module +
                                                        "description"),
            device=self.device,
            excitation_lambda=self.data['ophys_metadata'].get(
                name_module + "excitation_lambda"),
            imaging_rate=self.data['ophys_metadata'].get(name_module +
                                                         "imaging_rate"),
            indicator=self.data['ophys_metadata'].get(name_module +
                                                      "indicator"),
            location=self.data['ophys_metadata'].get(name_module + "location"),
            manifold=self.data['ophys_metadata'].get(name_module + "manifold"),
            conversion=self.data['ophys_metadata'].get(name_module +
                                                       "conversion"),
            unit=self.data['ophys_metadata'].get(name_module + "unit"),
            reference_frame=self.data['ophys_metadata'].get(name_module +
                                                            "reference_frame"))

    def cicada_create_two_photon_series(self,
                                        data_to_store=None,
                                        external_file=None):
        """ class pynwb.ophys.TwoPhotonSeries(name, imaging_plane,
            data=None, unit=None, format=None, field_of_view=None, pmt_gain=None, scan_line_rate=None,
            external_file=None, starting_frame=None, bits_per_pixel=None, dimension=[nan], resolution=0.0,
            conversion=1.0, timestamps=None, starting_time=None, rate=None, comments='no comments',
            description='no description', control=None, control_description=None, parent=None)
        """

        required_metadata = ["two_photon_name"]
        metadata_to_add = list(
            set(required_metadata) -
            set(list(self.data['ophys_metadata'].keys())))
        for i in metadata_to_add:
            self.data["ophys_metadata"] = self.add_required_metadata(
                self.data["ophys_metadata"], i, "ophys")
        # Nom du module où récupérer les infos de métadonnée
        name_module = "two_photon_"

        self.movie_two_photon = TwoPhotonSeries(
            name=self.data['ophys_metadata'].get(name_module + "name"),
            imaging_plane=self.imaging_plane,
            data=data_to_store,
            unit=self.data['ophys_metadata'].get(name_module + "unit"),
            format=self.data['ophys_metadata'].get(name_module + "format"),
            field_of_view=self.data['ophys_metadata'].get(name_module +
                                                          "field_of_view"),
            pmt_gain=self.data['ophys_metadata'].get(name_module + "pmt_gain"),
            scan_line_rate=self.data['ophys_metadata'].get(name_module +
                                                           "scan_line_rate"),
            external_file=external_file,
            starting_frame=self.data['ophys_metadata'].get(name_module +
                                                           "starting_frame"),
            bits_per_pixel=self.data['ophys_metadata'].get(name_module +
                                                           "bits_per_pixel"),
            dimension=data_to_store.shape[1:],
            resolution=0.0,
            conversion=1.0,
            timestamps=self.data['ophys_metadata'].get(name_module +
                                                       "timestamps"),
            starting_time=self.data['ophys_metadata'].get(name_module +
                                                          "starting_time"),
            rate=1.0,
            comments="no comments",
            description="no description",
            control=self.data['ophys_metadata'].get(name_module + "control"),
            control_description=self.data['ophys_metadata'].get(
                name_module + "control_description"),
            parent=self.data['ophys_metadata'].get(name_module + "parent"))

        self.nwbfile.add_acquisition(self.movie_two_photon)

    def cicada_create_motion_correction(self):
        """  class pynwb.ophys.MotionCorrection(corrected_images_stacks={}, name='MotionCorrection')
        """

        # Nom du module où récupérer les infos de métadonnée
        name_module = "motion_correction_"

        corrected_images_stacks = {}

        self.motion_correction = MotionCorrection(
            corrected_images_stacks=corrected_images_stacks,
            name="MotionCorrection")

        self.mod.add_data_interface(self.motion_correction)

    def cicada_add_corrected_image_stack(self,
                                         corrected=None,
                                         original=None,
                                         xy_translation=None):
        """ class pynwb.ophys.CorrectedImageStack(corrected, original, xy_translation, name='CorrectedImageStack')
        """

        # Nom du module où récupérer les infos de métadonnée
        name_module = "corrected_image_stack_"

        self.corrected_image_stack = CorrectedImageStack(
            corrected=corrected,
            original=original,
            xy_translation=xy_translation,
            name="CorrectedImageStack")

        self.motion_correction.add_corrected_image_stack(
            self.corrected_image_stack)

    def cicada_add_plane_segmentation(self):
        """ class pynwb.ophys.PlaneSegmentation(description, imaging_plane,
            name=None, reference_images=None, id=None, columns=None, colnames=None)
        """

        required_metadata = ["plane_segmentation_description"]
        metadata_to_add = list(
            set(required_metadata) -
            set(list(self.data['ophys_metadata'].keys())))
        for i in metadata_to_add:
            self.data["ophys_metadata"] = self.add_required_metadata(
                self.data["ophys_metadata"], i, "ophys")

        # Nom du module où récupérer les infos de métadonnée
        name_module = "plane_segmentation_"

        self.plane_segmentation = PlaneSegmentation(
            description=self.data['ophys_metadata'].get(name_module +
                                                        "description"),
            imaging_plane=self.imaging_plane,
            name=self.data['ophys_metadata'].get(name_module + "name"),
            reference_images=self.data['ophys_metadata'].get(
                name_module + "reference_image"),
            id=self.data['ophys_metadata'].get(name_module + "id"),
            columns=self.data['ophys_metadata'].get(name_module + "columns"),
            colnames=self.data['ophys_metadata'].get(name_module + "colnames"))

        self.image_segmentation.add_plane_segmentation(self.plane_segmentation)

    def cicada_add_roi_in_plane_segmentation(self,
                                             pixel_mask=None,
                                             voxel_mask=None,
                                             image_mask=None,
                                             id_roi=None):
        """add_roi(pixel_mask=None, voxel_mask=None, image_mask=None, id=None)
        """

        self.plane_segmentation.add_roi(pixel_mask=pixel_mask,
                                        voxel_mask=voxel_mask,
                                        image_mask=image_mask,
                                        id=id_roi)

    def cicada_create_roi_table_region_in_plane_segmentation(
        self, region=slice(None, None, None)):
        """create_roi_table_region(description, region=slice(None, None, None), name='rois')"""

        required_metadata = ["roi_table_region_description"]
        metadata_to_add = list(
            set(required_metadata) -
            set(list(self.data['ophys_metadata'].keys())))
        for i in metadata_to_add:
            self.data["ophys_metadata"] = self.add_required_metadata(
                self.data["ophys_metadata"], i, "ophys")

        # Nom du module où récupérer les infos de métadonnée
        name_module = "roi_table_region_"

        self.table_region = self.plane_segmentation.create_roi_table_region(
            description=self.data['ophys_metadata'].get(name_module +
                                                        "description"),
            region=region,
            name="rois")

    def cicada_create_image_segmentation(self):
        """  class pynwb.ophys.ImageSegmentation(plane_segmentations={}, name='ImageSegmentation')
        """

        # Nom du module où récupérer les infos de métadonnée
        name_module = "image_segmentation_"

        plane_segmentations = {}

        self.image_segmentation = ImageSegmentation(
            plane_segmentations=plane_segmentations, name="ImageSegmentation")

        self.mod.add_data_interface(self.image_segmentation)

    def cicada_create_fluorescence(self):
        """   class pynwb.ophys.Fluorescence(roi_response_series={}, name='Fluorescence')
        """

        # Nom du module où récupérer les infos de métadonnée
        name_module = "fluorescence_"

        roi_response_series = {}

        self.fluorescence = Fluorescence(
            roi_response_series=roi_response_series, name="Fluorescence")

        self.mod.add_data_interface(self.fluorescence)

    def cicada_create_DfOverF(self):
        """   class pynwb.ophys.DfOverF(roi_response_series={}, name='DfOverF')
        """

        # Nom du module où récupérer les infos de métadonnée
        name_module = "DfOverF_"

        roi_response_series = {}

        self.DfOverF = DfOverF(roi_response_series=roi_response_series,
                               name="DfOverF")

        self.mod.add_data_interface(self.DfOverF)

    def cicada_add_roi_response_series(self,
                                       module,
                                       traces_data=None,
                                       rois=None):
        """  class pynwb.ophys.RoiResponseSeries(name, data, unit, rois,
             resolution=0.0, conversion=1.0, timestamps=None, starting_time=None, rate=None, comments='no comments',
             description='no description', control=None, control_description=None, parent=None)
        """

        required_metadata = [
            "roi_response_series_name", "roi_response_series_unit"
        ]
        metadata_to_add = list(
            set(required_metadata) -
            set(list(self.data['ophys_metadata'].keys())))
        for i in metadata_to_add:
            self.data["ophys_metadata"] = self.add_required_metadata(
                self.data["ophys_metadata"], i, "ophys")

        # Nom du module où récupérer les infos de métadonnée
        name_module = "roi_response_series_"

        roi_response_series = RoiResponseSeries(
            name=self.data['ophys_metadata'].get(name_module + "name"),
            data=traces_data,
            unit=self.data['ophys_metadata'].get(name_module + "unit"),
            rois=self.table_region,
            resolution=0.0,
            conversion=1.0,
            timestamps=self.data['ophys_metadata'].get(name_module +
                                                       "timestamp"),
            starting_time=self.data['ophys_metadata'].get(name_module +
                                                          "starting_time"),
            rate=1.0,
            comments="no comments",
            description="no description",
            control=self.data['ophys_metadata'].get(name_module + "control"),
            control_description=self.data['ophys_metadata'].get(
                name_module + "control_description"),
            parent=self.data['ophys_metadata'].get(name_module + "parent"))

        if module == "DfOverF":
            self.DfOverF.add_roi_response_series(roi_response_series)
        elif module == "fluorescence":
            self.fluorescence.add_roi_response_series(roi_response_series)
        else:
            print(
                f"erreur : le nom du module doit être 'DfOverF' ou 'fluorescence', et non {module} !"
            )

    def find_roi(self):

        # Chemin du dossier suite2p
        data_path = "C:/Users/François/Documents/dossier François/Stage INMED/" \
                    "Programmes/Godly Ultimate Interface/NWB/exp2nwb-master/src/suite2p"
        self.suite2p_data = dict()

        # Ouverture des fichiers stat et is_cell
        f = np.load(data_path + "/F.npy", allow_pickle=True)
        self.suite2p_data["F"] = f
        f_neu = np.load(data_path + "/Fneu.npy", allow_pickle=True)
        self.suite2p_data["Fneu"] = f_neu
        spks = np.load(data_path + "/spks.npy", allow_pickle=True)
        self.suite2p_data["spks"] = spks
        stat = np.load(data_path + "/stat.npy", allow_pickle=True)
        self.suite2p_data["stat"] = stat
        is_cell = np.load(data_path + "/iscell.npy", allow_pickle=True)
        self.suite2p_data["is_cell"] = is_cell

        # Trouve les coordonnées de chaque ROI (cellule ici)
        coord = []
        for cell in np.arange(len(stat)):
            if is_cell[cell][0] == 0:
                continue
            print(is_cell[cell][0])
            list_points_coord = [
                (x, y, 1)
                for x, y in zip(stat[cell]["xpix"], stat[cell]["ypix"])
            ]
            # coord.append(np.array(list_points_coord).transpose())

            # La suite permet d'avoir uniquement les contours (sans les pixels intérieurs)
            """
            # ATTENTION ! Il faut : from shapely.geometry import MultiPoint, LineString
            convex_hull = MultiPoint(list_points_coord).convex_hull
            if isinstance(convex_hull, LineString):
                coord_shapely = MultiPoint(list_points_coord).convex_hull.coords
            else:
                coord_shapely = MultiPoint(list_points_coord).convex_hull.exterior.coords
            coord.append(np.array(coord_shapely).transpose())
            """

        self.suite2p_data[
            "coord"] = coord  # Contient la liste des pixels inclus dans chaque ROI
Example #14
0
    def setUp(self):

        nwbfile = NWBFile(
            'my first synthetic recording',
            'EXAMPLE_ID',
            datetime.now(tzlocal()),
            experimenter='Dr. Bilbo Baggins',
            lab='Bag End Laboratory',
            institution='University of Middle Earth at the Shire',
            experiment_description=('I went on an adventure with thirteen '
                                    'dwarves to reclaim vast treasures.'),
            session_id='LONELYMTN')

        device = Device('imaging_device_1')
        nwbfile.add_device(device)
        optical_channel = OpticalChannel('my_optchan', 'description', 500.)
        imaging_plane = nwbfile.create_imaging_plane(
            'my_imgpln', optical_channel,
            'a very interesting part of the brain',
            device, 600., 300., 'GFP', 'my favorite brain location',
            np.ones((5, 5, 3)), 4.0, 'manifold unit', 'A frame to refer to')

        self.image_series = TwoPhotonSeries(name='test_iS',
                                            dimension=[2],
                                            data=np.random.rand(10, 5, 5, 3),
                                            external_file=['images.tiff'],
                                            imaging_plane=imaging_plane,
                                            starting_frame=[0],
                                            format='tiff',
                                            starting_time=0.0,
                                            rate=1.0)
        nwbfile.add_acquisition(self.image_series)

        mod = nwbfile.create_processing_module(
            'ophys', 'contains optical physiology processed data')
        img_seg = ImageSegmentation()
        mod.add(img_seg)
        ps = img_seg.create_plane_segmentation(
            'output from segmenting my favorite imaging plane', imaging_plane,
            'my_planeseg', self.image_series)

        w, h = 3, 3
        pix_mask1 = [(0, 0, 1.1), (1, 1, 1.2), (2, 2, 1.3)]
        vox_mask1 = [(0, 0, 0, 1.1), (1, 1, 1, 1.2), (2, 2, 2, 1.3)]
        img_mask1 = [[0.0 for x in range(w)] for y in range(h)]
        img_mask1[0][0] = 1.1
        img_mask1[1][1] = 1.2
        img_mask1[2][2] = 1.3
        ps.add_roi(pixel_mask=pix_mask1,
                   image_mask=img_mask1,
                   voxel_mask=vox_mask1)

        pix_mask2 = [(0, 0, 2.1), (1, 1, 2.2)]
        vox_mask2 = [(0, 0, 0, 2.1), (1, 1, 1, 2.2)]
        img_mask2 = [[0.0 for x in range(w)] for y in range(h)]
        img_mask2[0][0] = 2.1
        img_mask2[1][1] = 2.2
        ps.add_roi(pixel_mask=pix_mask2,
                   image_mask=img_mask2,
                   voxel_mask=vox_mask2)

        fl = Fluorescence()
        mod.add(fl)

        rt_region = ps.create_roi_table_region('the first of two ROIs',
                                               region=[0])

        data = np.array([0., 1., 2., 3., 4., 5., 6., 7., 8.,
                         9.]).reshape(10, 1)
        timestamps = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
        rrs = fl.create_roi_response_series('my_rrs',
                                            data,
                                            rt_region,
                                            unit='lumens',
                                            timestamps=timestamps)

        self.df_over_f = DfOverF(rrs)
Example #15
0
img_mask2[1][1] = 2.2
ps.add_roi(pixel_mask=pix_mask2, image_mask=img_mask2)

####################
# Storing fluorescence measurements
# ---------------------------------
#
# Now that ROIs are stored, you can store fluorescence (or dF/F [#]_) data for these regions of interest.
# This type of data is stored using the :py:class:`~pynwb.ophys.RoiResponseSeries` class. You will not need
# to instantiate this class directly to create objects of this type, but it is worth noting that this is the
# class you will work with after you read data back in.
#
#
# First, create a data interface to store this data in

fl = Fluorescence()
mod.add_data_interface(fl)

####################
# Because this data stores information about specific ROIs, you will need to provide a reference to the ROIs
# that you will be storing data for. This is done using a :py:class:`~pynwb.ophys.ROITableRegion`, which can be
# created with :py:func:`~pynwb.ophys.PlaneSegmentation.create_roi_table_region`.

rt_region = ps.create_roi_table_region('the first of two ROIs', region=[0])

####################
# Now that you have an :py:class:`~pynwb.ophys.ROITableRegion`, you can create your an
# :py:class:`~pynwb.ophys.RoiResponseSeries`.

data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
timestamps = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
Example #16
0

####################
# Storing fluorescence measurements
# ---------------------------------
#
# Now that ROIs are stored, you can store fluorescence (or dF/F [#]_) data for these regions of interest.
# This type of data is stored using the :py:class:`~pynwb.ophys.RoiResponseSeries` class. You will not need
# to instantiate this class directly to create objects of this type, but it is worth noting that this is the
# class you will work with after you read data back in.
#
#
# First, create a data interface to store this data in


fl = Fluorescence('Ca2+ imaging example')
mod.add_data_interface(fl)


####################
# Because this data stores information about specific ROIs, you will need to provide a reference to the ROIs
# that you will be storing data for. This is done using a :py:class:`~pynwb.ophys.ROITableRegion`, which can be
# created with :py:func:`~pynwb.ophys.PlaneSegmentation.create_roi_table_region`.


rt_region = ps.create_roi_table_region('the first of two ROIs', region=[0])

####################
# Alternatively, you can get create a region using the names of the ROIs you added by passing in
# the ROI names with the *names* argument. We will create the same region we did above, but
# by using the name of the ROI.
Example #17
0
    def convert(self, **kwargs):
        """Convert the data and add to the nwb_file

        Args:
            **kwargs: arbitrary arguments
        """

        super().convert(**kwargs)
        if "suite2p_dir" not in kwargs:
            raise Exception(
                f"'suite2p_dir' argument should be pass to convert "
                f"function in class {self.__class__.__name__}")
        suite2p_dir = kwargs["suite2p_dir"]

        # looking for the motion_corrected_ci_movie, return None if it doesn't exists
        # TODO: take in consideration the movie is not available
        #  then don't construct image mask and don't build raw-traces, use F.npy is available
        image_series = self.nwb_file.acquisition.get(
            "motion_corrected_ci_movie")

        mod = self.nwb_file.create_processing_module(
            'ophys', 'contains optical physiology processed data')
        img_seg = ImageSegmentation(name="segmentation_suite2p")
        mod.add_data_interface(img_seg)
        imaging_plane = self.nwb_file.get_imaging_plane("my_imgpln")
        # description, imaging_plane, name=None
        ps = img_seg.create_plane_segmentation(
            description='output from segmenting',
            imaging_plane=imaging_plane,
            name='my_plane_seg',
            reference_images=image_series)

        stat = np.load(os.path.join(suite2p_dir, "stat.npy"),
                       allow_pickle=True)
        is_cell = np.load(os.path.join(suite2p_dir, "iscell.npy"),
                          allow_pickle=True)
        # TODO: load f.npy for raw_traces if available

        if image_series.format == "tiff":
            dim_y, dim_x = image_series.data.shape[1:]
            n_frames = image_series.data.shape[0]
            print(f"dim_y, dim_x: {image_series.data.shape[1:]}")
        elif image_series.format == "external":
            im = PIL.Image.open(image_series.external_file[0])
            n_frames = len(list(ImageSequence.Iterator(im)))
            dim_y, dim_x = np.array(im).shape
            print(f"dim_y, dim_x: {np.array(im).shape}")
        else:
            raise Exception(
                f"Format of calcium movie imaging {image_series.format} not yet implemented"
            )

        n_cells = 0
        # Add rois
        for cell in np.arange(len(stat)):
            if is_cell[cell][0] == 0:
                continue
            n_cells += 1
            pix_mask = [(y, x, 1)
                        for x, y in zip(stat[cell]["xpix"], stat[cell]["ypix"])
                        ]
            image_mask = np.zeros((dim_y, dim_x))
            for pix in pix_mask:
                image_mask[pix[0], pix[1]] = pix[2]
            # we can id to identify the cell (int) otherwise it will be incremented at each step
            ps.add_roi(pixel_mask=pix_mask, image_mask=image_mask)

        fl = Fluorescence(name="fluorescence_suite2p")
        mod.add_data_interface(fl)

        rt_region = ps.create_roi_table_region('all cells',
                                               region=list(np.arange(n_cells)))
        if format == "external":
            if image_series.external_file[0].endswith(".tiff") or \
                    image_series.external_file[0].endswith(".tif"):
                # TODO: fix this bug, so far external loading, taking in consideration frames_to_add is not possible
                #  either copy the code from ConvertCiMovieToNWB reconstructing frames_to_add from intervals
                #  or find another solution. Another solution would be to put on the yaml as argument
                #  frames_to_add but using the attribute from the ConvertMovie instance. s
                ci_movie = ConvertCiMovieToNWB.load_tiff_movie_in_memory(
                    image_series.external_file[0])
            else:
                raise Exception(
                    f"Calcium imaging format not supported yet {image_series.external_file[0]}"
                )
        else:
            ci_movie = image_series.data
        # TODO: if movie is external, see to load it
        if ci_movie:
            raw_traces = np.zeros((n_cells, ci_movie.shape[0]))
            for cell in np.arange(n_cells):
                img_mask = ps['image_mask'][cell]
                img_mask = img_mask.astype(bool)
                raw_traces[cell, :] = np.mean(ci_movie[:, img_mask], axis=1)
            rrs = fl.create_roi_response_series(name='raw_traces',
                                                data=raw_traces,
                                                unit='lumens',
                                                rois=rt_region,
                                                timestamps=np.arange(n_frames),
                                                description="raw traces")
Example #18
0
def add_ophys_processing_from_suite2p(save_folder,
                                      nwbfile,
                                      CaImaging_timestamps,
                                      device=None,
                                      optical_channel=None,
                                      imaging_plane=None,
                                      image_series=None):
    """ 
    adapted from suite2p/suite2p/io/nwb.py "save_nwb" function
    """

    plane_folders = natsorted([
        f.path for f in os.scandir(save_folder)
        if f.is_dir() and f.name[:5] == 'plane'
    ])
    ops1 = [
        np.load(os.path.join(f, 'ops.npy'), allow_pickle=True).item()
        for f in plane_folders
    ]
    if len(ops1) > 1:
        multiplane = True
    else:
        multiplane = False

    ops = ops1[0]

    if device is None:
        device = nwbfile.create_device(
            name='Microscope',
            description='My two-photon microscope',
            manufacturer='The best microscope manufacturer')
    if optical_channel is None:
        optical_channel = OpticalChannel(name='OpticalChannel',
                                         description='an optical channel',
                                         emission_lambda=500.)
    if imaging_plane is None:
        imaging_plane = nwbfile.create_imaging_plane(
            name='ImagingPlane',
            optical_channel=optical_channel,
            imaging_rate=ops['fs'],
            description='standard',
            device=device,
            excitation_lambda=600.,
            indicator='GCaMP',
            location='V1',
            grid_spacing=([2, 2, 30] if multiplane else [2, 2]),
            grid_spacing_unit='microns')

    if image_series is None:
        # link to external data
        image_series = TwoPhotonSeries(
            name='TwoPhotonSeries',
            dimension=[ops['Ly'], ops['Lx']],
            external_file=(ops['filelist'] if 'filelist' in ops else ['']),
            imaging_plane=imaging_plane,
            starting_frame=[0],
            format='external',
            starting_time=0.0,
            rate=ops['fs'] * ops['nplanes'])
        nwbfile.add_acquisition(image_series)  # otherwise, were added

    # processing
    img_seg = ImageSegmentation()
    ps = img_seg.create_plane_segmentation(name='PlaneSegmentation',
                                           description='suite2p output',
                                           imaging_plane=imaging_plane,
                                           reference_images=image_series)
    ophys_module = nwbfile.create_processing_module(
        name='ophys', description='optical physiology processed data')
    ophys_module.add(img_seg)

    file_strs = ['F.npy', 'Fneu.npy', 'spks.npy']
    traces = []
    ncells_all = 0
    for iplane, ops in enumerate(ops1):
        if iplane == 0:
            iscell = np.load(
                os.path.join(save_folder, 'plane%i' % iplane, 'iscell.npy'))
            for fstr in file_strs:
                traces.append(
                    np.load(os.path.join(save_folder, 'plane%i' % iplane,
                                         fstr)))
        else:
            iscell = np.append(iscell,
                               np.load(
                                   os.path.join(save_folder,
                                                'plane%i' % iplane,
                                                'iscell.npy')),
                               axis=0)
            for i, fstr in enumerate(file_strs):
                traces[i] = np.append(
                    traces[i],
                    np.load(os.path.join(save_folder, 'plane%i' % iplane,
                                         fstr)),
                    axis=0)

        stat = np.load(os.path.join(save_folder, 'plane%i' % iplane,
                                    'stat.npy'),
                       allow_pickle=True)
        ncells = len(stat)
        for n in range(ncells):
            if multiplane:
                pixel_mask = np.array([
                    stat[n]['ypix'], stat[n]['xpix'],
                    iplane * np.ones(stat[n]['npix']), stat[n]['lam']
                ])
                ps.add_roi(voxel_mask=pixel_mask.T)
            else:
                pixel_mask = np.array(
                    [stat[n]['ypix'], stat[n]['xpix'], stat[n]['lam']])
                ps.add_roi(pixel_mask=pixel_mask.T)
        ncells_all += ncells

    ps.add_column('iscell', 'two columns - iscell & probcell', iscell)

    rt_region = ps.create_roi_table_region(region=list(np.arange(
        0, ncells_all)),
                                           description='all ROIs')

    # FLUORESCENCE (all are required)
    file_strs = ['F.npy', 'Fneu.npy', 'spks.npy']
    name_strs = ['Fluorescence', 'Neuropil', 'Deconvolved']

    for i, (fstr, nstr) in enumerate(zip(file_strs, name_strs)):
        roi_resp_series = RoiResponseSeries(
            name=nstr,
            data=traces[i],
            rois=rt_region,
            unit='lumens',
            timestamps=CaImaging_timestamps
        )  # CRITICAL TO HAVE IT HERE FOR RE-ALIGNEMENT
        fl = Fluorescence(roi_response_series=roi_resp_series, name=nstr)
        ophys_module.add(fl)

    # BACKGROUNDS
    # (meanImg, Vcorr and max_proj are REQUIRED)
    bg_strs = ['meanImg', 'meanImgE', 'Vcorr', 'max_proj', 'meanImg_chan2']
    nplanes = ops['nplanes']
    for iplane in range(nplanes):
        images = Images('Backgrounds_%d' % iplane)
        for bstr in bg_strs:
            if bstr in ops:
                if bstr == 'Vcorr' or bstr == 'max_proj':
                    img = np.zeros((ops['Ly'], ops['Lx']), np.float32)
                    img[ops['yrange'][0]:ops['yrange'][-1],
                        ops['xrange'][0]:ops['xrange'][-1]] = ops[bstr]
                else:
                    img = ops[bstr]
                images.add_image(GrayscaleImage(name=bstr, data=img))

        ophys_module.add(images)
Example #19
0
    def write_segmentation(segext_obj,
                           save_path,
                           plane_num=0,
                           metadata=None,
                           overwrite=True):
        save_path = Path(save_path)
        assert save_path.suffix == '.nwb'
        if save_path.is_file() and not overwrite:
            nwbfile_exist = True
            file_mode = 'r+'
        else:
            if save_path.is_file():
                os.remove(save_path)
            if not save_path.parent.is_dir():
                save_path.parent.mkdir(parents=True)
            nwbfile_exist = False
            file_mode = 'w'

        # parse metadata correctly:
        if isinstance(segext_obj, MultiSegmentationExtractor):
            segext_objs = segext_obj.segmentations
            if metadata is not None:
                assert isinstance(metadata, list), "For MultiSegmentationExtractor enter 'metadata' as a list of " \
                                                   "SegmentationExtractor metadata"
                assert len(metadata) == len(segext_objs), "The 'metadata' argument should be a list with the same " \
                                                          "number of elements as the segmentations in the " \
                                                          "MultiSegmentationExtractor"
        else:
            segext_objs = [segext_obj]
            if metadata is not None and not isinstance(metadata, list):
                metadata = [metadata]
        metadata_base_list = [
            NwbSegmentationExtractor.get_nwb_metadata(sgobj)
            for sgobj in segext_objs
        ]

        print(f'writing nwb for {segext_obj.extractor_name}\n')
        # updating base metadata with new:
        for num, data in enumerate(metadata_base_list):
            metadata_input = metadata[num] if metadata else {}
            metadata_base_list[num] = dict_recursive_update(
                metadata_base_list[num], metadata_input)
        # loop for every plane:
        with NWBHDF5IO(str(save_path), file_mode) as io:
            metadata_base_common = metadata_base_list[0]
            if nwbfile_exist:
                nwbfile = io.read()
            else:
                nwbfile = NWBFile(**metadata_base_common['NWBFile'])
                # Subject:
                if metadata_base_common.get('Subject'):
                    nwbfile.subject = Subject(
                        **metadata_base_common['Subject'])

            # Processing Module:
            if 'ophys' not in nwbfile.processing:
                ophys = nwbfile.create_processing_module(
                    'ophys', 'contains optical physiology processed data')
            else:
                ophys = nwbfile.get_processing_module('ophys')

            for plane_no_loop, (segext_obj, metadata) in enumerate(
                    zip(segext_objs, metadata_base_list)):
                # Device:
                if metadata['Ophys']['Device'][0][
                        'name'] not in nwbfile.devices:
                    nwbfile.create_device(**metadata['Ophys']['Device'][0])

                # ImageSegmentation:
                image_segmentation_name = 'ImageSegmentation' if plane_no_loop == 0 else f'ImageSegmentation_Plane{plane_no_loop}'
                if image_segmentation_name not in ophys.data_interfaces:
                    image_segmentation = ImageSegmentation(
                        name=image_segmentation_name)
                    ophys.add_data_interface(image_segmentation)
                else:
                    image_segmentation = ophys.data_interfaces.get(
                        image_segmentation_name)

                # OpticalChannel:
                optical_channels = [
                    OpticalChannel(**i) for i in metadata['Ophys']
                    ['ImagingPlane'][0]['optical_channel']
                ]

                # ImagingPlane:
                image_plane_name = 'ImagingPlane' if plane_no_loop == 0 else f'ImagePlane_{plane_no_loop}'
                if image_plane_name not in nwbfile.imaging_planes.keys():
                    input_kwargs = dict(
                        name=image_plane_name,
                        device=nwbfile.get_device(metadata_base_common['Ophys']
                                                  ['Device'][0]['name']),
                    )
                    metadata['Ophys']['ImagingPlane'][0][
                        'optical_channel'] = optical_channels
                    input_kwargs.update(**metadata['Ophys']['ImagingPlane'][0])
                    if 'imaging_rate' in input_kwargs:
                        input_kwargs['imaging_rate'] = float(
                            input_kwargs['imaging_rate'])
                    imaging_plane = nwbfile.create_imaging_plane(
                        **input_kwargs)
                else:
                    imaging_plane = nwbfile.imaging_planes[image_plane_name]

                # PlaneSegmentation:
                input_kwargs = dict(
                    description='output from segmenting imaging plane',
                    imaging_plane=imaging_plane)
                ps_metadata = metadata['Ophys']['ImageSegmentation'][
                    'plane_segmentations'][0]
                if ps_metadata[
                        'name'] not in image_segmentation.plane_segmentations:
                    input_kwargs.update(**ps_metadata)
                    ps = image_segmentation.create_plane_segmentation(
                        **input_kwargs)
                    ps_exist = False
                else:
                    ps = image_segmentation.get_plane_segmentation(
                        ps_metadata['name'])
                    ps_exist = True

                # ROI add:
                image_masks = segext_obj.get_roi_image_masks()
                roi_ids = segext_obj.get_roi_ids()
                accepted_list = segext_obj.get_accepted_list()
                accepted_list = [] if accepted_list is None else accepted_list
                rejected_list = segext_obj.get_rejected_list()
                rejected_list = [] if rejected_list is None else rejected_list
                accepted_ids = [
                    1 if k in accepted_list else 0 for k in roi_ids
                ]
                rejected_ids = [
                    1 if k in rejected_list else 0 for k in roi_ids
                ]
                roi_locations = np.array(segext_obj.get_roi_locations()).T
                if not ps_exist:
                    ps.add_column(
                        name='RoiCentroid',
                        description=
                        'x,y location of centroid of the roi in image_mask')
                    ps.add_column(
                        name='Accepted',
                        description=
                        '1 if ROi was accepted or 0 if rejected as a cell during segmentation operation'
                    )
                    ps.add_column(
                        name='Rejected',
                        description=
                        '1 if ROi was rejected or 0 if accepted as a cell during segmentation operation'
                    )
                    for num, row in enumerate(roi_ids):
                        ps.add_roi(id=row,
                                   image_mask=image_masks[:, :, num],
                                   RoiCentroid=roi_locations[num, :],
                                   Accepted=accepted_ids[num],
                                   Rejected=rejected_ids[num])

                # Fluorescence Traces:
                if 'Flourescence' not in ophys.data_interfaces:
                    fluorescence = Fluorescence()
                    ophys.add_data_interface(fluorescence)
                else:
                    fluorescence = ophys.data_interfaces['Fluorescence']
                roi_response_dict = segext_obj.get_traces_dict()
                roi_table_region = ps.create_roi_table_region(
                    description=f'region for Imaging plane{plane_no_loop}',
                    region=list(range(segext_obj.get_num_rois())))
                rate = np.float('NaN') if segext_obj.get_sampling_frequency(
                ) is None else segext_obj.get_sampling_frequency()
                for i, j in roi_response_dict.items():
                    data = getattr(segext_obj, f'_roi_response_{i}')
                    if data is not None:
                        data = np.asarray(data)
                        trace_name = 'RoiResponseSeries' if i == 'raw' else i.capitalize(
                        )
                        trace_name = trace_name if plane_no_loop == 0 else trace_name + f'_Plane{plane_no_loop}'
                        input_kwargs = dict(name=trace_name,
                                            data=data.T,
                                            rois=roi_table_region,
                                            rate=rate,
                                            unit='n.a.')
                        if trace_name not in fluorescence.roi_response_series:
                            fluorescence.create_roi_response_series(
                                **input_kwargs)

                # create Two Photon Series:
                if 'TwoPhotonSeries' not in nwbfile.acquisition:
                    warn(
                        'could not find TwoPhotonSeries, using ImagingExtractor to create an nwbfile'
                    )

                # adding images:
                images_dict = segext_obj.get_images_dict()
                if any([image is not None for image in images_dict.values()]):
                    images_name = 'SegmentationImages' if plane_no_loop == 0 else f'SegmentationImages_Plane{plane_no_loop}'
                    if images_name not in ophys.data_interfaces:
                        images = Images(images_name)
                        for img_name, img_no in images_dict.items():
                            if img_no is not None:
                                images.add_image(
                                    GrayscaleImage(name=img_name, data=img_no))
                        ophys.add(images)

            # saving NWB file:
            io.write(nwbfile)

        # test read
        with NWBHDF5IO(str(save_path), 'r') as io:
            io.read()
Example #20
0
    def setUp(self):
        start_time = datetime(2017, 4, 3, 11, 0, 0)
        create_date = datetime(2017, 4, 15, 12, 0, 0)

        # create your NWBFile object
        nwbfile = NWBFile('PyNWB Sample File', 'A simple NWB file', 'NWB_test', start_time,
                        file_create_date=create_date)
        
        # create acquisition metadata
        optical_channel = OpticalChannel('test_optical_channel', 'optical channel source',
                                        'optical channel description', 3.14)
        imaging_plane = nwbfile.create_imaging_plane('test_imaging_plane',
                                                    'ophys integration tests',
                                                    optical_channel,
                                                    'imaging plane description',
                                                    'imaging_device_1',
                                                    6.28, '2.718', 'GFP', 'somewhere in the brain',
                                                    (1, 2, 1, 2, 3), 4.0, 'manifold unit', 'A frame to refer to')

        # create acquisition data
        image_series = TwoPhotonSeries(name='test_iS', source='a hypothetical source', dimension=[2],
                                    external_file=['images.tiff'], imaging_plane=imaging_plane,
                                    starting_frame=[1, 2, 3], format='tiff', timestamps=list())
        nwbfile.add_acquisition(image_series)


        mod = nwbfile.create_processing_module('img_seg_example', 'ophys demo', 'an example of writing Ca2+ imaging data')
        img_seg = ImageSegmentation('a toy image segmentation container')
        mod.add_data_interface(img_seg)
        ps = img_seg.create_plane_segmentation('integration test PlaneSegmentation', 'plane segmentation description',
                                            imaging_plane, 'test_plane_seg_name', image_series)
        # add two ROIs
        # - first argument is the pixel mask i.e. a list of pixels and their weights
        # - second argument is the image mask
        w, h = 3, 3
        pix_mask1 = [(0, 0, 1.1), (1, 1, 1.2), (2, 2, 1.3)]
        img_mask1 = [[0.0 for x in range(w)] for y in range(h)]
        img_mask1[0][0] = 1.1
        img_mask1[1][1] = 1.2
        img_mask1[2][2] = 1.3
        ps.add_roi('1234', pix_mask1, img_mask1)

        pix_mask2 = [(0, 0, 2.1), (1, 1, 2.2)]
        img_mask2 = [[0.0 for x in range(w)] for y in range(h)]
        img_mask2[0][0] = 2.1
        img_mask2[1][1] = 2.2
        ps.add_roi('5678', pix_mask2, img_mask2)

        # add a Fluorescence container
        fl = Fluorescence('a toy fluorescence container')
        mod.add_data_interface(fl)
        # get an ROI table region i.e. a subset of ROIs to create a RoiResponseSeries from
        rt_region = ps.create_roi_table_region('the first of two ROIs', region=[0])
        # make some fake timeseries data
        data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        timestamps = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
        rrs = fl.create_roi_response_series('test_roi_response_series', 'RoiResponseSeries integration test',
                                            data, 'lumens', rt_region, timestamps=timestamps)
        # write data
        nwb_path = './test_data/nwb_test_file.nwb'
        with NWBHDF5IO(nwb_path, 'w') as io:
            io.write(nwbfile)
Example #21
0
#
# .. only:: html
#
#   .. image:: ../../_static/Fluorescence.svg
#     :width: 600
#     :alt: fluorescence UML diagram
#     :align: center
#
# .. only:: latex
#
#   .. image:: ../../_static/Fluorescence.png
#     :width: 600
#     :alt: fluorescence UML diagram
#     :align: center

fl = Fluorescence(roi_response_series=roi_resp_series)
ophys_module.add(fl)

####################
# .. tip::
#    If you want to store dF/F data instead of fluorescence data, then store
#    the :py:class:`~pynwb.ophys.RoiResponseSeries` object in a
#    :py:class:`~pynwb.ophys.DfOverF` object, which works the same way as the
#    :py:class:`~pynwb.ophys.Fluorescence` class.
#

####################
# Write the file
# ---------------------------------
# Once we have finished adding all of our data to our
# :py:class:`~pynwb.file.NWBFile`, make sure to write the file.
Example #22
0
    def setUpClass(self):
        device = Device("imaging_device_1")
        optical_channel = OpticalChannel("my_optchan", "description", 500.0)
        self.imaging_plane = ImagingPlane(
            name="imgpln1",
            optical_channel=optical_channel,
            description="a fake ImagingPlane",
            device=device,
            excitation_lambda=600.0,
            imaging_rate=300.0,
            indicator="GFP",
            location="somewhere in the brain",
            reference_frame="unknown",
            origin_coords=[10, 20],
            origin_coords_unit="millimeters",
            grid_spacing=[0.001, 0.001],
            grid_spacing_unit="millimeters",
        )

        self.image_series = TwoPhotonSeries(
            name="test_image_series",
            data=np.random.randn(100, 5, 5),
            imaging_plane=self.imaging_plane,
            starting_frame=[0],
            rate=1.0,
            unit="n.a",
        )
        self.img_seg = ImageSegmentation()
        self.ps2 = self.img_seg.create_plane_segmentation(
            "output from segmenting my favorite imaging plane",
            self.imaging_plane,
            "2d_plane_seg",
            self.image_series,
        )
        self.ps2.add_column("type", "desc")
        self.ps2.add_column("type2", "desc")

        w, h = 3, 3
        img_mask1 = np.zeros((w, h))
        img_mask1[0, 0] = 1.1
        img_mask1[1, 1] = 1.2
        img_mask1[2, 2] = 1.3
        self.ps2.add_roi(image_mask=img_mask1, type=1, type2=0)

        img_mask2 = np.zeros((w, h))
        img_mask2[0, 0] = 2.1
        img_mask2[1, 1] = 2.2
        self.ps2.add_roi(image_mask=img_mask2, type=1, type2=1)

        img_mask2 = np.zeros((w, h))
        img_mask2[0, 0] = 9.1
        img_mask2[1, 1] = 10.2
        self.ps2.add_roi(image_mask=img_mask2, type=2, type2=0)

        img_mask2 = np.zeros((w, h))
        img_mask2[0, 0] = 3.5
        img_mask2[1, 1] = 5.6
        self.ps2.add_roi(image_mask=img_mask2, type=2, type2=1)

        fl = Fluorescence()
        rt_region = self.ps2.create_roi_table_region("the first of two ROIs",
                                                     region=[0, 1, 2, 3])

        rois_shape = 5
        data = np.arange(10 * rois_shape).reshape([10, -1], order='F')
        timestamps = np.array(
            [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
        rrs = fl.create_roi_response_series(name="my_rrs",
                                            data=data,
                                            rois=rt_region,
                                            unit="lumens",
                                            timestamps=timestamps)
        self.df_over_f = DfOverF(rrs)
Example #23
0
def save_nwb(ops1):
    if NWB and not ops1[0]['mesoscan']:
        if len(ops1) > 1:
            multiplane = True
        else:
            multiplane = False

        ops = ops1[0]

        ### INITIALIZE NWB FILE
        nwbfile = NWBFile(
            session_description='suite2p_proc',
            identifier=ops['data_path'][0],
            session_start_time=(ops['date_proc'] if 'date_proc' in ops else
                                datetime.datetime.now()))
        print(nwbfile)

        device = nwbfile.create_device(
            name='Microscope',
            description='My two-photon microscope',
            manufacturer='The best microscope manufacturer')
        optical_channel = OpticalChannel(name='OpticalChannel',
                                         description='an optical channel',
                                         emission_lambda=500.)

        imaging_plane = nwbfile.create_imaging_plane(
            name='ImagingPlane',
            optical_channel=optical_channel,
            imaging_rate=ops['fs'],
            description='standard',
            device=device,
            excitation_lambda=600.,
            indicator='GCaMP',
            location='V1',
            grid_spacing=([2, 2, 30] if multiplane else [2, 2]),
            grid_spacing_unit='microns')

        # link to external data
        image_series = TwoPhotonSeries(
            name='TwoPhotonSeries',
            dimension=[ops['Ly'], ops['Lx']],
            external_file=(ops['filelist'] if 'filelist' in ops else ['']),
            imaging_plane=imaging_plane,
            starting_frame=[0],
            format='external',
            starting_time=0.0,
            rate=ops['fs'] * ops['nplanes'])
        nwbfile.add_acquisition(image_series)

        # processing
        img_seg = ImageSegmentation()
        ps = img_seg.create_plane_segmentation(name='PlaneSegmentation',
                                               description='suite2p output',
                                               imaging_plane=imaging_plane,
                                               reference_images=image_series)
        ophys_module = nwbfile.create_processing_module(
            name='ophys', description='optical physiology processed data')
        ophys_module.add(img_seg)

        file_strs = ['F.npy', 'Fneu.npy', 'spks.npy']
        traces = []
        ncells_all = 0
        for iplane, ops in enumerate(ops1):
            if iplane == 0:
                iscell = np.load(os.path.join(ops['save_path'], 'iscell.npy'))
                for fstr in file_strs:
                    traces.append(np.load(os.path.join(ops['save_path'],
                                                       fstr)))
            else:
                iscell = np.append(iscell,
                                   np.load(
                                       os.path.join(ops['save_path'],
                                                    'iscell.npy')),
                                   axis=0)
                for i, fstr in enumerate(file_strs):
                    traces[i] = np.append(
                        traces[i],
                        np.load(os.path.join(ops['save_path'], fstr)),
                        axis=0)

            stat = np.load(os.path.join(ops['save_path'], 'stat.npy'),
                           allow_pickle=True)
            ncells = len(stat)
            for n in range(ncells):
                if multiplane:
                    pixel_mask = np.array([
                        stat[n]['ypix'], stat[n]['xpix'],
                        iplane * np.ones(stat[n]['npix']), stat[n]['lam']
                    ])
                    ps.add_roi(voxel_mask=pixel_mask.T)
                else:
                    pixel_mask = np.array(
                        [stat[n]['ypix'], stat[n]['xpix'], stat[n]['lam']])
                    ps.add_roi(pixel_mask=pixel_mask.T)
            ncells_all += ncells

        ps.add_column('iscell', 'two columns - iscell & probcell', iscell)

        rt_region = ps.create_roi_table_region(region=list(
            np.arange(0, ncells_all)),
                                               description='all ROIs')

        # FLUORESCENCE (all are required)
        file_strs = ['F.npy', 'Fneu.npy', 'spks.npy']
        name_strs = ['Fluorescence', 'Neuropil', 'Deconvolved']

        for i, (fstr, nstr) in enumerate(zip(file_strs, name_strs)):
            roi_resp_series = RoiResponseSeries(name=nstr,
                                                data=traces[i],
                                                rois=rt_region,
                                                unit='lumens',
                                                rate=ops['fs'])
            fl = Fluorescence(roi_response_series=roi_resp_series, name=nstr)
            ophys_module.add(fl)

        # BACKGROUNDS
        # (meanImg, Vcorr and max_proj are REQUIRED)
        bg_strs = ['meanImg', 'Vcorr', 'max_proj', 'meanImg_chan2']
        nplanes = ops['nplanes']
        for iplane in range(nplanes):
            images = Images('Backgrounds_%d' % iplane)
            for bstr in bg_strs:
                if bstr in ops:
                    if bstr == 'Vcorr' or bstr == 'max_proj':
                        img = np.zeros((ops['Ly'], ops['Lx']), np.float32)
                        img[ops['yrange'][0]:ops['yrange'][-1],
                            ops['xrange'][0]:ops['xrange'][-1]] = ops[bstr]
                    else:
                        img = ops[bstr]
                    images.add_image(GrayscaleImage(name=bstr, data=img))

            ophys_module.add(images)

        with NWBHDF5IO(os.path.join(ops['save_path0'], 'suite2p', 'ophys.nwb'),
                       'w') as fio:
            fio.write(nwbfile)
    else:
        print('pip install pynwb OR don"t use mesoscope recording')
Example #24
0
def add_ophys_processing_from_suite2p(save_folder, nwbfile, xml, 
                                      device=None,
                                      optical_channel=None,
                                      imaging_plane=None,
                                      image_series=None):
    """ 
    adapted from suite2p/suite2p/io/nwb.py "save_nwb" function
    """

    plane_folders = natsorted([ f.path for f in os.scandir(save_folder) if f.is_dir() and f.name[:5]=='plane'])
    OPS = [np.load(os.path.join(f, 'ops.npy'), allow_pickle=True).item() for f in plane_folders]

    if len(OPS)>1:
        multiplane, nplanes = True, len(plane_folders)
        pData_folder = os.path.join(save_folder, 'combined') # processed data folder -> using the "combined output from suite2p"
    else:
        multiplane, nplanes = False, 1
        pData_folder = os.path.join(save_folder, 'plane0') # processed data folder

    # find time sampling per plane
    functional_chan = ('Ch1' if len(xml['Ch1']['relativeTime'])>1 else 'Ch2') # functional channel is one of the two !!
    CaImaging_timestamps = xml[functional_chan]['relativeTime']+float(xml['settings']['framePeriod'])/2.

    ops = np.load(os.path.join(pData_folder, 'ops.npy'), allow_pickle=True).item() 
    
    if device is None:
        device = nwbfile.create_device(
            name='Microscope', 
            description='My two-photon microscope',
            manufacturer='The best microscope manufacturer')
    if optical_channel is None:
        optical_channel = OpticalChannel(
            name='OpticalChannel', 
            description='an optical channel', 
            emission_lambda=500.)
    if imaging_plane is None:
        imaging_plane = nwbfile.create_imaging_plane(
            name='ImagingPlane',
            optical_channel=optical_channel,
            imaging_rate=ops['fs'],
            description='standard',
            device=device,
            excitation_lambda=600.,
            indicator='GCaMP',
            location='V1',
            grid_spacing=([2,2,30] if multiplane else [2,2]),
            grid_spacing_unit='microns')

    if image_series is None:
        # link to external data
        image_series = TwoPhotonSeries(
            name='TwoPhotonSeries', 
            dimension=[ops['Ly'], ops['Lx']],
            external_file=(ops['filelist'] if 'filelist' in ops else ['']), 
            imaging_plane=imaging_plane,
            starting_frame=[0], 
            format='external', 
            starting_time=0.0, 
            rate=ops['fs'] * ops['nplanes']
        )
        nwbfile.add_acquisition(image_series) # otherwise, were added

    # processing
    img_seg = ImageSegmentation()
    ps = img_seg.create_plane_segmentation(
        name='PlaneSegmentation',
        description='suite2p output',
        imaging_plane=imaging_plane,
        reference_images=image_series
    )
    ophys_module = nwbfile.create_processing_module(
        name='ophys', 
        description='optical physiology processed data\n TSeries-folder=%s' % save_folder)
    ophys_module.add(img_seg)

    file_strs = ['F.npy', 'Fneu.npy', 'spks.npy']
    traces = []

    iscell = np.load(os.path.join(pData_folder, 'iscell.npy')).astype(bool)

    if ops['nchannels']>1:
        if os.path.isfile(os.path.join(pData_folder, 'redcell_manual.npy')):
            redcell = np.load(os.path.join(pData_folder, 'redcell_manual.npy'))[iscell[:,0], :]
        else:
            print('\n'+30*'--')
            print(' /!\ no file found for the manual labelling of red cells (generate it with the red-cell labelling GUI) /!\ ')
            print(' /!\ taking the raw suit2p output with the classifier settings /!\ ')
            print('\n'+30*'--')
            redcell = np.load(os.path.join(pData_folder, 'redcell.npy'))[iscell[:,0], :]
            
    for fstr in file_strs:
        traces.append(np.load(os.path.join(pData_folder, fstr))[iscell[:,0], :])
        
    stat = np.load(os.path.join(pData_folder, 'stat.npy'), allow_pickle=True)

    ncells = np.sum(iscell[:,0])
    plane_ID = np.zeros(ncells)
    for n in np.arange(ncells):
        pixel_mask = np.array([stat[iscell[:,0]][n]['ypix'], stat[iscell[:,0]][n]['xpix'], 
                               stat[iscell[:,0]][n]['lam']])
        ps.add_roi(pixel_mask=pixel_mask.T)
        if 'iplane' in stat[0]:
            plane_ID[n] = stat[iscell[:,0]][n]['iplane']

    if ops['nchannels']>1:
        ps.add_column('redcell', 'two columns - redcell & probcell', redcell)
    ps.add_column('plane', 'one column - plane ID', plane_ID)

    rt_region = ps.create_roi_table_region(
        region=list(np.arange(0, ncells)),
        description='all ROIs')

    # FLUORESCENCE (all are required)
    file_strs = ['F.npy', 'Fneu.npy', 'spks.npy']
    name_strs = ['Fluorescence', 'Neuropil', 'Deconvolved']

    for i, (fstr,nstr) in enumerate(zip(file_strs, name_strs)):
        roi_resp_series = RoiResponseSeries(
            name=nstr,
            data=traces[i],
            rois=rt_region,
            unit='lumens',
            timestamps=CaImaging_timestamps[::nplanes]) # ideally should be shifted for each ROI depending on the plane...
        fl = Fluorescence(roi_response_series=roi_resp_series, name=nstr)
        ophys_module.add(fl)

    # BACKGROUNDS
    # (meanImg, Vcorr and max_proj are REQUIRED)
    bg_strs = ['meanImg', 'meanImgE', 'Vcorr', 'max_proj', 'meanImg_chan2']
    nplanes = ops['nplanes']
    for iplane in range(nplanes):
        images = Images('Backgrounds_%d'%iplane)
        for bstr in bg_strs:
            if bstr in ops:
                if bstr=='Vcorr' or bstr=='max_proj':
                    img = np.zeros((ops['Ly'], ops['Lx']), np.float32)
                    img[ops['yrange'][0]:ops['yrange'][-1], 
                        ops['xrange'][0]:ops['xrange'][-1]] = ops[bstr]
                else:
                    img = ops[bstr]
                images.add_image(GrayscaleImage(name=bstr, data=img))

        ophys_module.add(images)