diff --git a/ndx-photostim/README.md b/ndx-photostim/README.md new file mode 100644 index 0000000..82614c0 --- /dev/null +++ b/ndx-photostim/README.md @@ -0,0 +1,176 @@ +# ndx-photostim Extension for NWB + +
+ + +This is a NeuroData Without Borders (NWB) extension for storing data and metadata from holographic photostimulation +methods. It includes containers for storing photostimulation-specific device parameters, holographic patterns +(either 2D or 3D), and time series data related to photostimulation. +
+ +
We release six PyNWB containers as part of this extension (we currently only have a Python implementation, rather than both Python and a MATLAB ones -- this is why the `matnwb` directory is empty): + +* The `SpatialLightModulator` and `Laser` containers store metadata about the spatial light modulator and laser used in the photostimulation, respectively. These containers are then stored within the `PhotostimulationMethod` parent container, which stores the remaining photostimulation method-specifici metadata. +* `HolographicPattern` stores the **holographic pattern** used in stimulation. +* `PhotostimulationSeries` contains the **time series data** corresponding to the presentation of a given stimulus (where the stimulus is represented by a `HolographicPattern` container linked to the `PhotostimulationSeries`). +* We group **all time series & patterns for a given experiment** together using the `PhotostimulationTable` container. This object is a dynamic table, where each row in the table corresponds to a single `PhotostimulationSeries`. Additionally, the table links to the `StimulationDevice` used in the experiment. + + +## Background + + +State-of-the-art holographic photostimulation methods, used in concert with two-photon imaging, +allow unprecedented +control and measurement of cell activity in the living brain. Methods for managing data for two-photon imaging +experiments are improving, but there is little to no standardization of data for holographic stimulation methods. +Stimulation in vivo depends on fine-tuning many experimental variables, which poses a challenge for reproducibility +and data sharing between researchers. To improve standardization of photostimulation data storage and processing, +we release this extension as a generic data format for simultaneous holographic stimulation experiments, +using the NWB format to store experimental details and data relating to both acquisition +and photostimulation. + +## Installation + +To install the extension, first clone the `ndx_photostim` repository to the desired folder using the command +```angular2svg +git clone https://github.com/histedlab/ndx-photostim.git +``` +Then, to install the requisite python packages and extension, run: +```angular2svg +python -m pip install -r requirements.txt -r requirements-dev.txt +python setup.py install +``` +The extension can then be imported into python scripts via `import ndx_photostim`. + +## Usage + +**For full example usage, see [tutorial.ipynb](https://github.com/histedlab/ndx-photostim/blob/main/tutorial.ipynb)** + +Below is example code to: +1. Create a device used in photostimulation +2. Simulate and store photostimulation ROIs +3. Store the time series corresponding to each stimulation +4. Record all time series and patterns used in an experiment in a table +5. Write the above to an NWB file and read it back + + +```python +import numpy as np +from dateutil.tz import tzlocal +from datetime import datetime +from pynwb import NWBFile, NWBHDF5IO +from ndx_photostim import SpatialLightModulator, Laser, PhotostimulationMethod, HolographicPattern, \ + PhotostimulationSeries, PhotostimulationTable + +# create an example NWB file +nwbfile = NWBFile('ndx-photostim_example', 'EXAMPLE_ID', datetime.now(tzlocal())) + +# store the spatial light modulator used +slm = SpatialLightModulator(name='slm', + model='Meadowlark', + size=np.array([512, 512])) + +# store the laser used +laser = Laser(name='laser', + model='Coherent Monaco', + wavelength=1030, + power=8, + peak_pulse_energy=20, + pulse_rate=500) + +# create a container for the method used for photostimulation, and link the SLM and laser to it +ps_method = PhotostimulationMethod(name="methodA", + stimulus_method="scanless", + sweep_pattern="none", + sweep_size=0, + time_per_sweep=0, + num_sweeps=0) +ps_method.add_slm(slm) +ps_method.add_laser(laser) + +# define holographic pattern +hp = HolographicPattern(name='pattern1', + image_mask_roi=np.round(np.random.rand(5, 5)), + stim_duration=0.300, + power_per_target=8) + +# show the mask +hp.show_mask() + +# define stimulation time series using holographic pattern +ps_series = PhotostimulationSeries(name="series_1", + format='interval', + data=[1, -1, 1, -1], + timestamps=[0.5, 1, 2, 4], + pattern=hp, + method=ps_method) + +# add the stimulus to the NWB file +nwbfile.add_stimulus(ps_series) + +# create a table to store the time series/patterns for all stimuli together, along with experiment-specific +# parameters +stim_table = PhotostimulationTable(name='test', description='...') +stim_table.add_series(ps_series) + +# plot the timestamps when the stimulus was presented +stim_table.plot_presentation_times() + +# create a processing module and add the PresentationTable to it +module = nwbfile.create_processing_module(name="photostimulation", description="example photostimulation table") +module.add(stim_table) + +# write to an NWB file and read it back +with NWBHDF5IO("example_file.nwb", "w") as io: + io.write(nwbfile) + +with NWBHDF5IO("example_file.nwb", "r", load_namespaces=True) as io: + read_nwbfile = io.read() + + # Check the file & processing module + print(read_nwbfile) + print(read_nwbfile.processing['photostimulation']) + +if os.path.exists("example_file.nwb"): + os.remove("example_file.nwb") +``` +## Running tests + +Unit and integration +tests are implemented using pytest, and can be run via the command +`pytest` from the root of the extension directory (i.e., inside `ndx-photostim/src`). In addition, the +`pytest` command will also run a test of the example code above. + +## Documentation + +### Specification + + +Documentation for the extension's specification, which is based on the YAML files, is generated and stored in +the `./docs` folder. To create it, run the following from the home directory: +```angular2svg +cd docs +make fulldoc +``` +This will save documentation to the `./docs/build` folder, and can be accessed via the +`./docs/build/html/index.html` file. + +### API + +To generate documentation for the Python API (stores in `./api_docs`), we use Sphinx +and a template from ReadTheDocs. API documentation can +be created by running +```angular2svg +sphinx-build -b html api_docs/source/ api_docs/build/ +``` +from the home folder. Similar to the specification docs, API documentation is stored in `./api_docs/build`. Select +`./api_docs/build/index.html` to access the API documentation in a website format. + + +## Credit + +Code by Carl Harris and Paul LaFosse (equal contribution). Collaboration between the NIMH's [Data Science and Sharing Team](https://cmn.nimh.nih.gov/dsst) and [Histed Lab](https://www.nimh.nih.gov/research/research-conducted-at-nimh/research-areas/clinics-and-labs/ncb). + + +This extension was created using [ndx-template](https://github.com/nwb-extensions/ndx-template). + diff --git a/ndx-photostim/ndx-meta.yaml b/ndx-photostim/ndx-meta.yaml new file mode 100644 index 0000000..4a89ee7 --- /dev/null +++ b/ndx-photostim/ndx-meta.yaml @@ -0,0 +1,8 @@ +name: ndx-photostim +version: 0.0.3 +src: https://github.com/histedlab/ndx-photostim +pip: https://pypi.org/project/ndx-photostim +license: BSD3 +maintainers: + - lafosse + - histed \ No newline at end of file