diff --git a/src/Model/D90AdisTS/D90AdisTS.py b/src/Model/D90AdisTS/D90AdisTS.py
index e4953cd85b9f4ac5139ef82302dc394fb3177936..39dac26af309c4c879218fe873f5521e99e71f01 100644
--- a/src/Model/D90AdisTS/D90AdisTS.py
+++ b/src/Model/D90AdisTS/D90AdisTS.py
@@ -62,7 +62,7 @@ class D90AdisTS(SQLSubModel):
                     id INTEGER NOT NULL PRIMARY KEY,
                     name TEXT NOT NULL,
                     d90 REAL NOT NULL,
-                    enabled BOOLEAN NOT NULL,
+                    enabled BOOLEAN NOT NULL
                   )
                 """)
 
diff --git a/src/Model/D90AdisTS/D90AdisTSSpec.py b/src/Model/D90AdisTS/D90AdisTSSpec.py
index d1ab2c8d65ccd80cb793394ae5cd972d8a634d75..7ce6bc3ad0fcf011994ac1035919a95fc43c9467 100644
--- a/src/Model/D90AdisTS/D90AdisTSSpec.py
+++ b/src/Model/D90AdisTS/D90AdisTSSpec.py
@@ -177,7 +177,7 @@ class D90AdisTSSpec(SQLSubModel):
         return self._d90
 
     @d90.setter
-    def d90(self, concentration):
+    def d90(self, d90):
         self._d90 = d90
         self._status.modified()
 
diff --git a/src/View/D90AdisTS/Table.py b/src/View/D90AdisTS/Table.py
new file mode 100644
index 0000000000000000000000000000000000000000..13d5555cb7a43845c940398e56f6b7aded460514
--- /dev/null
+++ b/src/View/D90AdisTS/Table.py
@@ -0,0 +1,217 @@
+# Table.py -- Pamhyr
+# Copyright (C) 2023-2024  INRAE
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+# -*- coding: utf-8 -*-
+
+import logging
+import traceback
+from tools import trace, timer
+
+from PyQt5.QtCore import (
+    Qt, QVariant, QAbstractTableModel,
+    QCoreApplication, QModelIndex, pyqtSlot,
+    QRect,
+)
+
+from PyQt5.QtWidgets import (
+    QDialogButtonBox, QPushButton, QLineEdit,
+    QFileDialog, QTableView, QAbstractItemView,
+    QUndoStack, QShortcut, QAction, QItemDelegate,
+    QComboBox,
+)
+
+from View.Tools.PamhyrTable import PamhyrTableModel
+
+from View.D90AdisTS.UndoCommand import (
+    SetCommand, AddCommand, SetCommandSpec,
+    DelCommand,
+)
+
+logger = logging.getLogger()
+
+_translate = QCoreApplication.translate
+
+
+class ComboBoxDelegate(QItemDelegate):
+    def __init__(self, data=None, ic_spec_lst=None, trad=None, parent=None, mode="reaches"):
+        super(ComboBoxDelegate, self).__init__(parent)
+
+        self._data = data
+        self._mode = mode
+        self._trad = trad
+        self._ic_spec_lst = ic_spec_lst
+
+    def createEditor(self, parent, option, index):
+        self.editor = QComboBox(parent)
+
+        val = []
+        if self._mode == "kp":
+            reach_id = self._ic_spec_lst[index.row()].reach
+
+            reach = next(filter(lambda edge: edge.id == reach_id, self._data.edges()))
+
+            if reach_id is not None:
+                val = list(
+                    map(
+                        lambda kp: str(kp), reach.reach.get_kp()
+                    )
+                )
+        else:
+            val = list(
+                map(
+                    lambda n: n.name, self._data.edges()
+                )
+            )
+
+        self.editor.addItems(
+            [self._trad['not_associated']] +
+            val
+        )
+
+        self.editor.setCurrentText(str(index.data(Qt.DisplayRole)))
+        return self.editor
+
+    def setEditorData(self, editor, index):
+        value = index.data(Qt.DisplayRole)
+        self.editor.currentTextChanged.connect(self.currentItemChanged)
+
+    def setModelData(self, editor, model, index):
+        text = str(editor.currentText())
+        model.setData(index, text)
+        editor.close()
+        editor.deleteLater()
+
+    def updateEditorGeometry(self, editor, option, index):
+        r = QRect(option.rect)
+        if self.editor.windowFlags() & Qt.Popup:
+            if editor.parent() is not None:
+                r.setTopLeft(self.editor.parent().mapToGlobal(r.topLeft()))
+        editor.setGeometry(r)
+
+    @pyqtSlot()
+    def currentItemChanged(self):
+        self.commitData.emit(self.sender())
+
+
+class D90TableModel(PamhyrTableModel):
+    def __init__(self, river=None, data=None, **kwargs):
+        self._river = river
+
+        super(D90TableModel, self).__init__(data=data, **kwargs)
+
+        self._data = data
+
+    def _setup_lst(self):
+        self._lst = self._data._data
+
+    def rowCount(self, parent):
+        return len(self._lst)
+
+    def data(self, index, role):
+        if role != Qt.ItemDataRole.DisplayRole:
+            return QVariant()
+
+        row = index.row()
+        column = index.column()
+
+        if self._headers[column] is "name":
+            n = self._lst[row].name
+            if n is None or n == "":
+                return self._trad['not_associated']
+            return n
+        elif self._headers[column] is "reach":
+            n = self._lst[row].reach
+            if n is None:
+                return self._trad['not_associated']
+            return next(filter(lambda edge: edge.id == n, self._river.edges())).name
+        elif self._headers[column] is "start_kp":
+            n = self._lst[row].start_kp
+            if n is None:
+                return self._trad['not_associated']
+            return n
+        elif self._headers[column] is "end_kp":
+            n = self._lst[row].end_kp
+            if n is None:
+                return self._trad['not_associated']
+            return n
+        elif self._headers[column] is "d90":
+            n = self._lst[row].d90
+            if n is None:
+                return self._trad['not_associated']
+            return n
+
+        return QVariant()
+
+    def setData(self, index, value, role=Qt.EditRole):
+        if not index.isValid() or role != Qt.EditRole:
+            return False
+
+        row = index.row()
+        column = index.column()
+
+        try:
+            if self._headers[column] != "reach":
+                self._undo.push(
+                    SetCommandSpec(
+                        self._lst, row, self._headers[column], value
+                    )
+                )
+            elif self._headers[column] == "reach":
+                print(self._river.edge(value).id)
+                self._undo.push(
+                    SetCommandSpec(
+                        self._lst, row, self._headers[column], self._river.edge(value).id
+                    )
+                )
+        except Exception as e:
+            logger.info(e)
+            logger.debug(traceback.format_exc())
+
+        self.dataChanged.emit(index, index)
+        return True
+
+    def add(self, row, parent=QModelIndex()):
+        self.beginInsertRows(parent, row, row - 1)
+
+        self._undo.push(
+            AddCommand(
+                self._data, self._lst, row
+            )
+        )
+
+        self.endInsertRows()
+        self.layoutChanged.emit()
+
+    def delete(self, rows, parent=QModelIndex()):
+        self.beginRemoveRows(parent, rows[0], rows[-1])
+
+        self._undo.push(
+            DelCommand(
+                self._data, self._lst, rows
+            )
+        )
+
+        self.endRemoveRows()
+        self.layoutChanged.emit()
+
+    def undo(self):
+        self._undo.undo()
+        self.layoutChanged.emit()
+
+    def redo(self):
+        self._undo.redo()
+        self.layoutChanged.emit()
+
diff --git a/src/View/D90AdisTS/TableDefault.py b/src/View/D90AdisTS/TableDefault.py
new file mode 100644
index 0000000000000000000000000000000000000000..c3231d424916abef2ccb4c1790739737e44e5989
--- /dev/null
+++ b/src/View/D90AdisTS/TableDefault.py
@@ -0,0 +1,95 @@
+# Table.py -- Pamhyr
+# Copyright (C) 2023-2024  INRAE
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+# -*- coding: utf-8 -*-
+
+import logging
+import traceback
+from tools import trace, timer
+
+from PyQt5.QtCore import (
+    Qt, QVariant, QAbstractTableModel,
+    QCoreApplication, QModelIndex, pyqtSlot,
+    QRect,
+)
+
+from PyQt5.QtWidgets import (
+    QDialogButtonBox, QPushButton, QLineEdit,
+    QFileDialog, QTableView, QAbstractItemView,
+    QUndoStack, QShortcut, QAction, QItemDelegate,
+    QComboBox,
+)
+
+from View.Tools.PamhyrTable import PamhyrTableModel
+
+from View.D90AdisTS.UndoCommand import (
+    SetCommand,
+)
+
+logger = logging.getLogger()
+
+_translate = QCoreApplication.translate
+
+class D90TableDefaultModel(PamhyrTableModel):
+    def __init__(self, **kwargs):
+        super(D90TableDefaultModel, self).__init__(**kwargs)
+
+    def data(self, index, role):
+        if role != Qt.ItemDataRole.DisplayRole:
+            return QVariant()
+
+        row = index.row()
+        column = index.column()
+
+        if self._headers[column] is "name":
+            return self._data[row].name
+        elif self._headers[column] is "d90":
+            n = self._data[row].d90
+            if n is None:
+                return self._trad['not_associated']
+            return n
+
+        return QVariant()
+
+    def setData(self, index, value, role=Qt.EditRole):
+        if not index.isValid() or role != Qt.EditRole:
+            return False
+
+        row = index.row()
+        column = index.column()
+
+        try:
+            if self._headers[column] is not None:
+                self._undo.push(
+                    SetCommand(
+                        self._data, row, self._headers[column], value
+                    )
+                )
+        except Exception as e:
+            logger.info(e)
+            logger.debug(traceback.format_exc())
+
+        self.dataChanged.emit(index, index)
+        return True
+
+    def undo(self):
+        self._undo.undo()
+        self.layoutChanged.emit()
+
+    def redo(self):
+        self._undo.redo()
+        self.layoutChanged.emit()
+
diff --git a/src/View/D90AdisTS/UndoCommand.py b/src/View/D90AdisTS/UndoCommand.py
new file mode 100644
index 0000000000000000000000000000000000000000..f0644955f804a69300d441ff4787ac60a377ab7d
--- /dev/null
+++ b/src/View/D90AdisTS/UndoCommand.py
@@ -0,0 +1,150 @@
+# UndoCommand.py -- Pamhyr
+# Copyright (C) 2023-2024  INRAE
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+# -*- coding: utf-8 -*-
+
+from copy import deepcopy
+from tools import trace, timer
+
+from PyQt5.QtWidgets import (
+    QMessageBox, QUndoCommand, QUndoStack,
+)
+
+from Model.D90AdisTS.D90AdisTS import D90AdisTS
+from Model.D90AdisTS.D90AdisTSList import D90AdisTSList
+
+
+class SetCommand(QUndoCommand):
+    def __init__(self, data, row, column, new_value):
+        QUndoCommand.__init__(self)
+
+        self._data = data
+        self._row = row
+        self._column = column
+
+        if self._column == "name":
+            self._old = self._data[self._row].name
+        elif self._column == "d90":
+            self._old = self._data[self._row].d90
+
+        _type = float
+        if column == "name":
+            _type = str
+
+        self._new = _type(new_value)
+
+    def undo(self):
+        if self._column == "name":
+            self._data[self._row].name = self._old
+        elif self._column == "d90":
+            self._data[self._row].d90 = self._old
+
+    def redo(self):
+        if self._column == "name":
+            self._data[self._row].name = self._new
+        elif self._column == "d90":
+            self._data[self._row].d90 = self._new
+
+class SetCommandSpec(QUndoCommand):
+    def __init__(self, data, row, column, new_value):
+        QUndoCommand.__init__(self)
+
+        self._data = data
+        self._row = row
+        self._column = column
+
+        if self._column == "name":
+            self._old = self._data[self._row].name
+        elif self._column == "reach":
+            self._old = self._data[self._row].reach
+        elif self._column == "start_kp":
+            self._old = self._data[self._row].start_kp
+        elif self._column == "end_kp":
+            self._old = self._data[self._row].end_kp
+        elif self._column == "d90":
+            self._old = self._data[self._row].d90
+
+        _type = float
+        if column == "name":
+            _type = str
+        elif column == "reach":
+            _type = int
+
+        self._new = _type(new_value)
+
+    def undo(self):
+        if self._column == "name":
+            self._data[self._row].name = self._old
+        elif self._column == "reach":
+            self._data[self._row].reach = self._old
+        elif self._column == "start_kp":
+            self._data[self._row].start_kp = self._old
+        elif self._column == "end_kp":
+            self._data[self._row].end_kp = self._old
+        elif self._column == "d90":
+            self._data[self._row].d90 = self._old
+
+    def redo(self):
+        if self._column == "name":
+            self._data[self._row].name = self._new
+        elif self._column == "reach":
+            self._data[self._row].reach = self._new
+        elif self._column == "start_kp":
+            self._data[self._row].start_kp = self._new
+        elif self._column == "end_kp":
+            self._data[self._row].end_kp = self._new
+        elif self._column == "d90":
+            self._data[self._row].d90 = self._new
+
+class AddCommand(QUndoCommand):
+    def __init__(self, data, ics_spec, index):
+        QUndoCommand.__init__(self)
+
+        self._data = data
+        self._ics_spec = ics_spec
+        self._index = index
+        self._new = None
+
+    def undo(self):
+        self._data.delete_i([self._index])
+
+    def redo(self):
+        if self._new is None:
+            self._new = self._data.new(self._index)
+        else:
+            self._data.insert(self._index, self._new)
+
+class DelCommand(QUndoCommand):
+    def __init__(self, data, ics_spec, rows):
+        QUndoCommand.__init__(self)
+
+        self._data = data
+        self._ics_spec = ics_spec
+        self._rows = rows
+        #self._data = data
+
+        self._ic = []
+        for row in rows:
+            self._ic.append((row, self._ics_spec[row]))
+        self._ic.sort()
+
+    def undo(self):
+        for row, el in self._ic:
+            self._data.insert(row, el)
+
+    def redo(self):
+        self._data.delete_i(self._rows)
+
diff --git a/src/View/D90AdisTS/Window.py b/src/View/D90AdisTS/Window.py
new file mode 100644
index 0000000000000000000000000000000000000000..5fffc17d68a61d9e2134c39fe9996a4f3a33c576
--- /dev/null
+++ b/src/View/D90AdisTS/Window.py
@@ -0,0 +1,283 @@
+# Window.py -- Pamhyr
+# Copyright (C) 2023-2024  INRAE
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+# -*- coding: utf-8 -*-
+
+import os
+import logging
+
+from tools import trace, timer, logger_exception
+
+from View.Tools.PamhyrWindow import PamhyrWindow
+
+from PyQt5.QtGui import (
+    QKeySequence, QIcon,
+)
+
+from PyQt5.QtCore import (
+    Qt, QVariant, QAbstractTableModel,
+    QCoreApplication, QModelIndex, pyqtSlot,
+    QRect, QItemSelectionModel,
+)
+
+from PyQt5.QtWidgets import (
+    QDialogButtonBox, QPushButton, QLineEdit,
+    QFileDialog, QTableView, QAbstractItemView,
+    QUndoStack, QShortcut, QAction, QItemDelegate,
+    QComboBox, QVBoxLayout, QHeaderView, QTabWidget,
+    QVBoxLayout, QToolBar, QAction, QToolButton,
+)
+
+from Modules import Modules
+
+from View.InitialConditionsAdisTS.UndoCommand import (
+    SetCommand,
+)
+
+from View.D90AdisTS.TableDefault import (
+    D90TableDefaultModel,
+)
+
+from View.D90AdisTS.Table import (
+    D90TableModel, ComboBoxDelegate,
+)
+
+from View.D90AdisTS.translate import D90AdisTSTranslate
+
+from Solver.Mage import Mage8
+
+_translate = QCoreApplication.translate
+
+logger = logging.getLogger()
+
+
+class D90AdisTSWindow(PamhyrWindow):
+    _pamhyr_ui = "D90AdisTS"
+    _pamhyr_name = "D90 AdisTS"
+
+    def __init__(self, data=None, study=None, config=None, parent=None):
+        self._data = []
+        self._data.append(data)
+        trad = D90AdisTSTranslate()
+
+        name = (
+            trad[self._pamhyr_name] +
+            " - " + study.name +
+            " - " + self._data[0].name
+        )
+
+        super(D90AdisTSWindow, self).__init__(
+            title=name,
+            study=study,
+            config=config,
+            trad=trad,
+            parent=parent
+        )
+
+        self._hash_data.append(data)
+
+        self._d90_adists_lst = study.river.d90_adists
+
+        self.setup_table()
+
+        self.ui.setWindowTitle(self._title)
+
+    def setup_table(self):
+
+        path_icons = os.path.join(self._get_ui_directory(), f"ressources")
+
+        table_default = self.find(QTableView, f"tableView")
+
+        self._table = D90TableDefaultModel(
+            table_view=table_default,
+            table_headers=self._trad.get_dict("table_headers"),
+            editable_headers=["name", "d90"],
+            delegates={},
+            data=self._data,
+            undo=self._undo_stack,
+            trad=self._trad
+        )
+
+        table_default.setModel(self._table)
+        table_default.setSelectionBehavior(QAbstractItemView.SelectRows)
+        table_default.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+        table_default.setAlternatingRowColors(True)
+
+        layout = self.find(QVBoxLayout, f"verticalLayout_1")
+        toolBar = QToolBar()
+        layout.addWidget(toolBar)
+
+        action_add = QAction(self)
+        action_add.setIcon(QIcon(os.path.join(path_icons, f"add.png")))
+        action_add.triggered.connect(self.add)
+        action_delete = QAction(self)
+        action_delete.setIcon(QIcon(os.path.join(path_icons, f"del.png")))
+        action_delete.triggered.connect(self.delete)
+
+        toolBar.addAction(action_add)
+        toolBar.addAction(action_delete)
+
+        self.table_spec = QTableView()
+        layout.addWidget(self.table_spec)
+
+        self._delegate_reach = ComboBoxDelegate(
+            trad=self._trad,
+            data=self._study.river,
+            ic_spec_lst=self._data[0]._data,
+            parent=self,
+            mode="reaches"
+        )
+        self._delegate_kp = ComboBoxDelegate(
+            trad=self._trad,
+            data=self._study.river,
+            ic_spec_lst=self._data[0]._data,
+            parent=self,
+            mode="kp"
+        )
+
+        self._table_spec = D90TableModel(
+            table_view=self.table_spec,
+            table_headers=self._trad.get_dict("table_headers_spec"),
+            editable_headers=["name", "reach", "start_kp", "end_kp", "d90"],
+            delegates={
+                "reach": self._delegate_reach,
+                "start_kp": self._delegate_kp,
+                "end_kp": self._delegate_kp
+            },
+            data=self._data[0],
+            undo=self._undo_stack,
+            trad=self._trad,
+            river=self._study.river
+        )
+
+        self.table_spec.setModel(self._table_spec)
+        self.table_spec.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.table_spec.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+        self.table_spec.setAlternatingRowColors(True)
+
+        selectionModel = self.table_spec.selectionModel()
+        index = self.table_spec.model().index(0, 0)
+
+        selectionModel.select(
+            index,
+            QItemSelectionModel.Rows |
+            QItemSelectionModel.ClearAndSelect |
+            QItemSelectionModel.Select
+        )
+        self.table_spec.scrollTo(index)
+
+    def index_selected_row(self):
+        #table = self.find(QTableView, f"tableView")
+        table = self.table_spec
+        rows = table.selectionModel()\
+                    .selectedRows()
+
+        if len(rows) == 0:
+            return 0
+
+        return rows[0].row()
+
+    def index_selected_rows(self):
+        #table = self.find(QTableView, f"tableView")
+        table = self.table_spec
+        return list(
+            # Delete duplicate
+            set(
+                map(
+                    lambda i: i.row(),
+                    table.selectedIndexes()
+                )
+            )
+        )
+
+    def move_up(self):
+        row = self.index_selected_row()
+        self._table.move_up(row)
+        self._update()
+
+    def move_down(self):
+        row = self.index_selected_row()
+        self._table.move_down(row)
+        self._update()
+
+    def _copy(self):
+        rows = list(
+            map(
+                lambda row: row.row(),
+                self.tableView.selectionModel().selectedRows()
+            )
+        )
+
+        table = list(
+            map(
+                lambda eic: list(
+                    map(
+                        lambda k: eic[1][k],
+                        ["kp", "discharge", "elevation"]
+                    )
+                ),
+                filter(
+                    lambda eic: eic[0] in rows,
+                    enumerate(self._ics.lst())
+                )
+            )
+        )
+
+        self.copyTableIntoClipboard(table)
+
+    def _paste(self):
+        header, data = self.parseClipboardTable()
+
+        if len(data) + len(header) == 0:
+            return
+
+        logger.debug(
+            "IC: Paste: " +
+            f"header = {header}, " +
+            f"data = {data}"
+        )
+
+        try:
+            row = self.index_selected_row()
+            # self._table.paste(row, header, data)
+            self._table.paste(row, [], data)
+        except Exception as e:
+            logger_exception(e)
+
+        self._update()
+
+    def _undo(self):
+        self._table.undo()
+        self._update()
+
+    def _redo(self):
+        self._table.redo()
+        self._update()
+
+    def add(self):
+        rows = self.index_selected_rows()
+        if len(self._data[0]._data) == 0 or len(rows) == 0:
+            self._table_spec.add(0)
+        else:
+            self._table_spec.add(rows[0])
+
+    def delete(self):
+        print("del")
+        rows = self.index_selected_rows()
+        if len(rows) == 0:
+            print("len 0")
+            return
+        self._table_spec.delete(rows)
diff --git a/src/View/D90AdisTS/translate.py b/src/View/D90AdisTS/translate.py
new file mode 100644
index 0000000000000000000000000000000000000000..5a7bbd755d514a6d628c3828d95883296bf13d95
--- /dev/null
+++ b/src/View/D90AdisTS/translate.py
@@ -0,0 +1,46 @@
+# translate.py -- Pamhyr
+# Copyright (C) 2023-2024  INRAE
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+# -*- coding: utf-8 -*-
+
+from PyQt5.QtCore import QCoreApplication
+
+from View.Translate import MainTranslate
+
+_translate = QCoreApplication.translate
+
+
+class D90AdisTSTranslate(MainTranslate):
+    def __init__(self):
+        super(D90AdisTSTranslate, self).__init__()
+
+        self._dict["D90 AdisTS"] = _translate(
+            "D90AdisTS", "D90 AdisTS")
+
+        self._dict["kp"] = self._dict["unit_kp"]
+
+        self._sub_dict["table_headers"] = {
+            "name": self._dict["name"],
+            "d90": _translate("Unit", "D90"),
+        }
+
+        self._sub_dict["table_headers_spec"] = {
+            "name": self._dict["name"],
+            "reach": self._dict["reach"],
+            "start_kp": _translate("Unit", "Start_KP (m)"),
+            "end_kp": _translate("Unit", "End_KP (m)"),
+            "d90": _translate("Unit", "D90"),
+        }
diff --git a/src/View/MainWindow.py b/src/View/MainWindow.py
index 12d9af6798387b768f78f877e3bc8a282b4327d0..c61fae9072100a0ec3c1e952ffa67fe2cb8f2209 100644
--- a/src/View/MainWindow.py
+++ b/src/View/MainWindow.py
@@ -77,6 +77,7 @@ from View.Results.ReadingResultsDialog import ReadingResultsDialog
 from View.Debug.Window import ReplWindow
 from View.OutputKpAdisTS.Window import OutputKpAdisTSWindow
 from View.Pollutants.Window import PollutantsWindow
+from View.D90AdisTS.Window import D90AdisTSWindow
 
 # Optional internal display of documentation for make the application
 # package lighter...
@@ -869,17 +870,23 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
     ###############
 
     def open_d90(self):
+        if len(self._study.river.d90_adists.lst) != 0:
+            d90_default = self._study.river.d90_adists.lst[0]
+        else:
+            d90_default = self._study.river.d90_adists.new(0)
+
         if self.sub_window_exists(
-            PollutantsWindow,
-            data=[self._study, None]
+            D90AdisTSWindow,
+            data=[self._study, None, d90_default]
         ):
             return
 
-        Pollutants = PollutantsWindow(
+        D90AdisTS = D90AdisTSWindow(
             study=self._study,
-            parent=self
+            parent=self,
+            data=d90_default
         )
-        Pollutants.show()
+        D90AdisTS.show()
 
     def open_pollutants(self):
         if self.sub_window_exists(
diff --git a/src/View/ui/D90AdisTS.ui b/src/View/ui/D90AdisTS.ui
new file mode 100644
index 0000000000000000000000000000000000000000..b4fe3e2d6777785e701a5c7771e11d6ce77952af
--- /dev/null
+++ b/src/View/ui/D90AdisTS.ui
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1024</width>
+    <height>576</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QGridLayout" name="gridLayout">
+    <item row="0" column="0">
+     <widget class="QSplitter" name="splitter_2">
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <widget class="QWidget" name="layoutWidget">
+       <layout class="QVBoxLayout" name="verticalLayout_3">
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout"/>
+        </item>
+        <item>
+         <widget class="QTableView" name="tableView"/>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QSplitter" name="splitter">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <widget class="QWidget" name="verticalLayoutWidget">
+        <layout class="QVBoxLayout" name="verticalLayout_1"/>
+       </widget>
+       <widget class="QWidget" name="verticalLayoutWidget_2">
+        <layout class="QVBoxLayout" name="verticalLayout_2"/>
+       </widget>
+      </widget>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>1024</width>
+     <height>22</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+  <widget class="QToolBar" name="toolBar">
+   <property name="windowTitle">
+    <string>toolBar</string>
+   </property>
+   <attribute name="toolBarArea">
+    <enum>TopToolBarArea</enum>
+   </attribute>
+   <attribute name="toolBarBreak">
+    <bool>false</bool>
+   </attribute>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests_cases/Enlargement/Enlargement.pamhyr b/tests_cases/Enlargement/Enlargement.pamhyr
index 9aa6c32eaddadc52309022f8de7ef26e5bb9a78a..ae39194e16d126cba23500f15e4cad5347be997e 100644
Binary files a/tests_cases/Enlargement/Enlargement.pamhyr and b/tests_cases/Enlargement/Enlargement.pamhyr differ