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}