celldetective 1.3.9.post4__py3-none-any.whl → 1.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- celldetective/__init__.py +0 -3
- celldetective/_version.py +1 -1
- celldetective/events.py +2 -4
- celldetective/extra_properties.py +320 -24
- celldetective/gui/InitWindow.py +33 -45
- celldetective/gui/__init__.py +1 -0
- celldetective/gui/about.py +19 -15
- celldetective/gui/analyze_block.py +34 -19
- celldetective/gui/base_components.py +23 -0
- celldetective/gui/btrack_options.py +26 -34
- celldetective/gui/classifier_widget.py +71 -80
- celldetective/gui/configure_new_exp.py +113 -17
- celldetective/gui/control_panel.py +68 -141
- celldetective/gui/generic_signal_plot.py +9 -12
- celldetective/gui/gui_utils.py +49 -21
- celldetective/gui/json_readers.py +5 -4
- celldetective/gui/layouts.py +246 -22
- celldetective/gui/measurement_options.py +32 -17
- celldetective/gui/neighborhood_options.py +10 -13
- celldetective/gui/plot_measurements.py +21 -17
- celldetective/gui/plot_signals_ui.py +131 -75
- celldetective/gui/process_block.py +180 -123
- celldetective/gui/processes/compute_neighborhood.py +594 -0
- celldetective/gui/processes/measure_cells.py +5 -0
- celldetective/gui/processes/segment_cells.py +27 -6
- celldetective/gui/processes/track_cells.py +6 -0
- celldetective/gui/retrain_segmentation_model_options.py +12 -20
- celldetective/gui/retrain_signal_model_options.py +57 -56
- celldetective/gui/seg_model_loader.py +21 -62
- celldetective/gui/signal_annotator.py +139 -72
- celldetective/gui/signal_annotator2.py +431 -635
- celldetective/gui/signal_annotator_options.py +8 -11
- celldetective/gui/survival_ui.py +49 -95
- celldetective/gui/tableUI.py +28 -25
- celldetective/gui/thresholds_gui.py +617 -1221
- celldetective/gui/viewers.py +106 -39
- celldetective/gui/workers.py +9 -3
- celldetective/io.py +73 -27
- celldetective/measure.py +63 -27
- celldetective/neighborhood.py +342 -268
- celldetective/preprocessing.py +25 -17
- celldetective/relative_measurements.py +50 -29
- celldetective/scripts/analyze_signals.py +4 -1
- celldetective/scripts/measure_relative.py +4 -1
- celldetective/scripts/segment_cells.py +0 -6
- celldetective/scripts/track_cells.py +3 -1
- celldetective/scripts/train_segmentation_model.py +7 -4
- celldetective/signals.py +29 -14
- celldetective/tracking.py +7 -2
- celldetective/utils.py +36 -8
- {celldetective-1.3.9.post4.dist-info → celldetective-1.4.0.dist-info}/METADATA +24 -16
- {celldetective-1.3.9.post4.dist-info → celldetective-1.4.0.dist-info}/RECORD +57 -55
- {celldetective-1.3.9.post4.dist-info → celldetective-1.4.0.dist-info}/WHEEL +1 -1
- tests/test_qt.py +21 -21
- {celldetective-1.3.9.post4.dist-info → celldetective-1.4.0.dist-info}/entry_points.txt +0 -0
- {celldetective-1.3.9.post4.dist-info → celldetective-1.4.0.dist-info/licenses}/LICENSE +0 -0
- {celldetective-1.3.9.post4.dist-info → celldetective-1.4.0.dist-info}/top_level.txt +0 -0
celldetective/neighborhood.py
CHANGED
|
@@ -9,6 +9,281 @@ from celldetective.io import locate_labels, get_position_pickle, get_position_ta
|
|
|
9
9
|
|
|
10
10
|
abs_path = os.sep.join([os.path.split(os.path.dirname(os.path.realpath(__file__)))[0], 'celldetective'])
|
|
11
11
|
|
|
12
|
+
def _fill_distance_neighborhood_at_t(time_index, setA, setB, dist_map, attention_weight=None, include_dead_weight=False, symmetrize=False, compute_cum_sum=False,
|
|
13
|
+
weights=None, closest_A=None, neigh_col="", column_labelsA=None, column_labelsB=None, statusA=None, statusB=None, distance=10):
|
|
14
|
+
|
|
15
|
+
index_A = list(setA.loc[setA[column_labelsA['time']] == time_index].index)
|
|
16
|
+
index_B = list(setB.loc[setB[column_labelsB['time']] == time_index].index)
|
|
17
|
+
|
|
18
|
+
dataA = setA.loc[setA[column_labelsA['time']] == time_index, [column_labelsA['x'], column_labelsA['y'], column_labelsA['track'],statusA]].to_numpy()
|
|
19
|
+
|
|
20
|
+
ids_A = dataA[:, 2]
|
|
21
|
+
status_A = dataA[:, 3]
|
|
22
|
+
|
|
23
|
+
dataB = setB.loc[setB[column_labelsB['time']] == time_index, [column_labelsB['x'], column_labelsB['y'], column_labelsB['track'],statusB]].to_numpy()
|
|
24
|
+
ids_B = dataB[:, 2]
|
|
25
|
+
status_B = dataB[:, 3]
|
|
26
|
+
|
|
27
|
+
for k in range(dist_map.shape[0]):
|
|
28
|
+
|
|
29
|
+
col = dist_map[k, :]
|
|
30
|
+
col[col == 0.] = 1.0E06
|
|
31
|
+
|
|
32
|
+
neighs_B = np.array([ids_B[i] for i in np.where((col <= distance))[0]])
|
|
33
|
+
status_neigh_B = np.array([status_B[i] for i in np.where((col <= distance))[0]])
|
|
34
|
+
dist_B = [round(col[i], 2) for i in np.where((col <= distance))[0]]
|
|
35
|
+
if len(dist_B) > 0:
|
|
36
|
+
closest_B_cell = neighs_B[np.argmin(dist_B)]
|
|
37
|
+
|
|
38
|
+
if symmetrize and attention_weight:
|
|
39
|
+
n_neighs = float(len(neighs_B))
|
|
40
|
+
if not include_dead_weight:
|
|
41
|
+
n_neighs_alive = len(np.where(status_neigh_B == 1)[0])
|
|
42
|
+
neigh_count = n_neighs_alive
|
|
43
|
+
else:
|
|
44
|
+
neigh_count = n_neighs
|
|
45
|
+
if neigh_count > 0:
|
|
46
|
+
weight_A = 1. / neigh_count
|
|
47
|
+
else:
|
|
48
|
+
weight_A = np.nan
|
|
49
|
+
|
|
50
|
+
if not include_dead_weight and status_A[k] == 0:
|
|
51
|
+
weight_A = 0
|
|
52
|
+
|
|
53
|
+
neighs = []
|
|
54
|
+
setA.at[index_A[k], neigh_col] = []
|
|
55
|
+
for n in range(len(neighs_B)):
|
|
56
|
+
|
|
57
|
+
# index in setB
|
|
58
|
+
n_index = np.where(ids_B == neighs_B[n])[0][0]
|
|
59
|
+
# Assess if neigh B is closest to A
|
|
60
|
+
if attention_weight:
|
|
61
|
+
if closest_A[n_index] == ids_A[k]:
|
|
62
|
+
closest = True
|
|
63
|
+
else:
|
|
64
|
+
closest = False
|
|
65
|
+
|
|
66
|
+
if symmetrize:
|
|
67
|
+
# Load neighborhood previous data
|
|
68
|
+
sym_neigh = setB.loc[index_B[n_index], neigh_col]
|
|
69
|
+
if neighs_B[n] == closest_B_cell:
|
|
70
|
+
closest_b = True
|
|
71
|
+
else:
|
|
72
|
+
closest_b = False
|
|
73
|
+
if isinstance(sym_neigh, list):
|
|
74
|
+
sym_neigh.append({'id': ids_A[k], 'distance': dist_B[n], 'status': status_A[k]})
|
|
75
|
+
else:
|
|
76
|
+
sym_neigh = [{'id': ids_A[k], 'distance': dist_B[n], 'status': status_A[k]}]
|
|
77
|
+
if attention_weight:
|
|
78
|
+
sym_neigh[-1].update({'weight': weight_A, 'closest': closest_b})
|
|
79
|
+
|
|
80
|
+
# Write the minimum info about neighborhing cell B
|
|
81
|
+
neigh_dico = {'id': neighs_B[n], 'distance': dist_B[n], 'status': status_neigh_B[n]}
|
|
82
|
+
if attention_weight:
|
|
83
|
+
neigh_dico.update({'weight': weights[n_index], 'closest': closest})
|
|
84
|
+
|
|
85
|
+
if compute_cum_sum:
|
|
86
|
+
# Compute the integrated presence of the neighboring cell B
|
|
87
|
+
assert column_labelsB[
|
|
88
|
+
'track'] == 'TRACK_ID', 'The set B does not seem to contain tracked data. The cumulative time will be meaningless.'
|
|
89
|
+
past_neighs = [[ll['id'] for ll in l] if len(l) > 0 else [None] for l in setA.loc[
|
|
90
|
+
(setA[column_labelsA['track']] == ids_A[k]) & (setA[column_labelsA['time']] <= time_index), neigh_col].to_numpy()]
|
|
91
|
+
past_neighs = [item for sublist in past_neighs for item in sublist]
|
|
92
|
+
|
|
93
|
+
if attention_weight:
|
|
94
|
+
past_weights = [[ll['weight'] for ll in l] if len(l) > 0 else [None] for l in setA.loc[
|
|
95
|
+
(setA[column_labelsA['track']] == ids_A[k]) & (
|
|
96
|
+
setA[column_labelsA['time']] <= time_index), neigh_col].to_numpy()]
|
|
97
|
+
past_weights = [item for sublist in past_weights for item in sublist]
|
|
98
|
+
|
|
99
|
+
cum_sum = len(np.where(past_neighs == neighs_B[n])[0])
|
|
100
|
+
neigh_dico.update({'cumulated_presence': cum_sum + 1})
|
|
101
|
+
|
|
102
|
+
if attention_weight:
|
|
103
|
+
cum_sum_weighted = np.sum(
|
|
104
|
+
[w if l == neighs_B[n] else 0 for l, w in zip(past_neighs, past_weights)])
|
|
105
|
+
neigh_dico.update({'cumulated_presence_weighted': cum_sum_weighted + weights[n_index]})
|
|
106
|
+
|
|
107
|
+
if symmetrize:
|
|
108
|
+
setB.at[index_B[n_index], neigh_col] = sym_neigh
|
|
109
|
+
|
|
110
|
+
neighs.append(neigh_dico)
|
|
111
|
+
|
|
112
|
+
setA.at[index_A[k], neigh_col] = neighs
|
|
113
|
+
|
|
114
|
+
def _fill_contact_neighborhood_at_t(time_index, setA, setB, dist_map, intersection_map=None, attention_weight=None, include_dead_weight=False, symmetrize=False, compute_cum_sum=False,
|
|
115
|
+
weights=None, closest_A=None, neigh_col="", column_labelsA=None, column_labelsB=None, statusA=None, statusB=None, d_filter=10):
|
|
116
|
+
|
|
117
|
+
index_A = list(setA.loc[setA[column_labelsA['time']] == time_index].index)
|
|
118
|
+
index_B = list(setB.loc[setB[column_labelsB['time']] == time_index].index)
|
|
119
|
+
|
|
120
|
+
dataA = setA.loc[setA[column_labelsA['time']] == time_index, [column_labelsA['x'], column_labelsA['y'], column_labelsA['track'], column_labelsA['mask_id'],
|
|
121
|
+
statusA]].to_numpy()
|
|
122
|
+
|
|
123
|
+
ids_A = dataA[:, 2]
|
|
124
|
+
status_A = dataA[:, 4]
|
|
125
|
+
|
|
126
|
+
dataB = setB.loc[setB[column_labelsB['time']] == time_index, [column_labelsB['x'], column_labelsB['y'], column_labelsB['track'], column_labelsB['mask_id'],
|
|
127
|
+
statusB]].to_numpy()
|
|
128
|
+
ids_B = dataB[:, 2]
|
|
129
|
+
status_B = dataB[:, 4]
|
|
130
|
+
|
|
131
|
+
for k in range(dist_map.shape[0]):
|
|
132
|
+
|
|
133
|
+
col = dist_map[k, :]
|
|
134
|
+
col_inter = intersection_map[k, :]
|
|
135
|
+
col[col == 0.] = 1.0E06
|
|
136
|
+
|
|
137
|
+
neighs_B = np.array([ids_B[i] for i in np.where((col <= d_filter))[0]])
|
|
138
|
+
status_neigh_B = np.array([status_B[i] for i in np.where((col <= d_filter))[0]])
|
|
139
|
+
dist_B = [round(col[i], 2) for i in np.where((col <= d_filter))[0]]
|
|
140
|
+
intersect_B = [round(col_inter[i], 2) for i in np.where((col <= d_filter))[0]]
|
|
141
|
+
|
|
142
|
+
if len(dist_B) > 0:
|
|
143
|
+
closest_B_cell = neighs_B[np.argmin(dist_B)]
|
|
144
|
+
|
|
145
|
+
if symmetrize and attention_weight:
|
|
146
|
+
n_neighs = float(len(neighs_B))
|
|
147
|
+
if not include_dead_weight:
|
|
148
|
+
n_neighs_alive = len(np.where(status_neigh_B == 1)[0])
|
|
149
|
+
neigh_count = n_neighs_alive
|
|
150
|
+
else:
|
|
151
|
+
neigh_count = n_neighs
|
|
152
|
+
if neigh_count > 0:
|
|
153
|
+
weight_A = 1. / neigh_count
|
|
154
|
+
else:
|
|
155
|
+
weight_A = np.nan
|
|
156
|
+
|
|
157
|
+
if not include_dead_weight and status_A[k] == 0:
|
|
158
|
+
weight_A = 0
|
|
159
|
+
|
|
160
|
+
neighs = []
|
|
161
|
+
setA.at[index_A[k], neigh_col] = []
|
|
162
|
+
for n in range(len(neighs_B)):
|
|
163
|
+
|
|
164
|
+
# index in setB
|
|
165
|
+
n_index = np.where(ids_B == neighs_B[n])[0][0]
|
|
166
|
+
# Assess if neigh B is closest to A
|
|
167
|
+
if attention_weight:
|
|
168
|
+
if closest_A[n_index] == ids_A[k]:
|
|
169
|
+
closest = True
|
|
170
|
+
else:
|
|
171
|
+
closest = False
|
|
172
|
+
|
|
173
|
+
if symmetrize:
|
|
174
|
+
# Load neighborhood previous data
|
|
175
|
+
sym_neigh = setB.loc[index_B[n_index], neigh_col]
|
|
176
|
+
if neighs_B[n] == closest_B_cell:
|
|
177
|
+
closest_b = True
|
|
178
|
+
else:
|
|
179
|
+
closest_b = False
|
|
180
|
+
if isinstance(sym_neigh, list):
|
|
181
|
+
sym_neigh.append({'id': ids_A[k], 'distance': dist_B[n], 'status': status_A[k],
|
|
182
|
+
'intersection': intersect_B[n]})
|
|
183
|
+
else:
|
|
184
|
+
sym_neigh = [{'id': ids_A[k], 'distance': dist_B[n], 'status': status_A[k],
|
|
185
|
+
'intersection': intersect_B[n]}]
|
|
186
|
+
if attention_weight:
|
|
187
|
+
sym_neigh[-1].update({'weight': weight_A, 'closest': closest_b})
|
|
188
|
+
|
|
189
|
+
# Write the minimum info about neighborhing cell B
|
|
190
|
+
neigh_dico = {'id': neighs_B[n], 'distance': dist_B[n], 'status': status_neigh_B[n],
|
|
191
|
+
'intersection': intersect_B[n]}
|
|
192
|
+
if attention_weight:
|
|
193
|
+
neigh_dico.update({'weight': weights[n_index], 'closest': closest})
|
|
194
|
+
|
|
195
|
+
if compute_cum_sum:
|
|
196
|
+
# Compute the integrated presence of the neighboring cell B
|
|
197
|
+
assert column_labelsB[
|
|
198
|
+
'track'] == 'TRACK_ID', 'The set B does not seem to contain tracked data. The cumulative time will be meaningless.'
|
|
199
|
+
past_neighs = [[ll['id'] for ll in l] if len(l) > 0 else [None] for l in setA.loc[
|
|
200
|
+
(setA[column_labelsA['track']] == ids_A[k]) & (
|
|
201
|
+
setA[column_labelsA['time']] <= time_index), neigh_col].to_numpy()]
|
|
202
|
+
past_neighs = [item for sublist in past_neighs for item in sublist]
|
|
203
|
+
|
|
204
|
+
if attention_weight:
|
|
205
|
+
past_weights = [[ll['weight'] for ll in l] if len(l) > 0 else [None] for l in
|
|
206
|
+
setA.loc[
|
|
207
|
+
(setA[column_labelsA['track']] == ids_A[k]) & (
|
|
208
|
+
setA[column_labelsA['time']] <= time_index), neigh_col].to_numpy()]
|
|
209
|
+
past_weights = [item for sublist in past_weights for item in sublist]
|
|
210
|
+
|
|
211
|
+
cum_sum = len(np.where(past_neighs == neighs_B[n])[0])
|
|
212
|
+
neigh_dico.update({'cumulated_presence': cum_sum + 1})
|
|
213
|
+
|
|
214
|
+
if attention_weight:
|
|
215
|
+
cum_sum_weighted = np.sum(
|
|
216
|
+
[w if l == neighs_B[n] else 0 for l, w in zip(past_neighs, past_weights)])
|
|
217
|
+
neigh_dico.update(
|
|
218
|
+
{'cumulated_presence_weighted': cum_sum_weighted + weights[n_index]})
|
|
219
|
+
|
|
220
|
+
if symmetrize:
|
|
221
|
+
setB.at[index_B[n_index], neigh_col] = sym_neigh
|
|
222
|
+
|
|
223
|
+
neighs.append(neigh_dico)
|
|
224
|
+
|
|
225
|
+
setA.at[index_A[k], neigh_col] = neighs
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def _compute_mask_contact_dist_map(setA, setB, labelsA, labelsB=None, distance=10, mode="self", column_labelsA=None, column_labelsB=None):
|
|
229
|
+
|
|
230
|
+
coordinates_A = setA.loc[:, [column_labelsA['x'], column_labelsA['y']]].to_numpy()
|
|
231
|
+
coordinates_B = setB.loc[:, [column_labelsB['x'], column_labelsB['y']]].to_numpy()
|
|
232
|
+
ids_A = setA.loc[:, column_labelsA["track"]].to_numpy()
|
|
233
|
+
ids_B = setB.loc[:, column_labelsB["track"]].to_numpy()
|
|
234
|
+
mask_ids_A = setA.loc[:, column_labelsA["mask_id"]].to_numpy()
|
|
235
|
+
mask_ids_B = setB.loc[:, column_labelsB["mask_id"]].to_numpy()
|
|
236
|
+
|
|
237
|
+
# compute distance matrix
|
|
238
|
+
dist_map = cdist(coordinates_A, coordinates_B, metric="euclidean")
|
|
239
|
+
intersection_map = np.zeros_like(dist_map).astype(float)
|
|
240
|
+
|
|
241
|
+
# Do the mask contact computation
|
|
242
|
+
labelsA = np.where(np.isin(labelsA, mask_ids_A), labelsA.copy(), 0.)
|
|
243
|
+
|
|
244
|
+
if labelsB is not None:
|
|
245
|
+
labelsB = np.where(np.isin(labelsB, mask_ids_B), labelsB.copy(), 0.)
|
|
246
|
+
|
|
247
|
+
contact_pairs = contact_neighborhood(labelsA, labelsB=labelsB, border=distance, connectivity=2)
|
|
248
|
+
|
|
249
|
+
# Put infinite distance to all non-contact pairs (something like this)
|
|
250
|
+
flatA = labelsA.flatten()
|
|
251
|
+
if labelsB is not None:
|
|
252
|
+
flatB = labelsB.flatten()
|
|
253
|
+
|
|
254
|
+
if len(contact_pairs) > 0:
|
|
255
|
+
mask = np.ones_like(dist_map).astype(bool)
|
|
256
|
+
|
|
257
|
+
indices_to_keep = []
|
|
258
|
+
for cp in contact_pairs:
|
|
259
|
+
|
|
260
|
+
cp = np.abs(cp)
|
|
261
|
+
mask_A, mask_B = cp
|
|
262
|
+
idx_A = np.where(mask_ids_A == int(mask_A))[0][0]
|
|
263
|
+
idx_B = np.where(mask_ids_B == int(mask_B))[0][0]
|
|
264
|
+
|
|
265
|
+
intersection = 0
|
|
266
|
+
if labelsB is not None:
|
|
267
|
+
intersection = len(flatA[(flatA == int(mask_A)) & (flatB == int(mask_B))])
|
|
268
|
+
|
|
269
|
+
indices_to_keep.append([idx_A, idx_B, intersection])
|
|
270
|
+
print(f'Ref cell #{ids_A[idx_A]} matched with neigh. cell #{ids_B[idx_B]}...')
|
|
271
|
+
print(f'Computed intersection: {intersection} px...')
|
|
272
|
+
|
|
273
|
+
if len(indices_to_keep) > 0:
|
|
274
|
+
indices_to_keep = np.array(indices_to_keep)
|
|
275
|
+
mask[indices_to_keep[:, 0], indices_to_keep[:, 1]] = False
|
|
276
|
+
if mode == 'self':
|
|
277
|
+
mask[indices_to_keep[:, 1], indices_to_keep[:, 0]] = False
|
|
278
|
+
dist_map[mask] = 1.0E06
|
|
279
|
+
intersection_map[indices_to_keep[:, 0], indices_to_keep[:, 1]] = indices_to_keep[:, 2]
|
|
280
|
+
else:
|
|
281
|
+
dist_map[:, :] = 1.0E06
|
|
282
|
+
else:
|
|
283
|
+
dist_map[:, :] = 1.0E06
|
|
284
|
+
|
|
285
|
+
return dist_map, intersection_map
|
|
286
|
+
|
|
12
287
|
|
|
13
288
|
def set_live_status(setA, setB, status, not_status_option):
|
|
14
289
|
"""
|
|
@@ -202,15 +477,12 @@ def distance_cut_neighborhood(setA, setB, distance, mode='two-pop', status=None,
|
|
|
202
477
|
int)
|
|
203
478
|
for t in tqdm(timeline):
|
|
204
479
|
|
|
205
|
-
index_A = list(setA.loc[setA[cl[0]['time']] == t].index)
|
|
206
480
|
coordinates_A = setA.loc[setA[cl[0]['time']] == t, [cl[0]['x'], cl[0]['y']]].to_numpy()
|
|
207
481
|
ids_A = setA.loc[setA[cl[0]['time']] == t, cl[0]['track']].to_numpy()
|
|
208
482
|
status_A = setA.loc[setA[cl[0]['time']] == t, status[0]].to_numpy()
|
|
209
483
|
|
|
210
|
-
index_B = list(setB.loc[setB[cl[1]['time']] == t].index)
|
|
211
484
|
coordinates_B = setB.loc[setB[cl[1]['time']] == t, [cl[1]['x'], cl[1]['y']]].to_numpy()
|
|
212
485
|
ids_B = setB.loc[setB[cl[1]['time']] == t, cl[1]['track']].to_numpy()
|
|
213
|
-
status_B = setB.loc[setB[cl[1]['time']] == t, status[1]].to_numpy()
|
|
214
486
|
|
|
215
487
|
if len(ids_A) > 0 and len(ids_B) > 0:
|
|
216
488
|
|
|
@@ -218,96 +490,14 @@ def distance_cut_neighborhood(setA, setB, distance, mode='two-pop', status=None,
|
|
|
218
490
|
dist_map = cdist(coordinates_A, coordinates_B, metric="euclidean")
|
|
219
491
|
|
|
220
492
|
if attention_weight:
|
|
221
|
-
weights, closest_A = compute_attention_weight(dist_map, d, status_A, ids_A, axis=1,
|
|
222
|
-
include_dead_weight=include_dead_weight)
|
|
493
|
+
weights, closest_A = compute_attention_weight(dist_map, d, status_A, ids_A, axis=1, include_dead_weight=include_dead_weight)
|
|
223
494
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
neighs_B = np.array([ids_B[i] for i in np.where((col <= d))[0]])
|
|
231
|
-
status_neigh_B = np.array([status_B[i] for i in np.where((col <= d))[0]])
|
|
232
|
-
dist_B = [round(col[i], 2) for i in np.where((col <= d))[0]]
|
|
233
|
-
if len(dist_B) > 0:
|
|
234
|
-
closest_B_cell = neighs_B[np.argmin(dist_B)]
|
|
235
|
-
|
|
236
|
-
if symmetrize and attention_weight:
|
|
237
|
-
n_neighs = float(len(neighs_B))
|
|
238
|
-
if not include_dead_weight:
|
|
239
|
-
n_neighs_alive = len(np.where(status_neigh_B == 1)[0])
|
|
240
|
-
neigh_count = n_neighs_alive
|
|
241
|
-
else:
|
|
242
|
-
neigh_count = n_neighs
|
|
243
|
-
if neigh_count > 0:
|
|
244
|
-
weight_A = 1. / neigh_count
|
|
245
|
-
else:
|
|
246
|
-
weight_A = np.nan
|
|
247
|
-
|
|
248
|
-
if not include_dead_weight and status_A[k] == 0:
|
|
249
|
-
weight_A = 0
|
|
250
|
-
|
|
251
|
-
neighs = []
|
|
252
|
-
setA.at[index_A[k], neigh_col] = []
|
|
253
|
-
for n in range(len(neighs_B)):
|
|
254
|
-
|
|
255
|
-
# index in setB
|
|
256
|
-
n_index = np.where(ids_B == neighs_B[n])[0][0]
|
|
257
|
-
# Assess if neigh B is closest to A
|
|
258
|
-
if attention_weight:
|
|
259
|
-
if closest_A[n_index] == ids_A[k]:
|
|
260
|
-
closest = True
|
|
261
|
-
else:
|
|
262
|
-
closest = False
|
|
263
|
-
|
|
264
|
-
if symmetrize:
|
|
265
|
-
# Load neighborhood previous data
|
|
266
|
-
sym_neigh = setB.loc[index_B[n_index], neigh_col]
|
|
267
|
-
if neighs_B[n] == closest_B_cell:
|
|
268
|
-
closest_b = True
|
|
269
|
-
else:
|
|
270
|
-
closest_b = False
|
|
271
|
-
if isinstance(sym_neigh, list):
|
|
272
|
-
sym_neigh.append({'id': ids_A[k], 'distance': dist_B[n], 'status': status_A[k]})
|
|
273
|
-
else:
|
|
274
|
-
sym_neigh = [{'id': ids_A[k], 'distance': dist_B[n], 'status': status_A[k]}]
|
|
275
|
-
if attention_weight:
|
|
276
|
-
sym_neigh[-1].update({'weight': weight_A, 'closest': closest_b})
|
|
277
|
-
|
|
278
|
-
# Write the minimum info about neighborhing cell B
|
|
279
|
-
neigh_dico = {'id': neighs_B[n], 'distance': dist_B[n], 'status': status_neigh_B[n]}
|
|
280
|
-
if attention_weight:
|
|
281
|
-
neigh_dico.update({'weight': weights[n_index], 'closest': closest})
|
|
282
|
-
|
|
283
|
-
if compute_cum_sum:
|
|
284
|
-
# Compute the integrated presence of the neighboring cell B
|
|
285
|
-
assert cl[1][
|
|
286
|
-
'track'] == 'TRACK_ID', 'The set B does not seem to contain tracked data. The cumulative time will be meaningless.'
|
|
287
|
-
past_neighs = [[ll['id'] for ll in l] if len(l) > 0 else [None] for l in setA.loc[
|
|
288
|
-
(setA[cl[0]['track']] == ids_A[k]) & (setA[cl[0]['time']] <= t), neigh_col].to_numpy()]
|
|
289
|
-
past_neighs = [item for sublist in past_neighs for item in sublist]
|
|
290
|
-
|
|
291
|
-
if attention_weight:
|
|
292
|
-
past_weights = [[ll['weight'] for ll in l] if len(l) > 0 else [None] for l in setA.loc[
|
|
293
|
-
(setA[cl[0]['track']] == ids_A[k]) & (
|
|
294
|
-
setA[cl[0]['time']] <= t), neigh_col].to_numpy()]
|
|
295
|
-
past_weights = [item for sublist in past_weights for item in sublist]
|
|
296
|
-
|
|
297
|
-
cum_sum = len(np.where(past_neighs == neighs_B[n])[0])
|
|
298
|
-
neigh_dico.update({'cumulated_presence': cum_sum + 1})
|
|
299
|
-
|
|
300
|
-
if attention_weight:
|
|
301
|
-
cum_sum_weighted = np.sum(
|
|
302
|
-
[w if l == neighs_B[n] else 0 for l, w in zip(past_neighs, past_weights)])
|
|
303
|
-
neigh_dico.update({'cumulated_presence_weighted': cum_sum_weighted + weights[n_index]})
|
|
304
|
-
|
|
305
|
-
if symmetrize:
|
|
306
|
-
setB.at[index_B[n_index], neigh_col] = sym_neigh
|
|
307
|
-
|
|
308
|
-
neighs.append(neigh_dico)
|
|
309
|
-
|
|
310
|
-
setA.at[index_A[k], neigh_col] = neighs
|
|
495
|
+
_fill_distance_neighborhood_at_t(t, setA, setB, dist_map,
|
|
496
|
+
attention_weight=attention_weight,
|
|
497
|
+
include_dead_weight=include_dead_weight, symmetrize=symmetrize,
|
|
498
|
+
compute_cum_sum=compute_cum_sum, weights=weights, closest_A=closest_A,
|
|
499
|
+
neigh_col=neigh_col, column_labelsA=cl[0], column_labelsB=cl[1],
|
|
500
|
+
statusA=status[0], statusB=status[1], distance=d)
|
|
311
501
|
|
|
312
502
|
return setA, setB
|
|
313
503
|
|
|
@@ -435,6 +625,7 @@ def compute_neighborhood_at_position(pos, distance, population=['targets', 'effe
|
|
|
435
625
|
df_B = df_B.drop(columns=unwanted)
|
|
436
626
|
|
|
437
627
|
df_A, df_B = distance_cut_neighborhood(df_A, df_B, distance, **neighborhood_kwargs)
|
|
628
|
+
|
|
438
629
|
if df_A is None or df_B is None or len(df_A)==0:
|
|
439
630
|
return None
|
|
440
631
|
|
|
@@ -442,6 +633,7 @@ def compute_neighborhood_at_position(pos, distance, population=['targets', 'effe
|
|
|
442
633
|
|
|
443
634
|
if neighborhood_kwargs['mode'] == 'two-pop':
|
|
444
635
|
neigh_col = f'neighborhood_2_circle_{d}_px'
|
|
636
|
+
|
|
445
637
|
elif neighborhood_kwargs['mode'] == 'self':
|
|
446
638
|
neigh_col = f'neighborhood_self_circle_{d}_px'
|
|
447
639
|
|
|
@@ -464,17 +656,27 @@ def compute_neighborhood_at_position(pos, distance, population=['targets', 'effe
|
|
|
464
656
|
df_A = mean_neighborhood_after_event(df_A, neigh_col, event_time_col)
|
|
465
657
|
print('Done...')
|
|
466
658
|
|
|
467
|
-
df_A.to_pickle(path_A.replace('.csv', '.pkl'))
|
|
468
659
|
if not population[0] == population[1]:
|
|
469
|
-
# Remove neighborhood column
|
|
660
|
+
# Remove neighborhood column from neighbor table, rename with actual population name
|
|
470
661
|
for td, d in zip(theta_dist, distance):
|
|
471
662
|
if neighborhood_kwargs['mode'] == 'two-pop':
|
|
472
663
|
neigh_col = f'neighborhood_2_circle_{d}_px'
|
|
664
|
+
new_neigh_col = neigh_col.replace('_2_',f'_({population[0]}-{population[1]})_')
|
|
665
|
+
df_A = df_A.rename(columns={neigh_col: new_neigh_col})
|
|
473
666
|
elif neighborhood_kwargs['mode'] == 'self':
|
|
474
667
|
neigh_col = f'neighborhood_self_circle_{d}_px'
|
|
475
668
|
df_B = df_B.drop(columns=[neigh_col])
|
|
476
669
|
df_B.to_pickle(path_B.replace('.csv', '.pkl'))
|
|
477
670
|
|
|
671
|
+
cols_to_rename = [c for c in list(df_A.columns) if c.startswith('intermediate_count_') or c.startswith('inclusive_count_') or c.startswith('exclusive_count_') or c.startswith('mean_count_')]
|
|
672
|
+
new_col_names = [c.replace('_2_',f'_({population[0]}-{population[1]})_') for c in cols_to_rename]
|
|
673
|
+
new_name_map = {}
|
|
674
|
+
for k,c in enumerate(cols_to_rename):
|
|
675
|
+
new_name_map.update({c: new_col_names[k]})
|
|
676
|
+
df_A = df_A.rename(columns=new_name_map)
|
|
677
|
+
|
|
678
|
+
df_A.to_pickle(path_A.replace('.csv', '.pkl'))
|
|
679
|
+
|
|
478
680
|
unwanted = df_A.columns[df_A.columns.str.startswith('neighborhood_')]
|
|
479
681
|
df_A2 = df_A.drop(columns=unwanted)
|
|
480
682
|
df_A2.to_csv(path_A, index=False)
|
|
@@ -904,16 +1106,6 @@ def mask_contact_neighborhood(setA, setB, labelsA, labelsB, distance, mode='two-
|
|
|
904
1106
|
do not count dead cells when establishing attention weight
|
|
905
1107
|
"""
|
|
906
1108
|
|
|
907
|
-
# Check live_status option
|
|
908
|
-
# if setA is not None:
|
|
909
|
-
# setA_id = extract_identity_col(setA)
|
|
910
|
-
# if setA_id=="TRACK_ID":
|
|
911
|
-
# setA = setA.loc[~setA['TRACK_ID'].isnull(),:].copy()
|
|
912
|
-
# if setB is not None:
|
|
913
|
-
# setB_id = extract_identity_col(setB)
|
|
914
|
-
# if setB_id=="TRACK_ID":
|
|
915
|
-
# setB = setB.loc[~setB['TRACK_ID'].isnull(),:].copy()
|
|
916
|
-
|
|
917
1109
|
if setA is not None and setB is not None:
|
|
918
1110
|
setA, setB, status = set_live_status(setA, setB, status, not_status_option)
|
|
919
1111
|
else:
|
|
@@ -949,6 +1141,9 @@ def mask_contact_neighborhood(setA, setB, labelsA, labelsB, distance, mode='two-
|
|
|
949
1141
|
neigh_col = f'neighborhood_2_contact_{d}_px'
|
|
950
1142
|
elif mode == 'self':
|
|
951
1143
|
neigh_col = f'neighborhood_self_contact_{d}_px'
|
|
1144
|
+
else:
|
|
1145
|
+
print("Please provide a valid mode between `two-pop` and `self`...")
|
|
1146
|
+
return None
|
|
952
1147
|
|
|
953
1148
|
setA[neigh_col] = np.nan
|
|
954
1149
|
setA[neigh_col] = setA[neigh_col].astype(object)
|
|
@@ -961,163 +1156,30 @@ def mask_contact_neighborhood(setA, setB, labelsA, labelsB, distance, mode='two-
|
|
|
961
1156
|
int)
|
|
962
1157
|
for t in tqdm(timeline):
|
|
963
1158
|
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
coordinates_A = dataA[:,[0,1]]; ids_A = dataA[:,2]; mask_ids_A = dataA[:,3]; status_A = dataA[:,4];
|
|
967
|
-
|
|
968
|
-
index_B = list(setB.loc[setB[cl[1]['time']] == t].index)
|
|
969
|
-
dataB = setB.loc[setB[cl[1]['time']] == t, [cl[1]['x'], cl[1]['y'], cl[1]['track'], cl[1]['mask_id'], status[1]]].to_numpy()
|
|
970
|
-
coordinates_B = dataB[:,[0,1]]; ids_B = dataB[:,2]; mask_ids_B = dataB[:,3]; status_B = dataB[:,4]
|
|
971
|
-
|
|
972
|
-
if len(coordinates_A) > 0 and len(coordinates_B) > 0:
|
|
973
|
-
|
|
974
|
-
# compute distance matrix
|
|
975
|
-
dist_map = cdist(coordinates_A, coordinates_B, metric="euclidean")
|
|
976
|
-
intersection_map = np.zeros_like(dist_map).astype(float)
|
|
1159
|
+
setA_t = setA.loc[setA[cl[0]['time']] == t, :]
|
|
1160
|
+
setB_t = setB.loc[setB[cl[1]['time']] == t, :]
|
|
977
1161
|
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
lblB = labelsB[t]
|
|
983
|
-
if lblB is not None:
|
|
984
|
-
lblB = np.where(np.isin(lblB, mask_ids_B), lblB, 0.)
|
|
985
|
-
|
|
986
|
-
contact_pairs = contact_neighborhood(lblA, labelsB=lblB, border=d, connectivity=2)
|
|
987
|
-
|
|
988
|
-
# Put infinite distance to all non-contact pairs (something like this)
|
|
989
|
-
plot_map = False
|
|
990
|
-
flatA = lblA.flatten()
|
|
991
|
-
if lblB is not None:
|
|
992
|
-
flatB = lblB.flatten()
|
|
993
|
-
|
|
994
|
-
if len(contact_pairs) > 0:
|
|
995
|
-
mask = np.ones_like(dist_map).astype(bool)
|
|
996
|
-
|
|
997
|
-
indices_to_keep = []
|
|
998
|
-
for cp in contact_pairs:
|
|
999
|
-
|
|
1000
|
-
cp = np.abs(cp)
|
|
1001
|
-
mask_A, mask_B = cp
|
|
1002
|
-
idx_A = np.where(mask_ids_A == int(mask_A))[0][0]
|
|
1003
|
-
idx_B = np.where(mask_ids_B == int(mask_B))[0][0]
|
|
1004
|
-
|
|
1005
|
-
intersection = 0
|
|
1006
|
-
if lblB is not None:
|
|
1007
|
-
intersection = len(flatA[(flatA==int(mask_A))&(flatB==int(mask_B))])
|
|
1008
|
-
|
|
1009
|
-
indices_to_keep.append([idx_A,idx_B, intersection])
|
|
1010
|
-
print(f'Ref cell #{ids_A[idx_A]} matched with neigh. cell #{ids_B[idx_B]}...')
|
|
1011
|
-
print(f'Computed intersection: {intersection} px...')
|
|
1012
|
-
|
|
1013
|
-
if len(indices_to_keep) > 0:
|
|
1014
|
-
indices_to_keep = np.array(indices_to_keep)
|
|
1015
|
-
mask[indices_to_keep[:, 0], indices_to_keep[:, 1]] = False
|
|
1016
|
-
if mode == 'self':
|
|
1017
|
-
mask[indices_to_keep[:, 1], indices_to_keep[:, 0]] = False
|
|
1018
|
-
dist_map[mask] = 1.0E06
|
|
1019
|
-
intersection_map[indices_to_keep[:,0], indices_to_keep[:,1]] = indices_to_keep[:,2]
|
|
1020
|
-
plot_map=True
|
|
1021
|
-
else:
|
|
1022
|
-
dist_map[:,:] = 1.0E06
|
|
1023
|
-
else:
|
|
1024
|
-
dist_map[:, :] = 1.0E06
|
|
1162
|
+
if len(setA_t) > 0 and len(setB_t) > 0:
|
|
1163
|
+
dist_map, intersection_map = _compute_mask_contact_dist_map(setA_t, setB_t, labelsA[t], labelsB[t],
|
|
1164
|
+
distance=d, mode=mode, column_labelsA=cl[0],
|
|
1165
|
+
column_labelsB=cl[1])
|
|
1025
1166
|
|
|
1026
1167
|
d_filter = 1.0E05
|
|
1027
1168
|
if attention_weight:
|
|
1169
|
+
status_A = setA_t[status[0]].to_numpy()
|
|
1170
|
+
ids_A = setA_t[cl[0]["track"]].to_numpy()
|
|
1028
1171
|
weights, closest_A = compute_attention_weight(dist_map, d_filter, status_A, ids_A, axis=1,
|
|
1029
1172
|
include_dead_weight=include_dead_weight)
|
|
1173
|
+
else:
|
|
1174
|
+
weights = None
|
|
1175
|
+
closest_A = None
|
|
1030
1176
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
neighs_B = np.array([ids_B[i] for i in np.where((col <= d_filter))[0]])
|
|
1039
|
-
status_neigh_B = np.array([status_B[i] for i in np.where((col <= d_filter))[0]])
|
|
1040
|
-
dist_B = [round(col[i], 2) for i in np.where((col <= d_filter))[0]]
|
|
1041
|
-
intersect_B = [round(col_inter[i], 2) for i in np.where((col <= d_filter))[0]]
|
|
1042
|
-
|
|
1043
|
-
if len(dist_B) > 0:
|
|
1044
|
-
closest_B_cell = neighs_B[np.argmin(dist_B)]
|
|
1045
|
-
|
|
1046
|
-
if symmetrize and attention_weight:
|
|
1047
|
-
n_neighs = float(len(neighs_B))
|
|
1048
|
-
if not include_dead_weight:
|
|
1049
|
-
n_neighs_alive = len(np.where(status_neigh_B == 1)[0])
|
|
1050
|
-
neigh_count = n_neighs_alive
|
|
1051
|
-
else:
|
|
1052
|
-
neigh_count = n_neighs
|
|
1053
|
-
if neigh_count > 0:
|
|
1054
|
-
weight_A = 1. / neigh_count
|
|
1055
|
-
else:
|
|
1056
|
-
weight_A = np.nan
|
|
1057
|
-
|
|
1058
|
-
if not include_dead_weight and status_A[k] == 0:
|
|
1059
|
-
weight_A = 0
|
|
1060
|
-
|
|
1061
|
-
neighs = []
|
|
1062
|
-
setA.at[index_A[k], neigh_col] = []
|
|
1063
|
-
for n in range(len(neighs_B)):
|
|
1064
|
-
|
|
1065
|
-
# index in setB
|
|
1066
|
-
n_index = np.where(ids_B == neighs_B[n])[0][0]
|
|
1067
|
-
# Assess if neigh B is closest to A
|
|
1068
|
-
if attention_weight:
|
|
1069
|
-
if closest_A[n_index] == ids_A[k]:
|
|
1070
|
-
closest = True
|
|
1071
|
-
else:
|
|
1072
|
-
closest = False
|
|
1073
|
-
|
|
1074
|
-
if symmetrize:
|
|
1075
|
-
# Load neighborhood previous data
|
|
1076
|
-
sym_neigh = setB.loc[index_B[n_index], neigh_col]
|
|
1077
|
-
if neighs_B[n] == closest_B_cell:
|
|
1078
|
-
closest_b = True
|
|
1079
|
-
else:
|
|
1080
|
-
closest_b = False
|
|
1081
|
-
if isinstance(sym_neigh, list):
|
|
1082
|
-
sym_neigh.append({'id': ids_A[k], 'distance': dist_B[n], 'status': status_A[k], 'intersection': intersect_B[n]})
|
|
1083
|
-
else:
|
|
1084
|
-
sym_neigh = [{'id': ids_A[k], 'distance': dist_B[n], 'status': status_A[k], 'intersection': intersect_B[n]}]
|
|
1085
|
-
if attention_weight:
|
|
1086
|
-
sym_neigh[-1].update({'weight': weight_A, 'closest': closest_b})
|
|
1087
|
-
|
|
1088
|
-
# Write the minimum info about neighborhing cell B
|
|
1089
|
-
neigh_dico = {'id': neighs_B[n], 'distance': dist_B[n], 'status': status_neigh_B[n], 'intersection': intersect_B[n]}
|
|
1090
|
-
if attention_weight:
|
|
1091
|
-
neigh_dico.update({'weight': weights[n_index], 'closest': closest})
|
|
1092
|
-
|
|
1093
|
-
if compute_cum_sum:
|
|
1094
|
-
# Compute the integrated presence of the neighboring cell B
|
|
1095
|
-
assert cl[1][
|
|
1096
|
-
'track'] == 'TRACK_ID', 'The set B does not seem to contain tracked data. The cumulative time will be meaningless.'
|
|
1097
|
-
past_neighs = [[ll['id'] for ll in l] if len(l) > 0 else [None] for l in setA.loc[
|
|
1098
|
-
(setA[cl[0]['track']] == ids_A[k]) & (setA[cl[0]['time']] <= t), neigh_col].to_numpy()]
|
|
1099
|
-
past_neighs = [item for sublist in past_neighs for item in sublist]
|
|
1100
|
-
|
|
1101
|
-
if attention_weight:
|
|
1102
|
-
past_weights = [[ll['weight'] for ll in l] if len(l) > 0 else [None] for l in setA.loc[
|
|
1103
|
-
(setA[cl[0]['track']] == ids_A[k]) & (
|
|
1104
|
-
setA[cl[0]['time']] <= t), neigh_col].to_numpy()]
|
|
1105
|
-
past_weights = [item for sublist in past_weights for item in sublist]
|
|
1106
|
-
|
|
1107
|
-
cum_sum = len(np.where(past_neighs == neighs_B[n])[0])
|
|
1108
|
-
neigh_dico.update({'cumulated_presence': cum_sum + 1})
|
|
1109
|
-
|
|
1110
|
-
if attention_weight:
|
|
1111
|
-
cum_sum_weighted = np.sum(
|
|
1112
|
-
[w if l == neighs_B[n] else 0 for l, w in zip(past_neighs, past_weights)])
|
|
1113
|
-
neigh_dico.update({'cumulated_presence_weighted': cum_sum_weighted + weights[n_index]})
|
|
1114
|
-
|
|
1115
|
-
if symmetrize:
|
|
1116
|
-
setB.at[index_B[n_index], neigh_col] = sym_neigh
|
|
1117
|
-
|
|
1118
|
-
neighs.append(neigh_dico)
|
|
1119
|
-
|
|
1120
|
-
setA.at[index_A[k], neigh_col] = neighs
|
|
1177
|
+
_fill_contact_neighborhood_at_t(t, setA, setB, dist_map, intersection_map=intersection_map,
|
|
1178
|
+
attention_weight=attention_weight,
|
|
1179
|
+
include_dead_weight=include_dead_weight, symmetrize=symmetrize,
|
|
1180
|
+
compute_cum_sum=compute_cum_sum, weights=weights, closest_A=closest_A,
|
|
1181
|
+
neigh_col=neigh_col, column_labelsA=cl[0], column_labelsB=cl[1],
|
|
1182
|
+
statusA=status[0], statusB=status[1], d_filter=d_filter)
|
|
1121
1183
|
|
|
1122
1184
|
return setA, setB
|
|
1123
1185
|
|
|
@@ -1278,17 +1340,28 @@ def compute_contact_neighborhood_at_position(pos, distance, population=['targets
|
|
|
1278
1340
|
df_A = mean_neighborhood_after_event(df_A, neigh_col, event_time_col, metrics=['inclusive', 'intermediate'])
|
|
1279
1341
|
print('Done...')
|
|
1280
1342
|
|
|
1281
|
-
df_A.to_pickle(path_A.replace('.csv', '.pkl'))
|
|
1282
1343
|
if not population[0] == population[1]:
|
|
1283
|
-
# Remove neighborhood column
|
|
1344
|
+
# Remove neighborhood column from neighbor table, rename with actual population name
|
|
1284
1345
|
for td, d in zip(theta_dist, distance):
|
|
1285
1346
|
if neighborhood_kwargs['mode'] == 'two-pop':
|
|
1286
1347
|
neigh_col = f'neighborhood_2_contact_{d}_px'
|
|
1348
|
+
new_neigh_col = neigh_col.replace('_2_',f'_({population[0]}-{population[1]})_')
|
|
1349
|
+
df_A = df_A.rename(columns={neigh_col: new_neigh_col})
|
|
1287
1350
|
elif neighborhood_kwargs['mode'] == 'self':
|
|
1288
1351
|
neigh_col = f'neighborhood_self_contact_{d}_px'
|
|
1289
1352
|
df_B = df_B.drop(columns=[neigh_col])
|
|
1290
1353
|
df_B.to_pickle(path_B.replace('.csv', '.pkl'))
|
|
1291
1354
|
|
|
1355
|
+
cols_to_rename = [c for c in list(df_A.columns) if c.startswith('intermediate_count_') or c.startswith('inclusive_count_') or c.startswith('exclusive_count_') or c.startswith('mean_count_')]
|
|
1356
|
+
new_col_names = [c.replace('_2_',f'_({population[0]}-{population[1]})_') for c in cols_to_rename]
|
|
1357
|
+
new_name_map = {}
|
|
1358
|
+
for k,c in enumerate(cols_to_rename):
|
|
1359
|
+
new_name_map.update({c: new_col_names[k]})
|
|
1360
|
+
df_A = df_A.rename(columns=new_name_map)
|
|
1361
|
+
|
|
1362
|
+
print(f'{df_A.columns=}')
|
|
1363
|
+
df_A.to_pickle(path_A.replace('.csv', '.pkl'))
|
|
1364
|
+
|
|
1292
1365
|
unwanted = df_A.columns[df_A.columns.str.startswith('neighborhood_')]
|
|
1293
1366
|
df_A2 = df_A.drop(columns=unwanted)
|
|
1294
1367
|
df_A2.to_csv(path_A, index=False)
|
|
@@ -1355,28 +1428,29 @@ def extract_neighborhood_in_pair_table(df, distance=None, reference_population="
|
|
|
1355
1428
|
"""
|
|
1356
1429
|
|
|
1357
1430
|
|
|
1358
|
-
assert reference_population in ["targets", "effectors"], "Please set a valid reference population ('targets' or 'effectors')"
|
|
1431
|
+
#assert reference_population in ["targets", "effectors"], "Please set a valid reference population ('targets' or 'effectors')"
|
|
1359
1432
|
if neighborhood_key is None:
|
|
1360
|
-
assert neighbor_population in ["targets", "effectors"], "Please set a valid neighbor population ('targets' or 'effectors')"
|
|
1433
|
+
#assert neighbor_population in ["targets", "effectors"], "Please set a valid neighbor population ('targets' or 'effectors')"
|
|
1361
1434
|
assert mode in ["circle", "contact"], "Please set a valid neighborhood computation mode ('circle' or 'contact')"
|
|
1362
|
-
|
|
1363
|
-
type = "self"
|
|
1364
|
-
else:
|
|
1365
|
-
type = "2"
|
|
1366
|
-
|
|
1435
|
+
type = '('+'-'.join([reference_population, neighbor_population])+')'
|
|
1367
1436
|
neigh_col = f"neighborhood_{type}_{mode}_{distance}_px"
|
|
1368
1437
|
else:
|
|
1369
1438
|
neigh_col = neighborhood_key.replace('status_','')
|
|
1370
|
-
if '
|
|
1371
|
-
neighbor_population =
|
|
1439
|
+
if '_(' in neigh_col and ')_' in neigh_col:
|
|
1440
|
+
neighbor_population = neigh_col.split('_(')[-1].split(')_')[0].split('-')[-1]
|
|
1372
1441
|
else:
|
|
1373
|
-
if
|
|
1374
|
-
neighbor_population
|
|
1442
|
+
if 'self' in neigh_col:
|
|
1443
|
+
neighbor_population = reference_population
|
|
1375
1444
|
else:
|
|
1376
|
-
|
|
1445
|
+
if reference_population=="effectors":
|
|
1446
|
+
neighbor_population='targets'
|
|
1447
|
+
else:
|
|
1448
|
+
neighbor_population='effectors'
|
|
1377
1449
|
|
|
1378
1450
|
assert "status_"+neigh_col in list(df.columns),"The selected neighborhood does not appear in the data..."
|
|
1379
1451
|
|
|
1452
|
+
print(df[['reference_population','neighbor_population', "status_"+neigh_col]])
|
|
1453
|
+
|
|
1380
1454
|
if contact_only:
|
|
1381
1455
|
s_keep = [1]
|
|
1382
1456
|
else:
|