Skip to content

Commit f5f7896

Browse files
committed
fix TD/DD proportion test
1 parent 933f89b commit f5f7896

2 files changed

Lines changed: 83 additions & 56 deletions

File tree

tests/test_validations.py

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,15 @@ def test_td_dd_ratio():
212212
)
213213
for fdr_group in ['self', 'between']:
214214
# Test too few TT in CSM level
215-
n_td = min(len(x['csm'].filter('TD', pl.col('fdr_group') == fdr_group)), 10)
216215
n_dd = min(len(x['csm'].filter('DD', pl.col('fdr_group') == fdr_group)), 20)
217216
df = pl.concat([
218217
x['csm'].filter('TT', pl.col('fdr_group') == fdr_group),
219-
x['csm'].filter('TD', pl.col('fdr_group') == fdr_group).sample(n_td, seed=0),
220-
x['csm'].filter('DD', pl.col('fdr_group') == fdr_group).sample(n_dd, seed=0),
218+
x['csm'].sort('score', descending=True).filter(
219+
'TD', pl.col('fdr_group') == fdr_group
220+
).head(n_dd-1),
221+
x['csm'].sort('score', descending=True).filter(
222+
'DD', pl.col('fdr_group') == fdr_group
223+
).head(n_dd),
221224
x['csm'].filter(pl.col('fdr_group') != fdr_group)
222225
])
223226
with warnings.catch_warnings(record=True) as caught_warns:
@@ -233,12 +236,15 @@ def test_td_dd_ratio():
233236
assert len(td_dd_warn) == 1
234237

235238
# Test too few TT in peptide level
236-
n_td = min(len(x['csm'].filter('TD', pl.col('fdr_group') == fdr_group)), 10)
237239
n_dd = min(len(x['csm'].filter('DD', pl.col('fdr_group') == fdr_group)), 20)
238240
df = pl.concat([
239241
x['csm'].filter('TT', pl.col('fdr_group') == fdr_group),
240-
x['csm'].filter('TD', pl.col('fdr_group') == fdr_group).sample(n_td, seed=0),
241-
x['csm'].filter('DD', pl.col('fdr_group') == fdr_group).sample(n_dd, seed=0),
242+
x['csm'].sort('score', descending=True).filter(
243+
'TD', pl.col('fdr_group') == fdr_group
244+
).head(n_dd-1),
245+
x['csm'].sort('score', descending=True).filter(
246+
'DD', pl.col('fdr_group') == fdr_group
247+
).head(n_dd),
242248
x['csm'].filter(pl.col('fdr_group') != fdr_group)
243249
])
244250
with warnings.catch_warnings(record=True) as caught_warns:
@@ -256,12 +262,15 @@ def test_td_dd_ratio():
256262

257263
for fdr_group in ['self', 'between']:
258264
# Test too few TT in link level
259-
n_td = min(len(x['pep'].filter('TD', pl.col('fdr_group') == fdr_group)), 10)
260265
n_dd = min(len(x['pep'].filter('DD', pl.col('fdr_group') == fdr_group)), 20)
261266
df = pl.concat([
262267
x['pep'].filter('TT', pl.col('fdr_group') == fdr_group),
263-
x['pep'].filter('TD', pl.col('fdr_group') == fdr_group).sample(n_td, seed=0),
264-
x['pep'].filter('DD', pl.col('fdr_group') == fdr_group).sample(n_dd, seed=0),
268+
x['pep'].sort('score', descending=True).filter(
269+
'TD', pl.col('fdr_group') == fdr_group
270+
).head(n_dd-1),
271+
x['pep'].sort('score', descending=True).filter(
272+
'DD', pl.col('fdr_group') == fdr_group
273+
).sample(n_dd),
265274
x['pep'].filter(pl.col('fdr_group') != fdr_group)
266275
])
267276
with warnings.catch_warnings(record=True) as caught_warns:
@@ -278,12 +287,18 @@ def test_td_dd_ratio():
278287
assert len(td_dd_warn) == 1
279288

280289
# Test too few TT in PPI level
281-
n_td = min(len(x['link'].filter('TD', pl.col('fdr_group') == fdr_group)), 10)
282-
n_dd = min(len(x['link'].filter('DD', pl.col('fdr_group') == fdr_group)), 20)
290+
n_dd = min(
291+
len(x['link'].filter('DD', pl.col('fdr_group') == fdr_group)),
292+
5
293+
)
283294
df = pl.concat([
284295
x['link'].filter('TT', pl.col('fdr_group') == fdr_group),
285-
x['link'].filter('TD', pl.col('fdr_group') == fdr_group).sample(n_td, seed=0),
286-
x['link'].filter('DD', pl.col('fdr_group') == fdr_group).sample(n_dd, seed=0),
296+
x['link'].sort('score').filter(
297+
'TD', pl.col('fdr_group') == fdr_group
298+
).head(n_dd-1),
299+
x['link'].sort('score', descending=True).filter(
300+
'DD', pl.col('fdr_group') == fdr_group
301+
).head(n_dd),
287302
x['link'].filter(pl.col('fdr_group') != fdr_group)
288303
])
289304
with warnings.catch_warnings(record=True) as caught_warns:

xifdr/fdr.py

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -190,21 +190,24 @@ def _csm_fdr(df, csm_fdr, unique_csm, td_prob, td_dd_ratio):
190190
logger.debug('Calculate CSM FDR and cutoff')
191191
df_csm = df_csm.with_columns(
192192
csm_fdr = single_grouped_fdr(df_csm)
193-
)
194-
df_csm = df_csm.filter(pl.col('csm_fdr') <= csm_fdr)
193+
).filter(pl.col('csm_fdr') <= csm_fdr)
194+
195195
for fdr_group in fdr_groups_csm_pep:
196-
target_group = df_csm.filter(
197-
pl.col('fdr_group') == fdr_group
198-
)
199-
df_csm_tt = target_group.filter(pl.col('TT'))
200-
df_csm_td = target_group.filter(pl.col('TD'))
201-
df_csm_dd = target_group.filter(pl.col('DD'))
202-
if len(df_csm_tt)*csm_fdr < td_prob:
196+
passed_group = df_csm.filter(pl.col('fdr_group') == fdr_group)
197+
if passed_group.is_empty():
198+
continue
199+
200+
n_tt = passed_group.filter(pl.col('TT')).height
201+
n_td = passed_group.filter(pl.col('TD')).height
202+
n_dd = passed_group.filter(pl.col('DD')).height
203+
204+
if n_tt * csm_fdr < td_prob:
203205
warnings.warn(f'Insufficient TT for CSM FDR in group {fdr_group}.')
204206
df_csm = df_csm.filter(pl.col('fdr_group') != fdr_group)
205-
if len(df_csm_dd)*td_dd_ratio > len(df_csm_td):
207+
if n_dd * td_dd_ratio > n_td:
206208
warnings.warn(f'More DD than TD for CSM FDR in group {fdr_group}.')
207209
df_csm = df_csm.filter(pl.col('fdr_group') != fdr_group)
210+
208211
return df_csm
209212

210213

@@ -222,21 +225,24 @@ def _pep_fdr(df_csm, agg, pep_fdr, first_aggs, never_agg_cols, td_prob, td_dd_ra
222225
)
223226
df_pep = df_pep.with_columns(
224227
pep_fdr = single_grouped_fdr(df_pep)
225-
)
226-
df_pep = df_pep.filter(pl.col('pep_fdr') <= pep_fdr)
228+
).filter(pl.col('pep_fdr') <= pep_fdr)
229+
227230
for fdr_group in fdr_groups_csm_pep:
228-
target_group = df_pep.filter(
229-
pl.col('fdr_group') == fdr_group
230-
)
231-
df_pep_tt = target_group.filter(pl.col('TT'))
232-
df_pep_td = target_group.filter(pl.col('TD'))
233-
df_pep_dd = target_group.filter(pl.col('DD'))
234-
if len(df_pep_tt)*pep_fdr < td_prob:
231+
passed_group = df_pep.filter(pl.col('fdr_group') == fdr_group)
232+
if passed_group.is_empty():
233+
continue
234+
235+
n_tt = passed_group.filter(pl.col('TT')).height
236+
n_td = passed_group.filter(pl.col('TD')).height
237+
n_dd = passed_group.filter(pl.col('DD')).height
238+
239+
if n_tt * pep_fdr < td_prob:
235240
warnings.warn(f'Insufficient TT for peptide FDR in group {fdr_group}.')
236241
df_pep = df_pep.filter(pl.col('fdr_group') != fdr_group)
237-
if len(df_pep_dd)*td_dd_ratio > len(df_pep_td):
242+
if n_dd * td_dd_ratio > n_td:
238243
warnings.warn(f'More DD than TD for peptide FDR in group {fdr_group}.')
239244
df_pep = df_pep.filter(pl.col('fdr_group') != fdr_group)
245+
240246
return df_pep
241247

242248

@@ -383,21 +389,24 @@ def _link_fdr(df_pep, agg, link_fdr, first_aggs, never_agg_cols, td_prob, td_dd_
383389
)
384390
df_link = df_link.with_columns(
385391
link_fdr = single_grouped_fdr(df_link)
386-
)
387-
df_link = df_link.filter(pl.col('link_fdr') <= link_fdr)
392+
).filter(pl.col('link_fdr') <= link_fdr)
393+
388394
for fdr_group in fdr_groups_link_ppi:
389-
target_group = df_link.filter(
390-
pl.col('fdr_group') == fdr_group
391-
)
392-
df_link_tt = target_group.filter(pl.col('TT'))
393-
df_link_td = target_group.filter(pl.col('TD'))
394-
df_link_dd = target_group.filter(pl.col('DD'))
395-
if len(df_link_tt)*link_fdr < td_prob:
395+
passed_group = df_link.filter(pl.col('fdr_group') == fdr_group)
396+
if passed_group.is_empty():
397+
continue
398+
399+
n_tt = passed_group.filter(pl.col('TT')).height
400+
n_td = passed_group.filter(pl.col('TD')).height
401+
n_dd = passed_group.filter(pl.col('DD')).height
402+
403+
if n_tt * link_fdr < td_prob:
396404
warnings.warn(f'Insufficient TT for link FDR in group {fdr_group}.')
397405
df_link = df_link.filter(pl.col('fdr_group') != fdr_group)
398-
if len(df_link_dd)*td_dd_ratio > len(df_link_td):
406+
if n_dd * td_dd_ratio > n_td:
399407
warnings.warn(f'More DD than TD for link FDR in group {fdr_group}.')
400408
df_link = df_link.filter(pl.col('fdr_group') != fdr_group)
409+
401410
return df_link
402411

403412

@@ -437,21 +446,24 @@ def _ppi_fdr(df_link, agg, ppi_fdr, first_aggs, never_agg_cols, td_prob, td_dd_r
437446
)
438447
df_ppi = df_ppi.with_columns(
439448
ppi_fdr = single_grouped_fdr(df_ppi)
440-
)
441-
df_ppi = df_ppi.filter(pl.col('ppi_fdr') <= ppi_fdr)
449+
).filter(pl.col('ppi_fdr') <= ppi_fdr)
450+
442451
for fdr_group in fdr_groups_link_ppi:
443-
target_group = df_ppi.filter(
444-
pl.col('fdr_group') == fdr_group
445-
)
446-
df_ppi_tt = target_group.filter(pl.col('TT'))
447-
df_ppi_td = target_group.filter(pl.col('TD'))
448-
df_ppi_dd = target_group.filter(pl.col('DD'))
449-
if len(df_ppi_tt)*ppi_fdr < td_prob:
452+
passed_group = df_ppi.filter(pl.col('fdr_group') == fdr_group)
453+
if passed_group.is_empty():
454+
continue
455+
456+
n_tt = passed_group.filter(pl.col('TT')).height
457+
n_td = passed_group.filter(pl.col('TD')).height
458+
n_dd = passed_group.filter(pl.col('DD')).height
459+
460+
if n_tt * ppi_fdr < td_prob:
450461
warnings.warn(f'Insufficient TT for PPI FDR in group {fdr_group}.')
451462
df_ppi = df_ppi.filter(pl.col('fdr_group') != fdr_group)
452-
if len(df_ppi_dd)*td_dd_ratio > len(df_ppi_td):
463+
if n_dd * td_dd_ratio > n_td:
453464
warnings.warn(f'More DD than TD for PPI FDR in group {fdr_group}.')
454465
df_ppi = df_ppi.filter(pl.col('fdr_group') != fdr_group)
466+
455467
return df_ppi
456468

457469

@@ -512,10 +524,10 @@ def single_fdr(df: Union[pl.DataFrame, pd.DataFrame]) -> pl.Series:
512524
working_df = working_df.with_row_index(order_col)
513525
working_df = working_df.sort('score', descending=True)
514526
fdr_raw = (
515-
(working_df['TD'].cast(pl.Int8).cum_sum() - working_df['DD'].cast(pl.Int8).cum_sum())
516-
/ working_df['TT'].cast(pl.Int8).cum_sum()
527+
(working_df['TD'].cast(pl.Int32).cum_sum() - working_df['DD'].cast(pl.Int32).cum_sum())
528+
/ working_df['TT'].cast(pl.Int32).cum_sum()
517529
)
518530
working_df = working_df.with_columns(
519-
fdr = fdr_raw.reverse().cum_min().reverse()
531+
fdr = fdr_raw.clip(lower_bound=0).reverse().cum_min().reverse()
520532
)
521533
return working_df.sort(order_col)['fdr']

0 commit comments

Comments
 (0)