Skip to content

bowling

Tools for dealing with bowling in maps

jac_potato_grad(pn, p, tods)

Gradient of shitty potato chip (hyperbolic parabaloid) model for removing scan signal from maps Arguments:

pn: Which version of p is passed in, see below for details

p: Parameter vector with entries:

   * A, the overall amplitude
   * c0, an overall offset
   * c1 and c2, linear slopes
   * c3 and c4, parabolic amplitudes
   * theta, a rotation angle

   Acceptable subsets are:

   * (A, c0, c1, c2, c3, c4, theta) for pn = 0
   * (A, c1, c2, c3, c4, theta) for pn = 1
   * (A, c1, c3, c4, theta) for pn = 2
   * (c1, theta) for pn = 3

tods: (x, y) vectors

Returns:

grad: Gradient for this model with respect to p
Source code in witch/bowling.py
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
@partial(jax.jit, static_argnums=(0))
def jac_potato_grad(pn, p, tods):
    """
    Gradient of shitty potato chip (hyperbolic parabaloid) model for removing scan signal from maps
    Arguments:

        pn: Which version of p is passed in, see below for details

        p: Parameter vector with entries:

           * A, the overall amplitude
           * c0, an overall offset
           * c1 and c2, linear slopes
           * c3 and c4, parabolic amplitudes
           * theta, a rotation angle

           Acceptable subsets are:

           * (A, c0, c1, c2, c3, c4, theta) for pn = 0
           * (A, c1, c2, c3, c4, theta) for pn = 1
           * (A, c1, c3, c4, theta) for pn = 2
           * (c1, theta) for pn = 3

        tods: (x, y) vectors

    Returns:

        grad: Gradient for this model with respect to p
    """
    return jax.jacfwd(potato_chip, argnums=0)(pn, p, tods[0], tods[1])

jit_potato_full(pn, p, tods)

Shitty potato chip and its gradient (hyperbolic parabaloid) model for removing scan signal from maps Arguments:

pn: Which version of p is passed in, see below for details

p: Parameter vector with entries:

   * A, the overall amplitude
   * c0, an overall offset
   * c1 and c2, linear slopes
   * c3 and c4, parabolic amplitudes
   * theta, a rotation angle

   Acceptable subsets are:

   * (A, c0, c1, c2, c3, c4, theta) for pn = 0
   * (A, c1, c2, c3, c4, theta) for pn = 1
   * (A, c1, c3, c4, theta) for pn = 2
   * (c1, theta) for pn = 3

tods: (x, y) vectors

Returns:

pred: A vector of values for this model given p at the xi, yi

grad: Gradient for this model with respect to p
Source code in witch/bowling.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
@partial(jax.jit, static_argnums=(0))
def jit_potato_full(pn, p, tods):
    """
    Shitty potato chip and its gradient (hyperbolic parabaloid) model for removing scan signal from maps
    Arguments:

        pn: Which version of p is passed in, see below for details

        p: Parameter vector with entries:

           * A, the overall amplitude
           * c0, an overall offset
           * c1 and c2, linear slopes
           * c3 and c4, parabolic amplitudes
           * theta, a rotation angle

           Acceptable subsets are:

           * (A, c0, c1, c2, c3, c4, theta) for pn = 0
           * (A, c1, c2, c3, c4, theta) for pn = 1
           * (A, c1, c3, c4, theta) for pn = 2
           * (c1, theta) for pn = 3

        tods: (x, y) vectors

    Returns:

        pred: A vector of values for this model given p at the xi, yi

        grad: Gradient for this model with respect to p
    """
    pred = potato_chip(pn, p, tods[0], tods[1])
    grad = jax.jacfwd(potato_chip, argnums=0)(pn, p, tods[0], tods[1])

    return pred, grad

poly(x, c0, c1, c2)

JITed second order polynomial

Arguments:

x: X value(s) of polynomial

c0: 0th order constant

c1: 1st order constant

c2: 2nd order constant

Returns:

poly: Polynomial values at x
Source code in witch/bowling.py
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@partial(jax.jit, static_argnums=(1, 2, 3))
def poly(x, c0, c1, c2):
    """
    JITed second order polynomial

    Arguments:

        x: X value(s) of polynomial

        c0: 0th order constant

        c1: 1st order constant

        c2: 2nd order constant

    Returns:

        poly: Polynomial values at x
    """
    return c0 + c1 * x + c2 * x**2

poly_sub(x, y)

Fit a second order TOD to data. Nominally used to fit out atmosphere.

Inputs: designed to work with

Arguments: x: X values, nominally tod.info['apix'][j]

y: Y values, nominally tod.info['dat_calib'][j] - tod.info['cm']

Returns:

res.x: The best fit parameters in the order c0, c1, c2 for y = c0 + c1*x + c2*x**2
Source code in witch/bowling.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
@jax.jit
def poly_sub(x, y):
    """
    Fit a second order TOD to data.
    Nominally used to fit out atmosphere.

    # Inputs: designed to work with
    Arguments:
        x: X values, nominally tod.info['apix'][j]

        y: Y values, nominally tod.info['dat_calib'][j] - tod.info['cm']

    Returns:

        res.x: The best fit parameters in the order c0, c1, c2 for y = c0 + c1*x + c2*x**2
    """
    # compute the residual function for a 2nd degree poly, using res**2
    poly_resid = lambda p, x, y: jnp.sum(((p[0] + p[1] * x + p[2] * x**2) - y) ** 2)
    p0 = jnp.array([0.1, 0.1, 0.1])
    # minimize the residual
    res = sopt.minimize(poly_resid, p0, args=(x, y), method="BFGS")

    return res.x

potato_chip(pn, p, xi, yi)

A shitty potato chip (hyperbolic parabaloid) model for removing scan signal from maps Arguments:

pn: Which version of p is passed in, see below for details

p: Parameter vector with entries:

   * A, the overall amplitude
   * c0, an overall offset
   * c1 and c2, linear slopes
   * c3 and c4, parabolic amplitudes
   * theta, a rotation angle

   Acceptable subsets are:

   * (A, c0, c1, c2, c3, c4, theta) for pn = 0
   * (A, c1, c2, c3, c4, theta) for pn = 1
   * (A, c1, c3, c4, theta) for pn = 2
   * (c1, theta) for pn = 3

xi: X vector

yi: Y vectors

Returns:

chip: A vector of values for this model given p at the xi, yi
Source code in witch/bowling.py
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
@partial(jax.jit, static_argnums=(0))
def potato_chip(pn, p, xi, yi):
    """
    A shitty potato chip (hyperbolic parabaloid) model for removing scan signal from maps
    Arguments:

        pn: Which version of p is passed in, see below for details

        p: Parameter vector with entries:

           * A, the overall amplitude
           * c0, an overall offset
           * c1 and c2, linear slopes
           * c3 and c4, parabolic amplitudes
           * theta, a rotation angle

           Acceptable subsets are:

           * (A, c0, c1, c2, c3, c4, theta) for pn = 0
           * (A, c1, c2, c3, c4, theta) for pn = 1
           * (A, c1, c3, c4, theta) for pn = 2
           * (c1, theta) for pn = 3

        xi: X vector

        yi: Y vectors

    Returns:

        chip: A vector of values for this model given p at the xi, yi
    """
    if pn == 0:
        A, c0, c1, c2, c3, c4, theta = p
    elif pn == 1:
        A, c1, c2, c3, c4, theta = p
    elif pn == 2:
        A, c1, c3, c4, theta = p
    elif pn == 3:
        c1, theta = p
    else:
        return 0

    x1, x2 = (
        jnp.cos(theta) * xi + yi * jnp.sin(theta),
        -1 * jnp.sin(theta) * xi + jnp.cos(theta) * yi,
    )

    if pn == 0:
        return A * (c0 + c1 * x1 + c2 * x2 + x1**2 / c3 - x2**2 / c4)
    elif pn == 1:
        return A * (1 + c1 * x1 + c2 * x2 + x1**2 / c3 - x2**2 / c4)
    elif pn == 2:
        return A * (c1 * x1 + x1**2 / c3 - x2**2 / c4)
    elif pn == 3:
        return c1 * x1