vsdm 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vsdm-0.1.0/LICENSE +21 -0
- vsdm-0.1.0/PKG-INFO +41 -0
- vsdm-0.1.0/README.md +21 -0
- vsdm-0.1.0/pyproject.toml +43 -0
- vsdm-0.1.0/setup.cfg +4 -0
- vsdm-0.1.0/vsdm/__init__.py +52 -0
- vsdm-0.1.0/vsdm/analytic.py +202 -0
- vsdm-0.1.0/vsdm/basis.py +591 -0
- vsdm-0.1.0/vsdm/gaussians.py +225 -0
- vsdm-0.1.0/vsdm/matrixcalc.py +498 -0
- vsdm-0.1.0/vsdm/portfolio.py +440 -0
- vsdm-0.1.0/vsdm/projection.py +642 -0
- vsdm-0.1.0/vsdm/ratecalc.py +281 -0
- vsdm-0.1.0/vsdm/units.py +37 -0
- vsdm-0.1.0/vsdm/utilities.py +406 -0
- vsdm-0.1.0/vsdm/wigner.py +102 -0
- vsdm-0.1.0/vsdm.egg-info/PKG-INFO +41 -0
- vsdm-0.1.0/vsdm.egg-info/SOURCES.txt +19 -0
- vsdm-0.1.0/vsdm.egg-info/dependency_links.txt +1 -0
- vsdm-0.1.0/vsdm.egg-info/requires.txt +5 -0
- vsdm-0.1.0/vsdm.egg-info/top_level.txt +1 -0
vsdm-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 blillard
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
vsdm-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: vsdm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Vector space integration for dark matter direct detection
|
|
5
|
+
Author-email: "Ben G. Lillard" <blillard@uoregon.edu>
|
|
6
|
+
Project-URL: Homepage, https://github.com/blillard/vsdm
|
|
7
|
+
Project-URL: Source, https://github.com/blillard/vsdm/
|
|
8
|
+
Project-URL: Documentation, https://github.com/blillard/vsdm/blob/main/README.md
|
|
9
|
+
Classifier: Intended Audience :: Science/Research
|
|
10
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Requires-Python: >=3.7
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: scipy
|
|
16
|
+
Requires-Dist: vegas
|
|
17
|
+
Requires-Dist: h5py
|
|
18
|
+
Requires-Dist: spherical
|
|
19
|
+
Requires-Dist: quaternionic
|
|
20
|
+
|
|
21
|
+
# vsdm
|
|
22
|
+
|
|
23
|
+
By Benjamin Lillard
|
|
24
|
+
|
|
25
|
+
**Vector space dark matter rate calculation**
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
[](https://arxiv.org/abs/2310.01480)
|
|
29
|
+
[](https://arxiv.org/abs/2310.01483)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### DESCRIPTION: ##########################################################
|
|
33
|
+
|
|
34
|
+
VSDM is the Python implementation of the wavelet-harmonic integration method, designed for the efficient calculation of dark matter direct detection scattering rates in anisotropic detectors, and for arbitrary dark matter velocity distributions.
|
|
35
|
+
|
|
36
|
+
The code is still under development. Many of the components have been tested for accuracy, but no guarantee is made for the accuracy of the complete package.
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
vsdm-0.1.0/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# vsdm
|
|
2
|
+
|
|
3
|
+
By Benjamin Lillard
|
|
4
|
+
|
|
5
|
+
**Vector space dark matter rate calculation**
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
[](https://arxiv.org/abs/2310.01480)
|
|
9
|
+
[](https://arxiv.org/abs/2310.01483)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### DESCRIPTION: ##########################################################
|
|
13
|
+
|
|
14
|
+
VSDM is the Python implementation of the wavelet-harmonic integration method, designed for the efficient calculation of dark matter direct detection scattering rates in anisotropic detectors, and for arbitrary dark matter velocity distributions.
|
|
15
|
+
|
|
16
|
+
The code is still under development. Many of the components have been tested for accuracy, but no guarantee is made for the accuracy of the complete package.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "vsdm"
|
|
7
|
+
description = "Vector space integration for dark matter direct detection"
|
|
8
|
+
authors = [
|
|
9
|
+
{name = "Ben G. Lillard", email = "blillard@uoregon.edu"},
|
|
10
|
+
]
|
|
11
|
+
# licence = "MIT"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Intended Audience :: Science/Research",
|
|
15
|
+
"Topic :: Scientific/Engineering :: Physics",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
]
|
|
18
|
+
requires-python = ">=3.7"
|
|
19
|
+
dependencies = [
|
|
20
|
+
"scipy",
|
|
21
|
+
"vegas",
|
|
22
|
+
"h5py",
|
|
23
|
+
"spherical",
|
|
24
|
+
"quaternionic",
|
|
25
|
+
]
|
|
26
|
+
dynamic = ["version"]
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://github.com/blillard/vsdm"
|
|
30
|
+
Source = "https://github.com/blillard/vsdm/"
|
|
31
|
+
Documentation = "https://github.com/blillard/vsdm/blob/main/README.md"
|
|
32
|
+
|
|
33
|
+
[tool.setuptools]
|
|
34
|
+
packages = ["vsdm"]
|
|
35
|
+
|
|
36
|
+
# [tool.setuptools.packages.find]
|
|
37
|
+
# where = ["vsdm"]
|
|
38
|
+
# exclude = ["tools*"]
|
|
39
|
+
|
|
40
|
+
[tool.setuptools.dynamic]
|
|
41
|
+
version = {attr = "vsdm.__version__"}
|
|
42
|
+
|
|
43
|
+
#
|
vsdm-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# __init__.py
|
|
2
|
+
|
|
3
|
+
from . import units
|
|
4
|
+
from . import utilities
|
|
5
|
+
from . import analytic
|
|
6
|
+
from . import gaussians
|
|
7
|
+
from . import portfolio
|
|
8
|
+
from . import basis
|
|
9
|
+
from . import projection
|
|
10
|
+
from . import matrixcalc
|
|
11
|
+
from . import wigner
|
|
12
|
+
from . import ratecalc
|
|
13
|
+
|
|
14
|
+
from .units import *
|
|
15
|
+
from .utilities import *
|
|
16
|
+
from .analytic import *
|
|
17
|
+
from .gaussians import *
|
|
18
|
+
from .portfolio import *
|
|
19
|
+
from .basis import *
|
|
20
|
+
from .projection import *
|
|
21
|
+
from .matrixcalc import *
|
|
22
|
+
# wigner and ratecalc require 'spherical' and 'quaternionic' packages
|
|
23
|
+
from .wigner import *
|
|
24
|
+
from .ratecalc import *
|
|
25
|
+
|
|
26
|
+
__all__ = (units.__all__ + utilities.__all__ + basis.__all__ + wigner.__all__
|
|
27
|
+
+ projection.__all__ + matrixcalc.__all__ + ratecalc.__all__
|
|
28
|
+
+ gaussians.__all__
|
|
29
|
+
+ portfolio.__all__ + analytic.__all__)
|
|
30
|
+
|
|
31
|
+
__version__ = "0.1.0"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
Dependencies: the following packages are required:
|
|
36
|
+
math, time, os.path, csv, sys
|
|
37
|
+
numpy
|
|
38
|
+
scipy
|
|
39
|
+
gvar
|
|
40
|
+
vegas
|
|
41
|
+
quaternionic
|
|
42
|
+
spherical
|
|
43
|
+
h5py
|
|
44
|
+
|
|
45
|
+
Note: spherical and quaternionic packages may require specific
|
|
46
|
+
versions of Python. I have tested with Python 3.7 and 3.9.
|
|
47
|
+
Only .wigner and .ratecalc require 'spherical'.
|
|
48
|
+
- If a user does not need to perform rotations with the WignerG matrices,
|
|
49
|
+
can load 'vsdm' with the following lines commented out:
|
|
50
|
+
# from .wigner import *
|
|
51
|
+
# from .ratecalc import *
|
|
52
|
+
"""
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"""Analytic results for mcalI matrix calculation.
|
|
2
|
+
|
|
3
|
+
Dimensionless integrals of functions of q and v_min(q), as functions
|
|
4
|
+
of x = (q / q_star)**2, for q_star**2 = 2 * omegaS * mX.
|
|
5
|
+
|
|
6
|
+
Functions:
|
|
7
|
+
_t: integral for rectangular volume, [[v1,v2],[q1,q2]]
|
|
8
|
+
_u: integral where v_min(q) sets lower bound, [v_min(q),v2]
|
|
9
|
+
_b: intermediate function for rectangular integral
|
|
10
|
+
_c, _d, _s: intermediate function for non-rectangular integrals (for _u)
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
__all__ = ['mI_star', 't_ln_vq_int', 'u_ln_vq_int',
|
|
14
|
+
'_b_nk_int', '_c_alpha_int', '_s_n_int']
|
|
15
|
+
|
|
16
|
+
import math
|
|
17
|
+
import numpy as np
|
|
18
|
+
import scipy.special as spf
|
|
19
|
+
# import vegas # numeric integration
|
|
20
|
+
# import gvar # gaussian variables; for vegas
|
|
21
|
+
# import time
|
|
22
|
+
# import quaternionic # For rotations
|
|
23
|
+
# import spherical #For Wigner D matrix
|
|
24
|
+
# import csv # file IO for projectFnlm
|
|
25
|
+
# import os.path
|
|
26
|
+
# import h5py # database format for mathcalI arrays
|
|
27
|
+
|
|
28
|
+
# from .units import *
|
|
29
|
+
|
|
30
|
+
def _b_nk_int(n, k, x):
|
|
31
|
+
# x = q^2 / q_*^2.
|
|
32
|
+
assert k-int(k)==0, "'k' should be integer valued"
|
|
33
|
+
k = int(k)
|
|
34
|
+
assert x!=0, "Range in 'x' should not include x=0, even if basis function includes q=0."
|
|
35
|
+
sum = 0.
|
|
36
|
+
for j in range(k+1):
|
|
37
|
+
comb = math.factorial(k) / (math.factorial(j) * math.factorial(k-j))
|
|
38
|
+
ipower = j - n - k/2 + 1
|
|
39
|
+
if ipower==0:
|
|
40
|
+
summand = math.log(x)
|
|
41
|
+
else:
|
|
42
|
+
summand = (x**ipower)/ipower
|
|
43
|
+
sum += comb*summand
|
|
44
|
+
return 0.5*sum
|
|
45
|
+
|
|
46
|
+
def _c_alpha_int(alpha, x):
|
|
47
|
+
# Updated to 'PRD' format
|
|
48
|
+
if alpha==-2:
|
|
49
|
+
return -0.5*math.log( (1+x)/x ) + 0.5/x - 0.125/x**2
|
|
50
|
+
elif alpha==-1:
|
|
51
|
+
return math.log( (1+x)/x ) - 0.5/x
|
|
52
|
+
elif alpha==0:
|
|
53
|
+
return (-0.25*(math.log(x))**2 + math.log(x) * math.log(1 + x)
|
|
54
|
+
+ spf.spence(1 + x))
|
|
55
|
+
elif alpha==1:
|
|
56
|
+
return 0.5*x - math.log(1 + x)
|
|
57
|
+
elif alpha==2:
|
|
58
|
+
return 0.125*x**2 - 0.5*x + 0.5*math.log(1 + x)
|
|
59
|
+
else:
|
|
60
|
+
return x**(alpha)/alpha**2 * (0.5 - spf.hyp2f1(1, alpha, 1 + alpha, -x))
|
|
61
|
+
|
|
62
|
+
def _v_n_int(n, x):
|
|
63
|
+
if n==0:
|
|
64
|
+
return 0.5*math.log(x) + x + 0.25*x**2
|
|
65
|
+
elif n==1:
|
|
66
|
+
return 0.5/x + math.log(x) + 0.5*x
|
|
67
|
+
elif n==2:
|
|
68
|
+
return -0.25/x**2 - 1/x + 0.5*math.log(x)
|
|
69
|
+
else:
|
|
70
|
+
return 0.5*(x**(-n)/(-n)) + x**(-n+1)/(-n+1) + 0.5*x**(-n+2)/(-n+2)
|
|
71
|
+
|
|
72
|
+
def _s_n_int(n, x):
|
|
73
|
+
logfactor = 0.5*math.log(x/(1 + 2*x + x**2))
|
|
74
|
+
return (logfactor*_v_n_int(n, x) + 0.5*_c_alpha_int(-n, x)
|
|
75
|
+
+ _c_alpha_int(1-n, x) + 0.5*_c_alpha_int(2-n, x))
|
|
76
|
+
|
|
77
|
+
def t_ln_vq_int(l, n, v12_star, q12_star):
|
|
78
|
+
"""Rectangular integral T_{l,n}.
|
|
79
|
+
|
|
80
|
+
With [v1,v2] in units of v_star = q_star/mX, [q1,q2] in units of
|
|
81
|
+
q_star = sqrt(2*mX*omegaS).
|
|
82
|
+
|
|
83
|
+
Always v1 >= 1. Also require q1 > 0.
|
|
84
|
+
"""
|
|
85
|
+
assert int(l)-l==0, "'l' must be integer valued"
|
|
86
|
+
l = int(l)
|
|
87
|
+
[v1,v2] = v12_star
|
|
88
|
+
[q1,q2] = q12_star
|
|
89
|
+
x1 = q1**2
|
|
90
|
+
x2 = q2**2
|
|
91
|
+
sum = 0.
|
|
92
|
+
for k in range(l+1):
|
|
93
|
+
term_k = 2**(l-k) * spf.gamma(0.5*(k+1+l)) / spf.gamma(0.5*(k+1-l))
|
|
94
|
+
if k==2:
|
|
95
|
+
termV = math.log(v2/v1) / (2 * math.factorial(l-2))
|
|
96
|
+
termQ = (_b_nk_int(n, 2, x2) - _b_nk_int(n, 2, x1))
|
|
97
|
+
sum += termV*term_k*termQ
|
|
98
|
+
else:
|
|
99
|
+
termV = ((v2**(2-k) - v1**(2-k))
|
|
100
|
+
/ ((2-k)*math.factorial(k)*math.factorial(l-k)))
|
|
101
|
+
termQ = (_b_nk_int(n, k, x2) - _b_nk_int(n, k, x1))
|
|
102
|
+
sum += termV*term_k*termQ
|
|
103
|
+
return sum
|
|
104
|
+
|
|
105
|
+
def u_ln_vq_int(l, n, v2_star, q12_star):
|
|
106
|
+
"""Non-rectangular integral U_{l,n}, with lower bound v1 = v_min(q).
|
|
107
|
+
|
|
108
|
+
With v2 in units of v_star = q_star/mX, [q1,q2] in units of
|
|
109
|
+
q_star = sqrt(2*mX*omegaS).
|
|
110
|
+
"""
|
|
111
|
+
assert int(l)-l==0, "'l' must be integer valued"
|
|
112
|
+
l = int(l)
|
|
113
|
+
v2 = v2_star # only need v2, v1 is irrelevant
|
|
114
|
+
[q1,q2] = q12_star
|
|
115
|
+
x1 = q1**2
|
|
116
|
+
x2 = q2**2
|
|
117
|
+
sum = 0.
|
|
118
|
+
for k in range(l+1):
|
|
119
|
+
term_k = (spf.gamma(0.5*(k+1+l)) / spf.gamma(0.5*(k+1-l))
|
|
120
|
+
* 2**(l-k)/(math.factorial(k) * math.factorial(l-k)))
|
|
121
|
+
if k==2:
|
|
122
|
+
summand = (math.log(2*v2)*_b_nk_int(n, 2, x2) + _s_n_int(n, x2)
|
|
123
|
+
- math.log(2*v2)*_b_nk_int(n, 2, x1) - _s_n_int(n, x1))
|
|
124
|
+
sum += term_k*summand
|
|
125
|
+
else:
|
|
126
|
+
summand = (v2**(2-k)*(_b_nk_int(n, k, x2) - _b_nk_int(n, k, x1))
|
|
127
|
+
- 2**(k-2)*(_b_nk_int(n, 2, x2) - _b_nk_int(n, 2, x1)))
|
|
128
|
+
sum += term_k*summand/(2-k)
|
|
129
|
+
return sum
|
|
130
|
+
|
|
131
|
+
def mI_star(ell, n, v12_star, q12_star):
|
|
132
|
+
"""Dimensionless integral related to MathcalI.
|
|
133
|
+
|
|
134
|
+
This is 'I^{(\ell)}_\star' without the prefactor (qBohr/qStar)**(2n)
|
|
135
|
+
|
|
136
|
+
With v12, q12 in units of vStar, qStar.
|
|
137
|
+
|
|
138
|
+
There are 0, 1, 2 or 3 regions that contribute to mcalI:
|
|
139
|
+
qA < (R1) < qB < (R2) < qC < (R3) < qD.
|
|
140
|
+
R2 is rectangular, bounded by v1 < v < v2. -> t_ln_vq_int
|
|
141
|
+
R1 and R3 are not rectangular: vMin(q) < v < v2. -> u_ln_vq_int
|
|
142
|
+
If vmin(q) > v1 for all q1 < q < q2, then mcalI is given by u_ln_vq_int
|
|
143
|
+
"""
|
|
144
|
+
[v1,v2] = v12_star
|
|
145
|
+
[q1,q2] = q12_star
|
|
146
|
+
if v1==v2 or q1==q2:
|
|
147
|
+
return 0 # No integration volume
|
|
148
|
+
assert q1 < q2, "Need q12 to be ordered"
|
|
149
|
+
assert v1 < v2, "Need v12 to be ordered"
|
|
150
|
+
include_R2 = True
|
|
151
|
+
if v2 < 1:
|
|
152
|
+
# v2 is below the velocity threshold. mcaI=0
|
|
153
|
+
return 0
|
|
154
|
+
tilq_m,tilq_p = v2 - math.sqrt(v2**2-1), v2 + math.sqrt(v2**2-1)
|
|
155
|
+
if tilq_m > q2 or tilq_p < q1:
|
|
156
|
+
# in this case v2 < vmin(q) for all q in [q1,q2]
|
|
157
|
+
return 0
|
|
158
|
+
# Else: there are some q satisfying vmin(q) < v2 in this interval.
|
|
159
|
+
if v1 < 1:
|
|
160
|
+
# There is no v1 = vmin(q) solution for any real q
|
|
161
|
+
include_R2 = False
|
|
162
|
+
# Else: There are two real solutions to v1 = vmin(q)
|
|
163
|
+
else:
|
|
164
|
+
q_m,q_p = v1 - math.sqrt(v1**2-1), v1 + math.sqrt(v1**2-1)
|
|
165
|
+
if q_m > q2 or q_p < q1:
|
|
166
|
+
# in this case v1 < vmin(q) for all q in [q1,q2]
|
|
167
|
+
include_R2 = False
|
|
168
|
+
if include_R2 is False:
|
|
169
|
+
q_A = np.max([q1, tilq_m])
|
|
170
|
+
q_B = np.min([q2, tilq_p])
|
|
171
|
+
return u_ln_vq_int(ell, n, v2, [q_A, q_B])
|
|
172
|
+
# Else: at least part of the integration volume is set by v1 < v.
|
|
173
|
+
q_a = np.max([q1, tilq_m])
|
|
174
|
+
q_b = np.max([q1, q_m]) # q_m > tilq_m iff v2 > v1
|
|
175
|
+
q_c = np.min([q2, q_p]) # q_p < tilq_p iff v2 > v1
|
|
176
|
+
q_d = np.min([q2, tilq_p])
|
|
177
|
+
includeRegion = [True, True, True]
|
|
178
|
+
if q_a==q_b:
|
|
179
|
+
includeRegion[0] = False
|
|
180
|
+
if q_c==q_d:
|
|
181
|
+
includeRegion[2] = False
|
|
182
|
+
if v1>1:
|
|
183
|
+
assert q_b!=q_c, "If q_b==q_c then there should be no R2 region..."
|
|
184
|
+
mI_0,mI_1,mI_2 = 0, 0, 0
|
|
185
|
+
if includeRegion[0]:
|
|
186
|
+
mI_0 = u_ln_vq_int(ell, n, v2, [q_a, q_b])
|
|
187
|
+
if includeRegion[1]:
|
|
188
|
+
mI_1 = t_ln_vq_int(ell, n, [v1,v2], [q_b, q_c])
|
|
189
|
+
if includeRegion[2]:
|
|
190
|
+
mI_2 = u_ln_vq_int(ell, n, v2, [q_c, q_d])
|
|
191
|
+
return mI_0 + mI_1 + mI_2
|
|
192
|
+
#
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
#
|