musrfit 1.10.0
msr2msr.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 msr2msr.cpp
4
5 Author: Andreas Suter
6 e-mail: andreas.suter@psi.ch
7
8***************************************************************************/
9
10/***************************************************************************
11 * Copyright (C) 2007-2026 by Andreas Suter *
12 * andreas.suter@psi.ch *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28 ***************************************************************************/
29
30#include <iostream>
31#include <fstream>
32
33#include <cctype>
34#include <cstring>
35#include <cstdlib>
36
37#include <TString.h>
38
39#include "PStringUtils.h"
40
41//-------------------------------------------------------------
42// msr block header tags
43#define MSR_TAG_TITLE 0
44#define MSR_TAG_FITPARAMETER 1
45#define MSR_TAG_THEORY 2
46#define MSR_TAG_FUNCTIONS 3
47#define MSR_TAG_RUN 4
48#define MSR_TAG_COMMANDS 5
49#define MSR_TAG_PLOT 6
50#define MSR_TAG_STATISTIC 7
51#define MSR_TAG_NO_BLOCK 8
52
53//-------------------------------------------------------------
54// msr theory tags
55#define MSR_THEORY_INTERN_FLD 0
56#define MSR_THEORY_INTERN_BESSEL 1
57
58//--------------------------------------------------------------------------
63{
64 std::cout << std::endl << "usage: msr2msr <msr-file-in> <msr-file-out> | [--help]";
65 std::cout << std::endl << " <msr-file-in> : input msr-file";
66 std::cout << std::endl << " <msr-file-out>: converted msr-output-file";
67 std::cout << std::endl << " if the <msr-file-in> is already in the 2008 format";
68 std::cout << std::endl << " the output file will be identical to the input file.";
69 std::cout << std::endl << std::endl;
70}
71
72//--------------------------------------------------------------------------
83bool msr2msr_run(char *str, const std::size_t size)
84{
85 // not the RUN line itself, hence nothing to be done
86 if (!strstr(str, "RUN"))
87 return true;
88
89 TString run(str);
90 TString line(str);
91
92 // for filtering
93 run.ToUpper();
94
95 // remove run comment, i.e. (name ...
96 Ssiz_t idx = line.Index("(");
97 if (idx > 0)
98 line.Remove(idx);
99
100 // tokenize run
101 std::vector<std::string> tokens = PStringUtils::Split(line.Data(), " \t");
102 if (tokens.size() < 4) {
103 std::cout << std::endl << "**ERROR**: Something is wrong with the RUN block header:";
104 std::cout << std::endl << " >> " << str;
105 std::cout << std::endl << " >> no <msr-file-out> is created";
106 std::cout << std::endl;
107 return false;
108 }
109
110 if (tokens.size() == 5) { // already a new msr file, do only add the proper run comment
111 snprintf(str, size, "%s (name beamline institute data-file-format)", line.Data());
112 return true;
113 }
114
115 if (run.Contains("NEMU")) {
116 snprintf(str, size, "RUN %s MUE4 PSI WKM (name beamline institute data-file-format)", tokens[1].c_str());
117 } else if (run.Contains("PSI")) {
118 snprintf(str, size, "RUN %s %s PSI PSI-BIN (name beamline institute data-file-format)",
119 tokens[1].c_str(), tokens[2].c_str());
120 } else if (run.Contains("TRIUMF")) {
121 snprintf(str, size, "RUN %s %s TRIUMF MUD (name beamline institute data-file-format)",
122 tokens[1].c_str(), tokens[2].c_str());
123 } else if (run.Contains("RAL")) {
124 snprintf(str, size, "RUN %s %s RAL NEXUS (name beamline institute data-file-format)",
125 tokens[1].c_str(), tokens[2].c_str());
126 }
127
128 return true;
129}
130
131//--------------------------------------------------------------------------
143bool msr2msr_param(char *str)
144{
145 // check for comment header which needs to be replaced
146 if (strstr(str, "Nr.")) {
147 strcpy(str, "# No Name Value Step Pos_Error Boundaries");
148 return true;
149 }
150
151 // handle parameter line
152 TString line(str);
153 char sstr[256];
154 char spaces[256];
155
156 std::vector<std::string> tokens = PStringUtils::Split(line.Data(), " \t");
157 std::size_t noTokens = tokens.size();
158 if (noTokens == 4) {
159 // number
160 snprintf(sstr, sizeof(sstr), "%10s", tokens[0].c_str());
161 // name
162 strcat(sstr, " ");
163 strcat(sstr, tokens[1].c_str());
164 memset(spaces, 0, sizeof(spaces));
165 memset(spaces, ' ', 12-strlen(tokens[1].c_str()));
166 strcat(sstr, spaces);
167 // value
168 strcat(sstr, tokens[2].c_str());
169 if (strlen(tokens[2].c_str()) < 10) {
170 memset(spaces, 0, sizeof(spaces));
171 memset(spaces, ' ', 10-strlen(tokens[2].c_str()));
172 strcat(sstr, spaces);
173 } else {
174 strcat(sstr, " ");
175 }
176 // step
177 strcat(sstr, tokens[3].c_str());
178 if (strlen(tokens[3].c_str()) < 12) {
179 memset(spaces, 0, sizeof(spaces));
180 memset(spaces, ' ', 12-strlen(tokens[3].c_str()));
181 strcat(sstr, spaces);
182 } else {
183 strcat(sstr, " ");
184 }
185 strcat(sstr, "none");
186 strcpy(str, sstr);
187 } else if (noTokens == 6) {
188 // number
189 snprintf(sstr, sizeof(sstr), "%10s", tokens[0].c_str());
190 // name
191 strcat(sstr, " ");
192 strcat(sstr, tokens[1].c_str());
193 memset(spaces, 0, sizeof(spaces));
194 memset(spaces, ' ', 12-strlen(tokens[1].c_str()));
195 strcat(sstr, spaces);
196 // value
197 strcat(sstr, tokens[2].c_str());
198 if (strlen(tokens[2].c_str()) < 10) {
199 memset(spaces, 0, sizeof(spaces));
200 memset(spaces, ' ', 10-strlen(tokens[2].c_str()));
201 strcat(sstr, spaces);
202 } else {
203 strcat(sstr, " ");
204 }
205 // step
206 strcat(sstr, tokens[3].c_str());
207 if (strlen(tokens[3].c_str()) < 12) {
208 memset(spaces, 0, sizeof(spaces));
209 memset(spaces, ' ', 12-strlen(tokens[3].c_str()));
210 strcat(sstr, spaces);
211 } else {
212 strcat(sstr, " ");
213 }
214 // pos. error
215 strcat(sstr, "none ");
216 // lower boundary
217 strcat(sstr, tokens[4].c_str());
218 if (strlen(tokens[4].c_str()) < 8) {
219 memset(spaces, 0, sizeof(spaces));
220 memset(spaces, ' ', 8-strlen(tokens[4].c_str()));
221 strcat(sstr, spaces);
222 } else {
223 strcat(sstr, " ");
224 }
225 // upper boundary
226 strcat(sstr, tokens[5].c_str());
227 strcpy(str, sstr);
228 }
229
230 return true;
231}
232
233//--------------------------------------------------------------------------
246bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams)
247{
248 // handle theory line
249 TString line(str);
250 std::vector<std::string> tokens;
251 char sstr[256];
252
253 if ((line.Contains("sktt") || line.Contains("statKTTab")) && line.Contains("glf")) { // static Gauss KT LF table
254 // change cmd name
255 strcpy(sstr, "statGssKTLF ");
256
257 // tokenize the rest and extract the first two parameters
258 tokens = PStringUtils::Split(line.Data(), " \t");
259 std::size_t noTokens = tokens.size();
260 if (noTokens < 3) {
261 std::cout << std::endl << "**ERROR** in THEORY block";
262 std::cout << std::endl << " Line: '" << str << "' is not a valid statKTTab statement.";
263 std::cout << std::endl << " Cannot handle file." << std::endl;
264 return false;
265 }
266 for (Int_t i=1; i<3; i++) {
267 strcat(sstr, " ");
268 strcat(sstr, tokens[i].c_str());
269 }
270 strcat(sstr, " (frequency damping)");
271 strcpy(str, sstr);
272 } else if ((line.Contains("sktt") || line.Contains("statKTTab")) && line.Contains("llf")) { // static Lorentz KT LF table
273 // change cmd name
274 strcpy(sstr, "statExpKTLF ");
275
276 // tokenize the rest and extract the first two parameters
277 tokens = PStringUtils::Split(line.Data(), " \t");
278 std::size_t noTokens = tokens.size();
279 if (noTokens < 3) {
280 std::cout << std::endl << "**ERROR** in THEORY block";
281 std::cout << std::endl << " Line: '" << str << "' is not a valid statKTTab statement.";
282 std::cout << std::endl << " Cannot handle file." << std::endl;
283 return false;
284 }
285 for (Int_t i=1; i<3; i++) {
286 strcat(sstr, " ");
287 strcat(sstr, tokens[i].c_str());
288 }
289 strcat(sstr, " (frequency damping)");
290 strcpy(str, sstr);
291 } else if ((line.Contains("dktt") || line.Contains("dynmKTTab")) && line.Contains("kdglf")) { // dynamic Gauss KT LF table
292 // change cmd name
293 strcpy(sstr, "dynGssKTLF ");
294
295 // tokenize the rest and extract the first three parameters
296 tokens = PStringUtils::Split(line.Data(), " \t");
297 std::size_t noTokens = tokens.size();
298 if (noTokens < 4) {
299 std::cout << std::endl << "**ERROR** in THEORY block";
300 std::cout << std::endl << " Line: '" << str << "' is not a valid dynmKTTab statement.";
301 std::cout << std::endl << " Cannot handle file." << std::endl;
302 return false;
303 }
304 for (Int_t i=1; i<4; i++) {
305 strcat(sstr, " ");
306 strcat(sstr, tokens[i].c_str());
307 }
308 strcat(sstr, " (frequency damping hopping-rate)");
309 strcpy(str, sstr);
310 } else if ((line.Contains("dktt") || line.Contains("dynmKTTab")) && line.Contains("kdllf")) { // dynamic Lorentz KT LF table
311 // change cmd name
312 strcpy(sstr, "dynExpKTLF ");
313
314 // tokenize the rest and extract the first three parameters
315 tokens = PStringUtils::Split(line.Data(), " \t");
316 std::size_t noTokens = tokens.size();
317 if (noTokens < 4) {
318 std::cout << std::endl << "**ERROR** in THEORY block";
319 std::cout << std::endl << " Line: '" << str << "' is not a valid dynmKTTab statement.";
320 std::cout << std::endl << " Cannot handle file." << std::endl;
321 return false;
322 }
323 for (Int_t i=1; i<4; i++) {
324 strcat(sstr, " ");
325 strcat(sstr, tokens[i].c_str());
326 }
327 strcat(sstr, " (frequency damping hopping-rate)");
328 strcpy(str, sstr);
329 } else if (line.Contains("internFld")) {
331 noOfAddionalParams++;
332
333 // change cmd name
334 strcpy(sstr, "internFld ");
335
336 // tokenize the rest and extract the first three parameters
337 tokens = PStringUtils::Split(line.Data(), " \t");
338 std::size_t noTokens = tokens.size();
339 if (noTokens < 4) {
340 std::cout << std::endl << "**ERROR** in THEORY block";
341 std::cout << std::endl << " Line: '" << str << "' is not a valid internFld statement.";
342 std::cout << std::endl << " Cannot handle file." << std::endl;
343 return false;
344 }
345 strcat(sstr, " _x_");
346 for (Int_t i=1; i<4; i++) {
347 strcat(sstr, " ");
348 strcat(sstr, tokens[i].c_str());
349 }
350 strcat(sstr, " (fraction phase frequency Trate Lrate)");
351 strcpy(str, sstr);
352 } else if (line.Contains("internBsl")) {
354 noOfAddionalParams++;
355
356 // change cmd name
357 strcpy(sstr, "internBsl ");
358
359 // tokenize the rest and extract the first three parameters
360 tokens = PStringUtils::Split(line.Data(), " \t");
361 std::size_t noTokens = tokens.size();
362 if (noTokens < 4) {
363 std::cout << std::endl << "**ERROR** in THEORY block";
364 std::cout << std::endl << " Line: '" << str << "' is not a valid internBsl statement.";
365 std::cout << std::endl << " Cannot handle file." << std::endl;
366 return false;
367 }
368 strcat(sstr, " _x_");
369 for (Int_t i=1; i<4; i++) {
370 strcat(sstr, " ");
371 strcat(sstr, tokens[i].c_str());
372 }
373 strcat(sstr, " (fraction phase frequency Trate Lrate)");
374 strcpy(str, sstr);
375 }
376
377 return true;
378}
379
380
381//--------------------------------------------------------------------------
391bool msr2msr_is_comment(char *str)
392{
393 bool isComment = false;
394
395 for (unsigned int i=0; i<strlen(str); i++) {
396 if ((str[i] == ' ') || (str[i] == '\t'))
397 continue;
398 if (str[i] == '#') {
399 isComment = true;
400 break;
401 } else {
402 isComment = false;
403 break;
404 }
405 }
406
407 return isComment;
408}
409
410//--------------------------------------------------------------------------
421{
422 bool isWhitespace = true;
423
424 if (strlen(str) != 0) {
425 for (unsigned int i=0; i<strlen(str); i++) {
426 if ((str[i] != ' ') && (str[i] != '\t')) {
427 isWhitespace = false;
428 break;
429 }
430 }
431 }
432
433 return isWhitespace;
434}
435
436//--------------------------------------------------------------------------
443void msr2msr_replace(char *str, int paramNo)
444{
445 char temp[128];
446 char no[16];
447
448 memset(temp, 0, sizeof(temp));
449
450 snprintf(no, sizeof(no), "%d", paramNo);
451
452 int j=0;
453 for (unsigned int i=0; i<strlen(str); i++) {
454 if (str[i] != '_') {
455 temp[j] = str[i];
456 j++;
457 } else {
458 for (unsigned int k=0; k<strlen(no); k++)
459 temp[j+k] = no[k];
460 j += strlen(no);
461 i += 2;
462 }
463 }
464
465 strcpy(str, temp);
466}
467
468//--------------------------------------------------------------------------
477bool msr2msr_finalize_theory(char *fln, int theoryTag, int noOfAddionalParams)
478{
479 std::ifstream fin;
480 fin.open(fln, std::iostream::in);
481 if (!fin.is_open()) {
482 std::cout << std::endl << "**ERROR**: Couldn't open input msr-file " << fln;
483 std::cout << std::endl << " Will quit." << std::endl;
484 return 0;
485 }
486
487 // open temporary output msr-file
488 std::ofstream fout;
489 fout.open("__temp.msr", std::iostream::out);
490 if (!fout.is_open()) {
491 std::cout << std::endl << "**ERROR**: Couldn't open output msr-file __temp.msr";
492 std::cout << std::endl << " Will quit." << std::endl;
493 fin.close();
494 return 0;
495 }
496
497 char str[256];
498 int tag = -1;
499 bool success = true;
500 int param = 0;
501 int count = 0;
502 while (!fin.eof() && success) {
503 fin.getline(str, sizeof(str));
504
505 if (strstr(str, "FITPARAMETER")) {
507 } else if (strstr(str, "THEORY")) {
508 tag = MSR_TAG_THEORY;
509 }
510
511 if ((tag == MSR_TAG_FITPARAMETER) && !strstr(str, "FITPARAMETER")) {
512 if ((theoryTag == MSR_THEORY_INTERN_FLD) || (theoryTag == MSR_THEORY_INTERN_BESSEL)) {
513 if (!msr2msr_is_comment(str)) {
514 param++;
515 if (msr2msr_is_whitespace(str)) {
516 // add needed parameters
517 for (int i=0; i<noOfAddionalParams; i++) {
518 fout << " " << param+i << " frac" << i+1 << " 0.333333 0.0 none" << std::endl;
519 }
520 }
521 }
522 }
523 }
524
525 if (tag == MSR_TAG_THEORY) {
526 if ((theoryTag == MSR_THEORY_INTERN_FLD) || (theoryTag == MSR_THEORY_INTERN_BESSEL)) {
527 if (strstr(str, "_x_")) {
528 msr2msr_replace(str, param+count);
529 count++;
530 }
531 }
532 }
533
534 fout << str << std::endl;
535 }
536
537 // close files
538 fout.close();
539 fin.close();
540
541
542 // cp __temp.msr fln
543 snprintf(str, sizeof(str), "cp __temp.msr %s", fln);
544 if (system(str) == -1) {
545 std::cerr << "**ERROR** cmd: " << str << " failed." << std::endl;
546 return false;
547 }
548 // rm __temp.msr
549 strcpy(str, "rm __temp.msr");
550 if (system(str) == -1) {
551 std::cerr << "**ERROR** cmd: " << str << " failed." << std::endl;
552 return false;
553 }
554
555 return true;
556}
557
558//--------------------------------------------------------------------------
570bool msr2msr_statistic(char *str, const std::size_t size) {
571 bool success = true;
572
573 char *pstr;
574 int status;
575 double chisq, chisqred;
576 if (strstr(str, " chi")) {
577 pstr = strstr(str, "abs = ");
578 if (pstr != nullptr) {
579 status = sscanf(pstr, "abs = %lf", &chisq);
580 if (status != 1) {
581 success = false;
582 }
583 }
584 pstr = strstr(str, "norm = ");
585 if (pstr != nullptr) {
586 status = sscanf(pstr, "norm = %lf", &chisqred);
587 if (status != 1) {
588 success = false;
589 }
590 }
591 if (success) {
592 snprintf(str, size, " chisq = %lf, NDF = %d, chisq/NDF = %lf", chisq, static_cast<int>(chisq/chisqred), chisqred);
593 }
594 }
595
596 return success;
597}
598
599//--------------------------------------------------------------------------
607int main(int argc, char *argv[])
608{
609
610 // check the number of arguments
611 if (argc != 3) {
613 return 0;
614 }
615
616 // open input msr-file
617 std::ifstream fin;
618 fin.open(argv[1], std::iostream::in);
619 if (!fin.is_open()) {
620 std::cout << std::endl << "**ERROR**: Couldn't open input msr-file " << argv[1];
621 std::cout << std::endl << " Will quit." << std::endl;
622 return 0;
623 }
624
625 // open output msr-file
626 std::ofstream fout;
627 fout.open(argv[2], std::iostream::out);
628 if (!fout.is_open()) {
629 std::cout << std::endl << "**ERROR**: Couldn't open output msr-file " << argv[2];
630 std::cout << std::endl << " Will quit." << std::endl;
631 fin.close();
632 return 0;
633 }
634
635 // read input file and write output file
636 char str[256];
637 int tag = -1;
638 int theoryTag = -1;
639 int noOfAddionalParams = 0;
640 bool success = true;
641 while (!fin.eof() && success) {
642 fin.getline(str, sizeof(str));
643
644 if (strstr(str, "FITPARAMETER")) {
646 } else if (strstr(str, "RUN")) { // analyze and change header
647 tag = MSR_TAG_RUN;
648 } else if (strstr(str, "THEORY")) {
649 tag = MSR_TAG_THEORY;
650 } else if (strstr(str, "STATISTIC")) {
651 tag = MSR_TAG_STATISTIC;
652 }
653
654 switch (tag) {
656 success = msr2msr_param(str);
657 break;
658 case MSR_TAG_THEORY:
659 success = msr2msr_theory(str, theoryTag, noOfAddionalParams);
660 break;
661 case MSR_TAG_RUN:
662 success = msr2msr_run(str, sizeof(str));
663 break;
665 success = msr2msr_statistic(str, sizeof(str));
666 break;
667 default:
668 break;
669 }
670
671 fout << str << std::endl;
672 }
673
674 // close files
675 fout.close();
676 fin.close();
677
678 // check if conversion seems to be OK
679 if (!success) {
680 snprintf(str, sizeof(str), "rm -rf %s", argv[2]);
681 if (system(str) == -1) {
682 std::cerr << "**ERROR** cmd: " << str << " failed." << std::endl;
683 return 0;
684 }
685 }
686
687 if (theoryTag != -1) {
688 msr2msr_finalize_theory(argv[2], theoryTag, noOfAddionalParams);
689 }
690
691 std::cout << std::endl << "done ..." << std::endl;
692
693 return 1;
694}
#define MSR_TAG_RUN
RUN block - run-specific settings and data file information.
Definition PMusr.h:198
#define MSR_TAG_THEORY
THEORY block - specifies the theory function(s) to fit.
Definition PMusr.h:192
#define MSR_TAG_FITPARAMETER
FITPARAMETER block - defines fit parameters with initial values and constraints.
Definition PMusr.h:190
#define MSR_TAG_STATISTIC
STATISTIC block - fit statistics and results (generated after fit)
Definition PMusr.h:206
return status
void msr2msr_replace(char *str, int paramNo)
Definition msr2msr.cpp:443
int main(int argc, char *argv[])
Definition msr2msr.cpp:607
bool msr2msr_param(char *str)
Definition msr2msr.cpp:143
#define MSR_THEORY_INTERN_FLD
Definition msr2msr.cpp:55
bool msr2msr_is_whitespace(char *str)
Definition msr2msr.cpp:420
bool msr2msr_run(char *str, const std::size_t size)
Definition msr2msr.cpp:83
#define MSR_THEORY_INTERN_BESSEL
Definition msr2msr.cpp:56
bool msr2msr_is_comment(char *str)
Definition msr2msr.cpp:391
bool msr2msr_statistic(char *str, const std::size_t size)
Definition msr2msr.cpp:570
bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams)
Definition msr2msr.cpp:246
bool msr2msr_finalize_theory(char *fln, int theoryTag, int noOfAddionalParams)
Definition msr2msr.cpp:477
void msr2msr_syntax()
Definition msr2msr.cpp:62