1
+ #pragma once
2
+
3
+ #include < vector>
4
+ #include < string>
5
+ #include < cstdint>
6
+ #include < map>
7
+ #include < memory>
8
+ #include < chrono>
9
+
10
+ namespace CAMInputOutput {
11
+
12
+ // Structs
13
+ struct EfficiencyPoint {
14
+ int Index;
15
+ double Energy;
16
+ double Efficiency;
17
+ double EfficiencyUncertainty;
18
+ };
19
+
20
+ struct Peak {
21
+ double Energy;
22
+ double Centroid;
23
+ double CentroidUncertainty;
24
+ double FullWidthAtHalfMaximum;
25
+ double LowTail;
26
+ double Area;
27
+ double AreaUncertainty;
28
+ double Continuum;
29
+ double CriticalLevel;
30
+ double CountRate;
31
+ double CountRateUncertainty;
32
+
33
+ Peak () = default ;
34
+ Peak (double energy, double centrd, double centrdUnc, double fwhm, double lowTail,
35
+ double area, double areaUnc, double continuum, double critialLevel,
36
+ double cntRate, double cntRateUnc);
37
+ };
38
+
39
+ struct Nuclide {
40
+ std::string Name;
41
+ double HalfLife = 0 .;
42
+ double HalfLifeUncertainty = 0 .;
43
+ std::string HalfLifeUnit;
44
+ int Index = -1 ;
45
+ int AtomicNumber = 0 ;
46
+ std::string ElementSymbol;
47
+ std::string Metastable;
48
+
49
+ Nuclide () = default ;
50
+ Nuclide (const std::string& name, double halfLife, double halfLifeUnc,
51
+ const std::string& halfLifeUnit, int nucNo);
52
+
53
+ inline bool operator ==(const Nuclide & other) const
54
+ {
55
+ return Name == other.Name ;
56
+ }
57
+
58
+
59
+ };
60
+
61
+ struct Line {
62
+ double Energy;
63
+ double EnergyUncertainty;
64
+ double Abundance;
65
+ double AbundanceUncertainty;
66
+ bool IsKeyLine;
67
+ int NuclideIndex;
68
+ bool NoWeightMean;
69
+
70
+ Line () = default ;
71
+ Line (double energy, double energyUnc, double abundance, double abundanceUnc,
72
+ int nucNo, bool key = false , bool noWgtMean = false );
73
+ };
74
+
75
+ // Main CAMIO class
76
+ class CAMIO {
77
+ public:
78
+ enum class CAMBlock : uint32_t {
79
+ ACQP = 0x00012000 ,
80
+ SAMP = 0x00012001 ,
81
+ GEOM = 0x00012002 ,
82
+ PROC = 0x00012003 ,
83
+ DISP = 0x00012004 ,
84
+ SPEC = 0x00012005 , // also known as DATA
85
+ PEAK = 0x00012006 ,
86
+ NUCL = 0x00012007 ,
87
+ NLINES = 0x00012008
88
+ };
89
+
90
+ enum class RecordSize : uint16_t {
91
+ ACQP = 0x051C ,
92
+ NUCL = 0x023B ,
93
+ NLINES = 0x0085
94
+ };
95
+
96
+ enum class BlockSize : uint16_t {
97
+ ACQP = 0xA00U ,
98
+ PROC = 0x800 ,
99
+ NUCL = 0x4800U ,
100
+ NLINES = 0x4200U
101
+ };
102
+
103
+ enum class PeakParameterLocation : uint8_t {
104
+ Energy = 0x0 ,
105
+ Centroid = 0x40 ,
106
+ CentroidUncertainty = 0x40 ,
107
+ FullWidthAtHalfMaximum = 0x10 ,
108
+ LowTail = 0x50 ,
109
+ Area = 0x34 ,
110
+ AreaUncertainty = 0x84 ,
111
+ Continuum = 0x0C ,
112
+ CriticalLevel = 0x0D1 ,
113
+ CountRate = 0x18 ,
114
+ CountRateUncertainty = 0x1C
115
+ };
116
+
117
+ enum class EfficiencyPointParameterLocation : uint8_t {
118
+ Energy = 0x01 ,
119
+ Efficiency = 0x05 ,
120
+ EfficiencyUncertainty = 0x09
121
+ };
122
+
123
+ enum NuclideParameterLocation : uint8_t
124
+ {
125
+ Name = 0x03 ,
126
+ HalfLife = 0x1B ,
127
+ HalfLifeUncertainty = 0x89 ,
128
+ HalfLifeUnit = 0x61 ,
129
+ MeanActivity = 0x57 ,
130
+ MeanActivityUnceratinty = 0x69 ,
131
+ NuclideMDA = 0x27
132
+ };
133
+
134
+ enum LineParameterLocation : uint8_t
135
+ {
136
+ Energy = 0x01 ,
137
+ EnergyUncertainty = 0x21 ,
138
+ Abundance = 0x05 ,
139
+ AbundanceUncertainty = 0x39 ,
140
+ IsKeyLine = 0x1D ,
141
+ NuclideIndex = 0x1B ,
142
+ NoWeightMean = 0x1F ,
143
+ LineActivity = 0x0B ,
144
+ LineActivityUnceratinty = 0x13 ,
145
+ LineEfficiency = 0x31 ,
146
+ LineEfficiencyUncertainty = 0x35 ,
147
+ LineMDA = 0x25 ,
148
+ };
149
+
150
+ private:
151
+ std::multimap<CAMBlock, uint32_t > blockAddresses;
152
+ std::vector<uint8_t > readData;
153
+ std::vector<std::vector<uint8_t >> lines;
154
+ std::vector<std::vector<uint8_t >> nucs;
155
+ std::vector<Nuclide> writeNuclides;
156
+ std::vector<Line> fileLines;
157
+ std::vector<Nuclide> fileNuclides;
158
+ std::vector<EfficiencyPoint> efficiencyPoints;
159
+ std::vector<Peak> peaks;
160
+
161
+ static constexpr uint16_t header_size = 0x800 ;
162
+ static constexpr uint16_t block_header_size = 0x30 ;
163
+ static constexpr uint8_t nuclide_line_size = 0x03 ;
164
+
165
+ float key_line_intf_limit = 2.0 ; // keV
166
+
167
+ public:
168
+ CAMIO ();
169
+ void ReadFile (const std::string& fileName);
170
+ std::vector<Line> GetLines ();
171
+ std::vector<Nuclide> GetNuclides ();
172
+ std::vector<Peak> GetPeaks ();
173
+ std::vector<EfficiencyPoint> GetEfficiencyPoints ();
174
+ SpecUtils::time_point_t GetSampleTime ();
175
+ SpecUtils::time_point_t GetAquisitionTime ();
176
+ float GetLiveTime ();
177
+ float GetRealTime ();
178
+ std::vector<float > GetShapeCalibration ();
179
+ std::vector<float > GetEnergyCalibration ();
180
+ std::vector<uint32_t > GetSpectrum ();
181
+ void CreateFile (const std::string& filePath);
182
+ void CreateFile (std::shared_ptr<SpecUtils::Measurement> summed);
183
+ void AddNuclide (const std::string& name, const float halfLife,
184
+ const float halfLifeUnc, const std::string& halfLifeUnit, const int nucNo = -1 );
185
+ void AddNuclide (const Nuclide& nuc);
186
+ void AddLine (const float energy, const float enUnc, const float yield,
187
+ const float yieldUnc, const int nucNo, const bool key = false );
188
+ void AddLine (const Line& line);
189
+ void AddLineAndNuclide (const float energy, const float yield, const std::string& name,
190
+ const float halfLife, const std::string& halfLifeUnit, const bool noWeightMean = false ,
191
+ const float enUnc = -1 , const float yieldUnc = -1 , const float halfLifeUnc = -1 );
192
+
193
+ inline void SetKeyLineInerferenceLimit (const float limit) { key_line_intf_limit = limit; };
194
+ float GetKeyLineInerferenceLimit () const { return key_line_intf_limit; }
195
+
196
+ protected:
197
+ std::multimap<CAMBlock, uint32_t > ReadHeader ();
198
+ void ReadBlock (CAMBlock block);
199
+ std::vector<uint8_t > GenerateBlock (CAMBlock block, size_t loc,
200
+ const std::vector<std::vector<uint8_t >>& records = std::vector<std::vector<uint8_t >>(),
201
+ uint16_t blockNo = 0, bool hasCommon = true);
202
+ std::vector<uint8_t > GenerateBlockHeader (CAMBlock block, size_t loc, uint16_t numRec = 1 ,
203
+ uint16_t numLines = 1 , uint16_t blockNum = 0 , bool hasCommon = false );
204
+ uint16_t GetNumLines (const std::vector<uint8_t >& nuclRecord);
205
+ std::vector<uint8_t > GenerateNuclide (const std::string& name, float halfLife,
206
+ float halfLifeUnc, const std::string& halfLifeUnit,
207
+ const std::vector<uint16_t >& lineNums);
208
+ std::vector<uint8_t > AddLinesToNuclide (const std::vector<uint8_t >& nuc,
209
+ const std::vector<uint8_t >& lineNums);
210
+ std::vector<uint8_t > GenerateLine (float energy, float enUnc, float yield,
211
+ float yieldUnc, bool key, uint8_t nucNo, bool noWgtMn);
212
+ void AssignKeyLines ();
213
+
214
+ protected:
215
+ // Add block reading function declarations
216
+ void ReadGeometryBlock (size_t pos, uint16_t records);
217
+ void ReadLinesBlock (size_t pos, uint16_t records);
218
+ void ReadNuclidesBlock (size_t pos, uint16_t records);
219
+ void ReadPeaksBlock (size_t pos, uint16_t records);
220
+
221
+ // Add GenerateFile declaration
222
+ std::vector<uint8_t > GenerateFile (const std::vector<std::vector<uint8_t >>& blocks);
223
+
224
+ float ComputeUncertainty (float value);
225
+ };
226
+
227
+ // Helper class for comparing lines
228
+ class LineComparer {
229
+ public:
230
+ bool operator ()(const std::vector<uint8_t >& x, const std::vector<uint8_t >& y) const ;
231
+ };
232
+
233
+ class NuclideComparer {
234
+ public:
235
+ bool operator ()(const std::vector<uint8_t >& x, const std::vector<uint8_t >& y) const ;
236
+ };
237
+
238
+ } // namespace CAMInputOutput
0 commit comments