Skip to content

Commit

Permalink
Merge pull request #653 from Universite-Gustave-Eiffel/directivity_patch
Browse files Browse the repository at this point in the history
check consistency of frequencies between sources and directivity spheres
  • Loading branch information
pierromond authored Mar 19, 2024
2 parents 793e630 + 1053972 commit 76aa95e
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import java.io.Serializable;
import java.util.*;
import java.util.function.DoublePredicate;

/**
* Describe Attenuation directivity over a sphere
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -363,4 +351,9 @@ public double[] getAttenuation() {
return attenuation;
}
}

@Override
public boolean coverFrequency(double frequency) {
return Arrays.stream(frequencies).anyMatch(x -> x == frequency);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -213,5 +213,10 @@ public double[] getAttenuationArray(double[] frequencies, double phi, double the
}
return ret;
}

@Override
public boolean coverFrequency(double frequency) {
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -209,5 +209,10 @@ public double[] getAttenuationArray(double[] frequencies, double phi, double the
}
return ret;
}

@Override
public boolean coverFrequency(double frequency) {
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -68,6 +69,16 @@ public LDENPropagationProcessData(ProfileBuilder builder, LDENConfig ldenConfig)

public void setDirectionAttributes(Map<Integer, DirectivitySphere> 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
Expand Down Expand Up @@ -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;
}
}
}

0 comments on commit 76aa95e

Please sign in to comment.