-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathpumas.h
2331 lines (2233 loc) · 88.3 KB
/
pumas.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
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
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright (C) 2017 Université Clermont Auvergne, CNRS/IN2P3, LPC
* Author: Valentin NIESS (niess@in2p3.fr)
*
* This software is a C library whose purpose is to transport high energy
* muons or taus in various media.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef pumas_h
#define pumas_h
#ifdef __cplusplus
extern "C" {
#endif
#ifndef PUMAS_API
#define PUMAS_API
#endif
/* For C standard streams. */
#ifndef FILE
#include <stdio.h>
#endif
/**
* Projectiles supported by PUMAS.
*/
enum pumas_particle {
/** The muon or anti-muon lepton. */
PUMAS_PARTICLE_MUON = 0,
/** The tau or anti-tau lepton. */
PUMAS_PARTICLE_TAU
};
/**
* Physics properties tabulated by PUMAS.
*/
enum pumas_property {
/**
* The restricted cross-section for inelastic and radiative
* processes, in m^(2)/kg.
*/
PUMAS_PROPERTY_CROSS_SECTION = 0,
/**
* Cutoff angle for hard elastic events in the center of mass frame,
* in rad.
*/
PUMAS_PROPERTY_ELASTIC_CUTOFF_ANGLE,
/**
* The mean free path for hard elastic (Coulomb) collisions,
* in kg/m^(2).
*/
PUMAS_PROPERTY_ELASTIC_PATH,
/** The material stopping power, in GeV/(kg/m^(2)). */
PUMAS_PROPERTY_STOPPING_POWER,
/** The particle grammage range, in kg/m^(2). */
PUMAS_PROPERTY_RANGE,
/** The particle kinetic energy, in GeV. */
PUMAS_PROPERTY_KINETIC_ENERGY,
/** The total magnetic rotation angle, in rad kg/m^(3). */
PUMAS_PROPERTY_MAGNETIC_ROTATION,
/**
* The transport mean free path for soft processes, in kg/m^(2).
*/
PUMAS_PROPERTY_TRANSPORT_PATH,
/** The particle proper time, in kg/m^(2). */
PUMAS_PROPERTY_PROPER_TIME
};
/**
* Modes for the Monte Carlo transport.
*/
enum pumas_mode {
/** The simulation of the corresponding property is disabled.
*
* **Note** : When running without energy losses a distance / grammage
* limit must be defined or geometry callback provided.
*
* **Note** : When scattering is disabled, charged particles are still
* deflected by external electromagnetic fields.
*/
PUMAS_MODE_DISABLED = -1,
/** Energy losses are purely determinstic as given by the Continuously
* Slowing Down Approximation (CSDA).
*/
PUMAS_MODE_CSDA = 0,
/** Energy losses or scattering are simulated using a mixed (class II)
* Monte-Carlo algorithm with a split between soft and hard collisions.
*/
PUMAS_MODE_MIXED = 1,
/** In addition to the mixed algorithm, the energy loss due to soft
* electronic collisions is straggled.
*/
PUMAS_MODE_STRAGGLED = 2,
/**
* Decays are accounted for by a weight factor. This is efficient
* for muons but irrelevant -numerically instable- for the forward
* transport of taus since they decay in flight. Hence this mode is
* not allowed in the latter case.
*/
PUMAS_MODE_WEIGHTED = 0,
/** Decay vertices are randomised as a specific Monte-Carlo process.
*
* **Note** : the transported particle stops at the decay vertex but
* its decay is not simulated, i.e. no daughter particles are
* generated.
*/
PUMAS_MODE_RANDOMISED = 1,
/** Do a forward Monte Carlo transport.
*
* **Note** : the forward Monte Carlo transport is analog, i.e.
* unweighted. However, if the decay mode is set to
* `PUMAS_MODE_WEIGHTED` then the particle weight is updated
* accordingly.
*/
PUMAS_MODE_FORWARD = 0,
/** Do a backward Monte Carlo transport.
*
* **Note** : the backward Monte Carlo transport is **not** analog. I.e.
* the transported particle is weighted.
*/
PUMAS_MODE_BACKWARD = 1
};
/** Return codes for the API functions. */
enum pumas_return {
/** Execution was successful. */
PUMAS_RETURN_SUCCESS = 0,
/** The requested accuracy is not valid. */
PUMAS_RETURN_ACCURACY_ERROR,
/** End of file was reached. */
PUMAS_RETURN_END_OF_FILE,
/** The specified decay mode is not valid. */
PUMAS_RETURN_DECAY_ERROR,
/** Some medium has a wrong density value. */
PUMAS_RETURN_DENSITY_ERROR,
/** Some medium has a wrong density value. */
PUMAS_RETURN_DIRECTION_ERROR,
/** A non unit direction is provided. */
PUMAS_RETURN_INCOMPLETE_FILE,
/** Some index is out of validity range. */
PUMAS_RETURN_INDEX_ERROR,
/** The physics is not initialised or a NULL pointer was provided. */
PUMAS_RETURN_PHYSICS_ERROR,
/** An internal library error occured. */
PUMAS_RETURN_INTERNAL_ERROR,
/** Some read /write error occured. */
PUMAS_RETURN_IO_ERROR,
/** Some file is badly formated. */
PUMAS_RETURN_FORMAT_ERROR,
/** Wrong propagation medium. */
PUMAS_RETURN_MEDIUM_ERROR,
/** Some memory could not be allocated. */
PUMAS_RETURN_MEMORY_ERROR,
/** An invalid (unknown) DCS model was requested. */
PUMAS_RETURN_MODEL_ERROR,
/** A user supplied limit is required. */
PUMAS_RETURN_MISSING_LIMIT,
/** The random callback is not defined. */
PUMAS_RETURN_MISSING_RANDOM,
/** Some file could not be found. */
PUMAS_RETURN_PATH_ERROR,
/** A raise was called without any catch. */
PUMAS_RETURN_RAISE_ERROR,
/** Some input string is too long. */
PUMAS_RETURN_TOO_LONG,
/** No MDF file specified. */
PUMAS_RETURN_UNDEFINED_MDF,
/** An unkwon element was specified. */
PUMAS_RETURN_UNKNOWN_ELEMENT,
/** An unkwon material was specified. */
PUMAS_RETURN_UNKNOWN_MATERIAL,
/** The particle type is not known. */
PUMAS_RETURN_UNKNOWN_PARTICLE,
/** Some input value is not valid. */
PUMAS_RETURN_VALUE_ERROR,
/** The number of PUMAS return codes. */
PUMAS_N_RETURNS
};
/** Flags for transport events. */
enum pumas_event {
/** No event occured or is foreseen. */
PUMAS_EVENT_NONE = 0,
/** A kinetic energy limit was reached or is foreseen. */
PUMAS_EVENT_LIMIT_ENERGY = 1,
/** A distance limit was reached or is foreseen. */
PUMAS_EVENT_LIMIT_DISTANCE = 2,
/** A grammage limit was reached or is foreseen. */
PUMAS_EVENT_LIMIT_GRAMMAGE = 4,
/** A proper time limit was reached or is foreseen. */
PUMAS_EVENT_LIMIT_TIME = 8,
/** Shortcut for any external limit. */
PUMAS_EVENT_LIMIT = 15,
/** A change of medium occured or is foreseen. */
PUMAS_EVENT_MEDIUM = 16,
/** A Bremsstrahlung occured or is foreseen. */
PUMAS_EVENT_VERTEX_BREMSSTRAHLUNG = 32,
/** A Pair creation occured or is foreseen. */
PUMAS_EVENT_VERTEX_PAIR_CREATION = 64,
/** A Photonuclear interaction occured or is foreseen. */
PUMAS_EVENT_VERTEX_PHOTONUCLEAR = 128,
/** A Delta ray occured or is foreseen. */
PUMAS_EVENT_VERTEX_DELTA_RAY = 256,
/** Shortcut for any Discrete Energy Loss (DEL). */
PUMAS_EVENT_VERTEX_DEL = 480,
/** A hard Coulombian interaction occured or is foreseen. */
PUMAS_EVENT_VERTEX_COULOMB = 512,
/** A decay has occured or is foreseen. */
PUMAS_EVENT_VERTEX_DECAY = 1024,
/** Shortcut for any interaction vertex. */
PUMAS_EVENT_VERTEX = 2016,
/** The particle has a nul or negative weight. */
PUMAS_EVENT_WEIGHT = 2048,
/** Extra flag for records tagging the first transport step. */
PUMAS_EVENT_START = 4096,
/** Extra flag for records tagging the last transport step. */
PUMAS_EVENT_STOP = 8192
};
/** Radiative processes available in PUMAS. */
enum pumas_process {
/** The Bremstrahlung process */
PUMAS_PROCESS_BREMSSTRAHLUNG = 0,
/** The e+e- pair production process */
PUMAS_PROCESS_PAIR_PRODUCTION,
/** The photonuclear process */
PUMAS_PROCESS_PHOTONUCLEAR
};
/** Physics constants used by PUMAS. */
enum pumas_constant {
/** The electromagnetic coupling constant, alpha. */
PUMAS_CONSTANT_ALPHA_EM = 0,
/** The Avogadro number, in mol. */
PUMAS_CONSTANT_AVOGADRO_NUMBER,
/** The electron Bohr radius, in m. */
PUMAS_CONSTANT_BOHR_RADIUS,
/** The electron mass, in GeV/c^2. */
PUMAS_CONSTANT_ELECTRON_MASS,
/** The classical electron radius, in m. */
PUMAS_CONSTANT_ELECTRON_RADIUS,
/* The planck constant, in GeV m. */
PUMAS_CONSTANT_HBAR_C,
/** The muon decay length, in m. */
PUMAS_CONSTANT_MUON_C_TAU,
/** The muon mass, in GeV/c^2. */
PUMAS_CONSTANT_MUON_MASS,
/** The neutron mass, in GeV/c^2. */
PUMAS_CONSTANT_NEUTRON_MASS,
/** The mass of charged pions, in GeV/c^2 */
PUMAS_CONSTANT_PION_MASS,
/** The proton mass, in GeV/c^2. */
PUMAS_CONSTANT_PROTON_MASS,
/** The tau decay length, in m. */
PUMAS_CONSTANT_TAU_C_TAU,
/** The tau mass, in GeV/c^2. */
PUMAS_CONSTANT_TAU_MASS,
/** The number of PUMAS constants. */
PUMAS_N_CONSTANTS
};
/**
* Container for a Monte-Carlo state.
*
* This structure contains data defining a particle Monte Carlo state. It must
* be directly instancianted by the user.
*
* __Note__: this structure might be wrapped (sub-classed) in a larger one by
* the user.
*/
struct pumas_state {
/** The particle's electric charge. Note that non physical values,
* i.e. different from 1 or -1, could be set. */
double charge;
/** The current kinetic energy, in GeV. */
double energy;
/** The total travelled distance, in m. */
double distance;
/** The total travelled grammage, in kg/m^2. */
double grammage;
/** The particle's proper time, in m/c. */
double time;
/** The Monte-Carlo weight. */
double weight;
/** The absolute location, in m. */
double position[3];
/** The momentum's unit direction. Must be normalised to one. */
double direction[3];
/** Status flag telling if the particle has decayed or not. */
int decayed;
};
/**
* The local properties of a propagation medium.
*/
struct pumas_locals {
/** The material local density, in kg/m^3. Setting a null or negative
* value results in the material's default density being used.
*/
double density;
/** The local magnetic field components, in T. */
double magnet[3];
};
struct pumas_medium;
/**
* Callback for setting the local properties of a propagation medium.
*
* @param medium The propagation medium.
* @param state The Monte-Carlo state for which the local properties are
* requested.
* @param locals A pointer to a `pumas_locals` structure to update.
* @return The size of local inhomogeneities (see below).
*
* The callback must return a length, in m, consistent with the size of the
* propagation medium inhomogeneities, e. g. ρ / |∇ ρ| for a
* density gradient. Returning zero or less signs that the propagation medium is
* fully uniform.
*
* **Note** that inhomogeneities modelled by the `pumas_locals` callback must be
* **continuous**. If the geometry has a density or magnetic field discontinuity
* then this must be modelled by using separate media on both sides of the
* discontinuity.
*
* **Warning** : it is an error to return zero or less for any position of the
* medium if at least one area is not uniform. Instead one should use two
* different media even though they have the same material base.
*
*/
typedef double pumas_locals_cb (struct pumas_medium * medium,
struct pumas_state * state, struct pumas_locals * locals);
/**
* Description of a propagation medium.
*
* A propagation medium is fully defined by:
*
* - a *material* composition with a constant relative content.
*
* - Optionally, local properties set by a `pumas_locals_cb` callback.
*
* __Note__: this structure might be wrapped (sub-classed) in a larger one by
* the user.
*/
struct pumas_medium {
/**
* The material index in the Material Description File (MDF). It can be
* mapped to the corresponding name with the
* `pumas_physics_material_name` function.
*/
int material;
/**
* The user supplied callback for setting the medium local properties.
* Setting a `NULL` callback results in the material's default density
* being used with no magnetic field.
*/
pumas_locals_cb * locals;
};
/** A recorded Monte-Carlo frame.
*
* This structure exposes data relative to a recorded Monte Carlo frame. It is
* not meant to be modified by the user.
*
* See the `pumas_recorder` structure for more information on recording Monte
* Carlo steps.
*/
struct pumas_frame {
/** The recorded Monte Carlo state. */
struct pumas_state state;
/** The corresponding target medium. */
struct pumas_medium * medium;
/** The corresponding Monte Carlo event. */
enum pumas_event event;
/** Link to the next frame in the record. */
struct pumas_frame * next;
};
struct pumas_context;
/** A user supplied recorder callback.
* @param context The recording simulation context.
* @param state The recorded particle state.
* @param medium The corresponding medium.
* @param event The step event.
*
* This callback allows to customize the recording of PUMAS Monte-Carlo events.
*
* **Note** : by default the recorder uses an in-memory copy with dynamic
* allocation. Setting a custom recorder disables the default recording.
*/
typedef void pumas_recorder_cb (struct pumas_context * context,
struct pumas_state * state, struct pumas_medium * medium,
enum pumas_event event);
/**
* A Monte-Carlo recorder.
*
* This structure is used for recording Monte Carlo steps and/or accessing
* them. Although it exposes some public data that the user may alter it also
* encloses other opaque data. Therefore, it **must** be handled with the
* `pumas_recorder_create`, `pumas_recorder_clear` and `pumas_recorder_destroy`
* functions.
*
* By default a newly created recorder is configured for saving all Monte Carlo
* steps as `pumas_frame` objects. This behaviour can be modified by setting a
* `pumas_recorder_cb` callback as *record* field. Other attributes of the
* structure control the sampling rate of Monte Carlo steps and allow to access
* the sampled `pumas_frame`, as detailed herein.
*
* **Note** : A recorder is enabled (disabled) by setting (unsetting) it to
* (from) the *recorder* field of a `pumas_context`. Only the corresponding
* context is recorded.
*/
struct pumas_recorder {
/** Link to the 1^(st) recorded frame or `NULL` if none. This field
* should not be modified.
*/
struct pumas_frame * first;
/** The total number of recorded frames. This field should not be
* modified.
*/
int length;
/**
* The sampling period of the recorder. If set to zero or less only
* medium changes and user specified events are recorded. Defaults to 1,
* i.e. all Monte-Carlo steps are recorded.
*/
int period;
/**
* Link to an external (user supplied) recording callback. Note that
* setting this value disables the in-memory frame recording. Defaults
* to `NULL`.
*/
pumas_recorder_cb * record;
/**
* A pointer to additional memory, if any is requested at
* initialisation.
*/
void * user_data;
};
/** Return codes for the medium callback. */
enum pumas_step {
/** The proposed step is cross-checked by PUMAS beforehand.
*
* This is the safest option. Use this mode if you are unsure about
* the compatibility of your geometry ray tracer with PUMAS.
*/
PUMAS_STEP_CHECK = 0,
/** The proposed step is used by PUMAS as is.
*
* This mode is intended for expert usage. Depending on the geometry ray
* tracer used, it can save PUMAS from performing some redundant
* geometry checks.
*/
PUMAS_STEP_RAW
};
/**
* Callback for locating the propagation medium of a `pumas_state`.
*
* @param context The Monte-Carlo context requiring a medium.
* @param state The Monte-Carlo state for which the medium is requested.
* @param medium A pointer to store the medium or `NULL` if not requested.
* @param step The proposed step size or zero or less for an infinite
* medium. If not requested this points to `NULL`.
* @return If the proposed step size should be cross-checked by PUMAS
* `PUMAS_STEP_CHECK` should be returned otherwise `PUMAS_STEP_RAW`.
*
* If *step* is not `NULL`, this callback must propose a Monte-Carlo stepping
* distance, in m, consistent with the geometry. Note that returning zero or
* less signs that the corresponding medium has no boundaries. When *medium* is
* not `NULL` it must be set to the located `pumas_medium`.
*
* In addition the user must return a `pumas_step` enum indicating if the
* proposed *step* needs to be cross-checked by PUMAS or if it should be used
* raw. Managing steps that end on a geometry boundary can be tricky
* numerically. Therefore it is recommended to return `PUMAS_STEP_CHECK` if you
* are unsure of what to do since it is more robust. The raw mode is usefull if
* your geometry engine already performs those checks in order to avoid double
* work.
*
* **Warning** : it is an error to return zero or less for any state if the
* extension is finite.
*
* **Warning** : in backward Monte Carlo mode the particle is propagated reverse
* to the state direction. The user must take care to provide a *step* size
* accordingly, i.e. consistent with the geometry in both forward and backward
* modes.
*/
typedef enum pumas_step pumas_medium_cb (
struct pumas_context * context, struct pumas_state * state,
struct pumas_medium ** medium, double * step);
/**
* Generic function pointer.
*
* This is a generic function pointer used to identify the library functions,
* e.g. for error handling.
*/
typedef void pumas_function_t (void);
/**
* Callback for error handling.
*
* @param rc The PUMAS return code.
* @param caller The API function where the error occured.
* @param message Brief description of the error.
*
* The user can override the PUMAS default error handler by providing its own
* error handler. It will be called at the return of any PUMAS library function
* providing an error code.
*/
typedef void pumas_handler_cb (enum pumas_return rc, pumas_function_t * caller,
const char * message);
/**
* Callback providing a stream of pseudo random numbers.
*
* @param context The simulation context requiring a random number.
* @return A uniform pseudo random number in [0;1].
*
* **Note** : this is the only random stream used by PUMAS. If overriding the
* default `pumas_context` callback then the user must unsure proper behaviour,
* i.e. that a flat distribution in [0;1] is indeed returned.
*
* **Warning** : if multiple contexts are used the user must also ensure that
* this callback is thread safe, e.g. by using independant streams for each
* context or a locking mechanism in order to share a single random stream.
* The default `pumas_context` random callback uses distinct random streams per
* context which ensures thread safety.
*/
typedef double pumas_random_cb (struct pumas_context * context);
/** Mode flags for the Monte Carlo transport. */
struct pumas_context_mode {
/**
* The mode used for the computation of energy losses. Default
* is `PUMAS_MODE_STRAGGLED`. Other options are `PUMAS_MODE_DISABLED`,
* `PUMAS_MODE_CSDA` and `PUMAS_MODE_MIXED`.
*/
enum pumas_mode energy_loss;
/**
* The mode for handling decays. Default is `PUMAS_MODE_WEIGHTED`
* for a muon or `PUMAS_MODE_RANDOMISED` for a tau. Set this to
* `PUMAS_MODE_DISABLED` in order to disable decays at all.
*/
enum pumas_mode decay;
/**
* Direction of the Monte Carlo flow. Default is
* `PUMAS_MODE_FORWARD`. Set this to `PUMAS_MODE_BACKWARD` for a
* reverse Monte Carlo.
*/
enum pumas_mode direction;
/**
* Algorithm for the simulation of the scattering. Default is
* `PUMAS_MODE_MIXED`. Other option is `PUMAS_MODE_DISABLED` which
* neglects any scattering.
*/
enum pumas_mode scattering;
};
/** External limits for the Monte Carlo transport. */
struct pumas_context_limit {
/**
* The minimum kinetic energy for forward transport, or the
* maximum one for backward transport, in GeV.
*/
double energy;
/** The maximum travelled distance, in m. */
double distance;
/** The maximum travelled grammage, in kg/m^2. */
double grammage;
/** The maximum travelled proper time, in m/c. */
double time;
};
/**
* A simulation context.
*
* This structure manages thread specific data for a PUMAS Monte Carlo
* simulation. It also exposes configuration parameters for the Monte Carlo
* transport. The exposed parameters can be directly modified by the user.
*
* __Warning__: since the simulation context wraps opaque data it **must** be
* created (destroyed) with the `pumas_context_create`
* (`pumas_context_destroy`) function.
*
* A context created with `pumas_context_create` is initialised with default
* settings. That is, the transport is configured for forward Monte Carlo with
* the highest level of detail available, i.e. energy straggling and scattering
* enabled. This can be modified by overriding the *mode* attribute of the
* simulation context.
*
* **Note**: in the case of a muon projectile, the default initialisation is to
* account for decays by weighting according to the proper time
* (`PUMAS_MODE_WEIGHTED`). However, for a tau projectile the default is to
* randomise the decay location (`PUMAS_MODE_RANDOMISE`).
*
* Each simulation context natively embeds a pseudo random engine. A Mersenne
* Twister algorithm is used. The random engine can be seeded with the
* `pumas_context_random_seed_set` function. Note that two contexts seeded
* with the same value are 100% correlated. If no seed is provided then one is
* picked randomly from the OS, e.g. from `/dev/urandom` on UNIX.
* Alternatively, a custom random engine can be used instead of the native one
* by overriding the *random* callback.
*
* The geometry of the simulation is specified by setting the *medium* field
* with a `pumas_medium_cb` callback. By default the *medium* field is `NULL`.
* Note that it must be set by the user before calling
* `pumas_context_transport`.
*
* The *event* field of the simulation context allows to specify end conditions
* for the Monte Carlo transport. E.g. a lower (upper) limit can be set on the
* kinetic energy of the projectile in forward (backward) mode. The limit value
* is specified by setting the corresponding *limit* field.
*/
struct pumas_context {
/** The geometry of the simulation specified as a callback. It must be
* provided by the user.
*/
pumas_medium_cb * medium;
/** The pseudo random generator of the simulation context. An
* alternative generator can be used by overriding this callback.
*/
pumas_random_cb * random;
/** An optionnal recorder for Monte Carlo steps. */
struct pumas_recorder * recorder;
/** A pointer to additional memory if any is requested at
* initialisation. Otherwise this points to `NULL`.
*/
void * user_data;
/** Settings controlling the Monte Carlo transport algirithm. */
struct pumas_context_mode mode;
/**
* The events that stop the transport. Default is `PUMAS_EVENT_NONE`,
* i.e. the transport stops only if the particle exits the simulation
* media, or if it looses all of its energy.
*/
enum pumas_event event;
/** External limits for the Monte Carlo transport. */
struct pumas_context_limit limit;
/** Tuning parameter for the accuracy of the Monte Carlo integration.
*
* The Monte Carlo transport is discretized in elementary steps. This
* parameter directly controls the length of these steps. The smaller
* the *accuracy* value the smaller the step length. Thus, the longer
* the Monte Carlo simulation.
*/
double accuracy;
};
/**
* Physics tables for the Monte Carlo transport
*
* This is an **opaque** structure wrapping physics tables for the Monte Carlo
* transport. See `pumas_physics_create` for informations on how to create a
* physics object.
*
* __Note__: the physics is configured during its instantiation. It cannot
* be modified afterwards. Only the composition of composite materials can be
* updated with the `pumas_physics_composite_update` function.
*
* The settings of a `pumas_physics` instance can be inspected with the
* `pumas_physics_cutoff`, `pumas_physics_dcs` and `pumas_physics_elastic_ratio`
* functions. The materials data are retrieved with the
* `pumas_physics_element_*`, and `pumas_physics_material_*` functions.
* Alternatively, the `pumas_physics_print` function can be used in order to
* print out a human readable summary of the physics.
*
* Physics properties are tabulated as function of the projectile kinetic
* energy. The tabulated values can be retrieved with the
* `pumas_physics_table_value` function. In addition, the
* `pumas_physics_property_*` functions provide smooth interpolations of physics
* properties for arbitrary kinetic energy values.
*/
struct pumas_physics;
/**
* Prototype for a Differential Cross-Section (DCS).
*
* @param Z The charge number of the target atom.
* @param A The mass number of the target atom.
* @param m The projectile rest mass, in GeV
* @param K The projectile kinetic energy, in GeV.
* @param q The projectile energy loss, in GeV.
* @return The corresponding value of the atomic DCS, in m^(2)/GeV.
*
* The `pumas_dcs_get` function allows to retrieve the DCS for a given process
* and model. Extra DCSs can be registered with the `pumas_dcs_register`
* function.
*
* **Note** : only the Bremsstrahlung, pair creation and photonuclear processes
* can be modified.
*/
typedef double pumas_dcs_t (double Z, double A, double m, double K, double q);
/**
*/
struct pumas_physics_settings {
/** Relative cutoff between soft and hard energy losses.
*
* Setting a null or negative value results in the default cutoff value
* to be used i.e. 5% which is a good compromise between speed and
* accuracy for transporting a continuous spectrumm, see e.g. [Sokalski
* et al.](https://doi.org/10.1103/PhysRevD.64.074015)
*/
double cutoff;
/** Ratio of the mean free path for hard elastic events to the smallest
* of the transport mean free path or CSDA range.
*
* The lower the ratio the more detailed the simulation of elastic
* scattering, see e.g. [Fernandez-Varea et al. (1993)](
* https://doi.org/10.1016/0168-583X(93)95827-R) Setting a null or
* negative value results in the default ratio to be used i.e. 5%.
*/
double elastic_ratio;
/** Physics model for the Bremsstrahlung process.
*
* Available models are:
*
* - `ABB`: Andreev, Bezrukov and Bugaev, Physics of Atomic Nuclei 57
* (1994) 2066.
*
* - `KKP`: Kelner, Kokoulin and Petrukhin, Moscow Engineering Physics
* Inst., Moscow, 1995.
*
* - `SSR`: Sandrock, Soedingresko and Rhode, [ICRC 2019](
* https://arxiv.org/abs/1910.07050).
*
* Setting a `NULL` value results in PUMAS default Bremsstrahlung model
* to be used, i.e. `SSR`.
* */
const char * bremsstrahlung;
/** Physics model for e^(+)e^(-) pair production.
*
* Available models are:
*
* - `KKP`: Kelner, Kokoulin and Petrukhin, Soviet Journal of Nuclear
* Physics 7 (1968) 237.
*
* - `SSR`: Sandrock, Soedingresko and Rhode, [ICRC 2019](
* https://arxiv.org/abs/1910.07050).
*
* Setting a `NULL` value results in PUMAS default pair production model
* to be used, i.e. `SSR`.
*/
const char * pair_production;
/** Physics model for photonuclear interactions.
*
* Available models are:
*
* - `BBKS`: Bezrukov, Bugaev, Sov. J. Nucl. Phys. 33 (1981), 635.
* with improved photon-nucleon cross-section according to
* [Kokoulin](https://doi.org/10.1016/S0920-5632(98)00475-7)
* and hard component from [Bugaev and Shlepin](
* https://doi.org/10.1103/PhysRevD.67.034027).
*
* - `BM` : Butkevich and Mikheyev, Soviet Journal of Experimental and
* Theoretical Physics 95 (2002) 11.
*
* - `DRSS`: Dutta, Reno, Sarcevic and Seckel, [Phys.Rev. D63 (2001)
* 094020](https://arxiv.org/abs/hep-ph/0012350).
*
* Setting a `NULL` value results in PUMAS default photonuclear model to
* be used, i.e. `DRSS`.
*/
const char * photonuclear;
/** The number of kinetic energy values to tabulate. Providing a value
* of zero or less results in the PDG energy grid being used.
*/
int n_energies;
/** Array of kinetic energy values to tabulate. Providing a `NULL`
* value results in the PDG energy grid being used.
*/
double * energy;
/** Flag to force updating existing stopping power table(s). The default
* behaviour is to not overwrite any already existing file.
*/
int update;
/** Flag to enable dry mode.
*
* In dry mode energy loss files are generated but the physics is
* not created. This is usefull e.g. if only energy loss files are
* needed as a speed up.
*
* __Warning__: in dry mode no physics is returned, i.e. the *physics*
* pointer provided by `pumas_physics_create` points to `NULL`.
*/
int dry;
};
/**
* Create physics tables.
*
* @param physics The physics tables.
* @param particle The type of the particle to transport.
* @param mdf_path The path to a Material Description File (MDF), or `NULL`.
* @param dedx_path The path to the energy loss tabulation(s), or `NULL`.
* @param settings Extra physics settings or `NULL`.
* @return On success `PUMAS_RETURN_SUCCESS` is returned otherwise an error
* code is returned as detailed below.
*
* Create physics tables for a set of materials and a given *particle*. These
* tables are looked-up by the Monte Carlo engine for fast evaluation of physics
* properties during the transport. Tabulated properties are cross-sections,
* materials stopping power, transport mean free path length, etc.
*
* The materials to tabulate are specified in a Materials Description File (MDF)
* provided with the *mdf_path* argument. If a `NULL` argument is given then the
* path is read from the `PUMAS_MDF` environment variable. Examples of MDF are
* available from the [pumas-materials
* repository](https://github.com/niess/pumas-materials).
*
* **Note**: a MDF must be provided in any case.
*
* The physics creation generates stopping power table(s) in the Particle Data
* Group (PDG) format. These tables are written to the *dedx_path* directory.
* If the latter is `NULL` then it is read from the `PUMAS_DEDX` environment
* variable. If both are `NULL` then the tables are dumped beside the MDF, i.e.
* in the same directory.
*
* Specific physics settings can be selected by providing a
* `pumas_physics_settings` structure. If `NULL` is provided then PUMAS default
* physics settings are used which should perform well for most use cases.
*
* Call `pumas_physics_destroy` in order to unload the physics and release the
* corresponding alocated memory.
*
* __Note__: computing the physics tables can be long, e.g. a few seconds per
* material defined in the MDF. The `pumas_physics_dump` and
* `pumas_physics_load` functions allow to save and load the tables to/from a
* file. This can be used in order to greatly speed up the physics
* initialisation.
*
* __Warning__: this function is **not** thread safe.
*
* __Error codes__
*
* PUMAS_RETURN_END_OF_FILE And unexpected EOF occured.
*
* PUMAS_RETURN_FORMAT_ERROR A file has a wrong format.
*
* PUMAS_RETURN_INCOMPLETE_FILE There are missing entries in
* the MDF.
*
* PUMAS_RETURN_IO_ERROR A file could not be read.
*
* PUMAS_RETURN_MEMORY_ERROR Could not allocate memory.
*
* PUMAS_RETURN_MODEL_ERROR A requested DCS model is not valid.
*
* PUMAS_RETURN_PATH_ERROR A file could not be opened.
*
* PUMAS_RETURN_PHYSICS_ERROR A `NULL` physics pointer was
* provided.
*
* PUMAS_RETURN_TOO_LONG Some XML node in the MDF is
* too long.
*
* PUMAS_RETURN_UNDEFINED_MDF No MDF was provided.
*
* PUMAS_RETURN_UNKNOWN_ELEMENT An element in the MDF wasn't
* defined.
*
* PUMAS_RETURN_UNKNOWN_MATERIAL An material in the MDF wasn't
* defined.
*
* PUMAS_RETURN_UNKNOWN_PARTICLE The given type is not supported.
*
* PUMAS_RETURN_VALUE_ERROR A bad cutoff or elastic ratio
* was provided.
*/
PUMAS_API enum pumas_return pumas_physics_create(
struct pumas_physics ** physics, enum pumas_particle particle,
const char * mdf_path, const char * dedx_path,
const struct pumas_physics_settings * settings);
/**
* Destroy a physics instance.
*
* @param physics The physics tables.
*
* Finalise the physics and free its memory. Call `pumas_physics_create` or
* `pumas_physics_load` in order to reload the physics.
*
* __Note__: at return the *physics* pointer points to `NULL`.
*
* __Note__: finalising the physics does not release the memory allocated for
* related `pumas_context`. This must be done explictly with the
* `pumas_context_destroy` function.
*
* __Warning__: it is the user responsability to not use any simulation context
* whose physics would have been destroyed. Doing so would lead to
* unexpected results, e.g. memory corruption.
*
* __Warning__: this function is **not** thread safe.
*
*/
PUMAS_API void pumas_physics_destroy(struct pumas_physics ** physics);
/**
* Dump the physics tables to a file.
*
* @param physics The physics tables.
* @param stream The stream where to dump.
* @return On success `PUMAS_RETURN_SUCCESS` is returned otherwise an error
* code is returned as detailed below.
*
* Dump the *physics* tables to *stream* as a raw binary object. This binary
* dump can be re-loaded with the `pumas_physics_load` function. This provides a
* fast initialisation of the physics tables for subsequent uses.
*
* __Warning__: the binary dump is raw formated, thus *a priori* platform
* dependent.
*
* __Error codes__
*
* PUMAS_RETURN_PHYSICS_ERROR The physics is not initialised.
*
* PUMAS_RETURN_PATH_ERROR The output stream in invalid (NULL).
*
* PUMAS_RETURN_IO_ERROR Could not write to the stream.
*/
PUMAS_API enum pumas_return pumas_physics_dump(
const struct pumas_physics * physics, FILE * stream);
/**
* Load the physics tables from a file.
*
* @param physics The physics tables.
* @param stream The stream to load from.
* @return On success `PUMAS_RETURN_SUCCESS` is returned otherwise an error
* code is returned as detailed below.
*
* Load the physics tables from a binary dump previously generated with
* `pumas_physics_dump`.
*
* __Note__: loading to an already initialised physics instance generates an
* error. The `pumas_physics_destroy` function must be called first.
*
* __Warning__: the binary dump is raw formated, thus *a priori* platform
* dependent.
*
* __Error codes__
*
* PUMAS_RETURN_FORMAT_ERROR The binary dump is not compatible
* with the current version.
*
* PUMAS_RETURN_PHYSICS_ERROR The physics is not initialised.
*
* PUMAS_RETURN_PATH_ERROR The input stream in invalid (null).
*
* PUMAS_RETURN_IO_ERROR Could not read from the stream.
*/
PUMAS_API enum pumas_return pumas_physics_load(
struct pumas_physics ** physics, FILE * stream);
/**
* Get the cutoff value used by the physics.
*
* @param physcis The physics tables.
* @return The cutoff value or -1 if the physics is not properly initialised.
*
* The cutoff value between soft and hard energy losses is specified during the
* physics initialisation with `pumas_physics_create`. It cannot be modified
* afterwards. Instead a new physics object must be created.
*/
PUMAS_API double pumas_physics_cutoff(const struct pumas_physics * physics);
/**
* Get the elastic ratio value used by the physics.
*
* @param physics The physics tables.
* @return The elastic ratio or -1 if the physics is not properly initialised.
*
* The ratio of the m.f.p. to the transport m.f.p. for elastic events is
* specified during the physics initialisation with `pumas_physics_create`. It
* cannot be modified afterwards. Instead a new physics object must be created.
*/
PUMAS_API double pumas_physics_elastic_ratio(
const struct pumas_physics * physics);
/**