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

Merge healpix mapmaker #964

Merged
merged 1 commit into from
Oct 28, 2024
Merged

Merge healpix mapmaker #964

merged 1 commit into from
Oct 28, 2024

Conversation

earosenberg
Copy link
Contributor

Add healpix support to the sotodlib mapmaking module.
Includes some re-factoring of demod_mapmaker to minimize code duplication

@earosenberg earosenberg marked this pull request as ready for review September 25, 2024 14:00
@chervias
Copy link
Contributor

We changed the tod_grouping file to obs_grouping. Can you fix that please?

@earosenberg
Copy link
Contributor Author

We changed the tod_grouping file to obs_grouping. Can you fix that please?

I had just forgotten to delete tod_grouping I think; fixed now, thanks!

Copy link
Member

@mhasself mhasself left a comment

Choose a reason for hiding this comment

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

A few comments, but then I realized this is based on the SAT mapmaking branch, not master.

Do we want this all to go into master now, or do you want to do healpix -> SAT_mapmaking first, or healpix -> master first?

sotodlib/coords/pmat.py Outdated Show resolved Hide resolved
sotodlib/coords/pmat.py Outdated Show resolved Hide resolved
sotodlib/coords/pmat.py Outdated Show resolved Hide resolved
sotodlib/coords/pmat.py Outdated Show resolved Hide resolved
@earosenberg
Copy link
Contributor Author

A few comments, but then I realized this is based on the SAT mapmaking branch, not master.

Do we want this all to go into master now, or do you want to do healpix -> SAT_mapmaking first, or healpix -> master first?

My thought was that this is similar in spirit to #891, so could go directly to master (and perhaps be merged from there into SAT-mapmaking). But I suppose if that is still the main branch for mapmaking the most important thing is to put it there, so we could go the other way. Happy to go with whatever you and @chervias think is easiest/best.

@mhasself mhasself self-requested a review October 7, 2024 17:35
@mhasself
Copy link
Member

mhasself commented Oct 7, 2024

@earosenberg I think it will be fine to PR this towards master rather than a mapmaking branch.

Can you rebase + squash the commit history here, please? Currently it's deeply intertwined with other branches, but then includes reversion of some changes from those branches; so it would be better to present a simpler view of what's proposed here.

@chervias
Copy link
Contributor

chervias commented Oct 7, 2024

I deleted the PR for the SAT_mapmaking branch, we are doing a refactor and we'll go through another route, so please merge into master.

Copy link
Member

@mhasself mhasself left a comment

Choose a reason for hiding this comment

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

Thanks for pushing this forward! Lots of comments. We might need to brainstorm the right way to enrich demod_mapmaker.py classes to support healpix without too much copy paste.

We don't have enough unit testing for Pmat... that's beyond your scope, I guess -- but if you want to take a stab at inventing that, it would be welcome.

sotodlib/coords/healpix_utils.py Show resolved Hide resolved
sotodlib/coords/healpix_utils.py Show resolved Hide resolved
sotodlib/coords/healpix_utils.py Outdated Show resolved Hide resolved
sotodlib/coords/pmat.py Outdated Show resolved Hide resolved
sotodlib/coords/pmat.py Outdated Show resolved Hide resolved
sotodlib/coords/pmat.py Outdated Show resolved Hide resolved
sotodlib/coords/pmat.py Outdated Show resolved Hide resolved
sotodlib/coords/pmat.py Outdated Show resolved Hide resolved
sotodlib/mapmaking/demod_mapmaker.py Outdated Show resolved Hide resolved
sotodlib/mapmaking/demod_mapmaker.py Outdated Show resolved Hide resolved
@earosenberg
Copy link
Contributor Author

OK addressed above comments, did the re-factor, and added some documentation

@earosenberg
Copy link
Contributor Author

Added some (simple) tests for demod_mapmaker.py and pmat.py

Copy link
Member

@mhasself mhasself left a comment

Choose a reason for hiding this comment

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

Ok! I think this is looking good. A few comments about docs mostly.

Thanks for extending the existing tests -- that paves the way for more / better in the future.

Can you remind me what the use of qp_kwargs has been? It is a bit suspicious to have that, and det_weights, added to the DemodMapmaker.add_obs. You'd think that noise_model could somehow capture the effects of det_weights, and geom (or the class constructor, more generally) could handle whatever qp_kwargs is doing. I have stopped looking into this in the spirit of getting this review in in finite time, but perhaps you and @chervias could consider that, from the perspective of eventually unforking the mapmaker & signal classes.

Comment on lines 12 to 15
Full map: A normal healpix map (in NEST ordering). Numpy arrays with shape (...,npix); can have any number of leading dimensions.
Tiled map: A len(nTile) list of tiles. None for inactive tiles and a numpy array of shape (..., npix/nside) for active tiles.
Compressed map: Numpy array of shape (nActiveTile, ..., npix/nside). Requires additional active tile information to recover a full map.
The position of the tile axis in a compressed map can be controlled with the tile_axis_pos argument.
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the docs -- if you could "fill' these at 78 characters or so I would greatly appreciate it. It seems like you're doing one sentence per line, but rst/sphinx does not recognize that... so neither do I! Just fill them into a paragraph and let the punctuation guide the reader.

For these definitions, easiest is to just make it an rst list, with indentation to make multi-line entries:

- Full map: blah blah yada yada, then
  more text on next line about full map.
- Tiled map: and son on.
- ...

Functions are provided to transform between "full", "compressed", and "tiled" Healpix maps.
This follows a scheme in which the full map is broken up into individual tiles defined by a lower resolution map.
The setup ("geometry") is defined by the base nside, nside_tile of the tiling, and the ordering.
Tiled maps must use "NEST" ordering in this scheme. If no tiling is used, "RING" is allowed.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe mention that nTile = 12 * nside_tile**2... I know it's buried in the function later...

Comment on lines 50 to 52
compressed: compressed map
active_tile_list: len(nTile) boolean array of active tiles
tile_axis_pos: Index for the tile axis in the input compressed array
Copy link
Member

Choose a reason for hiding this comment

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

I think these args were copied from another function and not updated...

Comment on lines 77 to 80
object, with attributes .shape and .wcs;
a pixell.tilemap.TileGeometry (if tiled);
or a Healpix geometry with attributes nside, nside_tile, and
ordering.
Copy link
Member

Choose a reason for hiding this comment

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

reformat so paragraph width is the same as the rest of this module.

a pixell.tilemap.TileGeometry.
object, with attributes .shape and .wcs;
a pixell.tilemap.TileGeometry (if tiled);
or a Healpix geometry with attributes nside, nside_tile, and
Copy link
Member

Choose a reason for hiding this comment

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

Maybe just say "or a Healpix geometry as defined in coords.healpix_utils".

return map

def _get_hp_tile_list(self, tiled_arr=None):
"""Get len(nTile) boolean array of whether tiles are active. None if un-tiled.
Copy link
Member

Choose a reason for hiding this comment

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

"For healpix maps, ..."

self.rhs = enmap.zeros((Nsplits, ncomp) +shape, wcs, dtype=dtype)
self.div = enmap.zeros((Nsplits,ncomp,ncomp)+shape, wcs, dtype=dtype)
self.hits= enmap.zeros((Nsplits,)+shape, wcs, dtype=dtype)
return cls(shape, wcs, comm, comps, name, ofmt, output, ext, dtype, sys, recenter, tile_shape, tiled, Nsplits, singlestream)
Copy link
Member

Choose a reason for hiding this comment

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

Pass parameters by name, please!

filter+bin mapmaking, i.e. map from obs.signal rather than from obs.dsT,
obs.demodQ, obs.demodU
"""
return cls(None, None, None, comps, name, ofmt, output, ext, dtype, None, None, None, False, Nsplits, singlestream, nside, nside_tile)
Copy link
Member

Choose a reason for hiding this comment

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

Pass params by name.

m = np.reshape(m, (np.product(m.shape[:-1]), m.shape[-1]), order='C') # Flatten wrapping axes; healpy.write_map can't handle >2d array
hp.write_map(oname, m.view(self.dtype), nest=(self.hp_geom.ordering=='NEST'), partial=write_partial_fits, overwrite=True)
elif self.ext == "npy":
np.save(oname, m.view(self.dtype))
Copy link
Member

Choose a reason for hiding this comment

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

I think we'd be wise to write both the array and some supporting info the projection. NEST is essential for understanding the data. NSIDE is helpful. Eventually we might throw in the celestial frame (galactic / equatorial).

Copy link
Contributor Author

@earosenberg earosenberg Oct 16, 2024

Choose a reason for hiding this comment

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

The ordering and nside information is automatically included in the header for fits.
I don't think there is any way of including it for .npy files (?), except for forcibly adding it to the filename. (Aside: we can remove the npy option if it's not useful)

Copy link
Member

Choose a reason for hiding this comment

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

Like this, basically:

np.save('test.npy', {'nside': 10, 'data': np.zeros(1000)}, allow_pickle=True)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it, thanks for the help!

if h5py is None:
raise ValueError("Cannot save healpix map as hdf5; h5py could not be imported. Install h5py or save as npy or fits")
with h5py.File(oname, 'w') as f:
dset = f.create_dataset("data", m.shape, dtype=self.dtype, data=m)
Copy link
Member

Choose a reason for hiding this comment

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

Same here -- add attributes to this dataset with important projection info.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, added ordering and nside as attributes

@earosenberg
Copy link
Contributor Author

earosenberg commented Oct 16, 2024

Can you remind me what the use of qp_kwargs has been?

I am happy to leave or remove this as you and @chervias think. This was put in place to enable changing the settings of qpoint -- primarily so they could match TOAST settings. The point was to allow to_map match an input map that was scanned with TOAST at default settings. I think this is potentially useful, but maybe a sufficiently niche application that it's not worth complicating the code with.
Also, if we remove it from demod_mapmaker should I take it out of pmat as well?

You'd think that noise_model could somehow capture the effects of det_weights

I think this is correct. The main function of det_weights now is to disable inverse variance weighting for testing, but this can easily be achieved with Nmat. I'll remove it, thanks for the suggestion.

@earosenberg
Copy link
Contributor Author

That should be the most recent comments done -- thanks for the continued feedback. For qp_kwargs I thought it seemed sensible to remove it from demod_mapmaker but leave it in pmat, but happy to change that if there are any objections.

By the way, I also have a unit test file for healpix_utils, mostly checking that the conversions between different healpix formats (tiled, compressed, full) are working right. Wasn't sure if you want this to be included, but will add it if so.

@chervias
Copy link
Contributor

Besides fixing the conflict, is there anything stopping us from merging? I need this to be merged first so that I can start moving towards merging #973.

@earosenberg
Copy link
Contributor Author

Not from my side -- was waiting for the go-ahead before doing a final rebase and resolving the conflict.

@mhasself
Copy link
Member

Not from my side -- was waiting for the go-ahead before doing a final rebase and resolving the conflict.

This is good to go other than the conflict. Please rebase, fix conflict, squash ... in some order ... and I'll approve.

@earosenberg
Copy link
Contributor Author

Rebase/conflict/squash all done.
NB the new test_pmat.py is failing post-rebase on tiled rectpix maps. It seems that the new enmapify in remove_weights and invert_weights doesn't work for the tiled case. I can remove those lines from the test if it needs to pass before merging, but it seemed like an issue to address outside this PR.

@mhasself
Copy link
Member

Rebase/conflict/squash all done. NB the new test_pmat.py is failing post-rebase on tiled rectpix maps. It seems that the new enmapify in remove_weights and invert_weights doesn't work for the tiled case. I can remove those lines from the test if it needs to pass before merging, but it seemed like an issue to address outside this PR.

Ok ... ya, just suppress that test (comment it out) and we can fix it separately.

@earosenberg
Copy link
Contributor Author

Ok ... ya, just suppress that test (comment it out) and we can fix it separately.

Great, done

Copy link
Member

@mhasself mhasself left a comment

Choose a reason for hiding this comment

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

Quick merge it before something else breaks

@earosenberg earosenberg merged commit 0177b36 into master Oct 28, 2024
4 checks passed
@earosenberg earosenberg deleted the merge-healpix-mapmaker branch October 31, 2024 08:41
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.

4 participants