Skip to content

TG43

Class defining the TG43 simulation based on the selected brachy seed

Source code in pygrpm/tg43/seed.py
 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
122
123
124
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
155
156
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
class Seed:
    """
    Class defining the TG43 simulation based on the selected brachy seed
    """

    def __init__(self, dirname: str) -> None:
        """
        Construct a TG43 source object.

        The two top level functions are `line` and `point` that implement the
        line-formalism and point-formalism TG43.

        Some sources are already defined in the sources.py file. A new source
        can be initialized with the datafile, the source length and the dose
        rate constant.

        `dirname`: the datafile directory name
        """
        # find the absolute path of the data directory
        path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", dirname)
        if not os.path.isdir(path):
            raise SourceDataNotFound(path)

        # The length of the source
        self.L = np.loadtxt(os.path.join(path, "L.dat"))

        # The dose rate constant of the source
        self.Lambda = np.loadtxt(os.path.join(path, "Lambda.dat"))

        # The function gL
        gL = np.loadtxt(os.path.join(path, "gL.dat")).T
        self.gL = xr.DataArray(gL[1], dims=["r"], coords=[gL[0]])

        # The function F
        F = np.loadtxt(os.path.join(path, "F.dat"))
        self.F = xr.DataArray(
            F[1:, 1:].T, dims=["r", "theta"], coords=[F[0, 1:], F[1:, 0]]
        )

        # the function phi
        if os.path.isfile(os.path.join(path, "phi.dat")):
            phi = np.loadtxt(os.path.join(path, "phi.dat")).T
            self.phi = xr.DataArray(phi[1], dims=["r"], coords=[phi[0]])
        else:
            self.phi = self.F.mean(dim="theta")

        self._GL0 = self._beta(1, np.radians(90)) / self.L
        self.decimals_r = 1

    def _beta(self, r, theta):
        """
        Implementation of the beta function used in the geometric function (GL).
        """
        L = self.L
        L24 = (L**2) / 4
        theta1 = np.pi - theta
        beta = np.arcsin(
            (L / 2) * np.sin(theta) / np.sqrt(r**2 + L24 - r * L * np.cos(theta))
        ) + np.arcsin(
            (L / 2) * np.sin(theta1) / np.sqrt(r**2 + L24 - r * L * np.cos(theta1))
        )
        return beta

    def _GL(self, r, theta):
        rad_theta = np.radians(theta)
        GL_array = self._beta(r, rad_theta) / (self.L * r * np.sin(rad_theta))
        GL_array = GL_array.where(theta != 0, 1 / (r**2 - (self.L**2) / 4))
        GL_array = GL_array.where(theta != 180, 1 / (r**2 - (self.L**2) / 4))
        GL_array = GL_array.where(r != 0, np.nan)
        return GL_array

    def _dose(self, r, theta):
        """
        Internal method to perform dose calculation at the given point
        """
        return (
            self.Lambda
            * (self._GL(r, theta) / self._GL0)
            * self.gL.interp(r=r)
            * self.F.interp(r=r, theta=theta)
        )

    def dose(
        self, r: Union[Sequence, float], theta: Union[Sequence, float]
    ) -> xr.DataArray:
        """
        Returns the dose for each given point. If multiple points of r and theta are
        provided all cross values wil be returned.

        :param Union[Sequence, float] r: A sequence or scalar of radius values
        :param Union[Sequence, float] theta: A sequence or scalar of angle values

        :return DataArray: A DataArray of doses for each provided points
        """
        r_arr = np.array(r, ndmin=1)
        theta_arr = np.array(theta, ndmin=1)
        r_xarr = xr.DataArray(r_arr, dims=["r"], coords=[r_arr])
        theta_xarr = xr.DataArray(theta_arr, dims=["theta"], coords=[theta_arr])
        return self._dose(r_xarr, theta_xarr)

    # pylint: disable=R0913
    # Can't really bypass this many arguments
    def grid(
        self,
        boxmin: Union[Sequence, float] = -10,
        boxmax: Union[Sequence, float] = 10,
        voxsize=0.1,
        sourcepos: Union[Sequence, float] = 0,
        orientation: Sequence = (0, 0, 1),
    ) -> xr.DataArray:
        """
        Method to compute a 3D dosimetric grid for this brachy seed

        :param Union[Sequence, float] boxmin: Minimum coordinate value (along all axes)
        of the container box
        :param Union[Sequence, float] boxmax: Maximum coordinate value (along all axes)
        of the container box
        :param float voxsize: Voxel size of the container box
        :param Union[Sequence, float] sourcepos: Position of the source within the container box
        :param Sequence orientation: Sequence of float detailing source orientation in the box

        :return DataArray: A dataArray with the 3D dosimetric grid information
        """
        boxmin = _coords3d(boxmin)
        boxmax = _coords3d(boxmax)
        voxsize = _coords3d(voxsize)
        sourcepos = _coords3d(sourcepos)
        orientation = _coords3d(orientation)

        # np.arange accumulates the floating point error. Here, the error is
        # kept as small as possible.
        x = (
            boxmin[0]
            - sourcepos[0]
            + np.arange(0, boxmax[0] - boxmin[0] + voxsize[0], voxsize[0])
        )
        y = (
            boxmin[1]
            - sourcepos[1]
            + np.arange(0, boxmax[1] - boxmin[1] + voxsize[1], voxsize[1])
        )
        z = (
            boxmin[2]
            - sourcepos[2]
            + np.arange(0, boxmax[2] - boxmin[2] + voxsize[2], voxsize[2])
        )

        x = xr.DataArray(x, dims=["x"], coords=[x])
        y = xr.DataArray(y, dims=["y"], coords=[y])
        z = xr.DataArray(z, dims=["z"], coords=[z])

        r, theta = _get_sphere_coords(x, y, z)

        grid = self._dose(r, theta)
        grid = grid.drop_vars(["r", "theta"])
        grid = grid.assign_coords(
            x=(grid.x + sourcepos[0]),
            y=(grid.y + sourcepos[1]),
            z=(grid.z + sourcepos[2]),
        )

        return grid

    @domain
    def get_mean(self, array: xr.DataArray) -> xr.DataArray:
        """
        For a given dosimetric grid, obtain an array of mean values along the radius
        :param DataArray array: DataArray representing the dosimetric grid, such as that
        obtained from Seed.grid()
        :return DataArray: Mean dose value for values of radius
        """
        array90 = array.interp(z=0)
        r, _ = _get_sphere_coords(array90.x, array90.y, array90.z)
        array90["r"] = r.round(decimals=self.decimals_r)
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", category=RuntimeWarning)
            a = array90.groupby("r").mean()
        return a

    @domain
    def get_std(self, array: xr.DataArray) -> xr.DataArray:
        """
        For a given dosimetric grid, obtain an array of standard deviation values along the radius
        :param DataArray array: DataArray representing the dosimetric grid, such as that
        obtained from Seed.grid()
        :return DataArray: Standard deviation of dose value for values of radius
        """
        array90 = array.interp(z=0)
        r, _ = _get_sphere_coords(array90.x, array90.y, array90.z)
        array90["r"] = r.round(decimals=self.decimals_r)
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", category=RuntimeWarning)
            a = array90.groupby("r").std()
        return a

    @domain
    def get_cv(self, array: xr.DataArray) -> xr.DataArray:
        """
        For a given dosimetric grid, obtain an array of coefficients of variation
        values along the radius
        :param DataArray array: DataArray representing the dosimetric grid, such as that
        obtained from Seed.grid()
        :return DataArray: Standard deviation of dose value for values of radius
        """
        array90 = array.interp(z=0)
        r, _ = _get_sphere_coords(array90.x, array90.y, array90.z)
        array90["r"] = r.round(decimals=self.decimals_r)
        array90_groupby_r = array90.groupby("r")
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", category=RuntimeWarning)
            mean = array90_groupby_r.mean()
            std = array90_groupby_r.std()
        return std / abs(mean)

    @domain
    def get_gL(self, array: xr.DataArray) -> xr.DataArray:
        """
        For a given dosimetric grid, obtain an array of Geometry function (for line source)
        values along the radius
        :param DataArray array: DataArray representing the dosimetric grid, such as that
        obtained from Seed.grid()
        :return DataArray: Standard deviation of dose value for values of radius
        """
        array90 = array.interp(z=0)
        r, theta = _get_sphere_coords(array90.x, array90.y, array90.z)
        array90 *= self._GL0 / self._GL(r, theta)
        array90["r"] = r.round(decimals=self.decimals_r)
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", category=RuntimeWarning)
            a = array90.groupby("r").mean()
        return a / a.sel(r=1)

    @domain
    def get_F(self, array: xr.DataArray, R: float) -> xr.DataArray:
        """
        Obtain the Anisotropic function in terms of angles for a given radius R.
        Values are normalized by F(r, theta=90)
        :param DataArray array: DataArray representing the dosimetric grid, such as that
        obtained from Seed.grid()
        :param float R: Radius value for the anisotropic function
        :return DataArray: Anisotropic function in terms of theta (0 to 180)
        """
        r, theta = _get_sphere_coords(array.x, array.y, array.z)
        new_arr = array * self._GL0 / self._GL(r, theta)
        s = np.linspace(-R, R, 101)
        new_arr = new_arr.interp(x=s, y=s, z=s)
        r, theta = _get_sphere_coords(new_arr.x, new_arr.y, new_arr.z)
        new_arr["r"] = r.round(decimals=self.decimals_r)
        new_arr["theta"] = theta.round()
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", category=RuntimeWarning)
            a = new_arr.where(new_arr.r == R).groupby("theta").mean()
        return a / a.sel(theta=90)

    def get_calibration(
        self, array: xr.DataArray, significant_figures: int = 5
    ) -> float:
        """
        Returns the calibration factor based on internal or provided Lambda values.
        Function returns Lambda divided by the mean value of array at r=1 to the specified
        amount of significant figures
        :param DataArray array: DataArray representing the dosimetric grid, such as that
        obtained from Seed.grid()
        :param float significant_figures: Desired significant figures for returned value
        :return float: The calibration factor to apply to the provided grid
        """
        array90 = array.interp(z=0)
        r, _ = _get_sphere_coords(array90.x, array90.y, array90.z)
        array90["r"] = r.round(decimals=3)
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", category=RuntimeWarning)
            a = array90.groupby("r").mean()
        print(a.sel(r=1).values)
        C = self.Lambda / a.sel(r=1).values
        C = np.around(C, decimals=significant_figures - int(np.log10(C)))
        return C

__init__(dirname)

Construct a TG43 source object.

The two top level functions are line and point that implement the line-formalism and point-formalism TG43.

Some sources are already defined in the sources.py file. A new source can be initialized with the datafile, the source length and the dose rate constant.

dirname: the datafile directory name

Source code in pygrpm/tg43/seed.py
 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
def __init__(self, dirname: str) -> None:
    """
    Construct a TG43 source object.

    The two top level functions are `line` and `point` that implement the
    line-formalism and point-formalism TG43.

    Some sources are already defined in the sources.py file. A new source
    can be initialized with the datafile, the source length and the dose
    rate constant.

    `dirname`: the datafile directory name
    """
    # find the absolute path of the data directory
    path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", dirname)
    if not os.path.isdir(path):
        raise SourceDataNotFound(path)

    # The length of the source
    self.L = np.loadtxt(os.path.join(path, "L.dat"))

    # The dose rate constant of the source
    self.Lambda = np.loadtxt(os.path.join(path, "Lambda.dat"))

    # The function gL
    gL = np.loadtxt(os.path.join(path, "gL.dat")).T
    self.gL = xr.DataArray(gL[1], dims=["r"], coords=[gL[0]])

    # The function F
    F = np.loadtxt(os.path.join(path, "F.dat"))
    self.F = xr.DataArray(
        F[1:, 1:].T, dims=["r", "theta"], coords=[F[0, 1:], F[1:, 0]]
    )

    # the function phi
    if os.path.isfile(os.path.join(path, "phi.dat")):
        phi = np.loadtxt(os.path.join(path, "phi.dat")).T
        self.phi = xr.DataArray(phi[1], dims=["r"], coords=[phi[0]])
    else:
        self.phi = self.F.mean(dim="theta")

    self._GL0 = self._beta(1, np.radians(90)) / self.L
    self.decimals_r = 1

dose(r, theta)

Returns the dose for each given point. If multiple points of r and theta are provided all cross values wil be returned.

:param Union[Sequence, float] r: A sequence or scalar of radius values :param Union[Sequence, float] theta: A sequence or scalar of angle values

:return DataArray: A DataArray of doses for each provided points

Source code in pygrpm/tg43/seed.py
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
def dose(
    self, r: Union[Sequence, float], theta: Union[Sequence, float]
) -> xr.DataArray:
    """
    Returns the dose for each given point. If multiple points of r and theta are
    provided all cross values wil be returned.

    :param Union[Sequence, float] r: A sequence or scalar of radius values
    :param Union[Sequence, float] theta: A sequence or scalar of angle values

    :return DataArray: A DataArray of doses for each provided points
    """
    r_arr = np.array(r, ndmin=1)
    theta_arr = np.array(theta, ndmin=1)
    r_xarr = xr.DataArray(r_arr, dims=["r"], coords=[r_arr])
    theta_xarr = xr.DataArray(theta_arr, dims=["theta"], coords=[theta_arr])
    return self._dose(r_xarr, theta_xarr)

get_F(array, R)

Obtain the Anisotropic function in terms of angles for a given radius R. Values are normalized by F(r, theta=90) :param DataArray array: DataArray representing the dosimetric grid, such as that obtained from Seed.grid() :param float R: Radius value for the anisotropic function :return DataArray: Anisotropic function in terms of theta (0 to 180)

Source code in pygrpm/tg43/seed.py
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
@domain
def get_F(self, array: xr.DataArray, R: float) -> xr.DataArray:
    """
    Obtain the Anisotropic function in terms of angles for a given radius R.
    Values are normalized by F(r, theta=90)
    :param DataArray array: DataArray representing the dosimetric grid, such as that
    obtained from Seed.grid()
    :param float R: Radius value for the anisotropic function
    :return DataArray: Anisotropic function in terms of theta (0 to 180)
    """
    r, theta = _get_sphere_coords(array.x, array.y, array.z)
    new_arr = array * self._GL0 / self._GL(r, theta)
    s = np.linspace(-R, R, 101)
    new_arr = new_arr.interp(x=s, y=s, z=s)
    r, theta = _get_sphere_coords(new_arr.x, new_arr.y, new_arr.z)
    new_arr["r"] = r.round(decimals=self.decimals_r)
    new_arr["theta"] = theta.round()
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", category=RuntimeWarning)
        a = new_arr.where(new_arr.r == R).groupby("theta").mean()
    return a / a.sel(theta=90)

get_calibration(array, significant_figures=5)

Returns the calibration factor based on internal or provided Lambda values. Function returns Lambda divided by the mean value of array at r=1 to the specified amount of significant figures :param DataArray array: DataArray representing the dosimetric grid, such as that obtained from Seed.grid() :param float significant_figures: Desired significant figures for returned value :return float: The calibration factor to apply to the provided grid

Source code in pygrpm/tg43/seed.py
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
def get_calibration(
    self, array: xr.DataArray, significant_figures: int = 5
) -> float:
    """
    Returns the calibration factor based on internal or provided Lambda values.
    Function returns Lambda divided by the mean value of array at r=1 to the specified
    amount of significant figures
    :param DataArray array: DataArray representing the dosimetric grid, such as that
    obtained from Seed.grid()
    :param float significant_figures: Desired significant figures for returned value
    :return float: The calibration factor to apply to the provided grid
    """
    array90 = array.interp(z=0)
    r, _ = _get_sphere_coords(array90.x, array90.y, array90.z)
    array90["r"] = r.round(decimals=3)
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", category=RuntimeWarning)
        a = array90.groupby("r").mean()
    print(a.sel(r=1).values)
    C = self.Lambda / a.sel(r=1).values
    C = np.around(C, decimals=significant_figures - int(np.log10(C)))
    return C

get_cv(array)

For a given dosimetric grid, obtain an array of coefficients of variation values along the radius :param DataArray array: DataArray representing the dosimetric grid, such as that obtained from Seed.grid() :return DataArray: Standard deviation of dose value for values of radius

Source code in pygrpm/tg43/seed.py
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
@domain
def get_cv(self, array: xr.DataArray) -> xr.DataArray:
    """
    For a given dosimetric grid, obtain an array of coefficients of variation
    values along the radius
    :param DataArray array: DataArray representing the dosimetric grid, such as that
    obtained from Seed.grid()
    :return DataArray: Standard deviation of dose value for values of radius
    """
    array90 = array.interp(z=0)
    r, _ = _get_sphere_coords(array90.x, array90.y, array90.z)
    array90["r"] = r.round(decimals=self.decimals_r)
    array90_groupby_r = array90.groupby("r")
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", category=RuntimeWarning)
        mean = array90_groupby_r.mean()
        std = array90_groupby_r.std()
    return std / abs(mean)

get_gL(array)

For a given dosimetric grid, obtain an array of Geometry function (for line source) values along the radius :param DataArray array: DataArray representing the dosimetric grid, such as that obtained from Seed.grid() :return DataArray: Standard deviation of dose value for values of radius

Source code in pygrpm/tg43/seed.py
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
@domain
def get_gL(self, array: xr.DataArray) -> xr.DataArray:
    """
    For a given dosimetric grid, obtain an array of Geometry function (for line source)
    values along the radius
    :param DataArray array: DataArray representing the dosimetric grid, such as that
    obtained from Seed.grid()
    :return DataArray: Standard deviation of dose value for values of radius
    """
    array90 = array.interp(z=0)
    r, theta = _get_sphere_coords(array90.x, array90.y, array90.z)
    array90 *= self._GL0 / self._GL(r, theta)
    array90["r"] = r.round(decimals=self.decimals_r)
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", category=RuntimeWarning)
        a = array90.groupby("r").mean()
    return a / a.sel(r=1)

get_mean(array)

For a given dosimetric grid, obtain an array of mean values along the radius :param DataArray array: DataArray representing the dosimetric grid, such as that obtained from Seed.grid() :return DataArray: Mean dose value for values of radius

Source code in pygrpm/tg43/seed.py
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
@domain
def get_mean(self, array: xr.DataArray) -> xr.DataArray:
    """
    For a given dosimetric grid, obtain an array of mean values along the radius
    :param DataArray array: DataArray representing the dosimetric grid, such as that
    obtained from Seed.grid()
    :return DataArray: Mean dose value for values of radius
    """
    array90 = array.interp(z=0)
    r, _ = _get_sphere_coords(array90.x, array90.y, array90.z)
    array90["r"] = r.round(decimals=self.decimals_r)
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", category=RuntimeWarning)
        a = array90.groupby("r").mean()
    return a

get_std(array)

For a given dosimetric grid, obtain an array of standard deviation values along the radius :param DataArray array: DataArray representing the dosimetric grid, such as that obtained from Seed.grid() :return DataArray: Standard deviation of dose value for values of radius

Source code in pygrpm/tg43/seed.py
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
@domain
def get_std(self, array: xr.DataArray) -> xr.DataArray:
    """
    For a given dosimetric grid, obtain an array of standard deviation values along the radius
    :param DataArray array: DataArray representing the dosimetric grid, such as that
    obtained from Seed.grid()
    :return DataArray: Standard deviation of dose value for values of radius
    """
    array90 = array.interp(z=0)
    r, _ = _get_sphere_coords(array90.x, array90.y, array90.z)
    array90["r"] = r.round(decimals=self.decimals_r)
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", category=RuntimeWarning)
        a = array90.groupby("r").std()
    return a

grid(boxmin=-10, boxmax=10, voxsize=0.1, sourcepos=0, orientation=(0, 0, 1))

Method to compute a 3D dosimetric grid for this brachy seed

:param Union[Sequence, float] boxmin: Minimum coordinate value (along all axes) of the container box :param Union[Sequence, float] boxmax: Maximum coordinate value (along all axes) of the container box :param float voxsize: Voxel size of the container box :param Union[Sequence, float] sourcepos: Position of the source within the container box :param Sequence orientation: Sequence of float detailing source orientation in the box

:return DataArray: A dataArray with the 3D dosimetric grid information

Source code in pygrpm/tg43/seed.py
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
def grid(
    self,
    boxmin: Union[Sequence, float] = -10,
    boxmax: Union[Sequence, float] = 10,
    voxsize=0.1,
    sourcepos: Union[Sequence, float] = 0,
    orientation: Sequence = (0, 0, 1),
) -> xr.DataArray:
    """
    Method to compute a 3D dosimetric grid for this brachy seed

    :param Union[Sequence, float] boxmin: Minimum coordinate value (along all axes)
    of the container box
    :param Union[Sequence, float] boxmax: Maximum coordinate value (along all axes)
    of the container box
    :param float voxsize: Voxel size of the container box
    :param Union[Sequence, float] sourcepos: Position of the source within the container box
    :param Sequence orientation: Sequence of float detailing source orientation in the box

    :return DataArray: A dataArray with the 3D dosimetric grid information
    """
    boxmin = _coords3d(boxmin)
    boxmax = _coords3d(boxmax)
    voxsize = _coords3d(voxsize)
    sourcepos = _coords3d(sourcepos)
    orientation = _coords3d(orientation)

    # np.arange accumulates the floating point error. Here, the error is
    # kept as small as possible.
    x = (
        boxmin[0]
        - sourcepos[0]
        + np.arange(0, boxmax[0] - boxmin[0] + voxsize[0], voxsize[0])
    )
    y = (
        boxmin[1]
        - sourcepos[1]
        + np.arange(0, boxmax[1] - boxmin[1] + voxsize[1], voxsize[1])
    )
    z = (
        boxmin[2]
        - sourcepos[2]
        + np.arange(0, boxmax[2] - boxmin[2] + voxsize[2], voxsize[2])
    )

    x = xr.DataArray(x, dims=["x"], coords=[x])
    y = xr.DataArray(y, dims=["y"], coords=[y])
    z = xr.DataArray(z, dims=["z"], coords=[z])

    r, theta = _get_sphere_coords(x, y, z)

    grid = self._dose(r, theta)
    grid = grid.drop_vars(["r", "theta"])
    grid = grid.assign_coords(
        x=(grid.x + sourcepos[0]),
        y=(grid.y + sourcepos[1]),
        z=(grid.z + sourcepos[2]),
    )

    return grid

Bases: Exception

Implementation for possible future handling of missing source data

Source code in pygrpm/tg43/seed.py
22
23
24
25
26
27
28
class SourceDataNotFound(Exception):
    """
    Implementation for possible future handling of missing source data
    """

    # pylint: disable=unnecessary-pass
    pass