Skip to content
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

bright sky exposure factor #68

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions py/surveysim/exposures.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class ExposureList(object):
The maximum expected number of exposures, which determines the
memory size of this object.
"""
def __init__(self, restore=None, max_nexp=60000):
self.tiles = desisurvey.tiles.get_tiles()
def __init__(self, restore=None, max_nexp=60000, bgs_footprint=None):
self.tiles = desisurvey.tiles.get_tiles(bgs_footprint=bgs_footprint)
self._exposures = np.empty(max_nexp, dtype=[
('MJD', np.float64),
('EXPTIME', np.float32),
Expand All @@ -38,6 +38,11 @@ def __init__(self, restore=None, max_nexp=60000):
('SEEING', np.float32),
('TRANSP', np.float32),
('SKY', np.float32),
('MOON_ILL', np.float32),
('MOON_SEP', np.float32),
('MOON_ALT', np.float32),
('SUN_SEP', np.float32),
('SUN_ALT', np.float32)
])
self._tiledata = np.empty(self.tiles.ntiles, dtype=[
('AVAIL', np.int32),
Expand Down Expand Up @@ -93,7 +98,8 @@ def update_tiles(self, night, available, planned):
self._tiledata['AVAIL'][available] = night_index
self._tiledata['PLANNED'][planned] = night_index

def add(self, mjd, exptime, tileID, snr2frac, airmass, seeing, transp, sky):
def add(self, mjd, exptime, tileID, snr2frac, airmass, seeing, transp, sky,
moonill, moonsep, moonalt, sunsep, sunalt):
"""Record metadata for a single exposure.

Parameters
Expand All @@ -117,7 +123,8 @@ def add(self, mjd, exptime, tileID, snr2frac, airmass, seeing, transp, sky):
raise RuntimeError(
'Need to increase max_nexp={}'.format(len(self._exposures)))
self._exposures[self.nexp] = (
mjd, exptime, tileID, snr2frac, airmass, seeing, transp, sky)
mjd, exptime, tileID, snr2frac, airmass, seeing, transp, sky,
moonill, moonsep, moonalt, sunsep, sunalt)
self.nexp += 1
tileinfo = self._tiledata[self.tiles.index(tileID)]
tileinfo['EXPTIME'] += exptime
Expand Down
22 changes: 17 additions & 5 deletions py/surveysim/nightops.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

def simulate_night(night, scheduler, stats, explist, weather,
use_twilight=False, update_interval=10.,
plot=False, verbose=False):
use_brightsky=False, plot=False, verbose=False):
"""Simulate one night of observing.

Uses the online tile scheduler and exposure time calculator.
Expand All @@ -34,6 +34,9 @@ def simulate_night(night, scheduler, stats, explist, weather,
Observe during twilight when True.
update_interval : float
Interval in seconds for simulated ETC updates.
use_brightsky : bool
If True use improved bright sky model in exposure time calculations
(ETC.start and ETC.update calls)
plot : bool
Generate a plot summarizing the simulated night when True.
verbose : bool
Expand Down Expand Up @@ -131,7 +134,8 @@ def get_weather(mjd):
seeing_now, transp_now = get_weather(mjd_now)
# Get the next tile to observe from the scheduler.
tileid, passnum, snr2frac_start, exposure_factor, airmass, sched_program, mjd_program_end = \
scheduler.next_tile(mjd_now, ETC, seeing_now, transp_now, sky_now)
scheduler.next_tile(mjd_now, ETC, seeing_now, transp_now, sky_now,
use_brightsky=use_brightsky)
if tileid is None:
# Deadtime while we delay and try again.
mjd_now += NO_TILE_AVAIL_DELAY
Expand Down Expand Up @@ -165,7 +169,10 @@ def get_weather(mjd):
# -- NEXT EXPOSURE ---------------------------------------------------
# Get the current observing conditions.
seeing_now, transp_now = get_weather(mjd_now)
sky_now = 1.
if use_brightsky and tile_program == 'BRIGHT':
sky_now = exposure_factor
else:
sky_now = 1.
# Use the ETC to control the shutter.
mjd_open_shutter = mjd_now
ETC.start(mjd_now, tileid, tile_program, snr2frac_start, exposure_factor,
Expand All @@ -186,7 +193,11 @@ def get_weather(mjd):
continue_this_tile = False
# Get the current observing conditions.
seeing_now, transp_now = get_weather(mjd_now)
sky_now = 1.
if use_brightsky and tile_program == 'BRIGHT':
sky_now, moon_ill, moon_sep, moon_alt, sun_sep, sun_alt = scheduler.update_exposure_factor(mjd_now, tileid, return_obs_cond=True)
else:
moon_ill, moon_sep, moon_alt, sun_sep, sun_alt = scheduler.get_observing_conditions(mjd_now, tileid)
sky_now = 1
# Update the SNR.
if not ETC.update(mjd_now, seeing_now, transp_now, sky_now):
# Current exposure reached its target SNR according to the ETC.
Expand All @@ -202,7 +213,8 @@ def get_weather(mjd):
nightstats['nexp'][passnum] += 1
explist.add(
mjd_now - ETC.exptime, 86400 * ETC.exptime, tileid, ETC.snr2frac,
airmass, seeing_now, transp_now, sky_now)
airmass, seeing_now, transp_now, sky_now, moon_ill,
moon_sep, moon_alt, sun_sep, sun_alt)
scheduler.update_snr(tileid, ETC.snr2frac)

if continue_this_tile:
Expand Down
27 changes: 23 additions & 4 deletions py/surveysim/scripts/surveysim.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ def parse(options=None):
parser.add_argument(
'--config-file', default='config.yaml', metavar='CONFIG',
help='input configuration file')
parser.add_argument('--brightsky', action='store_true',
help='use improved bright sky model (slower)')
parser.add_argument( '--bgs_footprint', type=str, default=None,
help='reduce bgs footprint')

if options is None:
args = parser.parse_args()
Expand Down Expand Up @@ -125,20 +129,34 @@ def main(args):
if args.tiles_file is not None:
config.tiles_file.set_value(args.tiles_file)

if args.bgs_footprint is not None:
bgs_footprint = float(args.bgs_footprint)
else:
bgs_footprint = None


# Initialize simulation progress tracking.
stats = surveysim.stats.SurveyStatistics(args.start, args.stop)
explist = surveysim.exposures.ExposureList()
print('Initialize simulation progress tracking.')
stats = surveysim.stats.SurveyStatistics(args.start, args.stop,
bgs_footprint=bgs_footprint)
print('Exposure list.')
explist = surveysim.exposures.ExposureList(
bgs_footprint=bgs_footprint)

# Initialize the survey strategy rules.
print('Initialize the survey strategy rules.')
rules = desisurvey.rules.Rules(args.rules)

# Initialize afternoon planning.
print('Initialize afternoon planning.')
planner = desisurvey.plan.Planner(rules)

# Initialize next tile selection.
scheduler = desisurvey.scheduler.Scheduler()
print('Initialize next tile selection.')
scheduler = desisurvey.scheduler.Scheduler(bgs_footprint=bgs_footprint)

# Generate random weather conditions.
print('Generate random weather conditions.')
weather = surveysim.weather.Weather(seed=args.seed, replay=args.replay)

# Loop over nights.
Expand All @@ -159,7 +177,8 @@ def main(args):
if not desisurvey.utils.is_monsoon(night) and not scheduler.ephem.is_full_moon(night):
# Simulate one night of observing.
surveysim.nightops.simulate_night(
night, scheduler, stats, explist, weather=weather, use_twilight=args.twilight)
night, scheduler, stats, explist, weather=weather,
use_twilight=args.twilight, use_brightsky=args.brightsky)
if scheduler.survey_completed():
log.info('Survey complete on {}.'.format(night))
break
Expand Down
8 changes: 6 additions & 2 deletions py/surveysim/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,12 @@ class SurveyStatistics(object):
the configured output path unless an absolute path is
provided.
"""
def __init__(self, start_date=None, stop_date=None, restore=None):
self.tiles = desisurvey.tiles.Tiles()
def __init__(self, start_date=None, stop_date=None, restore=None,
tiles_file=None, bgs_footprint=None):
if tiles_file is None:
self.tiles = desisurvey.tiles.Tiles(bgs_footprint=bgs_footprint)
else:
self.tiles = desisurvey.tiles.Tiles(tiles_file=tiles_file, bgs_footprint=bgs_footprint)
config = desisurvey.config.Configuration()
if start_date is None:
self.start_date = config.first_day()
Expand Down