diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/directivity/DirectivitySphere.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/directivity/DirectivitySphere.java index dcf46bf19..cce33a33b 100644 --- a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/directivity/DirectivitySphere.java +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/directivity/DirectivitySphere.java @@ -33,4 +33,10 @@ public interface DirectivitySphere { * @return Attenuation in dB for each frequency */ double[] getAttenuationArray(double[] frequencies, double phi, double theta); + + /** + * @param frequency Frequency in Hertz + * @return True if this sphere is capable of producing an attenuation for this frequency + */ + boolean coverFrequency(double frequency); } diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/directivity/DiscreteDirectivitySphere.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/directivity/DiscreteDirectivitySphere.java index b65fb1daf..1dac5dbf4 100644 --- a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/directivity/DiscreteDirectivitySphere.java +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/directivity/DiscreteDirectivitySphere.java @@ -13,6 +13,7 @@ import java.io.Serializable; import java.util.*; +import java.util.function.DoublePredicate; /** * Describe Attenuation directivity over a sphere @@ -99,49 +100,36 @@ public int getDirectionIdentifier() { */ @Override public double getAttenuation(double frequency, double phi, double theta) { - DirectivityRecord query = new DirectivityRecord(theta, phi, null); - - // look for frequency index - Integer idFreq = frequencyMapping.get(Double.doubleToLongBits(frequency)); - if (idFreq == null) { - // get closest index - idFreq = Arrays.binarySearch(frequencies, frequency); - if (idFreq < 0) { - int last = Math.min(-idFreq - 1, frequencies.length - 1); - int first = Math.max(last - 1, 0); - idFreq = Math.abs(frequencies[first] - frequency) < Math.abs(frequencies[last] - frequency) ? - first : last; - } - } - return getRecord(query.theta, query.phi, interpolationMethod).getAttenuation()[idFreq]; + return getAttenuationArray(new double[]{frequency}, phi, theta)[0]; } /** * Returns the attenuation in dB of the directivity pattern at a given angle (phi, theta) - * @param frequencies Frequency array in Hertz (same order will be returned) + * @param requestFrequencies Frequency array in Hertz (same order will be returned) * @param phi (0 2π) with 0 is front * @param theta (-π/2 π/2) with 0 is horizontal; π is top * @return Attenuation array level in dB */ @Override - public double[] getAttenuationArray(double[] frequencies, double phi, double theta) { + public double[] getAttenuationArray(double[] requestFrequencies, double phi, double theta) { DirectivityRecord query = new DirectivityRecord(theta, phi, null); DirectivityRecord record = getRecord(query.theta, query.phi, interpolationMethod); - double[] returnAttenuation = new double[frequencies.length]; + double[] returnAttenuation = new double[requestFrequencies.length]; - for (int frequencyIndex = 0; frequencyIndex < frequencies.length; frequencyIndex++) { - double frequency = frequencies[frequencyIndex]; + for (int frequencyIndex = 0; frequencyIndex < requestFrequencies.length; frequencyIndex++) { + double frequency = requestFrequencies[frequencyIndex]; // look for frequency index Integer idFreq = frequencyMapping.get(Double.doubleToLongBits(frequency)); if (idFreq == null) { // get closest index - idFreq = Arrays.binarySearch(frequencies, frequency); + idFreq = Arrays.binarySearch(this.frequencies, frequency); if (idFreq < 0) { - int last = Math.min(-idFreq - 1, frequencies.length - 1); + int last = Math.min(-idFreq - 1, this.frequencies.length - 1); int first = Math.max(last - 1, 0); - idFreq = Math.abs(frequencies[first] - frequency) < Math.abs(frequencies[last] - frequency) ? first : last; + idFreq = Math.abs(this.frequencies[first] - frequency) < + Math.abs(this.frequencies[last] - frequency) ? first : last; } } returnAttenuation[frequencyIndex] = record.attenuation[idFreq]; @@ -363,4 +351,9 @@ public double[] getAttenuation() { return attenuation; } } + + @Override + public boolean coverFrequency(double frequency) { + return Arrays.stream(frequencies).anyMatch(x -> x == frequency); + } } diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossos/RailWayCnossosParameters.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossos/RailWayCnossosParameters.java index 20d2fc36b..47898f09a 100644 --- a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossos/RailWayCnossosParameters.java +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossos/RailWayCnossosParameters.java @@ -213,5 +213,10 @@ public double[] getAttenuationArray(double[] frequencies, double phi, double the } return ret; } + + @Override + public boolean coverFrequency(double frequency) { + return true; + } } } diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/nmpb/RailWayNMPBParameters.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/nmpb/RailWayNMPBParameters.java index 37db8f24d..df776ce77 100644 --- a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/nmpb/RailWayNMPBParameters.java +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/nmpb/RailWayNMPBParameters.java @@ -209,5 +209,10 @@ public double[] getAttenuationArray(double[] frequencies, double phi, double the } return ret; } + + @Override + public boolean coverFrequency(double frequency) { + return true; + } } } diff --git a/noisemodelling-emission/src/test/java/org/noise_planet/noisemodelling/emission/directivity/DiscreteDirectivitySphereTest.java b/noisemodelling-emission/src/test/java/org/noise_planet/noisemodelling/emission/directivity/DiscreteDirectivitySphereTest.java index c63538e00..5f934c9e6 100644 --- a/noisemodelling-emission/src/test/java/org/noise_planet/noisemodelling/emission/directivity/DiscreteDirectivitySphereTest.java +++ b/noisemodelling-emission/src/test/java/org/noise_planet/noisemodelling/emission/directivity/DiscreteDirectivitySphereTest.java @@ -66,6 +66,13 @@ public void testInsert() { assertArrayEquals(new double[]{-5.63, -5.63, -5.63, -5.63, -5.63, -5.63, -5.63, -5.63}, r.getAttenuation(), 0.1); + // check for non-existing frequency + assertArrayEquals(new double[]{-5.63, -5.63, -5.63, -5.63, -5.63, -5.63, -5.63, -5.63, -5.63, -5.63, -5.63, + -5.63, -5.63, -5.63, -5.63, -5.63, -5.63, -5.63, -5.63}, + d.getAttenuationArray(new double[]{125.0, 160.0, 200.0, 250.0, 315.0, 400.0, 500.0, 630.0, 800.0, + 1000.0, 1250.0, 1600.0, 2000.0, 2500.0, 3150.0, 4000.0, 5000.0, 6300.0, 8000.0}, + (float) Math.toRadians(31), (float) Math.toRadians(26)), 0.1); + assertEquals(-5.63, d.getAttenuation(freqTest[0], (float) Math.toRadians(31), (float) Math.toRadians(26)), 0.1); @@ -77,6 +84,7 @@ public void testInsert() { (float) Math.toRadians(26)), 0.1); assertEquals(-5.63, d.getAttenuation(freqTest[freqTest.length - 1] + 1, (float) Math.toRadians(31), (float) Math.toRadians(26)), 0.1); + } } \ No newline at end of file diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/LDENPropagationProcessData.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/LDENPropagationProcessData.java index 98bcc5ff7..d8e77c790 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/LDENPropagationProcessData.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/LDENPropagationProcessData.java @@ -39,6 +39,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import static org.noise_planet.noisemodelling.pathfinder.utils.PowerUtils.dbaToW; @@ -68,6 +69,16 @@ public LDENPropagationProcessData(ProfileBuilder builder, LDENConfig ldenConfig) public void setDirectionAttributes(Map directionAttributes) { this.directionAttributes = directionAttributes; + // Check if the directivities contain all required frequencies + directionAttributes.forEach((integer, directivitySphere) -> { + freq_lvl.forEach(frequency->{ + if(!directivitySphere.coverFrequency(frequency)) { + throw new IllegalArgumentException( + String.format(Locale.ROOT, + "The provided DirectivitySphere does not handle %d Hertz", frequency)); + } + }); + }); } @Override @@ -319,5 +330,10 @@ public double getAttenuation(double frequency, double phi, double theta) { public double[] getAttenuationArray(double[] frequencies, double phi, double theta) { return new double[frequencies.length]; } + + @Override + public boolean coverFrequency(double frequency) { + return true; + } } }