Skip to content

Commit

Permalink
fix attenuation
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-f committed Dec 12, 2024
1 parent 2ba6b9b commit b0f1538
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public NoiseMapInStack(NoiseMap multiThreadParent) {
double[] levels = new double[noiseMapComputeRaysOut.dayPathData.freq_lvl.size()];
for (Attenuation.SourceReceiverAttenuation lvl : receiverAttenuationLevels) {
levels = sumArray(levels,
dbaToW(sumArray(wToDba(wjSources.get((int) lvl.sourceId)), lvl.value)));
dbaToW(sumArray(wToDba(wjSources.get((int) lvl.source)), lvl.value)));
}
return levels;
}
Expand Down Expand Up @@ -224,7 +224,7 @@ public void pushInStack(ConcurrentLinkedDeque<CnossosPath> stack, Collection<Cno
* @param receiverId
*/
@Override
public void finalizeReceiver(final long receiverId) {
public void finalizeReceiver(int receiverId) {
if(!this.pathParameters.isEmpty()) {
if(noiseMapParameters.getExportRaysMethod() == org.noise_planet.noisemodelling.jdbc.NoiseMapParameters.ExportRaysMethods.TO_RAYS_TABLE) {
// Push propagation rays
Expand All @@ -245,7 +245,7 @@ public void finalizeReceiver(final long receiverId) {
}
long receiverPK = receiverId;
if(noiseMapComputeRaysOut.inputData != null) {
if(receiverId < noiseMapComputeRaysOut.inputData.receiversPk.size()) {
if(receiverId >= 0 && receiverId < noiseMapComputeRaysOut.inputData.receiversPk.size()) {
receiverPK = noiseMapComputeRaysOut.inputData.receiversPk.get((int)receiverId);
}
}
Expand All @@ -257,11 +257,11 @@ public void finalizeReceiver(final long receiverId) {
AttenuationVisitor attenuationVisitor = lDENAttenuationVisitor[timePeriod.ordinal()];
for (Attenuation.SourceReceiverAttenuation lvl : attenuationVisitor.receiverAttenuationLevels) {
NoiseMapParameters.TimePeriodParameters timePeriodParameters;
if (!levelsPerSourceLines.containsKey(lvl.sourceId)) {
if (!levelsPerSourceLines.containsKey(lvl.source)) {
timePeriodParameters = new NoiseMapParameters.TimePeriodParameters();
levelsPerSourceLines.put(lvl.sourceId, timePeriodParameters);
levelsPerSourceLines.put(lvl.source, timePeriodParameters);
} else {
timePeriodParameters = levelsPerSourceLines.get(lvl.sourceId);
timePeriodParameters = levelsPerSourceLines.get(lvl.source);
}
if (timePeriodParameters.getTimePeriodLevel(timePeriod) == null) {
timePeriodParameters.setTimePeriodLevel(timePeriod, lvl.value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,9 @@ void processStack(String tableName, ConcurrentLinkedDeque<Attenuation.SourceRece
Attenuation.SourceReceiverAttenuation row = stack.pop();
AttenuatedPaths.queueSize.decrementAndGet();
int parameterIndex = 1;
ps.setLong(parameterIndex++, row.receiverId);
ps.setLong(parameterIndex++, row.receiver);
if(!NoiseMapParameters.mergeSources) {
ps.setLong(parameterIndex++, row.sourceId);
ps.setLong(parameterIndex++, row.source);
}

if (!noiseMapParameters.computeLAEQOnly){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.math.Vector3D;
import org.noise_planet.noisemodelling.pathfinder.PathFinderVisitor;
import org.noise_planet.noisemodelling.pathfinder.path.Scene;
import org.noise_planet.noisemodelling.pathfinder.PathFinder;
import org.noise_planet.noisemodelling.pathfinder.profilebuilder.CutProfile;
Expand Down Expand Up @@ -8404,61 +8403,62 @@ public void TestFavorableConditionAttenuationRose() {
double globalValue = AcousticIndicatorsFunctions.sumDbArray(v.value);
if (globalValue > maxGlobalValue) {
maxGlobalValue = globalValue;
maxPowerReceiverIndex = (int) v.receiverId;
maxPowerReceiverIndex = (int) v.receiver;
}
}
assertEquals(idReceiver, maxPowerReceiverIndex);
}
}

/**
* Test optimisation feature {@link Scene#maximumError}
*/
@Test
public void testIgnoreNonSignificantSources() throws LayerDelaunayError {

GeometryFactory factory = new GeometryFactory();
//Scene dimension
Envelope cellEnvelope = new Envelope(new Coordinate(-1200, -1200, 0.), new Coordinate(1200, 1200, 0.));

//Create obstruction test object
ProfileBuilder builder = new ProfileBuilder();

builder.addGroundEffect(factory.toGeometry(new Envelope(0, 50, -250, 250)), 0.9);
builder.addGroundEffect(factory.toGeometry(new Envelope(50, 150, -250, 250)), 0.5);
builder.addGroundEffect(factory.toGeometry(new Envelope(150, 225, -250, 250)), 0.2);

builder.finishFeeding();

double[] roadLvl = new double[]{25.65, 38.15, 54.35, 60.35, 74.65, 66.75, 59.25, 53.95};
for(int i = 0; i < roadLvl.length; i++) {
roadLvl[i] = dbaToW(roadLvl[i]);
}

DirectPropagationProcessData rayData = new DirectPropagationProcessData(builder);
rayData.addReceiver(new Coordinate(0, 0, 4));
rayData.addSource(factory.createPoint(new Coordinate(10, 10, 1)), roadLvl);
rayData.addSource(factory.createPoint(new Coordinate(1100, 1100, 1)), roadLvl);
rayData.setComputeHorizontalDiffraction(true);
rayData.setComputeVerticalDiffraction(true);

rayData.maxSrcDist = 2000;
rayData.maximumError = 3; // 3 dB error max

AttenuationCnossosParameters attData = new AttenuationCnossosParameters();
attData.setHumidity(70);
attData.setTemperature(10);
RayOut propDataOut = new RayOut(true, attData, rayData);
PathFinder computeRays = new PathFinder(rayData);
computeRays.setThreadCount(1);
computeRays.run(propDataOut);

// Second source has not been computed because at best it would only increase the received level of only 0.0004 dB
assertEquals(1, propDataOut.receiversAttenuationLevels.size());

//TODO check the expected level and the delta should be reduced to at least 0.1
assertEquals(44.07, wToDba(sumArray(roadLvl.length, dbaToW(propDataOut.getVerticesSoundLevel().get(0).value))), 3);
}
//
// /**
// * Test optimisation feature {@link Scene#maximumError}
// * This feature is disabled and all sound sources are computed
// */
// @Test
// public void testIgnoreNonSignificantSources() throws LayerDelaunayError {
//
// GeometryFactory factory = new GeometryFactory();
// //Scene dimension
// Envelope cellEnvelope = new Envelope(new Coordinate(-1200, -1200, 0.), new Coordinate(1200, 1200, 0.));
//
// //Create obstruction test object
// ProfileBuilder builder = new ProfileBuilder();
//
// builder.addGroundEffect(factory.toGeometry(new Envelope(0, 50, -250, 250)), 0.9);
// builder.addGroundEffect(factory.toGeometry(new Envelope(50, 150, -250, 250)), 0.5);
// builder.addGroundEffect(factory.toGeometry(new Envelope(150, 225, -250, 250)), 0.2);
//
// builder.finishFeeding();
//
// double[] roadLvl = new double[]{25.65, 38.15, 54.35, 60.35, 74.65, 66.75, 59.25, 53.95};
// for(int i = 0; i < roadLvl.length; i++) {
// roadLvl[i] = dbaToW(roadLvl[i]);
// }
//
// DirectPropagationProcessData rayData = new DirectPropagationProcessData(builder);
// rayData.addReceiver(new Coordinate(0, 0, 4));
// rayData.addSource(factory.createPoint(new Coordinate(10, 10, 1)), roadLvl);
// rayData.addSource(factory.createPoint(new Coordinate(1100, 1100, 1)), roadLvl);
// rayData.setComputeHorizontalDiffraction(true);
// rayData.setComputeVerticalDiffraction(true);
//
// rayData.maxSrcDist = 2000;
// rayData.maximumError = 3; // 3 dB error max
//
// AttenuationCnossosParameters attData = new AttenuationCnossosParameters();
// attData.setHumidity(70);
// attData.setTemperature(10);
// RayOut propDataOut = new RayOut(true, attData, rayData);
// PathFinder computeRays = new PathFinder(rayData);
// computeRays.setThreadCount(1);
// computeRays.run(propDataOut);
//
// // Second source has not been computed because at best it would only increase the received level of only 0.0004 dB
// assertEquals(1, propDataOut.receiversAttenuationLevels.size());
//
// //TODO check the expected level and the delta should be reduced to at least 0.1
// assertEquals(44.07, wToDba(sumArray(roadLvl.length, dbaToW(propDataOut.getVerticesSoundLevel().get(0).value))), 3);
// }

@Test
public void testRoseIndex() {
Expand Down Expand Up @@ -8539,11 +8539,11 @@ public void testSourceLines() throws LayerDelaunayError, IOException, ParseExce
// Merge levels for each receiver for point sources
Map<Long, double[]> levelsPerReceiver = new HashMap<>();
for(Attenuation.SourceReceiverAttenuation lvl : propDataOut.receiversAttenuationLevels) {
if(!levelsPerReceiver.containsKey(lvl.receiverId)) {
levelsPerReceiver.put(lvl.receiverId, lvl.value);
if(!levelsPerReceiver.containsKey(lvl.receiver)) {
levelsPerReceiver.put(lvl.receiver, lvl.value);
} else {
// merge
levelsPerReceiver.put(lvl.receiverId, sumDbArray(levelsPerReceiver.get(lvl.receiverId),
levelsPerReceiver.put(lvl.receiver, sumDbArray(levelsPerReceiver.get(lvl.receiver),
lvl.value));
}
}
Expand All @@ -8552,11 +8552,11 @@ public void testSourceLines() throws LayerDelaunayError, IOException, ParseExce
// Merge levels for each receiver for lines sources
Map<Long, double[]> levelsPerReceiverLines = new HashMap<>();
for(Attenuation.SourceReceiverAttenuation lvl : propDataOutTest.receiversAttenuationLevels) {
if(!levelsPerReceiverLines.containsKey(lvl.receiverId)) {
levelsPerReceiverLines.put(lvl.receiverId, lvl.value);
if(!levelsPerReceiverLines.containsKey(lvl.receiver)) {
levelsPerReceiverLines.put(lvl.receiver, lvl.value);
} else {
// merge
levelsPerReceiverLines.put(lvl.receiverId, sumDbArray(levelsPerReceiverLines.get(lvl.receiverId),
levelsPerReceiverLines.put(lvl.receiver, sumDbArray(levelsPerReceiverLines.get(lvl.receiver),
lvl.value));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,10 @@ public void testPointDirectivity() throws Exception {
NoiseMap rout = (NoiseMap) out;

Attenuation.SourceReceiverAttenuation sl = rout.attenuatedPaths.lDenLevels.pop();
assertEquals(1, sl.receiverId);
assertEquals(1, sl.receiver);
assertEquals(73.3, sl.value[0], 1);
sl = rout.attenuatedPaths.lDenLevels.pop();
assertEquals(2, sl.receiverId);
assertEquals(2, sl.receiver);
assertEquals(53.3, sl.value[0], 1);
assertTrue(rout.attenuatedPaths.lDenLevels.isEmpty());

Expand Down Expand Up @@ -334,10 +334,10 @@ public void testLineDirectivity() throws Exception {
assertEquals(2, rout.attenuatedPaths.lDenLevels.size());

Attenuation.SourceReceiverAttenuation sl = rout.attenuatedPaths.lDenLevels.pop();
assertEquals(1, sl.receiverId);
assertEquals(1, sl.receiver);
assertEquals(68.3, sl.value[0], 1);
sl = rout.attenuatedPaths.lDenLevels.pop();
assertEquals(2, sl.receiverId);
assertEquals(2, sl.receiver);
assertEquals(70.8, sl.value[0], 1);

assertEquals(3 , rout.pathParameters.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ enum PathSearchStrategy {

/**
* No more propagation paths will be pushed for this receiver identifier
* @param receiverId Primary key of the receiver (not the id of the receiver in the subdomain)
* @param receiverId Id of the receiver in the subdomain
*/
void finalizeReceiver(long receiverId);
void finalizeReceiver(int receiverId);

/**
* If the implementation does not support thread concurrency, this method is called to return an instance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,11 @@ public CutProfile computeVEdgeDiffraction(ReceiverPointInfo rcv, SourcePointInfo


if(rcv.receiverIndex >= 0 && rcv.receiverIndex < data.receiversPk.size()) {
mainProfile.getReceiver().id = rcv.receiverIndex;
mainProfile.getReceiver().receiverPk = data.receiversPk.get(rcv.receiverIndex);
}
if(src.sourceIndex >= 0 && src.sourceIndex < data.sourcesPk.size()) {
mainProfile.getSource().id = src.sourceIndex;
mainProfile.getSource().sourcePk = data.sourcesPk.get(src.sourceIndex);
}

Expand Down Expand Up @@ -732,9 +734,11 @@ public IComputePathsOut.PathSearchStrategy computeReflexion(ReceiverPointInfo rc
mainProfileCutPoints.size() - 1).toArray(CutPoint[]::new));

if(rcv.receiverIndex >= 0 && rcv.receiverIndex < data.receiversPk.size()) {
mainProfile.getReceiver().id = rcv.receiverIndex;
mainProfile.getReceiver().receiverPk = data.receiversPk.get(rcv.receiverIndex);
}
if(src.sourceIndex >= 0 && src.sourceIndex < data.sourcesPk.size()) {
mainProfile.getSource().id = src.sourceIndex;
mainProfile.getSource().sourcePk = data.sourcesPk.get(src.sourceIndex);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public PathFinderVisitor(boolean keepCutPlanes) {
* @param receiverId
*/
@Override
public void finalizeReceiver(long receiverId) {
public void finalizeReceiver(int receiverId) {

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.locationtech.jts.geom.Coordinate;
import org.noise_planet.noisemodelling.pathfinder.path.Scene;
import org.noise_planet.noisemodelling.pathfinder.utils.geometry.JTSUtility;

import java.util.ArrayList;
Expand Down Expand Up @@ -79,26 +80,41 @@ public void sort(Coordinate c0) {
* @return the absorption coefficient of this path
*/
@JsonIgnore
public double getGPath(CutPoint p0, CutPoint p1) {
public double getGPath(CutPoint p0, CutPoint p1, double buildingRoofG) {
double totalLength = 0;
double rsLength = 0.0;

// Extract part of the path from the specified argument
List<CutPoint> reduced = cutPoints.subList(cutPoints.indexOf(p0), cutPoints.indexOf(p1) + 1);
int i0 = cutPoints.indexOf(p0);
int i1 = cutPoints.indexOf(p1);
if(i0 == -1 || i1 == -1 || i1 < i0) {
return 0.0;
}

for(int index = 0; index < reduced.size() - 1; index++) {
CutPoint current = reduced.get(index);
double segmentLength = current.getCoordinate().distance(reduced.get(index+1).getCoordinate());
rsLength += segmentLength * current.getGroundCoefficient();
totalLength += segmentLength;
boolean aboveRoof = false;
for(int index = 0; index < i1; index++) {
CutPoint current = cutPoints.get(index);
if(current instanceof CutPointWall) {
CutPointWall currentWall = (CutPointWall) current;
if(!aboveRoof && currentWall.intersectionType.equals(CutPointWall.INTERSECTION_TYPE.BUILDING_ENTER)) {
aboveRoof = true;
} else if(aboveRoof && currentWall.intersectionType.equals(CutPointWall.INTERSECTION_TYPE.BUILDING_EXIT)) {
aboveRoof = false;
}
}
if(index >= i0) {
double segmentLength = current.getCoordinate().distance(cutPoints.get(index + 1).getCoordinate());
rsLength += segmentLength * (aboveRoof ? buildingRoofG : current.getGroundCoefficient());
totalLength += segmentLength;
}
}
return rsLength / totalLength;
}

@JsonIgnore
public double getGPath() {
if(!cutPoints.isEmpty()) {
return getGPath(cutPoints.get(0), cutPoints.get(cutPoints.size() - 1));
return getGPath(cutPoints.get(0), cutPoints.get(cutPoints.size() - 1), Scene.DEFAULT_G_BUILDING);
} else {
return 0;
}
Expand Down Expand Up @@ -204,6 +220,11 @@ public static List<Coordinate> computePtsGround(List<CutPoint> pts, List<Integer
pts2D.add(new Coordinate(cut.getCoordinate().x, cut.getCoordinate().y, cut.getzGround()));
overArea = false;
}
} else if (cut instanceof CutPointReflection) {
// Z ground profile is duplicated for reflection point before and after
pts2D.add(new Coordinate(cut.getCoordinate().x, cut.getCoordinate().y, cut.getzGround()));
pts2D.add(new Coordinate(cut.getCoordinate().x, cut.getCoordinate().y, cut.getzGround()));
pts2D.add(new Coordinate(cut.getCoordinate().x, cut.getCoordinate().y, cut.getzGround()));
} else {
// we will ignore topographic point if we are over a building
if (!(overArea && cut instanceof CutPointTopography)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Arrays;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.noise_planet.noisemodelling.pathfinder.PathFinderTest.assertZProfil;
Expand Down Expand Up @@ -330,7 +331,10 @@ public void test2DGroundProfile() {

assertEquals(9, cutProfile.cutPoints.size());

List<Coordinate> zProfile = cutProfile.computePts2DGround();
List<Integer> index = new ArrayList<>(cutProfile.cutPoints.size());
List<Coordinate> zProfile = cutProfile.computePts2DGround(index);

assertEquals(cutProfile.cutPoints.size(), index.size());

/* Table 148 */
List<Coordinate> expectedZProfile = new ArrayList<>();
Expand All @@ -352,6 +356,9 @@ public void test2DGroundProfile() {
//Assertion
assertZProfil(expectedZProfile, zProfile);

assertArrayEquals(new int[]{0, 2, 4, 6, 8, 10, 12, 12, 13},
index.stream().mapToInt(Integer::intValue).toArray());


}
}
Loading

0 comments on commit b0f1538

Please sign in to comment.