it.unibo.alchemist.boundary.monitors.SAPERENearestNodeSampler.java Source code

Java tutorial

Introduction

Here is the source code for it.unibo.alchemist.boundary.monitors.SAPERENearestNodeSampler.java

Source

/*
 * Copyright (C) 2010-2014, Danilo Pianini and contributors
 * listed in the project's pom.xml file.
 * 
 * This file is part of Alchemist, and is distributed under the terms of
 * the GNU General Public License, with a linking exception, as described
 * in the file LICENSE in the Alchemist distribution's top directory.
 */
package it.unibo.alchemist.boundary.monitors;

import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.math3.util.FastMath;
import org.danilopianini.lang.HashUtils;
import org.danilopianini.view.ExportForGUI;

import it.unibo.alchemist.model.SAPEREIncarnation;
import it.unibo.alchemist.model.interfaces.Environment;
import it.unibo.alchemist.model.interfaces.ILsaMolecule;
import it.unibo.alchemist.model.interfaces.Molecule;
import it.unibo.alchemist.model.interfaces.Node;
import it.unibo.alchemist.model.interfaces.Position;
import it.unibo.alchemist.model.interfaces.Reaction;
import it.unibo.alchemist.model.interfaces.Time;

/**
 */
@ExportInspector
public class SAPERENearestNodeSampler extends PositionSampler<List<? extends ILsaMolecule>> {

    private static final long serialVersionUID = -5664559491928782478L;
    @ExportForGUI(nameToExport = "Enable support for node mobility")
    private boolean mobility = true;
    @ExportForGUI(nameToExport = "LSA to track")
    private String lsa = "";
    @ExportForGUI(nameToExport = "Properties to log")
    private String property = "";
    @ExportForGUI(nameToExport = "Property separators")
    private String propertySeparators = " ;,:";

    private String propertyCache;
    private String lsaCache;
    private Molecule mol;
    private final List<String> properties = new LinkedList<>();
    private final SAPEREIncarnation sapere = new SAPEREIncarnation();
    private final Map<Position, Node<List<? extends ILsaMolecule>>> pnCache = new ConcurrentHashMap<>();
    private Environment<List<? extends ILsaMolecule>> envCache;

    /**
     * @return lsa
     */
    protected String getLsa() {
        return lsa;
    }

    /**
     * @param l
     *            lsa
     */
    protected void setLsa(final String l) {
        this.lsa = l;
    }

    /**
     * @return property
     */
    protected String getProperty() {
        return property;
    }

    /**
     * @param p
     *            property
     */
    protected void setProperty(final String p) {
        this.property = p;
    }

    /**
     * @return property separators
     */
    protected String getPropertySeparators() {
        return propertySeparators;
    }

    /**
     * @param ps
     *            property separators
     */
    protected void setPropertySeparators(final String ps) {
        this.propertySeparators = ps;
    }

    /**
     * @return if mobility support is enabled
     */
    protected boolean isMobility() {
        return mobility;
    }

    /**
     * @param mobility true if mobility support should be enabled.
     */
    protected void setMobility(final boolean mobility) {
        this.mobility = mobility;
    }

    @Override
    protected double[] getProperties(final Environment<List<? extends ILsaMolecule>> env, final Position pos,
            final Reaction<List<? extends ILsaMolecule>> r, final Time time, final long step) {
        if (mobility || !HashUtils.pointerEquals(env, envCache)) {
            pnCache.clear();
            envCache = env;
        }
        if (!HashUtils.pointerEquals(propertyCache, property)) {
            propertyCache = property;
            properties.clear();
            final StringTokenizer tk = new StringTokenizer(propertyCache, propertySeparators);
            while (tk.hasMoreElements()) {
                properties.add(tk.nextToken());
            }
        }
        if (!HashUtils.pointerEquals(lsaCache, lsa)) {
            lsaCache = lsa;
            mol = sapere.createMolecule(lsaCache);
        }
        if (env.getNodesNumber() > 0 && mol != null) {
            final double[] res = new double[properties.size()];
            int i = 0;
            Node<List<? extends ILsaMolecule>> node = pnCache.get(pos);
            if (node == null) {
                double range = Arrays.stream(env.getSize()).reduce(1,
                        (x, y) -> FastMath.max(x, y) / FastMath.sqrt(env.getNodesNumber()));
                Collection<Node<List<? extends ILsaMolecule>>> neighs = env.getNodesWithinRange(pos, range);
                while (neighs.isEmpty()) {
                    range *= 2;
                    neighs = env.getNodesWithinRange(pos, range);
                }
                node = neighs.stream().reduce(
                        (n1, n2) -> env.getPosition(n1).getDistanceTo(pos) < env.getPosition(n2).getDistanceTo(pos)
                                ? n1
                                : n2)
                        .get();
                pnCache.put(pos, node);
            }
            for (final String prop : properties) {
                /*
                 * Take the nearest node
                 */
                res[i++] = sapere.getProperty(node, mol, prop);
            }
            return res;
        }
        return new double[0];
    }

}