airGRiwrm issueshttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues2023-01-05T09:33:09+01:00https://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/99CreateInputsmodel [Breaking change]: do not allow to use `Qobs` on nodes othe...2023-01-05T09:33:09+01:00Dorchies DavidCreateInputsmodel [Breaking change]: do not allow to use `Qobs` on nodes other than Direct Injection and DiversionWith the introduction of Diversion nodes (#95) arises the need to clarify the use of the parameter `Qobs` in `CreateInputsModel`.
`Qobs` is only necessary on nodes of type "Direct Injection" and "Diversion" which use a flow time series ...With the introduction of Diversion nodes (#95) arises the need to clarify the use of the parameter `Qobs` in `CreateInputsModel`.
`Qobs` is only necessary on nodes of type "Direct Injection" and "Diversion" which use a flow time series provided by the user. Until now, if the matrix had flows for other type of nodes they were silently ignored.
I propose to raise an error in the case of using Qobs on node other type than the ones which really need it.
A simple warning can eventually be ignored by the user and can lead to errors difficult to debug since this case can come from mismatch column names.v0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/143ConvertSD not allowing T < 0 °C2024-03-03T10:41:10+01:00Thirel GuillaumeConvertSD not allowing T < 0 °CconvertSD gives temperatures that are always >= 0 °C, with several values exactly equal to 0 °C.
See below an example with some personal data, I'll try to reproduce that with data from seineBasin2. It seems the argument temperature = T...convertSD gives temperatures that are always >= 0 °C, with several values exactly equal to 0 °C.
See below an example with some personal data, I'll try to reproduce that with data from seineBasin2. It seems the argument temperature = TRUE is not passed to other functions. See in https://gitlab.irstea.fr/in-wop/airGRiwrm/-/blob/dev/R/ConvertMeteoSD.R, `output <- lapply(id_runoff, ConvertMeteoSD, griwrm = x, meteo = meteo)` or
```r
output <- ConvertMeteoSD(
meteo[, upperIDs, drop = FALSE],
areas = areas
)
```
```
> griwrm
id down length model area
1 I5060001_ONDE I6201020_HYDRO&EDF 5.92 RunModel_CemaNeigeGR4J 98.68
2 I6122020_HYDRO&EDF I5060001_ONDE 2.55 RunModel_CemaNeigeGR4J 91.48
3 I6201020_HYDRO&EDF I6211020_HYDRO&EDF 10.29 RunModel_CemaNeigeGR4J 298.47
4 I6302020_HYDRO&EDF I6322010_HYDRO&EDF 5.88 RunModel_CemaNeigeGR4J 138.71
5 I6322010_HYDRO&EDF I6421030_HYDRO&EDF 17.45 RunModel_CemaNeigeGR4J 183.04
6 I6211020_HYDRO&EDF I5110200_RCS 13.91 RunModel_CemaNeigeGR4J 375.54
7 I5110200_RCS I6421030_HYDRO&EDF 14.40 RunModel_CemaNeigeGR4J 569.54
8 I6421030_HYDRO&EDF <NA> NA RunModel_CemaNeigeGR4J 1009.10
9 I6413010_HYDRO&EDF I6421030_HYDRO&EDF 10.93 RunModel_CemaNeigeGR4J 148.18
TempMean <- as.data.frame(ConvertMeteoSD(griwrm, TempTot, temperature = TRUE))
> summary(TempMean)
I5060001_ONDE I6122020_HYDRO&EDF I6201020_HYDRO&EDF I6302020_HYDRO&EDF I6322010_HYDRO&EDF I6211020_HYDRO&EDF
Min. : 0.000 Min. :-7.107 Min. : 0.000 Min. :-6.211 Min. : 0.000 Min. : 0.000
1st Qu.: 8.272 1st Qu.: 8.438 1st Qu.: 8.217 1st Qu.: 8.532 1st Qu.: 8.632 1st Qu.: 8.486
Median :11.891 Median :11.968 Median :11.821 Median :12.138 Median :12.240 Median :12.109
Mean :11.928 Mean :12.003 Mean :11.885 Mean :12.204 Mean :12.326 Mean :12.149
3rd Qu.:15.793 3rd Qu.:15.816 3rd Qu.:15.738 3rd Qu.:16.076 3rd Qu.:16.183 3rd Qu.:16.024
Max. :32.557 Max. :32.413 Max. :33.003 Max. :33.561 Max. :34.522 Max. :32.432
I5110200_RCS I6421030_HYDRO&EDF I6413010_HYDRO&EDF DatesR
Min. : 0.00 Min. : 0.000 Min. :-6.677 Min. :1951-01-01 00:00:00
1st Qu.: 8.58 1st Qu.: 8.656 1st Qu.: 8.595 1st Qu.:1988-07-01 12:00:00
Median :12.20 Median :12.267 Median :12.197 Median :2025-12-31 00:00:00
Mean :12.25 Mean :12.340 Mean :12.255 Mean :2025-12-31 00:00:00
3rd Qu.:16.15 3rd Qu.:16.210 3rd Qu.:16.149 3rd Qu.:2063-07-01 12:00:00
Max. :32.68 Max. :34.491 Max. :33.973 Max. :2100-12-31 00:00:00
```https://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/140Release v0.6.22023-11-01T21:07:25+01:00Dorchies DavidRelease v0.6.2v0.6.2Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/139airGR changes cause failed check2024-02-13T19:34:47+01:00Dorchies DavidairGR changes cause failed checkThe release of [airGR 1.7.5](https://gitlab.irstea.fr/HYCAR-Hydro/airgr/-/milestones/7) introduces changes in calibration results which break airGRiwrm regression test on calibration parametersThe release of [airGR 1.7.5](https://gitlab.irstea.fr/HYCAR-Hydro/airgr/-/milestones/7) introduces changes in calibration results which break airGRiwrm regression test on calibration parametersv0.6.2Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/138Problem when trying to fix parameter values in semi-distributed mode2024-03-24T17:42:57+01:00Thibault HallouinProblem when trying to fix parameter values in semi-distributed modeHi,
I think there is a bug when trying to fix parameters in a semi-distributed mode. It seems to be due to the varying numbers of parameters for each sub-basin (depending on the presence of a lag model or not). Here is an example (reusi...Hi,
I think there is a bug when trying to fix parameters in a semi-distributed mode. It seems to be due to the varying numbers of parameters for each sub-basin (depending on the presence of a lag model or not). Here is an example (reusing some code written by @guillaume.thirel, thanks Guillaume):
```R
library(airGRiwrm)
rm(list = ls())
data(Severn)
data(X0310010)
## hydro network
gauges <- c("54057", "54032", "54001")
nodes <- Severn$BasinsInfo[, c("gauge_id", "downstream_id", "distance_downstream", "area")]
nodes <- nodes[nodes$gauge_id %in% gauges, ]
nodes$model <- "RunModel_CemaNeigeGR4J"
griwrm <- airGRiwrm::CreateGRiwrm(
nodes,
list(id="gauge_id", down="downstream_id", length="distance_downstream")
)
## inputs
basins_obs <- Severn$BasinsObs
dates <- basins_obs[[1]]$DatesR
precip_tot <- cbind(sapply(basins_obs, function(x) {x$precipitation}))
pot_evap_tot <- cbind(sapply(basins_obs, function(x) {x$peti}))
q_obs <- cbind(sapply(basins_obs, function(x) {x$discharge_spec}))
precip <- airGRiwrm::ConvertMeteoSD(griwrm, precip_tot[, griwrm$id])
pot_evap <- airGRiwrm::ConvertMeteoSD(griwrm, pot_evap_tot[, griwrm$id])
hypso <- array(
data=rep(BasinInfo$HypsoData, 3),
dim=c(101,3)
)
colnames(hypso) <- gauges
inputs_model <- airGRiwrm::CreateInputsModel(
griwrm,
DatesR=dates,
Precip=precip,
PotEvap=pot_evap,
TempMean=pot_evap+5, # fake Temp
HypsoData=hypso,
NLayers=setNames(c(5, 6, 7), gauges),
IsHyst=TRUE
)
calib_options <- airGRiwrm::CreateCalibOptions(
inputs_model,
FixedParam=c(
NA, # C (lag)
NA, # X1 (GR4J)
NA, # X2 (GR4J)
NA, # X3 (GR4J)
NA, # X4 (GR4J)
0.25, # cT (CemaNeige)
NA, # Kf (CemaNeige)
10, # Gacc (CemaNeige)
NA # Gseuil (CemaNeige)
)
)
```
which results for me in the following error:
> Error in (function (FUN_MOD, FUN_CALIB = Calibration_Michel, FUN_TRANSFO = NULL, :
Incompatibility between 'FixedParam' length and 'FUN_MOD'
The following trick (provided to me by @laurent.strohmenger, thanks Laurent) bypasses the problem:
```R
calib_options <- airGRiwrm::CreateCalibOptions(
inputs_model
)
for (code in names(calib_options))
{
n_param <- length(calib_options[[code]]$FixedParam)
if (n_param == 9)
{
calib_options[[code]]$FixedParam <- c(
NA, # C (lag)
NA, # X1 (GR4J)
NA, # X2 (GR4J)
NA, # X3 (GR4J)
NA, # X4 (GR4J)
0.25, # cT (CemaNeige)
NA, # Kf (CemaNeige)
10, # Gacc (CemaNeige)
NA # Gseuil (CemaNeige)
)
}
else if (n_param == 8)
{
calib_options[[code]]$FixedParam <- c(
NA, # X1 (GR4J)
NA, # X2 (GR4J)
NA, # X3 (GR4J)
NA, # X4 (GR4J)
0.25, # cT (CemaNeige)
NA, # Kf (CemaNeige)
10, # Gacc (CemaNeige)
NA # Gseuil (CemaNeige)
)
}
else
{
stop("sub-basin with number of parameters not equal to 8 or 9")
}
}
```https://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/137Update HAL URL to pass cran checks2024-02-13T16:42:11+01:00Delaigue OlivierUpdate HAL URL to pass cran checksThe HAL archive URL has been modified. The address `archives-ouvertes.fr` is automatically redirected to `hal.science`. However, the CRAN does not allowed redirection. So we hat to use `hal.science` in the following files.
- R/Calibrat...The HAL archive URL has been modified. The address `archives-ouvertes.fr` is automatically redirected to `hal.science`. However, the CRAN does not allowed redirection. So we hat to use `hal.science` in the following files.
- R/Calibration.GriwrmInputsModel.R
- vignettes/airGRiwrm.bibv0.6.2https://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/135Ungauged nodes: X4 transformation not handled with CemaNeige models2023-06-20T15:26:18+02:00Dorchies DavidUngauged nodes: X4 transformation not handled with CemaNeige models`InputsModel$model$hasX4` is always set to `FALSE` in case of CemaNeige model and subsequently the X4 transformation is not handled for the ungauged nodes.`InputsModel$model$hasX4` is always set to `FALSE` in case of CemaNeige model and subsequently the X4 transformation is not handled for the ungauged nodes.v0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/134Crash with Hysteresis in Cemaneige2023-06-20T15:26:18+02:00Dorchies DavidCrash with Hysteresis in CemaneigeAs reported by @guillaume.thirel, Calibration crashes when using hysteresis in Cemaneige:
```r
OutputsCalib <- suppressWarnings(
+ Calibration(InputsModel, RunOptions, InputsCrit, CalibOptions))
Calibration.GRiwrmInputsModel: Processi...As reported by @guillaume.thirel, Calibration crashes when using hysteresis in Cemaneige:
```r
OutputsCalib <- suppressWarnings(
+ Calibration(InputsModel, RunOptions, InputsCrit, CalibOptions))
Calibration.GRiwrmInputsModel: Processing sub-basin 54057...
Grid-Screening in progress (0%Error in .ArgumentsCheckGR(InputsModel, RunOptions, Param) :
'Param' must be a vector of length 8 and contain no NA
In addition: There were 12 warnings (use warnings() to see them)
```
Reproductible example: [Severn_GR4JCemaNeigeHyst_semiglobal.R](/uploads/b3c3d704e673fee34d0131415404b414/Severn_GR4JCemaNeigeHyst_semiglobal.R)v0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/132Ungauged node - CreateGRiwrm: Search donor through Diversion if not available...2023-05-23T14:35:19+02:00Dorchies DavidUngauged node - CreateGRiwrm: Search donor through Diversion if not available by natural networkIn this following case, `CreateGRiwrm` stop with the following error message:
```
Error in FUN(X[[i]], ...) :
No Gauged node found downstream the node '54001'
```
![image](/uploads/ae5464fec327ec9d14a091c6956af699/image.png)
We sho...In this following case, `CreateGRiwrm` stop with the following error message:
```
Error in FUN(X[[i]], ...) :
No Gauged node found downstream the node '54001'
```
![image](/uploads/ae5464fec327ec9d14a091c6956af699/image.png)
We should allow `CreateGRiwrm` to search the donor through a `Diversion` if it exists.v0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/129Ungauged node: allow to define donor manually2023-05-12T15:27:57+02:00Dorchies DavidUngauged node: allow to define donor manuallyRemove update of `griwrm$donor` in `CreateInputsModel`Remove update of `griwrm$donor` in `CreateInputsModel`v0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/128Calibration: crash with a diverted ungauged node2023-05-12T14:44:09+02:00Dorchies DavidCalibration: crash with a diverted ungauged nodeThe network below results in the following error:
`
Error in InputsModel$Qupstream[Runoptions$IndPeriod_Run, i] <- OutputsModel[[InputsModel$UpstreamNodes[i]]][[InputsModel$UpstreamVarQ[i]]]:
le nombre d'objets à remplacer n'est pas mult...The network below results in the following error:
`
Error in InputsModel$Qupstream[Runoptions$IndPeriod_Run, i] <- OutputsModel[[InputsModel$UpstreamNodes[i]]][[InputsModel$UpstreamVarQ[i]]]:
le nombre d'objets à remplacer n'est pas multiple de la taille du remplacement
`
```mermaid
graph LR
id_54001[54001]
id_54095[54095]
id_Dam[Dam]
id_54095[54095]
id_54095 -->| 0 km| id_Dam
id_Dam -->| 42 km| id_54001
id_54095 -->| 42 km| id_54001
class id_54001 IntermediateGauged
class id_54095,id_54095 UpstreamUngaugedDiversion
class id_Dam Reservoir
classDef default stroke:#333
classDef UpstreamUngauged fill:#eef
classDef UpstreamGauged fill:#aaf
classDef IntermediateUngauged fill:#efe
classDef IntermediateGauged fill:#afa
classDef DirectInjection fill:#faa
classDef Reservoir fill:#9de
classDef UpstreamUngaugedDiversion fill:#eef, stroke:#faa, stroke-width:3px
classDef UpstreamGaugedDiversion fill:#aaf, stroke:#faa, stroke-width:3px
classDef IntermediateUngaugedDiversion fill:#efe, stroke:#faa, stroke-width:3px
classDef IntermediateGaugedDiversion fill:#afa, stroke:#faa, stroke-width:3px
linkStyle 0 stroke:#faa, stroke-width:2px,stroke-dasharray: 5 5;
```v0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/127Ungauged node: Diversions are not handled correctly in Calibration2023-05-11T16:58:19+02:00Dorchies DavidUngauged node: Diversions are not handled correctly in CalibrationDuring calibration of ungauged nodes, airGRirwm create a sub-network that is used for calibrating the gauged node and the related ungauged nodes together.
If the original network contains Diversions, the sub-network forget to include Di...During calibration of ungauged nodes, airGRirwm create a sub-network that is used for calibrating the gauged node and the related ungauged nodes together.
If the original network contains Diversions, the sub-network forget to include Diversions located into it.v0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/126RunModel.Supervisor: error with Diversion node2023-05-11T14:23:21+02:00Dorchies DavidRunModel.Supervisor: error with Diversion nodeIf the GRiwrm object contains Diversion that are not adjoin to the "normal" node in the table, we face this kind of error:
```
Processing: 0%Error in FUN(X[[i]], ...) :
Node 54001 must be a Direct Injection or a Diversion node
```
I...If the GRiwrm object contains Diversion that are not adjoin to the "normal" node in the table, we face this kind of error:
```
Processing: 0%Error in FUN(X[[i]], ...) :
Node 54001 must be a Direct Injection or a Diversion node
```
Its due to an offset in the labels of the node properties list.v0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/124CreateInputsModel: wrong area of sub-basin with upstream Reservoir, Lag or Di...2023-05-11T11:22:10+02:00Dorchies DavidCreateInputsModel: wrong area of sub-basin with upstream Reservoir, Lag or Direct Injection nodesIf a sub-basin has an upstream node with a model running with `area=NA`, then the area of the sub-basin is miscalculated because it doesn't take into account the area of the basins upstream the node with `area=NA`.
Solution: we need to...If a sub-basin has an upstream node with a model running with `area=NA`, then the area of the sub-basin is miscalculated because it doesn't take into account the area of the basins upstream the node with `area=NA`.
Solution: we need to look upstream the node in order to take into account the area of more upstream nodes.v0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/123Calibration: crash with ungauged node and multiple Diversions2023-05-11T08:59:50+02:00Dorchies DavidCalibration: crash with ungauged node and multiple Diversionsv0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/122Calibration: Diversion is not handled on upstream nodes2023-04-29T18:02:27+02:00Dorchies DavidCalibration: Diversion is not handled on upstream nodesThe diversion is not taken into account during calibration at least on upstream nodes.
On this small example below, if we define a huge Diversion flow in the node "54095" in order to derive the totality of the flow, the node should not ...The diversion is not taken into account during calibration at least on upstream nodes.
On this small example below, if we define a huge Diversion flow in the node "54095" in order to derive the totality of the flow, the node should not be able to be calibrated because the resulting flow `Qsim` at the node "54095" should be zero.
```mermaid
graph LR
id_54001[54001]
id_54095[54095]
id_54095[54095]
id_54095 -->| 42 km| id_54001
class id_54001 IntermediateGauged
class id_54095,id_54095 UpstreamGaugedDiversion
classDef default stroke:#333
classDef UpstreamUngauged fill:#eef
classDef UpstreamGauged fill:#aaf
classDef IntermediateUngauged fill:#efe
classDef IntermediateGauged fill:#afa
classDef DirectInjection fill:#faa
classDef Reservoir fill:#9de
classDef UpstreamUngaugedDiversion fill:#eef, stroke:#faa, stroke-width:3px
classDef UpstreamGaugedDiversion fill:#aaf, stroke:#faa, stroke-width:3px
classDef IntermediateUngaugedDiversion fill:#efe, stroke:#faa, stroke-width:3px
classDef IntermediateGaugedDiversion fill:#afa, stroke:#faa, stroke-width:3px
linkStyle 0 stroke:#faa, stroke-width:2px,stroke-dasharray: 5 5;
```v0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/119Update package citation reference2023-04-19T10:48:50+02:00Dorchies DavidUpdate package citation referenceUse the DOI provided by Inrae.
Use the Hubeau citation file as template: https://github.com/inrae/hubeau/blob/master/inst/CITATIONUse the DOI provided by Inrae.
Use the Hubeau citation file as template: https://github.com/inrae/hubeau/blob/master/inst/CITATIONv0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/117CreateSupervisor: wrong definition of allowed nodes for command2023-03-29T08:29:10+02:00Dorchies DavidCreateSupervisor: wrong definition of allowed nodes for commandThe list of nodes allowed for use as controller actuators or commands (the parameter `U` of `CreateController`), can be wrong if the network contains Diversion nodes.The list of nodes allowed for use as controller actuators or commands (the parameter `U` of `CreateController`), can be wrong if the network contains Diversion nodes.v0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/116getSD_Ids crashes on upstream nodes with Diversion2023-03-22T08:52:28+01:00Dorchies DavidgetSD_Ids crashes on upstream nodes with DiversionTodo:
- write a test
- fix the bug by removing Diversion from the griwrm object at the beginning of the process
- check get_no_SD_Ids as wellTodo:
- write a test
- fix the bug by removing Diversion from the griwrm object at the beginning of the process
- check get_no_SD_Ids as wellv0.7.0Dorchies DavidDorchies Davidhttps://gitlab.irstea.fr/in-wop/airGRiwrm/-/issues/115Ungauged node: difference of ErrorCrit between Calibration and RunModel2023-02-24T19:05:58+01:00Dorchies DavidUngauged node: difference of ErrorCrit between Calibration and RunModelHow to reproduce:
- Calibrate a little network with at least one ungauged node
- Run the model after calibration
- Compute the same ErrorCrit as the one used for Calibration
- Compare the value of the ErrorCrit of the downstream donor n...How to reproduce:
- Calibrate a little network with at least one ungauged node
- Run the model after calibration
- Compute the same ErrorCrit as the one used for Calibration
- Compare the value of the ErrorCrit of the downstream donor node: they are different
This issue is not arising on this configuration:
```mermaid
graph LR
id_54032[54032]
id_54001[54001]
id_54095[54095]
id_54001 -->| 45 km| id_54032
id_54095 -->| 42 km| id_54001
class id_54032 IntermediateGauged
class id_54001 IntermediateUngauged
class id_54095 UpstreamGauged
classDef default stroke:#333
classDef UpstreamUngauged fill:#eef
classDef UpstreamGauged fill:#aaf
classDef IntermediateUngauged fill:#efe
classDef IntermediateGauged fill:#afa
classDef DirectInjection fill:#faa
classDef Reservoir fill:#9de
classDef UpstreamUngaugedDiversion fill:#eef, stroke:#faa, stroke-width:3px
classDef UpstreamGaugedDiversion fill:#aaf, stroke:#faa, stroke-width:3px
classDef IntermediateUngaugedDiversion fill:#efe, stroke:#faa, stroke-width:3px
classDef IntermediateGaugedDiversion fill:#afa, stroke:#faa, stroke-width:3px
```
But one experience it on the following cases:
```mermaid
graph LR
id_54032[54032]
id_54001[54001]
id_54029[54029]
id_54001 -->| 45 km| id_54032
id_54029 -->| 32 km| id_54032
class id_54032 IntermediateGauged
class id_54001 UpstreamGauged
class id_54029 UpstreamUngauged
classDef default stroke:#333
classDef UpstreamUngauged fill:#eef
classDef UpstreamGauged fill:#aaf
classDef IntermediateUngauged fill:#efe
classDef IntermediateGauged fill:#afa
classDef DirectInjection fill:#faa
classDef Reservoir fill:#9de
classDef UpstreamUngaugedDiversion fill:#eef, stroke:#faa, stroke-width:3px
classDef UpstreamGaugedDiversion fill:#aaf, stroke:#faa, stroke-width:3px
classDef IntermediateUngaugedDiversion fill:#efe, stroke:#faa, stroke-width:3px
classDef IntermediateGaugedDiversion fill:#afa, stroke:#faa, stroke-width:3px
```
```mermaid
graph LR
id_54032[54032]
id_54001[54001]
id_54095[54095]
id_54001 -->| 45 km| id_54032
id_54095 -->| 42 km| id_54001
class id_54032,id_54001 IntermediateGauged
class id_54095 UpstreamUngauged
classDef default stroke:#333
classDef UpstreamUngauged fill:#eef
classDef UpstreamGauged fill:#aaf
classDef IntermediateUngauged fill:#efe
classDef IntermediateGauged fill:#afa
classDef DirectInjection fill:#faa
classDef Reservoir fill:#9de
classDef UpstreamUngaugedDiversion fill:#eef, stroke:#faa, stroke-width:3px
classDef UpstreamGaugedDiversion fill:#aaf, stroke:#faa, stroke-width:3px
classDef IntermediateUngaugedDiversion fill:#efe, stroke:#faa, stroke-width:3px
classDef IntermediateGaugedDiversion fill:#afa, stroke:#faa, stroke-width:3px
```v0.7.0Dorchies DavidDorchies David