Skip to content

Incorporating LyA 1B changes into AMTL#162

Open
LNapolitano wants to merge 64 commits into
mainfrom
LGN-LyA-1B
Open

Incorporating LyA 1B changes into AMTL#162
LNapolitano wants to merge 64 commits into
mainfrom
LGN-LyA-1B

Conversation

@LNapolitano

@LNapolitano LNapolitano commented Jul 29, 2025

Copy link
Copy Markdown
Member

This PR will contain the changes necessary to incorporate the LyA 1B numobs changes into the alt MTLs. Planning to add a new actiontype to the tiletracker file, that when encountered will run desitarget.mtl.update_lya_1b on the alt ledger directory.

…AML file based on the file creation times of the real mtl ledgers
…w" actions to create new ledgers in an already existing set of alternate MTL ledgers.
@LNapolitano LNapolitano self-assigned this Jun 15, 2026
LNapolitano and others added 12 commits June 17, 2026 12:14
Removing special handling for tiles with 4.0 < FAVER < 5.0. Testing shows this is no longer necessary.
This should altmtltools to be used in pre desitarget version 3.4.0 environments, as is currently desirable for the mock alt-mtls due to memory issues in later versions.
comment out target option since is not used for mocks
Remove target option, is not used
remove targfile. Is not needed in mocks
remove targfile for mocks. Is not used
remove targfile option, is not needed
remove targfile option, is not needed for mocks
Comment thread bin/SingleNode-InitializeAltMTLsParallel.py
@jalasker

Copy link
Copy Markdown
Contributor

Hi Lucas,

Just finished reviewing the pull request. Notes/Comments/Questions below.

Most of the comments are for improvements that aren't going to directly impact the function of the code, but I will highlight the comments for altmtltools.py L787 and fatools.py L388 as potential issues (though much more likely I didn't trace the logic exactly right).

The addnew function is somewhat unique in that it requires some variables set at the creation of a set of alt mtl ledgers, namely {"seed", "reproducing", "shuffleSubpriorities", "shuffleBrightPriorities", "shuffleELGPriorities", "PromoteFracBGSFaint", "PromoteFracELG"}. Presently the code looks to find these in an initialization log file (default format: "Initialize{Obscon}AltMTLsParallelOutput_mainRepro.out"). We will need to discuss how to best handle accessing these keywords for the mock altMTLs.

  • This is one of the reasons I liked having the script copied over from the initialization step. We don’t currently have any easily readable memory for this beyond the initial file (which, even with the copy checking step, can still be manually changed if it’s changed in the AMTL directory, so not perfect!). However, I believe we can store all of this information as metadata in the tile tracker ECSV header.

Comments on code changes:
bin/DA2ALTMTLRealizationsBRIGHT_mock.sh‎

  • L225 - Let’s remove the targfile variable from the code entirely at some point since only the mocks should have required this. Then we can remove the option and the commented associated options from the script files.
  • Not going to make this comment for every bin/*.sh file but it applies to all of them

bin/SingleNode-InitializeAltMTLsParallel.py

  • L94-96 - Can we safely remove the legacy code and those comments now? It sounds like YAML is working and we always have prior tagged versions on GitHub in case we need to access it again.
  • L159-169 - put these inside of an “if verbose and/or debug” block. It’s already hard to read the log files.

py/LSS/SV3/altmtltools.py

  • L35-43 - It should be more reliable to directly check the version of desitarget rather than excepting all ImportErrors
  • L178 (previously 166) - IIRC, the purpose of this check was to ensure that the argument bit2Flip was a power of two. If you want to remove the “int()” from around the second argument of that assert statement, you should replace the entire argument with “bit2Flip == bit2Flip” since you’re only catching nans with that anyway.
  • L515-546 - Anything related to parsing/creating the YAML files I’m going to assume is correct based on your testing since I’m not super familiar with the syntax. I want to get this review done quickly so you can start running the new AMTLs again. Let me know if you want me to review the YAML changes more closely.
  • L765-6 - This warning should be propagated to the bin/*.sh files and/or written to log file/console if set to False.
  • L787 - Shouldn’t one of these date checks be “<=“ or “>=“?
  • L837-885 - Flagging that we decided yesterday that we wanted to rewrite this without using svn directly in the script. A file written to a (DESI-)universally accessible directory in CFS sounded like a good option.
  • L926, 1035,1236,1238 - These, and many other log statements I left in this function, should be behind “if verbose” and/or “if debug” to clean up log files.

py/LSS/SV3/fatools.py

  • L388 - I’m a little worried about this line being applied to higher target versions than the default (1.1.1). These may(/will?) have new targets that aren’t present in 1.1.1 and so removing the check we have to see if v3.0.0 and 3.2.0 are being incorporated correctly feels suboptimal.

@jalasker jalasker left a comment

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.

Accidentally submitted the review as a comment, resubmitted all of the content from the comment as review comments directly on the relevant lines of code except for this comment in reply to one of your comments:

The addnew function is somewhat unique in that it requires some variables set at the creation of a set of alt mtl ledgers, namely {"seed", "reproducing", "shuffleSubpriorities", "shuffleBrightPriorities", "shuffleELGPriorities", "PromoteFracBGSFaint", "PromoteFracELG"}. Presently the code looks to find these in an initialization log file (default format: "Initialize{Obscon}AltMTLsParallelOutput_mainRepro.out"). We will need to discuss how to best handle accessing these keywords for the mock altMTLs.

  • This is one of the reasons I liked having the script copied over from the initialization step. We don’t currently have any easily readable memory for this beyond the initial file (which, even with the copy checking step, can still be manually changed if it’s changed in the AMTL directory, so not perfect!). However, I believe we can store all of this information as metadata in the tile tracker ECSV header.

#targfile='' #CHANGEME IF RUNNING ON MOCKS
#targfile='--targfile=/global/cfs/cdirs/desi/target/catalogs/dr9/1.1.1/targets/main/resolve/' #Main survey target directory
#ACR: we deactivate this option since is not used for mocks, it is not needed
targfile=''

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.

  • Let’s remove the targfile variable from the code entirely at some point since only the mocks should have required this. Then we can remove the option and the commented associated options from the script files.
  • Not going to make this comment for every bin/*.sh file but it applies to all of them

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Agreed. I'll pass this along to @aureliocarnero as well for the mock scripts. Not urgent, but good to remove the targfile variables at some point.

log.debug('First healpixel: {0:d}'.format(HPList[0]))
log.debug('Last healpixel: {0:d}'.format(HPList[-1]))
log.debug('Number of healpixels: {0:d}'.format(int(len(HPList))))
# 20260401 LGN - Modifying HPList to be read from a YAML file, not a csv

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.

Can we safely remove the legacy code and those comments now? It sounds like YAML is working and we always have prior tagged versions on GitHub in case we need to access it again.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks James! Agreed, we can remove some of the comments here. I think the HPList info is still useful, as we do load that from the yaml file. Also I've just rewritten this section to use a --yamlpath argument to specify the directory name, with the default value supplied.

28924ce

log.info(args.finalDir)
log.info('shuffleSubpriorities: {0}'.format(args.shuffleSubpriorities))

# 20260420 LGN - Adding some additional log statements here for reproducibility

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.

put these inside of an “if verbose and/or debug” block. It’s already hard to read the log files.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done! dd5349a

I just had to work out the tiletracker meta change first, as I was relying on these statements otherwise.

Comment thread py/LSS/SV3/altmtltools.py Outdated

#LGN 20260617 - Adding a T/E wrapping around the update_lya_1b import
# - This should enable the this code to be used with older desitarget versions.
try:

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.

It should be more reliable to directly check the version of desitarget rather than excepting all ImportErrors

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Agreed, the try/except was a little nasty. I've replaced this with a "hasattr" check:
95576c2

This whole block is hopefully temporary as the mock team investigates the memory issues they encounter in desitarget versions after 3.0.0

Comment thread py/LSS/SV3/altmtltools.py
def flipBit(cat, bit2Flip, cond = None, fieldName = 'DESI_TARGET', mode = 'on'):
#only works on single bits
assert( np.abs( np.log2(int(bit2Flip)) - int(np.log2(int(bit2Flip))) ) < 0.001 )
assert( np.abs( np.log2(int(bit2Flip)) - np.log2(int(bit2Flip)) ) < 0.001 )

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.

IIRC, the purpose of this check was to ensure that the argument bit2Flip was a power of two. If you want to remove the “int()” from around the second argument of that assert statement, you should replace the entire argument with “bit2Flip == bit2Flip” since you’re only catching nans with that anyway.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, this is something that I believe broke with a new numpy version at some point? The log2 function required the explicit casting I believe. Anyway, since this is working for now I'm going to leave it as is, but I agree I can take another look later.

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.

If the check here was solely for bit2Flip being a power of 2, then this answer is a lot smoother than what I wrote trying to avoid floating point rounding errors and vagaries of built-ins: https://stackoverflow.com/a/57025941 ((n & (n-1) == 0) and n != 0)

Comment thread py/LSS/SV3/altmtltools.py Outdated
fn = initMTL.split('/')[-1]
log.info('reading initial MTL(s)')
allentries = Table.read(initMTL)
log.info('initial MTL size: {}'.format(len(allentries)))

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.

This, and many other log statements I left in this function, should be behind “if verbose” and/or “if debug” to clean up log files.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added: 669b5e6

Comment thread py/LSS/SV3/altmtltools.py
#makeTileTracker(outputMTLDir, survey = survey, obscon = obscon,overwrite = False,
#startDate = startDateShort, endDate = endDateShort)
else:
log.info('tiletracker already exists, not overwriting')

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.

“if verbose” and/or “if debug”

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added: 669b5e6

Comment thread py/LSS/SV3/altmtltools.py Outdated
#JL - reset TARGET_STATES based on new target bits. This step isn't necessary for AMTL function but makes debugging using target states vastly easier.
initialentries['TARGET_STATE'][ELGNewHIP & np.invert(QSOs)] = np.broadcast_to(np.array(['ELG_HIP|UNOBS']), np.sum(ELGNewHIP & np.invert(QSOs) ) )

log.info('Initial Entries Size: {}'.format(len(initialentries)))

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.

“if verbose” and/or “if debug”

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added: 669b5e6

Comment thread py/LSS/SV3/altmtltools.py Outdated

log.info('Initial Entries Size: {}'.format(len(initialentries)))
retval = desitarget.io.write_mtl(outputMTLDir, initialentries, survey=survey, obscon=obscon, extra=meta, nsidefile=meta['FILENSID'], hpxlist = [meta['FILEHPX']])
log.info('write_mtl return value: {}'.format(retval))

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.

“if verbose” and/or “if debug”

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added: 669b5e6

Comment thread py/LSS/SV3/fatools.py Outdated
log.info(f'reproducing = {reproducing}')

#LGN 01/28/26: Adding compatibility with BRIGHT1B
elif targver == '1.0.0' or targver == '3.0.0' or targver == '3.2.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’m a little worried about this line being applied to higher target versions than the default (1.1.1). These may(/will?) have new targets that aren’t present in 1.1.1 and so removing the check we have to see if v3.0.0 and 3.2.0 are being incorporated correctly feels suboptimal.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, I was admittedly a little unsure about this one. The intention here was to handle the very early survey tiles by directly copying their targ files rather than generating them via altcreate_mtl() is that correct?

Since this only ever runs with reproduction = True, it won't affect our standard reproduction = False runs. And I have verified that we can run dark1b/bright1b with reproduction = False. Maybe the best solution is to just remove 3.0.0 and 3.2.0 from this check and move them into the earlier statement:
if (not reproducing) or (targver == '1.1.1'):

But I'm not sure I totally understand the intention here either. Let me know what you think would be best.

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.

The point I wanted to make here is related to the original reason this copy block was made for the reproduction runs.

Originally there was a very short period of time (few days-weeks?) where DESI used target version 1.0.0 rather than 1.1.1. It proved to be challenging to exactly handle this target version change with the precision required for an exact reproduction test, but it was simple (IIRC we didn't actually have to make any changes) to get it working good enough from a statistical POV given the small number of tiles observed in that period of time.

Therefore, we decided we could directly copy a handful of tiles and test that everything downstream of those tiles ran as expected and that would validate the remainder of the survey running on the same target version.

With the version change going forward into BRIGHT1B, we have a similar scenario where 1.1.1 was used for a period of time and going forward we are using 3.0.0/3.2.0. Except this time we are doing the exact target file copy for the new version which will be used going forward. This means that any reproduction test should automatically succeed starting at the date where you use 3.0.0/3.2.0. At best, it means that no targets in v3.0.0 /3.2.0 are being properly tested, but the v1.1.1 targets which are still remaining get properly tested.

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.

3 participants