de.tudarmstadt.ukp.csniper.webapp.statistics.SortableAggregatedEvaluationResultDataProvider.java Source code

Java tutorial

Introduction

Here is the source code for de.tudarmstadt.ukp.csniper.webapp.statistics.SortableAggregatedEvaluationResultDataProvider.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.webapp.statistics;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.mutable.MutableInt;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;

import de.tudarmstadt.ukp.csniper.webapp.statistics.model.AggregatedEvaluationResult;
import de.tudarmstadt.ukp.csniper.webapp.statistics.page.StatisticsPage.TypeStatistics;
import de.tudarmstadt.ukp.csniper.webapp.statistics.page.StatisticsPage2.ItemStatistics;
import de.tudarmstadt.ukp.dkpro.statistics.agreement.AnnotationStudy;
import de.tudarmstadt.ukp.dkpro.statistics.agreement.IAnnotationStudy;
import de.tudarmstadt.ukp.dkpro.statistics.agreement.MultiRaterPiAgreement;

/**
 * Original code from org.apache.wicket.examples.repeater.SortableContactDataProvider, modified and
 * extended.
 * 
 * @author Erik-Ln Do Dinh
 * 
 */
public class SortableAggregatedEvaluationResultDataProvider
        extends SortableDataProvider<AggregatedEvaluationResult, String> {
    public enum ResultFilter {
        CORRECT("Correct", Color.GREEN), WRONG("Wrong", Color.RED), DISPUTED("Disputed",
                Color.ORANGE), INCOMPLETE("Incomplete", Color.LIGHT_GRAY), UNKNOWN("Unknown", Color.DARK_GRAY);

        private String label;
        private Color color;

        private ResultFilter(String aLabel, Color aColor) {
            label = aLabel;
            color = aColor;
        }

        public String getLabel() {
            return label;
        }

        public Color getColor() {
            return color;
        }
    }

    private static final long serialVersionUID = -4680400414358831292L;

    private List<AggregatedEvaluationResult> aerList;
    private List<AggregatedEvaluationResult> limitedResults;
    private Set<String> users;

    private List<ResultFilter> filters;
    private boolean filterChanged;

    private String lastSortProperty;
    private boolean lastSortOrder;

    private SortableAggregatedEvaluationResultDataProvider() {
        // set default sort
        setSort("id", SortOrder.ASCENDING);
    }

    public SortableAggregatedEvaluationResultDataProvider(List<AggregatedEvaluationResult> aAerList,
            Collection<String> aUsers) {
        this();
        aerList = aAerList;
        users = new HashSet<String>(aUsers);
        filters = new ArrayList<ResultFilter>();
    }

    /**
     * @see org.apache.wicket.markup.repeater.data.IDataProvider#iterator(int, int)
     */
    @Override
    public Iterator<AggregatedEvaluationResult> iterator(long aFirst, long aCount) {
        // Apply paging
        updateView();
        return limitedResults.subList((int) aFirst, (int) Math.min(aFirst + aCount, limitedResults.size()))
                .iterator();
    }

    /**
     * @see org.apache.wicket.markup.repeater.data.IDataProvider#size()
     */
    @Override
    public long size() {
        updateView();
        return limitedResults.size();
    }

    private void updateView() {
        final SortParam<String> sp = getSort();

        // filter
        if (!sp.getProperty().equals(lastSortProperty) || (lastSortOrder != sp.isAscending()) || filterChanged) {
            limitedResults = new ArrayList<AggregatedEvaluationResult>();
            for (AggregatedEvaluationResult aer : aerList) {
                if (getFilters().contains(aer.getClassification())) {
                    limitedResults.add(aer);
                }
            }
        }

        // sort
        Collections.sort(limitedResults, new Comparator<AggregatedEvaluationResult>() {
            @SuppressWarnings({ "rawtypes", "unchecked" })
            @Override
            public int compare(AggregatedEvaluationResult aO1, AggregatedEvaluationResult aO2) {
                try {
                    Comparable v1 = (Comparable) PropertyUtils.getNestedProperty(aO1, sp.getProperty());
                    Comparable v2 = (Comparable) PropertyUtils.getNestedProperty(aO2, sp.getProperty());

                    return sp.isAscending() ? v1.compareTo(v2) : v2.compareTo(v1);
                } catch (Exception e) {
                    throw new IllegalStateException(e);
                }
            }
        });

        lastSortProperty = sp.getProperty();
        lastSortOrder = sp.isAscending();
        filterChanged = false;
    }

    /**
     * @see org.apache.wicket.markup.repeater.data.IDataProvider#model(java.lang.Object)
     */
    @Override
    public IModel<AggregatedEvaluationResult> model(AggregatedEvaluationResult aObject) {
        return new Model<AggregatedEvaluationResult>(aObject);
    }

    /**
     * Counts how many results there are in each ResultFilter category.
     * 
     * @return map
     */
    @Deprecated
    public Map<ResultFilter, Integer> getClassifications() {
        Map<ResultFilter, Integer> classifications = new HashMap<ResultFilter, Integer>();
        for (ResultFilter filter : ResultFilter.values()) {
            classifications.put(filter, 0);
        }
        for (AggregatedEvaluationResult aer : aerList) {
            ResultFilter current = aer.getClassification();
            classifications.put(current, classifications.get(current) + 1);
        }
        return classifications;
    }

    public double computeInterAnnotatorAgreement() {
        IAnnotationStudy study = new AnnotationStudy(users.size());
        for (AggregatedEvaluationResult aer : aerList) {
            // only use items which are annotated by all users
            if (aer.getUserRatio() == 1) {
                study.addItemAsArray(aer.getOrderedMarks());
            }
        }
        MultiRaterPiAgreement m = new MultiRaterPiAgreement(study);
        return m.calculateAgreement();
    }

    public ItemStatistics getItemStatistics() {
        ItemStatistics istats = new ItemStatistics();
        istats.users = users.size();
        istats.items = aerList.size();

        for (AggregatedEvaluationResult aer : aerList) {
            istats.correctVotes += aer.getCorrect();
            istats.wrongVotes += aer.getWrong();

            ResultFilter classification = aer.getClassification();
            if (classification == ResultFilter.CORRECT) {
                istats.truePositives++;
            } else if (classification == ResultFilter.WRONG) {
                istats.falsePositive++;
            }
        }
        istats.unknown = istats.items - istats.truePositives - istats.falsePositive;
        istats.fleissKappa = computeInterAnnotatorAgreement();
        return istats;
    }

    public Map<String, TypeStatistics> getTypeStatistics(Map<String, TypeStatistics> aStatsMap,
            Map<String, MutableInt> aUserStats) {
        for (AggregatedEvaluationResult aer : aerList) {
            String type = aer.getItem().getType();
            TypeStatistics tstats = aStatsMap.get(type);
            if (tstats == null) {
                tstats = new TypeStatistics();
                aStatsMap.put(type, tstats);
            }

            boolean countForUser = true;
            switch (aer.getClassification()) {
            case CORRECT:
                tstats.correct++;
                countForUser = true;
                break;
            case WRONG:
                tstats.wrong++;
                countForUser = true;
                break;
            case DISPUTED:
                tstats.disputed++;
                countForUser = true;
                break;
            case INCOMPLETE:
                tstats.incomplete++;
                break;
            default:
                // do nothing
            }

            if (countForUser) {
                Set<String> users = aer.getUsers(true);
                for (String user : users) {
                    MutableInt count = aUserStats.get(user);
                    if (count == null) {
                        count = new MutableInt();
                        aUserStats.put(user, count);
                    }
                    count.increment();
                }
            }
        }
        return aStatsMap;
    }

    public List<ResultFilter> getFilters() {
        return filters;
    }

    public void setFilters(List<ResultFilter> aFilters) {
        if (!(aFilters.containsAll(filters) && filters.containsAll(aFilters))) {
            filters = aFilters;
            filterChanged = true;
        }
    }
}