@@ -417,9 +417,9 @@ def import_ppd(ppd_file_path):
417417 data_dict .update (header_dict )
418418 return data_dict
419419
420- def processppdphotometry (ppd_file_path ):
420+ def processppdphotometry (ppd_file_path , nwbfile : NWBFile , metadata : dict ):
421421 """
422-
422+ Process pyPhotometry data from a .ppd file and add the processed signals to the NWB file.
423423 """
424424 ppd_data = import_ppd (ppd_file_path )
425425
@@ -430,30 +430,117 @@ def processppdphotometry(ppd_file_path):
430430 relative_raw_signal = raw_green / raw_405
431431
432432 sampling_rate = ppd_data ['sampling_rate' ]
433+ visits = ppd_data ['pulse_inds_1' ][1 :]
433434
435+ # low pass at 10Hz to remove high frequency noise
436+ print ('Filtering data...' )
434437 b ,a = butter (2 , 10 , btype = 'low' , fs = sampling_rate )
435438 GACh_denoised = filtfilt (b ,a , raw_green )
436439 rDA3m_denoised = filtfilt (b ,a , raw_red )
437440 ratio_denoised = filtfilt (b ,a , relative_raw_signal )
438441 denoised_405 = filtfilt (b ,a , raw_405 )
439-
440442 # high pass at 0.001Hz which removes the drift due to bleaching, but will also remove any physiological variation in the signal on very slow timescales.
441443 b ,a = butter (2 , 0.001 , btype = 'high' , fs = sampling_rate )
442444 GACh_highpass = filtfilt (b ,a , GACh_denoised , padtype = 'even' )
443445 rDA3m_highpass = filtfilt (b ,a , rDA3m_denoised , padtype = 'even' )
444446 ratio_highpass = filtfilt (b ,a , ratio_denoised , padtype = 'even' )
445447 highpass_405 = filtfilt (b ,a , denoised_405 , padtype = 'even' )
446448
449+ # Z-score of each signal to normalize the data
450+ print ('Z-scoring data...' )
447451 green_zscored = np .divide (np .subtract (GACh_highpass ,GACh_highpass .mean ()),GACh_highpass .std ())
448452
449453 red_zscored = np .divide (np .subtract (rDA3m_highpass ,rDA3m_highpass .mean ()),rDA3m_highpass .std ())
450454
451455 zscored_405 = np .divide (np .subtract (highpass_405 ,highpass_405 .mean ()),highpass_405 .std ())
452456
453457 ratio_zscored = np .divide (np .subtract (ratio_highpass ,ratio_highpass .mean ()),ratio_highpass .std ())
458+ print ('Done processing photometry data! Returning z-scored signals...' )
454459
455- return {"green_zscored" : green_zscored , "red_zscored" : red_zscored , "ratio_zscored" : ratio_zscored , "zscored_405" : zscored_405 }
456- pass
460+ # Add photometry metadata to the NWB
461+ print ("Adding photometry metadata to NWB ..." )
462+ add_photometry_metadata (NWBFile , metadata )
463+
464+ # Add actual photometry data to the NWB
465+ print ("Adding photometry signals to NWB ..." )
466+
467+ raw_470_response_series = FiberPhotometryResponseSeries (
468+ name = "raw_470" ,
469+ description = "Raw ACh signal @470 nm" ,
470+ data = raw_green .T [0 ],
471+ unit = "V" ,
472+ rate = float (sampling_rate ),
473+ )
474+
475+ z_scored_470_response_series = FiberPhotometryResponseSeries (
476+ name = "z_scored_470" ,
477+ description = "Z-scored ACh signal @470 nm" ,
478+ data = green_zscored .T [0 ],
479+ unit = "z-score" ,
480+ rate = float (sampling_rate ),
481+ )
482+
483+ raw_405_response_series = FiberPhotometryResponseSeries (
484+ name = "raw_405" ,
485+ description = "Raw ACh signal @405 nm" ,
486+ data = raw_405 .T [0 ],
487+ unit = "V" ,
488+ rate = float (sampling_rate ),
489+ )
490+
491+ z_scored_405_response_series = FiberPhotometryResponseSeries (
492+ name = "zscored_405" ,
493+ description = "Z-scored ACh signal @ 405nm. This is used to calculate the ratiometric index when using GRAB-ACh3.8" ,
494+ data = zscored_405 .T [0 ],
495+ unit = "z-score" ,
496+ rate = float (sampling_rate ),
497+ )
498+
499+ raw_565_response_series = FiberPhotometryResponseSeries (
500+ name = "raw_565" ,
501+ description = "Raw DA signal @565 nm" ,
502+ data = raw_red .T [0 ],
503+ unit = "V" ,
504+ rate = float (sampling_rate ),
505+ )
506+
507+ z_scored_565_response_series = FiberPhotometryResponseSeries (
508+ name = "zscored_565" ,
509+ description = "Z-scored DA signal @ 565nm" ,
510+ data = red_zscored .T [0 ],
511+ unit = "z-score" ,
512+ rate = float (sampling_rate ),
513+ )
514+
515+ raw_ratio_response_series = FiberPhotometryResponseSeries (
516+ name = "raw_470/405" ,
517+ description = "Raw ratiometric index of ACh signal @ 470nm and 405nm" ,
518+ data = relative_raw_signal .T [0 ],
519+ unit = "V" ,
520+ rate = float (sampling_rate ),
521+ )
522+
523+ z_scored_ratio_response_series = FiberPhotometryResponseSeries (
524+ name = "zscored_470/405" ,
525+ description = "Z-scored ratiometric index of ACh3.8 signal @ 470nm and 405nm" ,
526+ data = ratio_zscored .T [0 ],
527+ unit = "z-score" ,
528+ rate = float (sampling_rate ),
529+ )
530+
531+ # Add the FiberPhotometryResponseSeries objects to the NWB
532+ nwbfile .add_acquisition (raw_405_response_series )
533+ nwbfile .add_acquisition (raw_470_response_series )
534+ nwbfile .add_acquisition (raw_565_response_series )
535+ nwbfile .add_acquisition (raw_ratio_response_series )
536+ nwbfile .add_acquisition (z_scored_405_response_series )
537+ nwbfile .add_acquisition (z_scored_470_response_series )
538+ nwbfile .add_acquisition (z_scored_565_response_series )
539+ nwbfile .add_acquisition (z_scored_ratio_response_series )
540+
541+ # Return port visits in downsampled photometry time (250 Hz) to use for alignment
542+
543+ return sampling_rate , visits
457544
458545
459546def add_photometry_metadata (nwbfile : NWBFile , metadata : dict ):
0 commit comments