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#include <TObjArray.h>
39#include <TObjString.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 TObjArray *tokens;
92 TObjString *ostr[2];
93
94 // for filtering
95 run.ToUpper();
96
97 // remove run comment, i.e. (name ...
98 Ssiz_t idx = line.Index("(");
99 if (idx > 0)
100 line.Remove(idx);
101
102 // tokenize run
103 tokens = line.Tokenize(" \t");
104 if (tokens->GetEntries() < 4) {
105 std::cout << std::endl << "**ERROR**: Something is wrong with the RUN block header:";
106 std::cout << std::endl << " >> " << str;
107 std::cout << std::endl << " >> no <msr-file-out> is created";
108 std::cout << std::endl;
109 return false;
110 }
111
112 if (tokens->GetEntries() == 5) { // already a new msr file, do only add the proper run comment
113 snprintf(str, size, "%s (name beamline institute data-file-format)", line.Data());
114 return true;
115 }
116
117 if (run.Contains("NEMU")) {
118 ostr[0] = dynamic_cast<TObjString*>(tokens->At(1)); // file name
119 snprintf(str, size, "RUN %s MUE4 PSI WKM (name beamline institute data-file-format)", ostr[0]->GetString().Data());
120 } else if (run.Contains("PSI")) {
121 ostr[0] = dynamic_cast<TObjString*>(tokens->At(1)); // file name
122 ostr[1] = dynamic_cast<TObjString*>(tokens->At(2)); // beamline
123 snprintf(str, size, "RUN %s %s PSI PSI-BIN (name beamline institute data-file-format)",
124 ostr[0]->GetString().Data(), ostr[1]->GetString().Data());
125 } else if (run.Contains("TRIUMF")) {
126 ostr[0] = dynamic_cast<TObjString*>(tokens->At(1)); // file name
127 ostr[1] = dynamic_cast<TObjString*>(tokens->At(2)); // beamline
128 snprintf(str, size, "RUN %s %s TRIUMF MUD (name beamline institute data-file-format)",
129 ostr[0]->GetString().Data(), ostr[1]->GetString().Data());
130 } else if (run.Contains("RAL")) {
131 ostr[0] = dynamic_cast<TObjString*>(tokens->At(1)); // file name
132 ostr[1] = dynamic_cast<TObjString*>(tokens->At(2)); // beamline
133 snprintf(str, size, "RUN %s %s RAL NEXUS (name beamline institute data-file-format)",
134 ostr[0]->GetString().Data(), ostr[1]->GetString().Data());
135 }
136
137 // clean up
138 if (tokens) {
139 delete tokens;
140 tokens = nullptr;
141 }
142
143 return true;
144}
145
146//--------------------------------------------------------------------------
158bool msr2msr_param(char *str)
159{
160 // check for comment header which needs to be replaced
161 if (strstr(str, "Nr.")) {
162 strcpy(str, "# No Name Value Step Pos_Error Boundaries");
163 return true;
164 }
165
166 // handle parameter line
167 TString line(str);
168 TObjArray *tokens;
169 TObjString *ostr[6];
170 char sstr[256];
171 char spaces[256];
172
173 tokens = line.Tokenize(" \t");
174 Int_t noTokens = tokens->GetEntries();
175 if (noTokens == 4) {
176 for (unsigned int i=0; i<4; i++)
177 ostr[i] = dynamic_cast<TObjString*>(tokens->At(i));
178 // number
179 snprintf(sstr, sizeof(sstr), "%10s", ostr[0]->GetString().Data());
180 // name
181 strcat(sstr, " ");
182 strcat(sstr, ostr[1]->GetString().Data());
183 memset(spaces, 0, sizeof(spaces));
184 memset(spaces, ' ', 12-strlen(ostr[1]->GetString().Data()));
185 strcat(sstr, spaces);
186 // value
187 strcat(sstr, ostr[2]->GetString().Data());
188 if (strlen(ostr[2]->GetString().Data()) < 10) {
189 memset(spaces, 0, sizeof(spaces));
190 memset(spaces, ' ', 10-strlen(ostr[2]->GetString().Data()));
191 strcat(sstr, spaces);
192 } else {
193 strcat(sstr, " ");
194 }
195 // step
196 strcat(sstr, ostr[3]->GetString().Data());
197 if (strlen(ostr[3]->GetString().Data()) < 12) {
198 memset(spaces, 0, sizeof(spaces));
199 memset(spaces, ' ', 12-strlen(ostr[3]->GetString().Data()));
200 strcat(sstr, spaces);
201 } else {
202 strcat(sstr, " ");
203 }
204 strcat(sstr, "none");
205 strcpy(str, sstr);
206 } else if (noTokens == 6) {
207 for (unsigned int i=0; i<6; i++)
208 ostr[i] = dynamic_cast<TObjString*>(tokens->At(i));
209 // number
210 snprintf(sstr, sizeof(sstr), "%10s", ostr[0]->GetString().Data());
211 // name
212 strcat(sstr, " ");
213 strcat(sstr, ostr[1]->GetString().Data());
214 memset(spaces, 0, sizeof(spaces));
215 memset(spaces, ' ', 12-strlen(ostr[1]->GetString().Data()));
216 strcat(sstr, spaces);
217 // value
218 strcat(sstr, ostr[2]->GetString().Data());
219 if (strlen(ostr[2]->GetString().Data()) < 10) {
220 memset(spaces, 0, sizeof(spaces));
221 memset(spaces, ' ', 10-strlen(ostr[2]->GetString().Data()));
222 strcat(sstr, spaces);
223 } else {
224 strcat(sstr, " ");
225 }
226 // step
227 strcat(sstr, ostr[3]->GetString().Data());
228 if (strlen(ostr[3]->GetString().Data()) < 12) {
229 memset(spaces, 0, sizeof(spaces));
230 memset(spaces, ' ', 12-strlen(ostr[3]->GetString().Data()));
231 strcat(sstr, spaces);
232 } else {
233 strcat(sstr, " ");
234 }
235 // pos. error
236 strcat(sstr, "none ");
237 // lower boundary
238 strcat(sstr, ostr[4]->GetString().Data());
239 if (strlen(ostr[4]->GetString().Data()) < 8) {
240 memset(spaces, 0, sizeof(spaces));
241 memset(spaces, ' ', 8-strlen(ostr[4]->GetString().Data()));
242 strcat(sstr, spaces);
243 } else {
244 strcat(sstr, " ");
245 }
246 // upper boundary
247 strcat(sstr, ostr[5]->GetString().Data());
248 strcpy(str, sstr);
249 }
250
251 // clean up
252 if (tokens) {
253 delete tokens;
254 tokens = nullptr;
255 }
256
257 return true;
258}
259
260//--------------------------------------------------------------------------
273bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams)
274{
275 // handle theory line
276 TString line(str);
277 TObjArray *tokens;
278 TObjString *ostr;
279 char sstr[256];
280
281 if ((line.Contains("sktt") || line.Contains("statKTTab")) && line.Contains("glf")) { // static Gauss KT LF table
282 // change cmd name
283 strcpy(sstr, "statGssKTLF ");
284
285 // tokenize the rest and extract the first two parameters
286 tokens = line.Tokenize(" \t");
287 Int_t noTokens = tokens->GetEntries();
288 if (noTokens < 3) {
289 std::cout << std::endl << "**ERROR** in THEORY block";
290 std::cout << std::endl << " Line: '" << str << "' is not a valid statKTTab statement.";
291 std::cout << std::endl << " Cannot handle file." << std::endl;
292 return false;
293 }
294 for (Int_t i=1; i<3; i++) {
295 strcat(sstr, " ");
296 ostr = dynamic_cast<TObjString*>(tokens->At(i));
297 strcat(sstr, ostr->GetString().Data());
298 }
299 strcat(sstr, " (frequency damping)");
300 strcpy(str, sstr);
301 } else if ((line.Contains("sktt") || line.Contains("statKTTab")) && line.Contains("llf")) { // static Lorentz KT LF table
302 // change cmd name
303 strcpy(sstr, "statExpKTLF ");
304
305 // tokenize the rest and extract the first two parameters
306 tokens = line.Tokenize(" \t");
307 Int_t noTokens = tokens->GetEntries();
308 if (noTokens < 3) {
309 std::cout << std::endl << "**ERROR** in THEORY block";
310 std::cout << std::endl << " Line: '" << str << "' is not a valid statKTTab statement.";
311 std::cout << std::endl << " Cannot handle file." << std::endl;
312 return false;
313 }
314 for (Int_t i=1; i<3; i++) {
315 strcat(sstr, " ");
316 ostr = dynamic_cast<TObjString*>(tokens->At(i));
317 strcat(sstr, ostr->GetString().Data());
318 }
319 strcat(sstr, " (frequency damping)");
320 strcpy(str, sstr);
321 } else if ((line.Contains("dktt") || line.Contains("dynmKTTab")) && line.Contains("kdglf")) { // dynamic Gauss KT LF table
322 // change cmd name
323 strcpy(sstr, "dynGssKTLF ");
324
325 // tokenize the rest and extract the first three parameters
326 tokens = line.Tokenize(" \t");
327 Int_t noTokens = tokens->GetEntries();
328 if (noTokens < 4) {
329 std::cout << std::endl << "**ERROR** in THEORY block";
330 std::cout << std::endl << " Line: '" << str << "' is not a valid dynmKTTab statement.";
331 std::cout << std::endl << " Cannot handle file." << std::endl;
332 return false;
333 }
334 for (Int_t i=1; i<4; i++) {
335 strcat(sstr, " ");
336 ostr = dynamic_cast<TObjString*>(tokens->At(i));
337 strcat(sstr, ostr->GetString().Data());
338 }
339 strcat(sstr, " (frequency damping hopping-rate)");
340 strcpy(str, sstr);
341 } else if ((line.Contains("dktt") || line.Contains("dynmKTTab")) && line.Contains("kdllf")) { // dynamic Lorentz KT LF table
342 // change cmd name
343 strcpy(sstr, "dynExpKTLF ");
344
345 // tokenize the rest and extract the first three parameters
346 tokens = line.Tokenize(" \t");
347 Int_t noTokens = tokens->GetEntries();
348 if (noTokens < 4) {
349 std::cout << std::endl << "**ERROR** in THEORY block";
350 std::cout << std::endl << " Line: '" << str << "' is not a valid dynmKTTab statement.";
351 std::cout << std::endl << " Cannot handle file." << std::endl;
352 return false;
353 }
354 for (Int_t i=1; i<4; i++) {
355 strcat(sstr, " ");
356 ostr = dynamic_cast<TObjString*>(tokens->At(i));
357 strcat(sstr, ostr->GetString().Data());
358 }
359 strcat(sstr, " (frequency damping hopping-rate)");
360 strcpy(str, sstr);
361 } else if (line.Contains("internFld")) {
363 noOfAddionalParams++;
364
365 // change cmd name
366 strcpy(sstr, "internFld ");
367
368 // tokenize the rest and extract the first three parameters
369 tokens = line.Tokenize(" \t");
370 Int_t noTokens = tokens->GetEntries();
371 if (noTokens < 4) {
372 std::cout << std::endl << "**ERROR** in THEORY block";
373 std::cout << std::endl << " Line: '" << str << "' is not a valid internFld statement.";
374 std::cout << std::endl << " Cannot handle file." << std::endl;
375 return false;
376 }
377 strcat(sstr, " _x_");
378 for (Int_t i=1; i<4; i++) {
379 strcat(sstr, " ");
380 ostr = dynamic_cast<TObjString*>(tokens->At(i));
381 strcat(sstr, ostr->GetString().Data());
382 }
383 strcat(sstr, " (fraction phase frequency Trate Lrate)");
384 strcpy(str, sstr);
385 } else if (line.Contains("internBsl")) {
387 noOfAddionalParams++;
388
389 // change cmd name
390 strcpy(sstr, "internBsl ");
391
392 // tokenize the rest and extract the first three parameters
393 tokens = line.Tokenize(" \t");
394 Int_t noTokens = tokens->GetEntries();
395 if (noTokens < 4) {
396 std::cout << std::endl << "**ERROR** in THEORY block";
397 std::cout << std::endl << " Line: '" << str << "' is not a valid internBsl statement.";
398 std::cout << std::endl << " Cannot handle file." << std::endl;
399 return false;
400 }
401 strcat(sstr, " _x_");
402 for (Int_t i=1; i<4; i++) {
403 strcat(sstr, " ");
404 ostr = dynamic_cast<TObjString*>(tokens->At(i));
405 strcat(sstr, ostr->GetString().Data());
406 }
407 strcat(sstr, " (fraction phase frequency Trate Lrate)");
408 strcpy(str, sstr);
409 }
410
411 return true;
412}
413
414
415//--------------------------------------------------------------------------
425bool msr2msr_is_comment(char *str)
426{
427 bool isComment = false;
428
429 for (unsigned int i=0; i<strlen(str); i++) {
430 if ((str[i] == ' ') || (str[i] == '\t'))
431 continue;
432 if (str[i] == '#') {
433 isComment = true;
434 break;
435 } else {
436 isComment = false;
437 break;
438 }
439 }
440
441 return isComment;
442}
443
444//--------------------------------------------------------------------------
455{
456 bool isWhitespace = true;
457
458 if (strlen(str) != 0) {
459 for (unsigned int i=0; i<strlen(str); i++) {
460 if ((str[i] != ' ') && (str[i] != '\t')) {
461 isWhitespace = false;
462 break;
463 }
464 }
465 }
466
467 return isWhitespace;
468}
469
470//--------------------------------------------------------------------------
477void msr2msr_replace(char *str, int paramNo)
478{
479 char temp[128];
480 char no[16];
481
482 memset(temp, 0, sizeof(temp));
483
484 snprintf(no, sizeof(no), "%d", paramNo);
485
486 int j=0;
487 for (unsigned int i=0; i<strlen(str); i++) {
488 if (str[i] != '_') {
489 temp[j] = str[i];
490 j++;
491 } else {
492 for (unsigned int k=0; k<strlen(no); k++)
493 temp[j+k] = no[k];
494 j += strlen(no);
495 i += 2;
496 }
497 }
498
499 strcpy(str, temp);
500}
501
502//--------------------------------------------------------------------------
511bool msr2msr_finalize_theory(char *fln, int theoryTag, int noOfAddionalParams)
512{
513 std::ifstream fin;
514 fin.open(fln, std::iostream::in);
515 if (!fin.is_open()) {
516 std::cout << std::endl << "**ERROR**: Couldn't open input msr-file " << fln;
517 std::cout << std::endl << " Will quit." << std::endl;
518 return 0;
519 }
520
521 // open temporary output msr-file
522 std::ofstream fout;
523 fout.open("__temp.msr", std::iostream::out);
524 if (!fout.is_open()) {
525 std::cout << std::endl << "**ERROR**: Couldn't open output msr-file __temp.msr";
526 std::cout << std::endl << " Will quit." << std::endl;
527 fin.close();
528 return 0;
529 }
530
531 char str[256];
532 int tag = -1;
533 bool success = true;
534 int param = 0;
535 int count = 0;
536 while (!fin.eof() && success) {
537 fin.getline(str, sizeof(str));
538
539 if (strstr(str, "FITPARAMETER")) {
541 } else if (strstr(str, "THEORY")) {
542 tag = MSR_TAG_THEORY;
543 }
544
545 if ((tag == MSR_TAG_FITPARAMETER) && !strstr(str, "FITPARAMETER")) {
546 if ((theoryTag == MSR_THEORY_INTERN_FLD) || (theoryTag == MSR_THEORY_INTERN_BESSEL)) {
547 if (!msr2msr_is_comment(str)) {
548 param++;
549 if (msr2msr_is_whitespace(str)) {
550 // add needed parameters
551 for (int i=0; i<noOfAddionalParams; i++) {
552 fout << " " << param+i << " frac" << i+1 << " 0.333333 0.0 none" << std::endl;
553 }
554 }
555 }
556 }
557 }
558
559 if (tag == MSR_TAG_THEORY) {
560 if ((theoryTag == MSR_THEORY_INTERN_FLD) || (theoryTag == MSR_THEORY_INTERN_BESSEL)) {
561 if (strstr(str, "_x_")) {
562 msr2msr_replace(str, param+count);
563 count++;
564 }
565 }
566 }
567
568 fout << str << std::endl;
569 }
570
571 // close files
572 fout.close();
573 fin.close();
574
575
576 // cp __temp.msr fln
577 snprintf(str, sizeof(str), "cp __temp.msr %s", fln);
578 if (system(str) == -1) {
579 std::cerr << "**ERROR** cmd: " << str << " failed." << std::endl;
580 return false;
581 }
582 // rm __temp.msr
583 strcpy(str, "rm __temp.msr");
584 if (system(str) == -1) {
585 std::cerr << "**ERROR** cmd: " << str << " failed." << std::endl;
586 return false;
587 }
588
589 return true;
590}
591
592//--------------------------------------------------------------------------
604bool msr2msr_statistic(char *str, const std::size_t size) {
605 bool success = true;
606
607 char *pstr;
608 int status;
609 double chisq, chisqred;
610 if (strstr(str, " chi")) {
611 pstr = strstr(str, "abs = ");
612 if (pstr != nullptr) {
613 status = sscanf(pstr, "abs = %lf", &chisq);
614 if (status != 1) {
615 success = false;
616 }
617 }
618 pstr = strstr(str, "norm = ");
619 if (pstr != nullptr) {
620 status = sscanf(pstr, "norm = %lf", &chisqred);
621 if (status != 1) {
622 success = false;
623 }
624 }
625 if (success) {
626 snprintf(str, size, " chisq = %lf, NDF = %d, chisq/NDF = %lf", chisq, static_cast<int>(chisq/chisqred), chisqred);
627 }
628 }
629
630 return success;
631}
632
633//--------------------------------------------------------------------------
641int main(int argc, char *argv[])
642{
643
644 // check the number of arguments
645 if (argc != 3) {
647 return 0;
648 }
649
650 // open input msr-file
651 std::ifstream fin;
652 fin.open(argv[1], std::iostream::in);
653 if (!fin.is_open()) {
654 std::cout << std::endl << "**ERROR**: Couldn't open input msr-file " << argv[1];
655 std::cout << std::endl << " Will quit." << std::endl;
656 return 0;
657 }
658
659 // open output msr-file
660 std::ofstream fout;
661 fout.open(argv[2], std::iostream::out);
662 if (!fout.is_open()) {
663 std::cout << std::endl << "**ERROR**: Couldn't open output msr-file " << argv[2];
664 std::cout << std::endl << " Will quit." << std::endl;
665 fin.close();
666 return 0;
667 }
668
669 // read input file and write output file
670 char str[256];
671 int tag = -1;
672 int theoryTag = -1;
673 int noOfAddionalParams = 0;
674 bool success = true;
675 while (!fin.eof() && success) {
676 fin.getline(str, sizeof(str));
677
678 if (strstr(str, "FITPARAMETER")) {
680 } else if (strstr(str, "RUN")) { // analyze and change header
681 tag = MSR_TAG_RUN;
682 } else if (strstr(str, "THEORY")) {
683 tag = MSR_TAG_THEORY;
684 } else if (strstr(str, "STATISTIC")) {
685 tag = MSR_TAG_STATISTIC;
686 }
687
688 switch (tag) {
690 success = msr2msr_param(str);
691 break;
692 case MSR_TAG_THEORY:
693 success = msr2msr_theory(str, theoryTag, noOfAddionalParams);
694 break;
695 case MSR_TAG_RUN:
696 success = msr2msr_run(str, sizeof(str));
697 break;
699 success = msr2msr_statistic(str, sizeof(str));
700 break;
701 default:
702 break;
703 }
704
705 fout << str << std::endl;
706 }
707
708 // close files
709 fout.close();
710 fin.close();
711
712 // check if conversion seems to be OK
713 if (!success) {
714 snprintf(str, sizeof(str), "rm -rf %s", argv[2]);
715 if (system(str) == -1) {
716 std::cerr << "**ERROR** cmd: " << str << " failed." << std::endl;
717 return 0;
718 }
719 }
720
721 if (theoryTag != -1) {
722 msr2msr_finalize_theory(argv[2], theoryTag, noOfAddionalParams);
723 }
724
725 std::cout << std::endl << "done ..." << std::endl;
726
727 return 1;
728}
#define MSR_TAG_RUN
RUN block - run-specific settings and data file information.
Definition PMusr.h:193
#define MSR_TAG_THEORY
THEORY block - specifies the theory function(s) to fit.
Definition PMusr.h:187
#define MSR_TAG_FITPARAMETER
FITPARAMETER block - defines fit parameters with initial values and constraints.
Definition PMusr.h:185
#define MSR_TAG_STATISTIC
STATISTIC block - fit statistics and results (generated after fit)
Definition PMusr.h:201
return status
void msr2msr_replace(char *str, int paramNo)
Definition msr2msr.cpp:477
int main(int argc, char *argv[])
Definition msr2msr.cpp:641
bool msr2msr_param(char *str)
Definition msr2msr.cpp:158
#define MSR_THEORY_INTERN_FLD
Definition msr2msr.cpp:55
bool msr2msr_is_whitespace(char *str)
Definition msr2msr.cpp:454
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:425
bool msr2msr_statistic(char *str, const std::size_t size)
Definition msr2msr.cpp:604
bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams)
Definition msr2msr.cpp:273
bool msr2msr_finalize_theory(char *fln, int theoryTag, int noOfAddionalParams)
Definition msr2msr.cpp:511
void msr2msr_syntax()
Definition msr2msr.cpp:62