def _load_templates_from_file(path): template_store = load_template_store(path) templates = { k: template_store[k].to_template() # TODO be able to avoid the call to to_template. for k in template_store } return templates
def main(): # Parse command line. parser = argparse.ArgumentParser() parser.add_argument('--configuration', dest='pending_configuration', action='store_true', default=None) parser.add_argument('--generation', dest='pending_generation', action='store_true', default=None) parser.add_argument('--sorting', dest='pending_sorting', action='store_true', default=None) parser.add_argument('--introspection', dest='pending_introspection', action='store_true', default=None) parser.add_argument('--validation', dest='pending_validation', action='store_true', default=None) args = parser.parse_args() if args.pending_configuration is None and args.pending_generation is None \ and args.pending_sorting is None and args.pending_introspection is None \ and args.pending_validation is None: args.pending_configuration = True args.pending_generation = True args.pending_sorting = True args.pending_introspection = True args.pending_validation = False else: args.pending_configuration = args.pending_configuration is True args.pending_generation = args.pending_generation is True args.pending_sorting = args.pending_sorting is True args.pending_introspection = args.pending_introspection is True args.pending_validation = args.pending_validation is True # Define the working directory. directory = network.directory directory = os.path.expanduser(directory) if not os.path.isdir(directory): os.makedirs(directory) configuration_directory = os.path.join(directory, "configuration") if args.pending_configuration: # Clean the configuration directory (if necessary). if os.path.isdir(configuration_directory): shutil.rmtree(configuration_directory) os.makedirs(configuration_directory) # Generate configurations. for nb_cells in nb_cells_range: name = str(nb_cells) kwargs = { 'general': { 'duration': duration, 'name': name, }, 'probe': { 'mode': 'mea', 'nb_rows': nb_rows, 'nb_columns': nb_columns, 'radius': radius, }, 'cells': { 'nb_cells': nb_cells, } } configuration = circusort.io.generate_configuration(**kwargs) configuration_directory_ = os.path.join(configuration_directory, name) configuration.save(configuration_directory_) # Load configurations. configurations = circusort.io.get_configurations(configuration_directory) # Configure Matplotlib. plt.ioff() plt.style.use('seaborn-paper') # Process each configuration. for configuration in configurations: name = configuration['general']['name'] configuration_directory = os.path.join(directory, "configuration", name) generation_directory = os.path.join(directory, "generation", name) # Generate data (if necessary). if args.pending_generation: circusort.net.pregenerator( configuration_directory=configuration_directory, generation_directory=generation_directory) # Sort data (if necessary). if args.pending_sorting: network.sorting(name) # Introspect sorting (if necessary). if args.pending_introspection: block_names = network.block_names block_labels = { block_name: network.block_labels.get(block_name, block_name) for block_name in block_names } try: block_nb_buffers = network.block_nb_buffers except AttributeError: block_nb_buffers = {} showfliers = False duration_factors = OrderedDict() output_directory = os.path.join(directory, "output") if not os.path.isdir(output_directory): os.makedirs(output_directory) image_format = 'pdf' configuration_names = [ configuration['general']['name'] for configuration in configurations ] # Load data from each configuration. for configuration_name in configuration_names: generation_directory = os.path.join(directory, "generation", configuration_name) introspection_directory = os.path.join(directory, "introspection", configuration_name) # Load generation parameters. parameters = circusort.io.get_data_parameters(generation_directory) # Define parameters. nb_samples = parameters['general']['buffer_width'] sampling_rate = parameters['general']['sampling_rate'] # Load time measurements from disk. duration_factors[configuration_name] = OrderedDict() for block_name in block_names: measurements = circusort.io.load_time_measurements( introspection_directory, name=block_name) end_times = measurements.get('end', np.empty(shape=0)) start_times = measurements.get('start', np.empty(shape=0)) durations = end_times - start_times nb_buffers = block_nb_buffers.get(block_name, 1) duration_buffer = float( nb_buffers * nb_samples) / sampling_rate duration_factors_ = np.log10(durations / duration_buffer) duration_factors[configuration_name][ block_name] = duration_factors_ # Plot real-time performances of blocks for each condition (i.e. number of cells). for configuration_name in configuration_names: data = [ duration_factors[configuration_name][block_name] for block_name in block_names ] labels = [block_labels[block_name] for block_name in block_names] flierprops = { 'marker': 's', 'markersize': 1, 'markerfacecolor': 'k', 'markeredgecolor': 'k', } output_filename = "real_time_performances_{}.{}".format( configuration_name, image_format) output_path = os.path.join(output_directory, output_filename) fig, ax = plt.subplots(1, 1, num=0, clear=True) ax.set(yscale='log') ax_ = ax.twinx() ax_.boxplot(data, notch=True, whis=1.5, labels=labels, flierprops=flierprops, showfliers=showfliers) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax.set_ylim(10.0**np.array(ax_.get_ylim())) ax.set_ylabel("duration factor") ax.set_title( "Real-time performances ({} cells)".format(configuration_name)) fig.tight_layout() fig.savefig(output_path) # Plot real-time performances of conditions for each block. for block_name in block_names: data = [ duration_factors[configuration_name][block_name] for configuration_name in configuration_names ] flierprops = { 'marker': 's', 'markersize': 1, 'markerfacecolor': 'k', 'markeredgecolor': 'k', } output_filename = "real_time_performances_{}.{}".format( block_name, image_format) output_path = os.path.join(output_directory, output_filename) fig, ax = plt.subplots(1, 1, num=0, clear=True) ax.set(yscale='log') ax_ = ax.twinx() ax_.boxplot(data, notch=True, whis=1.5, labels=configuration_names, flierprops=flierprops, showfliers=showfliers) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax.set_ylim(10.0**np.array(ax_.get_ylim())) ax.set_xlabel("number of cells") ax.set_ylabel("duration factor") ax.set_title("Real-time performances ({})".format(block_name)) fig.tight_layout() fig.savefig(output_path) if len(configuration_names) == 1: configuration_name = configuration_names[0] # TODO clean the following copied lines. # Load data from each configuration. generation_directory = os.path.join(directory, "generation", configuration_name) introspection_directory = os.path.join(directory, "introspection", configuration_name) # # Load generation parameters. parameters = circusort.io.get_data_parameters(generation_directory) # # Define parameters. nb_samples = parameters['general']['buffer_width'] sampling_rate = parameters['general']['sampling_rate'] # # Load time measurements from disk. duration_factors_bis = OrderedDict() for block_name in block_names: measurements = circusort.io.load_time_measurements( introspection_directory, name=block_name) keys = [k for k in measurements.keys()] start_keys = [k for k in keys if k.endswith(u"_start")] end_keys = [k for k in keys if k.endswith(u"_end")] start_keys = [k[0:-len(u"_start")] for k in start_keys] end_keys = [k[0:-len(u"_end")] for k in end_keys] keys = [k for k in start_keys if k in end_keys] if keys: keys = [u""] + keys duration_factors_bis[block_name] = OrderedDict() for key in keys: start_key = u"start" if key == u"" else "{}_start".format( key) end_key = u"end" if key == u"" else "{}_end".format( key) start_times = measurements.get(start_key, np.empty(shape=0)) end_times = measurements.get(end_key, np.empty(shape=0)) durations = end_times - start_times nb_buffers = block_nb_buffers.get(block_name, 1) duration_buffer = float( nb_buffers * nb_samples) / sampling_rate duration_factors_bis_ = np.log10(durations / duration_buffer) duration_factors_bis[block_name][ key] = duration_factors_bis_ # Plot additional real-time performances of conditions for each block. for block_name in block_names: if block_name in duration_factors_bis: key_names = duration_factors_bis[block_name].keys() data = [ duration_factors_bis[block_name][k] for k in key_names ] flierprops = { 'marker': 's', 'markersize': 1, 'markerfacecolor': 'k', 'markeredgecolor': 'k', } output_filename = "real_time_performances_{}_bis.{}".format( block_name, image_format) output_path = os.path.join(output_directory, output_filename) fig, ax = plt.subplots(1, 1, num=0, clear=True) ax.set(yscale='log') ax_ = ax.twinx() ax_.boxplot(data, notch=True, whis=1.5, labels=key_names, flierprops=flierprops, showfliers=showfliers) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax.set_ylim(10.0**np.array(ax_.get_ylim())) xticklabels = [t[2] for t in ax.xaxis.iter_ticks()] ax.set_xticklabels(xticklabels, rotation=45, horizontalalignment='right') ax.set_xlabel("measurement") ax.set_ylabel("duration factor") ax.set_title( "Real-time performances ({})".format(block_name)) fig.tight_layout() fig.savefig(output_path) # Plot median real-time performances. output_filename = "median_real_time_performances.{}".format( image_format) output_path = os.path.join(output_directory, output_filename) fig, ax = plt.subplots(1, 1, num=0, clear=True) ax.set(yscale='log') ax_ = ax.twinx() x = [k for k, _ in enumerate(configuration_names)] for block_name in block_names: y = [ np.median(duration_factors[configuration_name][block_name]) for configuration_name in configuration_names ] label = block_labels[block_name] ax_.plot(x, y, marker='o', label=label) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax.set_ylim(10.0**np.array(ax_.get_ylim())) ax.set_xticks(x) ax.set_xticklabels(configuration_names) ax.set_xlabel("number of cells") ax.set_ylabel("median duration factor") ax.set_title("Median real-time performances") ax_.legend() fig.tight_layout() fig.savefig(output_path) # Validate sorting (if necessary). if args.pending_validation: configuration_names = [ configuration['general']['name'] for configuration in configurations ] # Load data from each configuration. for configuration_name in configuration_names: generation_directory = os.path.join(directory, "generation", configuration_name) sorting_directory = os.path.join(directory, "sorting", configuration_name) # Load generation parameters. parameters = circusort.io.get_data_parameters(generation_directory) # Define parameters. nb_channels = nb_rows * nb_columns sampling_rate = parameters['general']['sampling_rate'] print("# Loading data...") injected_cells = circusort.io.load_cells(generation_directory) from circusort.io.spikes import spikes2cells from circusort.io.template_store import load_template_store detected_spikes_path = os.path.join(sorting_directory, "spikes.h5") detected_spikes = circusort.io.load_spikes(detected_spikes_path) detected_templates_path = os.path.join(sorting_directory, "templates.h5") detected_templates = load_template_store(detected_templates_path) detected_cells = spikes2cells(detected_spikes, detected_templates) # Load the data. data_path = os.path.join(generation_directory, "data.raw") from circusort.io.datafile import load_datafile data = load_datafile(data_path, sampling_rate, nb_channels, 'int16', 0.1042) # Load the MADs (if possible). mads_path = os.path.join(sorting_directory, "mad.raw") if os.path.isfile(mads_path): from circusort.io.madfile import load_madfile mads = load_madfile(mads_path, 'float32', nb_channels, 1024, sampling_rate) else: mads = None # Load the peaks (if possible). peaks_path = os.path.join(sorting_directory, "peaks.h5") if os.path.isfile(peaks_path): from circusort.io.peaks import load_peaks peaks = load_peaks(peaks_path) else: peaks = None # Load the filtered data (if possible). filtered_data_path = os.path.join(sorting_directory, "data.raw") if os.path.isfile(filtered_data_path): from circusort.io.datafile import load_datafile filtered_data = load_datafile(filtered_data_path, sampling_rate, nb_channels, 'float32', 1.0) else: filtered_data = None ordering = True output_directory = os.path.join(directory, "output") image_format = 'pdf' # Compute the similarities between detected and injected cells. print("# Computing similarities...") similarities = detected_cells.compute_similarities(injected_cells) output_filename = "similarities_{}.{}".format( configuration_name, image_format) output_path = os.path.join(output_directory, output_filename) similarities.plot(ordering=ordering, path=output_path) # Compute the matches between detected and injected cells. print("# Computing matches...") t_min = 1.0 * 60.0 # s # discard the 1st minute t_max = None matches = detected_cells.compute_matches(injected_cells, t_min=t_min, t_max=t_max) output_filename = "matches_{}.{}".format(configuration_name, image_format) output_path = os.path.join(output_directory, output_filename) matches.plot(ordering=ordering, path=output_path) # Consider the match with the worst error. sorted_indices = np.argsort(matches.errors) sorted_index = sorted_indices[-1] match = matches[sorted_index] # # Determine if false positives or false negatives are dominant. # # r_fp = match.compute_false_positive_rate() # # r_fn = match.compute_false_negative_rate() # Collect the spike times associated to the false positives / negatives. from circusort.plt.base import plot_times_of_interest train_fn = match.collect_false_negatives() # Plot the reconstruction around these spike times (if necessary). if len(train_fn) > 0: times_of_interest = train_fn.sample(size=10) output_filename = "times_of_interest_{}.{}".format( configuration_name, image_format) output_path = os.path.join(output_directory, output_filename) plot_times_of_interest(data, times_of_interest, path=output_path, window=10e-3, cells=detected_cells, sampling_rate=sampling_rate, mads=mads, peaks=peaks, filtered_data=filtered_data) # Plot the reconstruction. from circusort.plt.cells import plot_reconstruction t = 2.0 * 60.0 # s # start time of the reconstruction plot d = 2.0 # s # duration of the reconstruction plot output_filename = "reconstruction_{}.{}".format( configuration_name, image_format) output_path = os.path.join(output_directory, output_filename) plot_reconstruction(detected_cells, t, t + d, sampling_rate, data, output=output_path, mads=mads, peaks=peaks, filtered_data=filtered_data) plt.show()
def main(): # Parse command line. parser = argparse.ArgumentParser() parser.add_argument('--configuration', dest='pending_configuration', action='store_true', default=None) parser.add_argument('--generation', dest='pending_generation', action='store_true', default=None) parser.add_argument('--sorting', dest='pending_sorting', action='store_true', default=None) parser.add_argument('--introspection', dest='pending_introspection', action='store_true', default=None) parser.add_argument('--validation', dest='pending_validation', action='store_true', default=None) args = parser.parse_args() if args.pending_configuration is None and args.pending_generation is None \ and args.pending_sorting is None and args.pending_introspection is None and args.pending_validation is None: args.pending_configuration = True args.pending_generation = True args.pending_sorting = True args.pending_introspection = True args.pending_validation = True else: args.pending_configuration = args.pending_configuration is True args.pending_generation = args.pending_generation is True args.pending_sorting = args.pending_sorting is True args.pending_introspection = args.pending_introspection is True args.pending_validation = args.pending_validation is True # Define the working directory. directory = network.directory directory = os.path.expanduser(directory) if not os.path.isdir(directory): os.makedirs(directory) configuration_directory = os.path.join(directory, "configuration") if args.pending_configuration: # Clean the configuration directory (if necessary). if os.path.isdir(configuration_directory): shutil.rmtree(configuration_directory) os.makedirs(configuration_directory) # Generate configurations. for nb_rows, nb_columns in zip(nb_rows_range, nb_columns_range): nb_electrodes = nb_rows * nb_columns name = str(nb_electrodes) kwargs = { 'general': { 'duration': duration, 'name': name, }, 'probe': { 'mode': 'mea', 'nb_rows': nb_rows, 'nb_columns': nb_columns, 'radius': radius, }, 'cells': { 'nb_cells': int(cell_density * float(nb_electrodes)), } } configuration = circusort.io.generate_configuration(**kwargs) configuration_directory_ = os.path.join(configuration_directory, name) configuration.save(configuration_directory_) # Load configurations. configurations = circusort.io.get_configurations(configuration_directory) # Configure Matplotlib. plt.ioff() plt.style.use('seaborn-paper') # Process each configuration. for configuration in configurations: name = configuration['general']['name'] configuration_directory = os.path.join(directory, "configuration", name) generation_directory = os.path.join(directory, "generation", name) # Generate data (if necessary). if args.pending_generation: circusort.net.pregenerator(configuration_directory=configuration_directory, generation_directory=generation_directory) # Sort data (if necessary). if args.pending_sorting: network.sorting(name) # Introspect sorting (if necessary). if args.pending_introspection: block_names = network.block_names block_groups = network.block_groups block_nb_buffers = network.block_nb_buffers showfliers = False durations = OrderedDict() duration_factors = OrderedDict() output_directory = os.path.join(directory, "output") if not os.path.isdir(output_directory): os.makedirs(output_directory) image_format = 'pdf' # image_format = 'png' configuration_names = [ configuration['general']['name'] for configuration in configurations ] # Load data from each configuration. for configuration_name in configuration_names: generation_directory = os.path.join(directory, "generation", configuration_name) introspection_directory = os.path.join(directory, "introspection", configuration_name) # Load generation parameters. parameters = circusort.io.get_data_parameters(generation_directory) # Define parameters. nb_samples = parameters['general']['buffer_width'] sampling_rate = parameters['general']['sampling_rate'] # Load time measurements from disk. durations[configuration_name] = OrderedDict() duration_factors[configuration_name] = OrderedDict() for block_name in block_names: measurements = circusort.io.load_time_measurements(introspection_directory, name=block_name) end_times = measurements.get('end', np.empty(shape=0)) start_times = measurements.get('start', np.empty(shape=0)) durations_ = end_times - start_times nb_buffers = block_nb_buffers[block_name] duration_buffer = float(nb_buffers * nb_samples) / sampling_rate duration_factors_ = np.log10(durations_ / duration_buffer) durations[configuration_name][block_name] = durations_ duration_factors[configuration_name][block_name] = duration_factors_ # Plot real-time performances of blocks for each condition. for configuration_name in configuration_names: data = [ duration_factors[configuration_name][block_name] for block_name in block_names ] flierprops = { 'marker': 's', 'markersize': 1, 'markerfacecolor': 'k', 'markeredgecolor': 'k', } output_filename = "real_time_performances_{}.{}".format(configuration_name, image_format) output_path = os.path.join(output_directory, output_filename) fig, ax = plt.subplots(1, 1, num=0, clear=True) ax.set(yscale='log') ax_ = ax.twinx() ax_.boxplot(data, notch=True, whis=1.5, labels=block_names, flierprops=flierprops, showfliers=showfliers) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax.set_ylim(10.0 ** np.array(ax_.get_ylim())) ax.set_ylabel("duration factor") ax.set_title("Real-time performances ({} channels)".format(configuration_name)) fig.tight_layout() fig.savefig(output_path) # Plot real-time performances of conditions for each block. for block_name in block_names: data = [ duration_factors[configuration_name][block_name] for configuration_name in configuration_names ] flierprops = { 'marker': 's', 'markersize': 1, 'markerfacecolor': 'k', 'markeredgecolor': 'k', } output_filename = "real_time_performances_{}.{}".format(block_name, image_format) output_path = os.path.join(output_directory, output_filename) fig, ax = plt.subplots(1, 1, num=0, clear=True) ax.set(yscale='log') ax_ = ax.twinx() ax_.boxplot(data, notch=True, whis=1.5, labels=configuration_names, flierprops=flierprops, showfliers=showfliers) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax.set_ylim(10.0 ** np.array(ax_.get_ylim())) ax.set_xlabel("number of channels") ax.set_ylabel("duration factor") ax.set_title("Real-time performances ({})".format(block_name)) fig.tight_layout() fig.savefig(output_path) # Plot median real-time performances. output_filename = "median_real_time_performances.{}".format(image_format) output_path = os.path.join(output_directory, output_filename) fig, ax = plt.subplots(1, 1, num=0, clear=True) ax.set(yscale='log') ax_ = ax.twinx() x = [ k for k, _ in enumerate(configuration_names) ] for block_name in block_names: y = [ np.median(duration_factors[configuration_name][block_name]) for configuration_name in configuration_names ] ax_.plot(x, y, marker='o', label=block_name) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax.set_ylim(10.0 ** np.array(ax_.get_ylim())) ax.set_xticks(x) ax.set_xticklabels(configuration_names) ax.set_xlabel("number of channels") ax.set_ylabel("median duration factor") ax.set_title("Median real-time performances") ax_.legend() fig.tight_layout() fig.savefig(output_path) # Plot real-time performances. output_filename = "real_time_performances.{}".format(image_format) output_path = os.path.join(output_directory, output_filename) mode = 'mean_and_standard_deviation' # mode = 'median_and_median_absolute_deviation' # fig, ax = plt.subplots(1, 1, num=0, clear=True) # fig, ax = plt.subplots(1, 1, figsize=(3.6, 2.4), num=1, clear=True) # fig, ax = plt.subplots(1, 1, figsize=(4.8, 4.8), num=1, clear=True) format_ = 'presentation' if format_ == 'presentation': figsize = (4.5, 5.5) # title_fs = 18 label_fs = 14 ticklabel_fs = 10 else: raise NotImplementedError() fig, ax = plt.subplots(1, 1, figsize=figsize, num=1, clear=True) ax.set(yscale='log') ax.tick_params(labelsize=ticklabel_fs) ax_ = ax.twinx() ax_.tick_params(labelsize=ticklabel_fs) x = [ k for k, _ in enumerate(configuration_names) ] # Compute y_min. y_min = float('inf') for block_group, block_names in block_groups.items(): d = { configuration_name: np.concatenate([ durations[configuration_name][block_name] / float(block_nb_buffers[block_name]) for block_name in block_names ]) for configuration_name in configuration_names } if mode == 'mean_and_standard_deviation': y = np.array([ np.mean(d[configuration_name]) for configuration_name in configuration_names ]) y_error = np.array([ np.std(d[configuration_name]) for configuration_name in configuration_names ]) elif mode == 'median_and_median_absolute_deviation': y = np.array([ np.median(d[configuration_name]) for configuration_name in configuration_names ]) y_error = np.array([ 1.4826 * np.median(np.abs(d[configuration_name] - y[k])) for k, configuration_name in enumerate(configuration_names) ]) else: raise ValueError("unexpected mode value: {}".format(mode)) y1 = y - y_error if np.any(y1 > 0.0): y_min = min(y_min, np.min(y1[y1 > 0.0])) # Plot everything. colors = { block_group: "C{}".format(k % 10) for k, block_group in enumerate(block_groups.keys()) } for block_group, block_names in block_groups.items(): d = { configuration_name: np.concatenate([ durations[configuration_name][block_name] / float(block_nb_buffers[block_name]) for block_name in block_names ]) for configuration_name in configuration_names } if mode == 'mean_and_standard_deviation': y = np.array([ np.mean(d[configuration_name]) for configuration_name in configuration_names ]) y_error = np.array([ np.std(d[configuration_name]) for configuration_name in configuration_names ]) elif mode == 'median_and_median_absolute_deviation': # Median and median absolute deviation. y = np.array([ np.median(d[configuration_name]) for configuration_name in configuration_names ]) y_error = np.array([ 1.4826 * np.median(np.abs(d[configuration_name] - y[k])) for k, configuration_name in enumerate(configuration_names) ]) else: raise ValueError("unexpected mode value: {}".format(mode)) color = colors[block_group] y1 = y - y_error y1[y1 <= 0.0] = y_min # i.e. replace negative values y1 = np.log10(y1) y2 = np.log10(y + y_error) ax_.fill_between(x, y1, y2, alpha=0.5, facecolor=color, edgecolor=None) ax_.plot(x, np.log10(y), color=color, marker='o', label=block_group) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax_.set_ylim(bottom=np.log10(y_min)) ax_.set_ylim(bottom=np.log10(y_min), top=0.0) ax.set_ylim(10.0 ** np.array(ax_.get_ylim())) ax.set_xticks(x) ax.set_xticklabels(configuration_names, fontsize=ticklabel_fs) # ax.set_xticklabels(["$2^{" + "{}".format(2 * i) + "}$" for i in [1, 2, 3, 4, 5]]) # Hide the right and top spines ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) ax_.spines['right'].set_visible(False) ax_.spines['top'].set_visible(False) # Add labels. ax.set_xlabel("number of channels", fontsize=label_fs) ax.set_ylabel("duration (s)", fontsize=label_fs) # ax.set_title("Real-time performances") ax_.legend(loc='center left', bbox_to_anchor=(1.0, 0.5), fontsize=ticklabel_fs) fig.tight_layout() fig.savefig(output_path) # Validate sorting (if necessary). if args.pending_validation: configuration_names = [ configuration['general']['name'] for configuration in configurations ] # Load data from each configuration. for configuration_name in configuration_names: figure_format = 'png' generation_directory = os.path.join(directory, "generation", configuration_name) sorting_directory = os.path.join(directory, "sorting", configuration_name) output_directory = os.path.join(directory, "output", configuration_name) if not os.path.isdir(output_directory): os.makedirs(output_directory) # Compute the interspike interval histograms of the generated spike trains (if necessary). output_directory_ = os.path.join(output_directory, "generated_interspike_interval_histograms") if not os.path.isdir(output_directory_): os.makedirs(output_directory_) cells = circusort.io.load_cells(generation_directory) # Compute the refractory period violation coefficients. nb_rpv = {} rpv = {} for cell_id in cells.ids: cell = cells[cell_id] train = cell.train nb_rpv[cell_id] = train.nb_refractory_period_violations() rpv[cell_id] = train.refractory_period_violation_coefficient() # Compute the interspike interval histograms. for cell_id in cells.ids: cell = cells[cell_id] train = cell.train nb_spikes = len(train) bin_counts, bin_edges = train.interspike_interval_histogram(bin_width=0.5, width=25.0) bar_centers = 0.5 * (bin_edges[:-1] + bin_edges[1:]) bar_heights = bin_counts bar_widths = bin_edges[1:] - bin_edges[:-1] fig, ax = plt.subplots() ax.bar(bar_centers, bar_heights, width=bar_widths) ax.axvline(x=2.0, color='black', linestyle='--') ax.set_xlim(bin_edges[0], bin_edges[-1]) ax.set_xlabel("interspike interval (ms)") ax.set_ylabel("number of intervals") if 100.0 * rpv[cell_id] > 1e-3: title_string = "ISIH of template {} (2 ms RPV: {:.3f}%, {}/{})" title = title_string.format(cell_id, 100.0 * rpv[cell_id], nb_rpv[cell_id], nb_spikes) else: title_string = "ISIH of template {} (2 ms RPV: <1e-3%, {}/{})" title = title_string.format(cell_id, nb_rpv[cell_id], nb_spikes) ax.set_title(title) fig.tight_layout() filename = "generated_interspike_interval_histogram_{}.{}".format(cell_id, figure_format) path = os.path.join(output_directory_, filename) fig.savefig(path) plt.close(fig) # Compute the auto-correlograms. output_directory_ = os.path.join(output_directory, "autocorrelograms") if not os.path.isdir(output_directory_): os.makedirs(output_directory_) spikes_path = os.path.join(sorting_directory, "spikes.h5") spikes = circusort.io.load_spikes(spikes_path) for cell_id in range(0, len(spikes)): cell = spikes.get_cell(cell_id) train = cell.train nb_spikes = len(train) bin_counts, bin_edges = train.auto_correlogram() bar_centers = (bin_edges[:-1] + bin_edges[1:]) / 2.0 bar_heights = bin_counts bar_widths = bin_edges[1:] - bin_edges[:-1] fig, ax = plt.subplots() ax.bar(bar_centers, bar_heights, width=bar_widths) ax.set_xlabel("lag (ms)") ax.set_ylabel("number of spikes") ax.set_title("Auto-correlogram of template {} ({} spikes)".format(cell_id, nb_spikes)) fig.tight_layout() filename = "autocorrelogram_{}.{}".format(cell_id, figure_format) path = os.path.join(output_directory_, filename) fig.savefig(path) plt.close(fig) # Compute the interspike interval histograms of the sorted spike trains (if necessary). output_directory_ = os.path.join(output_directory, "interspike_interval_histograms") if not os.path.isdir(output_directory_): os.makedirs(output_directory_) spikes_path = os.path.join(sorting_directory, "spikes.h5") spikes = circusort.io.load_spikes(spikes_path) # Compute the refractory period violation coefficients. nb_rpv = {} rpv = {} for cell_id in range(0, len(spikes)): cell = spikes.get_cell(cell_id) train = cell.train nb_rpv[cell_id] = train.nb_refractory_period_violations() rpv[cell_id] = train.refractory_period_violation_coefficient() # Compute the interspike interval histograms. for cell_id in range(0, len(spikes)): cell = spikes.get_cell(cell_id) train = cell.train nb_spikes = len(train) bin_counts, bin_edges = train.interspike_interval_histogram(bin_width=0.5, width=25.0) bar_centers = 0.5 * (bin_edges[:-1] + bin_edges[1:]) bar_heights = bin_counts bar_widths = bin_edges[1:] - bin_edges[:-1] fig, ax = plt.subplots() ax.bar(bar_centers, bar_heights, width=bar_widths) ax.axvline(x=2.0, color='black', linestyle='--') ax.set_xlim(bin_edges[0], bin_edges[-1]) ax.set_xlabel("interspike interval (ms)") ax.set_ylabel("number of intervals") if 100.0 * rpv[cell_id] > 1e-3: title_string = "ISIH of template {} (2 ms RPV: {:.3f}%, {}/{})" title = title_string.format(cell_id, 100.0 * rpv[cell_id], nb_rpv[cell_id], nb_spikes) else: title_string = "ISIH of template {} (2 ms RPV: <1e-3%, {}/{})" title = title_string.format(cell_id, nb_rpv[cell_id], nb_spikes) ax.set_title(title) fig.tight_layout() filename = "interspike_interval_histogram_{}.{}".format(cell_id, figure_format) path = os.path.join(output_directory_, filename) fig.savefig(path) plt.close(fig) # TODO compare the sorted spike trains with the generated spike trains. # TODO find the matching between sorted templates and detected templates based on: # TODO - template waveforms only? # TODO - spike trains only? # TODO - template waveforms and spike trains? injected_cells = circusort.io.load_cells(generation_directory) from circusort.io import load_spikes detected_spikes_path = os.path.join(sorting_directory, "spikes.h5") t_max = 10.0 * 60.0 # s detected_spikes = load_spikes(detected_spikes_path, t_max=t_max) from circusort.io.template_store import load_template_store detected_templates_path = os.path.join(sorting_directory, "templates.h5") detected_templates = load_template_store(detected_templates_path) from circusort.io.spikes import spikes2cells detected_cells = spikes2cells(detected_spikes, detected_templates) # Compute the similarities between detected and injected cells. print("# Computing similarities...") similarities = detected_cells.compute_similarities(injected_cells) ordering = True similarities_filename = "similarities.pdf" similarities_path = os.path.join(output_directory, similarities_filename) similarities.plot(ordering=ordering, path=similarities_path) # Compute the matches between detected and injected cells. print("# Computing matches...") t_min = 5.0 * 60.0 # s # discard the 5 first minutes t_max = 10.0 * 60.0 # s for cell in detected_cells: print("{}, {}, {}".format(cell.train.t_min, cell.train.t_max, cell.train.nb_times)) matches = detected_cells.compute_matches(injected_cells, t_min=t_min, t_max=t_max) ordering = True matches_filename = "matches.pdf" matches_path = os.path.join(output_directory, matches_filename) matches.plot(ordering=ordering, path=matches_path)
from circusort.io.probe import load_probe from circusort.io.template_store import load_template_store from circusort.io.cells import load_cells from circusort.io.spikes import load_spikes, spikes2cells from circusort.obj.cells import Cells from circusort.obj.cell import Cell from circusort.obj.train import Train from circusort.obj.amplitude import Amplitude templates = load_template_store('data/templates.h5', 'probe.prb') fitted_spikes = load_spikes('data/spikes.h5') # spikes_a = fitted_spikes.get_spike_data(t_min=0, t_max=100, indices=[0]) # train = Train(spikes_a['spike_times']) # amplitude = Amplitude(spikes_a['amplitudes'], spikes_a['spike_times']) b = Cells({}) for i in range(len(templates)): mytemplate = templates[i] new_cell = Cell(mytemplate, Train([]), Amplitude([], [])) b.append(new_cell) # b.append(a) # spikes_b = fitted_spikes.get_spike_data(t_min=100, t_max=120, indices=[0]) # b.add_spikes(spikes_b['spike_times'], spikes_b['amplitudes'], spikes_b['templates']) spikes_all = fitted_spikes.get_spike_data() b.add_spikes(spikes_all['spike_times'], spikes_all['amplitudes'], spikes_all['templates'])
def main(): # Parse command line. parser = argparse.ArgumentParser() parser.add_argument('--configuration', dest='pending_configuration', action='store_true', default=None) parser.add_argument('--generation', dest='pending_generation', action='store_true', default=None) parser.add_argument('--sorting', dest='pending_sorting', action='store_true', default=None) parser.add_argument('--introspection', dest='pending_introspection', action='store_true', default=None) parser.add_argument('--validation', dest='pending_validation', action='store_true', default=None) args = parser.parse_args() if args.pending_configuration is None and args.pending_generation is None \ and args.pending_sorting is None and args.pending_introspection is None \ and args.pending_validation is None: args.pending_configuration = True args.pending_generation = True args.pending_sorting = True args.pending_introspection = True args.pending_validation = True else: args.pending_configuration = args.pending_configuration is True args.pending_generation = args.pending_generation is True args.pending_sorting = args.pending_sorting is True args.pending_introspection = args.pending_introspection is True args.pending_validation = args.pending_validation is True # Define the working directory. directory = network.directory directory = os.path.expanduser(directory) if not os.path.isdir(directory): os.makedirs(directory) configuration_directory = os.path.join(directory, "configuration") if args.pending_configuration: # Clean the configuration directory (if necessary). if os.path.isdir(configuration_directory): shutil.rmtree(configuration_directory) os.makedirs(configuration_directory) # Generate configurations. for cell_density in cell_densities: nb_electrodes = nb_rows * nb_columns nb_cells = max(1, int(cell_density * float(nb_electrodes))) name = str(nb_cells) kwargs = { 'general': { 'duration': duration, 'name': name, }, 'probe': { 'mode': 'mea', 'nb_rows': nb_rows, 'nb_columns': nb_columns, 'radius': radius, }, 'cells': { 'nb_cells': nb_cells, } } configuration = circusort.io.generate_configuration(**kwargs) configuration_directory_ = os.path.join(configuration_directory, name) configuration.save(configuration_directory_) # Load configurations. configurations = circusort.io.get_configurations(configuration_directory) # Configure Matplotlib. plt.ioff() plt.style.use('seaborn-paper') # Process each configuration. for configuration in configurations: name = configuration['general']['name'] configuration_directory = os.path.join(directory, "configuration", name) generation_directory = os.path.join(directory, "generation", name) # Generate data (if necessary). if args.pending_generation: circusort.net.pregenerator(configuration_directory=configuration_directory, generation_directory=generation_directory) # Sort data (if necessary). if args.pending_sorting: network.sorting(name) # Introspect sorting (if necessary). if args.pending_introspection: block_names = network.block_names block_groups = network.block_groups block_nb_buffers = network.block_nb_buffers showfliers = False durations = OrderedDict() duration_factors = OrderedDict() output_directory = os.path.join(directory, "output") if not os.path.isdir(output_directory): os.makedirs(output_directory) image_format = 'pdf' configuration_names = [ configuration['general']['name'] for configuration in configurations ] # Load data from each configuration. for configuration_name in configuration_names: generation_directory = os.path.join(directory, "generation", configuration_name) introspection_directory = os.path.join(directory, "introspection", configuration_name) # Load generation parameters. parameters = circusort.io.get_data_parameters(generation_directory) # Define parameters. nb_samples = parameters['general']['buffer_width'] sampling_rate = parameters['general']['sampling_rate'] # Load time measurements from disk. durations[configuration_name] = OrderedDict() duration_factors[configuration_name] = OrderedDict() for block_name in block_names: measurements = circusort.io.load_time_measurements(introspection_directory, name=block_name) end_times = measurements.get('end', np.empty(shape=0)) start_times = measurements.get('start', np.empty(shape=0)) durations_ = end_times - start_times nb_buffers = block_nb_buffers[block_name] duration_buffer = float(nb_buffers * nb_samples) / sampling_rate duration_factors_ = np.log10(durations_ / duration_buffer) durations[configuration_name][block_name] = durations_ duration_factors[configuration_name][block_name] = duration_factors_ # Plot real-time performances of blocks for each condition (i.e. number of cells). for configuration_name in configuration_names: data = [ duration_factors[configuration_name][block_name] for block_name in block_names ] flierprops = { 'marker': 's', 'markersize': 1, 'markerfacecolor': 'k', 'markeredgecolor': 'k', } output_filename = "real_time_performances_{}.{}".format(configuration_name, image_format) output_path = os.path.join(output_directory, output_filename) fig, ax = plt.subplots(1, 1, num=0, clear=True) ax.set(yscale='log') ax_ = ax.twinx() ax_.boxplot(data, notch=True, whis=1.5, labels=block_names, flierprops=flierprops, showfliers=showfliers) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax.set_ylim(10.0 ** np.array(ax_.get_ylim())) ax.set_ylabel("duration factor") ax.set_title("Real-time performances ({} cells)".format(configuration_name)) fig.tight_layout() fig.savefig(output_path) # Plot real-time performances of conditions for each block. for block_name in block_names: data = [ duration_factors[configuration_name][block_name] for configuration_name in configuration_names ] flierprops = { 'marker': 's', 'markersize': 1, 'markerfacecolor': 'k', 'markeredgecolor': 'k', } output_filename = "real_time_performances_{}.{}".format(block_name, image_format) output_path = os.path.join(output_directory, output_filename) fig, ax = plt.subplots(1, 1, num=0, clear=True) ax.set(yscale='log') ax_ = ax.twinx() ax_.boxplot(data, notch=True, whis=1.5, labels=configuration_names, flierprops=flierprops, showfliers=showfliers) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax.set_ylim(10.0 ** np.array(ax_.get_ylim())) ax.set_xlabel("number of cells") ax.set_ylabel("duration factor") ax.set_title("Real-time performances ({})".format(block_name)) fig.tight_layout() fig.savefig(output_path) if len(configuration_names) == 1: configuration_name = configuration_names[0] # TODO clean the following copied lines. # Load data from each configuration. generation_directory = os.path.join(directory, "generation", configuration_name) introspection_directory = os.path.join(directory, "introspection", configuration_name) # # Load generation parameters. parameters = circusort.io.get_data_parameters(generation_directory) # # Define parameters. nb_samples = parameters['general']['buffer_width'] sampling_rate = parameters['general']['sampling_rate'] # # Load time measurements from disk. duration_factors_bis = OrderedDict() for block_name in block_names: measurements = circusort.io.load_time_measurements(introspection_directory, name=block_name) keys = [k for k in measurements.keys()] start_keys = [k for k in keys if k.endswith(u"_start")] end_keys = [k for k in keys if k.endswith(u"_end")] start_keys = [k[0:-len(u"_start")] for k in start_keys] end_keys = [k[0:-len(u"_end")] for k in end_keys] keys = [k for k in start_keys if k in end_keys] if keys: keys = [u""] + keys duration_factors_bis[block_name] = OrderedDict() for key in keys: start_key = u"start" if key == u"" else "{}_start".format(key) end_key = u"end" if key == u"" else "{}_end".format(key) start_times = measurements.get(start_key, np.empty(shape=0)) end_times = measurements.get(end_key, np.empty(shape=0)) durations = end_times - start_times nb_buffers = block_nb_buffers.get(block_name, 1) duration_buffer = float(nb_buffers * nb_samples) / sampling_rate duration_factors_bis_ = np.log10(durations / duration_buffer) duration_factors_bis[block_name][key] = duration_factors_bis_ # Plot additional real-time performances of conditions for each block. for block_name in block_names: if block_name in duration_factors_bis: key_names = duration_factors_bis[block_name].keys() data = [ duration_factors_bis[block_name][k] for k in key_names ] flierprops = { 'marker': 's', 'markersize': 1, 'markerfacecolor': 'k', 'markeredgecolor': 'k', } output_filename = "real_time_performances_{}_bis.{}".format(block_name, image_format) output_path = os.path.join(output_directory, output_filename) fig, ax = plt.subplots(1, 1, num=0, clear=True) ax.set(yscale='log') ax_ = ax.twinx() ax_.boxplot(data, notch=True, whis=1.5, labels=key_names, flierprops=flierprops, showfliers=showfliers) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax.set_ylim(10.0 ** np.array(ax_.get_ylim())) xticklabels = [t[2] for t in ax.xaxis.iter_ticks()] ax.set_xticklabels(xticklabels, rotation=45, horizontalalignment='right') ax.set_xlabel("measurement") ax.set_ylabel("duration factor") ax.set_title("Real-time performances ({})".format(block_name)) fig.tight_layout() fig.savefig(output_path) # Plot median real-time performances. output_filename = "median_real_time_performances.{}".format(image_format) output_path = os.path.join(output_directory, output_filename) fig, ax = plt.subplots(1, 1, num=0, clear=True) ax.set(yscale='log') ax_ = ax.twinx() x = [ k for k, _ in enumerate(configuration_names) ] for block_name in block_names: y = [ np.median(duration_factors[configuration_name][block_name]) for configuration_name in configuration_names ] ax_.plot(x, y, marker='o', label=block_name) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax.set_ylim(10.0 ** np.array(ax_.get_ylim())) ax.set_xticks(x) ax.set_xticklabels(configuration_names) ax.set_xlabel("number of cells") ax.set_ylabel("median duration factor") ax.set_title("Median real-time performances") ax_.legend() fig.tight_layout() fig.savefig(output_path) # Plot real-time performances. output_filename = "real_time_performances.{}".format(image_format) output_path = os.path.join(output_directory, output_filename) mode = 'mean_and_standard_deviation' # mode = 'median_and_median_absolute_deviation' fig, ax = plt.subplots(1, 1, num=0, clear=True) # fig, ax = plt.subplots(1, 1, figsize=(3.6, 2.4), num=1, clear=True) ax.set(yscale='log') ax_ = ax.twinx() x = [ k for k, _ in enumerate(configuration_names) ] # Compute y_min. y_min = float('inf') for block_group, block_names in block_groups.items(): d = { configuration_name: np.concatenate([ durations[configuration_name][block_name] / float(block_nb_buffers[block_name]) for block_name in block_names ]) for configuration_name in configuration_names } if mode == 'mean_and_standard_deviation': y = np.array([ np.mean(d[configuration_name]) for configuration_name in configuration_names ]) y_error = np.array([ np.std(d[configuration_name]) for configuration_name in configuration_names ]) elif mode == 'median_and_median_absolute_deviation': y = np.array([ np.median(d[configuration_name]) for configuration_name in configuration_names ]) y_error = np.array([ 1.4826 * np.median(np.abs(d[configuration_name] - y[k])) for k, configuration_name in enumerate(configuration_names) ]) else: raise ValueError("unexpected mode value: {}".format(mode)) y1 = y - y_error if np.any(y1 > 0.0): y_min = min(y_min, np.min(y1[y1 > 0.0])) # Plot everything. colors = { block_group: "C{}".format(k % 10) for k, block_group in enumerate(block_groups.keys()) } for block_group, block_names in block_groups.items(): d = { configuration_name: np.concatenate([ durations[configuration_name][block_name] / float(block_nb_buffers[block_name]) for block_name in block_names ]) for configuration_name in configuration_names } if mode == 'mean_and_standard_deviation': y = np.array([ np.mean(d[configuration_name]) for configuration_name in configuration_names ]) y_error = np.array([ np.std(d[configuration_name]) for configuration_name in configuration_names ]) elif mode == 'median_and_median_absolute_deviation': # Median and median absolute deviation. y = np.array([ np.median(d[configuration_name]) for configuration_name in configuration_names ]) y_error = np.array([ 1.4826 * np.median(np.abs(d[configuration_name] - y[k])) for k, configuration_name in enumerate(configuration_names) ]) else: raise ValueError("unexpected mode value: {}".format(mode)) color = colors[block_group] y1 = y - y_error y1[y1 <= 0.0] = y_min # i.e. replace negative values y1 = np.log10(y1) y2 = np.log10(y + y_error) ax_.fill_between(x, y1, y2, alpha=0.5, facecolor=color, edgecolor=None) ax_.plot(x, np.log10(y), color=color, marker='o', label=block_group) ax_.set_yticks([]) ax_.set_yticklabels([]) ax_.set_ylabel("") ax_.set_ylim(bottom=np.log10(y_min)) # ax_.set_ylim(bottom=np.log10(y_min), top=0.0) ax.set_ylim(10.0 ** np.array(ax_.get_ylim())) ax.set_xticks(x) ax.set_xticklabels(configuration_names) # ax.set_xticklabels(["$2^{" + "{}".format(2 * i) + "}$" for i in [1, 2, 3, 4, 5]]) ax.set_xlabel("number of cells") ax.set_ylabel("duration (s)") ax.set_title("Real-time performances") ax_.legend(loc='center left', bbox_to_anchor=(1.0, 0.5)) fig.tight_layout() fig.savefig(output_path) # Validate sorting (if necessary). if args.pending_validation: configuration_names = [ configuration['general']['name'] for configuration in configurations ] # Load data from each configuration. for configuration_name in configuration_names: generation_directory = os.path.join(directory, "generation", configuration_name) sorting_directory = os.path.join(directory, "sorting", configuration_name) output_directory = os.path.join(directory, "output") if not os.path.isdir(output_directory): os.makedirs(output_directory) # Load generation parameters. parameters = circusort.io.get_data_parameters(generation_directory) # Define parameters. nb_channels = nb_rows * nb_columns sampling_rate = parameters['general']['sampling_rate'] print("# Loading data...") injected_cells = circusort.io.load_cells(generation_directory) from circusort.io.spikes import spikes2cells from circusort.io.template_store import load_template_store detected_spikes_path = os.path.join(sorting_directory, "spikes.h5") t_min = 0.0 # s t_max = duration detected_spikes = circusort.io.load_spikes(detected_spikes_path, t_min=t_min, t_max=t_max) detected_templates_path = os.path.join(sorting_directory, "templates.h5") detected_templates = load_template_store(detected_templates_path) detected_cells = spikes2cells(detected_spikes, detected_templates) # Load the data. data_path = os.path.join(generation_directory, "data.raw") from circusort.io.datafile import load_datafile data = load_datafile(data_path, sampling_rate, nb_channels, 'int16', 0.1042) # Load the probe. probe_path = os.path.join(generation_directory, "probe.prb") probe = circusort.io.load_probe(probe_path) # Load the MADs (if possible). mads_path = os.path.join(sorting_directory, "mad.raw") if os.path.isfile(mads_path): from circusort.io.madfile import load_madfile mads = load_madfile(mads_path, 'float32', nb_channels, 1024, sampling_rate) else: mads = None # Load the peaks (if possible). peaks_path = os.path.join(sorting_directory, "peaks.h5") if os.path.isfile(peaks_path): from circusort.io.peaks import load_peaks peaks = load_peaks(peaks_path) else: peaks = None # Load the filtered data (if possible). filtered_data_path = os.path.join(sorting_directory, "data.raw") if os.path.isfile(filtered_data_path): from circusort.io.datafile import load_datafile filtered_data = load_datafile(filtered_data_path, sampling_rate, nb_channels, 'float32', 1.0) else: filtered_data = None ordering = True image_format = 'pdf' # Plot probe. output_probe_filename = "probe_{}.{}".format(configuration_name, image_format) output_probe_path = os.path.join(output_directory, output_probe_filename) if not os.path.isfile(output_probe_path): probe.plot(path=output_probe_path) # Compute the similarities between detected and injected cells. # figsize = (2.25, 2.25) # slide figsize = (4.0, 3.5) # poster ticklabel_fontsize = 14 # poster label_fontsize = 18 # poster title_fontsize = 22 # poster similarities_filename = "similarities_{}.{}".format(configuration_name, image_format) similarities_path = os.path.join(output_directory, similarities_filename) if not os.path.isfile(similarities_path): print("# Computing similarities...") similarities_cache_filename = "similarities_{}.npz".format(configuration_name) similarities_cache_path = os.path.join(output_directory, similarities_cache_filename) similarities = detected_cells.compute_similarities(injected_cells, path=similarities_cache_path) similarities.plot(ordering=ordering, path=similarities_path, figsize=figsize, title_fontsize=title_fontsize, label_fontsize=label_fontsize, ticklabel_fontsize=ticklabel_fontsize) # Compute the matches between detected and injected cells. # figsize = (4.5, 2.25) # slide figsize = (4.0, 3.5) # poster matches_filename = "matches_{}.{}".format(configuration_name, image_format) matches_path = os.path.join(output_directory, matches_filename) matches_curve_filename = "matches_curve_{}.{}".format(configuration_name, image_format) matches_curve_path = os.path.join(output_directory, matches_curve_filename) if not os.path.isfile(matches_path) or not os.path.isfile(matches_curve_path): print("# Computing matches...") matches_cache_filename = "matches_{}.npz".format(configuration_name) matches_cache_path = os.path.join(output_directory, matches_cache_filename) matches = detected_cells.compute_matches(injected_cells, t_min=t_min, t_max=t_max, path=matches_cache_path) if not os.path.isfile(matches_path): matches.plot(ordering=ordering, path=matches_path) if not os.path.isfile(matches_curve_path): matches.plot_curve(path=matches_curve_path, figsize=figsize) # # Consider the match with the worst error. # sorted_indices = np.argsort(matches.errors) # sorted_index = sorted_indices[-1] # match = matches[sorted_index] # # Determine if false positives or false negatives are dominant. # # r_fp = match.compute_false_positive_rate() # # r_fn = match.compute_false_negative_rate() # # Collect the spike times associated to the false positives / negatives. # from circusort.plt.base import plot_times_of_interest # train_fn = match.collect_false_negatives() # # Plot the reconstruction around these spike times (if necessary). # if len(train_fn) > 0: # times_of_interest = train_fn.sample(size=10) # times_of_interest_filename = "times_of_interest_{}.{}".format(configuration_name, image_format) # times_of_interest_path = os.path.join(output_directory, times_of_interest_filename) # plot_times_of_interest(data, times_of_interest, # window=10e-3, cells=detected_cells, sampling_rate=sampling_rate, # mads=mads, peaks=peaks, filtered_data=filtered_data, # path=times_of_interest_path) # Plot the reconstruction. # figsize = (4.5, 4.5) # slide figsize = (8.0, 3.5) # poster reconstruction_filename = "reconstruction_{}.{}".format(configuration_name, image_format) reconstruction_path = os.path.join(output_directory, reconstruction_filename) if not os.path.isfile(reconstruction_path): print("# Computing reconstruction...") t = 5.0 * 60.0 # s # start time of the reconstruction plot d = 0.3 # s # duration of the reconstruction plot nb_channels_max = 8 if nb_channels > nb_channels_max: channels = np.random.choice(nb_channels, size=nb_channels_max, replace=False) channels = np.sort(channels) else: channels = None buffer_width = 1024 plot_reconstruction(detected_cells, t, t + d, sampling_rate, data, channels=channels, mads=mads, peaks=peaks, filtered_data=filtered_data, buffer_width=buffer_width, output=reconstruction_path, figsize=figsize) # TODO plot the highest similarity with another template against the false negative rate. sim_vs_fnr_filename = "sim_vs_fnr_{}.{}".format(configuration_name, image_format) sim_vs_fnr_path = os.path.join(output_directory, sim_vs_fnr_filename) if not os.path.isfile(sim_vs_fnr_path): print("# Computing sim. v.s. FNR...") # Retrieve the template similarities. similarities_cache_filename = "similarities_{}.npz".format(configuration_name) similarities_cache_path = os.path.join(output_directory, similarities_cache_filename) similarities = detected_cells.compute_similarities(injected_cells, path=similarities_cache_path) # Retrieve the best matching between templates. matches_cache_filename = "matches_{}.npz".format(configuration_name) matches_cache_path = os.path.join(output_directory, matches_cache_filename) matches = detected_cells.compute_matches(injected_cells, t_min=t_min, t_max=t_max, path=matches_cache_path) # Plot similarity v.s. FNR. x = 100.0 * matches.false_negative_rates y = similarities.highest_similarities(num=2) y = y[:, 1] # y = np.mean(y, axis=1) fig, ax = plt.subplots() ax.scatter(x, y, s=5, color='black') ax.set_xlabel("false negative rate (%)") ax.set_ylabel("2nd highest similarity (arb. unit)") fig.tight_layout() fig.savefig(sim_vs_fnr_path) plt.close(fig) # TODO plot the templates with worst FNR. worst_fnr_filename = "worst_fnr_{}.{}".format(configuration_name, image_format) worst_fnr_path = os.path.join(output_directory, worst_fnr_filename) if not os.path.isfile(worst_fnr_path): print("# Computing worst FNRs...") # Retrieve the best matching between templates. matches_cache_filename = "matches_{}.npz".format(configuration_name) matches_cache_path = os.path.join(output_directory, matches_cache_filename) matches = detected_cells.compute_matches(injected_cells, t_min=t_min, t_max=t_max, path=matches_cache_path) # Find the worst FNR. fnrs = matches.false_negative_rates index = np.argmax(fnrs) match = matches[index] sorted_cell, injected_cell = match.get_cells() sorted_template = sorted_cell.template injected_template = injected_cell.template probe_filename = "probe.prb" probe_path = os.path.join(generation_directory, probe_filename) probe = circusort.io.load_probe(probe_path) # Plot templates with worst FNR. fig, ax = plt.subplots(ncols=2) sorted_template.plot(ax=ax[0], output=worst_fnr_path, probe=probe, time_factor=25.0) injected_template.plot(ax=ax[1], output=worst_fnr_path, probe=probe, time_factor=25.0) plt.close(fig) # TODO plot template norm against the false negative rates. norm_vs_fnr_filename = "norm_vs_fnr_{}.{}".format(configuration_name, image_format) norm_vs_fnr_path = os.path.join(output_directory, norm_vs_fnr_filename) if not os.path.isfile(norm_vs_fnr_path): print("# Computing norm v.s. FNR...") # Retrieve the best matching between templates. matches_cache_filename = "matches_{}.npz".format(configuration_name) matches_cache_path = os.path.join(output_directory, matches_cache_filename) matches = detected_cells.compute_matches(injected_cells, t_min=t_min, t_max=t_max, path=matches_cache_path) # Plot template norm against FNR. x = 100.0 * matches.false_negative_rates y = np.array([cell.template.norm for cell in detected_cells]) fig, ax = plt.subplots() ax.scatter(x, y, s=5, color='black') ax.set_xlabel("false negative rate (%)") ax.set_ylabel("template norm (arb. unit)") ax.set_title("Template norm against false negative rate") fig.tight_layout() fig.savefig(norm_vs_fnr_path) plt.close(fig) # TODO plot template amplitude against the false negative rates. ampl_vs_fnr_filename = "ampl_vs_fnr_{}.{}".format(configuration_name, image_format) ampl_vs_fnr_path = os.path.join(output_directory, ampl_vs_fnr_filename) if not os.path.isfile(ampl_vs_fnr_path): print("# Computing amplitude v.s. FNR") # Retrieve the best matching between templates. matches_cache_filename = "matches_{}.npz".format(configuration_name) matches_cache_path = os.path.join(output_directory, matches_cache_filename) matches = detected_cells.compute_matches(injected_cells, t_min=t_min, t_max=t_max, path=matches_cache_path) # Plot template norm against FNR. x = 100.0 * matches.false_negative_rates y = np.array([cell.template.peak_amplitude() for cell in detected_cells]) # z = detected_cells.ids fig, ax = plt.subplots(figsize=(4.5, 2.25)) ax.scatter(x, y, s=5, color='black') # for x_, y_, z_ in zip(x, y, z): # ax.annotate(z_, (x_, y_), fontsize=1, color='grey', # verticalalignment='center', horizontalalignment='center') ax.set_xlabel("false negative rate (%)") ax.set_ylabel("template amplitude (µV)") ax.set_title("Template amplitude against false negative rate") fig.tight_layout() fig.savefig(ampl_vs_fnr_path) plt.close(fig) # TODO plot false negative count through time. fnr_filename = "fnr_{}.{}".format(configuration_name, image_format) fnr_path = os.path.join(output_directory, fnr_filename) if not os.path.isfile(fnr_path): print("# Computing FN counts through time...") # Retrieve the best matching between templates. matches_cache_filename = "matches_{}.npz".format(configuration_name) matches_cache_path = os.path.join(output_directory, matches_cache_filename) matches = detected_cells.compute_matches(injected_cells, t_min=t_min, t_max=t_max, path=matches_cache_path) # Plot FNR through time. mode = 'sorted' x, y, z = matches.false_negative_counts(nb_bins=100) if mode == 'sorted': i = np.argsort(matches.false_negative_rates) z = z[i, :] fig, ax = plt.subplots(figsize=(4.5, 2.25)) c = ax.pcolor(x, y, z) ax.set_xlabel("time (s)") ax.set_ylabel("detected unit") ax.set_title("False negative count through time") cbar = fig.colorbar(c, ax=ax) cbar.set_label("false negative count") fig.tight_layout() fig.savefig(fnr_path) plt.close(fig) # TODO plot the templates with worst FNR. nb_worst_templates = 10 worst_fnr_paths = {} for k in range(0, nb_worst_templates): worst_fnr_filename = "worst_fnr_{}_{}.{}".format(configuration_name, k, image_format) worst_fnr_paths[k] = os.path.join(output_directory, worst_fnr_filename) if np.any([not os.path.isfile(path) for path in worst_fnr_paths.values()]): # Retrieve the best matching between templates. matches_cache_filename = "matches_{}.npz".format(configuration_name) matches_cache_path = os.path.join(output_directory, matches_cache_filename) matches = detected_cells.compute_matches(injected_cells, t_min=t_min, t_max=t_max, path=matches_cache_path) # Find the worst FNRs. fnrs = matches.false_negative_rates indices = np.argsort(fnrs) for k in range(0, nb_worst_templates): if not os.path.isfile(worst_fnr_paths[k]): index = indices[-k-1] match = matches[index] sorted_cell, injected_cell = match.get_cells() sorted_template = sorted_cell.template injected_template = injected_cell.template probe_filename = "probe.prb" probe_path = os.path.join(generation_directory, probe_filename) probe = circusort.io.load_probe(probe_path) # Plot templates with worst FNR. fig, ax = plt.subplots(ncols=2) sorted_template.plot(ax=ax[0], output=worst_fnr_paths[k], probe=probe, time_factor=25.0, voltage_factor=0.5) injected_template.plot(ax=ax[1], output=worst_fnr_paths[k], probe=probe, time_factor=25.0, voltage_factor=0.5) plt.close(fig) # TODO plot the templates with best FNR. nb_best_templates = 10 best_fnr_paths = {} for k in range(0, nb_best_templates): best_fnr_filename = "best_fnr_{}_{}.{}".format(configuration_name, k, image_format) best_fnr_paths[k] = os.path.join(output_directory, best_fnr_filename) if np.any([not os.path.isfile(path) for path in best_fnr_paths.values()]): # Retrieve the best matching between templates. matches_cache_filename = "matches_{}.npz".format(configuration_name) matches_cache_path = os.path.join(output_directory, matches_cache_filename) matches = detected_cells.compute_matches(injected_cells, t_min=t_min, t_max=t_max, path=matches_cache_path) # Find the best FNRs. fnrs = matches.false_negative_rates indices = np.argsort(fnrs) for k in range(0, nb_best_templates): if not os.path.isfile(best_fnr_paths[k]): index = indices[k] match = matches[index] sorted_cell, injected_cell = match.get_cells() sorted_template = sorted_cell.template injected_template = injected_cell.template probe_filename = "probe.prb" probe_path = os.path.join(generation_directory, probe_filename) probe = circusort.io.load_probe(probe_path) # Plot templates with best FNR. fig, ax = plt.subplots(ncols=2) sorted_template.plot(ax=ax[0], output=best_fnr_paths[k], probe=probe, time_factor=25.0, voltage_factor=0.5) injected_template.plot(ax=ax[1], output=best_fnr_paths[k], probe=probe, time_factor=25.0, voltage_factor=0.5) plt.close(fig)
p = load_probe( '/home/pierre/.spyking-circus-ort/benchmarks/%s/generation/probe.prb' % data_path) generation_directory = os.path.join("~", ".spyking-circus-ort", "benchmarks", data_path) probe_path = os.path.join(generation_directory, "probe.prb") similarity_thresh = 0.9 print('Loading data...') injected_cells = load_cells(os.path.join(generation_directory, 'generation')) fitted_spikes = load_spikes( os.path.join(os.path.join(generation_directory, 'sorting'), 'spikes.h5')) found_templates = load_template_store( os.path.join(os.path.join(generation_directory, 'sorting'), 'templates.h5')) fitted_cells = spikes2cells(fitted_spikes, found_templates) filename = os.path.join(os.path.join(generation_directory, 'generation'), 'data.raw') data_file = load_datafile(filename, 20000, p.nb_channels, 'int16', 0.1042) print('Computing similarities...') similarities = injected_cells.compute_similarities(fitted_cells) print('Computing matches...') matches = injected_cells.compute_matches(fitted_cells) # injected_cells[0].template.plot(probe=p) # found_templates[matches[0][0]].plot(probe=p)