Skip to content

Commit 16b0914

Browse files
authored
Update ProcessMultipleExcelTables_FromAivia.py
v1.61: - Secondary relationship sets can be named differently if the main object is "Cells" - Handles NaN in summary tabs (no results detected, Aivia 12.1)
1 parent 8efeca5 commit 16b0914

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

Recipes/ProcessMeasurementTables/ProcessMultipleExcelTables_FromAivia.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,13 @@ def search_activation_path():
7171
'Dendrite Set': ['Dendrite Segments'],
7272
'Cells': ['Cell Membranes', 'Cytoplasm', 'Nucleus', 'Vesicles - ']}
7373

74-
# Due to discrepancy between object name and ID header, we can provide the correspondence below
74+
# Due to discrepancy between object name and ID header in related object meas, we can provide the correspondence below
7575
relationship_ID_headers = {'Neuron Set': 'Neuron ID', 'Dendrite Set': 'Tree ID', 'Cells': 'Cell ID'}
7676

77-
# Measurements to extract, to avoid too many columns in the final table
78-
relationship_measurements = {'Soma Set': ['Volume (µm³)'],
79-
'Dendrite Set': ['Mean Diameter (µm)'],
80-
'Dendrite Segments': ['Mean Diameter (µm)', 'Total Path Length (µm)', 'Branch Angle'],
77+
# Measurements to extract, to avoid too many columns in the final table. Keywords are searched as prefix!
78+
relationship_measurements = {'Soma Set': ['Volume '],
79+
'Dendrite Set': ['Mean Diameter '],
80+
'Dendrite Segments': ['Mean Diameter ', 'Total Path Length ', 'Branch Angle'],
8181
'Cell Membranes': [],
8282
'Cytoplasm': [],
8383
'Nucleus': [],
@@ -314,7 +314,7 @@ def run(params):
314314
if do_multiple_files_as_cols:
315315
output_basename = 'Analysis_All results.xlsx'
316316
else:
317-
output_basename = '{}_grouped.xlsx'.format(''.join(os.path.basename(indiv_path_list[0]).split('.')[:-1]))
317+
output_basename = '{}_grouped.xlsx'.format('.'.join(os.path.basename(indiv_path_list[0]).split('.')[:-1]))
318318
output_file = os.path.join(output_folder, output_basename.replace('.aivia', ''))
319319

320320
df_grouped = {} # init
@@ -450,8 +450,9 @@ def run(params):
450450
# Collecting all measurements exact names
451451
all_meas_names = []
452452
for tmp_df in df_grouped.values():
453-
if not 'summary' in str(tmp_df.columns[0]).lower():
454-
all_meas_names.extend(tmp_df.columns[1:])
453+
if not tmp_df.empty:
454+
if not 'summary' in str(tmp_df.columns[0]).lower():
455+
all_meas_names.extend(tmp_df.columns[1:])
455456

456457
# Specific to neurons: split dendrite trees from segments
457458
if 'Dendrite Set' in df_grouped.keys():
@@ -476,32 +477,37 @@ def run(params):
476477
else:
477478
df_grouped[n] = df_grouped_tmp[n]
478479

479-
# Process relationships between object sets (see definition before the def run)
480+
# Process RELATIONSHIPS between object sets (see definition before the def run)
480481
for rel_k in relationships.keys(): # E.g. 'Cells'
481-
# Select all tabs where the primary object is # E.g. 'Cells.Cell_Cytoplasm Volume ...'
482+
# Select all tabs where the primary object exists # E.g. 'Cells.Cell_Cytoplasm Volume ...'
482483
for k in [it_k for it_k in df_grouped.keys() if rel_k in it_k]:
483484
k_suffix = k.replace(rel_k, '') # Important when multiple object sets existed (' (2)')
484485

485486
# Check presence of secondary object defined by relationships
486487
for rel_s in relationships[rel_k]:
487488
# v1.60 gives the ability to provide only the beginning of the object name ('Vesicles - ')
489+
# v1.61 gives the ability to search relationships for cell components even if renamed
488490
# It also provides relationships of multiple secondary objects beginning with the same name
489491

490492
for s in [it_s for it_s in df_grouped.keys() if is_same_object_set(it_s, k_suffix)]:
491493

492-
if rel_s in s: # positive match for secondary object
494+
if rel_s in s or rel_k == 'Cells': # positive match for secondary object
493495
# Check presence of correct ID header in measurements in order to associate objects
494496
id_header = relationship_ID_headers[rel_k]
495497
if id_header in df_grouped[s].columns:
496498
prefix = s + '.'
497-
selected_meas_prefixes = relationship_measurements[rel_s]
499+
500+
# Changing 'rel_s' ref to last item from II sets (vesicles) if I set is 'Cells'
501+
rel_s_tmp = relationships['Cells'][-1] if rel_k == 'Cells' else rel_s
502+
503+
selected_meas_prefixes = relationship_measurements[rel_s_tmp]
498504

499505
# See if prefixes exists in exact names of measurements (columns)
500506
for meas_prefix in selected_meas_prefixes:
501507
meas = [col for col in df_grouped[s].columns if meas_prefix in col]
502508
print('Collecting statistics ({}) from [{}] to be reported for [{}]'.format(meas, s, k))
503509
df_grouped[k] = calculate_relation_stats(df_grouped[k], df_grouped[s],
504-
id_header, prefix, rel_s, meas)
510+
id_header, prefix, rel_s_tmp, meas)
505511

506512
# Collecting summary values
507513
for k in df_grouped.keys():
@@ -615,6 +621,10 @@ def run(params):
615621
summary_lbls = [su for su in df_grouped.keys() if su.endswith('Summary')]
616622
summary_lbl = summary_lbls[0]
617623

624+
# Put zeros if some summary values are NaN
625+
if df_grouped[summary_lbl][df_grouped[summary_lbl].columns[1]].isnull().sum() > 0:
626+
df_grouped[summary_lbl][df_grouped[summary_lbl].columns[1]].fillna(0, inplace=True)
627+
618628
# Merge with potential existing summary tab
619629
df_grouped[summary_lbl] = pd.concat([df_grouped[summary_lbl], df_summary_to_add], axis=0, ignore_index=True)
620630

@@ -840,6 +850,7 @@ def calculate_relation_stats(df_i, df_ii, id_header, meas_prefix, obj_ii_type, m
840850
df_to_add = pd.DataFrame()
841851

842852
if set(df_ii.columns) & set(measurements):
853+
# Warning: ID of main/primary object is retrieved from its name!!!
843854
for obj_i_name in df_i.iloc[:, 0]:
844855
obj_i_id = int(obj_i_name.split(' ')[-1]) # Expecting a space before number
845856

@@ -1021,3 +1032,5 @@ def Mbox(title, text, style):
10211032
# v1.56: - Bug fix since Aivia 12.0 (r38705) security release for scenario F where only the summary tab is output
10221033
# v1.60: - Add Cell Analysis support for relationship grouping. Better recognition of object sets with numbers '(1)'
10231034
# - Bug fixed at line 660 (if result table is empty)
1035+
# v1.61: - Secondary relationship sets can be named differently if the main object is "Cells"
1036+
# - Handles NaN in summary tabs (no results detected, Aivia 12.1)

0 commit comments

Comments
 (0)