Skip to content

fix: use original Vensim names in generated headers for spec output vars#462

Merged
chrispcampbell merged 10 commits into
mainfrom
todd/461-validation-subs
Apr 22, 2024
Merged

fix: use original Vensim names in generated headers for spec output vars#462
chrispcampbell merged 10 commits into
mainfrom
todd/461-validation-subs

Conversation

@ToddFincannonEI
Copy link
Copy Markdown
Collaborator

@ToddFincannonEI ToddFincannonEI commented Apr 18, 2024

Fixes #461

See issue #461 for details.


const char* getHeader() {
return "${R.map(varName => headerTitle(varName), headerVars).join('\\t')}";
return "${headerVars.join('\\t')}";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@ToddFincannonEI: It looks like the build is failing due to a test failure when running the "allocate" model, but probably others are affected as well:
https://github.com/climateinteractive/SDEverywhere/actions/runs/8741036880/job/23986139008

The error points back to this line, which will fail if headerVars is undefined.

The issue is that there are two ways to specify output variables in the spec.json, you can either use outputVars (which takes C names) or outputVarNames (which takes Vensim names). In the case of outputVarNames, we convert to outputVars in this code in Model.read so that the rest of the code only needs to deal with outputVars (sort of a lowest common denominator):

  if (spec) {
    // If the spec file contains `input/outputVarNames` (with full Vensim variable names)
    // convert those to C names first.  Otherwise, use `input/outputNames` which are already
    // assumed to be valid C names.
    if (spec.inputVarNames) {
      spec.inputVars = R.map(cName, spec.inputVarNames)
    }
    if (spec.outputVarNames) {
      spec.outputVars = R.map(cName, spec.outputVarNames)
    }
    // Save the input vars locally so that they can be referenced by `isInputVar`.
    if (spec.inputVars) {
      inputVars = spec.inputVars
    }
  }

There are only 3 sample models that use the older outputVars form (allocate, arrays_cname, longeqns).

There are a few different ways we could solve this. I don't think it's imperative that we retain support for outputVars. For En-ROADS/C-ROADS we use the newer outputVarNames and all the new build stuff in SDE also uses that form, so I doubt anyone out in the wild is relying on outputVars. I think if we changed those 3 tests to use outputVarNames and effectively drop support for outputVars, then your proposed fix will be nearly correct (though I'd need to look through the rest of the code to see if any other changes are needed).

Let me know which approach you'd like to take.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Sorry I forgot to run the tests before submitting. EPS uses outputVarNames too, so your proposed solution looks good to me. I will change the tests and resubmit.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It looks like the only purpose of the arrays_cname test model is to test the outputVars C name support in spec files. I propose deleting this model, since we are dropping support for outputVars.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@ToddFincannonEI: I agree with deleting arrays_cname, and also suggest renaming arrays_varname back to just arrays, but I'd be OK handling that myself in a separate PR after this one.

@ToddFincannonEI
Copy link
Copy Markdown
Collaborator Author

@chrispcampbell I made the changes to the test models we discussed and found one other bug in the process. It's ready for you to review again.

Copy link
Copy Markdown
Collaborator Author

@ToddFincannonEI ToddFincannonEI left a comment

Choose a reason for hiding this comment

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

Thanks for finding all the other references to outputVars and clarifying the other references to outputVarNames. Much improved!

Copy link
Copy Markdown
Contributor

@chrispcampbell chrispcampbell left a comment

Choose a reason for hiding this comment

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

@ToddFincannonEI: Looks good, thanks, Todd. I made a couple small tweaks to comments/docs which I noted in inline comments, the rest looked good so I will merge now.

} else {
outputAllVars = true
}
let outputAllVars = spec.outputVarNames === undefined || spec.outputVarNames.length === 0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I simplified this logic now that the user can only provide outputVarNames and outputVars is only used internally.

let headerVars = outputAllVars ? expandedVarNames(true) : spec.outputVars
let outputVars = outputAllVars ? expandedVarNames() : spec.outputVars
let headerVarNames = outputAllVars ? expandedVarNames(true) : spec.outputVarNames
let outputVarIds = outputAllVars ? expandedVarNames() : spec.outputVars
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I renamed these two variables to emphasize the difference, but otherwise it's the same as you had it.

// convert those to C names first. Otherwise, use `input/outputNames` which are already
// assumed to be valid C names.
// If the spec file contains `input/outputVarNames`, convert the full Vensim variable
// names to C names first so that later phases only need to work with canonical names
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I updated this comment to make it match the new reality better (also input/outputNames had the wrong property names anyway).

Comment thread packages/cli/README.md
"inputVars": ["Reference predators", "Reference prey"],
"outputVars": ["Time", "Predators Y", "Prey X"]
"inputVarNames": ["Reference predators", "Reference prey"],
"outputVarNames": ["Time", "Predators Y", "Prey X"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I updated the README (which I guess had been incorrect for a while) so that it only shows using input/outputVarNames.

@chrispcampbell chrispcampbell merged commit 966066a into main Apr 22, 2024
@chrispcampbell chrispcampbell deleted the todd/461-validation-subs branch April 22, 2024 17:55
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.

sde compare fails to detect output errors

2 participants