Fix Bug in Compound Error function when reference data (eg Deaths) are
all zero
diff --git a/org.eclipse.stem/analysis/org.eclipse.stem.analysis/src/org/eclipse/stem/analysis/impl/CompoundErrorFunctionImpl.java b/org.eclipse.stem/analysis/org.eclipse.stem.analysis/src/org/eclipse/stem/analysis/impl/CompoundErrorFunctionImpl.java
index 9405234..b704fd7 100644
--- a/org.eclipse.stem/analysis/org.eclipse.stem.analysis/src/org/eclipse/stem/analysis/impl/CompoundErrorFunctionImpl.java
+++ b/org.eclipse.stem/analysis/org.eclipse.stem.analysis/src/org/eclipse/stem/analysis/impl/CompoundErrorFunctionImpl.java
@@ -575,16 +575,22 @@
 		return avgList;
 	}
 
-	public double[] getSpecificErrors(Map<String,List<Double>>commonDailyIncidenceLocationsMapA,Map<String,List<Double>>commonDailyIncidenceLocationsMapB,BasicEList<Double> list) {
-		double[]errors = new double[2];//contains error and verror
-		
-		double [] Xref = new double[time.length];
-		double [] Xdata = new double[time.length];
-		
-		double finalerror = 0.0;
-	    double verror = 0.0;
 	
-		for(int i=0;i<time.length;++i)list.add(0.0);
+	
+	
+	/**
+	 * calculate the individual error(s) contributing to the compound error function
+	 * (a user defined combination of cumulative incidence, daily incidence, and deaths
+	 * 
+	 */
+	public double[] getSpecificErrors(Map<String,List<Double>>commonDailyIncidenceLocationsMapA,Map<String,List<Double>>commonDailyIncidenceLocationsMapB,BasicEList<Double> list) {
+		double[] errors 	= new double[2];//contains error and verror
+		double[] Xref 		= new double[time.length];
+		double[] Xdata 		= new double[time.length];
+		double finalerror 	= 0.0;
+	    double verror 		= 0.0;
+	    
+		for(int i=0;i<time.length;++i) list.add(0.0);
 		
 		// Get the average population for each location
 		for(String loc:commonPopulationLocationsA.keySet()) {
@@ -592,16 +598,16 @@
 			double sum = 0;for(double d:ld)sum+=d;
 			sum /= (double)ld.size();
 			commonAvgPopulationLocationsA.put(loc, sum);
-		}		
-
+		}	
+		
 		// Get the average population for each location
 		for(String loc:commonPopulationLocationsB.keySet()) {
 			List<Double>ld = commonPopulationLocationsB.get(loc);
 			double sum = 0;for(double d:ld)sum+=d;
 			sum /= (double)ld.size();
 			commonAvgPopulationLocationsB.put(loc, sum);
-		}		
-
+		}	
+		
 		// Get the maximum value for the A series (reference)
 		for(String loc:commonPopulationLocationsA.keySet()) {
 			List<Double>ld = commonDailyIncidenceLocationsMapA.get(loc);
@@ -612,9 +618,7 @@
 		
 		// Calculate the normalized root mean square error for each location, then
 		// divide by the number of locatins
-		
 		double weighted_denom = 0.0;
-		
 		if(!AGGREGATE_NRMSE) { // Use NRMSE per location first
 			for(String loc:commonDailyIncidenceLocationsMapA.keySet()) {
 				double maxRef = 0.0;
@@ -623,62 +627,56 @@
 				for(int icount =0; icount < time.length; icount ++) {
 					List<Double> dataAI = commonDailyIncidenceLocationsMapA.get(loc);
 					List<Double> dataBI = commonDailyIncidenceLocationsMapB.get(loc);
-													
 					double iA = dataAI.get(icount).doubleValue();
 					double iB = dataBI.get(icount).doubleValue();
-				
 					Xref[icount]=iA;
 					Xdata[icount]=iB;
 				}
-			
 				double nominator = 0.0; 
 				double timesteps = 0;
 				for(int icount =0; icount < time.length; icount ++) {
 					if(Xref[icount]>maxRef)maxRef = Xref[icount];
 					if(Xref[icount]<minRef)minRef = Xref[icount];
-					
 					// If we use the threshold and both the reference and the model is less than
 					// the THRESHOLD*MAXref(loc) we don't measure the data point
-					
 					if(USE_THRESHOLD && (Xref[icount]<=THRESHOLD*commonMaxLocationsA.get(loc) &&
 							Xdata[icount]<=THRESHOLD*commonMaxLocationsA.get(loc))) continue;
-					
 					nominator = nominator + Math.pow(Xref[icount]-Xdata[icount], 2);
 					list.set(icount, list.get(icount)+Math.abs(Xref[icount]-Xdata[icount]));
 					++timesteps;
 				}
 				double error = Double.MAX_VALUE;
-			    if(timesteps > 0 && maxRef-minRef > 0.0) {
+			    if(timesteps > 0) {
 			    	error = Math.sqrt(nominator/timesteps);
-			    	error = error / (maxRef-minRef);
+			    	if(maxRef-minRef > 0.0) {
+			    		error = error / (maxRef-minRef);
+			    	}
+			    	else if(maxRef-minRef==0) {
+			    		error=Double.MIN_VALUE;// if all values in the reference data is 0
+			    	}
 			    	if(WEIGHTED_AVERAGE) finalerror += commonAvgPopulationLocationsA.get(loc) * error;
 			    	else finalerror += error;
 			    	if(WEIGHTED_AVERAGE) weighted_denom += commonAvgPopulationLocationsA.get(loc);
 			    	else weighted_denom += 1.0;
 			    }
-			
 			}
-			
-			
-		
 			// Divide the error by the number of locations
 			finalerror /= weighted_denom; 
+			
 		} else { // Aggregate signal, then calculate NRMSE 
 			for(int icount =0; icount < time.length; icount ++) {
 				for(String loc:commonDailyIncidenceLocationsMapA.keySet()) {
 					List<Double> dataAI = commonDailyIncidenceLocationsMapA.get(loc);
 					List<Double> dataBI = commonDailyIncidenceLocationsMapB.get(loc);
-													
 					double iA = dataAI.get(icount).doubleValue();
 					double iB = dataBI.get(icount).doubleValue();
-				
 					Xref[icount]+=iA;
 					Xdata[icount]+=iB;
 				}
 			}
 			
-			double maxRef = Double.MIN_VALUE;
-			double minRef = Double.MAX_VALUE;
+			double maxRef 			= Double.MIN_VALUE;
+			double minRef 			= Double.MAX_VALUE;
 			double maxValidationRef = Double.MIN_VALUE;
 			double minValidationRef = Double.MAX_VALUE;
 			
@@ -694,12 +692,10 @@
 			double nominator = 0.0, vnominator = 0.0;
 			double timesteps = 0.0, vtimesteps = 0.0;
 			for(int icount =0; icount < time.length; icount ++) {
-				
 				// Calculate validation error then skip
 				if(icount >= validationYear*365.25 && icount <= (validationYear+1)*365.25) {
 					if(USE_THRESHOLD && (Xref[icount]<=THRESHOLD*maxValidationRef &&
 							Xdata[icount]<=THRESHOLD*maxValidationRef)) continue;
-					
 					vnominator = vnominator + Math.pow(Xref[icount]-Xdata[icount], 2);
 					list.set(icount, new Double(0)); // Set to 0 for validation data points
 					++vtimesteps;
@@ -707,28 +703,35 @@
 				}
 				// If we use the threshold and both the reference and the model is less than
 				// the THRESHOLD*MAXref(loc) we don't measure the data point
-				
 				if(USE_THRESHOLD && (Xref[icount]<=THRESHOLD*maxRef &&
 						Xdata[icount]<=THRESHOLD*maxRef)) continue;
-				
 				nominator = nominator + Math.pow(Xref[icount]-Xdata[icount], 2);
 				list.set(icount, Math.abs(Xref[icount]-Xdata[icount]));
 				++timesteps;
 			}
-			
 			double error = Double.MAX_VALUE;
-		    if(timesteps > 0 && maxRef-minRef > 0.0) {
-		    	error = Math.sqrt(nominator/timesteps);
-		    	finalerror = error / (maxRef-minRef);
+		    if(timesteps > 0) {
+		    	if(maxRef-minRef > 0.0) {
+		    		error = Math.sqrt(nominator/timesteps);
+			    	finalerror = error / (maxRef-minRef);
+		    	}
+		    	else if(maxRef-minRef==0) {
+		    		error=Double.MIN_VALUE;// if all values in the reference data is 0
+		    		finalerror=Double.MIN_VALUE;// if all values in the reference data is 0
+		    	}
 		    }
 		    // Validation
 		    error = Double.MAX_VALUE;
-		    if(vtimesteps > 0 && maxValidationRef-minValidationRef > 0.0) {
+		    if(vtimesteps > 0) {
+		    	if(maxValidationRef-minValidationRef > 0.0) {
 		    	error = Math.sqrt(vnominator/vtimesteps);
 		    	verror = error / (maxValidationRef-minValidationRef);
+		    	}else if(maxValidationRef-minValidationRef==0) {
+		    		error=Double.MIN_VALUE;// if all values in the reference data is 0
+		    		verror=Double.MIN_VALUE;// if all values in the reference data is 0
+		    	}
 		    }
 		} // else
-		
 		errors[0]=finalerror;
 		errors[1]=verror;
 		return errors;