From dd850cdb637edd01ccb36790faead5c60dcc3df8 Mon Sep 17 00:00:00 2001
From: Tor-Einar Skog <tor-einar.skog@bioforsk.no>
Date: Fri, 18 Nov 2016 16:22:51 -0800
Subject: [PATCH] Allowing for just one of height / MSC to be set of the
 optimization parameters Avoiding some ConcurrentModificationExceptions by
 copying list

---
 .../OptimizationObservation.java              |    4 +
 .../RoughageNutritionModel.java               |   28 +-
 .../RoughageNutritionModelImpl.java           | 1662 ++++++++---------
 .../RoughageNutritionModelTest.java           |    4 +
 4 files changed, 779 insertions(+), 919 deletions(-)

diff --git a/src/main/java/no/bioforsk/vips/model/roughagenutritionmodel/OptimizationObservation.java b/src/main/java/no/bioforsk/vips/model/roughagenutritionmodel/OptimizationObservation.java
index c3dd382..2f2596b 100644
--- a/src/main/java/no/bioforsk/vips/model/roughagenutritionmodel/OptimizationObservation.java
+++ b/src/main/java/no/bioforsk/vips/model/roughagenutritionmodel/OptimizationObservation.java
@@ -65,6 +65,10 @@ public class OptimizationObservation implements Comparable{
      */
     public Double getAvling()
     {
+        if(this.getHeight() == null)
+        {
+            return null;
+        }
         return 34.86f + 0.017f * (Double) Math.pow(this.getHeight(), 2) + 10.21f * this.getHeight();
     }
 
diff --git a/src/main/java/no/bioforsk/vips/model/roughagenutritionmodel/RoughageNutritionModel.java b/src/main/java/no/bioforsk/vips/model/roughagenutritionmodel/RoughageNutritionModel.java
index d83a609..88edc17 100644
--- a/src/main/java/no/bioforsk/vips/model/roughagenutritionmodel/RoughageNutritionModel.java
+++ b/src/main/java/no/bioforsk/vips/model/roughagenutritionmodel/RoughageNutritionModel.java
@@ -236,8 +236,7 @@ public class RoughageNutritionModel implements Model {
 
     @Override
     public void setConfiguration(ModelConfiguration config) throws ConfigValidationException {
-        
-        
+
         /*
             // Daily values
             List<WeatherObservation> luftTemperatur, TM
@@ -456,27 +455,36 @@ public class RoughageNutritionModel implements Model {
         }
     }
 
-    private List<OptimizationObservation> parseOptimizationInfo(List<String> optimizationInfo, TimeZone timeZone) {
+    private List<OptimizationObservation> parseOptimizationInfo(List<String> optimizationInfo, TimeZone timeZone) throws ConfigValidationException {
         List<OptimizationObservation> retVal = new ArrayList<>();
         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
         format.setTimeZone(timeZone);
         for(String line:optimizationInfo)
         {
-            String[] parts = line.split(",");
+            // The -1 as second parameter ensures that trailing delimiters will not be discarded,
+            // Thus avoiding ArrayIndexOutOfBoundsException when parsing
+            // E.g. "2015-06-02,2,3,,,,"
+            String[] parts = line.split(",",-1); 
             try
             {
                 OptimizationObservation optObs = new OptimizationObservation(
                         format.parse(parts[0]), // Date
-                        Double.parseDouble(parts[1]), // Height
-                        Double.parseDouble(parts[2]), // MSC
-                        Double.parseDouble(parts[4]), // NDF
-                        Double.parseDouble(parts[5]), // INDF
-                        Double.parseDouble(parts[6]), // Raw protein
-                        Double.parseDouble(parts[3]) // FEm
+                        (! parts[1].trim().isEmpty() ? Double.parseDouble(parts[1]) : null), // Height
+                        (! parts[2].trim().isEmpty() ? Double.parseDouble(parts[2]) : null), // MSC
+                        (! parts[4].trim().isEmpty() ? Double.parseDouble(parts[4]) : null), // NDF
+                        (! parts[5].trim().isEmpty() ? Double.parseDouble(parts[5]) : null), // INDF
+                        (! parts[6].trim().isEmpty() ? Double.parseDouble(parts[6]) : null), // Raw protein
+                        (! parts[3].trim().isEmpty() ? Double.parseDouble(parts[3]) : null) // FEm
                 );
+                if(optObs.getHeight() == null && optObs.getMSC() == null)
+                {
+                    throw new ConfigValidationException("Optimization error: Height and/or MSC must be set");
+                }
                retVal.add(optObs);
             }
             catch(ArrayIndexOutOfBoundsException | ParseException ex) {
+                throw new ConfigValidationException("There's something wrong with this line of optimization observations: " + 
+                        line + " . The error is: " + ex.getClass() + ":" + ex.getMessage());
             }
         }
         return retVal;
diff --git a/src/main/java/no/bioforsk/vips/model/roughagenutritionmodel/RoughageNutritionModelImpl.java b/src/main/java/no/bioforsk/vips/model/roughagenutritionmodel/RoughageNutritionModelImpl.java
index 7452eea..c88cfc3 100644
--- a/src/main/java/no/bioforsk/vips/model/roughagenutritionmodel/RoughageNutritionModelImpl.java
+++ b/src/main/java/no/bioforsk/vips/model/roughagenutritionmodel/RoughageNutritionModelImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 NIBIO <http://www.nibio.no/>. 
+ * Copyright (c) 2016 NIBIO <http://www.nibio.no/>. 
  * 
  * This file is part of RoughageNutritionModel.
  * RoughageNutritionModel is free software: you can redistribute it and/or modify
@@ -16,10 +16,10 @@
  * along with RoughageNutritionModel.  If not, see <http://www.nibio.no/licenses/>.
  * 
  */
-
 package no.bioforsk.vips.model.roughagenutritionmodel;
 
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collection;
 import java.util.Collections;
@@ -44,13 +44,11 @@ import org.apache.commons.math.optimization.CostFunction;
 import org.apache.commons.math.optimization.NelderMead;
 import org.apache.commons.math.optimization.PointCostPair;
 
-
-
 /**
- * @copyright 2015 <a href="http://www.nibio.no/">NIBIO</a>
+ * @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a>
  * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
  */
-public class RoughageNutritionModelImpl implements CostFunction{
+public class RoughageNutritionModelImpl implements CostFunction {
 
     // Globale variable som må nullstilles for hver beregning av modellen
     private List<WeatherObservation> nedboerVerdier;
@@ -66,7 +64,7 @@ public class RoughageNutritionModelImpl implements CostFunction{
     private FEmDataMatrix FEmBakgrunnsdataMatrise;
 
     private ResultMatrix resultatMatrise;
-    
+
     private Date datoFoersteSlaatt;
     private Date datoAndreSlaatt;
 
@@ -92,7 +90,7 @@ public class RoughageNutritionModelImpl implements CostFunction{
     private List<OptimizationObservation> observasjoner;
 
     //private Float MSCVedFoersteslaatt = null;
-    private final static Double MSCVedFoersteslaattGrenseverdi = 2.4;
+    private final static Double MSC_VED_FOERSTESLAATT_GRENSEVERDI = 2.4;
 
     // "Konstante" (optimerbare) variable brukt i beregning av utviklingsstadium
     private Double alfa;
@@ -106,18 +104,20 @@ public class RoughageNutritionModelImpl implements CostFunction{
     private Double pINDF;
     private Double FEmJ;
     private Double FEmM;
-    
+
     private Date calculatedDateOfGrowthStart;
-    
+
     private TimeZone timeZone;
-    
+
     /**
      * Hovedmetoden som beregner modellen
+     *
      * @param dailyMeanAirTemperature liste med døgnverdier for luftTemperatur
-     * @param dailyMeanSoilTemperature liste med døgnverdier for jordTemperatur (forbedrer
-     * beregning av vekststart, men er ikke obligatorisk)
+     * @param dailyMeanSoilTemperature liste med døgnverdier for jordTemperatur
+     * (forbedrer beregning av vekststart, men er ikke obligatorisk)
      * @param dailyPrecipitation liste med døgnverdier for nedbør
-     * @param dailyPotentialEvaporation liste med døgnverdier for potensiell fordamping
+     * @param dailyPotentialEvaporation liste med døgnverdier for potensiell
+     * fordamping
      * @param dailyGlobalRadiation liste med døgnverdier for globalstråling
      * @param firstHarvest dato for førsteslått
      * @param secondHarvest dato for andreslått
@@ -128,19 +128,18 @@ public class RoughageNutritionModelImpl implements CostFunction{
      * @throws com.ac.march.ModelExcecutionException
      */
     public synchronized ResultMatrix beregnModell(
-            List<WeatherObservation> dailyMeanAirTemperature, 
-            List<WeatherObservation> dailyMeanSoilTemperature, 
-            List<WeatherObservation> dailyPrecipitation, 
-            List<WeatherObservation> dailyPotentialEvaporation, 
-            List<WeatherObservation> dailyGlobalRadiation, 
-            Date firstHarvest, 
-            Date secondHarvest, 
-            int soilType, 
-            int cloverShare, 
+            List<WeatherObservation> dailyMeanAirTemperature,
+            List<WeatherObservation> dailyMeanSoilTemperature,
+            List<WeatherObservation> dailyPrecipitation,
+            List<WeatherObservation> dailyPotentialEvaporation,
+            List<WeatherObservation> dailyGlobalRadiation,
+            Date firstHarvest,
+            Date secondHarvest,
+            int soilType,
+            int cloverShare,
             List<OptimizationObservation> optimizationObservations,
             TimeZone timeZone
-    ) throws ModelExcecutionException 
-    {
+    ) throws ModelExcecutionException {
         // Initaliserer modellen
         this.luftTemperaturVerdier = dailyMeanAirTemperature;
         this.jordTemperaturVerdier = dailyMeanSoilTemperature;
@@ -157,25 +156,20 @@ public class RoughageNutritionModelImpl implements CostFunction{
         // Valider inputdata
         validateInputData();
 
-
         Calendar cal = Calendar.getInstance(timeZone);
         // Hvis datoAndreSlaatt == null, sett den til 31/12
-        if(this.datoAndreSlaatt == null)
-        {
-            
+        if (this.datoAndreSlaatt == null) {
+
             cal.setTime(this.datoFoersteSlaatt);
             cal.set(Calendar.MONTH, Calendar.DECEMBER);
-            cal.set(Calendar.DATE,31);
+            cal.set(Calendar.DATE, 31);
             this.datoAndreSlaatt = cal.getTime();
         }
 
-        
-
         // Vi har fått inn observasjoner som kan brukes til optimering av interne
         // parametre i modellen. Da gjør vi det først.
         this.observasjoner = optimizationObservations;
-        if(this.observasjoner != null)
-        {
+        if (this.observasjoner != null) {
             try {
                 this.optimerParametre();
             } catch (CostException | ConvergenceException ex) {
@@ -202,9 +196,8 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
         // Siste post på programmet er å justere for målt råprotein etter at alle andre
         // beregninger er kjørt
-        if(this.observasjoner != null)
-        {
-            this.kallibrerRaaprotein();
+        if (this.observasjoner != null) {
+            this.kalibrerRaaprotein();
 
             // Setter verdien av optimerte parametre inn
             this.resultatMatrise.setOptimeringForetatt(true);
@@ -221,96 +214,80 @@ public class RoughageNutritionModelImpl implements CostFunction{
             this.resultatMatrise.setFEmm(this.FEmM);
         }
 
-        
-
         // Returnerer resultatet
         return this.resultatMatrise;
     }
 
-    private double getTTVStart(int jordtype)
-    {
-        switch(jordtype)
-        {
-                case RoughageNutritionModel.JORDTYPE_LEIR:
-                    return 25.6;
-                case RoughageNutritionModel.JORDTYPE_SAND:
-                    return 67.7;
-                case RoughageNutritionModel.JORDTYPE_SILT:
-                    return 124.0;
-                default:
-                    return 0;
+    private double getTTVStart(int jordtype) {
+        switch (jordtype) {
+            case RoughageNutritionModel.JORDTYPE_LEIR:
+                return 25.6;
+            case RoughageNutritionModel.JORDTYPE_SAND:
+                return 67.7;
+            case RoughageNutritionModel.JORDTYPE_SILT:
+                return 124.0;
+            default:
+                return 0;
         }
     }
 
-    private double getLTVStart(int jordtype)
-    {
-        switch(jordtype)
-        {
-                case RoughageNutritionModel.JORDTYPE_LEIR:
-                    return 82.3;
-                case RoughageNutritionModel.JORDTYPE_SAND:
-                    return 46.9;
-                case RoughageNutritionModel.JORDTYPE_SILT:
-                    return 83.3;
-                default:
-                    return 0;
+    private double getLTVStart(int jordtype) {
+        switch (jordtype) {
+            case RoughageNutritionModel.JORDTYPE_LEIR:
+                return 82.3;
+            case RoughageNutritionModel.JORDTYPE_SAND:
+                return 46.9;
+            case RoughageNutritionModel.JORDTYPE_SILT:
+                return 83.3;
+            default:
+                return 0;
         }
     }
 
     /**
      * Beregner NDF, inkl. bakgrunnsdata
+     *
      * @param kloeverandel konstant (Definert i denne klassen)
      * @param jordtype konstant (Definert i denne klassen)
      * @throws com.ac.march.ModelExcecutionException
      */
-    private void beregnNDFBakgrunnsdata(int kloeverandel, int jordtype) throws ModelExcecutionException
-    {
+    private void beregnNDFBakgrunnsdata(int kloeverandel, int jordtype) throws ModelExcecutionException {
         Collections.sort((List) this.luftTemperaturVerdier);
         WeatherObservation temperatur;
-        if(this.NDFBakgrunnsdataMatrise == null)
+        if (this.NDFBakgrunnsdataMatrise == null) {
             this.NDFBakgrunnsdataMatrise = new NDFDataMatrix();
+        }
 
         boolean first = true;
         Date forrigeDato = null;
-        for(Iterator<WeatherObservation> tempI = this.luftTemperaturVerdier.iterator();tempI.hasNext();)
-        {
+        for (Iterator<WeatherObservation> tempI = this.luftTemperaturVerdier.iterator(); tempI.hasNext();) {
             temperatur = tempI.next();
 
             // Beregner TS1
             double TS1;
-            if(first)
-            {
+            if (first) {
                 first = false;
                 TS1 = temperatur.getValue();
-                
-            }
-            else
-            {
-                if(temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0)
-                    TS1 = 0;
-                else if(this.getAvling(forrigeDato, jordtype) > 50)
-                    TS1 = temperatur.getValue() + this.NDFBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, NDFDataMatrix.TS1);
-                else
-                    TS1 = this.NDFBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, NDFDataMatrix.TS1);
 
+            } else if (temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0) {
+                TS1 = 0;
+            } else if (this.getAvling(forrigeDato, jordtype) > 50) {
+                TS1 = temperatur.getValue() + this.NDFBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, NDFDataMatrix.TS1);
+            } else {
+                TS1 = this.NDFBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, NDFDataMatrix.TS1);
             }
             this.NDFBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), NDFDataMatrix.TS1, TS1);
 
             // Beregner NDF
             double NDF;
-            if(temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0)
-            {
+            if (temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0) {
                 NDF = 0.35;
-            }
-            else if(temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) < 0)
-            {
+            } else if (temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) < 0) {
 
-                NDF = (double) (this.getNDm(kloeverandel) / (1 + Math.exp(this.getD(temperatur.getTimeMeasured())/this.getNRm(temperatur.getTimeMeasured(), kloeverandel) - this.getC(temperatur.getTimeMeasured(), kloeverandel) * this.getMSC(temperatur.getTimeMeasured()))));
+                NDF = (double) (this.getNDm(kloeverandel) / (1 + Math.exp(this.getD(temperatur.getTimeMeasured()) / this.getNRm(temperatur.getTimeMeasured(), kloeverandel) - this.getC(temperatur.getTimeMeasured(), kloeverandel) * this.getMSC(temperatur.getTimeMeasured()))));
                 //System.out.println(temperatur.getTimeMeasured().toString() + ": " + NDF + "=" + this.getNDm(kloeverandel) + "/(1+Math.exp(" + this.getD(temperatur.getTimeMeasured()) + "/" + this.getNRm(temperatur.getTimeMeasured(), kloeverandel) + "-" + this.getC(temperatur.getTimeMeasured(),kloeverandel) + "*" + this.getMSC(temperatur.getTimeMeasured())+ ")");
-            }
-            else
-            {
-                NDF = (double) (this.getNDm(kloeverandel) / (1 + Math.exp(this.getD(temperatur.getTimeMeasured())/this.getNRm(temperatur.getTimeMeasured(), kloeverandel) - this.getC(temperatur.getTimeMeasured(), kloeverandel) * TS1)));
+            } else {
+                NDF = (double) (this.getNDm(kloeverandel) / (1 + Math.exp(this.getD(temperatur.getTimeMeasured()) / this.getNRm(temperatur.getTimeMeasured(), kloeverandel) - this.getC(temperatur.getTimeMeasured(), kloeverandel) * TS1)));
             }
 
             // Creating percent points
@@ -318,8 +295,7 @@ public class RoughageNutritionModelImpl implements CostFunction{
             this.NDFBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), NDFDataMatrix.NDF, NDF);
 
             // Lagrer NDF i resultatmatrisen
-            if(this.resultatMatrise != null)
-            {
+            if (this.resultatMatrise != null) {
                 this.resultatMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), ResultMatrix.NDF, NDF);
             }
 
@@ -330,197 +306,179 @@ public class RoughageNutritionModelImpl implements CostFunction{
     }
 
     /**
-     * Returnerer NDF (fiberkonsentrasjon, andel av tørrstoff) for en bestemt dato
+     * Returnerer NDF (fiberkonsentrasjon, andel av tørrstoff) for en bestemt
+     * dato
+     *
      * @param dato
      * @param kloeverandel konstant (Definert i denne klassen)
      * @param jordtype konstant (Definert i denne klassen)
      * @return NDF-verdi for en bestemt dato
      * @throws com.ac.march.ModelExcecutionException
      */
-    protected double getNDF(Date dato, int kloeverandel, int jordtype) throws ModelExcecutionException
-    {
-        if(this.NDFBakgrunnsdataMatrise == null)
+    protected double getNDF(Date dato, int kloeverandel, int jordtype) throws ModelExcecutionException {
+        if (this.NDFBakgrunnsdataMatrise == null) {
             this.beregnNDFBakgrunnsdata(kloeverandel, jordtype);
+        }
         return this.NDFBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, NDFDataMatrix.NDF);
     }
 
     /**
      * Brukes i beregning av NDF
+     *
      * @param kloeverandel konstant
      * @return
      */
-    private double getNDm(int kloeverandel)
-    {
-        if(kloeverandel == RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_LITEN)
-            return 0.75;
-        else if(kloeverandel == RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_MEDIUM)
-            return 0.7;
-        else if(kloeverandel == RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_STOR)
-            return 0.65;
-        else return 0;
+    private double getNDm(int kloeverandel) {
+        switch (kloeverandel) {
+            case RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_LITEN:
+                return 0.75;
+            case RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_MEDIUM:
+                return 0.7;
+            case RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_STOR:
+                return 0.65;
+            default:
+                return 0;
+        }
     }
 
     /**
-     * Brukes i beregning av NDF
-     * 2011-03-01: Endret metoden til å bli avhengig av verdien til MSC ved førsteslått, ihht.
-     * dokumentasjon av 28/2-2011 fra Anne Kjersti Bakken og Anne Langerud<br/>
-     * 2013-11-01: Endret metoden til at MSC-verdi ved førsteslått kun har betydning mellom
-     * første- og andreslått, ikke etter andreslått.
-     * 
-     * @param dato 
+     * Brukes i beregning av NDF 2011-03-01: Endret metoden til å bli avhengig
+     * av verdien til MSC ved førsteslått, ihht. dokumentasjon av 28/2-2011 fra
+     * Anne Kjersti Bakken og Anne Langerud<br/>
+     * 2013-11-01: Endret metoden til at MSC-verdi ved førsteslått kun har
+     * betydning mellom første- og andreslått, ikke etter andreslått.
+     *
+     * @param dato
      * @param kloeverandel konstant
      * @param MSCVedFoersteSlaatt vedien av MSC ved førsteslått
      * @return
      */
-    private double getC(Date dato, int kloeverandel) throws ModelExcecutionException
-    {
-        if(dato.compareTo(this.datoFoersteSlaatt) <= 0)
-        {
-            if(this.cFoersteslaatt != null)
-            {
+    private double getC(Date dato, int kloeverandel) throws ModelExcecutionException {
+        if (dato.compareTo(this.datoFoersteSlaatt) <= 0) {
+            if (this.cFoersteslaatt != null) {
                 return this.cFoersteslaatt; // Optimert verdi
-            }
-            else
-            {
+            } else {
                 //return 1; // Testreturnverdi
                 /* Default ikke-optimerte verdier */
-                if(kloeverandel == RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_LITEN)
-                    return 1.15;
-                else if(kloeverandel == RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_MEDIUM)
-                    return 1.2;
-                else if(kloeverandel == RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_STOR)
-                    return 1.25;
-                else return 0;
-            }
-             
-        }
-        else
-        {
+                switch (kloeverandel) {
+                    case RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_LITEN:
+                        return 1.15;
+                    case RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_MEDIUM:
+                        return 1.2;
+                    case RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_STOR:
+                        return 1.25;
+                    default:
+                        return 0;
+                }
+            }
+
+        } else {
             //return 0.0028; // Default fast returnverdi (skal ikke optimeres for gjenvekst)
-            return this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi && dato.compareTo(this.datoAndreSlaatt) <= 0 ? 0.0019f : 0.0014;
+            return this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI && dato.compareTo(this.datoAndreSlaatt) <= 0 ? 0.0019f : 0.0014;
         }
     }
 
-
     /**
      * Brukes i beregning av NDF
+     *
      * @return
      */
-    private double getNRm(Date dato, int kloeverandel)
-    {
-        if(dato.compareTo(this.datoFoersteSlaatt) <= 0)
-        {
+    private double getNRm(Date dato, int kloeverandel) {
+        if (dato.compareTo(this.datoFoersteSlaatt) <= 0) {
             //return 0.0995839970429309; // Testreturnverdi
-            return this.NRmFoersteslaatt != null ? this.NRmFoersteslaatt : 0.09; 
-        }
-        else
-        {
-            //return 0.45;// Testreturnverdi
-            if(this.NRmAndreslaatt != null)
-            {
-                return this.NRmAndreslaatt;
-            }
-            else
-            {
-                /* Ikke-optimerte default-verdier for gjenvekst*/
-                if(kloeverandel == RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_LITEN)
+            return this.NRmFoersteslaatt != null ? this.NRmFoersteslaatt : 0.09;
+        } else //return 0.45;// Testreturnverdi
+        if (this.NRmAndreslaatt != null) {
+            return this.NRmAndreslaatt;
+        } else {
+            /* Ikke-optimerte default-verdier for gjenvekst*/
+            switch (kloeverandel) {
+                case RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_LITEN:
                     return 0.4;
-                else if(kloeverandel == RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_MEDIUM)
+                case RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_MEDIUM:
                     return 0.42;
-                else if(kloeverandel == RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_STOR)
+                case RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_STOR:
                     return 0.44;
-                else
+                default:
                     return 0;
             }
         }
-        
+
     }
 
     /**
-     * Brukes i beregning av NDF
-     * 2011-03-01: Endret metoden til å bli avhengig av verdien til MSC ved førsteslått, ihht.
-     * dokumentasjon av 28/2-2011 fra Anne Kjersti Bakken og Anne Langerud
-     * 2013-11-01: Endret metoden til at MSC-verdi ved førsteslått kun har betydning mellom
-     * første- og andreslått, ikke etter andreslått.
-     * Brukes i beregning av NDF
+     * Brukes i beregning av NDF 2011-03-01: Endret metoden til å bli avhengig
+     * av verdien til MSC ved førsteslått, ihht. dokumentasjon av 28/2-2011 fra
+     * Anne Kjersti Bakken og Anne Langerud 2013-11-01: Endret metoden til at
+     * MSC-verdi ved førsteslått kun har betydning mellom første- og andreslått,
+     * ikke etter andreslått. Brukes i beregning av NDF
+     *
      * @return
      */
-    private double getD(Date dato) throws ModelExcecutionException
-    {
-        if(dato.compareTo(this.datoFoersteSlaatt) <= 0)
-        {
+    private double getD(Date dato) throws ModelExcecutionException {
+        if (dato.compareTo(this.datoFoersteSlaatt) <= 0) {
             return 0.15;
-        }
-        else
-        {
-            return this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi && dato.compareTo(this.datoAndreSlaatt) <= 0 ? -0.12f : -0.15;
+        } else {
+            return this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI && dato.compareTo(this.datoAndreSlaatt) <= 0 ? -0.12f : -0.15;
         }
     }
 
     /**
-     * 
+     *
      * @param dato
      * @return
      * @throws com.ac.march.ModelExcecutionException
      */
-    protected double getINDF(Date dato) throws ModelExcecutionException
-    {
-       if(this.INDFBakgrunnsdataMatrise == null)
-           this.beregnINDFBakgrunnsdata();
-       return this.INDFBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, INDFDataMatrix.INDF);
+    protected double getINDF(Date dato) throws ModelExcecutionException {
+        if (this.INDFBakgrunnsdataMatrise == null) {
+            this.beregnINDFBakgrunnsdata();
+        }
+        return this.INDFBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, INDFDataMatrix.INDF);
     }
 
     /**
-     * Løper gjennom eksisterende klimadatasett og beregner bakgrunnsdata for INDF, samt
-     * INDF pr. dato. Avhenger av temperaturdata
+     * Løper gjennom eksisterende klimadatasett og beregner bakgrunnsdata for
+     * INDF, samt INDF pr. dato. Avhenger av temperaturdata
+     *
      * @throws com.ac.march.ModelExcecutionException
      */
-    private void beregnINDFBakgrunnsdata() throws ModelExcecutionException
-    {
+    private void beregnINDFBakgrunnsdata() throws ModelExcecutionException {
         Collections.sort((List) this.luftTemperaturVerdier);
         WeatherObservation temperatur;
-        if(this.INDFBakgrunnsdataMatrise == null)
+        if (this.INDFBakgrunnsdataMatrise == null) {
             this.INDFBakgrunnsdataMatrise = new INDFDataMatrix();
+        }
 
         boolean first = true;
         Date forrigeDato = null;
         Integer dagNummer = 1;
-        for(Iterator<WeatherObservation> tempI = this.luftTemperaturVerdier.iterator();tempI.hasNext();)
-        {
+        for (Iterator<WeatherObservation> tempI = this.luftTemperaturVerdier.iterator(); tempI.hasNext();) {
             temperatur = tempI.next();
 
             // Beregner TS1
             double TS1;
-            if(first)
-            {
+            if (first) {
                 first = false;
                 // Improbable, but U never know...
-                if(temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0)
+                if (temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0) {
                     TS1 = 0;
-                else
+                } else {
                     TS1 = temperatur.getValue();
-            }
-            else
-            {
-                if(temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0)
-                    TS1 = 0;
-                else
-                    TS1=temperatur.getValue() + this.INDFBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, INDFDataMatrix.TS1);
+                }
+            } else if (temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0) {
+                TS1 = 0;
+            } else {
+                TS1 = temperatur.getValue() + this.INDFBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, INDFDataMatrix.TS1);
             }
             this.INDFBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), INDFDataMatrix.TS1, TS1);
 
             // Beregner INDF
             double INDF;
-            if(temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0)
-            {
+            if (temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0) {
                 INDF = 0;
-            }
-            else if(temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) < 0)
-            {
-                INDF = this.getIm()/(1+(double)Math.exp(this.getG()/this.getF()-this.getIRm()*TS1));
-            }
-            else
-            {
+            } else if (temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) < 0) {
+                INDF = this.getIm() / (1 + (double) Math.exp(this.getG() / this.getF() - this.getIRm() * TS1));
+            } else {
                 INDF = (this.getBeta() * TS1) + this.getP(temperatur.getTimeMeasured());
             }
 
@@ -529,8 +487,7 @@ public class RoughageNutritionModelImpl implements CostFunction{
             this.INDFBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), INDFDataMatrix.INDF, INDF);
 
             // Lagrer INDF i resultatmatrisen
-            if(this.resultatMatrise != null)
-            {
+            if (this.resultatMatrise != null) {
                 this.resultatMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), ResultMatrix.INDF, INDF);
             }
             forrigeDato = temperatur.getTimeMeasured();
@@ -542,23 +499,21 @@ public class RoughageNutritionModelImpl implements CostFunction{
      * @return faktoren IRm, som brukes til beregning av INDF
      * @see #beregnINDFBakgrunnsdata()
      */
-    private double getIRm()
-    {
-        if(this.IRmFoersteslaatt != null)
+    private double getIRm() {
+        if (this.IRmFoersteslaatt != null) {
             return this.IRmFoersteslaatt;
-        else
+        } else {
             return 0.0085d; // Default-verdi (ikke-optimert)
-        //return 0.00831136805776142; // TEST-verdi
+        }        //return 0.00831136805776142; // TEST-verdi
     }
 
-    
     /**
      * Fom. 2011: Optimeres ikke lenger. Har fast verdi
+     *
      * @return faktoren Beta
      * @see #beregnINDFBakgrunnsdata()
      */
-    private double getBeta()
-    {
+    private double getBeta() {
         return 0.0002d;
         //return this.betaINDF != null ? this.betaINDF : 0.00014;
         //return 0.00014; // Default-verdi (ikke-optimert)
@@ -567,43 +522,43 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
     /**
      * Innført fra sesongen 2011.<br/>
-     * Optimert parameter. Avhenger av MSC ved førsteslått.
-     * 2013-11-01: Endret metoden til at MSC-verdi ved førsteslått kun har betydning mellom
-     * første- og andreslått, ikke etter andreslått.
+     * Optimert parameter. Avhenger av MSC ved førsteslått. 2013-11-01: Endret
+     * metoden til at MSC-verdi ved førsteslått kun har betydning mellom første-
+     * og andreslått, ikke etter andreslått.
+     *
      * @return
      */
-    private double getP(Date dato) throws ModelExcecutionException
-    {
-        return this.pINDF != null ? this.pINDF : this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi && dato.compareTo(this.datoAndreSlaatt) <= 0 ? -0.0166f : -0.0193;
+    private double getP(Date dato) throws ModelExcecutionException {
+        return this.pINDF != null ? this.pINDF : this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI && dato.compareTo(this.datoAndreSlaatt) <= 0 ? -0.0166f : -0.0193;
     }
 
     /**
      * Dette er en fast parameter (skal ikke optimeres)
+     *
      * @return faktoren f, som brukes til beregning av INDF
      * @see #beregnINDFBakgrunnsdata()
      */
-    private double getF()
-    {
+    private double getF() {
         return 0.001;
     }
 
     /**
      * Dette er en fast parameter (skal ikke optimeres)
+     *
      * @return faktoren g, som brukes til beregning av INDF
      * @see #beregnINDFBakgrunnsdata()
      */
-    private double getG()
-    {
+    private double getG() {
         return 0.005;
     }
 
     /**
      * Dette er en fast parameter (skal ikke optimeres)
+     *
      * @return faktoren Im, som brukes til beregning av INDF
      * @see #beregnINDFBakgrunnsdata()
      */
-    private double getIm()
-    {
+    private double getIm() {
         return 0.17;
     }
 
@@ -614,69 +569,61 @@ public class RoughageNutritionModelImpl implements CostFunction{
      * @return beregnet råproteinverdi for den gitte datoen og jordtypen
      * @throws com.ac.march.ModelExcecutionException
      */
-    protected double getRaaprotein(Date dato, int jordtype) throws ModelExcecutionException
-    {
-        double dagensAvlingITonnToerrstoffPrHektar = this.getAvling(dato, jordtype)/100;
-        if(dagensAvlingITonnToerrstoffPrHektar < 1.5)
-        {
+    protected double getRaaprotein(Date dato, int jordtype) throws ModelExcecutionException {
+        double dagensAvlingITonnToerrstoffPrHektar = this.getAvling(dato, jordtype) / 100;
+        if (dagensAvlingITonnToerrstoffPrHektar < 1.5) {
             return 0d;
+        } else {
+            return 6.25 * (1.33 + (double) Math.exp(1.4 - 0.26 * dagensAvlingITonnToerrstoffPrHektar));
         }
-        else
-        {
-            return  6.25 * (1.33 + (double) Math.exp(1.4-0.26*dagensAvlingITonnToerrstoffPrHektar));
-        }
-        
+
     }
 
     /**
-     * 
+     *
      * @param dato
      * @return beregnet FEM (fôrhenhetskonsentrasjon) for gitt dato
      */
-    protected double getFEm(Date dato) throws ModelExcecutionException
-    {
-        if(this.FEmBakgrunnsdataMatrise == null)
+    protected double getFEm(Date dato) throws ModelExcecutionException {
+        if (this.FEmBakgrunnsdataMatrise == null) {
             this.beregnFEmBakgrunnsdata();
+        }
         return this.FEmBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, FEmDataMatrix.FEM);
     }
 
     /**
-     * Beregner bakgrunnsdata for FEM-beregning, og selve FEM-verdien
-     * NB! Fungerer ikke med klimadata som strekker seg over nyttår.
+     * Beregner bakgrunnsdata for FEM-beregning, og selve FEM-verdien NB!
+     * Fungerer ikke med klimadata som strekker seg over nyttår.
+     *
      * @throws com.ac.march.ModelExcecutionException
      */
-    private void beregnFEmBakgrunnsdata() throws ModelExcecutionException
-    {
+    private void beregnFEmBakgrunnsdata() throws ModelExcecutionException {
         // Vi trenger MSC, sjekker om utviklingsdatamatrisen er klar
-        if(this.AIBakgrunnsdataMatrise == null)
+        if (this.AIBakgrunnsdataMatrise == null) {
             this.beregnAIBakgrunnsdata();
+        }
         //GrovforModellFEmBakgrunnsdataMatriseBO
         Collections.sort((List) this.luftTemperaturVerdier);
         WeatherObservation temperatur;
-        if(this.FEmBakgrunnsdataMatrise == null)
+        if (this.FEmBakgrunnsdataMatrise == null) {
             this.FEmBakgrunnsdataMatrise = new FEmDataMatrix();
+        }
 
         boolean first = true;
         Date forrigeDato = null;
-        for(Iterator<WeatherObservation> tempI = this.luftTemperaturVerdier.iterator();tempI.hasNext();)
-        {
+        for (Iterator<WeatherObservation> tempI = this.luftTemperaturVerdier.iterator(); tempI.hasNext();) {
             temperatur = tempI.next();
             //Setter Ts2
             double Ts2;
-            if(first)
-            {
+            if (first) {
                 first = false;
                 Ts2 = temperatur.getValue();
-            }
-            else
-            {
-                if(forrigeDato.compareTo(this.getDatoFoersteSlaatt()) == 0 || forrigeDato.compareTo(this.getDatoAndreSlaatt()) == 0)
-                    Ts2 = 0;
-                else if(forrigeDato.compareTo(this.getDatoFoersteSlaatt()) < 0)
-                    Ts2 = this.FEmBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, FEmDataMatrix.TS2);
-                else
-                    Ts2 = temperatur.getValue() - 6 + this.FEmBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, FEmDataMatrix.TS2);
-
+            } else if (forrigeDato.compareTo(this.getDatoFoersteSlaatt()) == 0 || forrigeDato.compareTo(this.getDatoAndreSlaatt()) == 0) {
+                Ts2 = 0;
+            } else if (forrigeDato.compareTo(this.getDatoFoersteSlaatt()) < 0) {
+                Ts2 = this.FEmBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, FEmDataMatrix.TS2);
+            } else {
+                Ts2 = temperatur.getValue() - 6 + this.FEmBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, FEmDataMatrix.TS2);
             }
             this.FEmBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), FEmDataMatrix.TS2, Ts2);
 
@@ -690,37 +637,25 @@ public class RoughageNutritionModelImpl implements CostFunction{
             int dagNrAndreSlaatt = cal.get(Calendar.DAY_OF_YEAR);
             cal.setTime(temperatur.getTimeMeasured());
             int dagNrTemperaturVerdi = cal.get(Calendar.DAY_OF_YEAR);
-            
-            if(temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0)
-            {
+
+            if (temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0) {
                 FEm = 0;
-            }
-            else 
-            {
-                if(dagNrTemperaturVerdi == dagNrFoersteSlaatt + 1 || dagNrTemperaturVerdi == dagNrAndreSlaatt)
-                {
-                    FEm = 1.1;
-                }
-                else
-                {
-                    double MSC = this.getMSC(temperatur.getTimeMeasured());
-                    if((dagNrTemperaturVerdi > dagNrFoersteSlaatt + 1 || dagNrTemperaturVerdi > dagNrAndreSlaatt) && Ts2 > 100)
-                    {
-                        FEm = this.getK(dagNrTemperaturVerdi > dagNrAndreSlaatt)*Ts2 + this.getM(dagNrTemperaturVerdi > dagNrAndreSlaatt);
-                        //System.out.println(temperatur.getTimeMeasured() + ": this.getK()*Ts2 + this.getM() = " + this.getK() + " * " + Ts2 + " + " + this.getM() + " = " + FEm);
-                    }
-                    else
-                    {
-                        FEm = (this.getH()*MSC*MSC)-(this.getI()*MSC)+this.getJ();
-                        //System.out.println(temperatur.getTimeMeasured() + ": (this.getH()*MSC*MSC)-(this.getI()*MSC)+this.getJ()) = (" + this.getH() + "*" + MSC + "*" + MSC+ ")-(" + this.getI() + "*" + MSC + ")+" + this.getJ() + ") = " + FEm);
-                    }
+            } else if (dagNrTemperaturVerdi == dagNrFoersteSlaatt + 1 || dagNrTemperaturVerdi == dagNrAndreSlaatt) {
+                FEm = 1.1;
+            } else {
+                double MSC = this.getMSC(temperatur.getTimeMeasured());
+                if ((dagNrTemperaturVerdi > dagNrFoersteSlaatt + 1 || dagNrTemperaturVerdi > dagNrAndreSlaatt) && Ts2 > 100) {
+                    FEm = this.getK(dagNrTemperaturVerdi > dagNrAndreSlaatt) * Ts2 + this.getM(dagNrTemperaturVerdi > dagNrAndreSlaatt);
+                    //System.out.println(temperatur.getTimeMeasured() + ": this.getK()*Ts2 + this.getM() = " + this.getK() + " * " + Ts2 + " + " + this.getM() + " = " + FEm);
+                } else {
+                    FEm = (this.getH() * MSC * MSC) - (this.getI() * MSC) + this.getJ();
+                    //System.out.println(temperatur.getTimeMeasured() + ": (this.getH()*MSC*MSC)-(this.getI()*MSC)+this.getJ()) = (" + this.getH() + "*" + MSC + "*" + MSC+ ")-(" + this.getI() + "*" + MSC + ")+" + this.getJ() + ") = " + FEm);
                 }
             }
             this.FEmBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), FEmDataMatrix.FEM, FEm);
 
             // Setter data inn i resultatmatrisen
-            if(this.resultatMatrise != null)
-            {
+            if (this.resultatMatrise != null) {
                 this.resultatMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), ResultMatrix.FEM, FEm);
             }
 
@@ -732,143 +667,123 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
     /**
      * Fast (ikke-optimert) konstant
+     *
      * @return faktor h, som brukes i beregning av FEM i vårvekst
      */
-    private double getH()
-    {
+    private double getH() {
         return -0.0251;
     }
-    
+
     /**
      * Fast (ikke-optimert) konstant
+     *
      * @return faktor i, som brukes i beregning av FEM i vårvekst
      */
-    private double getI()
-    {
+    private double getI() {
         //return 0.0477;
         return 0.06; // 2010-03-04 endret ihht. e-post fra Anne Langerud
     }
 
     /**
-     * I 2009: Fast (ikke-optimert) konstant med verdi 1.2287;
-     * I 2010: Optimert konstant med default-verdi 1.2287f, og beskrankning 1,1574-1,3074.
+     * I 2009: Fast (ikke-optimert) konstant med verdi 1.2287; I 2010: Optimert
+     * konstant med default-verdi 1.2287f, og beskrankning 1,1574-1,3074.
+     *
      * @return faktor j, som brukes i beregning av FEM i vårvekst
      */
-    private double getJ()
-    {
+    private double getJ() {
         return this.FEmJ != null ? this.FEmJ : 1.2287d;
     }
 
     /**
-     * Fast (ikke-optimert) konstant
-     * 2011-03-01: Endret metoden til å bli avhengig av verdien til MSC ved førsteslått, ihht.
-     * dokumentasjon av 28/2-2011 fra Anne Kjersti Bakken og Anne Langerud
-     * 2013-11-01: Endret metoden til at MSC-verdi ved førsteslått kun har betydning mellom
-     * første- og andreslått, ikke etter andreslått.
-     * @param etterAndreSlaatt  Om dette er etter andreslått eller ikke
+     * Fast (ikke-optimert) konstant 2011-03-01: Endret metoden til å bli
+     * avhengig av verdien til MSC ved førsteslått, ihht. dokumentasjon av
+     * 28/2-2011 fra Anne Kjersti Bakken og Anne Langerud 2013-11-01: Endret
+     * metoden til at MSC-verdi ved førsteslått kun har betydning mellom første-
+     * og andreslått, ikke etter andreslått.
+     *
+     * @param etterAndreSlaatt Om dette er etter andreslått eller ikke
      * @return faktor k, som brukes i beregning av FEM i vårvekst
      */
-    private double getK(boolean etterAndreSlaatt) throws ModelExcecutionException
-    {
+    private double getK(boolean etterAndreSlaatt) throws ModelExcecutionException {
         //return -0.0005;
-        return this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi && ! etterAndreSlaatt ? -0.0008f : -0.0006;
+        return this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI && !etterAndreSlaatt ? -0.0008f : -0.0006;
     }
 
     /**
-     * Fast (ikke-optimert) konstant
-     * 2011-03-01: Endret metoden til å bli avhengig av verdien til MSC ved førsteslått, ihht.
-     * dokumentasjon av 28/2-2011 fra Anne Kjersti Bakken og Anne Langerud<br/>
-     * 2013-11-01: Endret metoden til at MSC-verdi ved førsteslått kun har betydning mellom
-     * første- og andreslått, ikke etter andreslått.
+     * Fast (ikke-optimert) konstant 2011-03-01: Endret metoden til å bli
+     * avhengig av verdien til MSC ved førsteslått, ihht. dokumentasjon av
+     * 28/2-2011 fra Anne Kjersti Bakken og Anne Langerud<br/>
+     * 2013-11-01: Endret metoden til at MSC-verdi ved førsteslått kun har
+     * betydning mellom første- og andreslått, ikke etter andreslått.
+     *
      * @param MSCVedFoersteSlaatt vedien av MSC ved førsteslått
      * @return faktor m, som brukes i beregning av FEM i vårvekst
      */
-    private double getM(boolean etterAndreSlaatt) throws ModelExcecutionException
-    {
+    private double getM(boolean etterAndreSlaatt) throws ModelExcecutionException {
         //return 1.0186;
-        double m =  this.FEmM != null ? this.FEmM : this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi && ! etterAndreSlaatt ? 1.1177f : 1.0843;
+        double m = this.FEmM != null ? this.FEmM : this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI && !etterAndreSlaatt ? 1.1177f : 1.0843;
         //System.out.println("m=" + m);
         return m;
     }
 
     /**
-     * Løper gjennom eksisterende klimadatasett og beregner utvikling (MSC_BEREGNET)
-     * Dette trenger man bare å gjøre en gang pr. modellberegning
+     * Løper gjennom eksisterende klimadatasett og beregner utvikling
+     * (MSC_BEREGNET) Dette trenger man bare å gjøre en gang pr. modellberegning
+     *
      * @throws com.ac.march.ModelExcecutionException
      */
-    private void beregnAIBakgrunnsdata() throws ModelExcecutionException
-    {
+    private void beregnAIBakgrunnsdata() throws ModelExcecutionException {
         Collections.sort((List) this.luftTemperaturVerdier);
         WeatherObservation temperatur;
-        if(this.AIBakgrunnsdataMatrise == null)
+        if (this.AIBakgrunnsdataMatrise == null) {
             this.AIBakgrunnsdataMatrise = new AIDataMatrix();
+        }
 
         boolean first = true;
         Date forrigeDato = null;
-        for(Iterator<WeatherObservation> tempI = this.luftTemperaturVerdier.iterator();tempI.hasNext();)
-        {
+        List<WeatherObservation> tempCopy = new ArrayList<>(this.luftTemperaturVerdier);
+        for (Iterator<WeatherObservation> tempI = tempCopy.iterator(); tempI.hasNext();) {
 
             temperatur = tempI.next();
 
             //Setter Ts1
-            if(first)
-            {
+            if (first) {
                 this.AIBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), AIDataMatrix.TS1, temperatur.getValue());
-            }
-            else
-            {
+            } else {
                 this.AIBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), AIDataMatrix.TS1, temperatur.getValue() + this.AIBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, AIDataMatrix.TS1));
             }
 
             // Beregner DVR
             double DVR;
-            if(temperatur.getTimeMeasured().compareTo(this.getVekstStart()) >= 0 && this.AIBakgrunnsdataMatrise.getParamDoubleValueForDate(temperatur.getTimeMeasured(), AIDataMatrix.TS1) > 150)
-            {
+            if (temperatur.getTimeMeasured().compareTo(this.getVekstStart()) >= 0 && this.AIBakgrunnsdataMatrise.getParamDoubleValueForDate(temperatur.getTimeMeasured(), AIDataMatrix.TS1) > 150) {
                 DVR = Math.max(0, this.getAlfa(temperatur.getTimeMeasured()) * (temperatur.getValue() - this.getTb1()));
-            }
-            else
-            {
+            } else {
                 DVR = 0;
             }
             this.AIBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), AIDataMatrix.DVR, DVR);
 
             // Beregner MSC_BEREGNET
             double MSC;
-            if(first)
-            {
+            if (first) {
                 first = false;
                 MSC = 1.35;
-            }
-            else
-            {
-                // Hvis dag == dag for første slått eller dag for andre slått: 1.35
-                if(temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0)
-                {
-                    MSC = 1.35;
-                }
-                else
-                {
-                    if(temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) > 0)
-                    {
-                        MSC = 1.35;
-                    }
-                    else
-                    {
-                        MSC = Math.min(DVR + this.AIBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, AIDataMatrix.MSC_BEREGNET), 3.99999f);
-                    }
-                }
+            } else // Hvis dag == dag for første slått eller dag for andre slått: 1.35
+            if (temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) == 0 || temperatur.getTimeMeasured().compareTo(this.getDatoAndreSlaatt()) == 0) {
+                MSC = 1.35;
+            } else if (temperatur.getTimeMeasured().compareTo(this.getDatoFoersteSlaatt()) > 0) {
+                MSC = 1.35;
+            } else {
+                MSC = Math.min(DVR + this.AIBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, AIDataMatrix.MSC_BEREGNET), 3.99999f);
             }
 
             this.AIBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), AIDataMatrix.MSC_BEREGNET, MSC);
 
             // Lagrer MSC i resultatmatrisen
-            if(this.resultatMatrise != null)
-            {
+            if (this.resultatMatrise != null) {
                 //this.resultatMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), ResultMatrix.DVR, DVR);
                 this.resultatMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), ResultMatrix.MSC_BEREGNET, MSC);
             }
 
-
             //this.AIBakgrunnsdataMatrise.printValuesForDate(temperatur.getTimeMeasured());
             forrigeDato = temperatur.getTimeMeasured();
         }
@@ -877,13 +792,12 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
     /**
      * Brukes i beregning av NDF. Utledet ved beregning av AI (utviklingsindeks)
+     *
      * @param dato
      * @return
      */
-    protected double getMSC(Date dato) throws ModelExcecutionException
-    {
-        if(this.AIBakgrunnsdataMatrise == null)
-        {
+    protected double getMSC(Date dato) throws ModelExcecutionException {
+        if (this.AIBakgrunnsdataMatrise == null) {
             this.beregnAIBakgrunnsdata();
             //System.out.println("Resultatmatrise rett etter getMSC" + this.AIBakgrunnsdataMatrise.toString());
         }
@@ -891,8 +805,7 @@ public class RoughageNutritionModelImpl implements CostFunction{
         return this.AIBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, AIDataMatrix.MSC_BEREGNET);
     }
 
-    protected double getMSCVedFoersteslaatt() throws ModelExcecutionException
-    {
+    protected double getMSCVedFoersteslaatt() throws ModelExcecutionException {
         // Beregn MSC ved førsteslått før optimering.
         // Vi må bruke dagen før førsteslått, hvis ikke er MSC feil
         Calendar cal = Calendar.getInstance(this.timeZone);
@@ -903,24 +816,25 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
     /**
      * Tb1 er en konstant som brukes i beregningen av utvikling (MSC_BEREGNET)
+     *
      * @return verdien av konstanten Tb1
      */
-    private double getTb1()
-    {
+    private double getTb1() {
         return 0.002;
     }
 
     /**
      * Ak er en verdi som inngår i beregningen av AI-indeksen.
+     *
      * @param dato
      * @return
      */
-    private double getAk(Date dato)
-    {
-        if(dato.before(this.getDatoFoersteSlaatt()))
+    private double getAk(Date dato) {
+        if (dato.before(this.getDatoFoersteSlaatt())) {
             return this.getAkFoersteSlaatt();
-        else
+        } else {
             return this.getAkAndreSlaatt();
+        }
     }
 
     private double getAkFoersteSlaatt() {
@@ -930,53 +844,55 @@ public class RoughageNutritionModelImpl implements CostFunction{
     private double getAkAndreSlaatt() {
         return 0.5;
     }
+
     /**
-     * alfa er en optimert konstant som brukes til beregning av DVR, som igjen 
-     * brukes til beregning av utvikling (MSC_BEREGNET), som i sin tur danner grunnlag for beregning av AI
+     * alfa er en optimert konstant som brukes til beregning av DVR, som igjen
+     * brukes til beregning av utvikling (MSC_BEREGNET), som i sin tur danner
+     * grunnlag for beregning av AI
+     *
      * @param dato
      * @return
      */
-    private double getAlfa(Date dato)
-    {
+    private double getAlfa(Date dato) {
         return this.alfa != null ? this.alfa : 0.0028;
     }
 
-    
-
     /**
-     * Cm er en konstant som brukes i beregning av avling
-     * I henhold til e-post fra Anne Langerud pr. 2010-02-26, så skal nå denne
-     * parameteren være = 35 fram til førsteslått, og deretter senkes til 30.
-     * I henhold til e-post fra Anne Langerud pr. 2011-02-28, så skal parameteren
-     * være 25 etter førsteslått
+     * Cm er en konstant som brukes i beregning av avling I henhold til e-post
+     * fra Anne Langerud pr. 2010-02-26, så skal nå denne parameteren være = 35
+     * fram til førsteslått, og deretter senkes til 30. I henhold til e-post fra
+     * Anne Langerud pr. 2011-02-28, så skal parameteren være 25 etter
+     * førsteslått
+     *
      * @return
      */
-    private double getCm(Date dato)
-    {
-        if(dato.compareTo(this.datoFoersteSlaatt) < 0)
+    private double getCm(Date dato) {
+        if (dato.compareTo(this.datoFoersteSlaatt) < 0) {
             return 35.0;
-        else
+        } else {
             return 25.0;
+        }
     }
 
     /**
-     * Rm er en konstant som brukes i beregning av avling. Er ulik i vårvekst (1. slått) og gjenvekst (2. slått)
-     * Er en av de optimerbare parametrene
+     * Rm er en konstant som brukes i beregning av avling. Er ulik i vårvekst
+     * (1. slått) og gjenvekst (2. slått) Er en av de optimerbare parametrene
+     *
      * @param dato
      * @return
      */
-    private double getRm(Date dato)
-    {
-        if(dato.compareTo(this.datoFoersteSlaatt) < 0)
+    private double getRm(Date dato) {
+        if (dato.compareTo(this.datoFoersteSlaatt) < 0) {
             return this.getRmFoersteSlaatt();
-        else
+        } else {
             return this.getRmAndreSlaatt();
+        }
     }
 
-    
     /**
-     * Rm er en konstant som brukes i beregning av avling. Er ulik i vårvekst (1. slått) og gjenvekst (2. slått)
-     * Er en av de optimerbare parametrene
+     * Rm er en konstant som brukes i beregning av avling. Er ulik i vårvekst
+     * (1. slått) og gjenvekst (2. slått) Er en av de optimerbare parametrene
+     *
      * @return
      */
     private double getRmFoersteSlaatt() {
@@ -985,8 +901,9 @@ public class RoughageNutritionModelImpl implements CostFunction{
     }
 
     /**
-     * Rm er en konstant som brukes i beregning av avling. Er ulik i vårvekst (1. slått) og gjenvekst (2. slått)
-     * Er en av de optimerbare parametrene
+     * Rm er en konstant som brukes i beregning av avling. Er ulik i vårvekst
+     * (1. slått) og gjenvekst (2. slått) Er en av de optimerbare parametrene
+     *
      * @return
      */
     private double getRmAndreSlaatt() {
@@ -994,139 +911,129 @@ public class RoughageNutritionModelImpl implements CostFunction{
         //return 0.0510631743660617; // Testverdi som samsvarer med test-regnearket
     }
 
-
     /**
-     * b er en konstant som brukes i beregning av avling. Er ulik i vårvekst (1. slått) og gjenvekst (2. slått)
-     * Er en fast parameter (skal ikke optimeres)
+     * b er en konstant som brukes i beregning av avling. Er ulik i vårvekst (1.
+     * slått) og gjenvekst (2. slått) Er en fast parameter (skal ikke optimeres)
+     *
      * @param dato
      * @return
      */
-    private double getB(Date dato)
-    {
-        if(dato.compareTo(this.datoFoersteSlaatt) < 0)
+    private double getB(Date dato) {
+        if (dato.compareTo(this.datoFoersteSlaatt) < 0) {
             return this.getBFoersteSlaatt();
-        else if(dato.compareTo(this.datoAndreSlaatt) < 0)
+        } else if (dato.compareTo(this.datoAndreSlaatt) < 0) {
             return this.getBMellomFoersteOgAndreSlaatt();
-        else 
+        } else {
             return this.getBAndreSlaatt();
+        }
     }
 
     /**
-     * b er en konstant som brukes i beregning av avling. Er ulik før og etter vårvekst (1. slått) og etter gjenvekst (2. slått) 
-     * Er en fast parameter (skal ikke optimeres)
+     * b er en konstant som brukes i beregning av avling. Er ulik før og etter
+     * vårvekst (1. slått) og etter gjenvekst (2. slått) Er en fast parameter
+     * (skal ikke optimeres)
+     *
      * @return
      */
-    private double getBFoersteSlaatt()
-    {
+    private double getBFoersteSlaatt() {
         return 1.2;
     }
-    
+
     /**
-     * b er en konstant som brukes i beregning av avling. Er ulik før og etter vårvekst (1. slått) og etter gjenvekst (2. slått) 
-     * Er en fast parameter (skal ikke optimeres)
+     * b er en konstant som brukes i beregning av avling. Er ulik før og etter
+     * vårvekst (1. slått) og etter gjenvekst (2. slått) Er en fast parameter
+     * (skal ikke optimeres)
+     *
      * @return
      */
-    
-    private double getBMellomFoersteOgAndreSlaatt()
-    {
+    private double getBMellomFoersteOgAndreSlaatt() {
         return 0.8;
     }
 
     /**
-     * b er en konstant som brukes i beregning av avling. Er ulik før og etter vårvekst (1. slått) og etter gjenvekst (2. slått) 
-     * Er en fast parameter (skal ikke optimeres)
-     * 2012-04-12: Endret fra 0.8f til 0.5f etter henv. fra Anne Langerud pr. 2012-03-06
+     * b er en konstant som brukes i beregning av avling. Er ulik før og etter
+     * vårvekst (1. slått) og etter gjenvekst (2. slått) Er en fast parameter
+     * (skal ikke optimeres) 2012-04-12: Endret fra 0.8f til 0.5f etter henv.
+     * fra Anne Langerud pr. 2012-03-06
+     *
      * @return
      */
-    private double getBAndreSlaatt()
-    {
+    private double getBAndreSlaatt() {
         return 0.5;
     }
 
     /**
-     * 
+     *
      * @param dato
      * @param jordtype
      * @return
      * @throws com.ac.march.ModelExcecutionException
      */
-    protected double getAvling(Date dato, int jordtype) throws ModelExcecutionException
-    {
-        if(this.avlingBakgrunnsdataMatrise == null)
+    protected double getAvling(Date dato, int jordtype) throws ModelExcecutionException {
+        if (this.avlingBakgrunnsdataMatrise == null) {
             this.beregnAvlingBakgrunnsdata(jordtype);
+        }
         return this.avlingBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, YieldDataMatrix.AVLING);
     }
 
     /**
-     * Løper gjennom eksisterende klimadatasett og beregner bakgrunnsdata for avling
+     * Løper gjennom eksisterende klimadatasett og beregner bakgrunnsdata for
+     * avling
+     *
      * @throws com.ac.march.ModelExcecutionException
      */
-    private void beregnAvlingBakgrunnsdata(int jordtype) throws ModelExcecutionException
-    {
+    private void beregnAvlingBakgrunnsdata(int jordtype) throws ModelExcecutionException {
         Collections.sort((List) this.luftTemperaturVerdier);
         Collections.sort((List) this.globalStraalingVerdier);
         WeatherObservation temperatur;
         WeatherObservation straaling;
-        if(this.avlingBakgrunnsdataMatrise == null)
+        if (this.avlingBakgrunnsdataMatrise == null) {
             this.avlingBakgrunnsdataMatrise = new YieldDataMatrix();
+        }
 
         boolean first = true;
         Date forrigeDato = null;
         Integer dagNummer = 1;
+        // Must make a shallow copy to avoid iterator change errors (concurrentModification)
+        List<WeatherObservation> tempCopy = new ArrayList<>(this.luftTemperaturVerdier);
         Iterator<WeatherObservation> straalingI = this.globalStraalingVerdier.iterator();
-        for(Iterator<WeatherObservation> tempI = this.luftTemperaturVerdier.iterator();tempI.hasNext();)
-        {
+        for (Iterator<WeatherObservation> tempI = tempCopy.iterator(); tempI.hasNext();) {
             temperatur = tempI.next();
             straaling = straalingI.next();
             // Beregner Ts1
             Double Ts1;
-            if(first)
-            {
+            if (first) {
                 Ts1 = temperatur.getValue();
-            }
-            else
-            {
-                if(temperatur.getTimeMeasured().compareTo(this.datoFoersteSlaatt) < 0 || temperatur.getTimeMeasured().compareTo(this.datoAndreSlaatt) == 0)
-                {
-                    Ts1 = 0.0;
-                }
-                else
-                    Ts1 = temperatur.getValue() + this.avlingBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, YieldDataMatrix.TS1);
-                //else
-                //    Ts1 = 0;
-            }
+            } else if (temperatur.getTimeMeasured().compareTo(this.datoFoersteSlaatt) < 0 || temperatur.getTimeMeasured().compareTo(this.datoAndreSlaatt) == 0) {
+                Ts1 = 0.0;
+            } else {
+                Ts1 = temperatur.getValue() + this.avlingBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, YieldDataMatrix.TS1);
+            } //else
+            //    Ts1 = 0;
             this.avlingBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), YieldDataMatrix.TS1, Ts1);
-            
+
             // Beregner LAI
             Double LAI;
             Double gaarsdagensAvling = 0.0;
-            if(first)
-            {
+            if (first) {
                 first = false;
                 LAI = 0.0;
-                
-            }
-            else
-            {
+
+            } else {
                 gaarsdagensAvling = this.avlingBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, YieldDataMatrix.AVLING);
-                if(temperatur.getTimeMeasured().compareTo(this.datoFoersteSlaatt) < 0)
-                {
-                    if(gaarsdagensAvling <= 300)
-                    {
+                if (temperatur.getTimeMeasured().compareTo(this.datoFoersteSlaatt) < 0) {
+                    if (gaarsdagensAvling <= 300) {
                         LAI = gaarsdagensAvling / 75;
+                    } else {
+                        LAI = 4 + (gaarsdagensAvling - 300) / 200;
                     }
-                    else
-                    {
-                        LAI = 4+(gaarsdagensAvling-300)/200;
-                    }
-                }
-                else
-                {
+                } else {
                     double gaarsdagensTs1 = this.avlingBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, YieldDataMatrix.TS1);
-                    if(gaarsdagensTs1 <= 350)
+                    if (gaarsdagensTs1 <= 350) {
                         LAI = 0.0114 * gaarsdagensTs1;
-                    else
-                        LAI = 4+(gaarsdagensAvling-300)/200;
+                    } else {
+                        LAI = 4 + (gaarsdagensAvling - 300) / 200;
+                    }
                 }
             }
             this.avlingBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), YieldDataMatrix.LAI, LAI);
@@ -1136,14 +1043,13 @@ public class RoughageNutritionModelImpl implements CostFunction{
             this.avlingBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), YieldDataMatrix.CPOT, Cpot);
 
             // Beregner v og Avling
-            Double v = Cpot * Math.min(this.getTI(temperatur.getTimeMeasured(),temperatur.getValue()), Math.min(this.getSI(temperatur.getTimeMeasured(),straaling.getValue()), this.getVI(temperatur.getTimeMeasured(), jordtype))) * this.getAI(temperatur.getTimeMeasured());
+            Double v = Cpot * Math.min(this.getTI(temperatur.getTimeMeasured(), temperatur.getValue()), Math.min(this.getSI(temperatur.getTimeMeasured(), straaling.getValue()), this.getVI(temperatur.getTimeMeasured(), jordtype))) * this.getAI(temperatur.getTimeMeasured());
             Double avling = temperatur.getTimeMeasured().compareTo(this.datoFoersteSlaatt) == 0 || temperatur.getTimeMeasured().compareTo(this.datoAndreSlaatt) == 0 ? 0f : gaarsdagensAvling + v;
             this.avlingBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), YieldDataMatrix.V, v);
             this.avlingBakgrunnsdataMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), YieldDataMatrix.AVLING, avling);
 
             // Setter data inn i resultatmatrisen, inkl. råprotein
-            if(this.resultatMatrise != null)
-            {
+            if (this.resultatMatrise != null) {
                 //this.resultatMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), ResultMatrix.V, v);
                 this.resultatMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), ResultMatrix.AVLING, avling);
                 this.resultatMatrise.setParamDoubleValueForDate(temperatur.getTimeMeasured(), ResultMatrix.RAAPROTEIN, this.getRaaprotein(temperatur.getTimeMeasured(), jordtype));
@@ -1159,30 +1065,28 @@ public class RoughageNutritionModelImpl implements CostFunction{
      * Løper gjennom eksisterende klimadatasett og beregner aktuell fordamping
      * Dette trenger man bare å gjøre en gang pr. modellberegning
      */
-    private void beregnVIBakgrunnsdata(int jordtype) throws ModelExcecutionException
-    {
+    private void beregnVIBakgrunnsdata(int jordtype) throws ModelExcecutionException {
         Collections.sort((List) this.nedboerVerdier);
         Collections.sort((List) this.potensiellFordampingVerdier);
 
         WeatherObservation nedboer;
         WeatherObservation potensiellFordamping;
-        if(this.VIBakgrunnsdataMatrise == null)
+        if (this.VIBakgrunnsdataMatrise == null) {
             this.VIBakgrunnsdataMatrise = new VIDataMatrix();
-        
+        }
+
         boolean first = true;
         Iterator<WeatherObservation> pfI = this.potensiellFordampingVerdier.iterator();
         Date forrigeDato = null;
-        for(Iterator<WeatherObservation> nedboerI = this.nedboerVerdier.iterator();nedboerI.hasNext();)
-        {
+        for (Iterator<WeatherObservation> nedboerI = this.nedboerVerdier.iterator(); nedboerI.hasNext();) {
             nedboer = nedboerI.next();
             potensiellFordamping = pfI.next();
             // Setter potensiell fordamping i matrisen, for enkelthets skyld
             //System.out.println("EPoriginal=" +potensiellFordamping.getValue());
-            
-            this.VIBakgrunnsdataMatrise.setParamDoubleValueForDate(nedboer.getTimeMeasured(), VIDataMatrix.POTENSIELL_FORDAMPING, (double)potensiellFordamping.getValue());
+
+            this.VIBakgrunnsdataMatrise.setParamDoubleValueForDate(nedboer.getTimeMeasured(), VIDataMatrix.POTENSIELL_FORDAMPING, (double) potensiellFordamping.getValue());
             // Første verdi er samme som potensiell fordamping
-            if(first)
-            {
+            if (first) {
                 first = false;
                 // Setter aktuell fordamping
                 this.VIBakgrunnsdataMatrise.setParamDoubleValueForDate(nedboer.getTimeMeasured(), VIDataMatrix.AKTUELL_FORDAMPING, potensiellFordamping.getValue());
@@ -1190,42 +1094,31 @@ public class RoughageNutritionModelImpl implements CostFunction{
                 this.VIBakgrunnsdataMatrise.setParamDoubleValueForDate(nedboer.getTimeMeasured(), VIDataMatrix.LTV, this.getLTVStart(jordtype));
                 // Setter TTV
                 this.VIBakgrunnsdataMatrise.setParamDoubleValueForDate(nedboer.getTimeMeasured(), VIDataMatrix.TTV, this.getTTVStart(jordtype));
-            }
-            else
-            {
+            } else {
                 // Setter aktuell fordamping
                 Double aktuellFordamping;
                 Double gaarsdagensVann = this.VIBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, VIDataMatrix.LTV) + this.VIBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, VIDataMatrix.TTV);
                 Double gaarsdagensTTV = this.VIBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, VIDataMatrix.TTV);
-                if(gaarsdagensVann <= gaarsdagensTTV)
-                {
+                if (gaarsdagensVann <= gaarsdagensTTV) {
                     aktuellFordamping = potensiellFordamping.getValue() * (gaarsdagensTTV / this.getTTVStart(jordtype));
-                }
-                else
-                {
+                } else {
                     aktuellFordamping = potensiellFordamping.getValue();
                 }
                 this.VIBakgrunnsdataMatrise.setParamDoubleValueForDate(nedboer.getTimeMeasured(), VIDataMatrix.AKTUELL_FORDAMPING, aktuellFordamping);
                 // Setter LTV
                 Double LTV;
-                if(gaarsdagensTTV < this.getTTVStart(jordtype))
-                {
+                if (gaarsdagensTTV < this.getTTVStart(jordtype)) {
                     LTV = 0.0;
-                }
-                else
-                {
+                } else {
                     Double gaarsdagensLTV = this.VIBakgrunnsdataMatrise.getParamDoubleValueForDate(forrigeDato, VIDataMatrix.LTV);
                     LTV = Math.max(0, Math.min(gaarsdagensLTV - aktuellFordamping + nedboer.getValue(), this.getLTVStart(jordtype)));
                 }
                 this.VIBakgrunnsdataMatrise.setParamDoubleValueForDate(nedboer.getTimeMeasured(), VIDataMatrix.LTV, LTV);
                 // Setter TTV
                 Double TTV;
-                if(LTV > 0)
-                {
+                if (LTV > 0) {
                     TTV = gaarsdagensTTV;
-                }
-                else
-                {
+                } else {
                     TTV = Math.max(0, Math.min(gaarsdagensTTV - aktuellFordamping + nedboer.getValue(), this.getTTVStart(jordtype)));
                 }
                 this.VIBakgrunnsdataMatrise.setParamDoubleValueForDate(nedboer.getTimeMeasured(), VIDataMatrix.TTV, TTV);
@@ -1238,84 +1131,74 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
     /**
      * Beregner AI-indeksen
+     *
      * @param dato
      * @return
      * @throws com.ac.march.ModelExcecutionException
      */
-    protected double getAI(Date dato) throws ModelExcecutionException
-    {
-        if(this.AIBakgrunnsdataMatrise == null)
+    protected double getAI(Date dato) throws ModelExcecutionException {
+        if (this.AIBakgrunnsdataMatrise == null) {
             this.beregnAIBakgrunnsdata();
+        }
 
-        if(this.AIBakgrunnsdataMatrise.getParamValueForDate(dato, AIDataMatrix.MSC_REGISTRERT) != null)
-        {
+        if (this.AIBakgrunnsdataMatrise.getParamValueForDate(dato, AIDataMatrix.MSC_REGISTRERT) != null) {
             return 1;
-        }
-        else
-        {
-            //System.out.println("DEBUG " + dato.toString() + " " + this.AIBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, AIDataMatrix.MSC_BEREGNET));
-            if(this.AIBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, AIDataMatrix.MSC_BEREGNET) < 3f)
-            {
-                //System.out.println("Returnerer 1, rett og slett");
-                return 1;
-            }
-            else
-            {
-                //System.out.println("Returnerer resultatet av et regnestykke. AK=" + this.getAk(dato));
-                return Math.pow(1/(this.AIBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, AIDataMatrix.MSC_BEREGNET)/4)-1, this.getAk(dato));
-            }
+        } else //System.out.println("DEBUG " + dato.toString() + " " + this.AIBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, AIDataMatrix.MSC_BEREGNET));
+        if (this.AIBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, AIDataMatrix.MSC_BEREGNET) < 3f) {
+            //System.out.println("Returnerer 1, rett og slett");
+            return 1;
+        } else {
+            //System.out.println("Returnerer resultatet av et regnestykke. AK=" + this.getAk(dato));
+            return Math.pow(1 / (this.AIBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, AIDataMatrix.MSC_BEREGNET) / 4) - 1, this.getAk(dato));
         }
     }
 
     /**
-     * Beregner VI-indeksen.
-     * Forutsetninger: Vekststart er beregnet
+     * Beregner VI-indeksen. Forutsetninger: Vekststart er beregnet
+     *
      * @param dato
      * @param jordtype
      * @return
      */
-    protected double getVI(Date dato, int jordtype) throws ModelExcecutionException
-    {
-        if(dato.compareTo(this.getVekstStart()) < 0)
+    protected double getVI(Date dato, int jordtype) throws ModelExcecutionException {
+        if (dato.compareTo(this.getVekstStart()) < 0) {
             return 0;
-        
-        if(this.VIBakgrunnsdataMatrise == null)
+        }
+
+        if (this.VIBakgrunnsdataMatrise == null) {
             this.beregnVIBakgrunnsdata(jordtype);
+        }
 
         double potensiellFordamping = this.VIBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, VIDataMatrix.POTENSIELL_FORDAMPING);
-        
-        if(potensiellFordamping == 0)
+
+        if (potensiellFordamping == 0) {
             return 1;
-        else
+        } else {
             return this.VIBakgrunnsdataMatrise.getParamDoubleValueForDate(dato, VIDataMatrix.AKTUELL_FORDAMPING) / potensiellFordamping;
+        }
     }
 
-
     /**
      *
      * @param temperatur for et døgn, i grader Celcius
      * @return beregnet indeks TI
      */
-    protected double getTI(Date dato, double temperatur) throws ModelExcecutionException
-    {
-        if(dato.compareTo(this.getVekstStart()) < 0)
+    protected double getTI(Date dato, double temperatur) throws ModelExcecutionException {
+        if (dato.compareTo(this.getVekstStart()) < 0) {
             return 0d;
+        }
         int k_t = 2;
         int Tm_1 = 17;
         double T0_1 = 0.05;
 
-        if(Math.abs(temperatur - Tm_1) >= (Tm_1 - T0_1))
+        if (Math.abs(temperatur - Tm_1) >= (Tm_1 - T0_1)) {
             return 0;
-        else
-        {
+        } else {
             double x = Math.abs(temperatur - Tm_1) / (Tm_1 - T0_1);
-            if(x < 0.5)
-            {
-                return 1-(Math.pow(2*x,k_t)/2);
-            }
-            else
-            {
-                return Math.pow(2*(1-x),k_t)/2;
+            if (x < 0.5) {
+                return 1 - (Math.pow(2 * x, k_t) / 2);
+            } else {
+                return Math.pow(2 * (1 - x), k_t) / 2;
             }
         }
     }
@@ -1325,144 +1208,130 @@ public class RoughageNutritionModelImpl implements CostFunction{
      * @param globalStraaling for et døgn, angitt i MJ/kvm/dag
      * @return beregnet indeks SI
      */
-    protected double getSI(Date dato, double globalStraaling)  throws ModelExcecutionException
-    {
-        if(dato.compareTo(this.getVekstStart()) < 0)
+    protected double getSI(Date dato, double globalStraaling) throws ModelExcecutionException {
+        if (dato.compareTo(this.getVekstStart()) < 0) {
             return 0d;
+        }
         int rk = 3;
         int r_mxp = 25;
-        return (1 - Math.exp((-rk * globalStraaling)/r_mxp)/(1-Math.exp(-rk)));
+        return (1 - Math.exp((-rk * globalStraaling) / r_mxp) / (1 - Math.exp(-rk)));
     }
 
-
     /**
-     * 
-     * @return
-     * @throws com.ac.march.ModelExcecutionException
+     *
+     * @return @throws com.ac.march.ModelExcecutionException
      */
-    protected Date getVekstStart() throws ModelExcecutionException
-    {
-        if(this.calculatedDateOfGrowthStart == null)
-        {
+    protected Date getVekstStart() throws ModelExcecutionException {
+        if (this.calculatedDateOfGrowthStart == null) {
             this.calculatedDateOfGrowthStart = this.getVekstStart(this.luftTemperaturVerdier, this.jordTemperaturVerdier);
         }
         return this.calculatedDateOfGrowthStart;
     }
 
     /**
-     * Beregner datoen hvor vekststart antas å inntreffe. Vekststart antas å inntreffe
-     * etter tre påfølgende femdøgnsmiddel av temperatur > 5 grader Celcius. Dvs. datoen blir
-     * den tredje av disse påfølgende femdøgnsmiddel.
-     * Endring 2013-10-06: Hvis vi har jordtemperatur tilgjengelig, så må det samtidig
-     * ha vært i gjennomsnitt > 1 grader Celcius disse tre femdøgnsperiodene (siste 7 dager).
+     * Beregner datoen hvor vekststart antas å inntreffe. Vekststart antas å
+     * inntreffe etter tre påfølgende femdøgnsmiddel av temperatur > 5 grader
+     * Celcius. Dvs. datoen blir den tredje av disse påfølgende femdøgnsmiddel.
+     * Endring 2013-10-06: Hvis vi har jordtemperatur tilgjengelig, så må det
+     * samtidig ha vært i gjennomsnitt > 1 grader Celcius disse tre
+     * femdøgnsperiodene (siste 7 dager).
      *
      * @param dognMiddelLuftTemperatur
-     * @param jordTemperatur 
-     * @return Dato for vekststart, eller null hvis ikke betingelsene for vekstart er oppfylt i de gitte klimadata
+     * @param jordTemperatur
+     * @return Dato for vekststart, eller null hvis ikke betingelsene for
+     * vekstart er oppfylt i de gitte klimadata
      */
-    protected Date getVekstStart(Collection dognMiddelLuftTemperatur, Collection jordTemperatur) throws ModelExcecutionException
-    {
+    protected Date getVekstStart(Collection dognMiddelLuftTemperatur, Collection jordTemperatur) throws ModelExcecutionException {
         double lufttempTerskel = 5.0;
         double jordtempTerskel = 1.0;
         Collections.sort((List) dognMiddelLuftTemperatur);
         LinkedBlockingQueue<WeatherObservation> siste5DoegnVerdier = new LinkedBlockingQueue(5);
-        LinkedBlockingQueue<WeatherObservation> siste7DoegnVerdierJordtemp = (jordTemperatur != null && ! jordTemperatur.isEmpty()) ? new LinkedBlockingQueue(7) : null;
+        LinkedBlockingQueue<WeatherObservation> siste7DoegnVerdierJordtemp = (jordTemperatur != null && !jordTemperatur.isEmpty()) ? new LinkedBlockingQueue(7) : null;
         double sumSiste5DoegnVerdier = 0;
         boolean erAlleredeFull;
         int antallPaafoelgende5DoegnsMiddelOverTerskel = 0;
-        WeatherObservation eldsteDoegnverdi = null;
+        WeatherObservation eldsteDoegnverdi;
         WeatherObservation forrigeDoegnverdi = null;
         Calendar cal = Calendar.getInstance(this.timeZone);
         // Må ha minst sju jordtemperaturverdier
         Iterator<WeatherObservation> ji = (jordTemperatur != null && jordTemperatur.size() >= 7) ? jordTemperatur.iterator() : null;
-        for(Iterator<WeatherObservation> i= dognMiddelLuftTemperatur.iterator();i.hasNext();)
-        {
+        for (Iterator<WeatherObservation> i = dognMiddelLuftTemperatur.iterator(); i.hasNext();) {
             WeatherObservation doegnVerdi = i.next();
             WeatherObservation doegnVerdiJordtemp = (ji != null && ji.hasNext() ? ji.next() : null);
 
             // Validering
             // Verdiens parameterkode må være TM eller TMf
-            if(! (doegnVerdi.getElementMeasurementTypeId().equals("TM") || doegnVerdi.getElementMeasurementTypeId().equals("TMf") || doegnVerdi.getElementMeasurementTypeId().equals("TM1,60")))
+            if (!(doegnVerdi.getElementMeasurementTypeId().equals("TM") || doegnVerdi.getElementMeasurementTypeId().equals("TMf") || doegnVerdi.getElementMeasurementTypeId().equals("TM1,60"))) {
                 throw new ModelExcecutionException("Feil parameterKode. Fant " + doegnVerdi.getElementMeasurementTypeId() + ", forventet TM, TMf eller TM1,60");
+            }
             // Verdiens parameterkode må være TJM10
-            if(doegnVerdiJordtemp != null && !(doegnVerdiJordtemp.getElementMeasurementTypeId().equals("TJM10")))
-            {
+            if (doegnVerdiJordtemp != null && !(doegnVerdiJordtemp.getElementMeasurementTypeId().equals("TJM10"))) {
                 throw new ModelExcecutionException("Feil parameterKode. Fant " + doegnVerdi.getElementMeasurementTypeId() + ", forventet TJM10");
             }
             // Må være akkurat 1 døgn senere enn forrige verdi
-            if(forrigeDoegnverdi !=null)
-            {
+            if (forrigeDoegnverdi != null) {
                 cal.setTime(forrigeDoegnverdi.getTimeMeasured());
                 cal.add(Calendar.DATE, 1);
                 // Temperatures (air and optionally soil) must have the same timestamp
-                if(! cal.getTime().equals(doegnVerdi.getTimeMeasured()) || (doegnVerdiJordtemp != null  && ! cal.getTime().equals(doegnVerdiJordtemp.getTimeMeasured())))
+                if (!cal.getTime().equals(doegnVerdi.getTimeMeasured()) || (doegnVerdiJordtemp != null && !cal.getTime().equals(doegnVerdiJordtemp.getTimeMeasured()))) {
                     throw new ModelExcecutionException("Manglende klimadata mellom " + forrigeDoegnverdi.getTimeMeasured().toString() + " og " + doegnVerdi.getTimeMeasured().toString());
+                }
             }
 
-
             sumSiste5DoegnVerdier += doegnVerdi.getValue();
             // If first time filled or already full, we may start calculating
-            erAlleredeFull = ! siste5DoegnVerdier.offer(doegnVerdi);
+            erAlleredeFull = !siste5DoegnVerdier.offer(doegnVerdi);
             // Makes sure the last 3 soil temps are kept
-            if(doegnVerdiJordtemp != null)
-            {
-                if(!siste7DoegnVerdierJordtemp.offer(doegnVerdiJordtemp))
-                {
+            if (doegnVerdiJordtemp != null) {
+                if (!siste7DoegnVerdierJordtemp.offer(doegnVerdiJordtemp)) {
                     siste7DoegnVerdierJordtemp.poll();
                     siste7DoegnVerdierJordtemp.offer(doegnVerdiJordtemp);
                 }
             }
-            
+
             //System.out.println("[RoughageNutritionModel/getVekststart] siste5DoegnVerdier.remainingCapacity() = " + siste5DoegnVerdier.remainingCapacity());
-            if(erAlleredeFull || siste5DoegnVerdier.remainingCapacity() == 0)
-            {
+            if (erAlleredeFull || siste5DoegnVerdier.remainingCapacity() == 0) {
                 // First time we calculate average
-                if(!erAlleredeFull)
-                {
-                    if(sumSiste5DoegnVerdier / 5 > lufttempTerskel)
-                       antallPaafoelgende5DoegnsMiddelOverTerskel++;
-                    else
+                if (!erAlleredeFull) {
+                    if (sumSiste5DoegnVerdier / 5 > lufttempTerskel) {
+                        antallPaafoelgende5DoegnsMiddelOverTerskel++;
+                    } else {
                         antallPaafoelgende5DoegnsMiddelOverTerskel = 0;
-                }
-                // Average's been calculated before, so we need to extract the oldest value
-                else
-                {
+                    }
+                } // Average's been calculated before, so we need to extract the oldest value
+                else {
                     // We need to extract the head of the queue, and add the most current value
                     eldsteDoegnverdi = siste5DoegnVerdier.poll();
-                    if(!siste5DoegnVerdier.offer(doegnVerdi))
+                    if (!siste5DoegnVerdier.offer(doegnVerdi)) {
                         throw new ModelExcecutionException("Siste5DoegnVerdier er full, feil i logikken");
+                    }
                     // We then need to extract the value of the head from the sum
                     sumSiste5DoegnVerdier -= eldsteDoegnverdi.getValue();
-                    if(sumSiste5DoegnVerdier / 5 > lufttempTerskel)
-                       antallPaafoelgende5DoegnsMiddelOverTerskel++;
-                    else
+                    if (sumSiste5DoegnVerdier / 5 > lufttempTerskel) {
+                        antallPaafoelgende5DoegnsMiddelOverTerskel++;
+                    } else {
                         antallPaafoelgende5DoegnsMiddelOverTerskel = 0;
+                    }
                 }
 
                 //System.out.println("[RoughageNutritionModel/getVekststart] dato= " + doegnVerdi.getTimeMeasured().toString() + ", sumSiste5DoegnVerdier / 5 = " + (sumSiste5DoegnVerdier / 5));
-                if(antallPaafoelgende5DoegnsMiddelOverTerskel == 3)
-                {
+                if (antallPaafoelgende5DoegnsMiddelOverTerskel == 3) {
                     // If soil temps not provided, use only air temp
-                    if(doegnVerdiJordtemp == null)
-                    {
+                    if (doegnVerdiJordtemp == null) {
                         //System.out.println("Ingen jordtemp! Vekststart=" + doegnVerdi.getTimeMeasured());
                         return doegnVerdi.getTimeMeasured();
-                    }
-                    else
-                    {
+                    } else {
                         // Calculate mean of last 8 days (3 5-day periods, right?)
                         double soilTempSum = 0;
-                        for(WeatherObservation soilTemp : siste7DoegnVerdierJordtemp)
-                        {
+                        for (WeatherObservation soilTemp : siste7DoegnVerdierJordtemp) {
                             soilTempSum += soilTemp.getValue();
                         }
-                        if(soilTempSum/siste7DoegnVerdierJordtemp.size() > jordtempTerskel)
-                        {
+                        if (soilTempSum / siste7DoegnVerdierJordtemp.size() > jordtempTerskel) {
                             //System.out.println("Jordtempsnitt=" + soilTempSum/siste8DoegnVerdierJordtemp.size());
                             return doegnVerdi.getTimeMeasured();
                         }
                     }
-                    
+
                 }
             }
             //System.out.println("[RoughageNutritionModel/getVekststart] ");
@@ -1556,151 +1425,147 @@ public class RoughageNutritionModelImpl implements CostFunction{
     }
 
     /**
-     * Sjekker at inputdata henger på greip og kan brukes til modellberegning<br/>
+     * Sjekker at inputdata henger på greip og kan brukes til
+     * modellberegning<br/>
      * Krav til data:
      * <ul>
-     * <li>Alle klimadata må være satt og sammenhengende, og det må være minst 10 verdier</li>
+     * <li>Alle klimadata må være satt og sammenhengende, og det må være minst
+     * 10 verdier</li>
      * <li>Klimadata må ikke spenne over årsskifte</li>
-     * <li>Datasett for ulike klimaparametre må ha samme start- og sluttdato</li>
+     * <li>Datasett for ulike klimaparametre må ha samme start- og
+     * sluttdato</li>
      * <li>Jordtype må være satt, og ha en lovlig verdi</li>
      * <li>Kløverandel i eng må være satt, og ha en lovlig verdi</li>
      * </ul>
+     *
      * @throws com.ac.march.ModelExcecutionException dersom validering feiler
      */
-    private void validateInputData() throws ModelExcecutionException
-    {
+    private void validateInputData() throws ModelExcecutionException {
         // Alle klimadata (unntatt jordtemperatur) må være satt og sammenhengende
         // Minst 10 verdier
         // Må ikke spenne over årsskifte
         // Må ha samme start- og sluttdato
         Date foersteDato = null;
         Date sisteDato = null;
-        
-        try
-        {
+
+        try {
 
             // Sorterer klimadata først
-            Collections.sort((List)this.luftTemperaturVerdier);
-            Collections.sort((List)this.nedboerVerdier);
-            Collections.sort((List)this.potensiellFordampingVerdier);
-            Collections.sort((List)this.globalStraalingVerdier);
-            
+            Collections.sort((List) this.luftTemperaturVerdier);
+            Collections.sort((List) this.nedboerVerdier);
+            Collections.sort((List) this.potensiellFordampingVerdier);
+            Collections.sort((List) this.globalStraalingVerdier);
 
             // Itererer samtlige samtidig
             Iterator<WeatherObservation> luftTempI = this.luftTemperaturVerdier.iterator();
             Iterator<WeatherObservation> nedboerI = this.nedboerVerdier.iterator();
             Iterator<WeatherObservation> potFordI = this.potensiellFordampingVerdier.iterator();
             Iterator<WeatherObservation> straalingI = this.globalStraalingVerdier.iterator();
-            
+
             Iterator<WeatherObservation> jordTempI = null;
-            if(this.jordTemperaturVerdier != null && ! this.jordTemperaturVerdier.isEmpty())
-            {
-                Collections.sort((List)this.jordTemperaturVerdier);
+            if (this.jordTemperaturVerdier != null && !this.jordTemperaturVerdier.isEmpty()) {
+                Collections.sort((List) this.jordTemperaturVerdier);
                 jordTempI = this.jordTemperaturVerdier.iterator();
             }
-            
- 
+
             Date forrigeDato = null;
             boolean first = true;
             int counter = 0;
             Calendar cal = Calendar.getInstance(this.timeZone);
-            int dagensDagIAaret = -1;
-            for(;luftTempI.hasNext();)
-            {
+            int dagensDagIAaret;
+            for (; luftTempI.hasNext();) {
                 WeatherObservation luftTemperatur = luftTempI.next();
                 WeatherObservation nedboer = nedboerI.next();
                 WeatherObservation potFord = potFordI.next();
                 WeatherObservation straaling = straalingI.next();
-                WeatherObservation jordTemperatur = (jordTempI != null && jordTempI.hasNext()) ? jordTempI.next():null;
+                WeatherObservation jordTemperatur = (jordTempI != null && jordTempI.hasNext()) ? jordTempI.next() : null;
 
                 Date dagensDato = luftTemperatur.getTimeMeasured();
 
-                if(first)
-                {
+                if (first) {
                     first = false;
                     foersteDato = dagensDato;
-                }
-                else
-                {
+                } else {
                     cal.setTime(dagensDato);
                     dagensDagIAaret = cal.get(Calendar.DAY_OF_YEAR);
                     cal.setTime(forrigeDato);
-                    if(dagensDagIAaret - cal.get(Calendar.DAY_OF_YEAR) != 1)
+                    if (dagensDagIAaret - cal.get(Calendar.DAY_OF_YEAR) != 1) {
                         throw new ModelExcecutionException("Feil ved klimadata: Temperaturparameteren har hull i datasettet rundt " + dagensDato);
+                    }
                 }
 
                 // Datoer må stemme overens.
-                if(dagensDato.compareTo(nedboer.getTimeMeasured()) != 0 || dagensDato.compareTo(potFord.getTimeMeasured()) != 0 || dagensDato.compareTo(straaling.getTimeMeasured()) !=0)
-                    throw new ModelExcecutionException("Feil ved klimadata: Minst en av parametrene har hull i datasettet. Dette har applikasjonen kommet fram til ved &aring; " +
-                            "g&aring; gjennom klimaparametrene en verdi av gangen og sammenlikne datoer. Den parameteren som har avvikende dato, og da fram i tid, er den " +
-                            "som har hull i datasettet. <br/>" +
-                            "<ul><li>Temperaturlinjas dato er " + dagensDato.toString() + "</li><li>Nedb&oslash;rlinjas dato er " + nedboer.getTimeMeasured().toString() +
-                            "</li><li>Potensiell fordampinglinjas dato er  " + potFord.getTimeMeasured().toString() + "</li><li>Globalstr&aring;lingslinjas dato er " + straaling.getTimeMeasured().toString() + "</li></ul>");
-
+                if (dagensDato.compareTo(nedboer.getTimeMeasured()) != 0 || dagensDato.compareTo(potFord.getTimeMeasured()) != 0 || dagensDato.compareTo(straaling.getTimeMeasured()) != 0) {
+                    throw new ModelExcecutionException("Feil ved klimadata: Minst en av parametrene har hull i datasettet. Dette har applikasjonen kommet fram til ved &aring; "
+                            + "g&aring; gjennom klimaparametrene en verdi av gangen og sammenlikne datoer. Den parameteren som har avvikende dato, og da fram i tid, er den "
+                            + "som har hull i datasettet. <br/>"
+                            + "<ul><li>Temperaturlinjas dato er " + dagensDato.toString() + "</li><li>Nedb&oslash;rlinjas dato er " + nedboer.getTimeMeasured().toString()
+                            + "</li><li>Potensiell fordampinglinjas dato er  " + potFord.getTimeMeasured().toString() + "</li><li>Globalstr&aring;lingslinjas dato er " + straaling.getTimeMeasured().toString() + "</li></ul>");
+                }
 
-                if(jordTemperatur != null && dagensDato.compareTo(jordTemperatur.getTimeMeasured()) != 0)
-                {
+                if (jordTemperatur != null && dagensDato.compareTo(jordTemperatur.getTimeMeasured()) != 0) {
                     throw new ModelExcecutionException("Feil ved klimadata: Jordemperatur har hull i datasettet, omkring dato " + dagensDato);
                 }
-                
+
                 forrigeDato = dagensDato;
                 counter++;
             }
             sisteDato = forrigeDato;
-            if(counter < 10 || foersteDato == null || sisteDato == null)
+            if (counter < 10 || foersteDato == null || sisteDato == null) {
                 throw new ModelExcecutionException("Feil ved klimadata: For få klimadata.");
+            }
 
             // Sjekker om serien spenner over et årsskifte
             cal.setTime(foersteDato);
             int startAar = cal.get(Calendar.YEAR);
             cal.setTime(sisteDato);
             int sluttAar = cal.get(Calendar.YEAR);
-            if(sluttAar - startAar != 0)
+            if (sluttAar - startAar != 0) {
                 throw new ModelExcecutionException("Feil ved klimadata: Spenner over et årsskifte.");
+            }
 
-        }
-        catch(NoSuchElementException nee)
-        {
-            throw new ModelExcecutionException(   "Feil ved klimadata: Ulikt antall observasjoner for de ulike parametrene. " +
-                                        "Antall temperaturdata: " + this.luftTemperaturVerdier.size() +
-                                        ", antall nedb&oslash;rdata: " + this.nedboerVerdier.size() +
-                                        ", antall fordampingsdata: " + this.potensiellFordampingVerdier.size() +
-                                        ", antall str&aring;lingsdata: " + this.globalStraalingVerdier.size());
-        }
-        catch(NullPointerException npe)
-        {
-            npe.printStackTrace();
+        } catch (NoSuchElementException nee) {
+            throw new ModelExcecutionException("Feil ved klimadata: Ulikt antall observasjoner for de ulike parametrene. "
+                    + "Antall temperaturdata: " + this.luftTemperaturVerdier.size()
+                    + ", antall nedb&oslash;rdata: " + this.nedboerVerdier.size()
+                    + ", antall fordampingsdata: " + this.potensiellFordampingVerdier.size()
+                    + ", antall str&aring;lingsdata: " + this.globalStraalingVerdier.size());
+        } catch (NullPointerException npe) {
+            //npe.printStackTrace();
             throw new ModelExcecutionException("Data mangler.");
         }
-        
 
         SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
         format.setTimeZone(timeZone);
 
         // Dato for første- og andreslått må være innenfor klimadataenes spenn
-        if(this.datoFoersteSlaatt == null)
+        if (this.datoFoersteSlaatt == null) {
             throw new ModelExcecutionException("Feil: Mangler dato for førsteslått");
-        else if(this.datoFoersteSlaatt.compareTo(foersteDato) < 0 || this.datoFoersteSlaatt.compareTo(sisteDato) > 0)
+        } else if (this.datoFoersteSlaatt.compareTo(foersteDato) < 0 || this.datoFoersteSlaatt.compareTo(sisteDato) > 0) {
             throw new ModelExcecutionException("Feil: Dato for førsteslått(" + format.format(this.datoFoersteSlaatt) + ") er utenfor tidsperioden for klimadata(" + format.format(foersteDato) + "-" + format.format(sisteDato) + ")");
+        }
 
-        if(this.datoAndreSlaatt != null && (this.datoAndreSlaatt.compareTo(foersteDato) < 0 || this.datoAndreSlaatt.compareTo(sisteDato) > 0 || this.datoAndreSlaatt.compareTo(this.datoFoersteSlaatt) < 0))
+        if (this.datoAndreSlaatt != null && (this.datoAndreSlaatt.compareTo(foersteDato) < 0 || this.datoAndreSlaatt.compareTo(sisteDato) > 0 || this.datoAndreSlaatt.compareTo(this.datoFoersteSlaatt) < 0)) {
             throw new ModelExcecutionException("Feil: Dato for andreslått(" + format.format(this.datoAndreSlaatt) + ") er enten utenfor tidsperioden for klimadata(" + format.format(foersteDato) + "-" + format.format(sisteDato) + ") ELLER før dato for førsteslått(" + format.format(this.datoFoersteSlaatt) + ")");
+        }
 
         // Sjekker jordtype og engsammensetning
-        if(this.jordtype != RoughageNutritionModel.JORDTYPE_LEIR && this.jordtype != RoughageNutritionModel.JORDTYPE_SAND && this.jordtype != RoughageNutritionModel.JORDTYPE_SILT)
+        if (this.jordtype != RoughageNutritionModel.JORDTYPE_LEIR && this.jordtype != RoughageNutritionModel.JORDTYPE_SAND && this.jordtype != RoughageNutritionModel.JORDTYPE_SILT) {
             throw new ModelExcecutionException("Feil: Ugyldig verdi for jordtype");
-        if(this.kloeverandel != RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_LITEN && this.kloeverandel != RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_MEDIUM && this.kloeverandel != RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_STOR)
+        }
+        if (this.kloeverandel != RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_LITEN && this.kloeverandel != RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_MEDIUM && this.kloeverandel != RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_STOR) {
             throw new ModelExcecutionException("Feil: Ugyldig verdi for kløverandel");
+        }
 
     }
 
     /**
      * Sjekker at inputdata for optimering av parametre henger på greip og kan
      * brukes til modellberegning.
+     *
      * @throws com.ac.march.ModelExcecutionException dersom validering feiler
      */
-    private void validateOptimizationInputData() throws ModelExcecutionException
-    {
+    private void validateOptimizationInputData() throws ModelExcecutionException {
 
     }
 
@@ -1709,8 +1574,7 @@ public class RoughageNutritionModelImpl implements CostFunction{
      * @return De definerte jordtypene, med id og navn
      */
     public HashMap getTilgjengeligeJordtyper() {
-        if(this.tilgjengeligeJordtyper == null)
-        {
+        if (this.tilgjengeligeJordtyper == null) {
             this.tilgjengeligeJordtyper = new HashMap();
             this.tilgjengeligeJordtyper.put(RoughageNutritionModel.JORDTYPE_LEIR, "Leire");
             this.tilgjengeligeJordtyper.put(RoughageNutritionModel.JORDTYPE_SAND, "Sand");
@@ -1721,11 +1585,11 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
     /**
      * De definerte kløverandelene, med id og navn
+     *
      * @return
      */
     public HashMap getTilgjengeligeKloeverandeler() {
-        if(this.tilgjengeligeKloeverandeler == null)
-        {
+        if (this.tilgjengeligeKloeverandeler == null) {
             this.tilgjengeligeKloeverandeler = new HashMap();
             this.tilgjengeligeKloeverandeler.put(RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_LITEN, "Liten kløverandel (inntil 5%)");
             this.tilgjengeligeKloeverandeler.put(RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_MEDIUM, "Middels kløverandel (5%-20%)");
@@ -1734,14 +1598,14 @@ public class RoughageNutritionModelImpl implements CostFunction{
         return this.tilgjengeligeKloeverandeler;
     }
 
-    
     /**
      * Tar hånd om all optimeringen<br/>
      * Bruker Nelder-Mead-metoden for ikke-lineær optimering.
-     * @see http://commons.apache.org/math/api-1.2/org/apache/commons/math/optimization/NelderMead.html
+     *
+     * @see
+     * http://commons.apache.org/math/api-1.2/org/apache/commons/math/optimization/NelderMead.html
      */
-    private void optimerParametre() throws CostException, ConvergenceException, ModelExcecutionException
-    {
+    private void optimerParametre() throws CostException, ConvergenceException, ModelExcecutionException {
         boolean DEBUG = false;
         // Bruker Nelder-Mead-metoden for ikke-lineær optimering. 
         // Se http://commons.apache.org/math/api-1.2/org/apache/commons/math/optimization/NelderMead.html
@@ -1753,24 +1617,23 @@ public class RoughageNutritionModelImpl implements CostFunction{
         this.optimeringsMaal = RoughageNutritionModelImpl.OPTIMERING_UTVIKLING;
 
         /**
-         * Denne metoden forteller NelderMead-klassen om vi er "nær nok" til
-         * at vi kan avslutte optimeringen
+         * Denne metoden forteller NelderMead-klassen om vi er "nær nok" til at
+         * vi kan avslutte optimeringen
          */
-        ConvergenceChecker cChecker = new ConvergenceChecker(){
+        ConvergenceChecker cChecker = new ConvergenceChecker() {
 
             @Override
             public synchronized boolean converged(PointCostPair[] pair) {
                 boolean DEBUG = false;
                 // Prøver med 10%
                 double differencePercentage = 0.1;
-                double min=0;
-                double max=0;
-                for(int i=0;i<pair.length;i++)
-                {
-                    if(DEBUG)
+                double min = 0;
+                double max = 0;
+                for (int i = 0; i < pair.length; i++) {
+                    if (DEBUG) {
                         System.out.println("[converged] DEBUG Cost=" + pair[i].getCost());
-                    if(i==0)
-                    {
+                    }
+                    if (i == 0) {
                         min = pair[i].getCost();
                         max = min;
                     }
@@ -1781,18 +1644,17 @@ public class RoughageNutritionModelImpl implements CostFunction{
                 return (max - max * differencePercentage <= min);
             }
 
-            
         };
 
-        
         // Rekkefølge for elementene: {alfa}
         // Max og min-verdier for de ulike elementene:
         // alfa {0.002-0.004}
-        double[][] verticesUtvikling = { {0.0025}, {0.0035} };
+        double[][] verticesUtvikling = {{0.0025}, {0.0035}};
 
-        PointCostPair optimumUtvikling = nelderMead.minimize(this, 1000, cChecker , verticesUtvikling);
-        if(DEBUG)
+        PointCostPair optimumUtvikling = nelderMead.minimize(this, 1000, cChecker, verticesUtvikling);
+        if (DEBUG) {
             System.out.println("[GrovforModell/optimerParametre] DEBUG: alfa=" + optimumUtvikling.getPoint()[0]);
+        }
 
         this.alfa = ((Double) optimumUtvikling.getPoint()[0]);
         //this.AIbeta = ((Double) optimumUtvikling.getPoint()[1]).doubleValue();
@@ -1804,15 +1666,16 @@ public class RoughageNutritionModelImpl implements CostFunction{
         boolean avlingMaaltFoerFoersteslaatt = false;
         boolean avlingMaaltMellomFoersteOgAndreslaatt = false;
         for (OptimizationObservation observasjon : this.observasjoner) {
-            if(observasjon.getDate().before(this.datoFoersteSlaatt) && observasjon.getAvling() > 0)
+            if (observasjon.getDate().before(this.datoFoersteSlaatt) && observasjon.getAvling() != null && observasjon.getAvling() > 0) {
                 avlingMaaltFoerFoersteslaatt = true;
-            if(observasjon.getDate().after(this.datoFoersteSlaatt) && observasjon.getDate().before(this.datoAndreSlaatt) && observasjon.getAvling() > 0)
+            }
+            if (observasjon.getDate().after(this.datoFoersteSlaatt) && observasjon.getDate().before(this.datoAndreSlaatt) && observasjon.getAvling() != null && observasjon.getAvling() > 0) {
                 avlingMaaltMellomFoersteOgAndreslaatt = true;
+            }
         }
 
         // 2.1. Optimerer parametre for avling før førsteslått
-        if(avlingMaaltFoerFoersteslaatt)
-        {
+        if (avlingMaaltFoerFoersteslaatt) {
             this.optimeringsMaal = RoughageNutritionModelImpl.OPTIMERING_AVLING_FOERSTESLAATT;
 
             // Bruker (inntil det ikke funker lenger) samme ConvergenceChecker som for MSC
@@ -1820,17 +1683,17 @@ public class RoughageNutritionModelImpl implements CostFunction{
             // Men: Skiller mellom 1. og andreslått
             // Max- og min-verdier for de ulike elementene:
             // Rm {0.05-0.12}
-            double[][] verticesAvlingFoersteslaatt = {{0.07},{0.10}};
+            double[][] verticesAvlingFoersteslaatt = {{0.07}, {0.10}};
             PointCostPair optimumAvlingFoersteslaatt = nelderMead.minimize(this, 1000, cChecker, verticesAvlingFoersteslaatt);
 
-            if(DEBUG)
+            if (DEBUG) {
                 System.out.println("[GrovforModell/optimerParametre] DEBUG: RmFoersteslaatt=" + optimumAvlingFoersteslaatt.getPoint()[0]);
+            }
 
-            this.RmFoersteslaatt = ((Double)optimumAvlingFoersteslaatt.getPoint()[0]).doubleValue();
+            this.RmFoersteslaatt = ((Double) optimumAvlingFoersteslaatt.getPoint()[0]);
         }
         // 2.2. Optimerer parametre for avling mellom førsteslått og andreslått
-        if(avlingMaaltMellomFoersteOgAndreslaatt)
-        {
+        if (avlingMaaltMellomFoersteOgAndreslaatt) {
             this.optimeringsMaal = RoughageNutritionModelImpl.OPTIMERING_AVLING_ANDRESLAATT;
 
             // Bruker (inntil det ikke funker lenger) samme ConvergenceChecker som for MSC
@@ -1838,13 +1701,14 @@ public class RoughageNutritionModelImpl implements CostFunction{
             // Men: Skiller mellom 1. og andreslått
             // Max- og min-verdier for de ulike elementene:
             // Rm {0.05-0.09}
-            double[][] verticesAvlingAndreslaatt = {{0.06},{0.08}};
+            double[][] verticesAvlingAndreslaatt = {{0.06}, {0.08}};
             PointCostPair optimumAvlingAndreslaatt = nelderMead.minimize(this, 1000, cChecker, verticesAvlingAndreslaatt);
 
-            if(DEBUG)
+            if (DEBUG) {
                 System.out.println("[GrovforModell/optimerParametre] DEBUG: RmAndreslaatt=" + optimumAvlingAndreslaatt.getPoint()[0]);
+            }
 
-            this.RmAndreslaatt = ((Double)optimumAvlingAndreslaatt.getPoint()[0]);
+            this.RmAndreslaatt = ((Double) optimumAvlingAndreslaatt.getPoint()[0]);
         }
 
         // Nullstiller avlingsmatrisen, slik at andre beregninger går som planlagt
@@ -1854,15 +1718,16 @@ public class RoughageNutritionModelImpl implements CostFunction{
         boolean NDFMaaltFoerFoersteslaatt = false;
         boolean NDFMaaltMellomFoersteOgAndreslaatt = false;
         for (OptimizationObservation observasjon : this.observasjoner) {
-            if(observasjon.getDate().before(this.datoFoersteSlaatt) && observasjon.getNDF() > 0)
+            if (observasjon.getDate().before(this.datoFoersteSlaatt) && observasjon.getNDF() != null && observasjon.getNDF() > 0) {
                 NDFMaaltFoerFoersteslaatt = true;
-            if(observasjon.getDate().after(this.datoFoersteSlaatt) && observasjon.getDate().before(this.datoAndreSlaatt) && observasjon.getNDF() > 0)
+            }
+            if (observasjon.getDate().after(this.datoFoersteSlaatt) && observasjon.getDate().before(this.datoAndreSlaatt) && observasjon.getNDF() != null && observasjon.getNDF() > 0) {
                 NDFMaaltMellomFoersteOgAndreslaatt = true;
+            }
         }
 
         // 3.1 Optimerer parametre for NDF for førsteslått (vårvekst)
-        if(NDFMaaltFoerFoersteslaatt)
-        {
+        if (NDFMaaltFoerFoersteslaatt) {
             DEBUG = false;
             this.optimeringsMaal = RoughageNutritionModelImpl.OPTIMERING_NDF_FOERSTESLAATT;
             // Bruker (inntil det ikke funker lenger) samme ConvergenceChecker som for MSC
@@ -1871,16 +1736,16 @@ public class RoughageNutritionModelImpl implements CostFunction{
             // Max- og min-verdier for de ulike elementene:
             // NRm {0.05-0.10}, c {1.0-1.4}
 
-            double[][] verticesNDFFoersteslaatt = {{0.06, 1.05},{0.09,1.05},{0.06,1.35}};
+            double[][] verticesNDFFoersteslaatt = {{0.06, 1.05}, {0.09, 1.05}, {0.06, 1.35}};
             PointCostPair optimumNDFFoersteslaatt = nelderMead.minimize(this, 1000, cChecker, verticesNDFFoersteslaatt);
 
-            if(DEBUG)
-                    System.out.println("[GrovforModell/optimerParametre] DEBUG: NRmFoersteslaatt=" + optimumNDFFoersteslaatt.getPoint()[0] + ", c=" + optimumNDFFoersteslaatt.getPoint()[1]);
-            this.NRmFoersteslaatt  = ((Double)optimumNDFFoersteslaatt.getPoint()[0]);
-            this.cFoersteslaatt = ((Double)optimumNDFFoersteslaatt.getPoint()[1]);
+            if (DEBUG) {
+                System.out.println("[GrovforModell/optimerParametre] DEBUG: NRmFoersteslaatt=" + optimumNDFFoersteslaatt.getPoint()[0] + ", c=" + optimumNDFFoersteslaatt.getPoint()[1]);
+            }
+            this.NRmFoersteslaatt = ((Double) optimumNDFFoersteslaatt.getPoint()[0]);
+            this.cFoersteslaatt = ((Double) optimumNDFFoersteslaatt.getPoint()[1]);
         }
-        if(NDFMaaltMellomFoersteOgAndreslaatt)
-        {
+        if (NDFMaaltMellomFoersteOgAndreslaatt) {
             // 3.2 Optimerer parametre for NDF for perioden mellom førsteslått og andreslått (gjenvekst)
             this.optimeringsMaal = RoughageNutritionModelImpl.OPTIMERING_NDF_ANDRESLAATT;
             // Bruker (inntil det ikke funker lenger) samme ConvergenceChecker som for MSC
@@ -1888,13 +1753,14 @@ public class RoughageNutritionModelImpl implements CostFunction{
             // Men: Skiller mellom 1. og andreslått
             // Max- og min-verdier for de ulike elementene:
             // NRm {0.35-0.45}
-            double[][] verticesNDFAndreslaatt = {{0.36},{0.44}};
+            double[][] verticesNDFAndreslaatt = {{0.36}, {0.44}};
             PointCostPair optimumNDFAndreslaatt = nelderMead.minimize(this, 1000, cChecker, verticesNDFAndreslaatt);
 
-            if(DEBUG)
+            if (DEBUG) {
                 System.out.println("[GrovforModell/optimerParametre] DEBUG: NRmAndreslaatt=" + optimumNDFAndreslaatt.getPoint()[0]);
+            }
 
-            this.NRmAndreslaatt = ((Double)optimumNDFAndreslaatt.getPoint()[0]);
+            this.NRmAndreslaatt = ((Double) optimumNDFAndreslaatt.getPoint()[0]);
             DEBUG = false;
         }
         // Nullstiller avlingsmatrisen, slik at andre beregninger går som planlagt
@@ -1904,29 +1770,30 @@ public class RoughageNutritionModelImpl implements CostFunction{
         boolean INDFMaaltFoerFoersteslaatt = false;
         boolean INDFMaaltMellomFoersteOgAndreslaatt = false;
         for (OptimizationObservation observasjon : this.observasjoner) {
-            if(observasjon.getDate().before(this.datoFoersteSlaatt) && observasjon.getINDF() > 0)
+            if (observasjon.getDate().before(this.datoFoersteSlaatt) && observasjon.getINDF() != null && observasjon.getINDF() > 0) {
                 INDFMaaltFoerFoersteslaatt = true;
-            if(observasjon.getDate().after(this.datoFoersteSlaatt) && observasjon.getDate().before(this.datoAndreSlaatt) && observasjon.getINDF() > 0)
+            }
+            if (observasjon.getDate().after(this.datoFoersteSlaatt) && observasjon.getDate().before(this.datoAndreSlaatt) && observasjon.getINDF() != null && observasjon.getINDF() > 0) {
                 INDFMaaltMellomFoersteOgAndreslaatt = true;
+            }
         }
-        if(INDFMaaltFoerFoersteslaatt)
-        {
+        if (INDFMaaltFoerFoersteslaatt) {
             // 4.1 Optimerer parametre for INDF for førsteslått
             this.optimeringsMaal = RoughageNutritionModelImpl.OPTIMERING_INDF_FOERSTESLAATT;
             // Bruker (inntil det ikke funker lenger) samme ConvergenceChecker som for MSC
             // Rekkefølge for elementene: {IRm} (ja, bare ett element!)
             // Max- og min-verdier for de ulike elementene:
             // IRm {0.004-0.01}
-            double[][] verticesINDFFoersteslaatt = {{0.005},{0.009}};
+            double[][] verticesINDFFoersteslaatt = {{0.005}, {0.009}};
             PointCostPair optimumINDFFoersteslaatt = nelderMead.minimize(this, 1000, cChecker, verticesINDFFoersteslaatt);
 
-            if(DEBUG)
+            if (DEBUG) {
                 System.out.println("[GrovforModell/optimerParametre] DEBUG: IRmFoersteslaatt=" + optimumINDFFoersteslaatt.getPoint()[0]);
+            }
 
-            this.IRmFoersteslaatt = ((Double)optimumINDFFoersteslaatt.getPoint()[0]);
+            this.IRmFoersteslaatt = ((Double) optimumINDFFoersteslaatt.getPoint()[0]);
         }
-        if(INDFMaaltMellomFoersteOgAndreslaatt)
-        {
+        if (INDFMaaltMellomFoersteOgAndreslaatt) {
             DEBUG = false;
             // 4.1 Optimerer parametre for INDF for andreslått
             this.optimeringsMaal = RoughageNutritionModelImpl.OPTIMERING_INDF_ANDRESLAATT;
@@ -1936,59 +1803,58 @@ public class RoughageNutritionModelImpl implements CostFunction{
             // beta {0.0001-0.0002} // Fases ut før sesongen 2011
             // P: Når MSC ved førsteslått < 2.4:  {-0.0272,-0.006}, ellers {-0.0299,-0.0087}
             //double[][] verticesINDFAndreslaatt = {{0.00011},{0.00019}}; // Gjaldt for beta
-            double pMin = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi ? -0.0272 : -0.0299;
-            double pMax = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi ? -0.006 : -0.0087;
+            double pMin = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI ? -0.0272 : -0.0299;
+            double pMax = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI ? -0.006 : -0.0087;
 
-            if(DEBUG)
-            {
+            if (DEBUG) {
                 System.out.println("this.MSCVedFoersteslaatt=" + this.getMSCVedFoersteslaatt());
                 System.out.println("pMin=" + pMin);
                 System.out.println("pMax=" + pMax);
             }
-            double[][] verticesINDFAndreslaatt = {{pMin + 0.00001},{pMax - 0.0001}};
+            double[][] verticesINDFAndreslaatt = {{pMin + 0.00001}, {pMax - 0.0001}};
             //double[][] verticesINDFAndreslaatt = {{pMax - 0.0001},{pMin + 0.00001}};
             PointCostPair optimumINDFAndreslaatt = nelderMead.minimize(this, 1000, cChecker, verticesINDFAndreslaatt);
-            if(DEBUG)
+            if (DEBUG) {
                 System.out.println("[GrovforModell/optimerParametre] DEBUG: pINDF=" + optimumINDFAndreslaatt.getPoint()[0]);
+            }
             DEBUG = false;
 
-            this.pINDF = ((Double)optimumINDFAndreslaatt.getPoint()[0]);
+            this.pINDF = ((Double) optimumINDFAndreslaatt.getPoint()[0]);
 
-            
         }
-        
-        // 5. Optimerer parametre for FEm (Fôrenhetskonsentrasjonen (konsentrasjonen av energi i tørrstoffet,
+
+        // 5. Optimerer parametre for FEm (Fôrenhetskonsentrasjonen (konsentrasjonen av energi i tørrstoffet,
         //    uttrykt som FEm pr. kg tørrstoff
         boolean FEmMaaltFoerFoersteslaatt = false;
         boolean FEmMaaltMellomFoersteOgAndreslaatt = false;
-        for(Iterator<OptimizationObservation> i = this.observasjoner.iterator();i.hasNext();)
-        {
+        for (Iterator<OptimizationObservation> i = this.observasjoner.iterator(); i.hasNext();) {
             OptimizationObservation observasjon = i.next();
-            if(observasjon.getDate().before(this.datoFoersteSlaatt) && observasjon.getFEm() > 0)
+            if (observasjon.getDate().before(this.datoFoersteSlaatt) && observasjon.getFEm() != null && observasjon.getFEm() > 0) {
                 FEmMaaltFoerFoersteslaatt = true;
-            if(observasjon.getDate().after(this.datoFoersteSlaatt) && observasjon.getDate().before(this.datoAndreSlaatt) && observasjon.getFEm() > 0)
+            }
+            if (observasjon.getDate().after(this.datoFoersteSlaatt) && observasjon.getDate().before(this.datoAndreSlaatt) && observasjon.getFEm() != null && observasjon.getFEm() > 0) {
                 FEmMaaltMellomFoersteOgAndreslaatt = true;
+            }
         }
-        if(FEmMaaltFoerFoersteslaatt)
-        {
+        if (FEmMaaltFoerFoersteslaatt) {
             DEBUG = false;
             this.optimeringsMaal = RoughageNutritionModelImpl.OPTIMERING_FEM_FOERSTESLAATT;
             // Bruker (inntil det ikke funker lenger) samme ConvergenceChecker som for MSC
             // Rekkefølge for elementene: {j} (ja, bare ett element!)
             // Max- og min-verdier for de ulike elementene:
             // j {1.1574-1.3074}
-            double[][] verticesFEmFoersteslaatt = {{1.1575},{1.3073}};
+            double[][] verticesFEmFoersteslaatt = {{1.1575}, {1.3073}};
             PointCostPair optimumFEmFoersteslaatt = nelderMead.minimize(this, 1000, cChecker, verticesFEmFoersteslaatt);
 
-            if(DEBUG)
+            if (DEBUG) {
                 System.out.println("[GrovforModell/optimerParametre] DEBUG: FEmJFoersteslaatt=" + optimumFEmFoersteslaatt.getPoint()[0]);
+            }
+
+            this.FEmJ = ((Double) optimumFEmFoersteslaatt.getPoint()[0]);
 
-            this.FEmJ = ((Double)optimumFEmFoersteslaatt.getPoint()[0]);
-            
         }
-        if(FEmMaaltMellomFoersteOgAndreslaatt)
-        {
-            DEBUG = true;
+        if (FEmMaaltMellomFoersteOgAndreslaatt) {
+            //DEBUG = true;
             this.optimeringsMaal = RoughageNutritionModelImpl.OPTIMERING_FEM_ANDRESLAATT;
             // Bruker (inntil det ikke funker lenger) samme ConvergenceChecker som for MSC
             // Rekkefølge for elementene: {j} (ja, bare ett element!)
@@ -1997,15 +1863,16 @@ public class RoughageNutritionModelImpl implements CostFunction{
             // m {1.08-1.16}
             // Ellers:
             // m {1.05-1.112}
-            double mMin = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi ? 1.08 : 1.05 ;
-            double mMax = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi ? 1.16 : 1.112 ;
-            double[][] verticesFEmAndreslaatt = {{mMin + 0.00001},{mMax - 0.0001}};
+            double mMin = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI ? 1.08 : 1.05;
+            double mMax = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI ? 1.16 : 1.112;
+            double[][] verticesFEmAndreslaatt = {{mMin + 0.00001}, {mMax - 0.0001}};
             PointCostPair optimumFEmAndreslaatt = nelderMead.minimize(this, 1000, cChecker, verticesFEmAndreslaatt);
 
-            if(DEBUG)
+            if (DEBUG) {
                 System.out.println("[GrovforModell/optimerParametre] DEBUG: FEmMAndreslaatt=" + optimumFEmAndreslaatt.getPoint()[0]);
+            }
 
-            this.FEmM = ((Double)optimumFEmAndreslaatt.getPoint()[0]);
+            this.FEmM = ((Double) optimumFEmAndreslaatt.getPoint()[0]);
         }
 
         // Nullstiller alle bakgrunnsdatamatriser, slik at øvrige beregninger går som planlagt
@@ -2018,7 +1885,9 @@ public class RoughageNutritionModelImpl implements CostFunction{
     }
 
     /**
-     * Denne brukes til å optimere alle de ulike parametrene. Husk å sette hva som skal optimeres først!
+     * Denne brukes til å optimere alle de ulike parametrene. Husk å sette hva
+     * som skal optimeres først!
+     *
      * @param arg0
      * @return
      * @throws org.apache.commons.math.optimization.CostException
@@ -2027,46 +1896,41 @@ public class RoughageNutritionModelImpl implements CostFunction{
     public double cost(double[] parametre) throws CostException {
         boolean DEBUG = false;
         double grenseKost = 1000000000;
-        if(this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_UTVIKLING)
-        {
+        if (this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_UTVIKLING) {
 
-            if(DEBUG)
+            if (DEBUG) {
                 System.out.println("Estimerer utvikling");
+            }
 
             // Rekkefølge for elementene: {alfa}
             double alfa1 = parametre[0];
-            
 
             // Max og min-verdier for de ulike elementene:
             // alfa {0.002-0.004}
             double alfaMin = 0.002;
             double alfaMax = 0.004;
 
-
             // Hvis utenfor min/max: returner en stor verdi. Da opptrer cost-funksjonen
             // som om den har grenser
-            if(alfa1 < alfaMin || alfa1 > alfaMax)
-            {
+            if (alfa1 < alfaMin || alfa1 > alfaMax) {
                 return grenseKost;
-            }
-            else
-            {
+            } else {
                 // Vi setter de parametrene som er gitt, og beregner utvikling
                 this.alfa = (double) alfa1;
 
                 // Starter beregningen med blanke ark...
                 this.AIBakgrunnsdataMatrise = null;
                 double differanse = 0;
-                double maaltUtviklingstrinn;
+                Double maaltUtviklingstrinn;
                 double beregnetUtviklingstrinn;
-                for(Iterator<OptimizationObservation> i = this.observasjoner.iterator();i.hasNext();)
-                {
+                for (Iterator<OptimizationObservation> i = this.observasjoner.iterator(); i.hasNext();) {
                     try {
                         OptimizationObservation observasjon = i.next();
                         maaltUtviklingstrinn = observasjon.getMSC();
                         // Tar høyde for at observasjonen ikke inneholder måling av utviklingstrinn
-                        if(maaltUtviklingstrinn < 0)
+                        if (maaltUtviklingstrinn == null) {
                             continue;
+                        }
                         beregnetUtviklingstrinn = this.getMSC(observasjon.getDate());
                     } catch (ModelExcecutionException ex) {
                         Logger.getLogger(RoughageNutritionModel.class.getName()).log(Level.SEVERE, null, ex);
@@ -2076,12 +1940,11 @@ public class RoughageNutritionModelImpl implements CostFunction{
                 }
                 return differanse;
             }
-            
-        }
-        else if(this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_AVLING_FOERSTESLAATT)
-        {
-            if(DEBUG)
+
+        } else if (this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_AVLING_FOERSTESLAATT) {
+            if (DEBUG) {
                 System.out.println("Estimerer avling førsteslått");
+            }
 
             // Rekkefølge for elementene: {Rm} (ja, bare ett element!)
             double Rm = parametre[0];
@@ -2093,12 +1956,9 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
             // Hvis utenfor min/max: returner en stor verdi. Da opptrer cost-funksjonen
             // som om den har grenser
-            if(Rm < RmMin || Rm > RmMax)
-            {
+            if (Rm < RmMin || Rm > RmMax) {
                 return grenseKost;
-            }
-            else
-            {
+            } else {
                 // Vi setter de parametrene som er gitt, og beregner avling
                 // Bruker bare de målingene som er før 1. slått
                 this.RmFoersteslaatt = (double) Rm;
@@ -2109,17 +1969,18 @@ public class RoughageNutritionModelImpl implements CostFunction{
                 double maaltAvling;
                 double beregnetAvling;
                 // Forutsetter at observasjonene er sorterte
-                for(Iterator<OptimizationObservation> i = this.observasjoner.iterator();i.hasNext();)
-                {
+                for (Iterator<OptimizationObservation> i = this.observasjoner.iterator(); i.hasNext();) {
                     try {
                         OptimizationObservation observasjon = i.next();
                         // Bruker bare de målingene som er før 1. slått
-                        if(observasjon.getDate().compareTo(this.datoFoersteSlaatt) >= 0)
+                        if (observasjon.getDate().compareTo(this.datoFoersteSlaatt) >= 0) {
                             break;
+                        }
                         maaltAvling = observasjon.getAvling();
                         // Tar høyde for at observasjonen ikke inneholder avlingsmåling
-                        if(maaltAvling < 0)
+                        if (maaltAvling < 0) {
                             continue;
+                        }
                         beregnetAvling = this.getAvling(observasjon.getDate(), this.jordtype);
                     } catch (ModelExcecutionException ex) {
                         Logger.getLogger(RoughageNutritionModel.class.getName()).log(Level.SEVERE, null, ex);
@@ -2132,11 +1993,10 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
                 return differanse;
             }
-        }
-        else if(this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_AVLING_ANDRESLAATT)
-        {
-            if(DEBUG)
+        } else if (this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_AVLING_ANDRESLAATT) {
+            if (DEBUG) {
                 System.out.println("Estimerer avling andreslått");
+            }
 
             // Rekkefølge for elementene: {Rm} (ja, bare ett element!)
             double Rm = parametre[0];
@@ -2148,12 +2008,9 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
             // Hvis utenfor min/max: returner en stor verdi. Da opptrer cost-funksjonen
             // som om den har grenser
-            if(Rm < RmMin || Rm > RmMax)
-            {
+            if (Rm < RmMin || Rm > RmMax) {
                 return grenseKost;
-            }
-            else
-            {
+            } else {
                 // Vi setter de parametrene som er gitt, og beregner avling
                 // Bruker bare de målingene som er mellom 1. slått og 2. slått
                 this.RmAndreslaatt = (double) Rm;
@@ -2164,36 +2021,37 @@ public class RoughageNutritionModelImpl implements CostFunction{
                 double maaltAvling;
                 double beregnetAvling;
                 // Forutsetter at observasjonene er sorterte
-                for(Iterator<OptimizationObservation> i = this.observasjoner.iterator();i.hasNext();)
-                {
+                for (Iterator<OptimizationObservation> i = this.observasjoner.iterator(); i.hasNext();) {
                     try {
                         OptimizationObservation observasjon = i.next();
                         // Bruker bare de målingene som er mellom 1. slått og 2. slått
-                        if(observasjon.getDate().compareTo(this.datoFoersteSlaatt) <= 0)
+                        if (observasjon.getDate().compareTo(this.datoFoersteSlaatt) <= 0) {
                             continue;
-                        if(observasjon.getDate().compareTo(this.datoAndreSlaatt) > 0)
+                        }
+                        if (observasjon.getDate().compareTo(this.datoAndreSlaatt) > 0) {
                             break;
+                        }
                         maaltAvling = observasjon.getAvling();
                         // Tar høyde for at observasjonen ikke inneholder avlingsmåling
-                        if(maaltAvling < 0)
+                        if (maaltAvling < 0) {
                             continue;
+                        }
                         beregnetAvling = this.getAvling(observasjon.getDate(), this.jordtype);
                     } catch (ModelExcecutionException ex) {
                         Logger.getLogger(RoughageNutritionModel.class.getName()).log(Level.SEVERE, null, ex);
                         throw new CostException(ex);
                     }
-                    
+
                     // Kvadrerer for å droppe problematikk med negative tall
                     differanse += Math.pow(maaltAvling - beregnetAvling, 2);
                 }
 
                 return differanse;
             }
-        }
-        else if(this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_NDF_FOERSTESLAATT)
-        {
-            if(DEBUG)
+        } else if (this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_NDF_FOERSTESLAATT) {
+            if (DEBUG) {
                 System.out.println("Estimerer NDF førsteslått");
+            }
 
             // Rekkefølge for elementene: {NRm,c}
             // Men: Skiller mellom 1. og andreslått
@@ -2209,12 +2067,9 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
             // Hvis utenfor min/max: returner en stor verdi. Da opptrer cost-funksjonen
             // som om den har grenser
-            if(NRm < NRmMin || NRm > NRmMax || c < cMin || c > cMax)
-            {
+            if (NRm < NRmMin || NRm > NRmMax || c < cMin || c > cMax) {
                 return grenseKost;
-            }
-            else
-            {
+            } else {
                 this.NRmFoersteslaatt = (double) NRm;
                 this.cFoersteslaatt = (double) c;
                 // Starter med blanke ark...
@@ -2224,17 +2079,18 @@ public class RoughageNutritionModelImpl implements CostFunction{
                 double beregnetNDF;
 
                 // Forutsetter at observasjonene er sorterte
-                for(Iterator<OptimizationObservation> i = this.observasjoner.iterator();i.hasNext();)
-                {
+                for (Iterator<OptimizationObservation> i = this.observasjoner.iterator(); i.hasNext();) {
                     try {
                         OptimizationObservation observasjon = i.next();
                         // Bruker bare de målingene som er før 1. slått
-                        if(observasjon.getDate().compareTo(this.datoFoersteSlaatt) > 0)
+                        if (observasjon.getDate().compareTo(this.datoFoersteSlaatt) > 0) {
                             break;
+                        }
                         maaltNDF = observasjon.getNDF();
                         // Tar høyde for at observasjonen ikke inneholder NDF-måling
-                        if(maaltNDF < 0)
+                        if (maaltNDF < 0) {
                             continue;
+                        }
                         beregnetNDF = this.getNDF(observasjon.getDate(), this.kloeverandel, this.jordtype);
                     } catch (ModelExcecutionException ex) {
                         Logger.getLogger(RoughageNutritionModel.class.getName()).log(Level.SEVERE, null, ex);
@@ -2249,11 +2105,10 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
             }
 
-        }
-        else if(this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_NDF_ANDRESLAATT)
-        {
-            if(DEBUG)
+        } else if (this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_NDF_ANDRESLAATT) {
+            if (DEBUG) {
                 System.out.println("Estimerer NDF andreslått");
+            }
 
             // Rekkefølge for elementene: {NRm} (Ja, bare ett element)
             double NRm = parametre[0];
@@ -2265,12 +2120,9 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
             // Hvis utenfor min/max: returner en stor verdi. Da opptrer cost-funksjonen
             // som om den har grenser
-            if(NRm < NRmMin || NRm > NRmMax)
-            {
+            if (NRm < NRmMin || NRm > NRmMax) {
                 return grenseKost;
-            }
-            else
-            {
+            } else {
                 this.NRmAndreslaatt = (double) NRm;
                 // Starter med blanke ark...
                 this.NDFBakgrunnsdataMatrise = null;
@@ -2279,19 +2131,21 @@ public class RoughageNutritionModelImpl implements CostFunction{
                 double beregnetNDF;
 
                 // Forutsetter at observasjonene er sorterte
-                for(Iterator<OptimizationObservation> i = this.observasjoner.iterator();i.hasNext();)
-                {
+                for (Iterator<OptimizationObservation> i = this.observasjoner.iterator(); i.hasNext();) {
                     try {
                         OptimizationObservation observasjon = i.next();
                         // Bruker bare de målingene som er mellom 1. slått og 2. slått
-                        if(observasjon.getDate().compareTo(this.datoFoersteSlaatt) <= 0)
+                        if (observasjon.getDate().compareTo(this.datoFoersteSlaatt) <= 0) {
                             continue;
-                        if(observasjon.getDate().compareTo(this.datoAndreSlaatt) > 0)
+                        }
+                        if (observasjon.getDate().compareTo(this.datoAndreSlaatt) > 0) {
                             break;
+                        }
                         maaltNDF = observasjon.getNDF();
                         // Tar høyde for at observasjonen ikke inneholder NDF-måling
-                        if(maaltNDF < 0)
+                        if (maaltNDF < 0) {
                             continue;
+                        }
                         beregnetNDF = this.getNDF(observasjon.getDate(), this.kloeverandel, this.jordtype);
                     } catch (ModelExcecutionException ex) {
                         Logger.getLogger(RoughageNutritionModel.class.getName()).log(Level.SEVERE, null, ex);
@@ -2305,11 +2159,10 @@ public class RoughageNutritionModelImpl implements CostFunction{
                 return differanse;
 
             }
-        }
-        else if(this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_INDF_FOERSTESLAATT)
-        {
-            if(DEBUG)
+        } else if (this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_INDF_FOERSTESLAATT) {
+            if (DEBUG) {
                 System.out.println("Estimerer INDF førsteslått, NelderMead tester med IRm=" + parametre[0]);
+            }
             // Rekkefølge for elementene: {IRm}
             double IRm = parametre[0];
 
@@ -2317,15 +2170,12 @@ public class RoughageNutritionModelImpl implements CostFunction{
             // IRm {0.004-0.01}
             double IRmMin = 0.004;
             double IRmMax = 0.01;
-            
+
             // Hvis utenfor min/max: returner en stor verdi. Da opptrer cost-funksjonen
             // som om den har grenser
-            if(IRm < IRmMin || IRm > IRmMax)
-            {
+            if (IRm < IRmMin || IRm > IRmMax) {
                 return grenseKost;
-            }
-            else
-            {
+            } else {
                 this.IRmFoersteslaatt = (double) IRm;
                 // Starter med blanke ark...
                 this.INDFBakgrunnsdataMatrise = null;
@@ -2334,17 +2184,18 @@ public class RoughageNutritionModelImpl implements CostFunction{
                 double beregnetINDF;
 
                 // Forutsetter at observasjonene er sorterte
-                for(Iterator<OptimizationObservation> i = this.observasjoner.iterator();i.hasNext();)
-                {
+                for (Iterator<OptimizationObservation> i = this.observasjoner.iterator(); i.hasNext();) {
                     try {
                         OptimizationObservation observasjon = i.next();
                         // Bruker bare de målingene som er før 1. slått
-                        if(observasjon.getDate().compareTo(this.datoFoersteSlaatt) > 0)
+                        if (observasjon.getDate().compareTo(this.datoFoersteSlaatt) > 0) {
                             break;
+                        }
                         maaltINDF = observasjon.getINDF();
                         // Tar høyde for at observasjonen ikke inneholder INDF-måling
-                        if(maaltINDF < 0)
+                        if (maaltINDF < 0) {
                             continue;
+                        }
                         beregnetINDF = this.getINDF(observasjon.getDate());
                     } catch (ModelExcecutionException ex) {
                         Logger.getLogger(RoughageNutritionModel.class.getName()).log(Level.SEVERE, null, ex);
@@ -2358,16 +2209,13 @@ public class RoughageNutritionModelImpl implements CostFunction{
                 return differanse;
 
             }
-        }
-        else if(this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_INDF_ANDRESLAATT)
-        {
-            if(DEBUG)
+        } else if (this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_INDF_ANDRESLAATT) {
+            if (DEBUG) {
                 System.out.println("Estimerer INDF andreslått");
+            }
 
             // Rekkefølge for elementene: {beta}
             //double beta = parametre[0];
-            
-
             // Rekkefølge for elementene: {P}
             double p = parametre[0];
 
@@ -2375,21 +2223,16 @@ public class RoughageNutritionModelImpl implements CostFunction{
             // beta {0.0001-0.0002}
             //double betaMin = 0.0001;
             //double betaMax = 0.0002;
-
             // Max- og min-verdier for de ulike elementene:
-            try
-            {
-                double pMin = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi ? -0.0272 : -0.0299;
-                double pMax = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi ? -0.006 : -0.0087;
-            
+            try {
+                double pMin = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI ? -0.0272 : -0.0299;
+                double pMax = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI ? -0.006 : -0.0087;
+
                 // Hvis utenfor min/max: returner en stor verdi. Da opptrer cost-funksjonen
                 // som om den har grenser
-                if(p < pMin || p > pMax)
-                {
+                if (p < pMin || p > pMax) {
                     return grenseKost;
-                }
-                else
-                {
+                } else {
                     //this.betaINDF = (double) beta;
                     this.pINDF = (double) p;
                     // Starter med blanke ark...
@@ -2399,19 +2242,21 @@ public class RoughageNutritionModelImpl implements CostFunction{
                     double beregnetINDF;
 
                     // Forutsetter at observasjonene er sorterte
-                    for(Iterator<OptimizationObservation> i = this.observasjoner.iterator();i.hasNext();)
-                    {
+                    for (Iterator<OptimizationObservation> i = this.observasjoner.iterator(); i.hasNext();) {
                         try {
                             OptimizationObservation observasjon = i.next();
                             // Bruker bare de målingene som er mellom 1. slått og 2. slått
-                            if(observasjon.getDate().compareTo(this.datoFoersteSlaatt) <= 0)
+                            if (observasjon.getDate().compareTo(this.datoFoersteSlaatt) <= 0) {
                                 continue;
-                            if(observasjon.getDate().compareTo(this.datoAndreSlaatt) > 0)
+                            }
+                            if (observasjon.getDate().compareTo(this.datoAndreSlaatt) > 0) {
                                 break;
+                            }
                             maaltINDF = observasjon.getINDF();
                             // Tar høyde for at observasjonen ikke inneholder INDF-måling
-                            if(maaltINDF < 0)
+                            if (maaltINDF < 0) {
                                 continue;
+                            }
                             beregnetINDF = this.getINDF(observasjon.getDate());
                         } catch (ModelExcecutionException ex) {
                             Logger.getLogger(RoughageNutritionModel.class.getName()).log(Level.SEVERE, null, ex);
@@ -2425,13 +2270,13 @@ public class RoughageNutritionModelImpl implements CostFunction{
                     return differanse;
 
                 }
+            } catch (ModelExcecutionException me) {
+                me.printStackTrace();
             }
-            catch(ModelExcecutionException me) {me.printStackTrace();}
-        }
-        else if(this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_FEM_FOERSTESLAATT)
-        {
-            if(DEBUG)
+        } else if (this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_FEM_FOERSTESLAATT) {
+            if (DEBUG) {
                 System.out.println("Estimerer FEm førsteslått");
+            }
             // Rekkefølge for elementene {FEmj} (Ja, bare ett element)
             double FEmjTemp = parametre[0];
 
@@ -2441,12 +2286,9 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
             // Hvis utenfor min/max: returner en stor verdi. Da opptrer cost-funksjonen
             // som om den har grenser
-            if(FEmjTemp < FEmjTempMin || FEmjTemp > FEmjTempMax)
-            {
+            if (FEmjTemp < FEmjTempMin || FEmjTemp > FEmjTempMax) {
                 return grenseKost;
-            }
-            else
-            {
+            } else {
                 this.FEmJ = (double) FEmjTemp;
                 // Starter med blanke ark...
                 this.FEmBakgrunnsdataMatrise = null;
@@ -2455,19 +2297,20 @@ public class RoughageNutritionModelImpl implements CostFunction{
                 double beregnetFEm;
 
                 // Forutsetter at observasjonene er sorterte
-                for(Iterator<OptimizationObservation> i = this.observasjoner.iterator();i.hasNext();)
-                {
+                for (Iterator<OptimizationObservation> i = this.observasjoner.iterator(); i.hasNext();) {
                     try {
                         OptimizationObservation observasjon = i.next();
                         // Bruker bare de målingene som er før 1. slått
-                        if(observasjon.getDate().compareTo(this.datoFoersteSlaatt) > 0)
+                        if (observasjon.getDate().compareTo(this.datoFoersteSlaatt) > 0) {
                             break;
+                        }
                         maaltFEm = observasjon.getFEm();
                         // Tar høyde for at observasjonen ikke inneholder FEm-måling
-                        if(maaltFEm < 0)
+                        if (maaltFEm < 0) {
                             continue;
+                        }
                         beregnetFEm = this.getFEm(observasjon.getDate());
-                    }catch (ModelExcecutionException ex) {
+                    } catch (ModelExcecutionException ex) {
                         Logger.getLogger(RoughageNutritionModel.class.getName()).log(Level.SEVERE, null, ex);
                         throw new CostException(ex);
                     }
@@ -2477,30 +2320,25 @@ public class RoughageNutritionModelImpl implements CostFunction{
                 }
                 return differanse;
             }
-        }
-        else if(this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_FEM_ANDRESLAATT)
-        {
-             if(DEBUG)
+        } else if (this.optimeringsMaal == RoughageNutritionModelImpl.OPTIMERING_FEM_ANDRESLAATT) {
+            if (DEBUG) {
                 System.out.println("Estimerer FEm andreslått");
+            }
             // Rekkefølge for elementene {FEmj} (Ja, bare ett element)
             double FEmMTemp = parametre[0];
 
             //Max- og min-verdier for de ulike elementene:
             //double FEmjTempMin = 1.1574;
             //double FEmjTempMax = 1.3074;
-            try
-            {
-                double FEmMTempMin = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi ? 1.08 : 1.05;
-                double FEmMTempMax = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSCVedFoersteslaattGrenseverdi ? 1.16 : 1.112;
+            try {
+                double FEmMTempMin = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI ? 1.08 : 1.05;
+                double FEmMTempMax = this.getMSCVedFoersteslaatt() < RoughageNutritionModelImpl.MSC_VED_FOERSTESLAATT_GRENSEVERDI ? 1.16 : 1.112;
 
                 // Hvis utenfor min/max: returner en stor verdi. Da opptrer cost-funksjonen
                 // som om den har grenser
-                if(FEmMTemp < FEmMTempMin || FEmMTemp > FEmMTempMax)
-                {
+                if (FEmMTemp < FEmMTempMin || FEmMTemp > FEmMTempMax) {
                     return grenseKost;
-                }
-                else
-                {
+                } else {
                     this.FEmM = (double) FEmMTemp;
                     // Starter med blanke ark...
                     this.FEmBakgrunnsdataMatrise = null;
@@ -2509,21 +2347,23 @@ public class RoughageNutritionModelImpl implements CostFunction{
                     double beregnetFEm;
 
                     // Forutsetter at observasjonene er sorterte
-                    for(Iterator<OptimizationObservation> i = this.observasjoner.iterator();i.hasNext();)
-                    {
+                    for (Iterator<OptimizationObservation> i = this.observasjoner.iterator(); i.hasNext();) {
                         try {
                             OptimizationObservation observasjon = i.next();
                             // Bruker bare de målingene som er før 1. slått
-                            if(observasjon.getDate().compareTo(this.datoFoersteSlaatt) <= 0)
+                            if (observasjon.getDate().compareTo(this.datoFoersteSlaatt) <= 0) {
                                 continue;
-                            if(observasjon.getDate().after(this.datoAndreSlaatt))
+                            }
+                            if (observasjon.getDate().after(this.datoAndreSlaatt)) {
                                 break;
+                            }
                             maaltFEm = observasjon.getFEm();
                             // Tar høyde for at observasjonen ikke inneholder FEm-måling
-                            if(maaltFEm < 0)
+                            if (maaltFEm < 0) {
                                 continue;
+                            }
                             beregnetFEm = this.getFEm(observasjon.getDate());
-                        }catch (ModelExcecutionException ex) {
+                        } catch (ModelExcecutionException ex) {
                             Logger.getLogger(RoughageNutritionModel.class.getName()).log(Level.SEVERE, null, ex);
                             throw new CostException(ex);
                         }
@@ -2533,32 +2373,36 @@ public class RoughageNutritionModelImpl implements CostFunction{
                     }
                     return differanse;
                 }
+            } catch (ModelExcecutionException me) {
+                me.printStackTrace();
             }
-            catch(ModelExcecutionException me) {me.printStackTrace();}
         }
-        
+
         return grenseKost;
     }
 
     /**
-     * Sjekker målte nivåer av råprotein på bestemte datoer, legger til differansen
-     * mellom målt og beregnet på denne datoen for alle datoer framover (evt. fram
-     * til dato for ny måling)
+     * Sjekker målte nivåer av råprotein på bestemte datoer, legger til
+     * differansen mellom målt og beregnet på denne datoen for alle datoer
+     * framover (evt. fram til dato for ny måling)
      */
-    private void kallibrerRaaprotein() throws ModelExcecutionException
-    {
+    private void kalibrerRaaprotein() throws ModelExcecutionException {
         boolean DEBUG = false;
-        if(this.observasjoner == null) return;
+        if (this.observasjoner == null) {
+            return;
+        }
 
         // This has already been done, but you can never be too sure...
         Collections.sort(this.observasjoner);
-        double differanseMellomMaaltOgSimulertNMengde = 0;
+        double differanseMellomMaaltOgSimulertNMengde;
         Calendar cal = Calendar.getInstance(this.timeZone);
-        for(ListIterator<OptimizationObservation> i=this.observasjoner.listIterator();i.hasNext();)
-        {
+        for (ListIterator<OptimizationObservation> i = this.observasjoner.listIterator(); i.hasNext();) {
             OptimizationObservation observasjon = i.next();
-            if(observasjon.getRawProtein() > 0 && this.getRaaprotein(observasjon.getDate(), this.jordtype) > 0)
+            if(observasjon.getRawProtein() == null)
             {
+                continue;
+            }
+            if (observasjon.getRawProtein() > 0 && this.getRaaprotein(observasjon.getDate(), this.jordtype) > 0) {
                 double beregnetNMengde = this.getNMengdeFraRaaprotein(this.getRaaprotein(observasjon.getDate(), this.jordtype), observasjon.getDate(), this.jordtype);
                 double maaltNMengde = this.getNMengdeFraRaaprotein(observasjon.getRawProtein(), observasjon.getDate(), this.jordtype);
 
@@ -2566,56 +2410,56 @@ public class RoughageNutritionModelImpl implements CostFunction{
 
                 // Finner dato for neste gyldige måling. Dette blir "grensedato"
                 Date grenseDato = null;
-                while(i.hasNext() && grenseDato == null)
-                {
+                while (i.hasNext() && grenseDato == null) {
                     OptimizationObservation tmp = i.next();
-                    if(tmp.getRawProtein() > 0 && this.getRaaprotein(tmp.getDate(), this.jordtype) > 0)
+                    if (tmp.getRawProtein() > 0 && this.getRaaprotein(tmp.getDate(), this.jordtype) > 0) {
                         grenseDato = tmp.getDate();
+                    }
                 }
 
                 cal.setTime(observasjon.getDate());
-                while((grenseDato == null || cal.getTime().before(grenseDato) ) && this.resultatMatrise.getParamDoubleValueForDate(cal.getTime(), ResultMatrix.RAAPROTEIN) != null)
-                {
+                while ((grenseDato == null || cal.getTime().before(grenseDato)) && this.resultatMatrise.getParamDoubleValueForDate(cal.getTime(), ResultMatrix.RAAPROTEIN) != null) {
                     double preRaaprotein = this.resultatMatrise.getParamDoubleValueForDate(cal.getTime(), ResultMatrix.RAAPROTEIN);
                     double preNMengde = preRaaprotein != 0 ? this.getNMengdeFraRaaprotein(preRaaprotein, cal.getTime(), this.jordtype) : 0;
                     double justertNMengde = preRaaprotein != 0 ? preNMengde + differanseMellomMaaltOgSimulertNMengde : 0;
                     double justertRaaprotein = preRaaprotein != 0 ? this.getRaaproteinFraNMengde(justertNMengde, cal.getTime(), this.jordtype) : 0;
                     this.resultatMatrise.setParamDoubleValueForDate(cal.getTime(), ResultMatrix.RAAPROTEIN, justertRaaprotein);
 
-                    if(DEBUG)
+                    if (DEBUG) {
                         System.out.println("[GrovforModell/kallibrerRaaprotein] DEBUG dato=" + cal.getTime().toString() + ", preRaaprotein = " + preRaaprotein + ", justertRaaprotein=" + justertRaaprotein + ", raaproteinDiff = " + (justertRaaprotein - preRaaprotein));
+                    }
 
                     cal.add(Calendar.DATE, 1);
                 }
 
                 // Hvis vi fant en grensedato, går vi ett hakk tilbake...
-                if(grenseDato != null)
+                if (grenseDato != null) {
                     i.previous();
-                
+                }
+
             }
         }
     }
 
     /**
      * Omregningsformel
+     *
      * @param raaprotein
      * @param dato
      * @return
      */
-    protected double getNMengdeFraRaaprotein(double raaprotein, Date dato, int jordtype) throws ModelExcecutionException
-    {
+    protected double getNMengdeFraRaaprotein(double raaprotein, Date dato, int jordtype) throws ModelExcecutionException {
         double NKons = raaprotein / 6.25;
         return NKons * this.getAvling(dato, jordtype) / 100;
     }
 
     /**
-     * 
+     *
      * @param NMengde
      * @param dato
      * @return
      */
-    protected double getRaaproteinFraNMengde(double NMengde, Date dato, int jordtype) throws ModelExcecutionException
-    {
+    protected double getRaaproteinFraNMengde(double NMengde, Date dato, int jordtype) throws ModelExcecutionException {
         return NMengde / this.getAvling(dato, jordtype) * 6.25f * 100;
     }
 
diff --git a/src/test/java/no/bioforsk/vips/model/roughagenutritionmodel/RoughageNutritionModelTest.java b/src/test/java/no/bioforsk/vips/model/roughagenutritionmodel/RoughageNutritionModelTest.java
index 732ca7e..cb767b9 100644
--- a/src/test/java/no/bioforsk/vips/model/roughagenutritionmodel/RoughageNutritionModelTest.java
+++ b/src/test/java/no/bioforsk/vips/model/roughagenutritionmodel/RoughageNutritionModelTest.java
@@ -28,6 +28,7 @@ import com.ibm.icu.util.Calendar;
 import com.ibm.icu.util.TimeZone;
 import java.io.BufferedInputStream;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
@@ -87,6 +88,9 @@ public class RoughageNutritionModelTest {
             config.setConfigParameter("firstHarvest", cal.getTime());
             config.setConfigParameter("soilType", RoughageNutritionModel.JORDTYPE_SAND);
             config.setConfigParameter("cloverShare", RoughageNutritionModel.ENGSAMMENSETNING_KLOEVERANDEL_LITEN);
+            String[] optimizationInfoLines = {"2015-06-02,2,3,,,,"};
+            List<String> optimizationInfo = Arrays.asList(optimizationInfoLines);
+            config.setConfigParameter("optimizationInfo", optimizationInfo);
             RoughageNutritionModel instance = new RoughageNutritionModel();
             instance.setConfiguration(config);
             //List<Result> expResult = null;
-- 
GitLab