All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gov.nih.ncats.molwitch.cdk.fingerprinters.FingerprinterAdapter Maven / Gradle / Ivy

/*
 * NCATS-MOLWITCH-CDK
 *
 * Copyright (c) 2023.
 *
 * This work is free software; you can redistribute it and/or modify it under the terms of the
 * GNU Lesser General Public License as published by the Free Software Foundation;
 * either version 2.1 of the License, or (at your option) any later version.
 *
 * This work is distributed in the hope that it will be useful, but without any warranty;
 * without even the implied warranty of merchantability or fitness for a particular purpose.
 * See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this library;
 *  if not, write to:
 *
 *  the Free Software Foundation, Inc.
 *  59 Temple Place, Suite 330
 *  Boston, MA 02111-1307 USA
 */

package gov.nih.ncats.molwitch.cdk.fingerprinters;

import java.io.IOException;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.openscience.cdk.aromaticity.Aromaticity;
import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.fingerprint.IBitFingerprint;
import org.openscience.cdk.fingerprint.IFingerprinter;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IBond.Order;
import org.openscience.cdk.isomorphism.matchers.QueryAtomContainer;
import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;

import gov.nih.ncats.common.sneak.Sneak;
import gov.nih.ncats.common.util.CachedSupplier;
import gov.nih.ncats.molwitch.Chemical;
import gov.nih.ncats.molwitch.ChemicalSource;
import gov.nih.ncats.molwitch.cdk.CdkChemicalImpl;
import gov.nih.ncats.molwitch.cdk.CdkUtil;
import gov.nih.ncats.molwitch.fingerprint.Fingerprint;
import gov.nih.ncats.molwitch.fingerprint.Fingerprinter;
import gov.nih.ncats.molwitch.spi.FingerprinterImpl;

/**
 * Adapter to wrap a {@link FingerprinterImpl} from the SPI
 * and adapt it to use the {@link Fingerprinter} interface
 * from the API.
 * 
 * @author katzelda
 *
 */
class FingerprinterAdapter implements Fingerprinter {
	private final IFingerprinter delegate;
	private boolean removeQueryAtomsAndBonds=false;
	private boolean forceExplicitH =false;

	public FingerprinterAdapter(IFingerprinter impl) {
		this.delegate = impl;
	}

	public boolean isRemoveQueryAtomsAndBonds() {
		return removeQueryAtomsAndBonds;
	}

	public void setRemoveQueryAtomsAndBonds(boolean removeQueryAtomsAndBonds) {
		this.removeQueryAtomsAndBonds = removeQueryAtomsAndBonds;
	}

	public boolean isForceExplicitH() {
		return forceExplicitH;
	}

	public void setForceExplicitH(boolean forceExplicitH) {
		this.forceExplicitH = forceExplicitH;
	}
	
	private void printContainer(IAtomContainer cln) {
	    
        CdkChemicalImpl cci = new CdkChemicalImpl(cln, (ChemicalSource)null);
        Chemical cq = new Chemical(cci);
        Chemical qq=cq.copy();
        try {
            System.out.println(qq.toMol());
        }catch(Exception e) {
            
        }
	}

	@Override
	public Fingerprint computeFingerprint(Chemical chemical) {
	   
		//cdk doesn't seem to support fingerprints with query atoms/bonds
		//so lets remove them
		IAtomContainer orig = (IAtomContainer)chemical.getImpl().getWrappedObject();

		CachedSupplier cloneCache = CachedSupplier.of(()->{
			try {
			    Chemical cc=chemical.copy();
			    IAtomContainer cln = (IAtomContainer)cc.getImpl().getWrappedObject();
			    try {
		            CdkUtil.removeQueryAtoms(cln);
		            CdkUtil.removeQueryBonds(cln);
		            cln=CdkUtil.getSimplifiedContainer(cln);
			        // The logic here is a little suspect, and may not be necessary,
			        // but the basic idea is to flag all bonds that will
			        // be modified by the aromatic detection and mark them for removal
			        // as they will interfere with fingerprints
			        Map oldOrder = new HashMap<>();
			        Iterator bondIter2 = cln.bonds().iterator();
                    while(bondIter2.hasNext()){
                        IBond next = bondIter2.next();
                        oldOrder.put(next, next.getOrder() + "" + next.isAromatic());
                    }
                    AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(cln);
		            Aromaticity.cdkLegacy().apply(cln);
		            CdkUtil.removeQueryBonds(cln);
		           
		            Iterator bondIter = cln.bonds().iterator();
		            while(bondIter.hasNext()){
		                IBond next = bondIter.next();
		                if(next.getOrder() ==null || next.getOrder() == Order.UNSET ||
		                        !(next.getOrder() + "" + next.isAromatic()).equals(oldOrder.get(next))){
		                    next.setOrder(Order.UNSET);
		                }
		            }
		        }catch(Exception e) {
		            //swallow issue
//		            e.printStackTrace();		            
		        }
				return cln;
			}catch(Exception t){
				return Sneak.sneakyThrow(t);
			}
		});
		IAtomContainer containerToFingerprint = orig;

		if(removeQueryAtomsAndBonds){
			containerToFingerprint = cloneCache.get();
			CdkUtil.removeQueryAtoms(containerToFingerprint);
			CdkUtil.removeQueryBonds(containerToFingerprint);
		}
		//This whole idea here is a bit suspicious
		if(forceExplicitH){
			containerToFingerprint = cloneCache.get();
			AtomContainerManipulator.convertImplicitToExplicitHydrogens(containerToFingerprint);
		}
		
		IAtomContainer iac= CdkUtil.getUsableFormOfAtomContainer(containerToFingerprint);
		
		// TODO:
		// IF IAtomContainer is a query container, it simply doesn't produce
		// ANY fingerprint, and something needs to be done.

		if(iac instanceof QueryAtomContainer) {
		    iac = CdkUtil.getSimplifiedContainer(iac);
		}
		
		try {
		    IBitFingerprint bitFingerprint = delegate.getBitFingerprint(iac);
		    BitSet bs = bitFingerprint.asBitSet();
		    return new Fingerprint(bs, (int) bitFingerprint.size());
		} catch (CDKException e) {
		    throw new RuntimeException(e);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy