r3610 - in branches/4.1/src/main/java/fr/ifremer/isisfish: equation simulator
Author: echatellier Date: 2012-02-16 17:58:57 +0100 (Thu, 16 Feb 2012) New Revision: 3610 Url: http://forge.codelutin.com/repositories/revision/isis-fish/3610 Log: Add simulation context methods to use entities variables. Added: branches/4.1/src/main/java/fr/ifremer/isisfish/equation/VariableEquation.java branches/4.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationVariable.java Modified: branches/4.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationContext.java Added: branches/4.1/src/main/java/fr/ifremer/isisfish/equation/VariableEquation.java =================================================================== --- branches/4.1/src/main/java/fr/ifremer/isisfish/equation/VariableEquation.java (rev 0) +++ branches/4.1/src/main/java/fr/ifremer/isisfish/equation/VariableEquation.java 2012-02-16 16:58:57 UTC (rev 3610) @@ -0,0 +1,56 @@ +/* + * #%L + * IsisFish + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 Ifremer, Code Lutin, Chatellier Eric + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) 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 + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-2.0.html>. + * #L% + */ + +package fr.ifremer.isisfish.equation; + +import org.nuiton.topia.persistence.TopiaEntity; + +import fr.ifremer.isisfish.simulator.SimulationContext; +import fr.ifremer.isisfish.types.TimeStep; +import fr.ifremer.isisfish.util.Args; + +/** + * Generic equation signature used in variable values. + * + * @author chatellier + * @version $Revision$ + * + * Last update : $Date$ + * By : $Author$ + */ +public interface VariableEquation { + + /** + * Compute target factor. + * + * @param context simulation context + * @param entity l'entity sur laquelle la variable a été ajoutée + * @param step le pas de temps courant + * @return equation result + * @throws Exception + */ + @Args({"context", "entity", "step"}) + public double compute(SimulationContext context, TopiaEntity entity, TimeStep step) throws Exception; +} Property changes on: branches/4.1/src/main/java/fr/ifremer/isisfish/equation/VariableEquation.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: branches/4.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationContext.java =================================================================== --- branches/4.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationContext.java 2012-02-16 16:58:26 UTC (rev 3609) +++ branches/4.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationContext.java 2012-02-16 16:58:57 UTC (rev 3610) @@ -5,7 +5,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2006 - 2010 Ifremer, Code Lutin, Cédric Pineau, Benjamin Poussin + * Copyright (C) 2006 - 2012 Ifremer, Code Lutin, Cédric Pineau, Benjamin Poussin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as @@ -26,18 +26,28 @@ package fr.ifremer.isisfish.simulator; import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; +import org.apache.commons.beanutils.BeanUtils; +import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.topia.TopiaContext; import org.nuiton.topia.TopiaException; +import org.nuiton.topia.persistence.TopiaEntity; +import fr.ifremer.isisfish.IsisFishRuntimeException; import fr.ifremer.isisfish.datastore.SimulationStorage; +import fr.ifremer.isisfish.entities.Variable; import fr.ifremer.isisfish.simulator.sensitivity.SensitivityUtils; +import fr.ifremer.isisfish.types.TimeStep; /** * Keep all information on one simulation. @@ -45,7 +55,7 @@ * <li> Launch parameter * <li> Database (TopiaContext) * <li> SimulationControl - * <li> Effectif by pop (N) + * <li> Effective by pop (N) * <li> Result * * Created: 3 juil. 2006 17:05:27 @@ -78,9 +88,12 @@ /** TopiaContext must be used to save result */ protected TopiaContext dbResult = null; + /** Cache des variables d'entités. Topia id > map of attributes. */ + protected Map<TopiaEntity, SimulationVariable> variablesCache = new HashMap<TopiaEntity, SimulationVariable>(); + /** Context value used in equation. */ protected Map<String, Double> contextEquationValue = new HashMap<String, Double>(); - + private static ThreadLocal<SimulationContext> simulationContext = new ThreadLocal<SimulationContext>() { protected synchronized SimulationContext initialValue() { return new SimulationContext(); @@ -336,7 +349,7 @@ public void setComputeValue(String key, Double value) { contextEquationValue.put(key, value); } - + /** * Return value from context. * @@ -361,7 +374,7 @@ log.trace("Found key '" + localKey + "' current value = " + value); } - // since 3.4.0.0, operator is always * + // since 4.0.0.0, operator is always * result = value; } else { @@ -373,4 +386,70 @@ return result; } + + /** + * Get object containing variable for given entity. + * + * @param entity entity + * @return map object for this class + */ + public SimulationVariable get(TopiaEntity entity) { + SimulationVariable v = variablesCache.get(entity); + if (v == null) { + v = new SimulationVariable(this, entity); + variablesCache.put(entity, v); + } + return v; + } + + /** + * Save all cached context values. + * + * @param step + */ + public void saveContextValues(TimeStep step) { + File exportFile = new File(getScriptDirectory(), "variables.txt"); + + Writer out = null; + try { + out = new FileWriter(exportFile, true); + + out.write("=========== Step : " + step.toString() + " ===========\n"); + for (Map.Entry<TopiaEntity, SimulationVariable> entry : variablesCache.entrySet()) { + TopiaEntity entity = entry.getKey(); + SimulationVariable simVariable = entry.getValue(); + + String name = null; + try { + name = BeanUtils.getProperty(entity, "name"); + } catch (Exception ex) { + name = entity.getTopiaId(); + } + + for (Entry<String, Variable> variableEntry : simVariable.variablesCache.entrySet()) { + Variable variable = variableEntry.getValue(); + + out.write(name + " "); + out.write(variable.getName()); + out.write(" = "); + + if ("double".equals(variable.getType())) { + out.write(String.valueOf(variable.getDoubleValue())); + } else if ("matrix".equals(variable.getType())) { + out.write("todo matrix"); + } else if ("equation".equals(variable.getType())) { + out.write("todo equation"); + } + out.write("\n"); + } + } + out.write("\n\n"); + + out.close(); + } catch (IOException ex) { + throw new IsisFishRuntimeException("Can't save ", ex); + } finally { + IOUtils.closeQuietly(out); + } + } } Added: branches/4.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationVariable.java =================================================================== --- branches/4.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationVariable.java (rev 0) +++ branches/4.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationVariable.java 2012-02-16 16:58:57 UTC (rev 3610) @@ -0,0 +1,155 @@ +/* + * #%L + * + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 Ifremer, Codelutin, Chatellier Eric + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) 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 + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package fr.ifremer.isisfish.simulator; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.nuiton.math.matrix.MatrixND; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.TopiaException; +import org.nuiton.topia.persistence.TopiaEntity; + +import fr.ifremer.isisfish.entities.Equation; +import fr.ifremer.isisfish.entities.EquationImpl; +import fr.ifremer.isisfish.entities.Variable; +import fr.ifremer.isisfish.equation.VariableEquation; +import fr.ifremer.isisfish.types.TimeStep; +import fr.ifremer.isisfish.util.EvaluatorHelper; + +/** + * Object containing cached variable value for a specific entity. + * + * @author chatellier + * @version $Revision$ + * + * Last update : $Date$ + * By : $Author$ + */ +public class SimulationVariable { + + /** Simulation context (to get db). */ + protected SimulationContext simulationContext; + + /** Managed entity id. */ + protected TopiaEntity topiaEntity; + + /** Variable name > variable entity. */ + protected Map<String, Variable> variablesCache = new HashMap<String, Variable>(); + + public SimulationVariable(SimulationContext simulationContext, TopiaEntity topiaEntity) { + this.simulationContext = simulationContext; + this.topiaEntity = topiaEntity; + } + + /** + * Return variable entity from cache or database. + * + * @param name variable name to get + * @return variable entity + * @throws TopiaException if can't restore variable from db + */ + protected Variable getVariableEntity(String name) throws TopiaException { + Variable v = variablesCache.get(name); + if (v == null) { + TopiaContext topiaContext = simulationContext.getDB(); + List<Variable> vindb = topiaContext.find("FROM " + Variable.class.getName() + + " WHERE " + Variable.PROPERTY_ENTITY_ID + " = :id" + + " AND " + Variable.PROPERTY_NAME + " = :name", + "id", topiaEntity.getTopiaId(), + "name", name); + if (!vindb.isEmpty()) { + v = vindb.get(0); + variablesCache.put(name, v); + } + } + return v; + } + + /** + * Return variable value as double. + * + * @param name variable name + * @return value as double + * @throws TopiaException if can't restore variable from db + */ + public double getAsDouble(String name) throws TopiaException { + Variable v = getVariableEntity(name); + double result = v.getDoubleValue(); + return result; + } + + /** + * Set variable value. + * + * @param name variable name + * @param value new value + * @throws TopiaException if can't restore variable from db + */ + public void set(String name, Object value) throws TopiaException { + Variable v = getVariableEntity(name); + if (double.class.isAssignableFrom(value.getClass()) || Double.class.isAssignableFrom(value.getClass())) { + v.setDoubleValue((Double)value); + } else if (value instanceof MatrixND) { + v.setMatrixValue((MatrixND)value); + } else if (value instanceof String) { + Equation eq = v.getEquationValue(); + if (eq == null) { + eq = new EquationImpl(); + eq.setContent((String)value); + } + v.setEquationValue(eq); + } + } + + /** + * Eval current variable equation. + * + * @param name variable name + * @return equation result + * @throws TopiaException if can't restore variable from db + */ + public double eval(String name) throws TopiaException { + Variable v = getVariableEntity(name); + Equation eq = v.getEquationValue(); + + Map<String, Object> args = new HashMap<String, Object>(); + args.put("context", simulationContext); + args.put("entity", topiaEntity); + args.put("step", new TimeStep()); // FIXME echatellier how to get real timestep value ? + + Object val = EvaluatorHelper.evaluate("fr.ifremer.isisfish.equation", + topiaEntity.getTopiaId() + "#" + name, VariableEquation.class, + eq.getContent(), args); + + double result = 0.0; + if (val instanceof Number) { + result = ((Number) val).doubleValue(); + } + return result; + } +} Property changes on: branches/4.1/src/main/java/fr/ifremer/isisfish/simulator/SimulationVariable.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL
participants (1)
-
echatellier@users.forge.codelutin.com