diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..046a28181 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Module", + "type": "python", + "request": "launch", + "module": "pint" + }, + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..0f512ca74 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "C:\\Users\\A\\anaconda3\\envs\\pinttest\\python.exe" +} \ No newline at end of file diff --git a/paper/Makefile b/paper/Makefile new file mode 100644 index 000000000..a61f2efd2 --- /dev/null +++ b/paper/Makefile @@ -0,0 +1,11 @@ +all: paper.pdf + +paper.pdf: paper.md paper.bib latex.template + pandoc --filter pandoc-citeproc --bibliography paper.bib paper.md \ + --template latex.template -o paper.pdf \ + --pdf-engine=xelatex + +clean: + rm paper.pdf + +.PHONY: clean diff --git a/paper/latex.template b/paper/latex.template new file mode 100644 index 000000000..d265e2a89 --- /dev/null +++ b/paper/latex.template @@ -0,0 +1,377 @@ +% Taken from MIT licensed `whedon` repository, Copyright (c) 2016 Open Journals +% https://github.com/openjournals/whedon/ +\documentclass[10pt,a4paper,onecolumn]{article} +\usepackage{marginnote} +\usepackage{graphicx} +\usepackage{xcolor} +\usepackage{authblk,etoolbox} +\usepackage{titlesec} +\usepackage{calc} +\usepackage{tikz} +\usepackage{hyperref} +\usepackage{caption} +\usepackage{tcolorbox} +\usepackage{amssymb,amsmath} +\usepackage{ifxetex,ifluatex} +\usepackage{seqsplit} +\usepackage{fixltx2e} % provides \textsubscript +\usepackage[ + backend=biber, +% style=alphabetic, +% citestyle=numeric +]{biblatex} +\bibliography{$bibliography$} + + +% --- Page layout ------------------------------------------------------------- +\usepackage[top=3.5cm, bottom=3cm, right=1.5cm, left=1.0cm, + headheight=2.2cm, reversemp, includemp, marginparwidth=4.5cm]{geometry} + +% --- Default font ------------------------------------------------------------ +% \renewcommand\familydefault{\sfdefault} + +% --- Style ------------------------------------------------------------------- +\renewcommand{\bibfont}{\small \sffamily} +\renewcommand{\captionfont}{\small\sffamily} +\renewcommand{\captionlabelfont}{\bfseries} + +% --- Section/SubSection/SubSubSection ---------------------------------------- +\titleformat{\section} + {\normalfont\sffamily\Large\bfseries} + {}{0pt}{} +\titleformat{\subsection} + {\normalfont\sffamily\large\bfseries} + {}{0pt}{} +\titleformat{\subsubsection} + {\normalfont\sffamily\bfseries} + {}{0pt}{} +\titleformat*{\paragraph} + {\sffamily\normalsize} + + +% --- Header / Footer --------------------------------------------------------- +\usepackage{fancyhdr} +\pagestyle{fancy} +\fancyhf{} +%\renewcommand{\headrulewidth}{0.50pt} +\renewcommand{\headrulewidth}{0pt} +%\fancyhead[L]{\hspace{-0.75cm}\includegraphics[width=5.5cm]{$joss_logo_path$}} +\fancyhead[C]{} +\fancyhead[R]{} +\renewcommand{\footrulewidth}{0.25pt} + +\fancyfoot[L]{\footnotesize{\sffamily $citation_author$, ($year$). $paper_title$. \textit{Journal of Open Source Software}, $volume$($issue$), $page$, \href{https://doi.org/$formatted_doi$}{doi:$formatted_doi$}}} + + +\fancyfoot[R]{\sffamily \thepage} +\makeatletter +\let\ps@plain\ps@fancy +\fancyheadoffset[L]{4.5cm} +\fancyfootoffset[L]{4.5cm} + +% --- Macros --------- + +\definecolor{linky}{rgb}{0.0, 0.5, 1.0} + +\newtcolorbox{repobox} + {colback=red, colframe=red!75!black, + boxrule=0.5pt, arc=2pt, left=6pt, right=6pt, top=3pt, bottom=3pt} + +\newcommand{\ExternalLink}{% + \tikz[x=1.2ex, y=1.2ex, baseline=-0.05ex]{% + \begin{scope}[x=1ex, y=1ex] + \clip (-0.1,-0.1) + --++ (-0, 1.2) + --++ (0.6, 0) + --++ (0, -0.6) + --++ (0.6, 0) + --++ (0, -1); + \path[draw, + line width = 0.5, + rounded corners=0.5] + (0,0) rectangle (1,1); + \end{scope} + \path[draw, line width = 0.5] (0.5, 0.5) + -- (1, 1); + \path[draw, line width = 0.5] (0.6, 1) + -- (1, 1) -- (1, 0.6); + } + } + +% --- Title / Authors --------------------------------------------------------- +% patch \maketitle so that it doesn't center +\patchcmd{\@maketitle}{center}{flushleft}{}{} +\patchcmd{\@maketitle}{center}{flushleft}{}{} +% patch \maketitle so that the font size for the title is normal +\patchcmd{\@maketitle}{\LARGE}{\LARGE\sffamily}{}{} +% patch the patch by authblk so that the author block is flush left +\def\maketitle{{% + \renewenvironment{tabular}[2][] + {\begin{flushleft}} + {\end{flushleft}} + \AB@maketitle}} +\makeatletter +\renewcommand\AB@affilsepx{ \protect\Affilfont} +%\renewcommand\AB@affilnote[1]{{\bfseries #1}\hspace{2pt}} +\renewcommand\AB@affilnote[1]{{\bfseries #1}\hspace{3pt}} +\makeatother +\renewcommand\Authfont{\sffamily\bfseries} +\renewcommand\Affilfont{\sffamily\small\mdseries} +\setlength{\affilsep}{1em} + + +\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex + \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc} + \usepackage[utf8]{inputenc} + +\else % if luatex or xelatex + \ifxetex + \usepackage{mathspec} + \else + \usepackage{fontspec} + \fi + \defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase} + +\fi +% use upquote if available, for straight quotes in verbatim environments +\IfFileExists{upquote.sty}{\usepackage{upquote}}{} +% use microtype if available +\IfFileExists{microtype.sty}{% +\usepackage{microtype} +\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts +}{} + +\usepackage{hyperref} +$if(colorlinks)$ +\PassOptionsToPackage{usenames,dvipsnames}{color} % color is loaded by hyperref +$endif$ +\hypersetup{unicode=true, +$if(title-meta)$ + pdftitle={$title-meta$}, +$endif$ +$if(author-meta)$ + pdfauthor={$author-meta$}, +$endif$ +$if(keywords)$ + pdfkeywords={$for(keywords)$$keywords$$sep$; $endfor$}, +$endif$ +$if(colorlinks)$ + colorlinks=true, + linkcolor=$if(linkcolor)$$linkcolor$$else$Maroon$endif$, + citecolor=$if(citecolor)$$citecolor$$else$Blue$endif$, + urlcolor=$if(urlcolor)$$urlcolor$$else$Blue$endif$, +$else$ + pdfborder={0 0 0}, +$endif$ + breaklinks=true} +\urlstyle{same} % don't use monospace font for urls +$if(lang)$ +\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex + \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel} +$if(babel-newcommands)$ + $babel-newcommands$ +$endif$ +\else + \usepackage{polyglossia} + \setmainlanguage[$polyglossia-lang.options$]{$polyglossia-lang.name$} +$for(polyglossia-otherlangs)$ + \setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$} +$endfor$ +\fi +$endif$ +$if(natbib)$ +\usepackage{natbib} +\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$} +$endif$ +$if(biblatex)$ +\usepackage$if(biblio-style)$[style=$biblio-style$]$endif${biblatex} +$if(biblatexoptions)$\ExecuteBibliographyOptions{$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$}$endif$ +$for(bibliography)$ +\addbibresource{$bibliography$} +$endfor$ +$endif$ +$if(listings)$ +\usepackage{listings} +$endif$ +$if(lhs)$ +\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} +$endif$ +$if(highlighting-macros)$ +$highlighting-macros$ +$endif$ +$if(verbatim-in-note)$ +\usepackage{fancyvrb} +\VerbatimFootnotes % allows verbatim text in footnotes +$endif$ +$if(tables)$ +\usepackage{longtable,booktabs} +$endif$ +$if(graphics)$ +\usepackage{graphicx,grffile} +\makeatletter +\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} +\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} +\makeatother +% Scale images if necessary, so that they will not overflow the page +% margins by default, and it is still possible to overwrite the defaults +% using explicit options in \includegraphics[width, height, ...]{} +\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} +$endif$ +$if(links-as-notes)$ +% Make links footnotes instead of hotlinks: +\renewcommand{\href}[2]{#2\footnote{\url{#1}}} +$endif$ +$if(strikeout)$ +\usepackage[normalem]{ulem} +% avoid problems with \sout in headers with hyperref: +\pdfstringdefDisableCommands{\renewcommand{\sout}{}} +$endif$ +$if(indent)$ +$else$ +\IfFileExists{parskip.sty}{% +\usepackage{parskip} +}{% else +\setlength{\parindent}{0pt} +\setlength{\parskip}{6pt plus 2pt minus 1pt} +} +$endif$ +\setlength{\emergencystretch}{3em} % prevent overfull lines +\providecommand{\tightlist}{% + \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} +$if(numbersections)$ +\setcounter{secnumdepth}{5} +$else$ +\setcounter{secnumdepth}{0} +$endif$ +$if(subparagraph)$ +$else$ +% Redefines (sub)paragraphs to behave more like sections +\ifx\paragraph\undefined\else +\let\oldparagraph\paragraph +\renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}} +\fi +\ifx\subparagraph\undefined\else +\let\oldsubparagraph\subparagraph +\renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}} +\fi +$endif$ +$if(dir)$ +\ifxetex + % load bidi as late as possible as it modifies e.g. graphicx + $if(latex-dir-rtl)$ + \usepackage[RTLdocument]{bidi} + $else$ + \usepackage{bidi} + $endif$ +\fi +\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex + \TeXXeTstate=1 + \newcommand{\RL}[1]{\beginR #1\endR} + \newcommand{\LR}[1]{\beginL #1\endL} + \newenvironment{RTL}{\beginR}{\endR} + \newenvironment{LTR}{\beginL}{\endL} +\fi +$endif$ +$for(header-includes)$ +$header-includes$ +$endfor$ + +$if(title)$ +\title{$title$$if(thanks)$\thanks{$thanks$}$endif$} +$endif$ +$if(subtitle)$ +\providecommand{\subtitle}[1]{} +\subtitle{$subtitle$} +$endif$ + +$if(authors)$ + $for(authors)$ + $if(authors.affiliation)$ + \author[$authors.affiliation$]{$authors.name$} + $else$ + \author{$authors.name$} + $endif$ + $endfor$ +$endif$ + +$if(affiliations)$ + $for(affiliations)$ + \affil[$affiliations.index$]{$affiliations.name$} + $endfor$ +$endif$ +\date{\vspace{-5ex}} + +\begin{document} +$if(title)$ +\maketitle +$endif$ +$if(abstract)$ +\begin{abstract} +$abstract$ +\end{abstract} +$endif$ + +\marginpar{ + %\hrule + \sffamily\small + + {\bfseries DOI:} \href{https://doi.org/$formatted_doi$}{\color{linky}{$formatted_doi$}} + + \vspace{2mm} + + {\bfseries Software} + \begin{itemize} + \setlength\itemsep{0em} + \item \href{$review_issue_url$}{\color{linky}{Review}} \ExternalLink + \item \href{$repository$}{\color{linky}{Repository}} \ExternalLink + \item \href{$archive_doi$}{\color{linky}{Archive}} \ExternalLink + \end{itemize} + + \vspace{2mm} + {\bfseries Licence}\\ + Authors of JOSS papers retain copyright and release the work under a Creative Commons Attribution 4.0 International License (\href{http://creativecommons.org/licenses/by/4.0/}{\color{linky}{CC-BY}}). +} + +$for(include-before)$ +$include-before$ + +$endfor$ +$if(toc)$ +{ +$if(colorlinks)$ +\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$black$endif$} +$endif$ +\setcounter{tocdepth}{$toc-depth$} +\tableofcontents +} +$endif$ +$if(lot)$ +\listoftables +$endif$ +$if(lof)$ +\listoffigures +$endif$ +$body$ + +$if(natbib)$ +$if(bibliography)$ +$if(biblio-title)$ +$if(book-class)$ +\renewcommand\bibname{$biblio-title$} +$else$ +\renewcommand\refname{$biblio-title$} +$endif$ +$endif$ +\bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$} + +$endif$ +$endif$ +$if(biblatex)$ +\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$ + +$endif$ +$for(include-after)$ +$include-after$ + +$endfor$ +\end{document} diff --git a/paper/paper.bib b/paper/paper.bib new file mode 100644 index 000000000..4a905b0cd --- /dev/null +++ b/paper/paper.bib @@ -0,0 +1,45 @@ +@article{ astropy_journal, + author = {{The Astropy Collaboration} and {Robitaille, Thomas P.} and {Tollerud, Erik J.} and {Greenfield, Perry} and {Droettboom, Michael} and {Bray, Erik} and {Aldcroft, Tom} and {Davis, Matt} and {Ginsburg, Adam} and {Price-Whelan, Adrian M.} and {Kerzendorf, Wolfgang E.} and {Conley, Alexander} and {Crighton, Neil} and {Barbary, Kyle} and {Muna, Demitri} and {Ferguson, Henry} and {Grollier, Frédéric} and {Parikh, Madhura M.} and {Nair, Prasanth H.} and {Günther, Hans M.} and {Deil, Christoph} and {Woillez, Julien} and {Conseil, Simon} and {Kramer, Roban} and {Turner, James E. H.} and {Singer, Leo} and {Fox, Ryan} and {Weaver, Benjamin A.} and {Zabalza, Victor} and {Edwards, Zachary I.} and {Azalee Bostroem, K.} and {Burke, D. J.} and {Casey, Andrew R.} and {Crawford, Steven M.} and {Dencheva, Nadia} and {Ely, Justin} and {Jenness, Tim} and {Labrie, Kathleen} and {Lim, Pey Lian} and {Pierfederici, Francesco} and {Pontzen, Andrew} and {Ptak, Andy} and {Refsdal, Brian} and {Servillat, Mathieu} and {Streicher, Ole}}, + title = {Astropy: A community Python package for astronomy}, + DOI= "10.1051/0004-6361/201322068", + url= "https://doi.org/10.1051/0004-6361/201322068", + journal = {A&A}, + year = 2013, + volume = 558, + pages = "A33", + month = "", +} +@article{700_units, title={The next 700 unit of measurement checkers}, DOI={10.1145/3276604.3276613}, journal={Proceedings of the 11th ACM SIGPLAN International Conference on Software Language Engineering}, author={Bennich-Björkman, Oscar and McKeever, Steve}, year={2018}, month={Oct}} +@article{unyt_journal, doi = {10.21105/joss.00809}, url = {https://doi.org/10.21105/joss.00809}, year = {2018}, publisher = {The Open Journal}, volume = {3}, number = {28}, pages = {809}, author = {Nathan J. Goldbaum and John A. ZuHone and Matthew J. Turk and Kacper Kowalik and Anna L. Rosen}, title = {unyt: Handle, manipulate, and convert data with units in Python}, journal = {Journal of Open Source Software} } +@misc{pint_pandas, + author = {{H. Grecco}, {A. Savage}, {Z Nicholls} and {M. Tiemann}}, + title = {pint-pandas: Extend Pandas Dataframe with Physical quantities}, + year = {2020}, + publisher = {GitHub}, + journal = {GitHub repository}, + url = {https://github.com/hgrecco/pint-pandas} +} +@misc{pint_xarray, + author = {T. Nicholas}, + title = {pint-xarray: Physical units interface to xarray using Pint}, + year = {2020}, + publisher = {GitHub}, + journal = {GitHub repository}, + url = {https://github.com/xarray-contrib/pint-xarray} +} +@misc{uncertainties, + author = {E. Lebigot}, + title = {Uncertainties: a Python package for calculations with uncertainties}, + year = {2010}, + publisher = {GitHub}, + journal = {GitHub repository}, + url = {https://github.com/lmfit/uncertainties} +} +@misc{babel, + author = {The Babel Team}, + title = {Babel: A collection of tools for internationalizing Python applications.}, + year = {2007}, + publisher = {GitHub}, + journal = {GitHub repository}, + url = {https://github.com/python-babel/babel} +} diff --git a/paper/paper.md b/paper/paper.md new file mode 100644 index 000000000..9dc196f43 --- /dev/null +++ b/paper/paper.md @@ -0,0 +1,91 @@ +--- +title: 'Pint: Operate and manipulate physical quantities in Python' +tags: + - units + - python +authors: + - name: Hector Grecco + orcid: --- + affiliation: + - name: Jules Chéron + orcid: --- + affiliation: + - name: Author Cherry + orcid: --- + affiliation: +affiliations: + - name: Institute 1 + index: 1 + - name: Institute 2 + index: 2 +date: TBD +bibliography: paper.bib +output: pdf_document +--- + +# Summary + +Pint is a Python package to define, operate and manipulate physical quantities: the product of a numerical value and a unit of measurement. It allows arithmetic operations between them and conversions from and to different units. + +It is distributed with a comprehensive list of physical units, prefixes and constants that can be extended or rewritten without changing the source code. Pint natively supports Numpy and uncertainties, and additional modules for pandas and xarray integrations. + +# Statement of need + +Python is commonly used for scientific data analysis but does not natively provide unit support. Pint provides Quantity objects that store numeric data such as ints, floats or arrays and their units, and propogates or converts units when performing arithmetic operations. This removes the need for researchers to keep track of units and conversion factors, significantly simplifying numerical analysis and reducing the likelihood of errors. + +Pint and astropy.units [@astropy_journal] are the two widely used python units libraries. [@700_units] Both are mature libraries with over 10 years of development. Unyt [@unyt_journal] is a relatively new library using sympy. All three libraries have similar core functionality. Pint's main advantages are its simple unit definition file, and integrations with Pandas, Xarray and uncertainties. + +## Key features + +### Unit parsing + +Prefixed and pluralized forms of units are recognized without explicitly defining them. In other words: as the prefix kilo and the unit meter are defined, Pint understands kilometers. This results in a much shorter and maintainable unit definition list as compared to other packages. + +### Standalone unit definitions + +Units definitions are loaded from a text file which is simple and easy to edit. Adding and changing units and their definitions does not involve changing the code. The default file contains over 600 commonly used constants, units and abbreviations. Units can also be defined programatically. + +### Advanced string formatting + +A quantity can be formatted into string using PEP 3101 syntax. Extended conversion flags are given to provide symbolic, LaTeX and pretty formatting. Unit name translation is available if Babel [@babel] is installed. + +### Dimensionality checking + +Pint detects operations on quantities that do not make physcial sense and raises a `DimensionalityError`. Examples include adding a length to a mass, or taking the exponential of a quantity which is not dimensionless. + +### Temperature & sound units. + +Pint handles conversion between units with different reference points, like positions on a map or absolute temperature scales. Logarathimic units, such as for sound pressure level (SPL), are also supported. Pint handles arithmetic operations for these units and prevents potential errors when operations are ambiguous by raising an OffsetUnitCalculusError. For example, when adding 10 °C + 100 °C two different result are reasonable depending on the context, 110 °C or 383.15 °C. + +### Native integration with NumPy, matplotlib and uncertainties + +NumPy ndarrays can be used as the numerical value of a quantity, and its methods and ufuncs are supported including automatic conversion of units. For example numpy.arccos(q) will require a dimensionless q and the units of the output quantity will be radian. + +Matplotlib is a comprehensive library for creating static, animated, and interactive visualizations. [https://matplotlib.org/stable/] Pint supports matplotlib's unit API, which automatically labels plot axes with units and converts plotted data to consitent units. + +The uncertainties package takes the pain and complexity out of uncertainty calculations. [@uncertainties] Pint provides `Measurement` objects to propogate units and uncertainty in calculations. + +### Integrations for pandas and Xarray + +pint-pandas [@pint_pandas] provides integration with pandas, 'a fast, powerful, flexible and easy to use open source data analysis and manipulation tool' [pandas.pydata.org] and pint-xarray[@pint_xarray] provides integration with xarray, which 'makes working with labelled multi-dimensional arrays in Python simple, efficient, and fun!' [https://docs.xarray.dev/en/stable/] + + +### Contexts + +Contexts allow conversion between quantities of incompatable dimensions based on some pre-established (physical) relationships. For example, in spectroscopy you need to convert from wavelength ([length]) to frequency ([1/time]), but this will fail due to the different dimensions. A context containing the relation 'frequency = speed_of_light / wavelength' can be used for this conversion. + +### Systems + +The units used to define dimensions are the 'base units', and pint provides a function to convert a quantity to its base units. Pint allows the base units to be changed through Systems, which are a group of units. A researcher can change the System to another System, such as cgs, imperial, atomic or Planck, which may be more desirable than using mks, or they may define their a custom system of units. + +## Publications using Pint + +To be written in full (there are likely heaps): + +- pymagicc +- openscm +- fair (?) + +# References + +- software archive