BYU-PRISM / GEKKO

GEKKO Python for Machine Learning and Dynamic Optimization
https://machinelearning.byu.edu
Other
593 stars 104 forks source link

GUI data loading with multiple models #34

Open loganbeal opened 6 years ago

loganbeal commented 6 years ago

It looks like when there are multiple models in one script, the GUI doesn't verify that the variables it's loading pertain to the associated model. For example, the GEKKO/tests/mpc_example.py fails on the rocket problem with KeyError: 'p1', but there isn't a p1 on the rocket problem. I think p1 comes from the CSTR problem solved earlier.

dhill2522 commented 6 years ago

I will get on that. Just a note, it is intended that the GUI be launced with m.solve(GUI=True) instead of m.GUI(). It may work both ways, but it is meant to be called from solve to handle updates properly.

I remember that we had the discussion before about whether we wanted to support multiple models in a file and nesting the variables and so forth, but I will look into this again.

dhill2522 commented 6 years ago

@loganbeal, I believe there is one way we may be able to get this working reliably and allow both naming patterns like m.myVar as well as myVar and support multiple models in one file. Let me explain and see what you think.

First, we rename all the internal Gekko variables to the same name with a preceding underscore (self.remote becomes self._remote). This will allow us to prevent name collisions and keep people from overwriting our internal variables and methods. For our API surface names (m.Var(), m.Equation()) we leave them without underscores, but add these into a check when the variable is assigned and return an error if someone tries to overwrite one of our API surface names. This could be done somewhat like how we were trying to get the APM var names to be the same as the script names, but it should work.

Second, we use the internal self._id of the model a variable is generated from to "label" that variable as being for the given model. For example, if a variable is declared myVar = m.Var() and the model m has a self._id of 3, then myVar._modelId = 3.

Finally, when the GUI checks the variables in the file it can filter them based on whether the _modelId property matches the model it is trying to collect data for.

This was kind of long and could be somewhat involved, but I think it could resolve several of our problems and leave us with a more stable framework. What do you think?

loganbeal commented 6 years ago

@dhill2522 Adding underscores is definitely a yes -- I should have done that a long time ago.

Regarding the model id, each model keeps a list of variable instances attributed to that model. We could use that if we didn't want to add an id attribute to every variable.

dhill2522 commented 6 years ago

Prefixing with underscores should be complete as of commit ae64ffdc

All e2e tests are passing, but hopefully there is no hidden problem our tests did not catch.

dhill2522 commented 5 years ago

@loganbeal Sorry I have been unavailable for some time. Do we know if this is still a problem?

dhill2522 commented 5 years ago

I found another place where our variable handling for the GUI fails. If someone creates a list of gekko variables or variables scoped within a method or class, none of these are noticed and caught by the GUI itself because they are not in the root level of the __main__ namespace.

I am going to try and play around on a new branch to see what if I can find a more robust way of getting the variables from the main process. It sounds like there is some interest in separating the GUI code out into a separate repository to minimize dependencies, so I will see if the potential solution would allow the GUI to separated out as well.