de.tudarmstadt.ukp.csniper.treevisualizer.TreeVisualizer.java Source code

Java tutorial

Introduction

Here is the source code for de.tudarmstadt.ukp.csniper.treevisualizer.TreeVisualizer.java

Source

/*******************************************************************************
 * Copyright 2013
 * Ubiquitous Knowledge Processing (UKP) Lab
 * Technische Universitt Darmstadt
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package de.tudarmstadt.ukp.csniper.treevisualizer;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.uima.UimaContext;
import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
import org.apache.uima.fit.component.JCasAnnotator_ImplBase;
import org.apache.uima.fit.descriptor.ConfigurationParameter;
import org.apache.uima.fit.util.JCasUtil;
import org.apache.uima.jcas.JCas;
import org.apache.uima.jcas.cas.FSArray;
import org.apache.uima.jcas.tcas.Annotation;
import org.apache.uima.resource.ResourceInitializationException;

import annis.frontend.servlets.visualizers.Visualizer;
import annis.frontend.servlets.visualizers.tree.TigerTreeVisualizer;
import annis.model.AnnisNode;
import annis.model.AnnotationGraph;
import annis.model.Edge;
import annis.model.Edge.EdgeType;
import de.tudarmstadt.ukp.dkpro.core.api.metadata.type.DocumentMetaData;
import de.tudarmstadt.ukp.dkpro.core.api.parameter.ComponentParameters;
import de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token;
import de.tudarmstadt.ukp.dkpro.core.api.syntax.type.constituent.Constituent;
import de.tudarmstadt.ukp.dkpro.core.api.syntax.type.constituent.ROOT;

/**
 * Draws constituent trees to png files.<br>
 * Requires a parser to be run before.
 * 
 * @author Erik-Ln Do Dinh
 */
public class TreeVisualizer extends JCasAnnotator_ImplBase {
    public static final String PARAM_OUTPUT_PATH = ComponentParameters.PARAM_TARGET_LOCATION;
    @ConfigurationParameter(name = PARAM_OUTPUT_PATH, mandatory = true)
    private File targetLocation;

    public static final String PARAM_NAMESPACE = "namespace";
    @ConfigurationParameter(name = PARAM_NAMESPACE, mandatory = true)
    private String namespace;

    private Log log = LogFactory.getLog(getClass());

    private Map<Annotation, AnnisNode> nodes;
    private List<Edge> edges;
    private JCas jcas;

    @Override
    public void initialize(UimaContext aContext) throws ResourceInitializationException {
        super.initialize(aContext);

        try {
            FileUtils.forceMkdir(targetLocation);
        } catch (IOException e) {
            throw new ResourceInitializationException(e);
        }
    }

    @Override
    public void process(JCas aJCas) throws AnalysisEngineProcessException {
        jcas = aJCas;
        OutputStream os = null;
        int i = 0;

        for (ROOT root : JCasUtil.select(jcas, ROOT.class)) {
            try {
                DocumentMetaData meta = DocumentMetaData.get(aJCas);
                File image = new File(targetLocation, meta.getDocumentId() + "_" + i + ".png");

                if (log.isInfoEnabled()) {
                    log.info("Started creating image [" + image.getAbsolutePath() + "].");
                }

                os = new FileOutputStream(image);
                Visualizer ttv = new TigerTreeVisualizer();
                ttv.setResult(new AnnisResultIncompleteImpl(createGraph(root)));
                ttv.setMappings(new Properties());
                ttv.setNamespace(namespace);
                ttv.writeOutput(os);

                if (log.isInfoEnabled()) {
                    log.info("Finished writing image [" + image.getAbsolutePath() + "].");
                }
            } catch (FileNotFoundException e) {
                throw new AnalysisEngineProcessException(e);
            } finally {
                i++;
                IOUtils.closeQuietly(os);
            }
        }
    }

    private AnnotationGraph createGraph(ROOT aRoot) {
        nodes = new HashMap<Annotation, AnnisNode>();
        edges = new ArrayList<Edge>();

        AnnotationGraph graph = new AnnotationGraph();
        AnnisNode rootV = getAnnisNode(aRoot);
        nodes.put(aRoot, rootV);
        traverse(aRoot);
        for (AnnisNode node : nodes.values()) {
            graph.addNode(node);
        }
        return graph;
    }

    private void traverse(Constituent parent) {
        FSArray children = parent.getChildren();

        AnnisNode parentNode = getAnnisNode(parent);
        annis.model.Annotation nodeAnno = new annis.model.Annotation(namespace, "cat", parent.getConstituentType());
        parentNode.addNodeAnnotation(nodeAnno);
        nodes.put(parent, parentNode);

        for (int i = 0; i < children.size(); i++) {
            Annotation child = parent.getChildren(i);

            // create/save node
            AnnisNode childNode = getAnnisNode(child);
            nodes.put(child, childNode);

            // create/save edge
            Edge edge = new Edge();
            edge.setName("edge");
            edge.setSource(parentNode);
            edge.setDestination(childNode);
            edge.setEdgeType(EdgeType.DOMINANCE);
            if ((child instanceof Constituent)) {
                // TODO show syntactic functions only if available
                String synFunc = ((Constituent) child).getSyntacticFunction();
                synFunc = synFunc == null ? "#" : synFunc;
                annis.model.Annotation edgeAnno = new annis.model.Annotation(namespace, "func", synFunc);
                edge.addAnnotation(edgeAnno);
            }
            edges.add(edge);

            // add edges to nodes
            parentNode.addOutgoingEdge(edge);
            childNode.addIncomingEdge(edge);

            // traverse deeper
            if (child instanceof Constituent) {
                traverse((Constituent) child);
            }
        }
    }

    private AnnisNode getAnnisNode(Annotation a) {
        AnnisNode node = nodes.get(a);
        if (node == null) {
            long id = a.hashCode();
            node = new AnnisNode(id);
            node.setRoot(a.getClass() == ROOT.class);
            node.setNamespace(namespace);
            node.setSpannedText(a.getCoveredText());
            if (a instanceof Constituent) {
                node.setToken(false);
            } else {
                node.setToken(true);
                Annotation dummy = new Annotation(jcas, 0, a.getBegin());
                Long idx = (long) JCasUtil.selectCovered(jcas, Token.class, dummy).size();
                node.setTokenIndex(idx);
            }
        }
        return node;
    }
}