femiguez / apsimx

R package for APSIM-X
https://femiguez.github.io/apsimx-docs/
51 stars 20 forks source link

We need to go deeper - inspect_apsimx cannot access sowing date #166

Open LenLon opened 1 month ago

LenLon commented 1 month ago

I currently am trying to edit the sowing date in my simulation using edit_apsimx. Unfortunately, it seems that edit_apsimx or rather inspect_apsimx are not able to dig "deep" enough in the .apsimx JSON file to get the attribute I want..

What I want to edit:

image

Code I tried:


# Using JSON queries for the parm argument
>     inspect_apsimx(file = paste0(name_sim, ".apsimx"),
+                    src.dir = in_path_sim, 
+                    node = "Other",
+                    parm = "$.Simulations.Simulation.Field")
Simulation Field Names level 3:[1] "SoilType =  loam"                   "Fertiliser"                        
[3] "SurfaceOrganicMatter"               "C4Maize"                           
[5] "CropStatus"                         "Reset on date"                     
[7] "Sow using a variable rule_extended" "Harvest"                           
[9] "Report"

# See the manager scripts, but can't access them individually :(
>     inspect_apsimx(file = paste0(name_sim, ".apsimx"),
+                    src.dir = in_path_sim, 
+                    node = "Other",
+                    parm = "$.Simulations.Simulation.Field.Sow using a variable rule_extended")
Error: Not implemented yet

# Using integer lists for parm: getting closer
>     inspect_apsimx(file = paste0(name_sim, ".apsimx"),, 
+                    src.dir = in_path_sim, 
+                    node = "Other",
+                    parm = list(1,2,6,7,3),
+                    print.path = T)
Parm path: .Simulations.Simulation.Field.Sow using a variable rule_extended.Parameters 

# But cannot access the parameters in the manager scripts
>     inspect_apsimx(file = paste0(name_sim, ".apsimx"),
+                    src.dir = in_path_sim, 
+                    node = "Other",
+                    parm = list(1,2,6,7,3,2),
+                    print.path = T)
Error in inspect_apsimx(file = paste0(name_sim, ".apsimx"), src.dir = in_path_sim,  : 
  object 'wlevel4' not found

# Hail mary: using jsonlite to try and edit the .apsimx file itself
# This does not throw any errors, but APSIMX itself gives you one when you try to open the edited file
>     apsimx_json <- jsonlite::read_json(paste0(in_path_sim, "\\", name_sim, ".apsimx"))
>     apsimx_json$Children[[2]]$Children[[6]]$Children[[7]]$Parameters[[2]]$Value <- sow_date
>     apsimx_json_mod <- jsonlite::toJSON(apsimx_json)
>     write(apsimx_json_mod, paste0(in_path_sim, "\\", name_sim, ".apsimx"))

Should I try to add just one more level in the inspect_apsimx source code, is there another way, am I doing something stupid altogether? Thank you for the great package, I am learning a lot currently :)

LenLon commented 1 month ago

Addendum:

I managed to get around it by trying to use the "Manager" node instead :)

>     inspect_apsimx(file = paste0(name_sim, ".apsimx"),
+                    src.dir = in_path_sim, 
+                    node = "Manager",
+                    parm = list("Sow using a variable rule_extended", NA))
Management Scripts:  CropStatus Reset on date Sow using a variable rule_extended Harvest 

Name:  Sow using a variable rule_extended 

|parm         |value     |
|:------------|:---------|
|Crop         |[C4Maize] |
|StartDate    |01-may    |
|EndDate      |15-jul    |
|MinESW       |30        |
|MinRain      |20        |
|RainDays     |5         |
|CultivarName |hybred511 |
|SowingDepth  |60        |
|RowSpacing   |900       |
|Population   |2         |
|MustSow      |True      |
|SowYear      |2000      |

>     inspect_apsimx(file = paste0(name_sim, ".apsimx"),
+                    src.dir = in_path_sim, 
+                    node = "Manager",
+                    parm = list("Sow using a variable rule_extended", 2))
Management Scripts:  CropStatus Reset on date Sow using a variable rule_extended Harvest 

Name:  Sow using a variable rule_extended 
Key: StartDate 

|parm      |value  |
|:---------|:------|
|StartDate |01-may |
femiguez commented 1 month ago

@LenLon Thanks for the report. The feature using node = "Other" is probably a bit unintuitive. I changed this behavior so that you can see the simulations components easily. This is a way of finding the 'root'. I'll create and post an example here.

Ok. I'm labeling this as a bug. The method using node = "Manager" is your best option here.

LenLon commented 1 month ago

So "Other" is a catch-all node that shows the path to the parameter in the JSON simulation tree? Curious to see your example :)

femiguez commented 1 month ago

@LenLon This is still not perfect. I made a minor change that will make this error go away, but it will return nothing if it can't find it, which is not ideal. The problem with .apsimx files is that although they generally follow a predictable json pattern, sometimes they deviate from it, which makes it hard to write code that always works. In the case of Manager, the 'node = "Other"' method will not work unless I make substantial changes.

Initially, for 'inspect_apsimx', node = 'Other' was almost useless. It was the counterpart of "node = 'Other'" in 'edit_apsimx', but you had to know the path already and the goal of 'inspect_apsimx' is not just to 'see' simulations, but to find the path and then edit them. The first change I made to 'node = 'Other'' in 'inspect' was to have the parameter be '0', '1', '2' or '3'. This simply prints the levels of a tree which is useful to find the different simulations in an APSIM file. This is the 'root' that might be needed for the 'edit_apsimx' function. I also have some functionality when node = "Other" and parm is a "character" or a "list". You started using the 'list' method with numbers, which is currently a relatively lazy way of finding some parameter paths. It is not fool-proof but it works some of the time. I will continue to improve them as I can.

If you want to see more examples, there are some in the file 'test_inspect.R' starting at line 480.

I greatly appreciate your interest in the package and the feedback.