/* * Copyright (C) 2019 3053464 * * 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 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 Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * . */ package rules; import org.apache.commons.io.FileUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.PrintWriter; import java.io.Writer; import java.util.List; import org.nuiton.math.matrix.*; import org.nuiton.topia.TopiaContext; import resultinfos.*; import fr.ifremer.isisfish.util.Doc; import fr.ifremer.isisfish.simulator.SimulationContext; import fr.ifremer.isisfish.types.Month; import fr.ifremer.isisfish.types.TimeStep; import fr.ifremer.isisfish.entities.*; import fr.ifremer.isisfish.rule.AbstractRule; import fr.ifremer.isisfish.datastore.SimulationStorage; import fr.ifremer.isisfish.simulator.ResultManager; import org.nuiton.j2r.*; import org.nuiton.j2r.jni.*; import org.nuiton.j2r.net.*; import org.nuiton.j2r.REngine; import org.nuiton.j2r.RProxy; import org.nuiton.j2r.types.*; /** * ChangeTransitionMatrix.java */ public class ChangeTransitionMatrix extends AbstractRule { //DEFINE THE COEFFICIENTS OF VARIATION ON CV HERE @Doc(value = "Coefficient on hake transition matrix CV") public double param_coeffHake = 1.0; @Doc(value = "Coefficient on Nephrops transition matrix CV") public double param_coeffNep = 1.0; @Doc(value = "Base hake transition matrix CV") public double param_baseCVHake = 1.0; @Doc(value = "Base Nephrops transition matrix CV") public double param_baseCVNep = 1.0; boolean hasBeenChanged = false; /** to use log facility, just put in your code: log.info("..."); */ private static Log log = LogFactory.getLog(ChangeTransitionMatrix.class); protected String[] necessaryResult = { // put here all necessary result for this rule // example: // MatrixBiomass.NAME, // MatrixNetValueOfLandingsPerStrategyMet.NAME, }; public String[] getNecessaryResult() { return this.necessaryResult; } /** * Permet d'afficher a l'utilisateur une aide sur la regle. * @return L'aide ou la description de la regle */ public String getDescription() throws Exception { return "This rule is a workaround to make the CV of transition matrix vary during a sensitivity analysis, for hake and Nephrops. It is active only at the beginning of the first time step; only the pre-action is used."; } /** * Appelé au démarrage de la simulation, cette méthode permet d'initialiser * des valeurs. * * @param context la simulation pour lequel on utilise cette regle */ public void init(SimulationContext context) throws Exception { // Get the coefficient of variation double paramHake = param_coeffHake*param_baseCVHake; double paramNep = param_coeffNep*param_baseCVNep; // Open R session REngine engine = new RProxy(); // R session // Call an R script writing a new transition matrix for hake (only ONE matrix for hake) engine.voidEval("NewCV<-\""+Double.toString(paramHake)+"\"") ; // To avoid writing and reading issue (writing CV1 and trying to read CV1.0), the CV is sent as a character, not a double engine.voidEval("source(\"C:/Users/3053464/these/isis-fish-4.4.2.2/input/updateHakeTransitionMatrix.R\")"); System.out.println("Nouvelle valeur CV merlu : " + paramHake + " interim : " + param_coeffHake + " interim : " + param_baseCVHake); engine.voidEval("hakeMatrix(NewCV)"); // Call an R script writing a new transition matrix for Nephrops (TWO matrix for Nephrops) engine.voidEval("NewCV<-\""+Double.toString(paramNep)+"\"") ; engine.voidEval("source(\"C:/Users/3053464/these/isis-fish-4.4.2.2/input/updateNepTransitionMatrix.R\")"); System.out.println("Nouvelle valeur CV langoustine : " + paramNep); engine.voidEval("nephropsMatrix(NewCV)"); //Update ISIS database List Pops = context.getPopulationMonitor().getPopulations(); for(Population pop : Pops){ changeDB(context, pop, paramHake, paramNep, context.getSimulationStorage()); } } /** * La condition qui doit etre vrai pour faire les actions. * * @param context la simulation pour lequel on utilise cette regle * @param step le pas de temps courant * @param metier le metier concerné * @return vrai si on souhaite que les actions soit faites */ public boolean condition(SimulationContext context, TimeStep step, Metier metier) throws Exception { // If step = 0 : true ; else, do not execute the rule boolean result = true; /* if (step.getStep()==0) { result = true; } */ return result; } /** * Si la condition est vrai alors cette action est executee avant le pas * de temps de la simulation. * * @param context la simulation pour lequel on utilise cette regle * @param step le pas de temps courant * @param metier le metier concerné */ public void preAction(SimulationContext context, TimeStep step, Metier metier) throws Exception { /* // Execute only once (do NOT do the metier loop) if(!hasBeenChanged){ boolean hakeHasBeenChanged = false; boolean nephropsHasBeenChanged = false; // Get the coefficient of variation double paramHake = param_coeffHake*param_baseCVHake; double paramNep = param_coeffNep*param_baseCVNep; // Open R session REngine engine = new RProxy(); // R session // Call an R script writing a new transition matrix for hake (only ONE matrix for hake) engine.voidEval("NewCV<-\""+Double.toString(paramHake)+"\"") ; // To avoid writing and reading issue (writing CV1 and trying to read CV1.0), the CV is sent as a character, not a double engine.voidEval("source(\"C:/Users/3053464/these/isis-fish-4.4.2.2/input/updateHakeTransitionMatrix.R\")"); System.out.println("Nouvelle valeur CV merlu : " + paramHake + " interim : " + param_coeffHake + " interim : " + param_baseCVHake); engine.voidEval("hakeMatrix(NewCV)"); // Call an R script writing a new transition matrix for Nephrops (TWO matrix for Nephrops) engine.voidEval("NewCV<-\""+Double.toString(paramNep)+"\"") ; engine.voidEval("source(\"C:/Users/3053464/these/isis-fish-4.4.2.2/input/updateNepTransitionMatrix.R\")"); System.out.println("Nouvelle valeur CV langoustine : " + paramNep); engine.voidEval("nephropsMatrix(NewCV)"); /* // Read the updated transition matrix (COULD BE IMPROVED) //Hake String hakeMatrix = "input/matrixUpdate/hakeCV"+paramHake+".csv"; File hakeMatrixFile = new File(hakeMatrix); int[] dimMatrixHake = {72,72}; MatrixND matrixHake = MatrixFactory.getInstance().create(dimMatrixHake); matrixHake.importCSV(new FileReader(hakeMatrixFile),new int []{0,0}); matrixHake=matrixHake.reduce(); //Nephrops String nepAprMatrix = "input/matrixUpdate/nepCVApril"+paramNep+".csv"; String nepOctMatrix = "input/matrixUpdate/nepCVOctober"+paramNep+".csv"; File nepAprMatrixFile = new File(nepAprMatrix); File nepOctMatrixFile = new File(nepOctMatrix); int[] dimMatrixNep = {58,58}; MatrixND matrixNepApr = MatrixFactory.getInstance().create(dimMatrixNep); MatrixND matrixNepOct = MatrixFactory.getInstance().create(dimMatrixNep); matrixNepApr.importCSV(new FileReader(nepAprMatrixFile),new int []{0,0}); matrixNepOct.importCSV(new FileReader(nepOctMatrixFile),new int []{0,0}); matrixNepApr=matrixNepApr.reduce(); matrixNepOct=matrixNepOct.reduce(); *//* //Update ISIS database List Pops = context.getPopulationMonitor().getPopulations(); for(Population pop : Pops){ changeDB(pop, paramHake, paramNep, context.getSimulationStorage()); } // Prevent useless multiple executions hasBeenChanged = true; //Check (to be commented all the time) : were the transition matrix changed correctly? /* for(Population pop : Pops){ if(pop.getSpecies().getName().equals("Merlu")){ Month month = new Month(5); PopulationSeasonInfo psi = pop.getPopulationSeasonInfo(month) ; MatrixND transition = psi.getLengthChangeMatrix(); //writeCSV File fileMatrix = new File ("input/matrixUpdate/hakeCheck.csv"); String string2write=""; for (MatrixIterator i = transition.iterator(); i.next();) { int[] coords = i.getCoordinates(); string2write += i.getValue(); if(coords[1]==(transition.getDim(1)-1)){ string2write += "\n"; } else{ string2write += ";"; } } FileUtils.writeStringToFile(fileMatrix,string2write,true); } if(pop.getSpecies().getName().equals("langoustine")){ Month april = new Month(3); PopulationSeasonInfo psiApril = pop.getPopulationSeasonInfo(april) ; MatrixND transitionApril = psiApril.getLengthChangeMatrix(); // get transition matrix Month october = new Month(9); PopulationSeasonInfo psiOctober = pop.getPopulationSeasonInfo(october) ; MatrixND transitionOctober = psiOctober.getLengthChangeMatrix(); // get transition matrix //writeCSV File fileMatrix = new File ("input/matrixUpdate/nepAprCheck.csv"); String string2write=""; for (MatrixIterator i = transitionApril.iterator(); i.next();) { int[] coords = i.getCoordinates(); string2write += i.getValue(); if(coords[1]==(transitionApril.getDim(1)-1)){ string2write += "\n"; } else{ string2write += ";"; } } FileUtils.writeStringToFile(fileMatrix,string2write,true); //writeCSV fileMatrix = new File ("input/matrixUpdate/nepOctCheck.csv"); string2write=""; for (MatrixIterator i = transitionOctober.iterator(); i.next();) { int[] coords = i.getCoordinates(); string2write += i.getValue(); if(coords[1]==(transitionOctober.getDim(1)-1)){ string2write += "\n"; } else{ string2write += ";"; } } FileUtils.writeStringToFile(fileMatrix,string2write,true); } } } */ } /** * Si la condition est vrai alors cette action est executée apres le pas * de temps de la simulation. * * @param context La simulation pour lequel on utilise cette regle * @param step le pas de temps courant * @param metier le metier concerné */ public void postAction(SimulationContext context, TimeStep step, Metier metier) throws Exception { // Nothing } protected void changeDB(SimulationContext context, Population pop, double paramHake, double paramNep, SimulationStorage nextSimulation) throws Exception { if(pop.getSpecies().getName().equals("Sole")){ //db.closeContext(); } if(pop.getSpecies().getName().equals("Merlu")){ //Load the new transition matrix /* String hakeMatrix = "input/matrixUpdate/hakeCV"+paramHake+".csv"; File hakeMatrixFile = new File(hakeMatrix); int[] dimMatrixHake = {72,72}; MatrixND matrixHake = MatrixFactory.getInstance().create(dimMatrixHake); matrixHake.importCSV(new FileReader(hakeMatrixFile),new int []{0,0}); matrixHake=matrixHake.reduce(); */ File transitionHakeNew = new File("C:/Users/3053464/these/isis-fish-4.4.2.2/input/matrixUpdate/hakeCV"+paramHake+".csv"); int[] dimMatrixHake = {72,72}; MatrixND matrixTransitionHakeNew = MatrixFactory.getInstance().create(dimMatrixHake); matrixTransitionHakeNew.importCSV(new FileReader(transitionHakeNew),new int []{0,0}); matrixTransitionHakeNew=matrixTransitionHakeNew.reduce(); TopiaContext db; Population popDB; for(int monthNumber =0; monthNumber<12; monthNumber++){ //db = nextSimulation.getStorage().beginTransaction();//ouvrir un context pour modifier les donnees db = context.getDB(); Month month = new Month(monthNumber); popDB = (Population) db.findByTopiaId(pop.getTopiaId()); PopulationSeasonInfo psi = popDB.getPopulationSeasonInfo(month) ; MatrixND transition = psi.getLengthChangeMatrix(); // get transition matrix // *** Update transition matrix for each month for (MatrixIterator i = transition.iterator(); i.hasNext();) { i.next(); int[] coords = i.getCoordinates(); i.setValue(matrixTransitionHakeNew.getValue(coords)); } popDB.getPopulationSeasonInfo(month).setLengthChangeMatrix(transition); //db.commitTransaction(); // effectue la modification //db.closeContext(); // ferme le context //System.out.println("MODIF DONE HAKE"); // check : was the transition matrix actually updated??? /* File fileMatrix = new File ("input/matrixUpdate/hakeCheck"+paramHake+".csv"); String string2write=""; MatrixND matrix2check = popDB.getPopulationSeasonInfo(month).getLengthChangeMatrix(); for (MatrixIterator i = matrix2check.iterator(); i.next();) { int[] coords = i.getCoordinates(); string2write += i.getValue(); if(coords[1]==(matrix2check.getDim(1)-1)){ string2write += "\n"; } else{ string2write += ";"; } } FileUtils.writeStringToFile(fileMatrix,string2write,true); */ } } if(pop.getSpecies().getName().equals("langoustine")){ //Load the new transition matrix int[] dimMatrixNep = {58,58}; File transitionNepAprilNew = new File("C:/Users/3053464/these/isis-fish-4.4.2.2/input/matrixUpdate/nepCVApril"+paramNep+".csv"); MatrixND matrixTransitionNepAprilNew = MatrixFactory.getInstance().create(dimMatrixNep); File transitionNepOctoberNew = new File("C:/Users/3053464/these/isis-fish-4.4.2.2/input/matrixUpdate/nepCVOctober"+paramNep+".csv"); MatrixND matrixTransitionNepOctoberNew = MatrixFactory.getInstance().create(dimMatrixNep); matrixTransitionNepAprilNew.importCSV(new FileReader(transitionNepAprilNew),new int []{0,0}); matrixTransitionNepAprilNew=matrixTransitionNepAprilNew.reduce(); matrixTransitionNepOctoberNew.importCSV(new FileReader(transitionNepOctoberNew),new int []{0,0}); matrixTransitionNepOctoberNew=matrixTransitionNepOctoberNew.reduce(); //TopiaContext db = nextSimulation.getStorage().beginTransaction();//ouvrir un context pour modifier les donnees TopiaContext db = context.getDB(); Population popDB= (Population) db.findByTopiaId(pop.getTopiaId()); Month april = new Month(3); PopulationSeasonInfo psiApril = popDB.getPopulationSeasonInfo(april) ; MatrixND transitionApril = psiApril.getLengthChangeMatrix(); // get transition matrix // *** Update transition matrix for April for (MatrixIterator i = transitionApril.iterator(); i.hasNext();) { i.next(); int[] coords = i.getCoordinates(); i.setValue(matrixTransitionNepAprilNew.getValue(coords)); } popDB.getPopulationSeasonInfo(april).setLengthChangeMatrix(transitionApril); //db.commitTransaction(); // effectue la modification //db.closeContext(); // ferme le context //db = nextSimulation.getStorage().beginTransaction();//ouvrir un context pour modifier les donnees Month october = new Month(9); PopulationSeasonInfo psiOctober = popDB.getPopulationSeasonInfo(october) ; MatrixND transitionOctober = psiOctober.getLengthChangeMatrix(); // get transition matrix // *** Update transition matrix for October for (MatrixIterator i = transitionOctober.iterator(); i.hasNext();) { i.next(); int[] coords = i.getCoordinates(); i.setValue(matrixTransitionNepOctoberNew.getValue(coords)); } popDB.getPopulationSeasonInfo(october).setLengthChangeMatrix(transitionOctober); //db.commitTransaction(); // effectue la modification //db.closeContext(); // ferme le context //System.out.println("MODIF DONE"); } } /* static public void main (String...args) throws Exception { /* double paramNep = 0.125; File transitionNepAprilNew = new File("input/matrixUpdate/nepCVApril"+paramNep+".csv"); MatrixND matrixTransitionNepAprilNew = MatrixFactory.getInstance().create(transitionNepAprilNew); //fr.ifremer.isisfish.util.RUtil.initJri(); //System.out.println(System.getProperty("java.home")); double paramHake=1.3859; // Open R session REngine engine = new RProxy(); // R session // Call an R script writing a new transition matrix for hake (only ONE matrix for hake) engine.voidEval("NewCV<-"+Double.toString(paramHake)+"") ; engine.voidEval("source(\"C:/Users/3053464/these/isis-fish-4.4.2.2/input/updateHakeTransitionMatrix.R\")"); engine.voidEval("hakeMatrix(NewCV)"); } */ }