rdkit/
fingerprint.rs

1use bitvec::prelude::*;
2use cxx::SharedPtr;
3
4#[derive(Clone, Debug)]
5pub struct Fingerprint(pub BitVec<u8, bitvec::order::Lsb0>);
6
7impl Fingerprint {
8    pub fn new(ptr: SharedPtr<rdkit_sys::fingerprint_ffi::ExplicitBitVect>) -> Self {
9        let unique_ptr_bytes = rdkit_sys::fingerprint_ffi::explicit_bit_vect_to_u64_vec(&ptr);
10        let rdkit_fingerprint_bytes: Vec<u64> = unique_ptr_bytes.into_iter().copied().collect();
11        let mut bitvec_u64 = bitvec::vec::BitVec::<u64, Lsb0>::from_vec(rdkit_fingerprint_bytes);
12
13        let mut idiomatic_bitvec_u8 = bitvec::vec::BitVec::<u8, Lsb0>::new();
14        idiomatic_bitvec_u8.append(&mut bitvec_u64);
15
16        Fingerprint(idiomatic_bitvec_u8)
17    }
18
19    pub fn tanimoto_distance(&self, other: &Fingerprint) -> f32 {
20        let and = self.0.clone() & &other.0;
21        let or = self.0.clone() | &other.0;
22
23        let and_ones = and.count_ones();
24        let or_ones = or.count_ones();
25
26        and_ones as f32 / or_ones as f32
27    }
28}