-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make sequencer constraint #378
Conversation
*make the Sequencer class *veto=True if current_obs is in obs_list *might want a better string to be returned
*return veto and score (does not need to be changed)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too easy. This is a much better approach than a different scheduler.
This looks good but we'll want to add some tests in a testing file that will ensure this is working. Take a look in pocs/tests/test_constraints.py
and you can just add directly to that file.
To run just that test you can do "pytest -xv pocs/tests/test_constraints.py" at the command line.
pocs/scheduler/constraint.py
Outdated
@@ -159,3 +159,23 @@ def get_score(self, time, observer, observation, **kwargs): | |||
|
|||
def __str__(self): | |||
return "Moon Avoidance" | |||
|
|||
class Seqencer(BaseConstraint): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seqencer -> Sequencer
But let's maybe name that AlreadyVisited
just to be really obvious. Sequencer seems to apply to more than one targets whereas a constraint technically only applies to one target at a time.
pocs/scheduler/constraint.py
Outdated
return veto, score * self.weight | ||
|
||
def __str__(self): | ||
return "Don't repeat observations" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How this gets used it's better to actually just have something like "AlreadyVisited". An example of how it shows up is with the word Altitude
here:
I0116 12:30:21.285 dispatch.py:56 Checking Constraint: Altitude
D0116 12:30:21.285 dispatch.py:59 Observation: Kepler 1100
*change name of method *change string returned by method
*small change to constraint *template of test **makes observed list **checks two different obs, one in list one not
pocs/scheduler/constraint.py
Outdated
@@ -170,10 +170,10 @@ def get_score(self, time, observer, observation, **kwargs): | |||
score = self._score | |||
|
|||
target = observation.field | |||
observed = observation.observed_list | |||
observed_list = kwargs['observed_list'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For normal operations you'll still want to pull from observation.observed_list
as that's how the scheduler builds it up. So do akwargs.get('observed_list', observation.observed_list)
here.
observed_list[observation1.seq_time] = observation1 | ||
observed_list[observation2.seq_time] = observation2 | ||
|
||
veto1, score1 = avc.get_score(time, observer, observation1, observed_list=observed_list) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative to passing the observed_list
and using the kwargs as above is to just alter the observer.observed_list
here.
The |
Haven't been able to test it yet... Windows problems. |
You can check the travis build here on the PR. You have some spacing/indent issues it is saying. |
OK, cool. I will just use that to check issues. |
*consistent formatting *add import OrderedDict to test_constraints.py
pocs/scheduler/constraint.py
Outdated
if target in observed_list: | ||
veto = True | ||
for seq_time, Observation in observed_list: | ||
if target = observation: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are assigning (=
) here instead of comparing (==
). Which might not show an error.
pocs/scheduler/constraint.py
Outdated
observed_list = kwargs.get('observed_list', observer.observed_list) | ||
|
||
if target in observed_list: | ||
veto = True | ||
for seq_time, Observation in observed_list: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Observation
-> previous_obs
You already have an observation
object above so can't just use observation
(no capital letters).
*add .items() at the end of observed_list
OK, so I know what it going on now with the
The previous entries are over written by a recent entry. I will try to just assign it as a normal dictionary but I can't see why he ordered dictionary is behaving in such a way. |
Not sure I understand what you mean. But the |
Ah, I see. The
then put it in the OrderedDict |
Ahh, of course! |
*set seq_time for all observations
Codecov Report
@@ Coverage Diff @@
## develop #378 +/- ##
===========================================
- Coverage 69.08% 69.05% -0.04%
===========================================
Files 60 60
Lines 4723 4757 +34
Branches 652 656 +4
===========================================
+ Hits 3263 3285 +22
- Misses 1289 1297 +8
- Partials 171 175 +4
Continue to review full report at Codecov.
|
Now we just need to implement this and we are good to merge! |
pocs/scheduler/constraint.py
Outdated
|
||
observed_list = kwargs.get('observed_list', observer.observed_list) | ||
|
||
for seq_time, previous_obs in observed_list.items(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, now that the OrderedDict is sorted out I think you can switch this back to if observation.seq_time in observed_list
and avoid the loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, didn't like the idea of the loop but I remembered that seq_time
will be different for each `observation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good. One last request: can you now update the Scheduler Playground notebook and add this constraint in cell 4? Then just run the rest of the notebook the same. Down in the Entire Night Simulation it currently selects Wasp-35 twice (once before the meridian and once after) and this update should change that.
Note that the order you add the constraints matters and you want this one first. That is, you want this constraint to veto something initially so that it will not even be considered by the other constraints.
Thank you! No problem, will do that soon. Good that we have Wasp-35 twice so we can make sure that it works properly in the Scheduler Playground. Of course, makes sense to make sure we aren't checking conditions that we won't be using. |
*include `AlreadyVisited` constraint *import from constraint *add to `constrains` array
@jermainegug Can you run all the cells in the notebook and then save and commit it? I want to be able to see the output in the bottom of the notebook where it vetoes targets because of constraint. |
pocs/scheduler/constraint.py
Outdated
veto = False | ||
score = self._score | ||
|
||
observed_list = kwargs.get('observed_list', observer.observed_list) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I told you wrong here. observed_list
belongs to the scheduler
, not to the observer
(the observer
also belongs to the scheduler
). You can remove the observer.observed_list
here and just fetch from kwargs
. Then in the dispatch.py
scheduler you can pass the observed_list
in as a common_properties
(here):
common_properties = {
'end_of_night': self.observer.tonight(time=time, horizon=-18 * u.degree)[-1],
'moon': get_moon(time, self.observer.location),
'observed_list': self.observed_list
}
The common_properties
get passed into as kwargs
down below that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this means we should add a test. You have added tests to successfully cover just the constraint, now we should add something in test_dispatch_scheduler.py
that uses it as part of a normal scheduling routine.
*take observer.observed_list out constraint *add observed_list to common_properties *just define observed_list in test (?)
How can I make the |
pocs/tests/test_constraints.py
Outdated
observed_list[observation1.seq_time] = observation1 | ||
observed_list[observation2.seq_time] = observation2 | ||
|
||
veto1, score1 = avc.get_score(time, observer, observation1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In dispatch.py
you can see how common properties is passed to get_score
by using the **common_properties
syntax, which passes individual keys of the dictionary to the method (as opposed to passing the dictionary itself).
So in your get_score
here you just need to pass the observed_list
with a keyword, so observed_list=observed_list
. Then the generic kwargs
in the get_score you wrote will have it available as kwargs.get('observed_list')
. This is one of the points of using **kwargs
as a parameter, it can pick up keyword arguments that are not otherwise explicitly stated. We have a get_score
in all of the constraints and not all the keywords apply to all the constraint types so this is how you design for something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, interesting. I wasn't too sure how **kwargs
worked but that makes plenty of sense. Thanks!
*take out observed_list=observed_list from get_score *was put into the wrong get_score
pocs/scheduler/constraint.py
Outdated
|
||
observed_list = kwargs.get('observed_list') | ||
|
||
if observation.seq_time in observed_list: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had told you wrong (again). By definition the seq_time
is going to be unique for each observation even if they are for the same field. What we want to check is the field, via
observed_field_list = [obs.field for obs in observed_list.values()]
if observation.field in observed_field_list:
I tested that out in the notebook copied from all your latest code and it finally outputs something like I would expect. It still dwells on one field but does not reselect a field after it has deselected it.
New PR for issue AstroHuntsman#5. This replaces #374.
Note: this is not to be merged yet! Much more work is to be done.