def make(self, key): """ Pseudocode for process: 1) Get the segment id from the key 2) Get the decomposed neurong object from Decomposition table 3) Run the multi_soma split suggestions algorithm 4) Get the number of splits required for this neuron 5) Split the neuron into a list of neuron objects 6) For each neuron object in the list: - get the number of errored limbs (to indicate the success type) - Change the description to include the multiplicity - Compute the information on the largest soma faces and volume - Save the neuron object to the external - Add the new write key to a list to commit 7) Write all of the keys """ whole_pass_time = time.time() # 1) Get the segment id from the key segment_id = key["segment_id"] print(f"\n\n\n---- Working on Neuron {key['segment_id']} ----") # 2) Get the decomposed neuron object from Decomposition table and the split suggestions neuron_obj_path = (minnie.Decomposition & key).fetch1("decomposition") neuron_obj = du.filepath_to_neuron_obj(neuron_obj_path) """ Old way that downloaded from another table # 3) Retrieve the multi soma suggestions split_results = (minnie.NeuronSplitSuggestions & key).fetch1("split_results") """ #3) Calculated the split results split_results = pru.multi_soma_split_suggestions( neuron_obj, plot_intermediates=False) # 4) Get the number of splits required for this neuron n_paths_cut = pru.get_n_paths_cut(split_results) if verbose: print(f"n_paths_cut = {n_paths_cut}") # 5) Split the neuron into a list of neuron objects (neuron_list, neuron_list_errored_limbs_area, neuron_list_errored_limbs_skeletal_length, neuron_list_n_multi_soma_errors, neuron_list_n_same_soma_errors) = pru.split_neuron( neuron_obj, limb_results=split_results, verbose=verbose, return_error_info=True) print(f"neuron_list = {neuron_list}") print( f"neuron_list_errored_limbs_area = {neuron_list_errored_limbs_area}" ) print( f"neuron_list_n_multi_soma_errors = {neuron_list_n_multi_soma_errors}" ) print( f"neuron_list_n_same_soma_errors = {neuron_list_n_same_soma_errors}" ) if verbose: print(f"Number of neurons: {len(neuron_list)}") neuron_entries = [] for neuron_idx in range(len(neuron_list)): """ # 6) For each neuron object in the list: # - get the number of errored limbs (to indicate the success type) # - Compute the information on the largest soma faces and volume # - Save the neuron object to the external # - Add the new write key to a list to commit """ n = neuron_list[neuron_idx] error_imbs_cancelled_area = neuron_list_errored_limbs_area[ neuron_idx] error_imbs_cancelled_skeletal_length = neuron_list_errored_limbs_skeletal_length[ neuron_idx] n_multi_soma_limbs_cancelled = neuron_list_n_multi_soma_errors[ neuron_idx] n_same_soma_limbs_cancelled = neuron_list_n_same_soma_errors[ neuron_idx] #for n in neuron_list: # nviz.visualize_neuron(n, # limb_branch_dict="all") # - get the number of errored limbs (to indicate the success type) if n.n_error_limbs == 0: split_success = 0 elif n.multi_soma_touching_limbs == 0: split_successs = 1 elif n.same_soma_multi_touching_limbs == 0: split_success = 2 else: split_success = 3 if verbose: print(f"split_success = {split_success}") # - Compute the information on the largest soma faces and volume soma_volumes = [ n[k].volume / 1000000000 for k in n.get_soma_node_names() ] soma_n_faces = [ len(n[k].mesh.faces) for k in n.get_soma_node_names() ] largest_n_faces = np.max(soma_n_faces) largest_volume = np.max(soma_volumes) if verbose: print(f"largest_n_faces = {largest_n_faces}") print(f"largest_volume = {largest_volume}") if "split" not in n.description: n.description += "_soma_0_split" #6) Save the file in a certain location if True: save_time = time.time() ret_file_path = n.save_compressed_neuron(output_folder=str( du.get_decomposition_path()), return_file_path=True, export_mesh=False, suppress_output=True) ret_file_path_str = str(ret_file_path.absolute()) + ".pbz2" print(f"Save time = {time.time() - save_time}") else: print("Storing a dummy value for neuron") ret_file_path_str = "dummy" #7) Pass stats and file location to insert new_key = dict( key, split_index=neuron_idx, split_version=split_version, multiplicity=len(neuron_list), n_splits=n_paths_cut, split_success=split_success, n_error_limbs_cancelled=len(error_imbs_cancelled_area), n_multi_soma_limbs_cancelled=n_multi_soma_limbs_cancelled, n_same_soma_limbs_cancelled=n_same_soma_limbs_cancelled, error_imbs_cancelled_area=np.round( np.sum(error_imbs_cancelled_area), 4), error_imbs_cancelled_skeletal_length=np.round( np.sum(error_imbs_cancelled_skeletal_length) / 1000, 4), split_results=split_results, max_soma_n_faces=largest_n_faces, max_soma_volume=largest_volume, decomposition=ret_file_path_str, n_vertices=len(n.mesh.vertices), n_faces=len(n.mesh.faces), run_time=np.round(time.time() - whole_pass_time, 4)) stats_dict = n.neuron_stats() new_key.update(stats_dict) attributes_to_remove = ["axon_length", "axon_area", "n_boutons"] for k in attributes_to_remove: del new_key[k] neuron_entries.append(new_key) self.insert(neuron_entries, allow_direct_insert=True, skip_duplicates=True) print( f"\n\n ------ Total time for {segment_id} = {time.time() - whole_pass_time} ------" )
def make(self, key): """ Purpose: To decimate a mesh by a perscribed decimation ratio and algorithm Pseudocode: 1) Fetch neuron object 2) Get the parameters for the mesh split 3) Calculate the split results 4) Apply the split results to the neuron 5) Save the neuron and write to the table (including the skeleton table) """ global_time = time.time() segment_id = key["segment_id"] decomposition_split_hash = key["decomposition_split_method"] ver = key["ver"] if verbose: print( f"\n\n--Working on {segment_id}: (decomposition_split_hash = " f"{decomposition_split_hash})") #1) Fetch neuron object st = time.time() neuron_obj = hdju.neuron_obj_from_table( segment_id=segment_id, table=h01auto.Decomposition.Object(), verbose=True, return_one=True, ) if verbose: print(f"Downloading Neuron Object: {time.time() - st}") if plotting: nviz.plot_soma_limb_concept_network(neuron_obj) for limb_idx in nru.error_limbs(neuron_obj): print(f"Error Limb: {limb_idx}") nviz.visualize_neuron_specific_limb(neuron_obj, limb_idx) #2) Get the parameters for the mesh split split_args = DecompositionSplitMethod.restrict_one_part_with_hash( decomposition_split_hash).fetch1() min_skeletal_length_limb = copy.copy( split_args["min_skeletal_length_limb"]) del split_args["min_skeletal_length_limb"] #3) Calculated the split results split_results = pru.multi_soma_split_suggestions( neuron_obj, plot_suggestions=plotting, verbose=verbose, #**split_args ) n_paths_cut = pru.get_n_paths_cut(split_results) if verbose: print(f"n_paths_cut = {n_paths_cut}") # 4) Apply the split results to the neuron (neuron_list, neuron_list_errored_limbs_area, neuron_list_errored_limbs_skeletal_length, neuron_list_n_multi_soma_errors, neuron_list_n_same_soma_errors) = pru.split_neuron( neuron_obj, limb_results=split_results, verbose=verbose, return_error_info=True, #min_skeletal_length_limb=min_skeletal_length_limb, ) #5) Save the neuron and write to the table (including the skeleton table) if len(neuron_list) > 1: raise Exception("More than one neuron after splitting") neuron_idx = 0 neuron_obj_comb = neuron_list[neuron_idx] error_imbs_cancelled_area = neuron_list_errored_limbs_area[neuron_idx] error_imbs_cancelled_skeletal_length = neuron_list_errored_limbs_skeletal_length[ neuron_idx] n_multi_soma_limbs_cancelled = neuron_list_n_multi_soma_errors[ neuron_idx] n_same_soma_limbs_cancelled = neuron_list_n_same_soma_errors[ neuron_idx] if plotting: nviz.visualize_neuron_limbs(neuron_obj_comb) st = time.time() stats_dict = neuron_obj_comb.neuron_stats( stats_to_ignore=[ "n_boutons", "axon_length", "axon_area", "max_soma_volume", "max_soma_n_faces", ], include_skeletal_stats=True, include_centroids=True, voxel_adjustment_vector=voxel_adjustment_vector, ) if verbose: print(f"-- Generating Stats: {time.time() - st}") #4) Save the neuron object in a certain location #file_name = f"{neuron_obj_comb.segment_id}_{neuron_idx}" file_name = f"{neuron_obj_comb.segment_id}_{neuron_idx}_{decomposition_split_hash}" file_name_decomp = f"{file_name}_{dataset}_decomposition" output_folder = str(target_dir_decomp) st = time.time() ret_file_path = neuron_obj_comb.save_compressed_neuron( output_folder=output_folder, file_name=file_name_decomp, return_file_path=True, export_mesh=False, suppress_output=True, ) ret_file_path_str = str(ret_file_path.absolute()) + ".pbz2" if verbose: print(f"-- Neuron Object Save time: {time.time() - st}") #5) Outputting skeleton object, computing stats and saving st = time.time() sk_stats = nst.skeleton_stats_from_neuron_obj( neuron_obj_comb, include_centroids=True, voxel_adjustment_vector=voxel_adjustment_vector, verbose=True) skeleton = neuron_obj_comb.skeleton file_name_decomp_sk = f"{file_name}_{dataset}_decomposition_sk" ret_sk_filepath = su.compressed_pickle(skeleton, filename=file_name_decomp_sk, folder=str(target_dir_sk), return_filepath=True) if verbose: print(f"ret_sk_filepath = {ret_sk_filepath}") if verbose: print(f"-- Skeleton Generation and Save time: {time.time() - st}") # 6) Calcuating the split statistics: split_success = pru.split_success(neuron_obj_comb) if verbose: print(f"Calculating split statistics dict") print(f"split_success = {split_success}") split_stats_dict = dict( n_splits=n_paths_cut, split_success=split_success, n_error_limbs_cancelled=len(error_imbs_cancelled_area), n_multi_soma_limbs_cancelled=n_multi_soma_limbs_cancelled, n_same_soma_limbs_cancelled=n_same_soma_limbs_cancelled, error_imbs_cancelled_area=np.round( np.sum(error_imbs_cancelled_area), 4), error_imbs_cancelled_skeletal_length=np.round( np.sum(error_imbs_cancelled_skeletal_length) / 1000, 4), split_results=split_results, ) # 7) make the insertions run_time = run_time = np.round(time.time() - global_time, 4) # -- decomp table -- decomp_dict = dict( key.copy(), multiplicity=1, split_index=neuron_idx, decomposition=ret_file_path_str, run_time=run_time, # statistics for the split ) decomp_dict.update(stats_dict) decomp_dict.update(split_stats_dict) self.insert1(decomp_dict, allow_direct_insert=True, ignore_extra_fields=True, skip_duplicates=True) self.Object.insert1(decomp_dict, allow_direct_insert=True, ignore_extra_fields=True, skip_duplicates=True) #-- sk table sk_dict = dict(key.copy(), multiplicity=1, split_index=neuron_idx, skeleton=ret_sk_filepath, run_time=run_time) sk_dict.update(sk_stats) SkeletonDecompositionSplit.insert1(sk_dict, allow_direct_insert=True, ignore_extra_fields=True, skip_duplicates=True) SkeletonDecompositionSplit.Object.insert1(sk_dict, allow_direct_insert=True, ignore_extra_fields=True, skip_duplicates=True)