dunno, long time ago changes
This commit is contained in:
parent
2665e166f9
commit
3ce3117d93
@ -12,17 +12,19 @@ We can easily record the responses to foreign-generated chirps but we are not ab
|
||||
|
||||
## Stimulus situation differs for self- and foreign generated chrips
|
||||
|
||||
The stimulus situation is remaredly different for self- vs other chirping. While the AM induced by the presence and the the chriping activity of a foreign fish depends strongly on the distance between the communication partners (i.e. the contrast), self-chirping will always affect the input to the electroreceptors. In the extreme, i.e. when chriping alone the AM is just the amplitude dip during the chirp.
|
||||
The stimulus situation is remarkedly different for self- chirping as compared to the situation in which the other fish chirps. While the AM induced by the presence and the chriping activity of a foreign fish depends strongly on the distance between the communication partners (i.e. the contrast), self-chirping will always affect the input to the own electroreceptors. In the extreme, i.e. when chriping alone the AM is just the amplitude dip during the chirp.
|
||||
|
||||

|
||||
|
||||
## P-unit simulations
|
||||
|
||||
We can still use simulations to test this ideaI test this using a P-unit model that was recently improved by a Master student in our Lab (Alexander Ott). In brief the model is a Leaky-Integrate-And-Fire neuron that contains an spike induced adaptation current, and a refractory period the code can be found in the **model.py** python script and is also available form our [gitub repository](https://github.com/bendalab/punitmodel). This model is driven by a signal that is the self-generated EOD + the foreign signal.
|
||||
We can still use simulations to test this idea using a P-unit model that was recently improved by a Master student in our Lab (Alexander Ott). In brief, the model is a Leaky-Integrate-And-Fire neuron that contains an spike induced adaptation current and a refractory period. The code can be found in the **model.py** python script and is also available form our [gitub repository](https://github.com/bendalab/punitmodel). This model is driven by a signal that is the self-generated EOD + the foreign signal.
|
||||
|
||||
The model more or less accurately models the baseline features of cells that were recorded in the lab. It is fitted to resemble the real cell with resect to the baseline firing rate, the coefficient of variation of the baseline interspike interval histogram, the vector strength and the the FI-curve, i.e. the neuron's sensitivity to a driving stimulus, the minimum as well as maximum firing rates, and the adaptation time-constant.
|
||||
The model more or less accurately reproduces the baseline features of cells that were recorded in the lab. It is fitted to resemble the real cell with resect to the baseline firing rate, the coefficient of variation of the baseline interspike interval histogram, the vector strength and the the FI-curve, i.e. the neuron's sensitivity to a driving stimulus, the minimum as well as maximum firing rates, and the adaptation time-constant.
|
||||
We have used such models also to recreate the responses to white-noise stimulation.
|
||||
|
||||
P-units will still be driven by the amplitude change during the slef chriping even if no other fish is present. The following figure shows this for a beat of 20 Hz, a chirp size of 100 Hz and an chirp induced amplitude dip of 5% for one example cell. The figure shows three conditions, chirping while nobody is around **soliloquy**, chirping while someone else is present **self chirping**, and the other fish is chriping **other chirping**. Top: illustration of the overall condition, second row, the combined signal of self-generated EOD and the foreign EOD. Red line is the AM. The remaining rows show the firing rate as a function of time. PSTHs are estimated using kernel convolution with a Gaussian kernel of 0.5ms standard deviation. Black lines are the averages across trials (25) and the gray area depict the across trial variability, i.e. the standard deviation of the firing rates across trials. C-values on the right are the contrasts, i.e. the strength of the foreign fish's EOD relative to the own EOD. The orange fish is the recorded fish, the EOD-frequency matches the one of fish in which we recorded the respective P-unit.
|
||||
P-units will still be driven by the amplitude change during the self chriping even if no other fish is present (soliloquy). The following figure shows this for a beat of 20 Hz, a chirp size of 100 Hz and an chirp induced amplitude dip of 5% for one example cell. The figure shows three conditions, chirping while nobody is around **soliloquy**, chirping while someone else is present **self chirping**, and there is another fish and the other fish is chriping **other chirping**. Top: illustration of the overall condition, second row, the combined signal of self-generated EOD and the foreign EOD. Red line is the AM. The remaining rows show the firing rate as a function of time. PSTHs are estimated using kernel convolution with a Gaussian kernel of 0.5ms standard deviation. Black lines are the averages across trials (n=25) and the gray area depicts the across trial variability, i.e. the standard deviation of the firing rates across trials. *C-values* on the right are the contrasts, i.e. the strength of the foreign fish's EOD relative to the own EOD. The orange fish is the recorded fish, the EOD-frequency matches the one of fish in which we recorded the respective P-unit.
|
||||
|
||||

|
||||
|
||||
## Foreign fish detection
|
||||
@ -38,8 +40,8 @@ The following comparisons are done. 
|
||||
|
||||
### ROC analysis example cell
|
||||
|
||||
The figure shows the results from the ROC analysis from one example cell. The rows are the comparisons (s.o.). The left column are the roc curves for all tested contrasts, it plots the rates of tru positives (correct classification) agains the rate of false positive (wrong classifications). If responses are indistinguishable the curve should follow the dashed diagonal line. From the ROC curve the area under the curve (**auc**) is plotted in the right column as a function of the contrast. The temporal resolution of the distance estimation is set by the Gaussian kernel used to estimate the firing rates and its std is 1ms in this for the ROC curves on the left. The temporal resolution has a strong impact on the discrimination performance.
|
||||
|
||||
The figure shows the results from the ROC analysis from one example cell. The rows are the comparisons (s.o.). The left column are the roc curves for all tested contrasts, it plots the rates of true positives (correct classification) against the rate of false positive (wrong classifications). If responses are indistinguishable, the curve should follow the dashed identity line. Colors show ROC curves estimated at different beat frequencies. From the ROC curve the area under the curve (**auc**) is plotted in the right column as a function of the contrast. The temporal resolution of the distance estimation is set by the Gaussian kernel used to estimate the firing rates and its standard deviation is set to 1ms for the ROC curves on the left. The temporal resolution has a strong impact on the discrimination performance. This is shown in the right column. (sigma is the standard deviation of the kernel, i.e. the temporal resolution)
|
||||
|
||||

|
||||
|
||||
### ROC analysis across cells and dfs
|
||||
@ -50,7 +52,7 @@ The figure below shows the discrimination performance as a function of the diffe
|
||||
|
||||

|
||||
|
||||
Basically the detection of a foreign fish's presence is easily done on the basis of the beat. It depends on the contrast, naturally, and saturates at alost perfect perfromance at high contrasts and low beats. The performance in this task directly depends on the Signal-To-Noise ratio and thus directly reflects the beat tunig curve. Good discriminability is is possible for "small" difference frequencies. At +- 200Hz discrimination is not possible on the basis of the beat response.
|
||||
Basically, the detection of a foreign fish's presence is easily done on the basis of the beat. It depends on the contrast, naturally, and saturates at alost perfect perfromance at high contrasts and low beats. The performance in this task directly depends on the Signal-To-Noise ratio and thus directly reflects the beat tunig curve. Good discriminability is is possible for "small" difference frequencies. At +- 200Hz discrimination is not possible on the basis of the beat response.
|
||||
|
||||
When we compare the self-chirping when no other animal is present it first of all seems that the overall performance is worse. There are however a few interesting effects:
|
||||
* it appears that detection of a foreigh fish extends to higher positive difference frequencies.
|
||||
|
48
plots.py
48
plots.py
@ -28,7 +28,7 @@ def plot_comparisons(args):
|
||||
return
|
||||
filename = files[0]
|
||||
nf = nix.File.open(filename, nix.FileMode.ReadOnly)
|
||||
block_map, all_contrasts, _, all_conditions = sort_blocks(nf)
|
||||
block_map, all_contrasts, _, _, all_conditions = sort_blocks(nf)
|
||||
conditions = ["no-other", "self", "other"]
|
||||
min_time = 0.5
|
||||
max_time = min_time + 0.5
|
||||
@ -103,7 +103,7 @@ def plot_comparisons(args):
|
||||
|
||||
def create_response_plot(filename, current_df=20, figure_name=None):
|
||||
nf = nix.File.open(filename, nix.FileMode.ReadOnly)
|
||||
block_map, all_contrasts, _, all_conditions = sort_blocks(nf)
|
||||
block_map, all_contrasts, _, _, all_conditions = sort_blocks(nf)
|
||||
|
||||
conditions = ["no-other", "self", "other"]
|
||||
condition_labels = ["soliloquy", "self chirping", "other chirping"]
|
||||
@ -259,12 +259,18 @@ def foreign_fish_detection_example_plot(args):
|
||||
|
||||
|
||||
def performance_plot(args):
|
||||
df = pd.read_csv(os.path.join(data_folder, "discrimination_results.csv"), sep=";")
|
||||
if not os.path.exists(args.inputfile):
|
||||
raise ValueError("Error plotting discrimination performance. Input file (%s) not found!" % args.inputfile)
|
||||
df = pd.read_csv(args.inputfile, sep=";")
|
||||
dfs = np.sort(df.df.unique())
|
||||
contrasts = np.sort(df.contrast.unique())
|
||||
tasks = df.detection_task.unique()
|
||||
kernel_widths = list(df.kernel_width.unique())
|
||||
kernel_width = args.kernel_width if args.kernel_width in kernel_widths else kernel_widths[0]
|
||||
chirpsizes = list(df.chirpsize.unique())
|
||||
if args.chirpsize not in chirpsizes:
|
||||
raise ValueError("Error plotting discrimination performance. Requested chirpsize (%i Hz) is not found in the data. Available chirpsizes are: " % args.chirpsize + str(chirpsizes))
|
||||
|
||||
X, Y = np.meshgrid(dfs, contrasts)
|
||||
Z = np.zeros_like(X)
|
||||
|
||||
@ -275,12 +281,13 @@ def performance_plot(args):
|
||||
ax.set_title(t, loc="left", pad=-0.5)
|
||||
for i, d in enumerate(dfs):
|
||||
for j, c in enumerate(contrasts):
|
||||
Z[j, i] = np.mean(df.auc[(df.kernel_width == kernel_width) & (df.contrast == c) & (df.df == d) & (df.detection_task == t)])
|
||||
|
||||
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, linewidth=0.2, edgecolor="white", antialiased=True, alpha=0.85, vmin=0.5, vmax=1.0)
|
||||
ax.set_xlabel(r"$\Delta_f [Hz]$")
|
||||
ax.set_ylabel("contrast [%]")
|
||||
ax.set_zlabel("performance")
|
||||
data_df = df[(df.kernel_width == kernel_width) & (df.contrast == c) & (df.df == d) & (df.detection_task == t) & (df.chirpsize == args.chirpsize)]
|
||||
Z[j, i] = np.mean(data_df.auc)
|
||||
|
||||
ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, linewidth=0.2, edgecolor="white", antialiased=True, alpha=0.85, vmin=0.5, vmax=1.0)
|
||||
ax.set_xlabel(r"$\Delta_f [Hz]$", fontsize=8)
|
||||
ax.set_ylabel("contrast [%]", fontsize=8)
|
||||
ax.set_zlabel("performance", fontsize=8, rotation=180)
|
||||
ax.set_zlim([0.45, 1.0])
|
||||
ax.set_zticks(np.arange(0.5, 1.01, 0.25))
|
||||
ax.set_zticks(np.arange(0.5, 1.01, 0.125), minor=True)
|
||||
@ -290,8 +297,9 @@ def performance_plot(args):
|
||||
errors = np.zeros_like(contrasts)
|
||||
for d in args.deltafs:
|
||||
for i, c in enumerate(contrasts):
|
||||
performances[i] = np.mean(df.auc[(df.kernel_width == kernel_width) & (df.contrast == c) & (df.df == d) & (df.detection_task == t)])
|
||||
errors[i] = np.std(df.auc[(df.kernel_width == kernel_width) & (df.contrast == c) & (df.df == d) & (df.detection_task == t)])
|
||||
data_df = df[(df.kernel_width == kernel_width) & (df.contrast == c) & (df.df == d) & (df.detection_task == t) & (df.chirpsize == args.chirpsize)]
|
||||
performances[i] = np.mean(data_df.auc)
|
||||
errors[i] = np.std(data_df.auc)
|
||||
cntrst_ax.errorbar(contrasts, performances, yerr=errors, fmt=".-", label=r"$\Delta_f:$ %i Hz" % d)
|
||||
cntrst_ax.set_ylim([0.25, 1.0])
|
||||
cntrst_ax.set_ylabel("performance", fontsize=8)
|
||||
@ -304,11 +312,12 @@ def performance_plot(args):
|
||||
errors = np.zeros_like(dfs)
|
||||
for c in args.contrasts:
|
||||
for i, d in enumerate(dfs):
|
||||
performances[i] = np.mean(df.auc[(df.kernel_width == kernel_width) & (df.contrast == c) & (df.df == d) & (df.detection_task == t)])
|
||||
errors[i] = np.std(df.auc[(df.kernel_width == kernel_width) & (df.contrast == c) & (df.df == d) & (df.detection_task == t)])
|
||||
data_df = df[(df.kernel_width == kernel_width) & (df.contrast == c) & (df.df == d) & (df.detection_task == t) & (df.chirpsize == args.chirpsize)]
|
||||
performances[i] = np.mean(data_df.auc)
|
||||
errors[i] = np.std(data_df.auc)
|
||||
df_ax.errorbar(dfs, performances, yerr=errors, fmt=".-", label="%.2f" % c)
|
||||
df_ax.set_ylim([0.25, 1.0])
|
||||
df_ax.set_ylabel("performance", fontsize=8, rotation=180)
|
||||
df_ax.set_ylabel("performance", fontsize=8)
|
||||
df_ax.set_xlabel(r"$\Delta_f$ [Hz]", fontsize=8)
|
||||
df_ax.hlines(0.5, dfs[0], dfs[-1], color="k", ls="--", lw=0.2)
|
||||
df_ax.legend(fontsize=7, ncol=4, frameon=False, loc="lower center", mode="expand", handlelength=1.0, handletextpad=0.25)
|
||||
@ -318,11 +327,7 @@ def performance_plot(args):
|
||||
plt.close()
|
||||
|
||||
|
||||
def main():
|
||||
cmd_map = {"comparisons": plot_comparisons,
|
||||
"response_examples": response_examples,
|
||||
"fish_detection_example": foreign_fish_detection_example_plot}
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Plotting tool for chrip probing project.")
|
||||
subparsers = parser.add_subparsers(title="commands",
|
||||
help="Sub commands for plotting different figures",
|
||||
@ -340,9 +345,12 @@ def main():
|
||||
|
||||
perf_parser = subparsers.add_parser("discrimination", help="plot discrimination performance across all cells")
|
||||
perf_parser.add_argument("-o", "--outfile", default=os.path.join(figure_folder, "discrimination_performances.pdf"), help="filename of the plot")
|
||||
infile = os.path.join(data_folder, "discrimination_results.csv")
|
||||
perf_parser.add_argument("-i", "--inputfile", default=infile , help="Filename of the file containing the discrimination results. Defaults to %s" % infile)
|
||||
perf_parser.add_argument("-k", "--kernel_width", type=float, default=0.001, help="Kernel width to choose for plotting")
|
||||
perf_parser.add_argument("-d", "--deltafs", type=float, nargs="+", default=[-100, 20, 100], help="deltaf for individual plot")
|
||||
perf_parser.add_argument("-d", "--deltafs", type=float, nargs="+", default=[-200, 5, 200], help="deltaf for individual plot")
|
||||
perf_parser.add_argument("-c", "--contrasts", type=float, nargs="+", default=[5, 10, 20], help="stimulus contrast for individual plot")
|
||||
perf_parser.add_argument("-cs", "--chirpsize", type=int, default=60, help="The chirpsize. Defaults to 60Hz.")
|
||||
perf_parser.set_defaults(func=performance_plot)
|
||||
|
||||
resps_parser = subparsers.add_parser("responses", help="plot responses from and example cell")
|
||||
|
@ -273,9 +273,7 @@ def process_cell(filename):
|
||||
print(filename)
|
||||
nf = nix.File.open(filename, nix.FileMode.ReadOnly)
|
||||
block_map, all_contrasts, all_dfs, all_chirpsizes, all_conditions = sort_blocks(nf)
|
||||
if "baseline" in block_map.keys():
|
||||
baseline_spikes = read_baseline(block_map["baseline"])
|
||||
else:
|
||||
if "baseline" not in block_map.keys():
|
||||
print("ERROR: no baseline data for file %s!" % filename)
|
||||
results = foreign_fish_detection(block_map, all_dfs, all_contrasts, all_conditions, all_chirpsizes,
|
||||
current_df=None, current_chirpsize=None,
|
||||
@ -293,7 +291,7 @@ def main():
|
||||
for pr in processed_list:
|
||||
results.extend(pr)
|
||||
df = pd.DataFrame(results)
|
||||
df.to_csv(os.path.join(data_folder, "discimination_results2.csv"), sep=";")
|
||||
df.to_csv(os.path.join(data_folder, "discrimination_results.csv"), sep=";")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Loading…
Reference in New Issue
Block a user