Package org.openbel.framework.test

Source Code of org.openbel.framework.test.KAMFilterHelper

package org.openbel.framework.test;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.openbel.framework.api.AnnotationFilterCriteria;
import org.openbel.framework.api.BelDocumentFilterCriteria;
import org.openbel.framework.api.CitationFilterCriteria;
import org.openbel.framework.api.FilterCriteria;
import org.openbel.framework.api.RelationshipTypeFilterCriteria;
import org.openbel.framework.api.internal.KAMStoreDao;
import org.openbel.framework.api.internal.KAMCatalogDao.KamFilter;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.Annotation;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.BelDocumentInfo;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.BelStatement;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.Citation;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.KamProtoEdge;
import org.openbel.framework.api.internal.KAMStoreDaoImpl.KamProtoNode;


/**
* KAM Filtering Helper
*
*/
public class KAMFilterHelper {

    private KAMStoreDao kamStoreDao; // for supporting evidence lookup

    public KAMFilterHelper(KAMStoreDao kamStoreDao) {
        this.kamStoreDao = kamStoreDao;
    }

    /**
     * @param kamProtoEdgeMap
     * @param kamFilter
     */
    public void filter(Map<Integer, KamProtoNode> kamProtoNodeMap, Map<Integer, KamProtoEdge> kamProtoEdgeMap, KamFilter kamFilter) throws SQLException {
        List<FilterCriteria> criteria = kamFilter.getFilterCriteria();

        for (FilterCriteria criterion : criteria) {
            //process each criteria, number of edges to filter may go down in each loop
            Set<Integer> matched = null;
            if (criterion instanceof RelationshipTypeFilterCriteria) {
                matched = processRelationshipTypeFilterCriteria(kamProtoEdgeMap, (RelationshipTypeFilterCriteria) criterion);
            } else if (criterion instanceof BelDocumentFilterCriteria) {
                matched = processBelDocumentFilterCriteria(kamProtoEdgeMap, (BelDocumentFilterCriteria) criterion);
            } else if (criterion instanceof AnnotationFilterCriteria) {
                matched = processAnnotationFilterCriteria(kamProtoEdgeMap, (AnnotationFilterCriteria) criterion);
            } else if (criterion instanceof CitationFilterCriteria) {
                matched = processCitationFilterCriteria(kamProtoEdgeMap, (CitationFilterCriteria) criterion);
            }
            if( matched != null ) {
                if (criterion.isInclude()) {
                    kamProtoEdgeMap.keySet().retainAll(matched);
                } else {
                    // must be exclude
                    kamProtoEdgeMap.keySet().removeAll(matched);
                }
            }
        }

        //post processing to remove orphaned nodes
        removeOrphanNodes(kamProtoNodeMap, kamProtoEdgeMap);
    }

    /**
     * remove all nodes from the proto node map that is not in at least one edge in the proto edge map
     * @param kamProtoNodeMap
     * @param kamProtoEdgeMap
     */
    protected void removeOrphanNodes(Map<Integer, KamProtoNode> kamProtoNodeMap, Map<Integer, KamProtoEdge> kamProtoEdgeMap) {
        Set<Integer> nodesInUse = new HashSet<Integer>();
        for (Entry<Integer, KamProtoEdge> entry : kamProtoEdgeMap.entrySet()) {
            KamProtoEdge edge = entry.getValue();
            nodesInUse.add(edge.getSourceNode().getId());
            nodesInUse.add(edge.getTargetNode().getId());
        }
        kamProtoNodeMap.keySet().retainAll(nodesInUse);
    }

    protected Set<Integer> processCitationFilterCriteria(Map<Integer, KamProtoEdge> kamProtoEdgeMap, CitationFilterCriteria c) throws SQLException {
        Set<Integer> matched = new HashSet<Integer>();
        Set<Citation> citations = c.getValues();
        Set<String> referenceIds = new HashSet<String>();
        for (Citation citation : citations) {
            referenceIds.add(citation.getId());
        }
        // statement level filter: edge is removed if no statement supports it
        for (Entry<Integer, KamProtoEdge> entry : kamProtoEdgeMap.entrySet()) {
            List<BelStatement> statements = kamStoreDao.getSupportingEvidence(entry.getValue().getId());
            boolean hasSupport = false;
            if( c.isInclude() ) {
                for (BelStatement statement : statements) {
                    if (referenceIds.contains(statement.getCitation().getId())) {
                        hasSupport = true;
                        break;
                    }
                }
                if( hasSupport ) {
                    matched.add(entry.getKey());
                }
            } else {
                for (BelStatement statement : statements) {
                    //try to find at least one statement not in the exclude set
                    if ( ! referenceIds.contains(statement.getCitation().getId())) {
                        hasSupport = true;
                        break;
                    }
                }
                if( !hasSupport ) {
                    matched.add(entry.getKey());
                }
            }

        }
        return matched;
    }



    /**
     * If filter type is include, return list of edges to be included.
     * If filter type is exclude, return list of edges to be excluded.
     *
     * @param kamProtoEdgeMap
     * @param c
     * @return
     * @throws SQLException
     */
    protected Set<Integer> processAnnotationFilterCriteria(Map<Integer, KamProtoEdge> kamProtoEdgeMap, AnnotationFilterCriteria c) throws SQLException {
        Set<Integer> matched = new HashSet<Integer>();
        // annotation level filter: supported statement is remove if no other annotation of the same type exists

        for (Entry<Integer, KamProtoEdge> entry : kamProtoEdgeMap.entrySet()) {
            List<BelStatement> statements = kamStoreDao.getSupportingEvidence(entry.getValue().getId());
            boolean hasStatementSupport = false;
            for (BelStatement statement : statements) {
                if( isStatementSupported(statement.getAnnotationList(), c) ) {
                    hasStatementSupport = true;
                    break;
                }
            }
            if( c.isInclude() ) {
                if( hasStatementSupport ) {
                    matched.add(entry.getKey());
                }
            } else {
                if( !hasStatementSupport ) {
                    //added the edge to list of edges to be removed
                    matched.add(entry.getKey());
                }
            }
        }



        return matched;
    }

    /**
     *     Statement is considered supported according to the following:
     *      if filter type is include: if it has at least one annotation matching the specified values
     *      if filter type is exclude: if it has at least one annotation not match the specified values, or
     *                            if it has no annotations of the specified annotation type
     * @param statementAnnotations
     * @param c
     * @return
     */
    private boolean isStatementSupported(List<Annotation> statementAnnotations, AnnotationFilterCriteria c) {


        boolean isStatementSupported = false;
        List<Annotation> matchAnnotationsSubset = new ArrayList<Annotation>();
        for(Annotation annotation : statementAnnotations) {
            //identify annotations relevant to our filtering criterion
            if (c.getAnnotationType().getId().equals(annotation.getAnnotationType().getId())) {
                matchAnnotationsSubset.add(annotation);
            }
        }

        if( matchAnnotationsSubset.size() > 0 ) {
            if( c.isInclude() ) {
                for(Annotation annotation : matchAnnotationsSubset) {
                    if (c.getValues().contains(annotation.getValue())) {
                        //at least one annotation matched the specified values, statement is supported
                        isStatementSupported = true;
                        break;
                    }
                }
            } else {
                for(Annotation annotation : matchAnnotationsSubset) {
                    if (!c.getValues().contains(annotation.getValue())) {
                        //at least one annotation doesn't match the specified values to exclude, statement is supported
                        isStatementSupported = true;
                        break;
                    }
                }
            }
        } else {
            if( c.isInclude() ) {
                isStatementSupported = false; //include filter, no match annotation type on statement
            } else {
                isStatementSupported = true;
            }
        }
        return isStatementSupported;
    }

    /**
     * @param kamProtoEdgeMap
     * @param c
     * @return
     * @throws SQLException
     */
    protected Set<Integer> processBelDocumentFilterCriteria(Map<Integer, KamProtoEdge> kamProtoEdgeMap, BelDocumentFilterCriteria c) throws SQLException {
        Set<Integer> matched = new HashSet<Integer>();
        Set<BelDocumentInfo> docInfos = c.getValues();
        Set<Integer> docInfoIds = new HashSet<Integer>();
        for (BelDocumentInfo info : docInfos) {
            docInfoIds.add(info.getId());
        }
        // statement level filter: edge is removed if no statement supports it
        for (Entry<Integer, KamProtoEdge> entry : kamProtoEdgeMap.entrySet()) {
            List<BelStatement> statements = kamStoreDao.getSupportingEvidence(entry.getValue().getId());
            boolean hasSupport = false;
            if( c.isInclude() ) {
                for (BelStatement statement : statements) {
                    if (docInfoIds.contains(statement.getBelDocumentInfo().getId())) {
                        hasSupport = true;
                        break;
                    }
                }
                if( hasSupport ) {
                    matched.add(entry.getKey());
                }
            } else {
                for (BelStatement statement : statements) {
                    //try to find at least one statement not in the exclude set
                    if ( ! docInfoIds.contains(statement.getBelDocumentInfo().getId())) {
                        hasSupport = true;
                        break;
                    }
                }
                if( !hasSupport ) {
                    matched.add(entry.getKey());
                }
            }

        }
        return matched;
    }

    /**
     * @param kamProtoEdgeMap
     * @param c
     * @return
     */
    protected Set<Integer> processRelationshipTypeFilterCriteria(Map<Integer, KamProtoEdge> kamProtoEdgeMap, RelationshipTypeFilterCriteria c) {
        Set<Integer> matched = new HashSet<Integer>();
        // edge level filtering: filter based on type match
        for (Entry<Integer, KamProtoEdge> entry : kamProtoEdgeMap.entrySet()) {
            if (c.getValues().contains(entry.getValue().getRelationship())) {
                matched.add(entry.getKey());
            }
        }
        return matched;
    }
}
TOP

Related Classes of org.openbel.framework.test.KAMFilterHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.