The impact of molecular size on similarity between very closely related molecules.

reference
similarity
fingerprints
How molecule size affects the impact of single-atom changes on molecular similarity.
Published

July 4, 2025

This post adapts the analysis I did previously of the impact of single-atom changes on calculated similarity to take into account molecule size. It’s kind of kind of a “part 2” of the post looking at the impact of molecular size on similarity

For the analysis I use the same sets (tranches) of molecules collected from PubChem in part 1. I randomly selected 10K molecules from each tranche. The code for determining the impact of single-atom changes in each molecule is the same as the earlier post.

The results look like this:

fp type tranche shift 90% 95%
MFP2 bits 10 0.46(0.11) 0.32 0.29
MFP2 bits 20 0.64(0.09) 0.52 0.48
MFP2 bits 30 0.71(0.08) 0.60 0.57
MFP2 bits 40 0.77(0.07) 0.68 0.66
MFP2 bits 50 0.80(0.06) 0.72 0.69

As before, we can think about these values as thresholds for retrieving extremely similar molecules; here we define that to mean molecules that have the same connectivity and differ in the identity of a single atom.

When working with molecules with between 10 and 20 atoms and using the MFP2 fingerprint (Morgan fingerprint with radius 2) we need to use a Tanimoto similarity threshold of 0.48 to be 95% certain of retrieving extremely similar molecules. The threshold goes up to 0.66 when working with molecules with between 30 and 40 atoms. The average similarity between extremely similar molecules with between 10 and 20 atoms is 0.64 with a standard deviation of 0.09.

Unsurprisingly, the values increase with the size of the molecules in the tranche. This holds for all of the fingerprints.

Here’s the giant table of numbers:

fp type tranche shift 90% 95%
MFP0 counts 10 0.77(0.07) 0.75 0.67
MFP0 counts 20 0.89(0.02) 0.87 0.86
MFP0 counts 30 0.92(0.01) 0.90 0.90
MFP0 counts 40 0.94(0.00) 0.94 0.94
MFP0 counts 50 0.96(0.00) 0.95 0.95
MFP1 counts 10 0.61(0.09) 0.50 0.45
MFP1 counts 20 0.78(0.04) 0.73 0.70
MFP1 counts 30 0.84(0.03) 0.80 0.78
MFP1 counts 40 0.88(0.02) 0.86 0.85
MFP1 counts 50 0.91(0.02) 0.89 0.88
MFP2 counts 10 0.49(0.10) 0.36 0.33
MFP2 counts 20 0.68(0.08) 0.58 0.55
MFP2 counts 30 0.75(0.06) 0.68 0.66
MFP2 counts 40 0.82(0.04) 0.76 0.75
MFP2 counts 50 0.85(0.04) 0.81 0.80
MFP3 counts 10 0.44(0.10) 0.32 0.29
MFP3 counts 20 0.60(0.10) 0.47 0.44
MFP3 counts 30 0.68(0.08) 0.58 0.55
MFP3 counts 40 0.75(0.07) 0.67 0.65
MFP3 counts 50 0.80(0.06) 0.73 0.71
MFP0 bits 10 0.77(0.10) 0.67 0.60
MFP0 bits 20 0.87(0.05) 0.80 0.78
MFP0 bits 30 0.89(0.04) 0.82 0.80
MFP0 bits 40 0.91(0.03) 0.86 0.83
MFP0 bits 50 0.91(0.04) 0.86 0.83
MFP1 bits 10 0.59(0.11) 0.47 0.41
MFP1 bits 20 0.75(0.07) 0.67 0.63
MFP1 bits 30 0.80(0.06) 0.73 0.71
MFP1 bits 40 0.84(0.05) 0.78 0.76
MFP1 bits 50 0.86(0.05) 0.80 0.78
MFP2 bits 10 0.46(0.11) 0.32 0.29
MFP2 bits 20 0.64(0.09) 0.52 0.48
MFP2 bits 30 0.71(0.08) 0.60 0.57
MFP2 bits 40 0.77(0.07) 0.68 0.66
MFP2 bits 50 0.80(0.06) 0.72 0.69
MFP3 bits 10 0.41(0.11) 0.29 0.26
MFP3 bits 20 0.55(0.11) 0.41 0.37
MFP3 bits 30 0.63(0.10) 0.50 0.46
MFP3 bits 40 0.70(0.09) 0.59 0.56
MFP3 bits 50 0.74(0.08) 0.64 0.60
FFP0 counts 10 0.91(0.13) 0.75 0.71
FFP0 counts 20 0.96(0.06) 0.88 0.86
FFP0 counts 30 0.98(0.04) 0.91 0.90
FFP0 counts 40 0.98(0.03) 0.94 0.94
FFP0 counts 50 0.99(0.02) 0.95 0.95
FFP1 counts 10 0.85(0.20) 0.57 0.50
FFP1 counts 20 0.93(0.11) 0.77 0.73
FFP1 counts 30 0.96(0.07) 0.84 0.82
FFP1 counts 40 0.97(0.05) 0.88 0.86
FFP1 counts 50 0.98(0.04) 0.91 0.89
FFP2 counts 10 0.81(0.25) 0.43 0.38
FFP2 counts 20 0.90(0.15) 0.65 0.61
FFP2 counts 30 0.94(0.11) 0.75 0.71
FFP2 counts 40 0.96(0.08) 0.81 0.79
FFP2 counts 50 0.97(0.06) 0.85 0.83
FFP3 counts 10 0.79(0.27) 0.37 0.33
FFP3 counts 20 0.88(0.19) 0.56 0.51
FFP3 counts 30 0.92(0.14) 0.67 0.62
FFP3 counts 40 0.94(0.11) 0.74 0.71
FFP3 counts 50 0.95(0.09) 0.79 0.76
FFP0 bits 10 0.92(0.16) 0.67 0.50
FFP0 bits 20 0.96(0.11) 0.80 0.71
FFP0 bits 30 0.97(0.08) 0.86 0.80
FFP0 bits 40 0.98(0.06) 1.00 0.83
FFP0 bits 50 0.99(0.05) 1.00 0.86
FFP1 bits 10 0.84(0.22) 0.50 0.43
FFP1 bits 20 0.92(0.14) 0.69 0.62
FFP1 bits 30 0.95(0.11) 0.77 0.71
FFP1 bits 40 0.96(0.08) 0.83 0.78
FFP1 bits 50 0.97(0.06) 0.88 0.82
FFP2 bits 10 0.78(0.28) 0.35 0.29
FFP2 bits 20 0.88(0.19) 0.56 0.50
FFP2 bits 30 0.92(0.14) 0.66 0.60
FFP2 bits 40 0.94(0.11) 0.74 0.69
FFP2 bits 50 0.95(0.09) 0.79 0.74
FFP3 bits 10 0.76(0.30) 0.30 0.25
FFP3 bits 20 0.85(0.23) 0.45 0.39
FFP3 bits 30 0.90(0.18) 0.57 0.51
FFP3 bits 40 0.92(0.14) 0.66 0.60
FFP3 bits 50 0.94(0.12) 0.72 0.66
RDK5 counts 10 0.36(0.19) 0.13 0.09
RDK5 counts 20 0.59(0.18) 0.35 0.29
RDK5 counts 30 0.69(0.14) 0.49 0.43
RDK5 counts 40 0.77(0.12) 0.60 0.55
RDK5 counts 50 0.81(0.10) 0.66 0.62
RDK7 counts 10 0.30(0.16) 0.11 0.08
RDK7 counts 20 0.53(0.20) 0.27 0.22
RDK7 counts 30 0.64(0.17) 0.40 0.35
RDK7 counts 40 0.73(0.14) 0.53 0.47
RDK7 counts 50 0.79(0.13) 0.60 0.55
RDK5 bits 10 0.36(0.18) 0.14 0.11
RDK5 bits 20 0.59(0.17) 0.36 0.30
RDK5 bits 30 0.68(0.15) 0.47 0.42
RDK5 bits 40 0.76(0.13) 0.58 0.52
RDK5 bits 50 0.79(0.12) 0.62 0.57
RDK7 bits 10 0.30(0.16) 0.12 0.09
RDK7 bits 20 0.55(0.19) 0.31 0.26
RDK7 bits 30 0.68(0.16) 0.46 0.41
RDK7 bits 40 0.79(0.13) 0.61 0.55
RDK7 bits 50 0.84(0.11) 0.68 0.63
TT counts 10 0.38(0.24) 0.00 0.00
TT counts 20 0.63(0.17) 0.41 0.35
TT counts 30 0.72(0.13) 0.55 0.50
TT counts 40 0.79(0.10) 0.66 0.62
TT counts 50 0.84(0.08) 0.72 0.69
TT bits 10 0.41(0.25) 0.08 0.00
TT bits 20 0.64(0.17) 0.41 0.35
TT bits 30 0.73(0.13) 0.55 0.50
TT bits 40 0.79(0.10) 0.66 0.62
TT bits 50 0.83(0.09) 0.71 0.68
AP counts 10 0.61(0.09) 0.56 0.50
AP counts 20 0.79(0.03) 0.75 0.73
AP counts 30 0.85(0.02) 0.82 0.82
AP counts 40 0.89(0.01) 0.88 0.88
AP counts 50 0.91(0.01) 0.90 0.90
AP bits 10 0.62(0.09) 0.56 0.50
AP bits 20 0.79(0.04) 0.75 0.72
AP bits 30 0.85(0.03) 0.82 0.81
AP bits 40 0.89(0.02) 0.87 0.86
AP bits 50 0.91(0.02) 0.89 0.88
import gzip
import glob
import pickle
import numpy as np

from rdkit import Chem
from rdkit import rdBase
import rdkit
print(rdkit.__version__)

import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('tableau-colorblind10')
2025.03.3
with gzip.open('./results/pubchem_tranches.pkl.gz','rb') as inf:
    mol_accum = pickle.load(inf)

We need to remove Hs from the input molecules, and we’ll only keep the first 10K from each tranche

import random
random.seed(0xa100f)
with rdBase.BlockLogs() as bl:
    for k in mol_accum:
        nv = []
        v = mol_accum[k]
        random.shuffle(v)
        v = v[:10000]
        for m in v:
            try:
                nm = Chem.RemoveHs(m)
            except Chem.MolSanitizeException:
                pass
            nv.append(nm)
        mol_accum[k] = nv
print([len(v) for v in mol_accum.values()])
[10000, 10000, 10000, 10000, 10000]
from rdkit.Chem import Draw
Draw.MolsToGridImage(mol_accum[20][:10])

Collect similarity values for bit-based and count-based fingerprints using

from rdkit import DataStructs
def get_modified_sims2(mol,maxRadius,fpgFunc,method):
    fpg = fpgFunc()
    fpFunc = getattr(fpg,method)
    basefp = fpFunc(mol)
    dm = Chem.GetDistanceMatrix(mol)
    res = []
    for aidx in range(mol.GetNumAtoms()):
        nm = Chem.Mol(mol)
        nm.GetAtomWithIdx(aidx).SetAtomicNum(0)
        count = sum(dm[aidx]<=maxRadius)
        res.append((count,DataStructs.TanimotoSimilarity(basefp,fpFunc(nm))))
    return res
try:
    import ipyparallel as ipp
    rc = ipp.Client()
    dview = rc[:]
    dview.execute('from rdkit import Chem')
    dview.execute('from rdkit.Chem import rdFingerprintGenerator')
    dview.execute('from rdkit import DataStructs')
except:
    print("could not use ipyparallel")
    dview = None
from collections import defaultdict
mfp_accum = defaultdict(lambda: defaultdict(lambda : defaultdict(list)))

for k in mol_accum:
    for radius in (0,1,2,3):
        print(f'tranche: {k}, radius {radius}')
        fpg = lambda r=radius:rdFingerprintGenerator.GetMorganGenerator(radius=r,fpSize=2048)
        lres = dview.map_sync(lambda x,r=radius,y=get_modified_sims2,
                              z=fpg:y(x,r,z,'GetCountFingerprint'),mol_accum[k])
        for entry in lres:
            mfp_accum[k]['counts'][radius].extend(entry)
        lres = dview.map_sync(lambda x,r=radius,y=get_modified_sims2,
                              z=fpg:y(x,r,z,'GetFingerprint'),mol_accum[k])
        for entry in lres:
            mfp_accum[k]['bits'][radius].extend(entry)
tranche: 10, radius 0
tranche: 10, radius 1
tranche: 10, radius 2
tranche: 10, radius 3
tranche: 20, radius 0
tranche: 20, radius 1
tranche: 20, radius 2
tranche: 20, radius 3
tranche: 30, radius 0
tranche: 30, radius 1
tranche: 30, radius 2
tranche: 30, radius 3
tranche: 40, radius 0
tranche: 40, radius 1
tranche: 40, radius 2
tranche: 40, radius 3
tranche: 50, radius 0
tranche: 50, radius 1
tranche: 50, radius 2
tranche: 50, radius 3
ffp_accum = defaultdict(lambda: defaultdict(lambda : defaultdict(list)))

for k in mol_accum:
    for radius in (0, 1,2,3):
        print(f'tranche: {k}, radius {radius}')
        fpg = lambda r=radius:rdFingerprintGenerator.GetMorganGenerator(radius=r,fpSize=2048,
                                                                        atomInvariantsGenerator=rdFingerprintGenerator.GetMorganFeatureAtomInvGen())
        lres = dview.map_sync(lambda x,r=radius,y=get_modified_sims2,
                              z=fpg:y(x,r,z,'GetCountFingerprint'),mol_accum[k])
        for entry in lres:
            ffp_accum[k]['counts'][radius].extend(entry)
        lres = dview.map_sync(lambda x,r=radius,y=get_modified_sims2,
                              z=fpg:y(x,r,z,'GetFingerprint'),mol_accum[k])
        for entry in lres:
            ffp_accum[k]['bits'][radius].extend(entry)
tranche: 10, radius 0
tranche: 10, radius 1
tranche: 10, radius 2
tranche: 10, radius 3
tranche: 20, radius 0
tranche: 20, radius 1
tranche: 20, radius 2
tranche: 20, radius 3
tranche: 30, radius 0
tranche: 30, radius 1
tranche: 30, radius 2
tranche: 30, radius 3
tranche: 40, radius 0
tranche: 40, radius 1
tranche: 40, radius 2
tranche: 40, radius 3
tranche: 50, radius 0
tranche: 50, radius 1
tranche: 50, radius 2
tranche: 50, radius 3
rdk_accum = defaultdict(lambda: defaultdict(lambda : defaultdict(list)))

for k in mol_accum:
    for radius in (5,7):
        print(f'tranche: {k}, radius {radius}')
        fpg = lambda r=radius:rdFingerprintGenerator.GetRDKitFPGenerator(maxPath=r,fpSize=2048)
        lres = dview.map_sync(lambda x,r=radius,y=get_modified_sims2,
                              z=fpg:y(x,r,z,'GetCountFingerprint'),mol_accum[k])
        for entry in lres:
            rdk_accum[k]['counts'][radius].extend(entry)
        lres = dview.map_sync(lambda x,r=radius,y=get_modified_sims2,
                              z=fpg:y(x,r,z,'GetFingerprint'),mol_accum[k])
        for entry in lres:
            rdk_accum[k]['bits'][radius].extend(entry)
tranche: 10, radius 5
tranche: 10, radius 7
tranche: 20, radius 5
tranche: 20, radius 7
tranche: 30, radius 5
tranche: 30, radius 7
tranche: 40, radius 5
tranche: 40, radius 7
tranche: 50, radius 5
tranche: 50, radius 7
tt_accum = defaultdict(lambda: defaultdict(lambda : defaultdict(list)))

for k in mol_accum:
    for radius in (3,):
        print(f'tranche: {k}, radius {radius}')
        fpg = lambda r=radius:rdFingerprintGenerator.GetTopologicalTorsionGenerator(fpSize=4096)
        lres = dview.map_sync(lambda x,r=radius,y=get_modified_sims2,
                              z=fpg:y(x,r,z,'GetCountFingerprint'),mol_accum[k])
        for entry in lres:
            tt_accum[k]['counts'][radius].extend(entry)
        lres = dview.map_sync(lambda x,r=radius,y=get_modified_sims2,
                              z=fpg:y(x,r,z,'GetFingerprint'),mol_accum[k])
        for entry in lres:
            tt_accum[k]['bits'][radius].extend(entry)
tranche: 10, radius 3
tranche: 20, radius 3
tranche: 30, radius 3
tranche: 40, radius 3
tranche: 50, radius 3
ap_accum = defaultdict(lambda: defaultdict(lambda : defaultdict(list)))

for k in mol_accum:
    for radius in (3,):
        print(f'tranche: {k}, radius {radius}')
        fpg = lambda r=radius:rdFingerprintGenerator.GetAtomPairGenerator(fpSize=4096)
        lres = dview.map_sync(lambda x,r=radius,y=get_modified_sims2,
                              z=fpg:y(x,r,z,'GetCountFingerprint'),mol_accum[k])
        for entry in lres:
            ap_accum[k]['counts'][radius].extend(entry)
        lres = dview.map_sync(lambda x,r=radius,y=get_modified_sims2,
                              z=fpg:y(x,r,z,'GetFingerprint'),mol_accum[k])
        for entry in lres:
            ap_accum[k]['bits'][radius].extend(entry)
tranche: 10, radius 3
tranche: 20, radius 3
tranche: 30, radius 3
tranche: 40, radius 3
tranche: 50, radius 3
import copy
def to_dict(dd):
    if not isinstance(dd,defaultdict):
        return copy.deepcopy(dd)
    res = {}
    for k,v in dd.items():
        res[k] = to_dict(v)
    return res
import pickle
import gzip
with gzip.open('./results/fp_perturbation.tranches.pkl.gz','wb+') as outf:
    pickle.dump((to_dict(mfp_accum),to_dict(ffp_accum),to_dict(rdk_accum),to_dict(ap_accum),to_dict(tt_accum)),outf)
!ls -lh ./results/fp_perturbation.tranches.pkl.gz
-rw-rw-r-- 1 glandrum glandrum 85M Jul  3 16:16 ./results/fp_perturbation.tranches.pkl.gz
print('''| fp | type | tranche| shift | 90% | 95% |
| -- | -- | -- | -- | -- | -- |''')

rs = (0, 1, 2, 3)
titl='MFP'
accum = mfp_accum

for which in ('counts','bits'):
    for rad in rs:
        for tranche in accum:
            tacc = accum[tranche]
            yps = [y for x,y in tacc[which][rad]]
            qs = np.quantile(yps,[0.1,0.05])
            print(f'| {titl}{rad} | {which} | {tranche} | {np.mean(yps):.2f}({np.std(yps):.2f}) | {qs[0]:.2f} | {qs[1]:.2f} |')
titl='FFP'
accum = ffp_accum

for which in ('counts','bits'):
    for rad in rs:
        for tranche in accum:
            tacc = accum[tranche]
            yps = [y for x,y in tacc[which][rad]]
            qs = np.quantile(yps,[0.1,0.05])
            print(f'| {titl}{rad} | {which} | {tranche} | {np.mean(yps):.2f}({np.std(yps):.2f}) | {qs[0]:.2f} | {qs[1]:.2f} |')

rs = (5,7)
titl='RDK'
accum = rdk_accum

for which in ('counts','bits'):
    for rad in rs:
        for tranche in accum:
            tacc = accum[tranche]
            yps = [y for x,y in tacc[which][rad]]
            qs = np.quantile(yps,[0.1,0.05])
            print(f'| {titl}{rad} | {which} | {tranche} | {np.mean(yps):.2f}({np.std(yps):.2f}) | {qs[0]:.2f} | {qs[1]:.2f} |')


rs = (3, )
titl='TT'
accum = tt_accum

for which in ('counts','bits'):
    for rad in rs:
        for tranche in accum:
            tacc = accum[tranche]
            yps = [y for x,y in tacc[which][rad]]
            qs = np.quantile(yps,[0.1,0.05])
            print(f'| {titl} | {which} | {tranche} | {np.mean(yps):.2f}({np.std(yps):.2f}) | {qs[0]:.2f} | {qs[1]:.2f} |')
            
rs = (3, )
titl='AP'
accum = ap_accum

for which in ('counts','bits'):
    for rad in rs:
        for tranche in accum:
            tacc = accum[tranche]
            yps = [y for x,y in tacc[which][rad]]
            qs = np.quantile(yps,[0.1,0.05])
            print(f'| {titl} | {which} | {tranche} | {np.mean(yps):.2f}({np.std(yps):.2f}) | {qs[0]:.2f} | {qs[1]:.2f} |')
         
| fp | type | tranche| shift | 90% | 95% |
| -- | -- | -- | -- | -- | -- |
| MFP0 | counts | 10 | 0.77(0.07) | 0.75 | 0.67 |
| MFP0 | counts | 20 | 0.89(0.02) | 0.87 | 0.86 |
| MFP0 | counts | 30 | 0.92(0.01) | 0.90 | 0.90 |
| MFP0 | counts | 40 | 0.94(0.00) | 0.94 | 0.94 |
| MFP0 | counts | 50 | 0.96(0.00) | 0.95 | 0.95 |
| MFP1 | counts | 10 | 0.61(0.09) | 0.50 | 0.45 |
| MFP1 | counts | 20 | 0.78(0.04) | 0.73 | 0.70 |
| MFP1 | counts | 30 | 0.84(0.03) | 0.80 | 0.78 |
| MFP1 | counts | 40 | 0.88(0.02) | 0.86 | 0.85 |
| MFP1 | counts | 50 | 0.91(0.02) | 0.89 | 0.88 |
| MFP2 | counts | 10 | 0.49(0.10) | 0.36 | 0.33 |
| MFP2 | counts | 20 | 0.68(0.08) | 0.58 | 0.55 |
| MFP2 | counts | 30 | 0.75(0.06) | 0.68 | 0.66 |
| MFP2 | counts | 40 | 0.82(0.04) | 0.76 | 0.75 |
| MFP2 | counts | 50 | 0.85(0.04) | 0.81 | 0.80 |
| MFP3 | counts | 10 | 0.44(0.10) | 0.32 | 0.29 |
| MFP3 | counts | 20 | 0.60(0.10) | 0.47 | 0.44 |
| MFP3 | counts | 30 | 0.68(0.08) | 0.58 | 0.55 |
| MFP3 | counts | 40 | 0.75(0.07) | 0.67 | 0.65 |
| MFP3 | counts | 50 | 0.80(0.06) | 0.73 | 0.71 |
| MFP0 | bits | 10 | 0.77(0.10) | 0.67 | 0.60 |
| MFP0 | bits | 20 | 0.87(0.05) | 0.80 | 0.78 |
| MFP0 | bits | 30 | 0.89(0.04) | 0.82 | 0.80 |
| MFP0 | bits | 40 | 0.91(0.03) | 0.86 | 0.83 |
| MFP0 | bits | 50 | 0.91(0.04) | 0.86 | 0.83 |
| MFP1 | bits | 10 | 0.59(0.11) | 0.47 | 0.41 |
| MFP1 | bits | 20 | 0.75(0.07) | 0.67 | 0.63 |
| MFP1 | bits | 30 | 0.80(0.06) | 0.73 | 0.71 |
| MFP1 | bits | 40 | 0.84(0.05) | 0.78 | 0.76 |
| MFP1 | bits | 50 | 0.86(0.05) | 0.80 | 0.78 |
| MFP2 | bits | 10 | 0.46(0.11) | 0.32 | 0.29 |
| MFP2 | bits | 20 | 0.64(0.09) | 0.52 | 0.48 |
| MFP2 | bits | 30 | 0.71(0.08) | 0.60 | 0.57 |
| MFP2 | bits | 40 | 0.77(0.07) | 0.68 | 0.66 |
| MFP2 | bits | 50 | 0.80(0.06) | 0.72 | 0.69 |
| MFP3 | bits | 10 | 0.41(0.11) | 0.29 | 0.26 |
| MFP3 | bits | 20 | 0.55(0.11) | 0.41 | 0.37 |
| MFP3 | bits | 30 | 0.63(0.10) | 0.50 | 0.46 |
| MFP3 | bits | 40 | 0.70(0.09) | 0.59 | 0.56 |
| MFP3 | bits | 50 | 0.74(0.08) | 0.64 | 0.60 |
| FFP0 | counts | 10 | 0.91(0.13) | 0.75 | 0.71 |
| FFP0 | counts | 20 | 0.96(0.06) | 0.88 | 0.86 |
| FFP0 | counts | 30 | 0.98(0.04) | 0.91 | 0.90 |
| FFP0 | counts | 40 | 0.98(0.03) | 0.94 | 0.94 |
| FFP0 | counts | 50 | 0.99(0.02) | 0.95 | 0.95 |
| FFP1 | counts | 10 | 0.85(0.20) | 0.57 | 0.50 |
| FFP1 | counts | 20 | 0.93(0.11) | 0.77 | 0.73 |
| FFP1 | counts | 30 | 0.96(0.07) | 0.84 | 0.82 |
| FFP1 | counts | 40 | 0.97(0.05) | 0.88 | 0.86 |
| FFP1 | counts | 50 | 0.98(0.04) | 0.91 | 0.89 |
| FFP2 | counts | 10 | 0.81(0.25) | 0.43 | 0.38 |
| FFP2 | counts | 20 | 0.90(0.15) | 0.65 | 0.61 |
| FFP2 | counts | 30 | 0.94(0.11) | 0.75 | 0.71 |
| FFP2 | counts | 40 | 0.96(0.08) | 0.81 | 0.79 |
| FFP2 | counts | 50 | 0.97(0.06) | 0.85 | 0.83 |
| FFP3 | counts | 10 | 0.79(0.27) | 0.37 | 0.33 |
| FFP3 | counts | 20 | 0.88(0.19) | 0.56 | 0.51 |
| FFP3 | counts | 30 | 0.92(0.14) | 0.67 | 0.62 |
| FFP3 | counts | 40 | 0.94(0.11) | 0.74 | 0.71 |
| FFP3 | counts | 50 | 0.95(0.09) | 0.79 | 0.76 |
| FFP0 | bits | 10 | 0.92(0.16) | 0.67 | 0.50 |
| FFP0 | bits | 20 | 0.96(0.11) | 0.80 | 0.71 |
| FFP0 | bits | 30 | 0.97(0.08) | 0.86 | 0.80 |
| FFP0 | bits | 40 | 0.98(0.06) | 1.00 | 0.83 |
| FFP0 | bits | 50 | 0.99(0.05) | 1.00 | 0.86 |
| FFP1 | bits | 10 | 0.84(0.22) | 0.50 | 0.43 |
| FFP1 | bits | 20 | 0.92(0.14) | 0.69 | 0.62 |
| FFP1 | bits | 30 | 0.95(0.11) | 0.77 | 0.71 |
| FFP1 | bits | 40 | 0.96(0.08) | 0.83 | 0.78 |
| FFP1 | bits | 50 | 0.97(0.06) | 0.88 | 0.82 |
| FFP2 | bits | 10 | 0.78(0.28) | 0.35 | 0.29 |
| FFP2 | bits | 20 | 0.88(0.19) | 0.56 | 0.50 |
| FFP2 | bits | 30 | 0.92(0.14) | 0.66 | 0.60 |
| FFP2 | bits | 40 | 0.94(0.11) | 0.74 | 0.69 |
| FFP2 | bits | 50 | 0.95(0.09) | 0.79 | 0.74 |
| FFP3 | bits | 10 | 0.76(0.30) | 0.30 | 0.25 |
| FFP3 | bits | 20 | 0.85(0.23) | 0.45 | 0.39 |
| FFP3 | bits | 30 | 0.90(0.18) | 0.57 | 0.51 |
| FFP3 | bits | 40 | 0.92(0.14) | 0.66 | 0.60 |
| FFP3 | bits | 50 | 0.94(0.12) | 0.72 | 0.66 |
| RDK5 | counts | 10 | 0.36(0.19) | 0.13 | 0.09 |
| RDK5 | counts | 20 | 0.59(0.18) | 0.35 | 0.29 |
| RDK5 | counts | 30 | 0.69(0.14) | 0.49 | 0.43 |
| RDK5 | counts | 40 | 0.77(0.12) | 0.60 | 0.55 |
| RDK5 | counts | 50 | 0.81(0.10) | 0.66 | 0.62 |
| RDK7 | counts | 10 | 0.30(0.16) | 0.11 | 0.08 |
| RDK7 | counts | 20 | 0.53(0.20) | 0.27 | 0.22 |
| RDK7 | counts | 30 | 0.64(0.17) | 0.40 | 0.35 |
| RDK7 | counts | 40 | 0.73(0.14) | 0.53 | 0.47 |
| RDK7 | counts | 50 | 0.79(0.13) | 0.60 | 0.55 |
| RDK5 | bits | 10 | 0.36(0.18) | 0.14 | 0.11 |
| RDK5 | bits | 20 | 0.59(0.17) | 0.36 | 0.30 |
| RDK5 | bits | 30 | 0.68(0.15) | 0.47 | 0.42 |
| RDK5 | bits | 40 | 0.76(0.13) | 0.58 | 0.52 |
| RDK5 | bits | 50 | 0.79(0.12) | 0.62 | 0.57 |
| RDK7 | bits | 10 | 0.30(0.16) | 0.12 | 0.09 |
| RDK7 | bits | 20 | 0.55(0.19) | 0.31 | 0.26 |
| RDK7 | bits | 30 | 0.68(0.16) | 0.46 | 0.41 |
| RDK7 | bits | 40 | 0.79(0.13) | 0.61 | 0.55 |
| RDK7 | bits | 50 | 0.84(0.11) | 0.68 | 0.63 |
| TT | counts | 10 | 0.38(0.24) | 0.00 | 0.00 |
| TT | counts | 20 | 0.63(0.17) | 0.41 | 0.35 |
| TT | counts | 30 | 0.72(0.13) | 0.55 | 0.50 |
| TT | counts | 40 | 0.79(0.10) | 0.66 | 0.62 |
| TT | counts | 50 | 0.84(0.08) | 0.72 | 0.69 |
| TT | bits | 10 | 0.41(0.25) | 0.08 | 0.00 |
| TT | bits | 20 | 0.64(0.17) | 0.41 | 0.35 |
| TT | bits | 30 | 0.73(0.13) | 0.55 | 0.50 |
| TT | bits | 40 | 0.79(0.10) | 0.66 | 0.62 |
| TT | bits | 50 | 0.83(0.09) | 0.71 | 0.68 |
| AP | counts | 10 | 0.61(0.09) | 0.56 | 0.50 |
| AP | counts | 20 | 0.79(0.03) | 0.75 | 0.73 |
| AP | counts | 30 | 0.85(0.02) | 0.82 | 0.82 |
| AP | counts | 40 | 0.89(0.01) | 0.88 | 0.88 |
| AP | counts | 50 | 0.91(0.01) | 0.90 | 0.90 |
| AP | bits | 10 | 0.62(0.09) | 0.56 | 0.50 |
| AP | bits | 20 | 0.79(0.04) | 0.75 | 0.72 |
| AP | bits | 30 | 0.85(0.03) | 0.82 | 0.81 |
| AP | bits | 40 | 0.89(0.02) | 0.87 | 0.86 |
| AP | bits | 50 | 0.91(0.02) | 0.89 | 0.88 |