From a7499aa76e11b851a14b7b984d502a9872bddef1 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Wed, 15 Nov 2017 11:37:23 +0100
Subject: [PATCH] =?UTF-8?q?-=20classe=20CourbeRemous=20:=20ajout=20d'un=20?=
 =?UTF-8?q?flag=20"debug"=20comme=20param=C3=A8tre=20du=20constructeur=20-?=
 =?UTF-8?q?=20classe=20CourbeRemous=20:=20modif=20de=20l'algo=20de=20d?=
 =?UTF-8?q?=C3=A9tection=20du=20ressaut=20-=20ajout=20du=20test=20automati?=
 =?UTF-8?q?que=20des=20courbes=20de=20remous=20par=20d=C3=A9placement=20d'?=
 =?UTF-8?q?une=20fen=C3=AAtre=20de=20calcul=20sur=20un=20bief=20-=20modifs?=
 =?UTF-8?q?=20des=20tests=20unitaires=20pour=20suivre=20(en=20partie)=20la?=
 =?UTF-8?q?=20modif=20de=20l'algo=20de=20d=C3=A9tection=20du=20ressaut?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 package.json                                  |   1 +
 spec/remous_rect_euler_pentefaible.spec.ts    |   4 +-
 spec/remous_rect_euler_penteforte.spec.ts     |  18 +-
 spec/remous_rect_rk4_pentefaible.spec.ts      |  16 +-
 spec/remous_rect_rk4_penteforte.spec.ts       |  32 +-
 spec/remous_rect_trapezes_pentefaible.spec.ts |  16 +-
 spec/remous_rect_trapezes_penteforte.spec.ts  |  29 +-
 spec/remous_trapez.spec.ts                    |  57 ++-
 spec/test-remous-fenetre.ts                   | 360 ++++++++++++++++++
 spec/tsconfig-remous-fenetre.spec.json        |  10 +
 spec/tsconfig.spec.json                       |   3 +
 src/remous.ts                                 | 141 ++++---
 12 files changed, 593 insertions(+), 94 deletions(-)
 create mode 100644 spec/test-remous-fenetre.ts
 create mode 100644 spec/tsconfig-remous-fenetre.spec.json

diff --git a/package.json b/package.json
index 971bacb9..9229f68d 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
   "scripts": {
     "build": "./node_modules/typescript/bin/tsc --p src/tsconfig.app.json",
     "buildspec": "./node_modules/typescript/bin/tsc --p spec/tsconfig.spec.json",
+    "runtestremous": "./node_modules/typescript/bin/tsc --p spec/tsconfig-remous-fenetre.spec.json && node ./build/spec/test-remous-fenetre.js",
     "jasmine": "npm run buildspec && ./node_modules/.bin/jasmine",
     "karma": "./node_modules/typescript/bin/tsc --p spec/tsconfig.spec.json && ./node_modules/karma/bin/karma start",
     "lint": "./node_modules/tslint/bin/tslint",
diff --git a/spec/remous_rect_euler_pentefaible.spec.ts b/spec/remous_rect_euler_pentefaible.spec.ts
index 37459134..0a0446ab 100644
--- a/spec/remous_rect_euler_pentefaible.spec.ts
+++ b/spec/remous_rect_euler_pentefaible.spec.ts
@@ -236,7 +236,7 @@ describe('Class Remous / section rectangulaire :', () => {
             let f = { "0": 0.9872500000000014, "5": 0.9872500000000014, "10": 0.9872500000000014, "15": 0.9872500000000014, "20": 0.9880000000000013, "25": 0.9887500000000012, "30": 0.9895000000000012, "35": 0.9902500000000011, "40": 0.991000000000001, "45": 0.9917500000000009, "50": 0.9925000000000008, "55": 0.9932500000000007, "60": 0.9940000000000007, "65": 0.9947500000000006, "70": 0.9955000000000005, "75": 0.9962500000000004, "80": 0.9970000000000003, "85": 0.9977500000000002, "90": 0.9985000000000002, "95": 0.9992500000000001, "100": 1 };
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
-            expect(res["tor"] == undefined).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
+            expect(Object.keys(res["tor"]).length == 0).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
 
             let x = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100];
             compareArray("abscisses", res["trX"], x);
@@ -289,7 +289,7 @@ describe('Class Remous / section rectangulaire :', () => {
             let f = { "0": 0.805499999999999, "5": 0.802249999999999, "10": 0.7984999999999991, "15": 0.7947499999999992, "20": 0.7909999999999993, "25": 0.7867499999999993, "30": 0.7824999999999993, "35": 0.7782499999999993, "40": 0.7739999999999994, "45": 0.7692499999999994, "50": 0.7644999999999995, "55": 0.7592499999999995, "60": 0.7539999999999996, "65": 0.7482499999999996, "70": 0.7424999999999997, "75": 0.7362499999999997, "80": 0.7299999999999998, "85": 0.7232499999999998, "90": 0.7159999999999999, "95": 0.7082499999999999, "100": 0.7 };
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
-            expect(res["tor"] == undefined).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
+            expect(Object.keys(res["tor"]).length == 0).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
 
             let x = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100];
             compareArray("abscisses", res["trX"], x);
diff --git a/spec/remous_rect_euler_penteforte.spec.ts b/spec/remous_rect_euler_penteforte.spec.ts
index 46d99637..9c518f64 100644
--- a/spec/remous_rect_euler_penteforte.spec.ts
+++ b/spec/remous_rect_euler_penteforte.spec.ts
@@ -5,6 +5,13 @@ import { round } from "../src/base";
 import { cLog } from "../src/util/log";
 import { Message, MessageCode } from "../src/util/message";
 
+/*
+   Certaines valeurs de ligne d'eau torrentielle étaient auparavant remplacées par une valeur fluviale
+   pour la représentation graphique du ressaut (mais fausse car torrentielle).
+   Idem pour la réciproque fluvial/torrentiel.
+   Le code ne faisant plus ça, les valeurs de validation ont été remplacée par les bonnes.
+ */
+
 describe('Class Remous / section rectangulaire :', () => {
     describe('méthode Euler explicite :', () => {
         it("forte pente, ressaut avant l'amont", () => {
@@ -94,8 +101,8 @@ describe('Class Remous / section rectangulaire :', () => {
             let f = {};
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
-            // let t = { 0.000: 0.15, 5.000: 0.207, 10.000: 0.241, 15.000: 0.252, 20.000: 0.253, 25.000: 0.253, 30.000: 0.253, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253, 95.000: 0.253, 100.000: 0.45 };
-            let t = { "0": 0.15, "5": 0.20725000000000002, "10": 0.23500000000000001, "15": 0.24675000000000002, "20": 0.251, "25": 0.25225, "30": 0.25249999999999995, "35": 0.2527499999999999, "40": 0.2529999999999999, "45": 0.2527499999999999, "50": 0.2529999999999999, "55": 0.2527499999999999, "60": 0.2529999999999999, "65": 0.2527499999999999, "70": 0.2529999999999999, "75": 0.2527499999999999, "80": 0.2529999999999999, "85": 0.2527499999999999, "90": 0.2529999999999999, "95": 0.2527499999999999, "100": 0.45 };
+            // let t = { "0": 0.15, "5": 0.20725000000000002, "10": 0.23500000000000001, "15": 0.24675000000000002, "20": 0.251, "25": 0.25225, "30": 0.25249999999999995, "35": 0.2527499999999999, "40": 0.2529999999999999, "45": 0.2527499999999999, "50": 0.2529999999999999, "55": 0.2527499999999999, "60": 0.2529999999999999, "65": 0.2527499999999999, "70": 0.2529999999999999, "75": 0.2527499999999999, "80": 0.2529999999999999, "85": 0.2527499999999999, "90": 0.2529999999999999, "95": 0.2527499999999999, "100": 0.45 };
+            let t = { "0": 0.15, "5": 0.20725000000000002, "10": 0.23500000000000001, "15": 0.24675000000000002, "20": 0.251, "25": 0.25225, "30": 0.25249999999999995, "35": 0.2527499999999999, "40": 0.2529999999999999, "45": 0.2527499999999999, "50": 0.2529999999999999, "55": 0.2527499999999999, "60": 0.2529999999999999, "65": 0.2527499999999999, "70": 0.2529999999999999, "75": 0.2527499999999999, "80": 0.2529999999999999, "85": 0.2527499999999999, "90": 0.2529999999999999, "95": 0.2527499999999999, "100": 0.253 }; // dernière valeur modifiée pour la raison en tête de fichier
             compareObject("Ytorrentiel", res["tor"], t, 0.03);
 
             let x = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100];
@@ -222,7 +229,8 @@ describe('Class Remous / section rectangulaire :', () => {
 
             // données de validation : version Typescript (Oct 2017) méthode des trapèzes
 
-            let f = { "0": 0.15, "1": 0.7560000000000007, "2": 0.8120000000000005, "3": 0.8670000000000002, "4": 0.9205000000000001, "5": 0.9735, "5.5": 1, "5.25": 0.98675, "4.75": 0.96025, "4.5": 0.9470000000000001, "4.25": 0.9337500000000001, "3.75": 0.9072500000000001, "3.5": 0.8940000000000001, "3.25": 0.8807500000000001, "2.75": 0.8532500000000003, "2.5": 0.8395000000000004, "2.25": 0.8257500000000004, "1.75": 0.7982500000000006, "1.5": 0.7845000000000006, "1.25": 0.7702500000000007, "0.75": 0.7417500000000007, "0.5": 0.7275000000000007, "0.25": 0.7132500000000007 };
+            // let f = { "0": 0.15, "1": 0.7560000000000007, "2": 0.8120000000000005, "3": 0.8670000000000002, "4": 0.9205000000000001, "5": 0.9735, "5.5": 1, "5.25": 0.98675, "4.75": 0.96025, "4.5": 0.9470000000000001, "4.25": 0.9337500000000001, "3.75": 0.9072500000000001, "3.5": 0.8940000000000001, "3.25": 0.8807500000000001, "2.75": 0.8532500000000003, "2.5": 0.8395000000000004, "2.25": 0.8257500000000004, "1.75": 0.7982500000000006, "1.5": 0.7845000000000006, "1.25": 0.7702500000000007, "0.75": 0.7417500000000007, "0.5": 0.7275000000000007, "0.25": 0.7132500000000007 };
+            let f = { "0": 0.698, "1": 0.7560000000000007, "2": 0.8120000000000005, "3": 0.8670000000000002, "4": 0.9205000000000001, "5": 0.9735, "5.5": 1, "5.25": 0.98675, "4.75": 0.96025, "4.5": 0.9470000000000001, "4.25": 0.9337500000000001, "3.75": 0.9072500000000001, "3.5": 0.8940000000000001, "3.25": 0.8807500000000001, "2.75": 0.8532500000000003, "2.5": 0.8395000000000004, "2.25": 0.8257500000000004, "1.75": 0.7982500000000006, "1.5": 0.7845000000000006, "1.25": 0.7702500000000007, "0.75": 0.7417500000000007, "0.5": 0.7275000000000007, "0.25": 0.7132500000000007 }; // première valeur modifiée pour la raison en tête de fichier
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
             let t = { "0": 0.15, "1": 0.161, "2": 0.17200000000000001, "3": 0.18100000000000002, "0.25": 0.15275, "0.5": 0.1555, "0.75": 0.15825, "1.25": 0.16375, "1.5": 0.1665, "1.75": 0.16925, "2.25": 0.17425000000000002, "2.5": 0.17650000000000002, "2.75": 0.17875000000000002, "3.25": 0.18325000000000002, "3.5": 0.18550000000000003, "3.75": 0.9072500000000001 };
@@ -281,7 +289,7 @@ describe('Class Remous / section rectangulaire :', () => {
 
             // données de validation : version Typescript (Oct 2017) méthode trapèzes
 
-            expect(res["flu"] == undefined).toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
+            expect(Object.keys(res["flu"]).length == 0).toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
             let t = { "0": 0.1, "1": 0.11425000000000002, "2": 0.12750000000000003, "3": 0.14025000000000004, "4": 0.15200000000000005, "5": 0.16325000000000006, "6": 0.17350000000000007, "7": 0.18325000000000008, "8": 0.1920000000000001, "9": 0.1997500000000001, "10": 0.2070000000000001, "11": 0.2137500000000001, "12": 0.2195000000000001, "13": 0.22475000000000012, "14": 0.22900000000000012, "15": 0.23275000000000012, "16": 0.23600000000000013, "17": 0.23875000000000013, "18": 0.24100000000000013, "19": 0.24325000000000013, "20": 0.24500000000000013, "21": 0.24625000000000014, "22": 0.24750000000000014, "23": 0.2485000000000001, "24": 0.2492500000000001, "25": 0.2502500000000001, "26": 0.25050000000000006, "27": 0.25075000000000003, "28": 0.251, "29": 0.25125, "30": 0.25149999999999995 };
             compareObject("Ytorrentiel", res["tor"], t, 0.01);
@@ -334,7 +342,7 @@ describe('Class Remous / section rectangulaire :', () => {
 
             // données de validation : version PHP (Oct 2017) méthode trapèzes
 
-            expect(res["flu"] == undefined).toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
+            expect(Object.keys(res["flu"]).length == 0).toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
             let t = { 0.000: 0.35, 0.100: 0.345, 0.200: 0.34, 0.300: 0.336, 0.400: 0.332, 0.500: 0.329, 0.600: 0.326, 0.700: 0.323, 0.800: 0.32, 0.900: 0.318, 1.000: 0.316, 1.100: 0.313, 1.200: 0.311, 1.300: 0.309, 1.400: 0.308, 1.500: 0.306, 1.600: 0.305, 1.700: 0.303, 1.800: 0.302, 1.900: 0.3, 2.000: 0.298, 2.100: 0.297, 2.200: 0.295, 2.300: 0.294, 2.400: 0.293, 2.500: 0.292, 2.600: 0.291, 2.700: 0.291, 2.800: 0.29, 2.900: 0.289, 3.000: 0.288, 3.100: 0.287, 3.200: 0.287, 3.300: 0.286, 3.400: 0.285, 3.500: 0.284, 3.600: 0.283, 3.700: 0.283, 3.800: 0.282, 3.900: 0.281, 4.000: 0.28, 4.100: 0.28, 4.200: 0.279, 4.300: 0.278, 4.400: 0.277, 4.500: 0.276, 4.600: 0.276, 4.700: 0.275, 4.800: 0.274, 4.900: 0.273, 5.000: 0.272, 5.100: 0.272, 5.200: 0.271, 5.300: 0.27, 5.400: 0.269, 5.500: 0.269, 5.600: 0.269, 5.700: 0.269, 5.800: 0.269, 5.900: 0.269, 6.000: 0.269, 6.100: 0.269, 6.200: 0.269, 6.300: 0.269, 6.400: 0.269, 6.500: 0.269, 6.600: 0.269, 6.700: 0.269, 6.800: 0.269, 6.900: 0.269, 7.000: 0.269, 7.100: 0.269, 7.200: 0.269, 7.300: 0.269, 7.400: 0.269, 7.500: 0.269, 7.600: 0.269, 7.700: 0.269, 7.800: 0.269, 7.900: 0.269, 8.000: 0.269, 8.100: 0.269, 8.200: 0.269, 8.300: 0.269, 8.400: 0.269, 8.500: 0.269, 8.600: 0.269, 8.700: 0.269, 8.800: 0.269, 8.900: 0.269, 9.000: 0.269, 9.100: 0.269, 9.200: 0.269, 9.300: 0.269, 9.400: 0.269, 9.500: 0.269, 9.600: 0.269, 9.700: 0.269, 9.800: 0.269, 9.900: 0.269, 10.000: 0.269 };
             compareObject("Ytorrentiel", res["tor"], t, 0.03);
diff --git a/spec/remous_rect_rk4_pentefaible.spec.ts b/spec/remous_rect_rk4_pentefaible.spec.ts
index 52b6bbf3..58828299 100644
--- a/spec/remous_rect_rk4_pentefaible.spec.ts
+++ b/spec/remous_rect_rk4_pentefaible.spec.ts
@@ -5,6 +5,12 @@ import { round } from "../src/base";
 import { cLog } from "../src/util/log";
 import { Message, MessageCode } from "../src/util/message";
 
+/*
+  Le code de modification des lignes fluviale et torrentielle a été modifié, on enlève un point de plus
+  ligne d'eau complète : if (iSens * (rXCC - rX) < 0) remplacé par if (iSens * (rXCC - rX) <= 0)
+  lign d'eau partielle : if (iSens * (rXCN - xRst) > 0)  remplacé par if (iSens * (rXCN - xRst) >= 0)
+  Les données de validation ont été modifiées en conséquence
+*/
 
 describe('Class Remous / section rectangulaire :', () => {
     describe('méthode Runge-Kutta ordre 4 :', () => {
@@ -96,10 +102,12 @@ describe('Class Remous / section rectangulaire :', () => {
 
             // données de validation : version PHP (Oct 2017) méthode RungeKutta4
 
-            let f = { 100.000: 0.42, 95.000: 0.583, 90.000: 0.604, 85.000: 0.621, 80.000: 0.636, 75.000: 0.65, 70.000: 0.662, 65.000: 0.673, 60.000: 0.683, 55.000: 0.692, 50.000: 0.701, 45.000: 0.709, 40.000: 0.717, 35.000: 0.724, 30.000: 0.731, 25.000: 0.737, 20.000: 0.743, 15.000: 0.749, 10.000: 0.755, 5.000: 0.76, 0.000: 0.15 };
+            // let f = { 100.000: 0.42, 95.000: 0.583, 90.000: 0.604, 85.000: 0.621, 80.000: 0.636, 75.000: 0.65, 70.000: 0.662, 65.000: 0.673, 60.000: 0.683, 55.000: 0.692, 50.000: 0.701, 45.000: 0.709, 40.000: 0.717, 35.000: 0.724, 30.000: 0.731, 25.000: 0.737, 20.000: 0.743, 15.000: 0.749, 10.000: 0.755, 5.000: 0.76, 0.000: 0.15 };
+            let f = { 100.000: 0.42, 95.000: 0.583, 90.000: 0.604, 85.000: 0.621, 80.000: 0.636, 75.000: 0.65, 70.000: 0.662, 65.000: 0.673, 60.000: 0.683, 55.000: 0.692, 50.000: 0.701, 45.000: 0.709, 40.000: 0.717, 35.000: 0.724, 30.000: 0.731, 25.000: 0.737, 20.000: 0.743, 15.000: 0.749, 10.000: 0.755, 5.000: 0.76 }; // dernière valeur supprimée pour la raison en tête de fichier
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
-            let t = { 0.000: 0.15, 5.000: 0.76 };
+            // let t = { 0.000: 0.15, 5.000: 0.76 };
+            let t = { 0.000: 0.15 }; // dernière valeur supprimée pour la raison en tête de fichier
             compareObject("Ytorrentiel", res["tor"], t, 0.03);
 
             let x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
@@ -221,7 +229,7 @@ describe('Class Remous / section rectangulaire :', () => {
             let f = { 100.000: 1, 95.000: 0.999, 90.000: 0.999, 85.000: 0.998, 80.000: 0.997, 75.000: 0.997, 70.000: 0.996, 65.000: 0.996, 60.000: 0.995, 55.000: 0.994, 50.000: 0.994, 45.000: 0.993, 40.000: 0.993, 35.000: 0.992, 30.000: 0.991, 25.000: 0.991, 20.000: 0.99, 15.000: 0.99, 10.000: 0.989, 5.000: 0.989, 0.000: 0.988 };
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
-            expect(res["tor"] == undefined).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
+            expect(Object.keys(res["tor"]).length == 0).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
 
             let x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
             compareArray("abscisses", res["trX"], x);
@@ -274,7 +282,7 @@ describe('Class Remous / section rectangulaire :', () => {
             let f = { 100.000: 0.7, 95.000: 0.708, 90.000: 0.716, 85.000: 0.723, 80.000: 0.73, 75.000: 0.737, 70.000: 0.743, 65.000: 0.749, 60.000: 0.754, 55.000: 0.759, 50.000: 0.764, 45.000: 0.769, 40.000: 0.774, 35.000: 0.779, 30.000: 0.783, 25.000: 0.787, 20.000: 0.791, 15.000: 0.795, 10.000: 0.799, 5.000: 0.802, 0.000: 0.806 };
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
-            expect(res["tor"] == undefined).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
+            expect(Object.keys(res["tor"]).length == 0).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
 
             let x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
             compareArray("abscisses", res["trX"], x);
diff --git a/spec/remous_rect_rk4_penteforte.spec.ts b/spec/remous_rect_rk4_penteforte.spec.ts
index 61109e1c..d816edb1 100644
--- a/spec/remous_rect_rk4_penteforte.spec.ts
+++ b/spec/remous_rect_rk4_penteforte.spec.ts
@@ -5,6 +5,22 @@ import { round } from "../src/base";
 import { cLog } from "../src/util/log";
 import { Message, MessageCode } from "../src/util/message";
 
+/*
+   cas 1 :
+   Certaines valeurs de ligne d'eau torrentielle étaient auparavant remplacées par une valeur fluviale
+   pour la représentation graphique du ressaut (mais fausse car torrentielle).
+   Idem pour la réciproque fluvial/torrentiel.
+   Le code ne faisant plus ça, les valeurs de validation ont été remplacée par les bonnes.
+ */
+
+/*
+  cas 2 :
+  Le code de modification des lignes fluviale et torrentielle a été modifié, on enlève un point de plus
+  ligne d'eau complète : if (iSens * (rXCC - rX) < 0) remplacé par if (iSens * (rXCC - rX) <= 0)
+  lign d'eau partielle : if (iSens * (rXCN - xRst) > 0)  remplacé par if (iSens * (rXCN - xRst) >= 0)
+  Les données de validation ont été modifiées en conséquence
+*/
+
 describe('Class Remous / section rectangulaire :', () => {
     describe('méthode Runge-Kutta ordre 4 :', () => {
         it("forte pente, ressaut avant l'amont", () => {
@@ -94,7 +110,8 @@ describe('Class Remous / section rectangulaire :', () => {
             let f = {};
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
-            let t = { 0.000: 0.15, 5.000: 0.198, 10.000: 0.228, 15.000: 0.243, 20.000: 0.249, 25.000: 0.251, 30.000: 0.252, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253, 95.000: 0.253, 100.000: 0.45 };
+            // let t = { 0.000: 0.15, 5.000: 0.198, 10.000: 0.228, 15.000: 0.243, 20.000: 0.249, 25.000: 0.251, 30.000: 0.252, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253, 95.000: 0.253, 100.000: 0.45 };
+            let t = { 0.000: 0.15, 5.000: 0.198, 10.000: 0.228, 15.000: 0.243, 20.000: 0.249, 25.000: 0.251, 30.000: 0.252, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253, 95.000: 0.253, 100.000: 0.253 }; // dernière valeur remplacée pour la raison 1 en tête de fichier
             compareObject("Ytorrentiel", res["tor"], t, 0.03);
 
             let x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
@@ -154,10 +171,12 @@ describe('Class Remous / section rectangulaire :', () => {
 
             // données de validation : version PHP (Oct 2017) méthode RungeKutta4
 
-            let f = { 100.000: 1, 95.000: 0.728, 90.000: 0.521 };
+            // let f = { 100.000: 1, 95.000: 0.728, 90.000: 0.521 };
+            let f = { 100.000: 1, 95.000: 0.728 }; // dernière valeur supprimée pour la raison 2 en tête de fichier
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
-            let t = { 0.000: 0.15, 5.000: 0.198, 10.000: 0.228, 15.000: 0.243, 20.000: 0.249, 25.000: 0.251, 30.000: 0.252, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.521 };
+            // let t = { 0.000: 0.15, 5.000: 0.198, 10.000: 0.228, 15.000: 0.243, 20.000: 0.249, 25.000: 0.251, 30.000: 0.252, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.521 };
+            let t = { 0.000: 0.15, 5.000: 0.198, 10.000: 0.228, 15.000: 0.243, 20.000: 0.249, 25.000: 0.251, 30.000: 0.252, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253 }; // dernière valeur remplacée pour la raison 1 en tête de fichier
             compareObject("Ytorrentiel", res["tor"], t, 0.03);
 
             let x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
@@ -217,7 +236,8 @@ describe('Class Remous / section rectangulaire :', () => {
 
             // données de validation : version PHP (Oct 2017) méthode RungeKutta4
 
-            let f = { 5.500: 1, 5.250: 0.987, 5.000: 0.974, 4.750: 0.96, 4.500: 0.947, 4.250: 0.934, 4.000: 0.921, 3.750: 0.907, 3.500: 0.894, 3.250: 0.88, 3.000: 0.867, 2.750: 0.853, 2.500: 0.84, 2.250: 0.826, 2.000: 0.812, 1.750: 0.798, 1.500: 0.785, 1.250: 0.771, 1.000: 0.756, 0.750: 0.742, 0.500: 0.728, 0.250: 0.713, 0.000: 0.15 };
+            // let f = { 5.500: 1, 5.250: 0.987, 5.000: 0.974, 4.750: 0.96, 4.500: 0.947, 4.250: 0.934, 4.000: 0.921, 3.750: 0.907, 3.500: 0.894, 3.250: 0.88, 3.000: 0.867, 2.750: 0.853, 2.500: 0.84, 2.250: 0.826, 2.000: 0.812, 1.750: 0.798, 1.500: 0.785, 1.250: 0.771, 1.000: 0.756, 0.750: 0.742, 0.500: 0.728, 0.250: 0.713, 0.000: 0.15 };
+            let f = { 5.500: 1, 5.250: 0.987, 5.000: 0.974, 4.750: 0.96, 4.500: 0.947, 4.250: 0.934, 4.000: 0.921, 3.750: 0.907, 3.500: 0.894, 3.250: 0.88, 3.000: 0.867, 2.750: 0.853, 2.500: 0.84, 2.250: 0.826, 2.000: 0.812, 1.750: 0.798, 1.500: 0.785, 1.250: 0.771, 1.000: 0.756, 0.750: 0.742, 0.500: 0.728, 0.250: 0.713, 0.000: 0.699 }; // dernière valeur remplacée pour la raison 1 en tête de fichier
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
             let t = { 0.000: 0.15, 0.250: 0.153, 0.500: 0.156, 0.750: 0.158, 1.000: 0.161, 1.250: 0.164, 1.500: 0.166, 1.750: 0.169, 2.000: 0.171, 2.250: 0.174, 2.500: 0.176, 2.750: 0.179, 3.000: 0.181, 3.250: 0.183, 3.500: 0.186, 3.750: 0.907 };
@@ -276,7 +296,7 @@ describe('Class Remous / section rectangulaire :', () => {
 
             // données de validation : version PHP (Oct 2017) méthode RungeKutta4
 
-            expect(res["flu"] == undefined).toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
+            expect(Object.keys(res["flu"]).length == 0).toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
             let t = { 0.000: 0.1, 5.000: 0.162, 10.000: 0.206, 15.000: 0.232, 20.000: 0.244, 25.000: 0.25, 30.000: 0.252, 35.000: 0.252, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253, 95.000: 0.253, 100.000: 0.253 };
             compareObject("Ytorrentiel", res["tor"], t, 0.01);
@@ -329,7 +349,7 @@ describe('Class Remous / section rectangulaire :', () => {
 
             // données de validation : version PHP (Oct 2017) méthode RungeKutta4
 
-            expect(res["flu"] == undefined).toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
+            expect(Object.keys(res["flu"]).length == 0).toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
             let t = { 0.000: 0.35, 0.100: 0.344, 0.200: 0.34, 0.300: 0.335, 0.400: 0.332, 0.500: 0.328, 0.600: 0.325, 0.700: 0.322, 0.800: 0.32, 0.900: 0.317, 1.000: 0.315, 1.100: 0.313, 1.200: 0.31, 1.300: 0.309, 1.400: 0.307, 1.500: 0.305, 1.600: 0.303, 1.700: 0.302, 1.800: 0.3, 1.900: 0.299, 2.000: 0.297, 2.100: 0.296, 2.200: 0.295, 2.300: 0.294, 2.400: 0.293, 2.500: 0.291, 2.600: 0.29, 2.700: 0.289, 2.800: 0.288, 2.900: 0.287, 3.000: 0.287, 3.100: 0.286, 3.200: 0.285, 3.300: 0.284, 3.400: 0.283, 3.500: 0.282, 3.600: 0.282, 3.700: 0.281, 3.800: 0.28, 3.900: 0.279, 4.000: 0.279, 4.100: 0.278, 4.200: 0.278, 4.300: 0.277, 4.400: 0.276, 4.500: 0.276, 4.600: 0.275, 4.700: 0.275, 4.800: 0.274, 4.900: 0.274, 5.000: 0.273, 5.100: 0.273, 5.200: 0.272, 5.300: 0.272, 5.400: 0.271, 5.500: 0.271, 5.600: 0.271, 5.700: 0.27, 5.800: 0.27, 5.900: 0.269, 6.000: 0.269, 6.100: 0.269, 6.200: 0.268, 6.300: 0.268, 6.400: 0.268, 6.500: 0.267, 6.600: 0.267, 6.700: 0.267, 6.800: 0.266, 6.900: 0.266, 7.000: 0.266, 7.100: 0.265, 7.200: 0.265, 7.300: 0.265, 7.400: 0.265, 7.500: 0.264, 7.600: 0.264, 7.700: 0.264, 7.800: 0.264, 7.900: 0.263, 8.000: 0.263, 8.100: 0.263, 8.200: 0.263, 8.300: 0.263, 8.400: 0.262, 8.500: 0.262, 8.600: 0.262, 8.700: 0.262, 8.800: 0.262, 8.900: 0.261, 9.000: 0.261, 9.100: 0.261, 9.200: 0.261, 9.300: 0.261, 9.400: 0.26, 9.500: 0.26, 9.600: 0.26, 9.700: 0.26, 9.800: 0.26, 9.900: 0.26, 10.000: 0.26 };
             compareObject("Ytorrentiel", res["tor"], t, 0.01);
diff --git a/spec/remous_rect_trapezes_pentefaible.spec.ts b/spec/remous_rect_trapezes_pentefaible.spec.ts
index aeb0bc77..10c56dbe 100644
--- a/spec/remous_rect_trapezes_pentefaible.spec.ts
+++ b/spec/remous_rect_trapezes_pentefaible.spec.ts
@@ -5,6 +5,12 @@ import { round } from "../src/base";
 import { cLog } from "../src/util/log";
 import { Message, MessageCode } from "../src/util/message";
 
+/*
+  Le code de modification des lignes fluviale et torrentielle a été modifié, on enlève un point de plus
+  ligne d'eau complète : if (iSens * (rXCC - rX) < 0) remplacé par if (iSens * (rXCC - rX) <= 0)
+  lign d'eau partielle : if (iSens * (rXCN - xRst) > 0)  remplacé par if (iSens * (rXCN - xRst) >= 0)
+  Les données de validation ont été modifiées en conséquence
+*/
 
 describe('Class Remous / section rectangulaire :', () => {
     describe('méthode trapèzes :', () => {
@@ -96,10 +102,12 @@ describe('Class Remous / section rectangulaire :', () => {
 
             // données de validation : version PHP (Oct 2017) méthode trapèzes
 
-            let f = { 100.000: 0.403, 95.000: 0.524, 90.000: 0.558, 85.000: 0.584, 80.000: 0.604, 75.000: 0.621, 70.000: 0.637, 65.000: 0.65, 60.000: 0.662, 55.000: 0.673, 50.000: 0.684, 45.000: 0.693, 40.000: 0.701, 35.000: 0.709, 30.000: 0.717, 25.000: 0.725, 20.000: 0.731, 15.000: 0.738, 10.000: 0.744, 5.000: 0.75, 0.000: 0.15 };
+            // let f = { 100.000: 0.403, 95.000: 0.524, 90.000: 0.558, 85.000: 0.584, 80.000: 0.604, 75.000: 0.621, 70.000: 0.637, 65.000: 0.65, 60.000: 0.662, 55.000: 0.673, 50.000: 0.684, 45.000: 0.693, 40.000: 0.701, 35.000: 0.709, 30.000: 0.717, 25.000: 0.725, 20.000: 0.731, 15.000: 0.738, 10.000: 0.744, 5.000: 0.75, 0.000: 0.15 };
+            let f = { 100.000: 0.403, 95.000: 0.524, 90.000: 0.558, 85.000: 0.584, 80.000: 0.604, 75.000: 0.621, 70.000: 0.637, 65.000: 0.65, 60.000: 0.662, 55.000: 0.673, 50.000: 0.684, 45.000: 0.693, 40.000: 0.701, 35.000: 0.709, 30.000: 0.717, 25.000: 0.725, 20.000: 0.731, 15.000: 0.738, 10.000: 0.744, 5.000: 0.75 };  // dernière valeur supprimée pour la raison en tête de fichier
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
-            let t = { 0.000: 0.15, 5.000: 0.75 };
+            // let t = { 0.000: 0.15, 5.000: 0.75 };
+            let t = { 0.000: 0.15 }; // dernière valeur supprimée pour la raison en tête de fichier
             compareObject("Ytorrentiel", res["tor"], t, 0.03);
 
             let x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
@@ -293,7 +301,7 @@ describe('Class Remous / section rectangulaire :', () => {
         let f = { 100.000: 1, 95.000: 0.999, 90.000: 0.999, 85.000: 0.998, 80.000: 0.997, 75.000: 0.997, 70.000: 0.996, 65.000: 0.996, 60.000: 0.995, 55.000: 0.994, 50.000: 0.994, 45.000: 0.993, 40.000: 0.992, 35.000: 0.992, 30.000: 0.991, 25.000: 0.991, 20.000: 0.99, 15.000: 0.989, 10.000: 0.989, 5.000: 0.988, 0.000: 0.988 };
         compareObject("Yfluvial", res["flu"], f, 0.03);
 
-        expect(res["tor"] == undefined).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
+        expect(Object.keys(res["tor"]).length == 0).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
 
         let x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
         compareArray("abscisses", res["trX"], x);
@@ -346,7 +354,7 @@ describe('Class Remous / section rectangulaire :', () => {
         let f = { 100.000: 0.7, 95.000: 0.708, 90.000: 0.716, 85.000: 0.723, 80.000: 0.73, 75.000: 0.737, 70.000: 0.743, 65.000: 0.749, 60.000: 0.754, 55.000: 0.76, 50.000: 0.765, 45.000: 0.77, 40.000: 0.775, 35.000: 0.779, 30.000: 0.783, 25.000: 0.787, 20.000: 0.792, 15.000: 0.795, 10.000: 0.799, 5.000: 0.803, 0.000: 0.806 };
         compareObject("Yfluvial", res["flu"], f, 0.03);
 
-        expect(res["tor"] == undefined).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
+        expect(Object.keys(res["tor"]).length == 0).toBeTruthy("la ligne d'eau torrentielle ne devrait comporter aucune valeur");
 
         let x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
         compareArray("abscisses", res["trX"], x);
diff --git a/spec/remous_rect_trapezes_penteforte.spec.ts b/spec/remous_rect_trapezes_penteforte.spec.ts
index 7695ae5a..4b8a237f 100644
--- a/spec/remous_rect_trapezes_penteforte.spec.ts
+++ b/spec/remous_rect_trapezes_penteforte.spec.ts
@@ -5,6 +5,22 @@ import { round } from "../src/base";
 import { cLog } from "../src/util/log";
 import { Message, MessageCode } from "../src/util/message";
 
+/*
+   cas 1 :
+   Certaines valeurs de ligne d'eau torrentielle étaient auparavant remplacées par une valeur fluviale
+   pour la représentation graphique du ressaut (mais fausse car torrentielle).
+   Idem pour la réciproque fluvial/torrentiel.
+   Le code ne faisant plus ça, les valeurs de validation ont été remplacée par les bonnes.
+ */
+
+/*
+  cas 2 :
+  Le code de modification des lignes fluviale et torrentielle a été modifié, on enlève un point de plus
+  ligne d'eau complète : if (iSens * (rXCC - rX) < 0) remplacé par if (iSens * (rXCC - rX) <= 0)
+  lign d'eau partielle : if (iSens * (rXCN - xRst) > 0)  remplacé par if (iSens * (rXCN - xRst) >= 0)
+  Les données de validation ont été modifiées en conséquence
+*/
+
 describe('Class Remous / section rectangulaire :', () => {
     describe('méthode trapèzes :', () => {
         it("forte pente, ressaut avant l'amont", () => {
@@ -95,7 +111,8 @@ describe('Class Remous / section rectangulaire :', () => {
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
             // let t = { 0.000: 0.15, 5.000: 0.207, 10.000: 0.235, 15.000: 0.246, 20.000: 0.25, 25.000: 0.252, 30.000: 0.253, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253, 95.000: 0.253, 100.000: 0.253 };
-            let t = { 0.000: 0.15, 5.000: 0.207, 10.000: 0.235, 15.000: 0.246, 20.000: 0.25, 25.000: 0.252, 30.000: 0.253, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253, 95.000: 0.253, 100.000: 0.45 };
+            // let t = { 0.000: 0.15, 5.000: 0.207, 10.000: 0.235, 15.000: 0.246, 20.000: 0.25, 25.000: 0.252, 30.000: 0.253, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253, 95.000: 0.253, 100.000: 0.45 }; // dernière valeur modifiée pour la raison 1 en tête de fichier
+            let t = { 0.000: 0.15, 5.000: 0.207, 10.000: 0.235, 15.000: 0.246, 20.000: 0.25, 25.000: 0.252, 30.000: 0.253, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253, 95.000: 0.253, 100.000: 0.253 };
             compareObject("Ytorrentiel", res["tor"], t, 0.03);
 
             let x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
@@ -158,7 +175,8 @@ describe('Class Remous / section rectangulaire :', () => {
             let f = { 100.000: 1, 95.000: 0.729 };
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
-            let t = { 0.000: 0.15, 5.000: 0.207, 10.000: 0.235, 15.000: 0.246, 20.000: 0.25, 25.000: 0.252, 30.000: 0.253, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253, 95.000: 0.729 };
+            // let t = { 0.000: 0.15, 5.000: 0.207, 10.000: 0.235, 15.000: 0.246, 20.000: 0.25, 25.000: 0.252, 30.000: 0.253, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253, 95.000: 0.729 };
+            let t = { 0.000: 0.15, 5.000: 0.207, 10.000: 0.235, 15.000: 0.246, 20.000: 0.25, 25.000: 0.252, 30.000: 0.253, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253 }; // dernière valeur supprimée pour la raison 2 en tête de fichier
             compareObject("Ytorrentiel", res["tor"], t, 0.03);
 
             let x = [0.000, 5.000, 10.000, 15.000, 20.000, 25.000, 30.000, 35.000, 40.000, 45.000, 50.000, 55.000, 60.000, 65.000, 70.000, 75.000, 80.000, 85.000, 90.000, 95.000, 100.000];
@@ -218,7 +236,8 @@ describe('Class Remous / section rectangulaire :', () => {
 
             // données de validation : version PHP (Oct 2017) méthode trapèzes
 
-            let f = { 5.500: 1, 5.250: 0.987, 5.000: 0.974, 4.750: 0.96, 4.500: 0.947, 4.250: 0.933, 4.000: 0.92, 3.750: 0.906, 3.500: 0.893, 3.250: 0.88, 3.000: 0.866, 2.750: 0.853, 2.500: 0.839, 2.250: 0.826, 2.000: 0.812, 1.750: 0.798, 1.500: 0.784, 1.250: 0.77, 1.000: 0.756, 0.750: 0.742, 0.500: 0.727, 0.250: 0.712, 0.000: 0.15 };
+            // let f = { 5.500: 1, 5.250: 0.987, 5.000: 0.974, 4.750: 0.96, 4.500: 0.947, 4.250: 0.933, 4.000: 0.92, 3.750: 0.906, 3.500: 0.893, 3.250: 0.88, 3.000: 0.866, 2.750: 0.853, 2.500: 0.839, 2.250: 0.826, 2.000: 0.812, 1.750: 0.798, 1.500: 0.784, 1.250: 0.77, 1.000: 0.756, 0.750: 0.742, 0.500: 0.727, 0.250: 0.712, 0.000: 0.15 };
+            let f = { 5.500: 1, 5.250: 0.987, 5.000: 0.974, 4.750: 0.96, 4.500: 0.947, 4.250: 0.933, 4.000: 0.92, 3.750: 0.906, 3.500: 0.893, 3.250: 0.88, 3.000: 0.866, 2.750: 0.853, 2.500: 0.839, 2.250: 0.826, 2.000: 0.812, 1.750: 0.798, 1.500: 0.784, 1.250: 0.77, 1.000: 0.756, 0.750: 0.742, 0.500: 0.727, 0.250: 0.712, 0.000: 0.699 };  // dernière valeur modifiée pour la raison 1 en tête de fichier
             compareObject("Yfluvial", res["flu"], f, 0.03);
 
             let t = { 0.000: 0.15, 0.250: 0.153, 0.500: 0.156, 0.750: 0.158, 1.000: 0.161, 1.250: 0.163, 1.500: 0.166, 1.750: 0.168, 2.000: 0.17, 2.250: 0.173, 2.500: 0.175, 2.750: 0.177, 3.000: 0.18, 3.250: 0.182, 3.500: 0.184, 3.750: 0.906 };
@@ -277,7 +296,7 @@ describe('Class Remous / section rectangulaire :', () => {
 
             // données de validation : version PHP (Oct 2017) méthode trapèzes
 
-            expect(res["flu"] == undefined).toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
+            expect(Object.keys(res["flu"]).length == 0).toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
             let t = { 0.000: 0.1, 5.000: 0.205, 10.000: 0.234, 15.000: 0.246, 20.000: 0.25, 25.000: 0.252, 30.000: 0.253, 35.000: 0.253, 40.000: 0.253, 45.000: 0.253, 50.000: 0.253, 55.000: 0.253, 60.000: 0.253, 65.000: 0.253, 70.000: 0.253, 75.000: 0.253, 80.000: 0.253, 85.000: 0.253, 90.000: 0.253, 95.000: 0.253, 100.000: 0.253 };
             compareObject("Ytorrentiel", res["tor"], t, 0.01);
@@ -330,7 +349,7 @@ describe('Class Remous / section rectangulaire :', () => {
 
             // données de validation : version PHP (Oct 2017) méthode trapèzes
 
-            expect(res["flu"] == undefined).toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
+            expect(Object.keys(res["flu"]).length == 0).toBeTruthy("la ligne d'eau fluviale ne devrait comporter aucune valeur");
 
             let t = { 0.000: 0.35, 0.100: 0.345, 0.200: 0.34, 0.300: 0.336, 0.400: 0.332, 0.500: 0.329, 0.600: 0.326, 0.700: 0.323, 0.800: 0.32, 0.900: 0.318, 1.000: 0.316, 1.100: 0.313, 1.200: 0.311, 1.300: 0.309, 1.400: 0.308, 1.500: 0.306, 1.600: 0.305, 1.700: 0.303, 1.800: 0.302, 1.900: 0.3, 2.000: 0.298, 2.100: 0.297, 2.200: 0.295, 2.300: 0.294, 2.400: 0.293, 2.500: 0.292, 2.600: 0.291, 2.700: 0.291, 2.800: 0.29, 2.900: 0.289, 3.000: 0.288, 3.100: 0.287, 3.200: 0.287, 3.300: 0.286, 3.400: 0.285, 3.500: 0.284, 3.600: 0.283, 3.700: 0.283, 3.800: 0.282, 3.900: 0.281, 4.000: 0.28, 4.100: 0.28, 4.200: 0.279, 4.300: 0.278, 4.400: 0.277, 4.500: 0.276, 4.600: 0.276, 4.700: 0.275, 4.800: 0.274, 4.900: 0.273, 5.000: 0.272, 5.100: 0.272, 5.200: 0.271, 5.300: 0.27, 5.400: 0.269, 5.500: 0.269, 5.600: 0.269, 5.700: 0.269, 5.800: 0.269, 5.900: 0.269, 6.000: 0.269, 6.100: 0.269, 6.200: 0.269, 6.300: 0.269, 6.400: 0.269, 6.500: 0.269, 6.600: 0.269, 6.700: 0.269, 6.800: 0.269, 6.900: 0.269, 7.000: 0.269, 7.100: 0.269, 7.200: 0.269, 7.300: 0.269, 7.400: 0.269, 7.500: 0.269, 7.600: 0.269, 7.700: 0.269, 7.800: 0.269, 7.900: 0.269, 8.000: 0.269, 8.100: 0.269, 8.200: 0.269, 8.300: 0.269, 8.400: 0.269, 8.500: 0.269, 8.600: 0.269, 8.700: 0.269, 8.800: 0.269, 8.900: 0.269, 9.000: 0.269, 9.100: 0.269, 9.200: 0.269, 9.300: 0.269, 9.400: 0.269, 9.500: 0.269, 9.600: 0.269, 9.700: 0.269, 9.800: 0.269, 9.900: 0.269, 10.000: 0.269 };
             compareObject("Ytorrentiel", res["tor"], t, 0.01);
diff --git a/spec/remous_trapez.spec.ts b/spec/remous_trapez.spec.ts
index 68dd03c6..350b6876 100644
--- a/spec/remous_trapez.spec.ts
+++ b/spec/remous_trapez.spec.ts
@@ -5,9 +5,16 @@ import { round } from "../src/base";
 import { cLog } from "../src/util/log";
 import { compareObject, compareArray } from "./nubtest";
 
+/*
+   Certaines valeurs de ligne d'eau torrentielle étaient auparavant remplacées par une valeur fluviale
+   pour la représentation graphique du ressaut (mais fausse car torrentielle).
+   Idem pour la réciproque fluvial/torrentiel.
+   Le code ne faisant plus ça, les valeurs de validation ont été remplacée par les bonnes.
+ */
+
 describe('Class Remous / section trapèze :', () => {
-    xdescribe('méthode trapèzes :', () => {
-        it('test 1', () => {
+    describe('méthode trapèzes :', () => {
+        it('pente faible, ressaut dans le bief sur plusieurs points', () => {
             let prms = new ParamsSectionTrapez(2.5, // largeur de fond
                 0.56, // fruit
                 undefined, // tirant d'eau
@@ -32,14 +39,50 @@ describe('Class Remous / section trapèze :', () => {
             let res = rem.calculRemous(undefined);
 
             let f = { 9: 0.278, 10: 0.4 };
-            compareObject("Yfluvial", res["flu"], f, precDist);
+            compareObject("Yfluvial", res["flu"], f, 0.002);
 
-            let t = { 0.000: 0.15, 1.000: 0.16369914454109, 2.000: 0.17743613485223, 3.000: 0.19117312516337, 4.000: 0.20491011547451, 5.000: 0.21864710578565, 6.000: 0.23238409609679, 7.000: 0.24688425253633, 8.000: 0.26214757510426, 9.000: 0.27817406380059, 10.000: 0.4 };
-            compareObject("Ytorrentiel", res["tor"], t, precDist);
+            // let t = { 0.000: 0.15, 1.000: 0.16369914454109, 2.000: 0.17743613485223, 3.000: 0.19117312516337, 4.000: 0.20491011547451, 5.000: 0.21864710578565, 6.000: 0.23238409609679, 7.000: 0.24688425253633, 8.000: 0.26214757510426, 9.000: 0.27817406380059, 10.000: 0.4 };
+            let t = { 0.000: 0.15, 1.000: 0.16369914454109, 2.000: 0.17743613485223, 3.000: 0.19117312516337, 4.000: 0.20491011547451, 5.000: 0.21864710578565, 6.000: 0.23238409609679, 7.000: 0.24688425253633, 8.000: 0.26214757510426, 9.000: 0.27817406380059, 10.000: 0.293 };  // dernière valeur modifiée pour la raison en tête de fichier
+            compareObject("Ytorrentiel", res["tor"], t, 0.002);
 
             let x = [0.000, 1.000, 2.000, 3.000, 4.000, 5.000, 6.000, 7.000, 8.000, 9.000, 10.000];
             compareArray("abcisses", res["trX"], x);
         });
+
+        // it('pente forte, ressaut dans le bief sur plusieurs points', () => {
+        //     let prms = new ParamsSectionTrapez(2.5, // largeur de fond
+        //         0.56, // fruit
+        //         undefined, // tirant d'eau
+        //         40, //  Ks=Strickler
+        //         2,  //  Q=Débit
+        //         0.05, //  If=pente du fond
+        //         precDist, // précision
+        //         1 // YB= hauteur de berge
+        //     );
+
+        //     let sect = new cSnTrapez(prms);
+
+        //     let prem = new CourbeRemousParams(sect,
+        //         0.15, // Yamont = tirant amont
+        //         1, // Yaval = tirant aval
+        //         8,  // Long= Longueur du bief
+        //         0.1,  // Dx=Pas d'espace
+        //         MethodeResolution.Trapezes
+        //     );
+
+        //     let rem = new CourbeRemous(prem);
+
+        //     let res = rem.calculRemous(undefined);
+
+        //     let f = { 8.000: 1, 7.900: 0.995, 7.800: 0.989, 7.700: 0.984, 7.600: 0.978, 7.500: 0.973, 7.400: 0.967, 7.300: 0.962, 7.200: 0.956, 7.100: 0.951, 7.000: 0.945, 6.900: 0.94, 6.800: 0.934, 6.700: 0.929, 6.600: 0.923, 6.500: 0.918, 6.400: 0.912, 6.300: 0.907, 6.200: 0.901, 6.100: 0.896, 6.000: 0.89, 5.900: 0.885, 5.800: 0.879, 5.700: 0.874, 5.600: 0.868, 5.500: 0.863, 5.400: 0.857, 5.300: 0.852, 5.200: 0.846, 5.100: 0.841, 5.000: 0.835, 4.900: 0.83, 4.800: 0.824, 4.700: 0.819, 4.600: 0.813, 4.500: 0.808, 4.400: 0.802, 4.300: 0.797, 4.200: 0.791, 4.100: 0.786, 4.000: 0.78, 3.900: 0.775, 3.800: 0.769, 3.700: 0.764, 3.600: 0.758, 3.500: 0.753, 3.400: 0.747, 3.300: 0.742, 3.200: 0.737, 3.100: 0.731, 3.000: 0.726, 2.900: 0.72, 2.800: 0.715, 2.700: 0.709, 2.600: 0.704, 2.500: 0.698, 2.400: 0.693, 2.300: 0.686, 2.200: 0.68, 2.100: 0.674, 2.000: 0.668, 1.900: 0.662, 1.800: 0.656, 1.700: 0.65, 1.600: 0.644, 1.500: 0.638, 1.400: 0.632, 1.300: 0.625, 1.200: 0.619, 1.100: 0.613, 1.000: 0.607, 0.900: 0.601, 0.800: 0.594, 0.700: 0.588, 0.600: 0.581, 0.500: 0.574, 0.400: 0.567, 0.300: 0.561, 0.200: 0.554, 0.100: 0.547, 0.000: 0.15 };
+        //     compareObject("Yfluvial", res["flu"], f, 0.011);
+
+        //     let t = { 0.000: 0.15, 0.100: 0.151, 0.200: 0.151, 0.300: 0.152, 0.400: 0.153, 0.500: 0.154, 0.600: 0.155, 0.700: 0.155, 0.800: 0.156, 0.900: 0.157, 1.000: 0.158, 1.100: 0.158, 1.200: 0.159, 1.300: 0.16, 1.400: 0.161, 1.500: 0.161, 1.600: 0.162, 1.700: 0.163, 1.800: 0.164, 1.900: 0.164, 2.000: 0.165, 2.100: 0.166, 2.200: 0.167, 2.300: 0.168, 2.400: 0.168, 2.500: 0.698, 2.6: 0.709500000000002 };
+        //     compareObject("Ytorrentiel", res["tor"], t, 0.004);
+
+        //     let x = [0.000, 0.100, 0.200, 0.300, 0.400, 0.500, 0.600, 0.700, 0.800, 0.900, 1.000, 1.100, 1.200, 1.300, 1.400, 1.500, 1.600, 1.700, 1.800, 1.900, 2.000, 2.100, 2.200, 2.300, 2.400, 2.500, 2.600, 2.700, 2.800, 2.900, 3.000, 3.100, 3.200, 3.300, 3.400, 3.500, 3.600, 3.700, 3.800, 3.900, 4.000, 4.100, 4.200, 4.300, 4.400, 4.500, 4.600, 4.700, 4.800, 4.900, 5.000, 5.100, 5.200, 5.300, 5.400, 5.500, 5.600, 5.700, 5.800, 5.900, 6.000, 6.100, 6.200, 6.300, 6.400, 6.500, 6.600, 6.700, 6.800, 6.900, 7.000, 7.100, 7.200, 7.300, 7.400, 7.500, 7.600, 7.700, 7.800, 7.900, 8.000];
+        //     compareArray("abcisses", res["trX"], x);
+        // });
     });
 
     describe('paramètre à calculer :', () => {
@@ -47,7 +90,7 @@ describe('Class Remous / section trapèze :', () => {
             let prms = new ParamsSectionTrapez(
                 2.5, // largeur de fond
                 0.56, // fruit
-                1, // tirant d'eau
+                undefined, // tirant d'eau
                 40, //  Ks=Strickler
                 2, // Q=Débit
                 0.001, // If=pente du fond
@@ -77,7 +120,7 @@ describe('Class Remous / section trapèze :', () => {
             let prms = new ParamsSectionTrapez(
                 2.5, // largeur de fond
                 0.56, // fruit
-                1, // tirant d'eau
+                undefined, // tirant d'eau
                 40, //  Ks=Strickler
                 2, // Q=Débit
                 0.05, // If=pente du fond
diff --git a/spec/test-remous-fenetre.ts b/spec/test-remous-fenetre.ts
new file mode 100644
index 00000000..fc4c7fde
--- /dev/null
+++ b/spec/test-remous-fenetre.ts
@@ -0,0 +1,360 @@
+import { Message, MessageCode, MessageSeverity } from "../src/util/message";
+import { CourbeRemous, CourbeRemousParams, MethodeResolution } from "../src/remous";
+import { cLog } from "../src/util/log";
+
+//import { ParamsSectionTrapez, cSnTrapez } from "../src/section/section_trapez";
+import { ParamsSectionRectang, cSnRectang } from "../src/section/section_rectang";
+import { nub, precDist, equalEpsilon } from "../spec/nubtest";
+
+/*
+   Tentative de validation automatique du calcul des courbes de remous.
+   Le principe :
+    - calculer d'abord les remous sur un bief (avec par exemple un ressaut au milieu) qui servira de référence
+    - déplacer dans ce bief une fenêtre dans laquelle on calcule les courbes de remous
+    - comparer les courbes obtenus dans la fenêtre avec celles se trouvant au même endroit dans le bief de référence
+
+   Ce code de validation n'est pas sous la forme d'un test unitaire, il doit être lancé à la main :
+   $ npm run runtestremous
+ */
+
+class Expect {
+    constructor(private b: boolean) {
+
+    }
+    public toBeTruthy(m: string) {
+        if (!this.b)
+            console.log(m);
+    }
+}
+
+function expect(b: boolean): Expect {
+    return new Expect(b);
+}
+
+export function compareObject(s: string, objTest: { [key: number]: number }, objValid: { [key: number]: number }, epsilon: number): boolean {
+    let n1 = Object.keys(objTest).length;
+    let n2 = Object.keys(objValid).length;
+    let b: boolean = n1 == n2;
+    expect(b).toBeTruthy(s + ": longueur incorrecte " + n1 + ", devrait etre " + n2);
+    if (!b) return false;
+
+    let kTest = Object.keys(objTest);
+    kTest.sort((a, b) => {
+        if (+a > +b) return 1;
+        if (+a < +b) return -1;
+        return 0;
+    });
+
+    let kValid = Object.keys(objValid);
+    kValid.sort((a, b) => {
+        if (+a > +b) return 1;
+        if (+a < +b) return -1;
+        return 0;
+    });
+
+    for (let i = 0; i < n1; i++) {
+        // let v1: number = objTest[+Object.keys(objTest)[i]];
+        let v1: number = objTest[+kTest[i]];
+        // let v2: number = objValid[+Object.keys(objValid)[i]];
+        let v2: number = objValid[+kValid[i]];
+        b = equalEpsilon(v1, v2, epsilon);
+        expect(b).toBeTruthy(s + " : " + i + "ieme valeur incorrecte " + v1 + ", devrait etre " + v2);
+        if (!b) return false;
+    }
+
+    return true;
+}
+
+export function compareArray(s: string, arrTest: string[], arrValid: string[]): boolean {
+    let n1 = arrTest.length;
+    let n2 = arrValid.length;
+    let b: boolean = n1 == n2;
+    expect(b).toBeTruthy(s + ": longueur incorrecte " + n1 + ", devrait etre " + n2);
+    if (!b) return false;
+
+    for (let i = 0; i < arrTest.length; i++) {
+        let v1: number = +arrTest[i];
+        let v2: number = +arrValid[i];
+        b = equalEpsilon(v1, v2);
+        expect(b).toBeTruthy(s + " : " + i + "ieme valeur incorrecte " + v1 + ", devrait etre " + v2);
+        if (!b) return false;
+    }
+
+    return true;
+}
+
+function logObject(obj: {}, m?: string) {
+    // évite le message "Value below was evaluated just now" dans le debugger de Chrome
+    if (m == undefined)
+        console.log(JSON.stringify(obj));
+    else
+        console.log(m + " " + JSON.stringify(obj));
+}
+
+function logArray(m: string, arr: { [key: string]: number }) {
+    console.log(m);
+
+    let keys = Object.keys(arr);
+    keys.sort((a, b) => {
+        if (+a > +b) return 1;
+        if (+a < +b) return -1;
+        return 0;
+    });
+
+    for (let k of keys)
+        console.log("[" + (+k).toFixed(3) + "]=" + arr[k]);
+}
+
+// function computeFenetreTrapez(yAmont: number, yAval: number, longBief: number, dxBief: number, prec: number) {
+//     let prms = new ParamsSectionTrapez(
+//         2.5, // largeur de fond
+//         0.56, // fruit
+//         undefined, // tirant d'eau
+//         40, //  Ks=Strickler
+//         2.5, // Q=Débit
+//         0.05, // If=pente du fond
+//         prec, // précision
+//         1 // YB=hauteur de berge
+//     );
+
+//     let sect = new cSnTrapez(prms);
+
+//     let prem = new CourbeRemousParams(sect,
+//         yAmont, // Yamont = tirant amont
+//         yAval, // Yaval = tirant aval
+//         longBief,  // Long = Longueur du bief
+//         dxBief,  // Dx = Pas d'espace
+//         MethodeResolution.Trapezes
+//     );
+
+//     // console.log("computeFenetre longBief=" + longBief + " y am/av=" + yAmont + " " + yAval);
+//     console.log("computeFenetre y am/av=" + yAmont + " " + yAval);
+
+//     let rem = new CourbeRemous(prem);
+//     return rem.calculRemous(undefined);
+// }
+
+function saveCSV(res) {
+    const fs = require('fs');
+
+    let csvFlu = "x;flu;tor";
+    for (let x of res.trX) {
+        if (res.flu[x] == undefined)
+            var flu = "";
+        else
+            flu = String(res.flu[x]).replace(".", ",");
+
+        if (res.tor[x] == undefined)
+            var tor = "";
+        else
+            tor = String(res.tor[x]).replace(".", ",");
+
+        csvFlu += "\n" + x.replace(".", ",") + ";" + flu + ";" + tor;
+    }
+
+    fs.writeFile("/tmp/flu.csv", csvFlu, function (err) {
+        if (err) {
+            return console.log(err);
+        }
+
+        console.log("The file was saved!");
+    });
+}
+
+function createSectionRect(prec: number, dbg: boolean = false): cSnRectang {
+    let prms = new ParamsSectionRectang(
+        undefined, // tirant d'eau
+        2, // largeur de fond
+        40, //  Ks=Strickler
+        2.5, // Q=Débit
+        0.001, // If=pente du fond
+        prec, // précision
+        1 // YB=hauteur de berge
+    );
+
+    return new cSnRectang(prms, dbg);
+}
+
+function computeFenetreRect(yAmont: number, yAval: number, longBief: number, dbg: boolean = false) {
+    // let prms = new ParamsSectionRectang(
+    //     undefined, // tirant d'eau
+    //     2, // largeur de fond
+    //     40, //  Ks=Strickler
+    //     2.5, // Q=Débit
+    //     0.001, // If=pente du fond
+    //     prec, // précision
+    //     1 // YB=hauteur de berge
+    // );
+    // let sect = new cSnRectang(prms);
+    let sect = createSectionRect(prec);
+
+    let prem = new CourbeRemousParams(sect,
+        yAmont, // Yamont = tirant amont
+        yAval, // Yaval = tirant aval
+        longBief,  // Long = Longueur du bief
+        dxBief,  // Dx = Pas d'espace
+        MethodeResolution.Trapezes
+    );
+
+    let rem = new CourbeRemous(prem, dbg);
+    return { "remous": rem, "res": rem.calculRemous(undefined) };
+}
+
+// ressaut entre x=8 et x=12.5
+const prec = 1e-3; // précision de calcul
+const longBief = 20; // longueur totale du bief
+const Yaval = 1.1; // tirant aval
+const Yamont = 0.1; // tirant amont
+const dxBief = 0.25; // pas de discrétisation
+
+function testFenetre() {
+    console.log("CALCUL DU BIEF\n\n");
+
+    // calcul du bief
+
+    let r = computeFenetreRect(Yamont, Yaval, longBief, false);
+    let res: {
+        "flu": { [key: number]: number; },
+        "tor": { [key: number]: number; },
+        "trX": string[],
+        "tRes": { [key: number]: number }
+    } = r["res"];
+
+    let remous = r["remous"];
+
+    // ligne fluviale totale, utilisée pour les conditions initiales
+    let ligneFluviale: { [key: number]: number; } = remous.calculFluvial();
+
+    // ligne torrentielle totale, utilisée pour les conditions initiales
+    let ligneTorrentielle: { [key: number]: number; } = remous.calculTorrentiel();
+
+    console.log(remous.log.toString());
+    // let ms = r["remous"].log.messages;
+
+    //  saveCSV(res);
+
+    console.log("X")
+    logObject(res.trX);
+    logArray("flu", res.flu);
+    logArray("tor", res.tor);
+
+    // mouvement de la fenêtre
+
+    console.log("\n\nMOUVEMENT DE LA FENETRE\n\n");
+
+    let sizeFenetre = Math.round(res.trX.length / 3.5);
+    console.log("taille de la fenetre (points) " + sizeFenetre);
+    if (sizeFenetre < 3)
+        throw "pas de discrétisation trop grand !";
+
+    let nFlu = Object.keys(res.flu).length;
+    if (nFlu < sizeFenetre * 2)
+        throw "pb de calcul de la ligne fluviale : nb de points (" + nFlu + ") < fenetre * 2";
+
+    let nTor = Object.keys(res.tor).length;
+    if (nTor < sizeFenetre * 2)
+        throw "pb de calcul de la ligne torrentielle : nb de points (" + nTor + ") < fenetre * 2";
+
+
+    let nX = res.trX.length;
+    console.log("taille du bief (points)=" + nX);
+
+    let ni = 13;
+    for (let i1 = 0; i1 <= nX - sizeFenetre; i1++) {
+        console.log();
+        console.log("i1", i1);
+
+        let i2 = i1 + sizeFenetre - 1;
+        let xBief1: string = res.trX[i1];
+        let xBief2: string = res.trX[i2];
+        console.log("test fenetre xBief=[" + xBief1 + "," + xBief2 + "]");
+        console.log("longueur fenetre " + (+xBief2 - +xBief1));
+
+        // let yAmont: number = res.tor[xBief1];
+        let yAmont: number = ligneTorrentielle[xBief1];
+        if (yAmont == undefined) {
+            // yAmont = res.flu[xBief1];
+            yAmont = ligneFluviale[xBief1];
+            // console.log("yAmont (flu)=" + yAmont);
+        }
+        // else
+        // console.log("yAmont (tor)=" + yAmont);
+
+        // let yAval = res.flu[xBief2];
+        let yAval = ligneFluviale[xBief2];
+        if (yAval == undefined) {
+            // yAval = res.tor[xBief2];
+            yAval = ligneTorrentielle[xBief2];
+            // console.log("yAval (tor)=" + yAval);
+        }
+        // else
+        // console.log("yAval (flu)=" + yAval   );
+
+        if (yAmont == undefined || yAval == undefined)
+            throw "pb ! yAmont == undefined || yAval == undefined";
+
+        // console.log("computeFenetre longBief=" + longBief + " y am/av=" + yAmont + " " + yAval);
+        console.log("computeFenetre y am/av=" + yAmont + " " + yAval);
+
+        let r = computeFenetreRect(yAmont, yAval, +xBief2 - +xBief1, i1 == ni);
+        let resFenetre = r["res"];
+
+        // validation du tableau d'abscisses
+
+        let validX: string[] = [];
+        for (let i = i1; i <= i2; i++)
+            validX.push(String(+res.trX[i] - dxBief * i1));
+        if (!compareArray("X", resFenetre.trX, validX)) {
+            console.log("X valid")
+            logObject(validX);
+            console.log("X fenetre")
+            logObject(resFenetre.trX);
+            break;
+        }
+        /**/
+
+        // if (xBief1 == "3.1")
+        //     console.log();
+
+        // validation de la courbe fluviale
+
+        let validFlu: { [key: number]: number; } = {};
+        for (let i = i1; i <= i2; i++) {
+            let x: number = +res.trX[i];
+            let y: number = res.flu[x];
+            if (y != undefined)
+                validFlu[(i - i1) * dxBief] = y;
+            // validFlu[x] = y;
+        }
+        if (Object.keys(validFlu).length > 0)
+            if (!compareObject("Flu", resFenetre.flu, validFlu, prec)) {
+                console.log("flu valid")
+                logObject(validFlu);
+                console.log("flu fenetre")
+                logObject(resFenetre.flu);
+                // break;
+            }
+        /**/
+
+        // validation de la courbe torrentielle
+
+        let validTor: { [key: number]: number; } = {};
+        for (let i = i1; i <= i2; i++) {
+            let x: number = +res.trX[i];
+            let y: number = res.tor[x];
+            if (y != undefined)
+                validTor[(i - i1) * dxBief] = y;
+            // validTor[x] = y;
+        }
+        if (Object.keys(validTor).length > 0)
+            if (!compareObject("Tor", resFenetre.tor, validTor, prec)) {
+                console.log("tor valid")
+                logObject(validTor);
+                console.log("tor fenetre")
+                logObject(resFenetre.tor);
+                // break;
+            }
+    }
+}
+
+testFenetre()
diff --git a/spec/tsconfig-remous-fenetre.spec.json b/spec/tsconfig-remous-fenetre.spec.json
new file mode 100644
index 00000000..dc5c20a0
--- /dev/null
+++ b/spec/tsconfig-remous-fenetre.spec.json
@@ -0,0 +1,10 @@
+{
+  "compilerOptions": {
+    "noImplicitAny": false
+  },
+  "extends": "../tsconfig.json",
+  "include": [
+    "../src/remous.ts",
+    "../spec/test-remous-fenetre.ts"
+  ]
+}
\ No newline at end of file
diff --git a/spec/tsconfig.spec.json b/spec/tsconfig.spec.json
index 5ce23c66..86e4fca2 100644
--- a/spec/tsconfig.spec.json
+++ b/spec/tsconfig.spec.json
@@ -3,5 +3,8 @@
   "include": [
     "../src/**/*.ts",
     "../spec/**/*.ts"
+  ],
+  "exclude": [
+    "../spec/test-remous-fenetre.ts"
   ]
 }
diff --git a/src/remous.ts b/src/remous.ts
index 9ad72bbe..3df80f27 100644
--- a/src/remous.ts
+++ b/src/remous.ts
@@ -100,8 +100,6 @@ export class CourbeRemous extends Nub {
 
 	private _debugDicho: boolean = false;
 
-	private static DBG: boolean = false; /// Pour loguer les messages de debug de cette classe
-
 	/**
 	 * Journal de calcul
 	 */
@@ -114,8 +112,8 @@ export class CourbeRemous extends Nub {
 	 */
 	private Dx: number;
 
-	constructor(crp: CourbeRemousParams) {
-		super(crp, CourbeRemous.DBG);
+	constructor(crp: CourbeRemousParams, dbg: boolean = false) {
+		super(crp, dbg);
 		this._log = crp.Sn.log;
 		this.prmSect = crp.Sn.prms;
 		this.Sn.Calc("Yc");
@@ -394,6 +392,50 @@ export class CourbeRemous extends Nub {
 		}
 	}
 
+	/**
+	 * calcul de la ligne fluviale depuis l'aval (si possible)
+	 */
+	public calculFluvial() {
+		let res: { [key: number]: number; } = {};
+
+		// Calcul depuis l'aval
+		if (this.Sn.HautCritique <= this.prms.Yaval.v) {
+			this._log.add(new Message(MessageCode.ERROR_REMOUS_CALCUL_FLUVIAL));
+
+			this.debug("Condition limite aval (" + this.prms.Yaval.v + ") >= Hauteur critique (" + this.Sn.HautCritique + ") : calcul de la partie fluviale à partir de l'aval");
+			this.Dx = this.prms.Dx.v;
+			res = this.calcul(this.prms.Yaval.v);
+		}
+		else {
+			this.debug("Condition limite aval (" + this.prms.Yaval.v + ") < Hauteur critique (" + this.Sn.HautCritique + ") : pas de calcul possible depuis l'aval");
+			this._log.add(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AVAL));
+		}
+
+		return res;
+	}
+
+	/**
+	 * calcul de la ligne torrentielle depuis l'amont (si possible)
+	 */
+	public calculTorrentiel() {
+		let res: { [key: number]: number; } = {};
+
+		// Calcul depuis l'amont
+		if (this.Sn.HautCritique >= this.prms.Yamont.v) {
+			this._log.add(new Message(MessageCode.ERROR_REMOUS_CALCUL_TORRENTIEL));
+
+			this.debug("Condition limite amont (" + this.prms.Yamont.v + ") <= Hauteur critique (" + this.Sn.HautCritique + ") : calcul de la partie torrentielle à partir de l'amont");
+			this.Dx = -this.prms.Dx.v;
+			res = this.calcul(this.prms.Yamont.v);
+		}
+		else {
+			this._log.add(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT));
+			this.debug("Condition limite amont (" + this.prms.Yamont.v + ") > Hauteur critique (" + this.Sn.HautCritique + ") : pas de calcul possible depuis l'amont");
+		}
+
+		return res;
+	}
+
 	/**
 	 * @param val_a_cal nom de la variable à calculer
 	 */
@@ -413,8 +455,9 @@ export class CourbeRemous extends Nub {
 		m.extraVar["Yc"] = Yc;
 		this._log.add(m);
 
+		let Yn = this.Sn.Calc("Yn");
 		m = new Message(MessageCode.ERROR_REMOUS_H_NORMALE);
-		m.extraVar["Yn"] = this.Sn.Calc("Yn");
+		m.extraVar["Yn"] = Yn;
 		this._log.add(m);
 
 		this.debug("largeur berge " + this.Sn.Calc("B"));
@@ -423,59 +466,43 @@ export class CourbeRemous extends Nub {
 		this.debug("hauteur normale " + this.Sn.HautNormale);
 
 		// Calcul des courbes de remous
-		let crbFlu: { [key: number]: number; } = undefined;
-		let crbTor: { [key: number]: number; } = undefined;
+		let crbFlu: { [key: number]: number; } = this.calculFluvial();
+		let crbTor: { [key: number]: number; } = this.calculTorrentiel();
 
 		//this.debug("HautCritique ", this.Sn.HautCritique);
 
-		// Calcul depuis l'aval
-		if (this.Sn.HautCritique <= this.prms.Yaval.v) {
-			this._log.add(new Message(MessageCode.ERROR_REMOUS_CALCUL_FLUVIAL));
-
-			this.debug("Condition limite aval (" + this.prms.Yaval.v + ") >= Hauteur critique (" + this.Sn.HautCritique + ") : calcul de la partie fluviale à partir de l'aval");
-			this.Dx = this.prms.Dx.v;
-			crbFlu = this.calcul(this.prms.Yaval.v);
-		}
-		else {
-			this.debug("Condition limite aval (" + this.prms.Yaval.v + ") < Hauteur critique (" + this.Sn.HautCritique + ") : pas de calcul possible depuis l'aval");
-			this._log.add(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AVAL));
-		}
-
 		this.debug("flu ");
 		// this.logObject(crbFlu);
 		this.debug(JSON.stringify(crbFlu));
 
-		// Calcul depuis l'amont
-		if (this.Sn.HautCritique >= this.prms.Yamont.v) {
-			this._log.add(new Message(MessageCode.ERROR_REMOUS_CALCUL_TORRENTIEL));
-
-			this.debug("Condition limite amont (" + this.prms.Yamont.v + ") <= Hauteur critique (" + this.Sn.HautCritique + ") : calcul de la partie torrentielle à partir de l'amont");
-			this.Dx = -this.prms.Dx.v;
-			crbTor = this.calcul(this.prms.Yamont.v);
-		}
-		else {
-			this._log.add(new Message(MessageCode.ERROR_REMOUS_PAS_CALCUL_DEPUIS_AMONT));
-			this.debug("Condition limite amont (" + this.prms.Yamont.v + ") > Hauteur critique (" + this.Sn.HautCritique + ") : pas de calcul possible depuis l'amont");
-		}
-
 		this.debug("tor");
 		// this.logObject(crbTor);
 		this.debug(JSON.stringify(crbTor));
 
+		for (let xflu in crbFlu) {
+			let yflu = crbFlu[xflu];
+			this.debug("imp x " + xflu + " flu " + this.Sn.Calc('Imp', yflu));
+		}
+
+		for (let xtor in crbTor) {
+			let ytor = crbTor[xtor];
+			this.debug("imp x " + xtor + " tor " + this.Sn.Calc('Imp', ytor));
+		}
+
 		// Détection du ressaut hydraulique
 		let nFlu: number = this.size(crbFlu);
 		let nTor: number = this.size(crbTor);
 		if (nFlu != 0 && nTor != 0) {
-			let xMaxFlu = crbFlu[0];
-			let xMaxTor = this.last(crbTor);
-			// this.debug("end flu " + xMaxFlu);
-			// this.debug("end tor " + xMaxTor);
+			let firstYFlu = crbFlu[0];
+			let lastYTor = this.last(crbTor);
+			// this.debug("end flu " + firstYFlu);
+			// this.debug("end tor " + lastYTor);
 			// this.debug("nFlu " + nFlu);
 			// this.debug("nTor " + nTor);
-			// this.debug("Imp flu " + this.Sn.Calc('Imp', xMaxFlu));
-			// this.debug("Imp tor " + this.Sn.Calc('Imp', xMaxTor));
-			// if (nFlu > nTor || (nFlu == nTor && this.Sn.Calc('Imp', this.last(crbFlu)) > this.Sn.Calc('Imp', this.last(crbTor)))) {
-			if (nFlu > nTor || (nFlu == nTor && this.Sn.Calc('Imp', xMaxFlu) > this.Sn.Calc('Imp', xMaxTor))) {
+			// this.debug("Imp flu " + this.Sn.Calc('Imp', firstYFlu));
+			// this.debug("Imp tor " + this.Sn.Calc('Imp', lastYTor));
+
+			if (nFlu > nTor || (nFlu == nTor && Yn < Yc)) {
 				// La courbe fluviale va jusqu'au bout
 				var crbComplete = crbFlu;  // courbe calculée sur tout le bief
 				var crbPartielle = crbTor;  // courbe calculée sur une partie seulement du bief
@@ -501,13 +528,13 @@ export class CourbeRemous extends Nub {
 
 			// Parcours des sections de la ligne d'eau la plus courte
 			let trX: string[] = Object.keys(crbPartielle);
-			if (iSens == -1)
+			if (iSens == -1) // tri dans l'ordre croissant
 				trX.sort((a, b) => {
 					if (+a > +b) return 1;
 					if (+a < +b) return -1;
 					return 0;
 				});
-			else
+			else  // tri dans l'ordre décroissant
 				trX.sort((a, b) => {
 					if (+a > +b) return -1;
 					if (+a < +b) return 1;
@@ -543,15 +570,17 @@ export class CourbeRemous extends Nub {
 				xRst = round(xRst, this.prmSect.iPrec.v);
 				// this.debug("xRst (arr)=" + xRst);
 
+				let impYpartielle = this.Sn.Calc('Imp', crbPartielle[rX]);
+				// this.debug("imp(Ypartiel[rX=" + rX + "]=" + crbPartielle[rX] + ")=" + impYpartielle);
+
 				if (crbComplete[xRst] != undefined) {
 					// Hauteur décalée de la longueur du ressaut (il faut gérer la pente du fond)
 					let Ydec: number = crbComplete[xRst] + rLongRst * this.prmSect.If.v * iSens;
 					// this.debug("Ydec=" + Ydec);
-					// this.debug("imp(Ycomplet[xRst=" + xRst + "]=" + crbComplete[xRst] + ")=" + this.Sn.Calc('Imp', crbComplete[xRst]));
-					// this.debug("imp(Ypartiel[rX=" + rX + "]=" + crbPartielle[rX] + ")=" + this.Sn.Calc('Imp', crbPartielle[rX]));
+					let impYcomplete = this.Sn.Calc('Imp', crbComplete[xRst]);
+					// this.debug("imp(Ycomplet[xRst=" + xRst + "]=" + crbComplete[xRst] + ")=" + impYcomplete);
 
-					// if (iSens == 1 ? Yco > Ydec : Yco < Ydec) {
-					if (Yco > Ydec) {
+					if (impYpartielle > impYcomplete) {
 						this.debug("Ressaut hydraulique détecté entre les abscisses " + Math.min(rX, xRst) + " et " + Math.max(rX, xRst));
 						m = new Message(MessageCode.ERROR_REMOUS_RESSAUT_HYDRO);
 						m.extraVar["xmin"] = Math.min(rX, xRst);
@@ -559,33 +588,23 @@ export class CourbeRemous extends Nub {
 						this._log.add(m);
 						// this.debug("rX=" + rX + " xRst=" + xRst);
 
-						// Modification de la ligne d'eau CC
+						// Modification de la ligne d'eau complète
 						for (let pi of trXr) {
 							let rXCC: number = +pi;
 							// this.debug("rXCC=" + rXCC);
-							if (iSens * (rXCC - rX) < 0) {
+							if (iSens * (rXCC - rX) <= 0) {
 								delete crbComplete[rXCC];
 								this.debug("Modification de la ligne d'eau complète : suppression de la valeur à rXCC=" + rXCC + ", rX=" + rX + ", iSens*(rXCC-rX)=" + (iSens * (rXCC - rX)));
-							} else if (rXCC == rX) {
-								this.debug("Modification de la ligne d'eau complète : valeur " + crbComplete[rXCC] + " remplacée par " + crbPartielle[rXCC] + " à rX=" + rXCC);
-								crbComplete[rXCC] = crbPartielle[rXCC];
-								this.debug("Fin de la modification de la ligne d'eau complète");
-								break;
 							}
 						}
 
-						// Modification de la ligne d'eau CN
+						// Modification de la ligne d'eau partielle
 						for (let xcn of trX) {
 							let rXCN = +xcn;
 							// this.debug("rXCN=" + rXCN);
-							if (iSens * (rXCN - xRst) > 0) {
+							if (iSens * (rXCN - xRst) >= 0) {
 								this.debug("Modification de la ligne d'eau partielle : suppression de la valeur à rX=" + rXCN);
 								delete crbPartielle[rXCN];
-							} else if (rXCN == xRst) {
-								this.debug("Modification de la ligne d'eau partielle : valeur " + crbPartielle[rXCN] + " remplacée par " + crbComplete[rXCN] + " à rX=" + rXCN);
-								crbPartielle[rXCN] = crbComplete[rXCN];
-								this.debug("Fin de la modification de la ligne d'eau partielle");
-								break;
 							}
 						}
 						bRessaut = true;
-- 
GitLab