-
Notifications
You must be signed in to change notification settings - Fork 40
Toast 3 Work in Progress #369
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
base: master
Are you sure you want to change the base?
Conversation
|
I think the easiest way to provide feedback would be to make an export of the notebook to a Python script in a separate pull request, so we can do line by line feedback there. Then the pull request can be closed without merging. |
|
Good idea @zonca, will do that soon. |
|
Ok @zonca, I enabled the
https://app.reviewnb.com//pull/369/files/
and comment on the per-cell level of the intro.ipynb file. Since a lot has changed, there is a switch to "hide previous version". Let me know if that works, since I can't tell if this plugin is usable by everyone. |
|
Note that the output of the notebook is stripped on github, so refer to the PDF attached to this issue to look at that. |
|
Updated notebook output, with config section. |
| "metadata": { | ||
| "toc-hr-collapsed": false | ||
| }, | ||
| "source": [ |
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.
mention if you can modify this in place or it is read-only. If it is read-only, how do I modify it?
Reply via ReviewNB
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.
Good point, some options are fixed by the OS runtime environment of python, but some can be changed after toast is imported. Will give more details.
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.
Added text about setting log level manually or through environment. Same with threading.
| "metadata": { | ||
| "toc-hr-collapsed": false | ||
| }, | ||
| "source": [ |
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.
better specify that "traditional CPU systems" means a supercomputer, otherwise it seems it is also required on a laptop.
Reply via ReviewNB
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.
Well, if the user has an AMD Ryzen workstation with 16 cores (for example), then they probably want to use mpi4py if they are doing something more with toast than just running a notebook with a few samples. I will definitely clarify though. I have started an "intro_parallel.ipynb" where I am going to discuss using IPython.parallel with mpi4py. I'll reference that in the serial notebook.
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.
Tried to clarify that toast parallelism is mainly through MPI, so that any system with more than a few cores will benefit from having mpi4py installed.
| "metadata": { | ||
| "toc-hr-collapsed": false | ||
| }, | ||
| "source": [ |
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.
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.
Good idea. astropy.units are a new addition to toast, and currently only used in the new Operator traits. I need to systematically go through the codebase and add support.
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 converted the fake focalplane simulation and plotting functions to use units. However, I'll wait on the rest of the instrument classes until we can revisit the overall plan for those.
| "metadata": { | ||
| "toc-hr-collapsed": false | ||
| }, | ||
| "source": [ |
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.
if detlabels is None, you could use the keys as labels, so we avoid to build the trivial dict x:x.
please use keyword arguments for all inputs, so people don't have to look at the help of plot_focalplane
For the color, what about using endswith("A") instead of enumerating?
Reply via ReviewNB
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.
Ok, this is cleaned up.
| "metadata": { | ||
| "toc-hr-collapsed": false | ||
| }, | ||
| "source": [ |
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.
| "metadata": { | ||
| "toc-hr-collapsed": false | ||
| }, | ||
| "source": [ |
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.
either it is an attribute, so other_simsat.config
or it is a method then needs to have a verb in the name:
other_simsat.get_config()
Reply via ReviewNB
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.
The methods are now get_config() and get_class_config()
| "metadata": { | ||
| "toc-hr-collapsed": false | ||
| }, | ||
| "source": [ |
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.
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 was inspired by the traitlets methods traits() and class_traits(), but I can add a "get_" in there if it is more clear.
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.
yes please
| "metadata": { | ||
| "toc-hr-collapsed": false | ||
| }, | ||
| "source": [ |
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 heard about it but first time I used
@tskisner, I think the Toast interface looks really good, good job! I have a bit more feedback in the notebook. |
|
Thanks @zonca for the detailed review, just what I was looking for! On overall question for objects that act like a dictionary, but which have other state information. For example, actually creates a And then have setitem check that the number of samples matches that in the observation. This did not seem as convenient to me, but I do hate typing :-) For the MPI shared memory class, I could replace the set method like this: or or something else? |
|
inside def __setitem__(self, key, value):
# if key is undefined
data = DetectorData(self.detectors, (self.n_sample,)+ value.shape, dtype=value.dtype)
# set this into the dictfor the set I don't understand, what do you need the |
|
I'll try to clarify... The For the MPIshared class, the |
|
I think I understand now- you want to allow I can implement that, but still not sure it is more convenient. On the other hand, no reason not to support multiple ways of assignment! |
|
Ahhh, now I see- you can create the full-size DetectorData object first, and then the slicing notation can be applied when actually assigning from the RHS. Ok, I will try this out. I agree this would be a more convenient interface. I'll also try to modify the MPIshared package to make the set() method optional at the cost of a precalculation. |
|
I have added setitem support to the upstream https://github.com/tskisner/pshmem/releases/tag/0.2.5 And this new version is available on PyPI: https://pypi.org/project/pshmem/0.2.5/ So now I can work on using that syntax in toast. |
|
Ok, I think I have concluded that the import numpy as np
class DetData:
def __init__(self, ndet, shape, dtype):
self.dtype = np.dtype(dtype)
self.shape = [ndet]
self.flatshape = ndet
for s in shape:
self.shape.append(s)
self.flatshape *= s
self.flatdata = np.zeros(self.flatshape, dtype=self.dtype)
self.data = self.flatdata.reshape(self.shape)
def __getitem__(self, key):
print("DetData getitem {}".format(key))
return self.data[key]
def __setitem__(self, key, value):
print("DetData setitem {}".format(key))
self.data[key] = value
def __repr__(self):
return str(self.data)
class Mgr:
def __init__(self, ndet):
self.ndet = ndet
self.d = dict()
def create(self, name, shape, dtype):
self.d[name] = DetData(self.ndet, shape, dtype)
def __getitem__(self, key):
print("Calling Mgr getitem")
if key not in self.d:
# Cannot guess what shape and dtype the user wants
pass
return self.d[key]
def __setitem__(self, key, value):
print("Calling Mgr setitem")
self.d[key] = value
mgr = Mgr(2)
# This works fine, as expected:
mgr.create("A", (3, 4), np.int32)
mgr["A"][1, 0:2, 0:2] = 5
print("mgr['A'] = \n", mgr["A"])
# This works, but it is annoying, since the user has to know the name
# of the DetData class and also has to get information from the Mgr
# class:
mgr["B"] = DetData(mgr.ndet, (3, 4), np.int32)
mgr["B"][1, 0:2, 0:2] = 5
print("mgr['B'] = \n", mgr["B"])
# The code below is actually doing:
#
# Mgr.__getitem__("C").__setitem(tuple, 5)
#
# Which means that the DetData class would have to be instantiated in
# Mgr.__getitem__() where we don't know the correct shape of the buffer
# to create. Obviously this gives a key error:
mgr["C"][1, 0:2, 0:2] = 5
print("mgr['C'] = \n", mgr["C"])The output of the above script is: |
|
you first need to create the thing before slicing it: mgr = Mgr(2)
mgr["A"] = np.zeros((3,4), dtype=np.int32)
mgr["A"][1, 0:2, 0:2] = 5It doesn't work now, but it should be implementable. |
|
Hi @zonca, thanks for your patience, and sorry if I am being dense :-) Below I updated the toy code to be closer to the real case. The central problem is that when assigning data (see the import numpy as np
class DetData:
def __init__(self, ndet, shape, dtype):
self.dtype = np.dtype(dtype)
self.shape = [ndet]
self.flatshape = ndet
for s in shape:
self.shape.append(s)
self.flatshape *= s
self.flatdata = np.zeros(self.flatshape, dtype=self.dtype)
self.data = self.flatdata.reshape(self.shape)
def __getitem__(self, key):
return self.data[key]
def __setitem__(self, key, value):
self.data[key] = value
def __repr__(self):
return str(self.data)
class Mgr:
def __init__(self, ndet, nsample):
self.ndet = ndet
self.nsample = nsample
self.d = dict()
def create(self, name, sample_shape, dtype):
self.d[name] = DetData(self.ndet, (self.nsample,) + sample_shape, dtype)
def __getitem__(self, key):
return self.d[key]
def __setitem__(self, key, value):
if isinstance(value, DetData):
self.d[key] = value
else:
# This is an array, verify that the number of dimensions match
sample_shape = None
if len(value.shape) < 2:
raise RuntimeError("Assigned array does not have sufficient dimensions")
elif len(value.shape) == 2:
# We assume the user meant one scalar value per sample...
sample_shape = (1,)
else:
# The first two dimensions are detector and sample. The rest of the
# dimensions are the data shape for every sample and must be fully
# specified when creating data like this.
sample_shape = value.shape[2:]
print(
"Creating DetData with {} dets, {} samples, {} samp shape".format(
self.ndet, self.nsample, sample_shape
)
)
self.d[key] = DetData(
self.ndet, (self.nsample,) + sample_shape, value.dtype
)
# If the value has the full size of the DetData object, then we can do the
# assignment, if not, then we cannot guess what detector / sample slice
# the user is trying to assign.
if (value.shape[0] == self.ndet) and (value.shape[1] == self.nsample):
# We can do it!
self.d[key][:] = value
# 2 detectors and 5 samples
mgr = Mgr(2, 5)
# This works fine, as expected:
mgr.create("A", (3, 4), np.int32)
mgr["A"][1, 2:3, 0:2, 0:2] = 5
print("mgr['A'] = \n", mgr["A"])
# This works, but it is annoying, since the user has to know the name
# of the DetData class and also has to get information from the Mgr
# class:
mgr["B"] = DetData(mgr.ndet, (mgr.nsample, 3, 4), np.int32)
mgr["B"][1, 2:3, 0:2, 0:2] = 5
print("mgr['B'] = \n", mgr["B"])
# This creates a buffer with the full number of detectors and samples and uses the
# last dimensions of the RHS to determine the shape of the data per sample. However,
# we have no information about what LHS slice we are assigning the RHS data to. UNLESS
# the user gives a RHS data with the full n_detector x n_sample data set:
# mgr["C"] is created by not assigned, since we don't know where to assign the data
# along the first 2 axes (detector and sample).
mgr["C"] = np.ones((1, 1, 3, 4), dtype=np.int32)
mgr["C"][1, 2:3, 0:2, 0:2] = 5
print("mgr['C'] = \n", mgr["C"])
# mgr["D"] is created AND assigned, since we specify data of the full size.
mgr["D"] = np.ones((mgr.ndet, mgr.nsample, 3, 4), dtype=np.int32)
mgr["D"][1, 2:3, 0:2, 0:2] = 5
print("mgr['D'] = \n", mgr["D"])I think that the How about we support cases
Does that seem acceptable? |
|
here: # mgr["C"] is created by not assigned, since we don't know where to assign the data
# along the first 2 axes (detector and sample).
mgr["C"] = np.ones((1, 1, 3, 4), dtype=np.int32)
mgr["C"][1, 2:3, 0:2, 0:2] = 5
print("mgr['C'] = \n", mgr["C"])This case is not supported, the user needs to initialize the array in 2 ways:
so the use case is: # provide just 1 timeline, it will be copied to all detectors, we should support both 3D and 4D
mgr["C"] = np.ones((mgr.n_samples, 3, 4), dtype=np.int32)
# or
mgr["C"] = np.ones((1, mgr.n_samples, 3, 4), dtype=np.int32)
mgr["C"][1, 2:3, 0:2, 0:2] = 5
print("mgr['C'] = \n", mgr["C"])inside |
|
Ok, no problem that sounds good. Will work on implementing and addressing your other feedback. |
|
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
* Small cleanups for building with LLVM-17: * Restore is_device_ptr clauses and formatting removed in #676 * Update test scripts to support llvm compilation * Remove debugging.
* Fix the simulated focalplane layout spacing. * Clarify that the angular "width" corresponds to the spacing of extreme pixel location along a specific axis. * Fix off-by-one to match this specification. * Add new rhombus_hex layout function as a unification of downstream tools into a central location for testing. * Ensure that all layout functions also propagate the detector gamma angle in the returned detector properties. * Add pixel centers to unit test plots to verify correct layout. * Small tweaks to rhombus hex layout.
such that `python -m toast.scripts.toast_ground_schedule -h` would work or we could do ```py from toast.scripts.toast_ground_schedule import main main(...) ```
* Add argument for selecting the reference time for boresight rotation; remove unnecessary keywords * Update src/toast/schedule_sim_ground.py Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
* Add a simple operator to apply a "counter 1/f" filter. For (at least) 25 years, the inverse time domain noise covariance has been used as a "change of basis" when solving a generalized least squares problem for the maximum likelihood map in pixel space. For simpler "filter and bin" mapmaking techniques, application of this N_tt'^-1 filter may be useful. This work adds an operator which uses a given noise model for detector PSDs to compute the inverse noise covariance fourier domain kernels for each detector and convolve the timestreams by those. * Add initial unit test. Fix normalization. * More unit test improvements and cleanup
* Fix argument types and add optional rotation * use the user-provided alpha
* Add options to noise model flagging to support detector groups. Sometimes groups of detectors have very different noise properties. These changes allow flagging of outliers in independent groups of detectors. * Address review comments
) * Add a generic "toast_run" workflow for arbitrary nested Pipelines. In practice, many workflows can be expressed as nested sequences (toast.ops.Pipeline) instances. Internal references between objects in config files have been supported for years, but using these in complex situations required a couple of small fixes. - Add toast_run script, which looks for a single "main" operator and runs it. - Add HDF5 helper functions for saving / loading just the instrument models in the same format as used in HDF5 Volumes. - In SimGround and SimSatellite, add support for loading instrument models and schedule files as traits. - Expand unit tests for nested pipelines in config files. * Fix typo * Move config file format parsing to a dedicated function.
* Tweak jump correction to better handle ringing * Jumpcorrect should not accept jumps that are scan-synchronous * Record HWPSS amplitudes * Various tweaks
* Fully working implementation of the common mode filter * Add support for changing the polarization reference frame in demodulated Stokes weights * WIP * Fix issues with stale quaternions, vastly improve the unit tests * Fix unit test failure * Clean up the common mode operator and address copilot-found issues * Fix demodulation of shared data (#869) * Add an operator that returns detector pointing in the boresight frame. Useful for Qr/Ur common mode. * Finalize support for radial polarization frame --------- Co-authored-by: Theodore Kisner <[email protected]>
* Variety of small fixes. - Fixes to interactive startup files - Cleanup of inplace demodulation - Fix typo in toast_run - Fix verbose logging in noise model cuts * Restore hwp helper file * Address review comments
* Detect anomalously low noise detectors * Update src/toast/ops/noise_model.py Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
#871) * Add infrastructure to store additional metadata to HEALPix and WCS headers * Add 0m0.000s 0m0.000s 0m0.000s 0m0.000s to mapmaker * Update src/toast/pixels.py Co-authored-by: Copilot <[email protected]> * Update src/toast/pixels.py Co-authored-by: Copilot <[email protected]> * Fix unit test failures; add time stamp and version to map headers * Use backwards-compatible UTC --------- Co-authored-by: Copilot <[email protected]>
This small change allows serializing the Weather base class to toast HDF5 files.
* User can now coadd noise-weighted matrices without de-weighting * Fix unit test
* Support past, current and future datetime modules * Update src/toast/pixels.py Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
- Parse the timestamp separately - Dump / load all parameters as Quantities - Use the base weather class in one of the unit tests.
* User can now define lists of SSOs and their radii to plot with the hits and background * Update src/toast/scripts/toast_project_schedule.py Co-authored-by: Copilot <[email protected]> * Address copilot findings * Fix small bugs, add labels to the planets --------- Co-authored-by: Copilot <[email protected]>
* Add stdout / stderr redirection to toast_run - Add a new context manager that uses wurlitzer to redirect both python and libc output to a file. Per-process output is written to separate files and then collated at the end. - Use redirection in toast_run so that all output is logged to the top level out_dir. - Several small fixes. * Bump required version of pshmem, to allow use of MPIBatch
* Allow user to disable log redirection * Change disabling of redirect to use a boolean flag * Make no-redirection the default
* Highpass-filter the signal before demodulation * Experiment with bandpass filtering * Use passband rather than highpass filter * Flag pathological detectors * Better help strings * Add operator for rms/skew/kurtosis-based detector cuts * Remove debug statements * Remove debug statement, make error message more informative * When deglitching demodulated data, apply flags to all coupled streams * Fix error in flag mask application * Fix two corner cases in time constant deconvolution * Add a helpful warning message * Add accessor for the detector properties list * Calibrate now looks for gains in the focalplane database when a dictionary is not found in the Observation. It is an error if no gains are found * Demodulation allows adjusting the passband * better trait names * Remove stale code
- Fix bug in parsing internal HDF5 paths of instrument files - Implement writing of ground schedules to enable splitting and writing out schedule files from python. - Rework GroundSchedule I/O to implement ECSV format. - Fix segfault when inverting pixel covariance when some processes have no local pixels. - Add utility script to plot maps and compute pseudo cls from job outputs. - In coadd script, add support for accumulating hits map and also support per-map weights in the input text file.
* Testing wheels for 3.0.0a40 tag * Restore tests and test doc build * Bump python version and mkdocs-jupyter for docs build * Remove stale docs reference * Restore testing
The recent refactor of the TimeConstant operator accidentally swapped the meaning of the deconvolve trait. This fixes that and also adds a unit test to verify that the convolution introduces an expected phase shift.
* Improvements to healpix plotting * Change default colormap to bwr
Simple detrend operator, removing mean/median/slope, with unit test script included. Signed-off-by: Bai-Chiang <[email protected]>
* Clarify per-map noise weights in coaddition * When running tests force spt3g to 1.0.0, which was the last to support macos x86_64 * Apply extra inverse noise weights after we are certain we are working with noise weighted maps
* Add a helper script which creates a fake telescope HDF5 file The SimGround and SimSatellite operators were recently updated to accept a "telescope" file which contains all the instrument and site information to conduct simulations. This work adds a helper script to construct generic telescope files for purely synthetic experiments. * Fix unit tests for MPI case
Hi @zonca and @keskitalo, this PR is for your feedback on API changes that we discussed offline. In addition to looking at the source, I have been updating the
tutorials/01_Introduction/intro.ipynbnotebook as a "look and feel" example. I have attached a rendered version of the notebook:intro.pdf
Main features are:
Observation class as the new data model, with
detdata,shared,intervals, andviewattributes as the key places where the contents are influenced.Improved processing model with changes to the
Operatorclass and the newPipelineoperator. These classes are configured withtraitlets.New distributed map classes (
PixelDistributionandPixelData) which split the calculation of the distribution from the actual data storage. These have the new Alltoallv communication pattern.There are only 2-3 operators that have been ported to the new API as a demo. I'll continue on some config file work that needs to be updated since the switch to traitlets.