You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/user_guide/detector/index.md
+12-1Lines changed: 12 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,7 @@ includes effects pointed out by Adam Anthony in his [thesis](https://ezproxy.msu
13
13
The detector system code simulates an event by going through a series of steps to
14
14
ultimately produce its point cloud. For each event, the detector system:
15
15
16
-
1. Generate the trajectory of the each nucleus in the exit channel of the event by solving its equation of motion in the AT-TPC with a fine grained-timestep
16
+
1. Generate the trajectory of the each nucleus in the exit channel (or the nuclei specified by the user) of the event by solving its equation of motion in the AT-TPC with a fine grained-timestep
17
17
2. Determines how many electrons are created at each point of each nucleus' trajectory
18
18
3. Converts the z coordinate of each point in each trajectory to a GET electronics sampling-frequency based Time Bucket using the electron drift velocity
19
19
3. Transports each point of the nucleus' trajectory to the pad plane, applying diffusion if requested, to identify the sensing pad for each timestep
@@ -141,6 +141,17 @@ step reaction a(b,c)d a=0, b=1, c=2, d=3. In a two step, a(b,c)d->e+f, e=4, f=5,
141
141
on for more complex scenarios. These labels are particularly useful for evaluating the
142
142
performance of machine learning methods like clustering in downstream analyses.
143
143
144
+
## Which nuclei get simulated in the detector simulation
145
+
146
+
By default, the detector simulation considers all nuclei in the exit channel. That is,
147
+
in a two step reaction a(b,c)d->e+f, the nuclei c, e, f are included in the detector
148
+
simulation and used to generate a point cloud. However, this is not always desireable.
149
+
In some usecases, only on particle is interesting and all others simply generate extra
150
+
data. As such, the `run_simulation` function contains an optional keyword argument
151
+
`indices` which can be used to specify the indices of the nuclei to include in the
152
+
detector simulation. Indices follow the same convention as the kinematics simulation,
153
+
i.e. for our earlier example two step reaction a=0, b=1, c=2, d=3, e=4, and f=5.
154
+
144
155
## Why Point clouds
145
156
146
157
It is worth elaborating why the detector system outputs point clouds instead of raw
Copy file name to clipboardExpand all lines: docs/user_guide/getting_started.md
+69-14Lines changed: 69 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,7 @@
1
1
# Getting Started
2
2
3
-
Once attpc_engine is installed it's time to setup our simulation project. Below is an outline of what we'd expect your project structure to look like
3
+
Once attpc_engine is installed it's time to setup our simulation project. Below is an
4
+
outline of what we'd expect your project structure to look like
4
5
5
6
```txt
6
7
|---my_sim
@@ -13,13 +14,18 @@ Once attpc_engine is installed it's time to setup our simulation project. Below
13
14
| | |---detector
14
15
```
15
16
16
-
You have a folder (in this case called `my_sim`) with two Python files (`generate_kinematics.py` and `apply_detector.py`) a virtual environment with attpc_engine installed (`.venv`) and an output directory with a folder for kinematics and detector effects. Note that you may want the output to be stored on a remote disk or other location as simulation files can be big at times (> 1 GB).
17
+
You have a folder (in this case called `my_sim`) with two Python files
18
+
(`generate_kinematics.py` and `apply_detector.py`) a virtual environment with
19
+
attpc_engine installed (`.venv`) and an output directory with a folder for kinematics
20
+
and detector effects. Note that you may want the output to be stored on a remote disk
21
+
or other location as simulation files can be big at times (> 1 GB).
17
22
18
23
Now lets talk about generating and sampling a kinematics phase space!
19
24
20
25
## Sampling Kinematics
21
26
22
-
Below is an example script for running a kinematics sample, which in our example project we would write in `my_sim/generate_kinematics.py`
27
+
Below is an example script for running a kinematics sample, which in our example
28
+
project we would write in `my_sim/generate_kinematics.py`
23
29
24
30
```python
25
31
from attpc_engine.kinematics import (
@@ -70,10 +76,13 @@ if __name__ == "__main__":
70
76
main()
71
77
```
72
78
73
-
First we import all of our pieces from the attpc_engine library and its dependencies. We also import the Python standard library Path object to handle our file paths.
79
+
First we import all of our pieces from the attpc_engine library and its dependencies.
80
+
We also import the Python standard library Path object to handle our file paths.
74
81
75
-
We then start to define our kinematics configuration. First we define the output path to be an HDF5 file in our output directory.
76
-
We also load a spyral-utils [gas target](https://attpc.github.io/spyral-utils/api/nuclear/target) from a file path.
82
+
We then start to define our kinematics configuration. First we define the output path
83
+
to be an HDF5 file in our output directory.
84
+
We also load a spyral-utils [gas target](https://attpc.github.io/spyral-utils/api/nuclear/target)
85
+
from a file path.
77
86
78
87
```python
79
88
target = load_target(target_path, nuclear_map)
@@ -90,7 +99,21 @@ nevents = 10000
90
99
beam_energy =184.131# MeV
91
100
```
92
101
93
-
Now were ready to define our kinematics Pipeline. The first argument of the Pipeline is a list of steps, where each step is either a Reaction or Deacy. The first element of the list must *always* be a Reaction, and all subsequent steps are *always* Decays. The residual of the previous step is *always* the parent of the next step. The Pipeline will attempt to validate this information for you. We also must define a list of ExcitationDistribution objects. These describe the state in the residual that is populated by each Reaction/Decay. There is exactly *one* distribution per step. There are two types of predefined ExcitationDistributions (ExcitationGaussian and ExcitationUniform), but others can be implemented by implementing the ExcitationDistribution protocol. Similarly, we use PolarUniform to define a uniform polar angle distribution from 0 degrees to 180 degrees in the center of mass frame (technically, this is from -1 to 1 in cos(polar)). We also define our KinematicsTargetMaterial, which includes our gas target, as well as the allowed space within the target for our reaction vertex (range in z in meters and standard deviation of cylindrical ρ in meters).
102
+
Now were ready to define our kinematics Pipeline. The first argument of the Pipeline
103
+
is a list of steps, where each step is either a Reaction or Deacy. The first element
104
+
of the list must *always* be a Reaction, and all subsequent steps are *always* Decays.
105
+
The residual of the previous step is *always* the parent of the next step. The
106
+
Pipeline will attempt to validate this information for you. We also must define a list
107
+
of ExcitationDistribution objects. These describe the state in the residual that is
108
+
populated by each Reaction/Decay. There is exactly *one* distribution per step. There
109
+
are two types of predefined ExcitationDistributions (ExcitationGaussian and
110
+
ExcitationUniform), but others can be implemented by implementing the
111
+
ExcitationDistribution protocol. Similarly, we use PolarUniform to define a uniform
112
+
polar angle distribution from 0 degrees to 180 degrees in the center of mass frame
113
+
(technically, this is from -1 to 1 in cos(polar)). We also define our
114
+
KinematicsTargetMaterial, which includes our gas target, as well as the allowed space
115
+
within the target for our reaction vertex (range in z in meters and standard deviation
116
+
of cylindrical ρ in meters).
94
117
95
118
```python
96
119
pipeline = KinematicsPipeline(
@@ -126,11 +149,13 @@ if __name__ == "__main__":
126
149
main()
127
150
```
128
151
129
-
That's it! This script will then sample 10000 events from the kinematic phase space of ${}^{16}C(d,d')$ and write the data out to an HDF5 file in our output directory.
152
+
That's it! This script will then sample 10000 events from the kinematic phase space of
153
+
${}^{16}C(d,d')$ and write the data out to an HDF5 file in our output directory.
130
154
131
155
## Applying the Detector
132
156
133
-
Below is an example script for running a kinematics sample, which in our example project we would write in `my_sim/apply_detector.py`
157
+
Below is an example script for running a kinematics sample, which in our example
158
+
project we would write in `my_sim/apply_detector.py`
134
159
135
160
```python
136
161
from attpc_engine.detector import (
@@ -193,7 +218,10 @@ if __name__ == "__main__":
193
218
main()
194
219
```
195
220
196
-
Just like in the kinematics script, we start off by importing a whole bunch of code. Next we define our kinematics input (which is the output of the kinematics script) and an output path. Note that for the output path we simply specify a directory; this is because our writer will handle breaking up the output data into reasonably sized files.
221
+
Just like in the kinematics script, we start off by importing a whole bunch of code.
222
+
Next we define our kinematics input (which is the output of the kinematics script) and
223
+
an output path. Note that for the output path we simply specify a directory; this is
224
+
because our writer will handle breaking up the output data into reasonably sized files.
@@ -209,7 +237,8 @@ if not isinstance(gas, GasTarget):
209
237
raiseException(f"Could not load target data from {target_path}!")
210
238
```
211
239
212
-
and finally we begin to define the detector specific configuration, which is ultimately stored in a Config object.
240
+
and finally we begin to define the detector specific configuration, which is ultimately
241
+
stored in a Config object.
213
242
214
243
```python
215
244
detector = DetectorParams(
@@ -237,13 +266,21 @@ pads = PadParams()
237
266
config = Config(detector, electronics, pads)
238
267
```
239
268
240
-
Note that by not passing any arguments to `PadParams` we are using the default pad description that is bundled with the package. See the [detector](./detector/index.md) guide for more details. For the output, we create a SpyralWriter object. This will take in the simulation data and convert it to match the format expected by the Spyral analysis. Note the final argument of the Writer; this is the maximum size of an individual file in events (here we've specified 5,000 events). The writer will then split our output up into many files, which will help later when trying to analyze the data with a framework like Spyral.
269
+
Note that by not passing any arguments to `PadParams` we are using the default pad
270
+
description that is bundled with the package. See the [detector](./detector/index.md)
271
+
guide for more details. For the output, we create a SpyralWriter object. This will take
272
+
in the simulation data and convert it to match the format expected by the Spyral
273
+
analysis. Note the final argument of the Writer; this is the maximum size of an
274
+
individual file in events (here we've specified 5,000 events). The writer will then
275
+
split our output up into many files, which will help later when trying to analyze the
276
+
data with a framework like Spyral.
241
277
242
278
```python
243
279
writer = SpyralWriter(output_path, config, 5_000)
244
280
```
245
281
246
-
Then, just like in the kinematics script we set up a main function and set it to be run when the script is processed
282
+
Then, just like in the kinematics script we set up a main function and set it to be
283
+
run when the script is processed
247
284
248
285
```python
249
286
defmain():
@@ -257,7 +294,25 @@ if __name__ == "__main__":
257
294
main()
258
295
```
259
296
260
-
And just like that, we can now take our kinematic samples and apply detector effects!
297
+
And just like that, we can now take our kinematic samples and apply detector effects!
298
+
Note that by default the simulation will apply detector effects and generate a point cloud
299
+
containing *every single final product* from the kinematics simulation. If you only want
300
+
to generate a point cloud containing specific particles you can utilize the `indices`
301
+
argument of `run_simulation`:
302
+
303
+
```python
304
+
defmain():
305
+
run_simulation(
306
+
config,
307
+
input_path,
308
+
writer,
309
+
indices=[2],
310
+
)
311
+
```
312
+
313
+
The `indices` argument is a list of particle indices to be included in the simulation.
314
+
The indicies follow the same convention as the kinematics simulation: i.e. for a reaction
315
+
a(b,c)d a=0, b=1, c=2, d=3. If you have a decay a(b,c)d->e+f e=4, f=5, and so on.
0 commit comments