new_mol=sanitize(new_mol)#We assume this is not None
returnnew_mol
deftree_decomp(mol):
n_atoms=mol.GetNumAtoms()
ifn_atoms==1:
return[[0]],[]
cliques=[]
forbondinmol.GetBonds():
a1=bond.GetBeginAtom().GetIdx()
a2=bond.GetEndAtom().GetIdx()
ifnotbond.IsInRing():
cliques.append([a1,a2])
ssr=[list(x)forxinChem.GetSymmSSSR(mol)]
cliques.extend(ssr)
nei_list=[[]foriinrange(n_atoms)]
foriinrange(len(cliques)):
foratomincliques[i]:
nei_list[atom].append(i)
#Merge Rings with intersection > 2 atoms
foriinrange(len(cliques)):
iflen(cliques[i])<=2:continue
foratomincliques[i]:
forjinnei_list[atom]:
ifi>=jorlen(cliques[j])<=2:continue
inter=set(cliques[i])&set(cliques[j])
iflen(inter)>2:
cliques[i].extend(cliques[j])
cliques[i]=list(set(cliques[i]))
cliques[j]=[]
cliques=[cforcincliquesiflen(c)>0]
nei_list=[[]foriinrange(n_atoms)]
foriinrange(len(cliques)):
foratomincliques[i]:
nei_list[atom].append(i)
#Build edges and add singleton cliques
edges=defaultdict(int)
foratominrange(n_atoms):
iflen(nei_list[atom])<=1:
continue
cnei=nei_list[atom]
bonds=[cforcincneiiflen(cliques[c])==2]
rings=[cforcincneiiflen(cliques[c])>4]
iflen(bonds)>2or(len(bonds)==2andlen(cnei)>2):#In general, if len(cnei) >= 3, a singleton should be added, but 1 bond + 2 ring is currently not dealt with.
cliques.append([atom])
c2=len(cliques)-1
forc1incnei:
edges[(c1,c2)]=1
eliflen(rings)>2:#Multiple (n>2) complex rings
cliques.append([atom])
c2=len(cliques)-1
forc1incnei:
edges[(c1,c2)]=MST_MAX_WEIGHT-1
else:
foriinrange(len(cnei)):
forjinrange(i+1,len(cnei)):
c1,c2=cnei[i],cnei[j]
inter=set(cliques[c1])&set(cliques[c2])
ifedges[(c1,c2)]<len(inter):
edges[(c1,c2)]=len(inter)#cnei[i] < cnei[j] by construction