Here are the things that I put into the package. It took about 45’ to set this up.
1. LICENSE: I just picked one from the menu git provided
2. README.md: auto-generated, at some point we could add a bit of info here
3. .gitignore: tells git which files to ignore, I picked a template, then added a few lines
I put these in the nb
directory. It’s pretty straightforward.
1. orig_nb.ipynb: the original notebook I started from
2. new_nb.ipynb: the version of the notebook I came up
I put this in the piff_syst_plots
directory, as that is the name I wanted to give the the package.
1. core.py: the core classes to keep track of plots made
2. label.py: class to keep plot labels consistent
3. funcs.py: utility functions that are used in making the plots
4. plotters.py: classes that actually make the plots
Because we want to keep track of the version of the code running, I used a mechanism provided py the
setup tools to write a version file _version.py
. Since that file gets autogenerated by the tools I added
it to the .gitignore
file so it doesn’t get tracked by git
.
5. __init__.py: this just imports the `version` from the autogenerated `_version.py` file.
I put the test data in the data
folder.
1. piff_sample_cat.fits: a small catalog with some test data
I made a bin
area for command line scripts:
1 piff_syst_plots: a script to generate plots
We use this to build the package using pip
. It include a few particular things:
1. Declaring where the code lives and what the python package is called:
packages=["piff_syst_plots"],
package_data={"": ["README.md", "LICENSE", "*.npy"]},
2. Stuff for the version tracking
setup_requires=['setuptools_scm', 'setuptools_scm_git_archive'],
use_scm_version={"write_to": "piff_syst_plots/_version.py"},
3. The command line script
scripts=["bin/piff_syst_plots"],
4. The dependencies:
install_requires=[
"matplotlib",
"numpy",
],
I made a docs
area, and used the mechanism that github
provides to turn that into this web documentation.
The idea here is that when you want to add a new plot, all you have to do is make a class that inherits from piff_syst_plots.Plotter
and that implements a couple of things, here is an example:
class PlotStarsPerCCD(Plotter):
"""Plot rough histogram of nstars/CCD
The 'factor' parameter accounts the fact that we are making this plot with
the reserve stars, which are typically 20% of the total, Thus the default value of 5.
"""
default_config = dict(
nbins=70,
factor=5.0,
figsize=(12, 8),
)
def _make_plot(self, cat):
fig = plt.figure(figsize=self.config["figsize"])
_, nstars = np.unique(
np.stack((cat["EXPNUM"], cat["CCDNUM"]), axis=1), axis=0, return_counts=True
)
plt.hist(nstars * self.config["factor"], bins=self.config["nbins"])
plt.xlabel(Labels.nstars)
return fig
This includes 4 things:
1. Declaration of the class, and that it inherits from `Plotter`
2. Docstring, which describes the plot being made
3. Dictionary of configuration parameters and their default values
4. Function to actually make the plot.
I think that is pretty much the minimum amount of stuff that we could expect the user to provide.
Something to note, because I used the __init_subclass__
method to keep track of all the Plotter
classes, so I don’t
have to do anything else to make the rest of the code aware of the plotter.