Simple, extendable framework for loading generic products from disk.
For any questions please reach out to Zach Atkins (email: zatkins@princeton.edu, github: @zatkins2).
Currently:
- from
simonsobs:pixellmnmsis required if you are usingsofindfor any functionality related tomnmsproducts.
All other dependencies (e.g. numpy etc.) are required by packages listed here, especially by pixell.
Clone this repo and install it via pip:
$ pip install path/to/sofindor
$ pip install -e path/to/sofindto see changes to source code automatically updated in your environment.
Users only need to set one environment variable, SOFIND_SYSTEM, corresponding to the name of the cluster they are working on. Supported systems are listed in sofind/systems.py (e.g. della, perlmutter).
All you need in your code is the following (e.g. for the act_dr6v4 data model):
from sofind import DataModel
# use the from_config method to specify the data model at runtime
dm = DataModel.from_config('act_dr6v4')
# a qid is an identifier tag for a dataset, like a detector array
my_qid = 'pa4a'
# have fun
my_default_map_filename = dm.get_map_fn(my_qid, **more_kwargs)
my_el_split_map = dm.read_map(my_qid, subproduct='el_split', el_split='el1')Users should only ever interface with the high-level DataModel class. This class inherits from all implemented sofind products! Available qids for a particular data model or product are available either by following the qids_config entry in the data model config itself (referring to a particular file in sofind/qids) or should be documented for the product (see, e.g., the sofind/products/maps README file).
There are two simple steps:
- Add the system name to
sofind/systems.py - For a given product
.yamlfile, add the location of the product on-disk on that system under thesystem_pathsblock. Of course, this does not add that product to that system in that location; that must happen outsidesofind.
There are four steps:
-
Create a new product folder in the
sofind/productsdirectory. Add to this folder a python module named__init__.py.- There is a minimum prescription your subclass implementation must follow. To make it easy, a template of this implementation (for a product called
HotDog) can be copied fromsofind/products/hotdogs/__init__.py. You should not delete the template class declaration or__init__method (but you may add to them), and you must modify thesofind.products.products.Productmethods decorated with@productmethod. Note the template has more detail on how to implement your product class. You can also look at e.g.sofind.products.maps.Mapfor inspiration. - Anything beyond this minimal perscription can be added if your product has more complicated features!
- There is a minimum prescription your subclass implementation must follow. To make it easy, a template of this implementation (for a product called
-
Make sure your product is imported directly by the
sofind.productspackage. For instance, if your module was namedhotdogsand your particular class namedHotDog, then add this line tosofind.products.__init__.py:from .hotdogs import HotDog
-
Add a config (or multiple configs if you have multiple product versions, or subproducts, etc.) to
sofind/products/{module_name}. Following the hotdog example, there is a config filehotdog_example.yamlinsofind/products/hotdogs.- This must be a
.yamlfile. - You must have a
system_pathsblock. This will have entries for a subset of the available clusters insofind/systems.py. Each entry will point to a path giving the directory on that system in which the product files are located. - You must have an
allowed_qids_configsblock. If your subproduct is agnostic to qids, this can beall; otherwise, it must list the individualqids_configfiles (insofind/qids) that this subproduct may work with. - You must have an
allowed_qidsblock. If your product methods use aqidto provide keywords to filename templates, then the permissibleqid(s) for that product must be listed here. May also beallor left blank if noqid(s) work with your subproduct. For instance, a call toHotDog.read_hotdogwill raise an error ifhotdog_example.yamlis used to configure the callingDataModelinstance and the suppliedqidis not one ofpa4a,pa5a, orpa6a. - You must have an
allowed_qids_extra_kwargsblock. If your template filename requires additional keywords for a givenqidthan are present in anyallowed_qids_configsfiles (seesofind/qids), those keywords would need to be added here. For instance, theact_dr6_default_qids.yamlfile only containsarray,freq,patch, anddaynightkeywords. Thenum_splitskeyword required for thehotdog_file_templateis thus added for each permissible qid directly inhotdog_example.yaml, e.g.:Theallowed_qids_extra_kwargs: pa6a: num_splits: 8
allowed_qids_extra_kwargsblock may be empty if there are no extra keywords to add for any of theallowed_qids. - This should contain any information to help get filenames for your product or load them from disk, such as a template filename. For instance, given a set of keyword arguments
array='pa6', freq='f090', num_splits=8, condiment='mustard', thehotdog_file_templatestring inhotdog_example.yamlwould format topa6_f090_8way_mustard.txt(the actual formatting would occur in yourHotDogclass'sget_hotdog_fnmethod).
- This must be a
-
Clearly document product implementations and product configs. For example, see the docstrings in the
Mapclass (sofind/products/maps/__init__.py) as well as themapsreadme (sofind/products/maps/README.md).
Please commit and push your contribution to a new branch and open a PR on github! If you are updating an old config, please include it under a new file altogether so that historical products may still be loaded at runtime.
There are one (maybe two) steps:
- Create a new data model config in
sofind/datamodels.- This config must have a block for each product this data model will load. Note, it is not necessary to have a block for every product in
sofind, only those that will be functional in this data model. The same goes for subproducts of a product -- include only those that will be functional in this data model. To add a subproduct, include an entry under the associated product block like:whereprod: subprod_config: config.yaml
prodandsubprodare the names of the product and subproduct that may be called by theDataModel. - This config file must also have an entry for a
qids_config(at the top-level), indicating one of the qid config files undersofind/qids.
- This config must have a block for each product this data model will load. Note, it is not necessary to have a block for every product in
- Only if one of the included qid config files are not sufficient for your needs, you'll need to add another one with your qids.
Please commit and push your contribution to a new branch and open a PR on github! If you are updating an old config, please include it under a new file altogether so that historical products may still be loaded at runtime.