TkN 2.1
Toolkit for Nuclei
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 * This software is governed by the CeCILL-B license under French law and *
11 * abiding by the rules of distribution of free software. You can use, *
12 * modify and/ or redistribute the software under the terms of the *
13 * CeCILL-B license as circulated by CEA, CNRS and INRIA at the following *
14 * URL \"http://www.cecill.info\". *
15 * *
16 * As a counterpart to the access to the source code and rights to copy, *
17 * modify and redistribute granted by the license, users are provided *
18 * only with a limited warranty and the software's author, the holder of *
19 * the economic rights, and the successive licensors have only limited *
20 * liability. *
21 * *
22 * In this respect, the user's attention is drawn to the risks associated *
23 * with loading, using, modifying and/or developing or reproducing the *
24 * software by the user in light of its specific status of free software, *
25 * that may mean that it is complicated to manipulate, and that also *
26 * therefore means that it is reserved for developers and experienced *
27 * professionals having in-depth computer knowledge. Users are therefore *
28 * encouraged to load and test the software's suitability as regards *
29 * their requirements in conditions enabling the security of their *
30 * systems and/or data to be ensured and, more generally, to use and *
31 * operate it in the same conditions as regards security. *
32 * *
33 * The fact that you are presently reading this means that you have had *
34 * knowledge of the CeCILL-B license and that you accept its terms. *
35 ********************************************************************************/
36
37#include "tkensdf_record.h"
38#include "tklog.h"
39
40namespace tkn {
47}
48
49using namespace tkn;
50using namespace std;
51
52std::string tkensdf_record::BLANK = " ";
53
54bool tkensdf_record::set_record(const tkstring &_record)
55{
56 clear();
57
58 if(_record.size() != (RSIZE-1)) { // -1 to remove the \n
59 glog << error_v << "oups, record size: "<<_record.length()<<" not equal to RSIZE: "<<RSIZE-1<< do_endl;
60 return false;
61 }
62
63 frecord = _record;
64 fid = frecord.substr(5,4);
65
67
68 return true;
69}
70
71void tkensdf_record::add_continuation_record(const tkstring &_continuation_record)
72{
73 tkstring rec = _continuation_record;
74 rec.erase(0, 9);
75 rec.replace_all("'","''");
76 if(!fcontinuation_record.is_empty()) fcontinuation_record += "$";
77 fcontinuation_record += rec.remove_all_extra_white_space();
78}
79
80void tkensdf_record::add_comment_record(const tkstring &_record, bool _is_continuation)
81{
82 tkstring rec = _record;
83 rec.erase(0, 9);
84 rec.replace_all("'","''");
85 if(!_is_continuation && !fcomment_record.empty()) fcomment_record += "\n";
86 fcomment_record += rec.remove_all_extra_white_space() + " ";
87}
88
91{
92 tkstring field6 = fid.substr(0,1);
93 tkstring field7 = fid.substr(1,1);
94 tkstring field9 = fid.substr(3,1);
95
96 f_is_continuation_record = false;
97
98 // gamma record
99 if(fid.match("* G ")) {
100 ftype = kgamma;
101 if(!field6.is_empty()) f_is_continuation_record = true;
102 return;
103 }
104 // Comment record
105 if( !field7.is_empty() && ( field7.equal_to("C",tkstring::ECaseCompare::kIgnoreCase) ||
106 field7.equal_to("D",tkstring::ECaseCompare::kIgnoreCase) ||
107 field7.equal_to("T",tkstring::ECaseCompare::kIgnoreCase) ) ) {
108 ftype = kcomment;
109 if(!field6.is_empty()) f_is_continuation_record = true;
110 return;
111 }
112 // Level record
113 if(fid.match("* L ")) {
114 ftype = klevel;
115 if(!field6.is_empty()) f_is_continuation_record = true;
116 return;
117 }
118 // history record
119 if(fid.match("* H ")) {
120 ftype = khistory;
121 if(!field6.is_empty()) f_is_continuation_record = true;
122 return;
123 }
124 // EC record
125 if(fid.match("* E ")) {
126 ftype = kec;
127 if(!field6.is_empty()) f_is_continuation_record = true;
128 return;
129 }
130 // Beta record
131 if(fid.match("* B ")) {
132 ftype = kbeta;
133 if(!field6.is_empty()) f_is_continuation_record = true;
134 return;
135 }
136 // Termination record
137 if(frecord.is_empty()) {
138 ftype = kend;
139 return;
140 }
141 // identification record
142 if(fid.match("* ")) {
143 ftype = kident;
144 if(!field6.is_empty()) f_is_continuation_record = true;
145 return;
146 }
147 // X-ref record
148 if(fid.match(" X*") && !field9.is_empty()) {
149 ftype = kxref;
150 return;
151 }
152 // Production normalization record
153 if(fid.match("*PN*")) {
154 ftype = kprodnorm;
155 if(!field6.is_empty()) f_is_continuation_record = true;
156 return;
157 }
158 // Normalization record
159 if(fid.match(" N*")) {
160 ftype = knorm;
161 return;
162 }
163 // Q-value record
164 if(fid.match("* Q ")) {
165 ftype = kq_value;
166 if(!field6.is_empty()) f_is_continuation_record = true;
167 return;
168 }
169 // Parent record
170 if(fid.match(" P*")) {
171 ftype = kparent;
172 return;
173 }
174 // Alpha record
175 if(fid.match("* A ")) {
176 ftype = kalpha;
177 if(!field6.is_empty()) f_is_continuation_record = true;
178 return;
179 }
180 // particle record
181 if( (fid.match("* *") || fid.match("* D*")) && (field9.equal_to("N") || field9.equal_to("P") || field9.equal_to("A")) ) {
182 ftype = kparticle;
183 if(!field6.is_empty()) f_is_continuation_record = true;
184 return;
185 }
186 // reference record
187 if(fid.match(" R ")) {
188 ftype = kreference;
189 return;
190 }
191 ftype = kunknown;
192}
193
195{
196 // Check if the level includes an offset
197 size_t index=0;
198
199 tkstring tmp_e = _st.substr(0,10);
200 tkstring tmp_de = _st.substr(10,2);
201
202 tmp_e.remove_all(" ");
203 tmp_de.remove_all(" ");
204
205 // check if this is a resonance level => ignored
206 if(tmp_e.begins_with("SN+")) {
207 tmp_e.erase(0,3);
208 return false;
209 }
210 // check if this is a resonance level => ignored
211 if(tmp_e.begins_with("SP+")) {
212 tmp_e.erase(0,3);
213 return false;
214 }
215
216 // check if the level is at an undefined energy
217 if(tmp_e.substr(0,1).is_alpha()) {
218 fenergy.info += ";OFF=" + tmp_e;
219 set_offset(tmp_e.substr(0,1));
220 tmp_e.erase(0,1);
221 if(tmp_e.is_empty()) {
222 tmp_e="0";
223 }
224 else if(tmp_e.substr(0,1)=="+"){
225 tmp_e.erase(0,1);
226 }
227 }
228
229 // check if the energy is only known relatively to a level of unknwon energy
230 index = tmp_e.index("+");
231 if(index != std::string::npos && tmp_e.substr(index-1,1).to_lower() != "e") {
232 tkstring offset = tmp_e.substr(index+1);
233 fenergy.info += ";OFF=" + offset;
234 set_offset(offset);
235 tmp_e.erase(index);
236 }
237
238 // check if the energy is only temptative
239 index = tmp_e.index("(");
240 if(index != std::string::npos) {
241 tmp_e.remove_all("("); tmp_e.remove_all(")");
242 fenergy.info += ";VAL=()";
243 }
244 // check if something is remaining
245 if(tmp_e.empty()) {
246 return false;
247 }
248
249 fenergy.unit = "KEV";
250 fenergy.value = tmp_e.atof();
251
252 fenergy.filled = true;
253
254 // cases LT,GT,LE,GE,AP,CA,SY
255 if(tmp_de.is_alpha()) {
256 fenergy.info += ";ERR=" + tmp_de;
257 tmp_de="";
258 }
259
260 if(fenergy.value>0.) {
261 if(tmp_de.is_empty()) fenergy.info += ";ERR=?";
262 double precision = tkstring::get_precision(tmp_e);
263 fenergy.err = tmp_de.atof()*precision;
264 }
265
266 return true;
267}
268
269bool tkensdf_record::decode_lifetime(const tkstring &_st, const tkstring &_st_ms)
270{
271 tkstring tmp_lt = _st.substr(0,10);
272
273 if(tmp_lt.is_empty()) return false;
274
275 if(fglobal_time_unit=="skip") return false;
276
277 if(tmp_lt.contains("?")) {
278 flifetime.info = "? ";
279 tmp_lt.remove_all("?");
280 }
281
282 if(tmp_lt.contains("STABLE")) {
283 flifetime.value = 3.2E23;
284 flifetime.unit = "S";
285 flifetime.info += ";STABLE";
286 }
287 else {
288 auto tokens_lt = tmp_lt.tokenize(" ");
289 if(tokens_lt.size() !=2 && fglobal_time_unit.is_empty()) {
290 // in this specific case, the most probable scenario is that this field has been used for something else than lifetime
291 // glog << error << "problem in decoding life time in record: " << frecord << " (no unit given)" << do_endl;
292 return false;
293 }
294 flifetime.value = tokens_lt.front().atof();
295 if(tokens_lt.size() !=2 && !fglobal_time_unit.is_empty()) flifetime.unit = fglobal_time_unit;
296 else flifetime.unit = tokens_lt.back();
297 if(flifetime.unit.equal_to("m",tkstring::ECaseCompare::kIgnoreCase)) flifetime.unit = "MIN";
298
299 tkstring lt_err = _st.substr(10,6).strip_all_extra_white_space();
300 if(!lt_err.is_empty()) {
301
302 if(lt_err.is_alpha()) {
303 flifetime.info += ";ERR=" + lt_err;
304 }
305 else {
306 // define precision according to the value string
307 double precision = tkstring::get_precision(tokens_lt.front());
308
309 // check if asym errors
310 if(lt_err.contains("+") && lt_err.contains("-")) {
311 bool inv = lt_err.index("-") < lt_err.index("+");
312 lt_err.replace_all("+"," ");
313 lt_err.replace_all("-"," ");
314 auto tokens_lt_err = lt_err.tokenize(" ");
315 if(tokens_lt_err.size()!=2) {
316 glog << error << " bad asymetric error decoding in record " << frecord << do_endl;
317 return false;
318 }
319 tkstring err_low_str = tokens_lt_err.back();
320 tkstring err_high_str = tokens_lt_err.front();
321 if(inv) {
322 err_low_str = tokens_lt_err.front();
323 err_high_str = tokens_lt_err.back();
324 }
325
326 flifetime.err_low = err_low_str.atof()*precision;
327 flifetime.err_high = err_high_str.atof()*precision;
328 }
329 else {
330 flifetime.err = lt_err.atof()*precision;
331 }
332 }
333 }
334 else
335 flifetime.info += ";ERR=?";
336 }
337
338 if(!_st_ms.is_empty()) {
339 flifetime.info += ";ISO=" + _st_ms;
340 }
341
342 flifetime.filled = true;
343
344 return true;
345}
346
348{
349 fenergy.clear();
350 flifetime.clear();
351
352 frecord = "";
353 ftype = kunknown;
354 f_is_continuation_record = false;
355 fcontinuation_record = "";
356 fcomment_record = "";
357
358 fUncertain_record = "";
359
360 fisknown_woth_offset = false;
361 fOffset="";
362}
363
364void tkensdf_record::print(std::ostream &out) const
365{
366 out << "Record: " << frecord << std::endl;
367}
bool decode_lifetime(const tkstring &_st, const tkstring &_st_ms)
decode a lifetime record
bool decode_energy(const tkstring &_st)
decode an anergy record
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
tkstring fglobal_time_unit
virtual void clear()
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:54
tkstring strip_all_extra_white_space() const
Definition: tkstring.cpp:560
tkstring & to_lower()
Change all letters to lower case.
Definition: tkstring.cpp:59
std::vector< tkstring > tokenize(const tkstring &_delim=" ") const
Create a vector of string separated by at least one delimiter.
Definition: tkstring.cpp:254
bool is_empty() const
Definition: tkstring.h:163
tkstring & remove_all(const tkstring &_s1)
Definition: tkstring.h:215
tkstring substr(size_type __pos=0, size_type __n=npos) const
Inlines.
Definition: tkstring.h:179
bool match(const char *_pattern) const
Definition: tkstring.cpp:579
bool is_alpha() const
Checks whether tkstring is only composed of alphabetic letters.
Definition: tkstring.cpp:420
bool equal_to(const char *_s, ECaseCompare _cmp=kExact) const
Returns true if the string and _s are identical.
Definition: tkstring.cpp:234
size_t index(const char *_s, size_t _pos=0, ECaseCompare _cmp=kExact) const
Returns the index of the substring _s.
Definition: tkstring.cpp:218
tkstring & remove_all_extra_white_space()
Definition: tkstring.cpp:526
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
Definition: tkstring.h:197
bool begins_with(const char *_s, ECaseCompare _cmp=kExact) const
Definition: tkstring.h:185
static double get_precision(tkstring _st)
Extract the precision for a given ENSDF data.
Definition: tkstring.cpp:649
tkstring & replace_all(const tkstring &_s1, const tkstring &_s2)
Definition: tkstring.h:203
double atof() const
Converts a string to double value.
Definition: tkstring.cpp:191
Definition: tklog.cpp:39
tklog & error_v(tklog &log)
Definition: tklog.h:430
tklog & error(tklog &log)
Definition: tklog.h:367
tklog & do_endl(tklog &log)
Definition: tklog.h:235