Skip to content

Conversation

@Aslak-Meister
Copy link

Seneste version til review primo primo januar

Aslak Meister added 16 commits November 21, 2025 16:04
Alle parametre rapporteret af metoden parametre udskrives nu i Parametre-fanebladet (i output-regnearket).
… take a list of InternKote objects as input.
…opotential_heights_to_metric_heights()

slightly modified due to rebase (new name for dataclasses for levelling observation and levelled height).
…ing af højder tilføjet til

regnemotor GeodætiskRegn.
…rektioner m.m. tilføjet til GeodætiskRegn.
…gnemotoren GeodætiskRegn samt til funktionen

apply_geodetic_corrections_to_height_diffs m.v.
…g initialisering af parametre i regnemotoren GeodætiskRegn udbedret.
@Aslak-Meister Aslak-Meister changed the title Nyregnemotor Geodetic levelling Dec 19, 2025
Copy link
Collaborator

@krebslw krebslw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overordnet synes jeg det ser virkeligt godt ud, og det virker som det skal "ud-af-boksen".
Din kodestil er meget stringent og altid godt med gode docstrings :) Og synes du er lykkedes med at integrere det mere eller mindre sømløst med regnemotor-modulet.

De fleste af mine kommentarer retter sig til logikken omkring "kontrol-flowet" hvor jeg mener man kan spare en del kompleksitet. Men jeg er selv god til at finde på kringlede logiske konstruktioner i min kode, så tag ikke det hele som den absolutte sandhed :)

Dét jeg helst så rettet inden vi kan merge det, er at få dataframes helt ud af geodetic-levelling-pakken. De underliggende funktioner bør returnere de nødvendige størrelser, som det overliggende lag (regnemotor) kan pakke sammen til en dataframe og som så gemmes som excel.

Comment on lines 211 to 232
motorkwargs = {}
for regneparameter in regneparametre:
try:
parameter, værdi = regneparameter.split("=")
except ValueError:
fire.cli.print(
(
f"ADVARSEL: regneparameteren '{regneparameter} kan ikke tolkes. "
"Skal være på formen 'parameter=værdi'."
),
bold=True,
bg="yellow",
)
continue

# konverter til float hvis der er givet en talværdi
try:
værdi = float(værdi)
except ValueError:
pass

motorkwargs[parameter] = værdi
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kan godt se du ikke har lavet ændringer til dette, men denne del kan godt smides i sin egen funktion:

def fortolk_regneparametre(regneparametre: list[str])->dict:
    motorkwargs = {}
    for regneparameter in regneparametre:
        try:
            parameter, værdi = regneparameter.split("=")
        except ValueError:
            fire.cli.print(
                (
                    f"ADVARSEL: regneparameteren '{regneparameter} kan ikke tolkes. "
                    "Skal være på formen 'parameter=værdi'."
                ),
                bold=True,
                bg="yellow",
            )
            continue

        # konverter til float hvis der er givet en talværdi
        try:
            værdi = float(værdi)
        except ValueError:
            pass

        motorkwargs[parameter] = værdi
    return motorkwargs

# The iteration is started if height_converted is not nan
if iterate == True and isnan(height_converted) == False:
while not (
-0.00001 <= (height_converted - approx_normal_height) <= 0.00001
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bør tolerancen kunne indstilles?

Comment on lines +769 to +776
for ny_kote in self.nye_koter:
punktnr = ny_kote.punkt

(ny_kote.nord, ny_kote.øst) = [
(gammel_kote.nord, gammel_kote.øst)
for gammel_kote in self.gamle_koter
if gammel_kote.punkt == punktnr
][0]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self._gamle_koter er allerede en dict, så du kan erstatte det her med:

for ny_kote in self.nye_koter:
    gammel_kote= self._gamle_koter[ny_kote.punkt]
    ny_kote.nord, ny_kote.øst = gammel_kote.nord, gammel_kote.øst

Men man kunne også bare antage at self.nye_koter allerede har værdierne for nord, øst som tages fra gamle_koter. Dette vil så skulle rettes i læs_gama_outputfil, se anden kommentar.

return list(self._gamle_koter.values())

@gamle_koter.setter
def gamle_koter(self, gamle_koter):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lidt forvirrende at input-parameteren hedder det samme som funktionen. Jeg ville ændre navnet til noget andet, og så tilføje typehint:

def gamle_koter(self, punktliste: list[NivKote])->dict[str,NivKote]:
   ...

return list(self._observationer.values())

@observationer.setter
def observationer(self, observationer):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lidt forvirrende at input-parameteren hedder det samme som funktionen. Jeg ville ændre navnet til noget andet, og så tilføje typehint:

def observationer(self, obsliste: list[NivObservation])->dict[str,NivObservation]:
   ...

Comment on lines +166 to +170
elif epoch_target is not None:
exit(
"Function apply_geodetic_corrections_to_height_diffs: Wrong arguments for\n\
parameter epoch_target and/or deformationmodel and/or grid_inputfolder."
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Er det nødvendigt at smide den her fejl? Vi ender kun hernede hvis fx epoch_target = 1990 og de andre to er None. Men hvis fx deformationmodel = PK_2016.tif og epoch_target=None, så fortsætter funktionen uden fejl.

Som jeg forstår det, så skal der kun laves uplift-korrektion hvis både epoch_target, deformationmodel og grid_inputfolder er givet. Hvis bare én af disse er None, så skal der ikke laves uplift-korrektion, og vi kan fortsætte til næste trin.

Suggested change
elif epoch_target is not None:
exit(
"Function apply_geodetic_corrections_to_height_diffs: Wrong arguments for\n\
parameter epoch_target and/or deformationmodel and/or grid_inputfolder."
)

Comment on lines +641 to +644
if not tidal_system:
self.tidal_system = None
else:
self.tidal_system = tidal_system
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Du kan forkorte alle de her udtryk via:

Suggested change
if not tidal_system:
self.tidal_system = None
else:
self.tidal_system = tidal_system
self.tidal_system = tidal_system or None

Comment on lines +654 to +669
if not output_height:
self.output_height = None
else:
self.output_height = output_height
if not deformationmodel:
self.deformationmodel = None
else:
self.deformationmodel = deformationmodel
if not gravitymodel:
self.gravitymodel = None
else:
self.gravitymodel = gravitymodel
if not grid_inputfolder:
self.grid_inputfolder = None
else:
self.grid_inputfolder = Path(grid_inputfolder)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Samme som ovenfor. Alle disse kan forkortes via self.x = x or None. Måske den med grid_inputfolder istedet skal skrives:
self.grid_inputfolder = Path(grid_inputfolder) if grid_inputfolder else None

Comment on lines +726 to +732
elif self.height_diff_unit == "metric":
pass

else:
raise ValideringFejl(
"Argumentet til parameteren height_diff_unit skal være enten 'metric' eller 'gpu'"
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Se også andre kommentarer om det samme. Generelt er det smart at tjekke for ugyldige inputs og evt. lade funktionen fejle først, sådan at man i resten af funktionen er sikker på at inputs er gyldige. Dette kan gøre det lidt lettere for uindviede at forstå hvordan funktionen fungerer, og man kan i mange tilfælde spare et indrykningsniveau, hvilket øger læsbarheden.

Fx;

if not self.height_diff_unit in ["gpu", "metric"]:
    raise ValideringFejl("Argumentet til parameteren height_diff_unit skal være enten 'metric' eller 'gpu'")

if not (
    self.tidal_system is not None
    or self.epoch_target is not None
    or self.height_diff_unit == "gpu"
):
    # Nothing to do...
    return

print("Højdeforskelle påføres geodætiske korrektioner inden udjævning")

(self.observationer, self.korrektioner_obs) = (
    apply_geodetic_corrections_to_height_diffs( ...
...

@@ -0,0 +1,38 @@
name: fire-dev-geod-lev
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vi skal ikke have dette miljø ind i repo'et. Meningen med at have et separat miljø fire-dev-geod-lev som dette var at det kan være lettere i udviklingsfasen af skifte imellem miljøer hvor man arbejder på forskellige tilføjelser til FIRE.
Men ift. denne pull request vil det være nok at tilføje de nye afhængigheder i environment-dev.yml og environment.yml filerne.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants