Prenight Simulations#
Generating new pre-night simulations and adding them to the archive#
Introduction#
Prenight simulation tools generate simulations of a few nights of observing, and add them to an archive.
These simulations can then be seen by schedview’s reporting tools, and used to generate pre-night brifing reports.
Normally, these simulation are run by submitting the batch/run_prenight_sims.sh script in the lsst_survey_sim repository as a batch job, either by hand or using a cron job.
For more fine-grained control, the simulations and be run and added to the archive using lower-level tools,
Running a standard set of pre-night simulations#
The standard set of pre-night simulations can be run by calling the batch/run_prenight_sims.sh shell (for SV) or batch/run_auxtel_prenight_sims.sh (for auxtel) scripts.
These scripts are “protected” by gate files: for user ${USER} to run batch/run_prenight_sims.sh, the file /sdf/data/rubin/shared/scheduler/cron_gates/run_prenight_sims/${USER} must exist,
and for that user to run batch/run_auxtel_prenight_sims.sh, the file /sdf/data/rubin/shared/scheduler/cron_gates/run_auxtel_prenight_sims/${USER} must exist.
(This was done so that any user with write access to /sdf/data/rubin/shared/scheduler/cron_gates/${SCRIPT} can stop a cron job that runs the corresponding script from doing anything, even if that cron job is not owned by that user.)
If LSST_SURVEY_SIM_DIR is the lsst_survey_sim root directory, it can be called thus:
${LSST_SURVEY_SIM_DIR}/batch/run_prenight_sims.sh
or thus:
${LSST_SURVEY_SIM_DIR}/batch/run_auxtel_prenight_sims.sh auxtel
or they can be submitted as a batch job to slurm.
At the USDF, there is an installation of lsst_survey_sim at /sdf/data/rubin/shared/scheduler/packages/lsst_survey_sim such that the commands become:
/sdf/data/rubin/shared/scheduler/packages/lsst_survey_sim/batch/run_auxtel_prenight_sims.sh
/sdf/data/rubin/shared/scheduler/packages/lsst_survey_sim/batch/run_prenight_sims.sh
These scripts build python environments in the USDF scratch disks of the user running the script, in directories of the form:
/sdf/scratch/users/${USER:0:1}/${USER}/prenight_venvs/prenight-YYYY-MM-DDTHHMMSS-XXXXXX
Where ${USER:0:1} is the first letter of a username, and the XXXXXX is replaced by random characters.
For example, a recent environment created was: /sdf/scratch/users/n/neilsen/prenight_venvs/prenight-2025-12-16T141515-gCnXfu.
These batch jobs will record their logs (stderr and stdout) in:
/sdf/data/rubin/shared/scheduler/prenight/sbatch/run_prenight_sims_%A_%a.outand/sdf/data/rubin/shared/scheduler/prenight/sbatch/run_prenight_sims_%A_%a.err
The working files can be found in /sdf/data/rubin/shared/scheduler/prenight/work/run_prenight_sims/%Y-%m-%dT%H%M%.
Automated runs of prenight simulations#
Batch jobs are submitted automatically each morning following the sbatch commands shown above.
The crontab entries are:
15 6 * * * /opt/slurm/slurm-curr/bin/sbatch /sdf/data/rubin/shared/scheduler/packages/lsst_survey_sim/batch/run_auxtel_prenight_sims.sh 2>&1 >> /sdf/data/rubin/shared/scheduler/prenight/daily/daily_auxtel_cr on.out
55 6 * * * /opt/slurm/slurm-curr/bin/sbatch /sdf/data/rubin/shared/scheduler/packages/lsst_survey_sim/batch/run_prenight_sims.sh 2>&1 >> /sdf/data/rubin/shared/scheduler/prenight/daily/daily_simonyi_cron.out
If necessary, these cron jobs can be stopped from doing anything, even a user that does not own the cron job, if they have write access to /sdf/data/rubin/shared/scheduler/cron_gates/${SCRIPT}.
This is accomplished using gate files: early in each script, the script checks for the existence of a file with name /sdf/data/rubin/shared/scheduler/cron_gates/${SCRIPT_NAME}/${USER} and aborts if it does not exist.
Any user with write access to /sdf/data/rubin/shared/scheduler/cron_gates/${SCRIPT_NAME} can create or remove files in that directory, so a user can cause these scripts to immediately abort
when started by a cron job owned by a different user by removing /sdf/data/rubin/shared/scheduler/cron_gates/${SCRIPT_NAME}/${CRON_JOB_USER}.
So, to stop the run_prenight_sims.sh cron job owned by user neilsen, remove the file /sdf/data/rubin/shared/scheduler/cron_gates/run_prenight_sims/neilsen,
and to stop the run_auxtel_prenight_sims.sh cron job owned by user neilsen, remove the file /sdf/data/rubin/shared/scheduler/cron_gates/run_auxtel_prenight_sims/neilsen,
The logs of the cron jobs (and any other executions of these scripts submitted using sbatch) can be found in /sdf/data/rubin/shared/scheduler/prenight/sbatch/run_prenight_sims_%A_%a.out,
where %A is the slurm “Job array’s master job allocation number” and %a is the slum “Job array ID (index) number”.
Updating the versions of the scripts#
The batch jobs run versions of lsst_survey_sim/batch/run_prenight_sims.sh and lsst_survey_sim/run_auxtel_prenight_sims.sh installed in /sdf/data/rubin/shared/scheduler/packages.
Versions of lsst_survey_sim installed in /sdf/data/rubin/shared/scheduler/packages can be updated as follows.
First, if one does not exist already, tag lsst_survey_sim at the commit you want.
To find the next available tag:
curl -s https://api.github.com/repos/lsst-sims/lsst_survey_sims/tags \
| jq -r '.[].name' \
| egrep '^v[0-9]+.[0-9]+.[0-9]+.*$' \
| sort -V
Make and push a new tag (with the base of the repository at the commit you want as the current working directory):
NEWVERSION="0.1.0.dev2"
NEWTAG=v${NEWVERSION}
echo "New version is ${NEWVERSION} with tag ${NEWTAG}"
echo ""
git tag ${NEWTAG}
git push origin tag ${NEWTAG}
Then install it in /sdf/data/rubin/shared/scheduler/packages:
PACKAGEDIR="/sdf/data/rubin/shared/scheduler/packages"
TARGETDIR="${PACKAGEDIR}/lsst_survey_sim-${NEWVERSION}"
PIPORIGIN="git+https://github.com/lsst-sims/lsst_survey_sim.git@${NEWTAG}"
echo "Installing from ${PIPORIGIN} to ${TARGETDIR}"
echo ""
pip install \
--no-deps \
--target=${TARGETDIR} \
${PIPORIGIN}
If you want to make it the default version, replace the link:
if test -L ${PACKAGEDIR}/lsst_survey_sim ; then
rm ${PACKAGEDIR}/lsst_survey_sim
fi
ln -s ${TARGETDIR} ${PACKAGEDIR}/lsst_survey_sim
Custom runs of prenight simulations#
Preparation of the environment#
Much of the run_prenight_sims.sh script is dedicated to figuring out what environment to use and configuring it.
If these defaults are not desired, a user can configure an environment to their liking, and run the simulation with the following steps.
The dependencies of lsst_survey_sim provide most of what the preniight simulations require to run.
The additional dependencies beyond what lsst_survey_sim requires are:
clickpsycopg2botocoreboto3lsst-resources
You will also need to configure environment variables for access to the prenight S3 bucket and metadata database:
export VSARCHIVE_PGDATABASE="opsim_log"
export VSARCHIVE_PGHOST="usdf-maf-visit-seq-archive-tx.sdf.slac.stanford.edu"
export VSARCHIVE_PGUSER="writer"
export VSARCHIVE_PGSCHEMA="vsmd"
Get completed visits#
First, retrieve the set of completed visits at the start of the nights to be simulated. For example:
DAYOBS="$(date -u --date='-12 hours' +'%Y%m%d')"
TOKEN_FILE="~/.lsst/usdf_access_token"
fetch_lsst_visits ${DAYOBS} completed_visits.db ${TOKEN_FILE}
You can register this visit list in the prenight simulation metadata database:
PREVIOUS_NIGHT_ISO="$(date --date='-36 hours' -u +'%F')"
COMPLETED=$(vseqarchive record-visitseq-metadata \
completed \
completed_visits.db \
"Consdb query through ${PREVIOUS_NIGHT_ISO}" \
--first_day_obs 20250620 \
--last_day_obs ${PREVIOUS_NIGHT_ISO})
The vseqarchive record-visitseq-metadata command creates a row in the completed table in the visit sequence archive metadata database,
automatically assigning it a UUID and recording a checksum of the table of visits and the label and date range provided as arguments in the above command.
It does not save the visits themselves in the S3 bucket:
it only records the checksum of the set of visits in the metadata database and assigns the set a UUID.
Above, this automatically generated UUID is saved in the COMPLETED environment variable.
Note that the fetch_lsst_visits command required the dayobs of the night you are about to simulate in YYYYMMDD format,
while the vseqarchive record-visitseq-metadata command takes the dayobs of the last night in the completed visits
(probably the night before the one used in fetch_lsst_visits) in either YYYYMMDD or YYYY-MM-DD format.
Create pickles of the objects you need to run the simulation#
If you do not already have a pickle, begin by getting the configuration you want from ts_config_scheduler:
TS_CONFIG_SCHEDULER_REFERENCE="develop"
SCHED_CONFIG_FNAME="ts_config_scheduler/Scheduler/feature_scheduler/maintel/fbs_config_lsst_survey.py"
git clone --depth 1 https://github.com/lsst-ts/ts_config_scheduler
cd ts_config_scheduler
git fetch --depth 1 origin "${TS_CONFIG_SCHEDULER_REFERENCE}"
git checkout FETCH_HEAD
Create a pickle of the scheduler you want to run:
make_lsst_scheduler scheduler.p --opsim completed_visits.db --config_script ${SCHED_CONFIG_FNAME}
Create a model observatory pickle:
make_model_observatory observatory.p
Run the simulation#
Set a directory in which to save the results of the simulations:
OPSIM_RESULTS_DIR=/my/results/directory
mkdir ${OPSIM_RESULTS_DIR}
Finally, run the sim (and add it to the archive):
OPSIMRUN="prenight_nominal_$(date --iso=s)"
NUM_NIGHTS="3"
LABEL="Nominal start and overhead, ideal conditions, run at $(date --iso=s)"
run_lsst_sim scheduler.p observatory.p "" ${DAYOBS} ${NUM_NIGHTS} "${OPSIMRUN}" \
--keep_rewards --label "${LABEL}" \
--delay 0 --anom_overhead_scale 0 \
--results ${OPSIM_RESULT_DIR}
Add the simulation to the S3 bucket and metadata database#
Set LAST_DAYOBS to whatever the last dayobs in the simualtion was.
In the above example, that’s three days ofter tonight:
LAST_DAYOBS="$(date -u --date='+36 hours' +'%Y%m%d')"
Register the simulation in the database:
SIM_UUID=$(vseqarchive record-visitseq-metadata \
simulations \
${OPSIM_RESULT_DIR}/opsim.db \
"${LABEL}" \
--first_day_obs ${DAYOBS} \
--last_day_obs ${LAST_DAYOBS}
)
Add additional metadata for this entry recording where the pre-simulation visits came from:
vseqarchive update-visitseq-metadata ${SIM_UUID} parent_visitseq_uuid ${COMPLETED}
vseqarchive update-visitseq-metadata ${SIM_UUID} parent_last_day_obs ${PREVIOUS_NIGHT_ISO}
Set appropriate tags.
The following set of tags make the visit sequence recognized as a standard prenight by tools like obsloctap and the prenight brifing report:
vseqarchive tag ${SIM_UUID} prenight ideal nominal
Save the visits themselves to the S3 bucket, simultaneously updating the metadata database with references for their locations:
ARCHIVE="s3://rubin:rubin-scheduler-prenight/opsim/vseq/"
vseqarchive archive-file ${SIM_UUID} ${OPSIM_RESULT_DIR}/opsim.db visits --archive-base ${ARCHIVE}
When the opsim visits file has an extension that indicates that it is an sqlite3 database (as it will be in this example),
it will be automatically converted to an HDF5 file for archiving.
If you used the --keep-rewords option in run_lsst_sim (as was done above), save the rewards file you generated as well:
vseqarchive archive-file ${SIM_UUID} ${OPSIM_RESULT_DIR}/rewards.h5 rewards --archive-base ${ARCHIVE}
Update the indexes of prenight simulations#
Some services (e.g. obsloctap) need to query for prenight simulation of a given night, but do not have access to the prenight simulation database.
To support them, we maintain the results of queries to the metadata database for prenight sims of a given night in a pre-determined location in the S3 bucket.
When we create a new simulation, we need to update the objects with the results in the S3 bucket.
We need to do this for each night simulated.
In this example, the DAYOBS environment variable contains the first night (tonight).
We specified that we were simulating 3 nights above, so set variables for tomorrow and the day after, and iterate over them:
NEXT_DAYOBS="$(date -u --date='+12 hours' +'%Y%m%d')"
LAST_DAYOBS="$(date -u --date='+36 hours' +'%Y%m%d')"
DAYOBS_SIMULATED="$DAYOBS $NEXT_DAYOBS $LAST_DAYOBS"
for DAYOBS_TO_INDEX in ${DAYOBS_SIMULATED}; do
vseqarchive make-prenight-index ${DAYOBS_TO_INDEX} simonyi
done
Retrieving indexes of prenight simulations#
The typical user of the prenight simulations should use the rubin_sim.sim_archive.prenightindex.get_prenight_index function.
get_prenight_index first attempts to query the metadata database for the data necessary to create the index.
If this query fails (e.g. due to access restrictions), it falls back on reading the index in the S3 bucket created by the vseqarchive make-prenight-index command.
For example:
>>> from rubin_sim.sim_archive.prenightindex import get_prenight_index
>>> pn_index_df = get_prenight_index('2025-12-10', 'simonyi')
>>> pn_index_df.tail()
sim_creation_day_obs daily_id visitseq_label ... tags comments files
visitseq_uuid ...
7468dd4a-54ef-44fb-8bc0-8091ad49e9ab 2025-12-10 2 Nominal start and overhead, ideal conditions, ... ... [ideal, nominal, prenight] {} {'rewards': 's3://rubin:rubin-scheduler-prenig...
c24d9a7a-995e-4b3a-8da6-40ac7ed3688d 2025-12-10 3 Start time delayed by 60 minutes, nominal slew... ... [delay_60, ideal, prenight] {} {'rewards': 's3://rubin:rubin-scheduler-prenig...
ff6df943-8a5b-4871-bbe2-5729f8aa0820 2025-12-10 4 Start time delayed by 240 minutes, nominal sle... ... [delay_240, ideal, prenight] {} {'rewards': 's3://rubin:rubin-scheduler-prenig...
6ee29551-5326-4d3b-9b2e-ba50c9e292d6 2025-12-10 5 Anomalous overhead (101, 0.1), nominal start, ... ... [anomalous_overhead, ideal, prenight] {} {'rewards': 's3://rubin:rubin-scheduler-prenig...
d08fb912-d57b-46ab-a911-ee97fd1a013f 2025-12-10 6 Anomalous overhead (102, 0.1), nominal start, ... ... [anomalous_overhead, ideal, prenight] {} {'rewards': 's3://rubin:rubin-scheduler-prenig...
[5 rows x 17 columns]
>>> pn_index_df.columns
Index(['sim_creation_day_obs', 'daily_id', 'visitseq_label', 'visitseq_url',
'telescope', 'first_day_obs', 'last_day_obs', 'creation_time',
'scheduler_version', 'config_url', 'sim_runner_kwargs',
'conda_env_sha256', 'parent_visitseq_uuid', 'parent_last_day_obs',
'tags', 'comments', 'files'],
dtype='object')
The columns of this pandas.DataFrame are as follows:
Field |
Type |
Description |
|---|---|---|
visitseq_label |
|
Human-readable label for the simulation |
visitseq_url |
|
URL of the visits file (HDF5) |
telescope |
|
Telescope identifier ( |
first_day_obs |
|
Local evening of the first night covered by the simulation |
last_day_obs |
|
Local evening of the last night covered |
creation_time |
|
When the simulation was run (UTC) |
scheduler_version |
|
Version of rubin_scheduler used |
config_url |
|
URL of the configuration script (if recorded) |
sim_runner_kwargs |
|
Arguments passed to |
conda_env_sha256 |
|
SHA-256 hash of the Conda environment used |
parent_visitseq_uuid |
|
UUID of the parent simulation (if this is a continuation) |
parent_last_day_obs |
|
Last night of the parent simulation |
sim_creation_day_obs |
|
Derived from |
daily_id |
|
Sequential ID for simulations created on the same day (1-based) |
stats |
|
Aggregated nightly statistics for the simulation. Structure follows the output of |
tags |
|
List of tags attached to the simulation (e.g., |
files |
|
Mapping from file type (e.g., |
comments |
|
Mapping from comment timestamp (ISO string) to comment text |
This data may also be read directly from the S3 bucket for the desired night (dayobs). The URL for the json data is of the form:
s3://rubin:rubin-scheduler-prenight/opsim/prenight_index/{telescope}/{year}/{month}/{telescope}_prenights_for_{YYYY-MM-DD}.json
The content is a json file with (hex representations of) simulation UUIDs as keys and dictionaries with metadata as the values of those keys. The start of a sample index looks like this:
{
"e572d2b3-d07b-496b-a0c3-a69c915a5ad4":{
"sim_creation_day_obs":"2025-12-08",
"daily_id":2,
"visitseq_label":"Nominal start and overhead, ideal conditions, run at 2025-12-08T06:59:18-08:00",
"visitseq_url":"s3:\/\/rubin:rubin-scheduler-prenight\/opsim\/vseq\/simonyi\/2025-12-08\/e572d2b3-d07b-496b-a0c3-a69c915a5ad4\/visits.h5",
"telescope":"simonyi",
"first_day_obs":"2025-12-08",
"last_day_obs":"2025-12-10",
"creation_time":"2025-12-08T15:09:51.399Z",
"scheduler_version":"",
"config_url":null,
"sim_runner_kwargs":null,
"conda_env_sha256":"52333af3b43db7704318f35d4fe7b9ddf770ca49c892f9681933c20de36cb0b3",
"parent_visitseq_uuid":"93b058db-c0f4-4395-b856-4064454299f3",
"parent_last_day_obs":"2025-12-07",
"tags":[
"ideal",
"nominal",
"prenight"
],
"comments":{
},
"files":{
"rewards":"s3:\/\/rubin:rubin-scheduler-prenight\/opsim\/vseq\/simonyi\/2025-12-08\/e572d2b3-d07b-496b-a0c3-a69c915a5ad4\/rewards.h5"
},
"stats":{
"azimuth":{
"q1":174.9977611669,
"q3":295.2438484415,
"max":359.7925184257,
"min":0.0004341731,
"p05":20.4236498145,
"p95":344.7673586831,
"std":82.3488406074,
"mean":226.8318565587,
"count":562,
"median":222.7917334351,
"accumulated":false
},
It can be read using lsst.resource.ResourcePath:
>>> from lsst.resources import ResourcePath
>>> import json
>>> prenight_index_rp = ResourcePath('s3://rubin:rubin-scheduler-prenight/opsim/prenight_index/simonyi/2025/12/simonyi_prenights_for_2025-12-10.json')
>>> prenight_index_json = prenight_index_rp.read().decode()
>>> prenight_index = json.loads(prenight_index_json)
Retrieving the table of visits for a simulation#
The indexed of simulations above include the visitseq_url referece to the HDF5 file with table of simulated visits themselves.
The simplest way to read these is with the rubin_sim.sim_archive.vseqarchive.get_visits utility:
>>> from rubin_sim.sim_archive.vseqarchive import get_visits
>>> visitseq_url = 's3://rubin:rubin-scheduler-prenight/opsim/vseq/simonyi/2025-12-08/e572d2b3-d07b-496b-a0c3-a69c915a5ad4/visits.h5'
>>> visits = get_visits(visitseq_url)
>>> visits.head()
observationId fieldRA fieldDec observationStartMJD flush_by_mjd visitExposureTime band filter rotSkyPos ... moonRA moonDec moonDistance solarElong moonPhase cummTelAz observation_reason science_program cloud_extinction
0 0 25.485040 -21.566665 61018.046632 0.0 150.0 r r_57 98.333137 ... 136.719114 19.773488 116.187971 113.972844 68.590565 8.975898 cwfs BLOCK-T630 0.0
1 1 24.731275 -13.747277 61018.048581 0.0 30.0 r r_57 92.888439 ... 136.749727 19.766991 115.028941 118.157641 68.575266 4.362920 singles_r BLOCK-407 0.0
2 2 26.590414 -11.364966 61018.049060 0.0 30.0 r r_57 97.394703 ... 136.757232 19.765397 112.626404 121.019966 68.571516 10.054260 singles_r BLOCK-407 0.0
3 3 25.249855 -8.776389 61018.049521 0.0 30.0 r r_57 93.312776 ... 136.764443 19.763864 113.121836 121.402330 68.567913 5.944932 singles_r BLOCK-407 0.0
4 4 23.904252 -6.185058 61018.049972 0.0 30.0 r r_57 90.071152 ... 136.771498 19.762364 113.578828 121.674979 68.564388 2.665790 singles_r BLOCK-407 0.0
The columns contained are those generated by the rubin_scheduler opsim simulation, and can therefore be analyzed using rubin_sim.maf tools.
The get_visits utility used above can accept a stackers keyword argument that takes a list of maf stackers, which supplement the base columns included in the HDF5 file with derived columns.
The HDF5 in the S3 store can alse be read directly using lower level tools:
>>> from lsst.resources import ResourcePath
>>> from tempfile import TemporaryDirectory
>>> import pandas as pd
>>> visitseq_url = 's3://rubin:rubin-scheduler-prenight/opsim/vseq/simonyi/2025-12-08/e572d2b3-d07b-496b-a0c3-a69c915a5ad4/visits.h5'
>>> visitseq_origin = ResourcePath(visitseq_url)
>>> with TemporaryDirectory() as temp_dir:
... h5_destination = ResourcePath(temp_dir).join("visits.h5")
... h5_destination.transfer_from(visitseq_origin, "copy")
... visits = pd.read_hdf(h5_destination.ospath, key="observations")
...
>>> visits.head()
observationId fieldRA fieldDec observationStartMJD flush_by_mjd visitExposureTime band filter rotSkyPos ... moonRA moonDec moonDistance solarElong moonPhase cummTelAz observation_reason science_program cloud_extinction
0 0 25.485040 -21.566665 61018.046632 0.0 150.0 r r_57 98.333137 ... 136.719114 19.773488 116.187971 113.972844 68.590565 8.975898 cwfs BLOCK-T630 0.0
1 1 24.731275 -13.747277 61018.048581 0.0 30.0 r r_57 92.888439 ... 136.749727 19.766991 115.028941 118.157641 68.575266 4.362920 singles_r BLOCK-407 0.0
2 2 26.590414 -11.364966 61018.049060 0.0 30.0 r r_57 97.394703 ... 136.757232 19.765397 112.626404 121.019966 68.571516 10.054260 singles_r BLOCK-407 0.0
3 3 25.249855 -8.776389 61018.049521 0.0 30.0 r r_57 93.312776 ... 136.764443 19.763864 113.121836 121.402330 68.567913 5.944932 singles_r BLOCK-407 0.0
4 4 23.904252 -6.185058 61018.049972 0.0 30.0 r r_57 90.071152 ... 136.771498 19.762364 113.578828 121.674979 68.564388 2.665790 singles_r BLOCK-407 0.0
Retrieving the latest nominal prenight simulation for a night#
A particularly common use of the prenight archive is to simply return visits from the latest nominal simulation for a given night and telescope.
The rubin_sim.sim_archive.fetch_sim_for_nights utility simplifies this task,
reading the prenight index, finding the ones with desirend metadata, and loading the corresponding visits from the latest matching simulation:
>>> from rubin_sim.sim_archive import fetch_sim_for_nights
>>> visits = fetch_sim_for_nights('2025-12-10', '2025-12-12', which_sim={'tags': ('ideal', 'nominal'), 'telescope': 'simonyi', 'max_simulation_age': 30})
>>> visits.head()
index observationId fieldRA fieldDec observationStartMJD flush_by_mjd visitExposureTime band filter ... moonRA moonDec moonDistance solarElong moonPhase cummTelAz observation_reason science_program cloud_extinction
0 0 0 27.728086 -21.211953 61020.047709 0.0 150.0 r r_57 ... 161.557441 8.748750 133.877255 114.115281 55.110377 7.944240 cwfs BLOCK-T630 0.0
1 1 1 28.993789 -13.374352 61020.049674 0.0 30.0 r r_57 ... 161.587119 8.738341 133.309112 119.900287 55.094211 10.547646 singles_r BLOCK-407 0.0
2 2 2 28.459780 -10.287782 61020.050117 0.0 30.0 r r_57 ... 161.593783 8.736001 133.791467 121.288930 55.090581 8.213424 singles_r BLOCK-407 0.0
3 3 3 27.969350 -7.184119 61020.050559 0.0 30.0 r r_57 ... 161.600448 8.733660 134.078759 122.629332 55.086950 6.614253 singles_r BLOCK-407 0.0
4 4 4 27.540610 -4.060129 61020.051002 0.0 30.0 r r_57 ... 161.607111 8.731318 134.143320 123.935418 55.083320 5.542837 singles_r BLOCK-407 0.0
The above call returns the latest simulation of the simonyi telescope that covers nights starting 2025-12-10 through 2025-12-12, has tags ideal and nominal.
Simulations older than 30 days are ignored, such that no visits will be return if the latest simulation is older than this.
Like the rubin_sim.sim_archive.vseqarchive.get_visits described above, the rubin_sim.sim_archive.get_sim_for_nights function can take a list of stackers in the stackers keyword argument.