
org.integratedmodelling.engine.visualization.VisualizationFactory Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (C) 2007, 2015:
*
* - Ferdinando Villa - integratedmodelling.org - any
* other authors listed in @author annotations
*
* All rights reserved. This file is part of the k.LAB software suite, meant to enable
* modular, collaborative, integrated development of interoperable data and model
* components. For details, see http://integratedmodelling.org.
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the Affero General Public License Version 3 or any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the Affero General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite
* 330, Boston, MA 02111-1307, USA. The license is also available at:
* https://www.gnu.org/licenses/agpl.html
*******************************************************************************/
package org.integratedmodelling.engine.visualization;
import java.io.File;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.integratedmodelling.api.data.IProbabilityDistribution;
import org.integratedmodelling.api.knowledge.IConcept;
import org.integratedmodelling.api.modelling.IClassification;
import org.integratedmodelling.api.modelling.IMeasuringObserver;
import org.integratedmodelling.api.modelling.IObservation;
import org.integratedmodelling.api.modelling.IScale;
import org.integratedmodelling.api.modelling.IScale.Locator;
import org.integratedmodelling.api.modelling.IState;
import org.integratedmodelling.api.modelling.ISubject;
import org.integratedmodelling.api.modelling.visualization.IMedia;
import org.integratedmodelling.api.modelling.visualization.IViewport;
import org.integratedmodelling.api.modelling.visualization.IVisualizationFactory;
import org.integratedmodelling.common.beans.responses.ValueSummary;
import org.integratedmodelling.common.data.IndexedCategoricalDistribution;
import org.integratedmodelling.common.owl.Knowledge;
import org.integratedmodelling.common.states.State;
import org.integratedmodelling.common.storage.ProbabilityStorage;
import org.integratedmodelling.common.visualization.Viewport;
import org.integratedmodelling.engine.geospace.Geospace;
import org.integratedmodelling.engine.time.Time;
import org.integratedmodelling.exceptions.KlabException;
import org.integratedmodelling.exceptions.KlabIOException;
import org.integratedmodelling.exceptions.KlabRuntimeException;
import org.springframework.http.MediaType;
import com.google.common.primitives.Doubles;
public class VisualizationFactory extends
org.integratedmodelling.common.visualization.VisualizationFactory implements
IVisualizationFactory {
private static VisualizationFactory _this = null;
public static VisualizationFactory get() {
if (_this == null) {
_this = new VisualizationFactory();
}
return _this;
}
public double[] getStateDataAsNumbers(IState state, Iterable locators) {
double[] ret = new double[(int) state.getValueCount()];
IClassification classification = getClassification(state);
List ls = new ArrayList<>();
for (IScale.Locator l : locators) {
ls.add(l);
}
for (int n : state.getScale().getIndex(ls.toArray(new Locator[ls.size()]))) {
/**
* If a specific extent offset is needed, e.g. the offset in space, the
* following can be used, which will return the spatial offset for the given
* overall offset. The reason for not having specific getSpatialOffset() or
* getTemporalOffset is that there can be additional extents beyond time and
* space, although these are not used at the moment.
*/
int i = state.getScale().getExtentOffset(state.getScale().getSpace(), n);
Double d = Double.NaN;
Object o = ((State) state).getValue(n);
if (o instanceof Number) {
d = ((Number) o).doubleValue();
} else if (o instanceof IndexedCategoricalDistribution) {
d = ((IndexedCategoricalDistribution) o).getMean();
} else if (o instanceof Boolean) {
d = ((Boolean) o) ? 1.0 : 0.0;
} else if (o instanceof IConcept) {
if (classification != null) {
d = classification.getNumericCode((IConcept) o);
}
} else if (o != null) {
throw new KlabRuntimeException("internal: unexpected state value in VisualizationFactory.getStateData");
}
ret[i] = d;
}
return ret;
}
public double[] getStateDataAsNumbers(IState state) {
double[] ret = new double[(int) state.getValueCount()];
IClassification classification = getClassification(state);
for (int i = 0; i < state.getValueCount(); i++) {
Double d = Double.NaN;
Object o = ((State) state).getValue(i);
if (o instanceof Number) {
d = ((Number) o).doubleValue();
} else if (o instanceof IndexedCategoricalDistribution) {
d = ((IndexedCategoricalDistribution) o).getMean();
} else if (o instanceof Boolean) {
d = ((Boolean) o) ? 1.0 : 0.0;
} else if (o instanceof IConcept) {
if (classification != null) {
d = classification.getNumericCode((IConcept) o);
}
} else if (o != null) {
throw new KlabRuntimeException("internal: unexpected state value in VisualizationFactory.getStateData");
}
ret[i] = d;
}
return ret;
}
public float[] getStateDataAsFloats(IState state) {
float[] ret = new float[(int) state.getValueCount()];
for (int i = 0; i < state.getValueCount(); i++) {
Double d = Double.NaN;
Object o = ((State) state).getValue(i);
if (o instanceof Number) {
d = ((Number) o).doubleValue();
} else if (o instanceof IndexedCategoricalDistribution) {
d = ((IndexedCategoricalDistribution) o).getMean();
} else if (o instanceof Boolean) {
d = ((Boolean) o) ? 1.0 : 0.0;
} else if (o != null) {
throw new KlabRuntimeException("internal: unexpected state value in VisualizationFactory.getStateData");
}
ret[i] = d.floatValue();
}
return ret;
}
@Override
public IMedia getMedia(IObservation observation, IScale.Index index, IViewport viewport, String mimeType, Map options) {
MediaType type = MediaType.valueOf(mimeType);
if (type.isCompatibleWith(MediaType.IMAGE_PNG)) {
return new ImageMedia(observation, index, viewport, type, options);
}
return null;
}
public void persist(IObservation obs, File file, boolean isVideo, Object... options)
throws KlabException {
/*
* parse back options. TODO may assume that anything else is a key,value pair for
* the media that take it, but for now let's skip the painful coding.
*/
List locators = new ArrayList<>();
Viewport viewport = null;
for (Object o : options) {
if (o instanceof IScale.Locator) {
locators.add((Locator) o);
} else if (o instanceof Viewport) {
viewport = (Viewport) o;
}
}
if (isVideo) {
if (obs instanceof IState && obs.getScale().isSpatiallyDistributed()
&& obs.getScale().isTemporallyDistributed()) {
VideoMedia vm = new VideoMedia(obs, viewport, null);
try {
FileUtils.copyFile(vm.getFile(), file);
} catch (IOException e) {
throw new KlabIOException(e);
}
}
} else {
if (obs instanceof IState) {
if (obs.getScale().isSpatiallyDistributed()) {
Geospace.get().persistState((IState) obs, file, locators);
} else if (obs.getScale().isTemporallyDistributed()) {
Time.get().persistState((IState) obs, file, locators);
}
} else if (obs instanceof ISubject) {
if (obs.getScale().isSpatiallyDistributed()) {
Geospace.get().persistSubject((ISubject) obs, file);
}
}
}
}
public ValueSummary describeValue(IState state, Object o) {
ValueSummary ret = new ValueSummary();
if (o == null || (o instanceof Double && Double.isNaN((Double) o))) {
o = "No data";
} else if (o instanceof IndexedCategoricalDistribution) {
ret.setDistribution(Doubles.asList(((IndexedCategoricalDistribution) o).getData()));
ret.setRanges(Doubles.asList(((IndexedCategoricalDistribution) o).getRanges()));
ret.setUncertainty(((IndexedCategoricalDistribution) o).getUncertainty());
if (state.getStorage() instanceof ProbabilityStorage) {
IConcept likelyClass = ((ProbabilityStorage) state.getStorage())
.getMostLikelyClass((IProbabilityDistribution) o);
if (likelyClass != null) {
ret.setMostLikelyClass(((Knowledge) likelyClass).asText());
}
}
o = "m=" +
NumberFormat.getInstance().format(((IndexedCategoricalDistribution) o).getMean())
+ ", s=" +
NumberFormat.getInstance().format(((IndexedCategoricalDistribution) o).getUncertainty());
} else if (o instanceof Boolean) {
o = state.getObservable().getType().getLocalName() + ((Boolean) o ? " present" : " absent");
} else if (o instanceof IConcept) {
o = ((IConcept) o).getLocalName();
} else if (o instanceof Number) {
o = NumberFormat.getInstance().format(o);
} else {
o = o.toString();
}
if (state.getObserver() instanceof IMeasuringObserver) {
o = o + " " + ((IMeasuringObserver) state.getObserver()).getUnit();
}
ret.setDescription(o.toString());
return ret;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy