TkN 2.4
Toolkit for Nuclei
Loading...
Searching...
No Matches
tkensdf_record.cpp
1/********************************************************************************
2 * Copyright (c) : Université de Lyon 1, CNRS/IN2P3, UMR5822, *
3 * IP2I, F-69622 Villeurbanne Cedex, France *
4 * Normandie Université, ENSICAEN, UNICAEN, CNRS/IN2P3, *
5 * LPC Caen, F-14000 Caen, France *
6 * Contibutor(s) : *
7 * Jérémie Dudouet jeremie.dudouet@cnrs.fr [2020] *
8 * Diego Gruyer diego.gruyer@cnrs.fr [2020] *
9 * *
10 * Licensed under the MIT License <http://opensource.org/licenses/MIT>. *
11 * SPDX-License-Identifier: MIT *
12 ********************************************************************************/
13
14#include "tkensdf_record.h"
15#include "tklog.h"
16
17namespace tkn {
24}
25
26using namespace tkn;
27using namespace std;
28
29std::string tkensdf_record::BLANK = " ";
30
32{
33 clear();
34
35 if(_record.size() != (RSIZE-1)) { // -1 to remove the \n
36 glog << error_v << "oups, record size: "<<_record.length()<<" not equal to RSIZE: "<<RSIZE-1<< do_endl;
37 return false;
38 }
39
40 frecord = _record;
41 fid = frecord.substr(5,4);
42
44
45 return true;
46}
47
48void tkensdf_record::add_continuation_record(const tkstring &_continuation_record)
49{
50 tkstring rec = _continuation_record;
51 rec.erase(0, 9);
52 rec.replace_all("'","''");
53 if(!fcontinuation_record.is_empty()) fcontinuation_record += "$";
54 fcontinuation_record += rec.remove_all_extra_white_space();
55}
56
57void tkensdf_record::add_comment_record(const tkstring &_record, bool _is_continuation)
58{
59 tkstring rec = _record;
60 rec.erase(0, 9);
61 rec.replace_all("'","''");
62 if(!_is_continuation && !fcomment_record.empty()) fcomment_record += "\n";
63 fcomment_record += rec.remove_all_extra_white_space() + " ";
64}
65
68{
69 tkstring field6 = fid.substr(0,1);
70 tkstring field7 = fid.substr(1,1);
71 tkstring field9 = fid.substr(3,1);
72
73 f_is_continuation_record = false;
74
75 // gamma record
76 if(fid.match("* G ")) {
77 ftype = kgamma;
78 if(!field6.is_empty()) f_is_continuation_record = true;
79 return;
80 }
81 // Comment record
82 if( !field7.is_empty() && ( field7.equal_to("C",tkstring::ECaseCompare::kIgnoreCase) ||
85 ftype = kcomment;
86 if(!field6.is_empty()) f_is_continuation_record = true;
87 return;
88 }
89 // Level record
90 if(fid.match("* L ")) {
91 ftype = klevel;
92 if(!field6.is_empty()) f_is_continuation_record = true;
93 return;
94 }
95 // history record
96 if(fid.match("* H ")) {
97 ftype = khistory;
98 if(!field6.is_empty()) f_is_continuation_record = true;
99 return;
100 }
101 // EC record
102 if(fid.match("* E ")) {
103 ftype = kec;
104 if(!field6.is_empty()) f_is_continuation_record = true;
105 return;
106 }
107 // Beta record
108 if(fid.match("* B ")) {
109 ftype = kbeta;
110 if(!field6.is_empty()) f_is_continuation_record = true;
111 return;
112 }
113 // Termination record
114 if(frecord.is_empty()) {
115 ftype = kend;
116 return;
117 }
118 // identification record
119 if(fid.match("* ")) {
120 ftype = kident;
121 if(!field6.is_empty()) f_is_continuation_record = true;
122 return;
123 }
124 // X-ref record
125 if(fid.match(" X*") && !field9.is_empty()) {
126 ftype = kxref;
127 return;
128 }
129 // Production normalization record
130 if(fid.match("*PN*")) {
131 ftype = kprodnorm;
132 if(!field6.is_empty()) f_is_continuation_record = true;
133 return;
134 }
135 // Normalization record
136 if(fid.match(" N*")) {
137 ftype = knorm;
138 return;
139 }
140 // Q-value record
141 if(fid.match("* Q ")) {
142 ftype = kq_value;
143 if(!field6.is_empty()) f_is_continuation_record = true;
144 return;
145 }
146 // Parent record
147 if(fid.match(" P*")) {
148 ftype = kparent;
149 return;
150 }
151 // Alpha record
152 if(fid.match("* A ")) {
153 ftype = kalpha;
154 if(!field6.is_empty()) f_is_continuation_record = true;
155 return;
156 }
157 // particle record
158 if( (fid.match("* *") || fid.match("* D*")) && (field9.equal_to("N") || field9.equal_to("P") || field9.equal_to("A")) ) {
159 ftype = kparticle;
160 if(!field6.is_empty()) f_is_continuation_record = true;
161 return;
162 }
163 // reference record
164 if(fid.match(" R ")) {
165 ftype = kreference;
166 return;
167 }
168 ftype = kunknown;
169}
170
172{
173 // Check if the level includes an offset
174 size_t index=0;
175
176 tkstring tmp_e = _st.substr(0,10);
177 tkstring tmp_de = _st.substr(10,2);
178
179 tmp_e.remove_all(" ");
180 tmp_de.remove_all(" ");
181
182 // check if this is a resonance level => ignored
183 if(tmp_e.begins_with("SN+")) {
184 tmp_e.erase(0,3);
185 return false;
186 }
187 // check if this is a resonance level => ignored
188 if(tmp_e.begins_with("SP+")) {
189 tmp_e.erase(0,3);
190 return false;
191 }
192
193 // check if the level is at an undefined energy
194 if(tmp_e.substr(0,1).is_alpha()) {
195 fenergy.info += ";OFF=" + tmp_e;
196 set_offset(tmp_e.substr(0,1));
197 tmp_e.erase(0,1);
198 if(tmp_e.is_empty()) {
199 tmp_e="0";
200 }
201 else if(tmp_e.substr(0,1)=="+"){
202 tmp_e.erase(0,1);
203 }
204 }
205
206 // check if the energy is only known relatively to a level of unknwon energy
207 index = tmp_e.index("+");
208 if(index != std::string::npos && tmp_e.substr(index-1,1).to_lower() != "e") {
209 tkstring offset = tmp_e.substr(index+1);
210 fenergy.info += ";OFF=" + offset;
211 set_offset(offset);
212 tmp_e.erase(index);
213 }
214
215 // check if the energy is only temptative
216 index = tmp_e.index("(");
217 if(index != std::string::npos) {
218 tmp_e.remove_all("("); tmp_e.remove_all(")");
219 fenergy.info += ";VAL=()";
220 }
221 // check if something is remaining
222 if(tmp_e.empty()) {
223 return false;
224 }
225
226 fenergy.unit = "KEV";
227 fenergy.value = tmp_e.atof();
228
229 fenergy.filled = true;
230
231 // cases LT,GT,LE,GE,AP,CA,SY
232 if(tmp_de.is_alpha()) {
233 fenergy.info += ";ERR=" + tmp_de;
234 tmp_de="";
235 }
236
237 if(fenergy.value>0.) {
238 if(tmp_de.is_empty()) fenergy.info += ";ERR=?";
239 double precision = tkstring::get_precision(tmp_e);
240 fenergy.err = tmp_de.atof()*precision;
241 }
242
243 return true;
244}
245
246bool tkensdf_record::decode_lifetime(const tkstring &_st, const tkstring &_st_ms)
247{
248 tkstring tmp_lt = _st.substr(0,10);
249
250 if(tmp_lt.is_empty()) return false;
251
252 if(fglobal_time_unit=="skip") return false;
253
254 if(tmp_lt.contains("?")) {
255 flifetime.info = "? ";
256 tmp_lt.remove_all("?");
257 }
258
259 if(tmp_lt.contains("STABLE")) {
260 flifetime.value = 3.2E23;
261 flifetime.unit = "S";
262 flifetime.info += ";STABLE";
263 }
264 else {
265 auto tokens_lt = tmp_lt.tokenize(" ");
266 if(tokens_lt.size() !=2 && fglobal_time_unit.is_empty()) {
267 // in this specific case, the most probable scenario is that this field has been used for something else than lifetime
268 // glog << error << "problem in decoding life time in record: " << frecord << " (no unit given)" << do_endl;
269 return false;
270 }
271 flifetime.value = tokens_lt.front().atof();
272 if(tokens_lt.size() !=2 && !fglobal_time_unit.is_empty()) flifetime.unit = fglobal_time_unit;
273 else flifetime.unit = tokens_lt.back();
274 if(flifetime.unit.equal_to("m",tkstring::ECaseCompare::kIgnoreCase)) flifetime.unit = "MIN";
275
276 tkstring lt_err = _st.substr(10,6).strip_all_extra_white_space();
277 if(!lt_err.is_empty()) {
278
279 if(lt_err.is_alpha()) {
280 flifetime.info += ";ERR=" + lt_err;
281 }
282 else {
283 // define precision according to the value string
284 double precision = tkstring::get_precision(tokens_lt.front());
285
286 // check if asym errors
287 if(lt_err.contains("+") && lt_err.contains("-")) {
288 bool inv = lt_err.index("-") < lt_err.index("+");
289 lt_err.replace_all("+"," ");
290 lt_err.replace_all("-"," ");
291 auto tokens_lt_err = lt_err.tokenize(" ");
292 if(tokens_lt_err.size()!=2) {
293 glog << error << " bad asymetric error decoding in record " << frecord << do_endl;
294 return false;
295 }
296 tkstring err_low_str = tokens_lt_err.back();
297 tkstring err_high_str = tokens_lt_err.front();
298 if(inv) {
299 err_low_str = tokens_lt_err.front();
300 err_high_str = tokens_lt_err.back();
301 }
302
303 flifetime.err_low = err_low_str.atof()*precision;
304 flifetime.err_high = err_high_str.atof()*precision;
305 }
306 else {
307 flifetime.err = lt_err.atof()*precision;
308 }
309 }
310 }
311 else
312 flifetime.info += ";ERR=?";
313 }
314
315 if(!_st_ms.is_empty()) {
316 flifetime.info += ";ISO=" + _st_ms;
317 }
318
319 flifetime.filled = true;
320
321 return true;
322}
323
325{
326 fenergy.clear();
327 flifetime.clear();
328
329 frecord = "";
330 ftype = kunknown;
331 f_is_continuation_record = false;
332 fcontinuation_record = "";
333 fcomment_record = "";
334
335 fUncertain_record = "";
336
337 fisknown_woth_offset = false;
338 fOffset="";
339}
340
341void tkensdf_record::print(std::ostream &out) const
342{
343 out << "Record: " << frecord << std::endl;
344}
bool decode_lifetime(const tkstring &_st, const tkstring &_st_ms)
decode a lifetime record
bool decode_energy(const tkstring &_st)
decode an anergy record
static std::string BLANK
void check_record_type()
check record type from its string
virtual void print(std::ostream &) const
virtual void add_comment_record(const tkstring &_comment_record, bool _is_continuation=false)
add a continuation record from a string
virtual bool set_record(const tkstring &_record)
define the record from a string. Option false only checks if the record is an identification record
virtual void add_continuation_record(const tkstring &_continuation_record)
add a continuation record from a string
static const int RSIZE
void set_offset(tkstring _offset)
set_energy_offset
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
Definition tkstring.h:31
tkstring strip_all_extra_white_space() const
Definition tkstring.cpp:537
tkstring & to_lower()
Change all letters to lower case.
Definition tkstring.cpp:36
std::vector< tkstring > tokenize(const tkstring &_delim=" ") const
Create a vector of string separated by at least one delimiter.
Definition tkstring.cpp:231
bool is_empty() const
Definition tkstring.h:140
tkstring & remove_all(const tkstring &_s1)
Definition tkstring.h:192
tkstring substr(size_type __pos=0, size_type __n=npos) const
Inlines.
Definition tkstring.h:156
bool is_alpha() const
Checks whether tkstring is only composed of alphabetic letters.
Definition tkstring.cpp:397
bool equal_to(const char *_s, ECaseCompare _cmp=kExact) const
Returns true if the string and _s are identical.
Definition tkstring.cpp:211
size_t index(const char *_s, size_t _pos=0, ECaseCompare _cmp=kExact) const
Returns the index of the substring _s.
Definition tkstring.cpp:195
tkstring & remove_all_extra_white_space()
Definition tkstring.cpp:503
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
Definition tkstring.h:174
bool begins_with(const char *_s, ECaseCompare _cmp=kExact) const
Definition tkstring.h:162
static double get_precision(tkstring _st)
Extract the precision for a given ENSDF data.
Definition tkstring.cpp:626
tkstring & replace_all(const tkstring &_s1, const tkstring &_s2)
Definition tkstring.h:180
double atof() const
Converts a string to double value.
Definition tkstring.cpp:168
Definition tklog.cpp:16
tklog & error_v(tklog &log)
Definition tklog.h:407
tklog & error(tklog &log)
Definition tklog.h:344
tklog & do_endl(tklog &log)
Definition tklog.h:212