@@ -342,15 +342,91 @@ def plot_grouped_efeatures(
342342 _ = _plot_legend (colors , markers , output_dir , show = show )
343343
344344
345+ def plot_impedance (cell , output_dir , efel_settings ):
346+ """Plots the impedance."""
347+ from scipy .ndimage .filters import gaussian_filter1d
348+
349+ dt = 0.1
350+ Z_max_freq = 50.0
351+ if efel_settings is not None :
352+ dt = efel_settings .get ("interp_step" , dt )
353+ Z_max_freq = efel_settings .get ("impedance_max_freq" , Z_max_freq )
354+
355+ for protocol_name in cell .get_protocol_names ():
356+ if "sinespec" in protocol_name .lower ():
357+ recordings = cell .get_recordings_by_protocol_name (protocol_name )
358+ for i , rec in enumerate (recordings ):
359+ voltage = rec .voltage
360+ current = rec .current
361+
362+ efel_vals = rec .call_efel (
363+ [
364+ "voltage_base" ,
365+ "steady_state_voltage_stimend" ,
366+ "current_base" ,
367+ "steady_state_current_stimend" ,
368+ ],
369+ efel_settings
370+ )
371+ if efel_vals [0 ]["voltage_base" ] is not None :
372+ holding_voltage = efel_vals [0 ]["voltage_base" ][0 ]
373+ else :
374+ holding_voltage = efel_vals [0 ]["steady_state_voltage_stimend" ][0 ]
375+ if efel_vals [0 ]["current_base" ] is not None :
376+ holding_current = efel_vals [0 ]["current_base" ][0 ]
377+ else :
378+ holding_current = efel_vals [0 ]["steady_state_current_stimend" ][0 ]
379+
380+ normalized_voltage = voltage - holding_voltage
381+ normalized_current = current - holding_current
382+
383+ fft_volt = numpy .fft .fft (normalized_voltage )
384+ fft_cur = numpy .fft .fft (normalized_current )
385+ if any (fft_cur ) == 0 :
386+ return None
387+ # convert dt from ms to s to have freq in Hz
388+ freq = numpy .fft .fftfreq (len (normalized_voltage ), d = dt / 1000. )
389+ Z = fft_volt / fft_cur
390+ norm_Z = abs (Z ) / max (abs (Z ))
391+ select_idxs = numpy .swapaxes (
392+ numpy .argwhere ((freq > 0 ) & (freq <= Z_max_freq )), 0 , 1
393+ )[0 ]
394+ smooth_Z = gaussian_filter1d (norm_Z [select_idxs ], 10 )
395+
396+ filename = "{}_{}_{}_{}_impedance.pdf" .format (
397+ cell .name , protocol_name , i , rec .name
398+ )
399+ dirname = pathlib .Path (output_dir ) / cell .name / "impedance"
400+
401+ fig = plt .figure ()
402+ ax = fig .add_subplot (1 , 1 , 1 )
403+ ax .plot (freq [:len (smooth_Z )], smooth_Z )
404+ ax .set_xlabel ("Frequency (Hz)" )
405+ ax .set_ylabel ("normalized Z" )
406+ fig .suptitle (f"Impedance for { rec .name } \n for cell { cell .name } " )
407+ _save_fig (dirname , filename )
408+
409+
410+ def plot_all_impedances (cells , output_dir , mapper = map , efel_settings = None ):
411+ """Plot recordings for all cells and all protocols"""
412+ if mapper == map :
413+ # For the built-in map(), ensure immediate evaluation as it returns a lazy iterator
414+ # which won't execute the function until iterated over. Converting to a list forces this iteration.
415+ list (mapper (partial (plot_impedance , output_dir = output_dir , efel_settings = efel_settings ), cells ))
416+ else :
417+ mapper (partial (plot_impedance , output_dir = output_dir , efel_settings = efel_settings ), cells )
418+
419+
345420def plot_all_recordings_efeatures (
346- cells , protocols , output_dir = None , show = False , mapper = map
421+ cells , protocols , output_dir = None , show = False , mapper = map , efel_settings = None
347422):
348423 """Generate plots for all recordings and efeatures both for individual
349424 cells and across all cells."""
350425
351426 colors , markers = _get_colors_markers_wheels (cells )
352427
353428 plot_all_recordings (cells , output_dir , mapper = mapper )
429+ plot_all_impedances (cells , output_dir , mapper = map , efel_settings = efel_settings )
354430
355431 for key_amp in ["amp" , "amp_rel" ]:
356432 plot_individual_efeatures (
0 commit comments