"""class AutoTarget"""
"""
Copyright (c) 2021, EPFL/Blue Brain Project
This file is part of BluePyEfe <https://github.com/BlueBrain/BluePyEfe>
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License version 3.0 as published
by the Free Software Foundation.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
[docs]
class AutoTarget():
"""Fuzzy targets defined by lists of ecodes, amplitudes and efeatures.
The AutoTarget will try to find the best combination of ecodes, amplitudes
and efeatures that match the data available in the recordings."""
def __init__(
self,
protocols,
amplitudes,
efeatures,
min_recordings_per_amplitude=10,
preferred_number_protocols=1,
tolerance=10,
):
"""
Extract efeatures.
Args:
protocols (list of str): list of eCodes, by order of priority.
amplitudes (list of int): list of amplitudes, expressed as
percentages of the rheobase, by order of priority
efeatures (list str): list of efeatures.
min_recordings_per_amplitude (int): minimum number of recordings
a amplitude should have to be considered as a target.
preferred_number_protocols (int): out of all the available
amplitudes, how many should be used.
tolerance (float): tolerance used to bin the efeatures around the
target amplitudes.
"""
self.efeatures = efeatures
self.protocols = protocols
self.amplitudes = amplitudes
self.min_recordings_per_amplitude = min_recordings_per_amplitude
self.preferred_number_protocols = preferred_number_protocols
self.tolerance = tolerance
self.active_amplitudes = []
self.active_ecode = []
[docs]
def select_ecode_and_amplitude(self, recordings):
"""Based on what ephys data is available, builds an effective (active)
set of targets."""
for ecode in self.protocols:
available_amps = []
for r in recordings:
if r.protocol_name == ecode and r.amp_rel is not None:
available_amps.append(r.amp_rel)
for amp in self.amplitudes:
n_available_rec = sum(
abs(a - amp) < self.tolerance for a in available_amps
)
if n_available_rec >= self.min_recordings_per_amplitude:
self.active_ecode.append(ecode)
self.active_amplitudes.append(amp)
if (
self.active_ecode and
len(self.active_ecode) > self.preferred_number_protocols
):
self.active_ecode = self.active_ecode[
:self.preferred_number_protocols]
self.active_amplitudes = self.active_amplitudes[
:self.preferred_number_protocols]
[docs]
def is_valid(self):
"""Check if the present AutoTarget has active targets (if matching
ephys data were found)"""
return bool(self.active_amplitudes) and bool(self.active_ecode)
[docs]
def generate_targets(self):
"""Build a list of targets in the format expected by the main
extraction function of BluePyEfe using the targets presently
active."""
targets = []
for amp, protocol_name in zip(
self.active_amplitudes, self.active_ecode):
for efeature in self.efeatures:
targets.append({
"efeature": efeature,
"protocol": protocol_name,
"amplitude": amp,
"tolerance": self.tolerance,
})
return targets
[docs]
def default_auto_targets():
"""Define a set of 3 generic AutoTarget for firing pattern properties,
AP waveform properties and hyperpolarizing step properties."""
auto_firing_pattern = AutoTarget(
protocols=["Step", "FirePattern", "IDrest", "IDRest", "IDthresh",
"IDThresh", "IDThres", "IDthres", "IV"],
amplitudes=[200, 150, 250, 300],
efeatures=['voltage_base',
'adaptation_index2',
'mean_frequency',
'time_to_first_spike',
'time_to_last_spike',
'inv_first_ISI',
'inv_second_ISI',
'inv_third_ISI',
'inv_fourth_ISI',
'inv_fifth_ISI',
'inv_last_ISI',
'ISI_CV',
'ISI_log_slope',
'doublet_ISI',
'AP_amplitude',
'AP1_amp',
'APlast_amp',
'AHP_depth',
'AHP_time_from_peak'],
min_recordings_per_amplitude=1,
preferred_number_protocols=2,
tolerance=25.,
)
auto_ap_waveform = AutoTarget(
protocols=["APWaveform", "APwaveform", "Step", "FirePattern",
"IDrest", "IDRest", "IDthresh", "IDThresh", "IDThres",
"IDthres", "IV"],
amplitudes=[300, 350, 250, 400, 200],
efeatures=["AP_amplitude",
"AP1_amp",
"AP2_amp",
'AP_width',
"AP_duration_half_width",
"AP_rise_time",
"AP_fall_time",
'AHP_depth_abs',
'AHP_time_from_peak',
"AHP_depth"],
min_recordings_per_amplitude=1,
preferred_number_protocols=1,
tolerance=25.,
)
auto_iv = AutoTarget(
protocols=["IV", "Step"],
amplitudes=[-50, -100],
efeatures=['voltage_base',
'steady_state_voltage_stimend',
'ohmic_input_resistance_vb_ssse',
'voltage_deflection',
'voltage_deflection_begin',
'decay_time_constant_after_stim',
'Spikecount',
'sag_ratio1',
'sag_ratio2',
'sag_amplitude',
'sag_time_constant'],
min_recordings_per_amplitude=1,
preferred_number_protocols=1,
tolerance=10.,
)
return [auto_firing_pattern, auto_ap_waveform, auto_iv]