commit c6cc508aaf7d4489e08825c7c73158c1bd9aa849 Author: nemu Date: Tue Jan 8 08:31:58 2008 +0000 newly added. Not for productive used yetsvn diff | grep Index: diff --git a/copying b/copying new file mode 100755 index 00000000..5b6e7c66 --- /dev/null +++ b/copying @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/doc/man/logo_n.eps b/doc/man/logo_n.eps new file mode 100755 index 00000000..343f735d --- /dev/null +++ b/doc/man/logo_n.eps @@ -0,0 +1,239 @@ +%!PS-Adobe-2.0 EPSF-1.2 +%%Creator: Adobe Illustrator(TM) for Windows, version 4.0 +%%For: (VK84 ) (PSI ) +%%Title: (LOGO_N.EPS) +%%CreationDate: (6/9/93) (3:23 PM) +%%DocumentProcessColors: Black +%%DocumentFonts: Helvetica +%%DocumentProcSets: Adobe_Illustrator_1.1 0 0 +%%DocumentSuppliedProcSets: Adobe_Illustrator_1.1 0 0 +%%BoundingBox:44 718 180 763 +%%ColorUsage: Black&White +%%TemplateBox:328.5 399 328.5 399 +%%TileBox: 17 2 813 561 +%%DocumentPreview: PC_TIFF +%%Template: +%%PageOrigin:17 2 +%%AI3_PaperRect:-23 577 819 -18 +%%AI3_Margin:23 -18 -23 18 +%%EndComments +% $Header: N:/pvcs/ninjamus/nmnew/res/prolog.1_v 3.0 20 Apr 1992 17:03:54 epperson $ +%%BeginProcSet:Adobe_Illustrator_1.1 0 0 +% Copyright (C) 1987-1990 Adobe Systems Incorporated. +% All Rights Reserved. +% Adobe Illustrator is a trademark of Adobe Systems Incorporated. +/Adobe_Illustrator_1.1 dup 100 dict def load begin +/Version 0 def +/Revision 0 def +% definition operators +/bdef {bind def} bind def +/ldef {load def} bdef +/xdef {exch def} bdef +% graphic state operators +/_K {3 index add neg dup 0 lt {pop 0} if 3 1 roll} bdef +/_k /setcmybcolor where +{/setcmybcolor get} {{1 sub 4 1 roll _K _K _K setrgbcolor pop} bind} ifelse def +/g {/_b xdef /p {_b setgray} def} bdef +/G {/_B xdef /P {_B setgray} def} bdef +/k {/_b xdef /_y xdef /_m xdef /_c xdef /p {_c _m _y _b _k} def} bdef +/K {/_B xdef /_Y xdef /_M xdef /_C xdef /P {_C _M _Y _B _k} def} bdef +/d /setdash ldef +/_i currentflat def +/i {dup 0 eq {pop _i} if setflat} bdef +/j /setlinejoin ldef +/J /setlinecap ldef +/M /setmiterlimit ldef +/w /setlinewidth ldef +% path construction operators +/_R {.25 sub round .25 add} bdef +/_r {transform _R exch _R exch itransform} bdef +/c {_r curveto} bdef +/C /c ldef +/v {currentpoint 6 2 roll _r curveto} bdef +/V /v ldef +/y {_r 2 copy curveto} bdef +/Y /y ldef +/l {_r lineto} bdef +/L /l ldef +/m {_r moveto} bdef +% error operators +/_e [] def +/_E {_e length 0 ne {gsave 0 g 0 G 0 i 0 J 0 j 1 w 10 M [] 0 d +/Courier 20 0 0 1 z [0.966 0.259 -0.259 0.966 +_e 0 get _e 2 get add 2 div _e 1 get _e 3 get add 2 div] e _f t T grestore} if} bdef +/_fill {{fill} stopped +{/_e [pathbbox] def /_f (ERROR: can't fill, increase flatness) def n _E} if} bdef +/_stroke {{stroke} stopped +{/_e [pathbbox] def /_f (ERROR: can't stroke, increase flatness) def n _E} if} bdef +% path painting operators +/n /newpath ldef +/N /n ldef +/F {p _fill} bdef +/f {closepath F} bdef +/S {P _stroke} bdef +/s {closepath S} bdef +/B {gsave F grestore S} bdef +/b {closepath B} bdef +% text block construction and painting operators +/_s /ashow ldef +/_S {(?) exch {2 copy 0 exch put pop dup false charpath currentpoint _g setmatrix +_stroke _G setmatrix moveto 3 copy pop rmoveto} forall pop pop pop n} bdef +/_A {_a moveto _t exch 0 exch} bdef +/_L {0 _l neg translate _G currentmatrix pop} bdef +/_w {dup stringwidth exch 3 -1 roll length 1 sub _t mul add exch} bdef +/_z [{0 0} bind {dup _w exch neg 2 div exch neg 2 div} bind {dup _w exch neg exch neg} bind] def +/z {_z exch get /_a xdef /_t xdef /_l xdef exch findfont exch scalefont setfont} bdef +/_g matrix def +/_G matrix def +/_D {_g currentmatrix pop gsave concat _G currentmatrix pop} bdef +/e {_D p /t {_A _s _L} def} bdef +/r {_D P /t {_A _S _L} def} bdef +/a {_D /t {dup p _A _s P _A _S _L} def} bdef +/o {_D /t {pop _L} def} bdef +/T {grestore} bdef +% group construction operators +/u {} bdef +/U {} bdef +% font construction operators +/Z {findfont begin currentdict dup length dict begin +{1 index /FID ne {def} {pop pop} ifelse} forall /FontName exch def dup length 0 ne +{/Encoding Encoding 256 array copy def 0 exch {dup type /nametype eq +{Encoding 2 index 2 index put pop 1 add} {exch pop} ifelse} forall} if pop +currentdict dup end end /FontName get exch definefont pop} bdef +end +%%EndProcSet +%AI3-Grid.0 1.417 14.1733 7 0.833333 0.833333 0.833333 1 +%%EndProlog +%%BeginSetup +% $Header: N:/pvcs/ninjamus/nmnew/res/setup.1_v 3.0 20 Apr 1992 17:04:24 epperson $ +Adobe_Illustrator_1.1 begin +n +%%BeginEncoding: _Helvetica Helvetica +[39/quotesingle 96/grave 130/quotesinglbase 131/florin 132/quotedblbase +133/ellipsis 134/dagger 135/daggerdbl 136/circumflex 137/perthousand +138/Scaron 139/guilsinglleft 140/OE 145/quoteleft 146/quoteright +147/quotedblleft 148/quotedblright 149/bullet 150/endash 151/emdash +152/tilde 153/trademark 154/scaron 155/guilsinglright 156/oe 157/dotlessi +159/Ydieresis 164/currency 166/brokenbar 168/dieresis 169/copyright +170/ordfeminine 172/logicalnot 174/registered 175/macron 176/ring +177/plusminus 178/twosuperior 179/threesuperior 180/acute 181/mu +183/periodcentered 184/cedilla 185/onesuperior 186/ordmasculine +188/onequarter 189/onehalf 190/threequarters 192/Agrave 193/Aacute +194/Acircumflex 195/Atilde 196/Adieresis 197/Aring 198/AE 199/Ccedilla +200/Egrave 201/Eacute 202/Ecircumflex 203/Edieresis 204/Igrave 205/Iacute +206/Icircumflex 207/Idieresis 208/Eth 209/Ntilde 210/Ograve 211/Oacute +212/Ocircumflex 213/Otilde 214/Odieresis 215/multiply 216/Oslash +217/Ugrave 218/Uacute 219/Ucircumflex 220/Udieresis 221/Yacute 222/Thorn +223/germandbls 224/agrave 225/aacute 226/acircumflex 227/atilde 228/adieresis +229/aring 230/ae 231/ccedilla 232/egrave 233/eacute 234/ecircumflex +235/edieresis 236/igrave 237/iacute 238/icircumflex 239/idieresis +240/eth 241/ntilde 242/ograve 243/oacute 244/ocircumflex 245/otilde +246/odieresis 247/divide 248/oslash 249/ugrave 250/uacute 251/ucircumflex +252/udieresis 253/yacute 254/thorn 255/ydieresis +]/_Helvetica/Helvetica Z +%%EndEncoding +%%EndSetup +u +u +u +u +u +0 g +0 i 0 J 0 j 1 w 4 M []0 d +%%Note: +/_Helvetica 10 12 0 1 z +[0.8822 0 0 1 112.1086 753.9832]e +(PAUL SCHERRER INSTITUT)t +T +U +U +U +U +U +u +0.7 g +171.2185 726.0363 m +171.2185 722.892 168.3513 722.892 v +57.9719 722.892 l +55.1049 722.892 55.1049 726.0363 v +55.1049 733.8967 l +55.1049 737.0409 57.9719 737.0409 v +168.3513 737.0409 l +171.2185 737.0409 171.2185 733.8967 v +171.2185 726.0363 l +F +u +1 g +0 G +1.5 w +129.6609 738.3986 m +132.5149 738.3986 132.5149 741.4486 y +132.5149 744.4985 l +132.5149 747.5484 129.6609 747.5484 y +109.6833 747.5484 l +106.8293 747.5484 106.8293 744.4985 y +106.8293 732.2989 l +106.8293 729.2489 109.6833 729.2489 y +B +u +115.3912 738.3986 m +129.6609 738.3986 l +132.5149 738.3986 132.5149 735.3486 v +132.5149 723.1491 l +132.5149 720.0991 129.6609 720.0991 v +109.6833 720.0991 l +106.8293 720.0991 106.8293 723.1491 v +106.8293 726.199 l +106.8293 729.2489 109.6833 729.2489 v +B +U +123.953 729.2489 m +109.6833 729.2489 l +B +U +u +u +u +u +u +103.9754 747.5485 m +83.9977 747.5484 l +81.1437 747.5484 81.1437 744.4985 y +81.1437 723.1491 l +81.1437 720.0991 83.9977 720.0991 y +86.8516 720.0991 l +89.7056 720.0991 89.7056 723.1491 y +89.7056 729.2489 l +103.9753 729.2489 l +106.8293 729.2489 106.8293 732.2989 y +106.8293 744.4985 l +B +U +106.8293 744.4985 m +106.8293 747.5484 103.9753 747.5484 y +B +U +U +89.7056 738.3986 m +98.2675 738.3986 l +B +U +U +u +132.5149 744.4985 m +132.5149 747.5484 135.3688 747.5484 v +142.5037 747.5484 l +145.3577 747.5484 145.3577 744.4985 v +145.3577 723.1491 l +145.3577 720.0991 142.5037 720.0991 v +135.3688 720.0991 l +132.5149 720.0991 132.5149 723.1491 v +132.5149 744.4985 l +b +U +U +%%PageTrailer +%%Trailer +% $Header: N:/pvcs/ninjamus/nmnew/res/trailer.1_v 3.0 20 Apr 1992 17:03:32 epperson $ +_E end +%%EOF diff --git a/doc/man/musrfit.tex b/doc/man/musrfit.tex new file mode 100755 index 00000000..efbc7420 --- /dev/null +++ b/doc/man/musrfit.tex @@ -0,0 +1,351 @@ +\documentclass[twoside]{article} + +\usepackage[english]{babel} +\usepackage{a4} +\usepackage{amssymb} +\usepackage{graphicx} +\usepackage{fancyhdr} +\usepackage{array} +\usepackage{float} +\usepackage{hyperref} +\usepackage{xspace} +\usepackage{rotating} + +\setlength{\topmargin}{10mm} +\setlength{\topmargin}{-13mm} +% \setlength{\oddsidemargin}{0.5cm} +% \setlength{\evensidemargin}{0cm} +\setlength{\oddsidemargin}{0.7cm} +\setlength{\evensidemargin}{0.7cm} +\setlength{\textwidth}{14.5cm} +\setlength{\textheight}{23.8cm} + +\pagestyle{fancyplain} +\addtolength{\headwidth}{0.6cm} +\fancyhead{}% +\fancyhead[RE,LO]{musrfit}% +\fancyhead[LE,RO]{\thepage} +%\cfoot{--- Andreas Suter -- \today ---} +\cfoot{LE-$\mu$SR -- \includegraphics[width=2cm]{logo_n.eps}~~~~ -- \today} + +\DeclareMathAlphabet{\bi}{OML}{cmm}{b}{it} + +\newcommand{\musr}{$\mu$SR\xspace} + +\begin{document} + +\tableofcontents + +\section{Introduction}\label{sec:introduction}% + +\section{Available Executables}\label{sec:available-executables}% + +\subsection{musrfit}\label{subsec:musrfit}% +\subsection{musrview}\label{subsec:musrview}% +\fbox{q} \textbf{Quit}: is terminating \texttt{musrview}. + +\subsection{musrt0}\label{subsec:musrt0}% +\subsection{musrpara}\label{subsec:musrpara}% + +\section{Users Guide}\label{sec:user-guide}% + +\section{Description of the msr-File Format}\label{sec:msr-file}% + +The programs are using an input file to control their action. This input file has the extension \texttt{.msr} (msr-file). the msr-file is built up from different blocks. Each block starts with a keyword, and is terminated by an empty line\footnote{The title is an exception from this rule.}. Comments are starting with the character `\#'. The various input blocks will be described now. + +\subsection{The Title}\label{subsec:msr-file-title}% + +The first line of the msr-file is the title line. Different than all the other input blocks, it doesn't start with a block keyword. It is just an simple text line, in which any information can be placed. The title text will be used in the graphical representation of the data as a headline. + +\subsection{The \texttt{FITPARAMETER}-Block}\label{subsec:msr-file-fitparameter-block}% + +The \texttt{FITPARAMETER}-block is used to define the fitparameters in a \textsc{Minuit} typical style. +There are various possible parameter definitions possible which are listed here: + +\begin{enumerate} + \item \verb! ! + \item \verb! ! + \item \verb! ! +\end{enumerate} + +\noindent where \verb!! is the parameter number, \verb!! is the parameter name\footnote{The parameter name is limited to 10 characters, and furthermore no spaces are allowed!}, \verb!! is the initial guess of the parameter, \verb!! the inital step width, \verb!! is the lower/upper boundary for the parameter\footnote{According to the \textsc{Minuit} manual this should be avoided whenever possible.}. + +In the output \texttt{mlog}-file, \verb!! will be the \textsc{Minuit} fit value, \verb!! will contain the error estimate (or the negative error estimate if \textsc{Minos} was successfully used), \verb!! will have the value \texttt{none} if no \textsc{Minos} was used, otherwise it will show the positive error estimate. A typical example will look like this: + +\begin{verbatim} +FITPARAMETER +# Nr. Name Value Step Pos_Error Bounderies + 1 alpha 1 0.02 none 0 1.8 + 2 asy 0.1042 0.004713 none 0 0.33 + 3 phase 15 1.0 none + 4 freq 0.9 0.0379 none + 5 rate 0.03 0.00579 none +\end{verbatim} + + +\subsection{The \texttt{THEORY}-Block}\label{subsec:msr-file-theory-block}% + +The \texttt{THEORY}-block is used to define the fit function. There is a set of predefined functions available (see table \ref{tab:predefined-theory-functions}). It is also possible to use externally defined functions. How to use them will be explained afterwards, first the predefined functions will be described. + +\begin{table}[h] + \centering + \begin{tabular}{|l|l|l|l|l|} + \hline + % title ------------------------------------------------------------------- + \rule[-3mm]{0mm}{8mm} + \textbf{name} & \textbf{abbriviation} & \textbf{parameters} & + \textbf{mathematical expression} & \textbf{refs.} \\ \hline\hline + % asymmetry --------------------------------------------------------------- + \rule[-3mm]{0mm}{8mm} + \texttt{asymmetry} & \texttt{a} & $A$ (1) & $A$ & \\ \hline + % simple exponential ------------------------------------------------------ + \rule[-3mm]{0mm}{8mm} + \texttt{simplExpo} & \texttt{se} & $\lambda$ ($\mu\mathrm{s}^{-1}$) & $\exp(-\lambda t)$ & \\ \hline + % general exponential ----------------------------------------------------- + \rule[-3mm]{0mm}{8mm} + \texttt{generExpo} & \texttt{ge} & $\lambda$ ($\mu\mathrm{s}^{-1}$), $\beta$ (1) + & $\exp\left[-\left(\lambda t\right)^\beta \right]$ & \\ \hline + % simple gauss ------------------------------------------------------------ + \rule[-3mm]{0mm}{8mm} + \texttt{simpleGss} & \texttt{sg} & $\sigma$ ($\mu\mathrm{s}^{-1}$) + & $\exp\left[-\frac{1}{2}\left(\sigma t\right)^2\right]$ & \\ \hline + % static Kubo-Toyabe ZF --------------------------------------------------- + \rule[-3mm]{0mm}{8mm} + \texttt{statGssKT} & \texttt{stg} & $\sigma$ ($\mu\mathrm{s}^{-1}$) + & $\frac{1}{3} + \frac{2}{3} [1-(\sigma t)^2] + \exp\left[-\frac{1}{2}\left(\sigma t\right)^2\right] $ & ?? \\ \hline + % static Kubo-Toyabe LF --------------------------------------------------- + \rule[-3mm]{0mm}{8mm} + \texttt{statKTTab} & \texttt{sktt} & $\nu$ (MHz), $\sigma$ ($\mu\mathrm{s}^{-1}$) + & static Kubo-Toyabe (ZF and LF, tabulated) & ?? \\ + & & table & & \\ \hline + % dynamic Kubo-Toyabe LF -------------------------------------------------- + \rule[-3mm]{0mm}{8mm} + \texttt{dynmKTTab} & \texttt{dktt} & $\nu$ (MHz), $\sigma$ ($\mu\mathrm{s}^{-1}$) + & dynamic Kubo-Toyabe (ZF and LF, tabulated) & ?? \\ + & & $\gamma$ ($\mu\mathrm{s}^{-1}$), table & & \\ \hline + % combined Lorentz-Gauss-Kubo-Toyabe -------------------------------------- + \rule[-3mm]{0mm}{8mm} + \texttt{combiLGKT} & \texttt{lgkt} & $\lambda_{\rm L}$ ($\mu\mathrm{s}^{-1}$), + $\lambda_{\rm G}$ ($\mu\mathrm{s}^{-1}$) & + $\frac{1}{3}+\frac{2}{3}\left[1-(\lambda_{\rm G}t)^2-\lambda_{\rm L}t + \right]\exp\left[-\frac{1}{2}(\lambda_{\rm G}t)^2-\lambda_{\rm L}t\right]$ + & ?? \\ \hline + % abragam ----------------------------------------------------------------- + \rule[-3mm]{0mm}{8mm} + \texttt{abragam} & \texttt{ab} & $\sigma$ ($\mu\mathrm{s}^{-1}$), + $\gamma$ ($\mu\mathrm{s}^{-1}$) & + $\exp\left[-\left(\frac{\displaystyle\sigma}{\displaystyle\gamma}\right)^2 + (e^{-\gamma t}-1-\gamma t)\right]$ & ?? \\ \hline + % spin glass -------------------------------------------------------------- + \rule[-3mm]{0mm}{8mm} + \texttt{spinGlas} & \texttt{sg} & $\lambda$ ($\mu\mathrm{s}^{-1}$), + $\gamma$ ($\mu\mathrm{s}^{-1}$) & $\alpha := \frac{4\lambda^2 (1-q)}{\gamma}$, + \qquad $\beta := \sqrt{q} \lambda$ & ?? \\ + \rule[-3mm]{0mm}{8mm} + & & & $\frac{1}{3} e^{-\sqrt{\alpha t}} + \frac{2}{3} \left( 1 - + \frac{(\beta t)^2}{\sqrt{\alpha t + (\beta t)^2}} \right) + e^{-\sqrt{\alpha t + (\beta t)^2}} $ & \\ \hline + % TF cos ------------------------------------------------------------------ + \rule[-3mm]{0mm}{8mm} + \texttt{TFieldCos} & \texttt{tf} & $\varphi$ ($^\circ$), $\nu$ (MHz) + & $\cos(2\pi\nu t + \frac{\displaystyle \pi}{180} \varphi) $ & ?? \\ \hline + % bessel ------------------------------------------------------------------ + \rule[-3mm]{0mm}{8mm} + \texttt{bessel} & \texttt{be} & $\varphi$ ($^\circ$), $\nu$ (MHz) + & $J_0(2\pi\nu t + \frac{\displaystyle \pi}{180} \varphi)$ & ?? \\ \hline + % internal bessel --------------------------------------------------------- + \rule[-3mm]{0mm}{8mm} + \texttt{internBsl} & \texttt{ib} & $\varphi$ ($^\circ$), $\nu$ (MHz) + & $\frac{2}{3} J_0(2\pi\nu t + \frac{\displaystyle \pi}{180} \varphi) + e^{-\lambda_{\rm T} t} + \frac{1}{3} e^{-\lambda_{\rm L} t}$ & ?? \\ + & & $\lambda_{\rm T}$ ($\mu\mathrm{s}^{-1}$), $\lambda_{\rm L}$ ($\mu\mathrm{s}^{-1}$) & & \\ \hline + % random anisotropy hyperfine field --------------------------------------- + \rule[-3mm]{0mm}{8mm} + \texttt{rdAnisoHf} & \texttt{rahf} & $\nu$ (MHz), $\lambda$ ($\mu\mathrm{s}^{-1}$) + & $\frac{1}{6} \left( 1 - \frac{\nu t}{2} \right) e^{-\frac{\nu t}{2}} + + \frac{1}{3} \left( 1 - \frac{\nu t}{4} \right) e^{-\frac{\nu t + 2.44949 \lambda t}{4}}$ & ?? \\ \hline + % internal field ---------------------------------------------------------- + \rule[-3mm]{0mm}{8mm} + \texttt{internFld} & \texttt{if} & $\varphi$ ($^\circ$), $\nu$ (MHz) + & $\frac{2}{3} \cos(2\pi\nu t + \frac{\displaystyle \pi}{180} \varphi) + e^{-\lambda_{\rm T} t} + \frac{1}{3} e^{-\lambda_{\rm L} t}$ & ?? \\ + & & $\lambda_{\rm T}$ ($\mu\mathrm{s}^{-1}$), $\lambda_{\rm L}$ ($\mu\mathrm{s}^{-1}$) & & \\ \hline + \end{tabular} + \caption{\textsl{List of the predefined theory functions.}}\label{tab:predefined-theory-functions} +\end{table} + +Every theory function has to be written on a single line. It starts with the theory function name or its abbriviation followed by the parameters. Consecutive lines of theory functions will be multiplied. If theory functions need to be added, a line with a `$+$' has to separte them. The parameters are given as the number assigned to them in the \texttt{FITPARAMETER}-block. The order of the parameters is given in table \ref{tab:predefined-theory-functions}. As an example + +\begin{verbatim} +simplExpo 4 +\end{verbatim} + +\noindent defines an exponential function with a depolarization rate $\lambda$ given by the parameter 4 of the \texttt{FITPARAMETER}-block. A full fetched \texttt{THEORY}-block could be + +\begin{verbatim} +THEORY +asymmetry 2 +simplExpo 3 +TFieldCos 4 5 ++ +asymmetry 6 +simplExpo 7 +\end{verbatim} + +\noindent which means + +\begin{math} + A(t) = P_2 \cdot e^{-t\cdot P_3} \cdot \cos(2\pi P_5 t + \frac{\displaystyle\pi}{180} P_4) + + P_6 \cdot e^{-t\cdot P_7} +\end{math} + +\noindent where $P_\alpha$ is the parameter $\alpha$. + +\subsubsection{Maps}\label{subsubsec:maps}% + +In case different runs are fitted simultaniously, it is very often necessary that for a given theory function, some parameters are run dependend. An example would be a temperature scan, where the parameters (asymmetry, depolarization rates, etc.\xspace) will depend on the temperature. In order to handle such situations, the mapping of parameters in the \texttt{THEORY}-block is possible. Instead of a parameter number, the mapping of the parameter is given. The definition of the mapping block is part of the \texttt{RUN}-block (see Sec.\ref{subsec:msr-file-run-block}) and will be described there. For example + +\begin{verbatim} +THEORY +asymmetry 2 +simplExpo 3 +TFieldCos 4 5 ++ +asymmetry map1 +simplExpo map2 +\end{verbatim} + +\noindent means that the first part of this theory function is run independ, as for instance the background, and the second part is changing from run to run, i.e.\xspace \texttt{map1/2} will point to different parameters depending on the run. + +\subsubsection{Functions}\label{subsubsec:functions}% + +Yet another useful feature is the possibilty to define functions (see Sec.\ref{subsec:msr-file-functions-block}). Within the \texttt{THEORY}-block functions can be address as \texttt{fun$\alpha$}, where $\alpha$ is the function number, e.g.\xspace \texttt{fun2}. + +\subsubsection{User Functions}\label{subsubsec:user-functions}% + +\subsection{The \texttt{FUNCTIONS}-Block}\label{subsec:msr-file-functions-block}% + +\subsection{The \texttt{RUN}-Block}\label{subsec:msr-file-run-block}% + +The \texttt{RUN}-Block is used to collect the data needed for a particular run to be fitted. This is including run name, fit type, data format, etc.\xspace The \texttt{RUN}-Block is slightly different organized than the other blocks. The information are collected via labels followed by the information. +Each run to be fitted has its own \texttt{RUN}-Block. A \texttt{RUN}-Block starts with run-file line which has the structure + +\begin{verbatim} +RUN +\end{verbatim} + +\noindent The tokens following the \texttt{RUN} statement are used to identifiy the run, the potential location where the run might be found, and the file format in which the run was saved. In order to understand the meaning of all the above tokens, a short digression is needed. Where is \texttt{musrfit} looking for data files? There is a specifc order how this is done: + +\begin{enumerate} + \item Check if the file is found in the current directory + \item Check if there is a system variable \texttt{WKMFULLDATAPATH}. This system variable can + contain multiple search paths separated by columns, e.g.\xspace \\ + \texttt{export WKMFULLDATAPATH=/mnt/home/nemu/analysis:/afs/psi.ch/.../analysis}. + \item Check if the path (or multiple paths) was (were) given in the XML startup file. + \item Construct the search path from the \texttt{RUN}-block information the following way: \\ + \texttt{??? NEEDS TO BE CHECKED ???} +\end{enumerate} + +\noindent Here some valid examples: + +\begin{verbatim} +RUN 2007/lem07_his_2018 MUE4 PSI ROOT-PPC +\end{verbatim} + +\begin{verbatim} +RUN 2007/lem07_2018_rb1_npp MUE4 PSI NEMU +\end{verbatim} + +\begin{verbatim} +RUN 2007/???? PIE3 PSI PSI-BIN +\end{verbatim} + +\noindent After this short digression back to the \texttt{RUN}-block description. + +\begin{table}[h] + \centering + \begin{tabular}{|l|l|} \hline + \textbf{\texttt{RUN}-block tag} & \textbf{comment} \\ \hline\hline + \texttt{} & sub path and filename without extension \\ \hline + \texttt{} & \begin{minipage}{12cm} + name of the beamline where the data where taken, + e.g.\xspace \texttt{MUE4}. Used to generate a + default path. + \end{minipage} \\ \hline + \texttt{} & \begin{minipage}{12cm} + name of the institute where the data where taken, + e.g.\xspace \texttt{PSI}. Used to generate a + default path. + \end{minipage} \\ \hline + \texttt{} & file format, e.g.\xspace \texttt{NEXUS} (for details + see Sec.\ref{subsec:supported-data-formats})\\ \hline + \end{tabular} + \caption{}\label{tab:run-block} +\end{table} + +\noindent In order to describe the operations needed for fitting and ploting, quite a few information are needed. These information are following the \texttt{RUN}-statement and will be listed below. Depending on the fit-type these information will vary and hence it will be indicated for which fit/plot-type the information is applicable. + +\begin{description} + \item[\texttt{fittype}] \textsl{(required)}, this tag is used to indicate which type of fit + is whished. The supported fit-types are: + \begin{description} + \item[0] Single Histogram Fit + \item[2] Asymmetry Fit + \item[4] Asymmetry Fit in a Rotating Reference Frame + \item[8] Non-\musr Fit + \end{description} + The description of these fit-types can be found in Sec.\ref{sec:fit-types} + \item[\texttt{alpha, beta}] \textsl{(fit-type 2, 4)} +\end{description} + + +\subsection{The \texttt{FOURIER}-Block}\label{subsec:msr-file-fourier-block}% + +\subsection{The \texttt{COMMANDS}-Block}\label{subsec:msr-file-commands-block}% + +\subsection{The \texttt{PLOT}-Block}\label{subsec:msr-file-plot-block}% + +\subsection{The \texttt{STATISTICS}-Block}\label{subsec:msr-file-statistics-block}% + +\subsection{Supported Data Formats}\label{subsec:supported-data-formats}% +\subsubsection{\texttt{NEMU} File Format}\label{subsubsec:nemu-format}% +\subsubsection{\texttt{ROOT} File Format}\label{subsubsec:root-format}% +\subsubsection{\texttt{NEXUS} File Format}\label{subsubsec:nexus-format}% +\subsubsection{\texttt{PSI-BIN} File Format}\label{subsubsec:psibin-format}% +\subsubsection{\texttt{MUD} File Format}\label{subsubsec:mud-format}% +\subsubsection{\texttt{NON-MUSR} File Format}\label{subsubsec:non-musr-format}% + +\section{Fit Types}\label{sec:fit-types}% + +\subsection{Single Histogram Fit}\label{subsec:single-histogram-fit}% +\subsection{Asymmetry Fit}\label{subsec:asymmetry-fit}% +\subsection{Rotating Reference Fit}\label{subsec:rrf}% +\subsection{Non-Musr Fit}\label{subsec:non-musr-fit}% + +\section{Data Preparation for Fitting and Plotting}\label{sec:data-preparation}% + +\subsection{Single Histogram Fit / Plot (\texttt{fittype/plottype 0})}\label{subsec:single-histo-fit-plot}% +\subsubsection{\texttt{fittype 0}}\label{subsubsec:single-histo-fit}% +\subsubsection{\texttt{plottype 0}}\label{subsubsec:single-histo-plot}% + +\subsection{Asymmetry Fit / Plot (\texttt{fittype/plottype 2})}\label{subsec:asymmetry-fit-plot}% +\subsubsection{\texttt{fittype 2}}\label{subsubsec:asymmetry-fit}% +\subsubsection{\texttt{plottype 2}}\label{subsubsec:asymmetry-plot}% + +\subsection{Rotating Reference Fit / Plot (\texttt{fittype/plottype 4})}\label{subsec:rrf-fit-plot}% +\subsubsection{\texttt{fittype 2}}\label{subsubsec:rrf-fit}% +\subsubsection{\texttt{plottype 2}}\label{subsubsec:rrf-plot}% + +\subsection{Non-Musr Fit / Plot (\texttt{fittype/plottype 8})}\label{subsec:non-musr-fit-plot}% +\subsubsection{\texttt{fittype 2}}\label{subsubsec:non-musr-fit}% +\subsubsection{\texttt{plottype 2}}\label{subsubsec:non-musr-plot}% + +\appendix + +\section{Installation}\label{sec:installation}% + +\begin{thebibliography}{99} +\end{thebibliography} + +\end{document} diff --git a/doc/musrfit_dox.cfg b/doc/musrfit_dox.cfg new file mode 100644 index 00000000..85e44888 --- /dev/null +++ b/doc/musrfit_dox.cfg @@ -0,0 +1,1283 @@ +# Doxyfile 1.4.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = musrfit + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.1 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../src/include/PFitterFcn.h \ + ../src/include/PFitter.h \ + ../src/include/PFunctionGrammar.h \ + ../src/include/PFunction.h \ + ../src/include/PFunctionHandler.h \ + ../src/include/PMsrHandler.h \ + ../src/include/PMusr.h \ + ../src/include/PRunAsymmetry.h \ + ../src/include/PRunBase.h \ + ../src/include/PRunDataHandler.h \ + ../src/include/PRunListCollection.h \ + ../src/include/PRunNonMusr.h \ + ../src/include/PRunRRF.h \ + ../src/include/PRunSingleHisto.h \ + ../src/include/PStartupHandler.h \ + ../src/include/PTheory.h \ + ../src/classes/PFitterFcn.cpp \ + ../src/classes/PFitter.cpp \ + ../src/classes/PFunction.cpp \ + ../src/classes/PFunctionHandler.cpp \ + ../src/classes/PMsrHandler.cpp \ + ../src/classes/PRunAsymmetry.cpp \ + ../src/classes/PRunBase.cpp \ + ../src/classes/PRunDataHandler.cpp \ + ../src/classes/PRunListCollection.cpp \ + ../src/classes/PRunNonMusr.cpp \ + ../src/classes/PRunRRF.cpp \ + ../src/classes/PRunSingleHisto.cpp \ + ../src/classes/PStartupHandler.cpp \ + ../src/classes/PTheory.cpp \ + ../src/musrfit.cpp \ + ../src/msr2msr.cpp + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.dox + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = /usr/local/bin + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/src/.kdbgrc.musrfit b/src/.kdbgrc.musrfit new file mode 100755 index 00000000..5b22ad34 --- /dev/null +++ b/src/.kdbgrc.musrfit @@ -0,0 +1,18 @@ +[Breakpoint 0] +Enabled=true +File=musrfit.cpp +Line=464 +Temporary=false + +[General] +DebuggerCmdStr= +DriverName=GDB +FileVersion=1 +OptionsSelected= +ProgramArgs= +TTYLevel=7 +WorkingDirectory= + +[Memory] +ColumnWidths=80,0 +NumExprs=0 diff --git a/src/ToDo.txt b/src/ToDo.txt new file mode 100644 index 00000000..31fedc45 --- /dev/null +++ b/src/ToDo.txt @@ -0,0 +1,66 @@ +2007/11/28 + +--------------------- +short term: +--------------------- + +* dump data and theory after fit (ascii/root): **DONE** for now + done for ascii/root asymmetry && single histo: all the rest is missing +* migrate all typedef's and defines -> PMusr.h **DONE** + +* Since rootcint cannot handle the spirit include files I will try to remove all the + root dictionary related stuff since almost for sure, nobody will use the classes + from the cint interpreter level 2007/12/27 **DONE** + +* begin with the implementation of the FUNCTIONS block + using the spirit parser framework **DONE** + +* 2007/12/30: implement functions in PTheory **DONE** 08-01-02 + +* 2008/01/02: nice function block output needed. **DONE** 08-01-02 + +* write a little standalone program which is converting the old msr-files to the new ones. **DONE** 08-01-04 + +* implement max.likelihood fits + +* implement table based theory functions (LF stuff) + +--------------------- +intermediate term: +--------------------- + +* start writing docu, i.e. transfering WKM doc from German -> English and + describe new features with examples! +* implement RRF stuff +* implement NonMuSR stuff +* implement access to user-function, i.e. functions not + defined within musrfit, using the ROOT dictionary feature + to look for them and use them. +* think about if it is worth to modifiy wkm in order to read + the new msr-files, so that wkmview can be used for an intermediate + time. + +--------------------- +long term: +--------------------- + +* implement ROOT based wkmview, i.e. all the graphical stuff needed + including event handler, etc. +* implement FFT with msr-interface +* switch from qmake to cmake + +--------------------- +problems: +--------------------- +* rootcint cannot handle spirit framework includes, hence FUNCTIONS related stuff cannot be included + into a root dictionary. + +--------------------- +fixes: +--------------------- +* Needed to change some part of the Minuit2 source code, otherwise I got a strange linker error message. + In MnMinos.h the constructors (3 overloaded versions) are defined implicitly. When linking against libPMusr.so + which is using libMinuit2Base.so, I got the error message from the linker that is cannot find the reference + to the second constructor. When transfering the implicit definition from the header file to the cxx, the + problem was gone. Since to fiddle in the Minuit2 source code directly is ugly, I should look for a way to + build libPMusr.so which doesn't have this problem. \ No newline at end of file diff --git a/src/classes/BUILD b/src/classes/BUILD new file mode 100644 index 00000000..d26b87a7 --- /dev/null +++ b/src/classes/BUILD @@ -0,0 +1,31 @@ +************************************************************* + + Build instructions for the shared library libPMusr.so + + Andreas Suter, 2008/01/08 + $Id$ + +************************************************************* + +At the moment a lot of the build stuff has to be done manually. +I will eventually migrate to cmake and than it will be much more +automatically. + +Required packages: + +* ROOT >= 5.16 : needed for read/write some data files, plotting, ... +* Minuit2 >= 5.08 : needed for fitting +* Spirit >= 1.8.5 : needed for parsing (this is part of the boost lib, and + hence installed on most linux machines). The boost libs + are platform independent and hence it should be easy in + the future to migrate also to Windows and Mac OS + +Build instructions: + +make -f Makefile.PMusr + +than as root + +make -f Makefile.PMusr install + + diff --git a/src/classes/Makefile.PMusr b/src/classes/Makefile.PMusr new file mode 100644 index 00000000..69c48eb8 --- /dev/null +++ b/src/classes/Makefile.PMusr @@ -0,0 +1,138 @@ +#--------------------------------------------------- +# Makefile.PMusr +# +# Author: Andreas Suter +# e-mail: andreas.suter@psi.ch +# +# $Id$ +# +# Comment: If it doesn't work, try +# make --warning-undefined-variables -f Makefile.PMusr +# it might be that OSTYPE is not set properly, i.e. +# OSTYPE being a variable (set), instead of a enviornment +# variable (printenv). If so, try +# export OSTYPE=linux-gnu +# are whatever makes sense on your system. +#--------------------------------------------------- + +#--------------------------------------------------- +# get compilation and library flags from root-config + +ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags) +ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) +ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs) + +#--------------------------------------------------- +# depending on the architecture, choose the compiler, +# linker, and the flags to use +# + +ifeq ($(OSTYPE),linux) +OS = LINUX +endif +ifeq ($(OSTYPE),linux-gnu) +OS = LINUX +endif +ifeq ($(OSTYPE),darwin) +OS = DARWIN +endif + +# -- Linux +ifeq ($(OS),LINUX) +CXX = g++ +CXXFLAGS = -g -Wall -fPIC +PMUSRPATH = ../include +MNPATH = /usr/local/include +INCLUDES = -I $(PMUSRPATH) -I $(MNPATH) +LD = g++ +LDFLAGS = -g +SOFLAGS = -O -shared +endif + +# -- Darwin +ifeq ($(OS),DARWIN) +CXX = g++ +CXXFLAGS = -g -Wall -fPIC +INCLUDES = -I../include +LD = g++ +LDFLAGS = -g +SOFLAGS = -dynamic +endif + +# the output from the root-config script: +CXXFLAGS += $(ROOTCFLAGS) +LDFLAGS += + +# the ROOT libraries (G = graphic) +LIBS = $(ROOTLIBS) -lXMLParser +GLIBS = $(ROOTGLIBS) -lXMLParser + +# PSI libs +PSILIBS = -lTLemRunHeader +# Minuit2 lib +MNLIB = -L/usr/local/lib -lMinuit2Base + + +# some definitions: headers, sources, objects,... +HEADERS = +HEADERS += PStartupHandler.h +HEADERS += PMsrHandler.h +HEADERS += PRunDataHandler.h +HEADERS += PFunctionHandler.h +HEADERS += PFunctionGrammar.h +HEADERS += PFunction.h +HEADERS += PRunBase.h +HEADERS += PRunSingleHisto.h +HEADERS += PRunAsymmetry.h +HEADERS += PRunRRF.h +HEADERS += PRunNonMusr.h +HEADERS += PRunListCollection.h +HEADERS += PTheory.h +HEADERS += PFitterFcn.h +HEADERS += PFitter.h + +OBJS = +OBJS += PStartupHandler.o +OBJS += PMsrHandler.o +OBJS += PRunDataHandler.o +OBJS += PFunctionHandler.o +OBJS += PFunction.o +OBJS += PRunBase.o +OBJS += PRunSingleHisto.o +OBJS += PRunAsymmetry.o +OBJS += PRunRRF.o +OBJS += PRunNonMusr.o +OBJS += PRunListCollection.o +OBJS += PTheory.o +OBJS += PFitterFcn.o +OBJS += PFitter.o + +SHLIB = libPMusr.so + +# make the shared lib: +# +all: $(SHLIB) + +$(SHLIB): $(OBJS) + @echo "---> Building shared library $(SHLIB) ..." + /bin/rm -f $(SHLIB) + $(LD) $(OBJS) $(SOFLAGS) -o $(SHLIB) $(GLIBS) $(PSILIBS) $(MNLIB) + @echo "done" + +# clean up: remove all object file (and core files) +# semicolon needed to tell make there is no source +# for this target! +# +clean:; @rm -f $(OBJS) *Dict* core* + @echo "---> removing $(OBJS)" + +# +$(OBJS): %.o: %.cpp + $(CXX) $(INCLUDES) $(CXXFLAGS) -c $< + +install: all + @echo "Installing shared lib: libPMusr.so ( you must be root ;-) )" +ifeq ($(OS),LINUX) + cp -pv $(SHLIB) $(ROOTSYS)/lib + cp -pv $(PMUSRPATH)/*.h $(ROOTSYS)/include +endif \ No newline at end of file diff --git a/src/classes/PFitter.cpp b/src/classes/PFitter.cpp new file mode 100644 index 00000000..b1ff98b1 --- /dev/null +++ b/src/classes/PFitter.cpp @@ -0,0 +1,478 @@ +/*************************************************************************** + + PFitter.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +using namespace std; + +#include "Minuit2/FunctionMinimum.h" +#include "Minuit2/MnMinimize.h" +#include "Minuit2/MnMigrad.h" +#include "Minuit2/MnMinos.h" +#include "Minuit2/MnSimplex.h" + +#include "PFitter.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + * \param runInfo + * \param runListCollection + */ +PFitter::PFitter(PMsrHandler *runInfo, PRunListCollection *runListCollection) : + fRunInfo(runInfo) +{ + fUseChi2 = true; // chi^2 is the default + + fParams = *(runInfo->GetMsrParamList()); + fCmdLines = *runInfo->GetMsrCommands(); + + // init class variables + fFitterFcn = 0; + fFcnMin = 0; + + // check msr minuit commands + if (!CheckCommands()) { + return; + } + + // create fit function object + fFitterFcn = new PFitterFcn(runListCollection, fUseChi2); + if (!fFitterFcn) { + fIsValid = false; + return; + } +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PFitter::~PFitter() +{ + fCmdList.clear(); + + if (fFitterFcn) { + delete fFitterFcn; + fFitterFcn = 0; + } +} + +//-------------------------------------------------------------------------- +// DoFit +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PFitter::DoFit() +{ + if (fUseChi2) + cout << endl << "Chi Square fit will be executed" << endl; + else + cout << endl << "Maximum Likelihood fit will be executed" << endl; + + // feed minuit parameters + SetParameters(); + + bool status; + for (unsigned int i=0; i + * + */ +bool PFitter::CheckCommands() +{ + fIsValid = true; + + PMsrLines::iterator it; + for (it = fCmdLines.begin(); it != fCmdLines.end(); ++it) { + it->fLine.ToUpper(); + if (it->fLine.Contains("COMMANDS")) { + continue; + } else if (it->fLine.Contains("SET BATCH")) { // needed for backward compatibility + continue; + } else if (it->fLine.Contains("END RETURN")) { // needed for backward compatibility + continue; + } else if (it->fLine.Contains("CHI_SQUARE")) { + fUseChi2 = true; + } else if (it->fLine.Contains("MAX_LIKELYHOOD")) { + fUseChi2 = false; + } else if (it->fLine.Contains("INTERACTIVE")) { + fCmdList.push_back(PMN_INTERACTIVE); + } else if (it->fLine.Contains("CONTOURS")) { + fCmdList.push_back(PMN_CONTOURS); + } else if (it->fLine.Contains("EIGEN")) { + fCmdList.push_back(PMN_EIGEN); + } else if (it->fLine.Contains("HESSE")) { + fCmdList.push_back(PMN_HESSE); + } else if (it->fLine.Contains("MACHINE_PRECISION")) { + fCmdList.push_back(PMN_MACHINE_PRECISION); + } else if (it->fLine.Contains("MIGRAD")) { + fCmdList.push_back(PMN_MIGRAD); + } else if (it->fLine.Contains("MINIMIZE")) { + fCmdList.push_back(PMN_MINIMIZE); + } else if (it->fLine.Contains("MINOS")) { + fCmdList.push_back(PMN_MINOS); + } else if (it->fLine.Contains("PLOT")) { + fCmdList.push_back(PMN_PLOT); + } else if (it->fLine.Contains("SAVE")) { + fCmdList.push_back(PMN_SAVE); + } else if (it->fLine.Contains("SCAN")) { + fCmdList.push_back(PMN_SCAN); + } else if (it->fLine.Contains("SIMPLEX")) { + fCmdList.push_back(PMN_SIMPLEX); + } else if (it->fLine.Contains("STRATEGY")) { + fCmdList.push_back(PMN_STRATEGY); + } else if (it->fLine.Contains("USER_COVARIANCE")) { + fCmdList.push_back(PMN_USER_COVARIANCE); + } else if (it->fLine.Contains("USER_PARAM_STATE")) { + fCmdList.push_back(PMN_USER_PARAM_STATE); + } else if (it->fLine.Contains("PRINT")) { + fCmdList.push_back(PMN_PRINT); + } else { // unkown command + cout << endl << "FATAL ERROR:"; + cout << endl << "PFitter::CheckCommands(): In line " << it->fLineNo << " an unkown command is found:"; + cout << endl << " " << it->fLine.Data(); + cout << endl << "Will stop ..."; + cout << endl; + fIsValid = false; + } + } + + return fIsValid; +} + +//-------------------------------------------------------------------------- +// SetParameters +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PFitter::SetParameters() +{ + PMsrParamList::iterator it; + + for (it = fParams.begin(); it != fParams.end(); ++it) { + // check if parameter is fixed + if (it->fStep == 0.0) { // add fixed parameter + fMnUserParams.Add(it->fName.Data(), it->fValue); + } else { // add free parameter + // check if boundaries are given + if (it->fNoOfParams > 5) { // boundaries given + fMnUserParams.Add(it->fName.Data(), it->fValue, it->fStep, it->fLowerBoundary, it->fUpperBoundary); + } else { // no boundaries given + fMnUserParams.Add(it->fName.Data(), it->fValue, it->fStep); + } + } + } + + return true; +} + +//-------------------------------------------------------------------------- +// ExecuteMigrad +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PFitter::ExecuteMigrad() +{ + cout << "PFitter::ExecuteMigrad(): will call migrad ..." << endl; + + // if already some minimization is done use the minuit2 output as input + if (fFcnMin) + fMnUserParams = fFcnMin->UserParameters(); + + // create migrad object + ROOT::Minuit2::MnMigrad migrad((*fFitterFcn), fMnUserParams); + + // minimize + ROOT::Minuit2::FunctionMinimum min = migrad(); + if (!min.IsValid()) { + cout << endl << "**WARNING**: PFitter::ExecuteMigrad(): Fit did not converge, sorry ..."; + return false; + } + + // keep FunctionMinimum object + if (fFcnMin) { // fFcnMin exist hence clean up first + delete fFcnMin; + } + fFcnMin = new ROOT::Minuit2::FunctionMinimum(min); + + // fill run info + for (unsigned int i=0; iSetMsrParamValue(i, min.UserState().Value(i)); + fRunInfo->SetMsrParamStep(i, min.UserState().Error(i)); + } + + // handle statistics + double minVal = min.Fval(); + unsigned int ndf = fFitterFcn->GetTotalNoOfFittedBins(); + // subtract number of varied parameters from total no of fitted bins -> ndf + for (unsigned int i=0; iSetMsrStatisticMin(minVal); + fRunInfo->SetMsrStatisticNdf(ndf); + + return true; +} + +//-------------------------------------------------------------------------- +// ExecuteMinimize +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PFitter::ExecuteMinimize() +{ + cout << "PFitter::ExecuteMinimize(): will call minimize ..." << endl; + + // if already some minimization is done use the minuit2 output as input + if (fFcnMin) + fMnUserParams = fFcnMin->UserParameters(); + + // create minimizer object + ROOT::Minuit2::MnMinimize minimize((*fFitterFcn), fMnUserParams); + + // minimize + ROOT::Minuit2::FunctionMinimum min = minimize(); + if (!min.IsValid()) { + cout << endl << "**WARNING**: PFitter::ExecuteMinimize(): Fit did not converge, sorry ..."; + return false; + } + + // keep FunctionMinimum object + if (fFcnMin) { // fFcnMin exist hence clean up first + delete fFcnMin; + } + fFcnMin = new ROOT::Minuit2::FunctionMinimum(min); + + // fill run info + for (unsigned int i=0; iSetMsrParamValue(i, min.UserState().Value(i)); + fRunInfo->SetMsrParamStep(i, min.UserState().Error(i)); + } + + // handle statistics + double minVal = min.Fval(); + unsigned int ndf = fFitterFcn->GetTotalNoOfFittedBins(); + // subtract number of varied parameters from total no of fitted bins -> ndf + for (unsigned int i=0; iSetMsrStatisticMin(minVal); + fRunInfo->SetMsrStatisticNdf(ndf); + + return true; +} + +//-------------------------------------------------------------------------- +// ExecuteMinos +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PFitter::ExecuteMinos() +{ + cout << "PFitter::ExecuteMinos(): will call minos ..." << endl; + + // if already some minimization is done use the minuit2 output as input + if (!fFcnMin) { + cout << endl << "**ERROR**: MINOS musn't be called before any minimization (MINIMIZE/MIGRAD/SIMPLEX) is done!!"; + cout << endl; + return false; + } + + // check if minimum was valid + if (!fFcnMin->IsValid()) { + cout << endl << "**ERROR**: MINOS cannot started since the previews minimization faild :-("; + cout << endl; + return false; + } + + fMnUserParams = fFcnMin->UserParameters(); + + // make minos analysis + ROOT::Minuit2::MnMinos minos((*fFitterFcn), (*fFcnMin)); + + for (unsigned int i=0; i err = minos(i); + + // fill msr-file structure + fRunInfo->SetMsrParamStep(i, err.first); + fRunInfo->SetMsrParamPosError(i, err.second); + } + } + + return true; +} + +//-------------------------------------------------------------------------- +// ExecuteSave +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PFitter::ExecuteSave() +{ + cout << "PFitter::ExecuteSave(): not yet implemented ..." << endl; + + // if any minimization was done, otherwise get out immediately + if (!fFcnMin) { + cout << endl << "PFitter::ExecuteSave(): nothing to be saved ..."; + return false; + } + + return true; +} + +//-------------------------------------------------------------------------- +// ExecuteSimplex +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PFitter::ExecuteSimplex() +{ + cout << "PFitter::ExecuteSimplex(): will call minimize ..." << endl; + + // if already some minimization is done use the minuit2 output as input + if (fFcnMin) + fMnUserParams = fFcnMin->UserParameters(); + + // create minimizer object + ROOT::Minuit2::MnSimplex simplex((*fFitterFcn), fMnUserParams); + + // minimize + ROOT::Minuit2::FunctionMinimum min = simplex(); + if (!min.IsValid()) { + cout << endl << "**WARNING**: PFitter::ExecuteSimplex(): Fit did not converge, sorry ..."; + return false; + } + + // keep FunctionMinimum object + if (fFcnMin) { // fFcnMin exist hence clean up first + delete fFcnMin; + } + fFcnMin = new ROOT::Minuit2::FunctionMinimum(min); + + // fill run info + for (unsigned int i=0; iSetMsrParamValue(i, min.UserState().Value(i)); + fRunInfo->SetMsrParamStep(i, min.UserState().Error(i)); + } + + // handle statistics + double minVal = min.Fval(); + unsigned int ndf = fFitterFcn->GetTotalNoOfFittedBins(); + // subtract number of varied parameters from total no of fitted bins -> ndf + for (unsigned int i=0; iSetMsrStatisticMin(minVal); + fRunInfo->SetMsrStatisticNdf(ndf); + + return true; +} diff --git a/src/classes/PFitterFcn.cpp b/src/classes/PFitterFcn.cpp new file mode 100644 index 00000000..5245bace --- /dev/null +++ b/src/classes/PFitterFcn.cpp @@ -0,0 +1,99 @@ +/*************************************************************************** + + PFitterFcn.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +using namespace std; + +#include "PFitterFcn.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + * \param runList + * \param fitType + */ +PFitterFcn::PFitterFcn(PRunListCollection *runList, bool useChi2) +{ + fUseChi2 = useChi2; + + if (fUseChi2) + fUp = 1.0; + else + fUp = 0.5; + + fRunListCollection = runList; +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ */ +PFitterFcn::~PFitterFcn() +{ +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param par + */ +double PFitterFcn::operator()(const std::vector& par) const +{ + double value = 0.0; + + if (fUseChi2) { // chi square + value += fRunListCollection->GetSingleHistoChisq(par); + value += fRunListCollection->GetAsymmetryChisq(par); + value += fRunListCollection->GetRRFChisq(par); + value += fRunListCollection->GetNonMusrChisq(par); + } else { // max likelyhood + value += fRunListCollection->GetSingleHistoMaximumLikelihood(par); + value += fRunListCollection->GetAsymmetryMaximumLikelihood(par); + value += fRunListCollection->GetRRFMaximumLikelihood(par); + value += fRunListCollection->GetNonMusrMaximumLikelihood(par); + } + +// cout << endl; +// for (unsigned int i=0; i + +#include +using namespace std; + +#include "PFunction.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + * info is an abstract syntax tree (AST) generate by the spirit parse library + * (see http://spirit.sourceforge.net/distrib/spirit_1_8_5/libs/spirit/doc/trees.html). + * It contains a single parsed msr-function in an ascii representation. + * Here it takes the from + * assignment (root node) + * |_ 'FUNx' + * |_ '=' + * |_ expression + * |_ ... + * + * Since it would be inefficient to evaluate this AST directly it is transferred to + * a more efficient tree fFuncs here in the constructor. + * + * \param info AST parse tree holding a single parsed msr-function in an ascii representation + */ +PFunction::PFunction(tree_parse_info<> info) +{ + cout << endl << "in PFunction ..."; + + fInfo = info; + + // init class variables + fValid = true; + fFuncNo = -1; + + // set the function number + SetFuncNo(); + + // generate function evaluation tree + if (!GenerateFuncEvalTree()) { + fValid = false; + } + + EvalTreeForString(info); +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ */ +PFunction::~PFunction() +{ +// cout << endl << "in ~PFunction ..."; + fParam.clear(); + fMap.clear(); + + CleanupFuncEvalTree(); +} + +//------------------------------------------------------------- +// SetFuncNo (protected) +//------------------------------------------------------------- +/** + *

+ * + * \param i + */ +bool PFunction::SetFuncNo() +{ + int funNo = -1; + int status; + bool success = true; + + // get root + iter_t i = fInfo.trees.begin(); // assignement + i = i->children.begin(); // FUNx + + // get string from tree + string str(i->value.begin(), i->value.end()); + + // extract function number from string + status = sscanf(str.c_str(), "FUN%d", &funNo); +//cout << endl << "SetFuncNo: status = " << status << ", funNo = " << funNo; + if (status == 1) { // found 1 int + fFuncNo = funNo; + } else { // wrong string + success = false; + } + + return success; +} + +//------------------------------------------------------------- +// GenerateFuncEvalTree (protected) +//------------------------------------------------------------- +/** + *

+ * + */ +bool PFunction::GenerateFuncEvalTree() +{ + FillFuncEvalTree(fInfo.trees.begin(), fFunc); + + return true; +} + +//------------------------------------------------------------- +// FillFuncEvalTree (protected) +//------------------------------------------------------------- +/** + *

+ * + */ +void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) +{ + double dvalue; + int ivalue; + int status; + string str; + PFuncTreeNode child; + + if (i->value.id() == PFunctionGrammar::realID) { // handle number + str = string(i->value.begin(), i->value.end()); // get string + status = sscanf(str.c_str(), "%lf", &dvalue); // convert string to double + node.fID = PFunctionGrammar::realID; // keep the ID + node.fDvalue = dvalue; // keep the value +// cout << endl << ">> realID: value = " << dvalue; + } else if (i->value.id() == PFunctionGrammar::parameterID) { // handle parameter number + str = string(i->value.begin(), i->value.end()); // get string + status = sscanf(str.c_str(), "PAR%d", &ivalue); // convert string to parameter number + node.fID = PFunctionGrammar::parameterID; // keep the ID + node.fIvalue = ivalue; // keep the value +// cout << endl << ">> parameterID: value = " << ivalue; + } else if (i->value.id() == PFunctionGrammar::mapID) { // handle map number + str = string(i->value.begin(), i->value.end()); // get string + status = sscanf(str.c_str(), "MAP%d", &ivalue); // convert string to map number + node.fID = PFunctionGrammar::mapID; // keep the ID + node.fIvalue = ivalue; // keep the value +// cout << endl << ">> mapID: value = " << ivalue; + } else if (i->value.id() == PFunctionGrammar::functionID) { // handle function like cos ... + // keep the id + node.fID = PFunctionGrammar::functionID; + // keep function tag + // i: 'funcName', '(', 'expression', ')' + iter_t it = i->children.begin(); + str = string(it->value.begin(), it->value.end()); // get string +// cout << endl << ">> functionID: value = " << str; + if (!strcmp(str.c_str(), "COS")) + node.fFunctionTag = FUN_COS; + else if (!strcmp(str.c_str(), "SIN")) + node.fFunctionTag = FUN_SIN; + else if (!strcmp(str.c_str(), "TAN")) + node.fFunctionTag = FUN_TAN; + else if (!strcmp(str.c_str(), "COSH")) + node.fFunctionTag = FUN_COSH; + else if (!strcmp(str.c_str(), "SINH")) + node.fFunctionTag = FUN_SINH; + else if (!strcmp(str.c_str(), "TANH")) + node.fFunctionTag = FUN_TANH; + else if (!strcmp(str.c_str(), "ACOS")) + node.fFunctionTag = FUN_ACOS; + else if (!strcmp(str.c_str(), "ASIN")) + node.fFunctionTag = FUN_ASIN; + else if (!strcmp(str.c_str(), "ATAN")) + node.fFunctionTag = FUN_ATAN; + else if (!strcmp(str.c_str(), "ACOSH")) + node.fFunctionTag = FUN_ACOSH; + else if (!strcmp(str.c_str(), "ASINH")) + node.fFunctionTag = FUN_ASINH; + else if (!strcmp(str.c_str(), "ATANH")) + node.fFunctionTag = FUN_ATANH; + else if (!strcmp(str.c_str(), "LOG")) + node.fFunctionTag = FUN_LOG; + else if (!strcmp(str.c_str(), "LN")) + node.fFunctionTag = FUN_LN; + else if (!strcmp(str.c_str(), "EXP")) + node.fFunctionTag = FUN_EXP; + else { + cout << endl << "**PANIC ERROR**: function " << str << " doesn't exist, but you never should have reached this point!"; + assert(0); + } + // add node + node.children.push_back(child); + // i: 'funcName', '(', 'expression', ')' + FillFuncEvalTree(i->children.begin()+2, node.children[0]); + } else if (i->value.id() == PFunctionGrammar::factorID) { +// cout << endl << ">> factorID"; + // keep the id + node.fID = PFunctionGrammar::factorID; + // add child lhs + node.children.push_back(child); + FillFuncEvalTree(i->children.begin(), node.children[0]); + } else if (i->value.id() == PFunctionGrammar::termID) { + // keep the id + node.fID = PFunctionGrammar::termID; + // keep operator tag + if (*i->value.begin() == '*') + node.fOperatorTag = OP_MUL; + else + node.fOperatorTag = OP_DIV; +/* +if (node.fOperatorTag == OP_MUL) + cout << endl << ">> termID: value = *"; +else + cout << endl << ">> termID: value = /"; +*/ + // add child lhs + node.children.push_back(child); + FillFuncEvalTree(i->children.begin(), node.children[0]); + // add child rhs + node.children.push_back(child); + FillFuncEvalTree(i->children.begin()+1, node.children[1]); + } else if (i->value.id() == PFunctionGrammar::expressionID) { // handle expression + // keep the id + node.fID = PFunctionGrammar::expressionID; + // keep operator tag + if (*i->value.begin() == '+') + node.fOperatorTag = OP_ADD; + else + node.fOperatorTag = OP_SUB; +/* +if (node.fOperatorTag == OP_ADD) + cout << endl << ">> expressionID: value = +"; +else + cout << endl << ">> expressionID: value = -"; +*/ + // add child lhs + node.children.push_back(child); + FillFuncEvalTree(i->children.begin(), node.children[0]); + // add child rhs + node.children.push_back(child); + FillFuncEvalTree(i->children.begin()+1, node.children[1]); + } else if (i->value.id() == PFunctionGrammar::assignmentID) { + // nothing to be done except to pass the next element in the ast + // i: 'funx', '=', 'expression' + FillFuncEvalTree(i->children.begin()+2, node); + } +} + +//------------------------------------------------------------- +// CheckMapAndParamRange (public) +//------------------------------------------------------------- +/** + *

+ * + * \param mapSize + * \param paramSize + */ +bool PFunction::CheckMapAndParamRange(unsigned int mapSize, unsigned int paramSize) +{ + return FindAndCheckMapAndParamRange(fFunc, mapSize, paramSize); +} + +//------------------------------------------------------------- +// FindAndCheckMapAndParamRange (protected) +//------------------------------------------------------------- +/** + *

+ * + * \param i + * \param mapSize + * \param paramSize + */ +bool PFunction::FindAndCheckMapAndParamRange(PFuncTreeNode &node, unsigned int mapSize, unsigned int paramSize) +{ + if (node.fID == PFunctionGrammar::realID) { + return true; + } else if (node.fID == PFunctionGrammar::parameterID) { + if (node.fIvalue <= (int) paramSize) + return true; + else + return false; + } else if (node.fID == PFunctionGrammar::mapID) { + if (node.fIvalue <= (int) mapSize) + return true; + else + return false; + } else if (node.fID == PFunctionGrammar::functionID) { + return FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize); + } else if (node.fID == PFunctionGrammar::factorID) { + return FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize); + } else if (node.fID == PFunctionGrammar::termID) { + if (FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize)) + return FindAndCheckMapAndParamRange(node.children[1], mapSize, paramSize); + else + return false; + } else if (node.fID == PFunctionGrammar::expressionID) { + if (FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize)) + return FindAndCheckMapAndParamRange(node.children[1], mapSize, paramSize); + else + return false; + } else { + cout << endl << "**PANIC ERROR**: PFunction::FindAndCheckMapAndParamRange: you never should have reached this point!" << endl; + assert(0); + } + return true; +} + +//------------------------------------------------------------- +// Eval (public) +//------------------------------------------------------------- +/** + *

+ * + */ +double PFunction::Eval(vector param) +{ + fParam = param; + + return EvalNode(fFunc); +} + +//------------------------------------------------------------- +// EvalNode (protected) +//------------------------------------------------------------- +/** + *

+ * + * \param node + */ +double PFunction::EvalNode(PFuncTreeNode &node) +{ + if (node.fID == PFunctionGrammar::realID) { + return node.fDvalue; + } else if (node.fID == PFunctionGrammar::parameterID) { + return fParam[node.fIvalue-1]; + } else if (node.fID == PFunctionGrammar::mapID) { + return fParam[fMap[node.fIvalue-1]-1]; + } else if (node.fID == PFunctionGrammar::functionID) { + if (node.fFunctionTag == FUN_COS) { + return cos(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_SIN) { + return sin(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_TAN) { + return tan(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_COSH) { + return cosh(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_SINH) { + return sinh(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_TANH) { + return tanh(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_ACOS) { + return acos(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_ASIN) { + return asin(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_ATAN) { + return atan(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_ACOSH) { + return acosh(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_ASINH) { + return asinh(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_ATANH) { + return atanh(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_LOG) { + return log(EvalNode(node.children[0]))/log(10); + } else if (node.fFunctionTag == FUN_LN) { + return log(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_EXP) { + return exp(EvalNode(node.children[0])); + } else { + cout << endl << "**PANIC ERROR**: PFunction::EvalNode: node.fID == PFunctionGrammar::functionID: you never should have reached this point!" << endl; + assert(0); + } + } else if (node.fID == PFunctionGrammar::factorID) { + return EvalNode(node.children[0]); + } else if (node.fID == PFunctionGrammar::termID) { + if (node.fOperatorTag == OP_MUL) { + return EvalNode(node.children[0]) * EvalNode(node.children[1]); + } else { + double denominator = EvalNode(node.children[1]); + if (denominator == 0.0) { + cout << endl << "**PANIC ERROR**: PFunction::EvalNode: division by 0.0" << endl; + assert(0); + } + return EvalNode(node.children[0]) / denominator; + } + } else if (node.fID == PFunctionGrammar::expressionID) { + if (node.fOperatorTag == OP_ADD) { + return EvalNode(node.children[0]) + EvalNode(node.children[1]); + } else { + return EvalNode(node.children[0]) - EvalNode(node.children[1]); + } + } else { + cout << endl << "**PANIC ERROR**: PFunction::EvalNode: you never should have reached this point!" << endl; + assert(0); + } + return 0.0; +} + +//------------------------------------------------------------- +// CleanupFuncEvalTree (protected) +//------------------------------------------------------------- +/** + *

+ * + */ +void PFunction::CleanupFuncEvalTree() +{ + // clean up all children + CleanupNode(fFunc); +} + +//------------------------------------------------------------- +// CleanupNode (protected) +//------------------------------------------------------------- +/** + *

+ * + * \param node + */ +void PFunction::CleanupNode(PFuncTreeNode &node) +{ + if (node.children.size() != 0) { + for (unsigned int i=0; i + * + * \param info + */ +void PFunction::EvalTreeForString(tree_parse_info<> info) +{ + fFuncString = ""; + EvalTreeForStringExpression(info.trees.begin()); +} + +//------------------------------------------------------------- +// EvalTreeForStringExpression (private) +//------------------------------------------------------------- +/** + *

+ * + * \param i + */ +void PFunction::EvalTreeForStringExpression(iter_t const& i) +{ + static int termOp = 0; + + if (i->value.id() == PFunctionGrammar::realID) { + assert(i->children.size() == 0); + if (*i->value.begin() == '-') + fFuncString += "("; + fFuncString += string(i->value.begin(), i->value.end()).c_str(); + if (*i->value.begin() == '-') + fFuncString += ")"; + } else if (i->value.id() == PFunctionGrammar::funLabelID) { + assert(i->children.size() == 0); + //SetFuncNo(i); + fFuncString += string(i->value.begin(), i->value.end()).c_str(); // funx + } else if (i->value.id() == PFunctionGrammar::parameterID) { + assert(i->children.size() == 0); + fFuncString += string(i->value.begin(), i->value.end()).c_str(); + } else if (i->value.id() == PFunctionGrammar::mapID) { + assert(i->children.size() == 0); + fFuncString += string(i->value.begin(), i->value.end()).c_str(); + } else if (i->value.id() == PFunctionGrammar::functionID) { + assert(i->children.size() == 4); + iter_t it = i->children.begin(); + // funcName, '(', expression, ')' + fFuncString += string(it->value.begin(), it->value.end()).c_str(); + if (termOp == 0) + fFuncString += "("; + EvalTreeForStringExpression(i->children.begin()+2); // the real stuff + if (termOp == 0) + fFuncString += ")"; + } else if (i->value.id() == PFunctionGrammar::factorID) { + EvalTreeForStringExpression(i->children.begin()); + } else if (i->value.id() == PFunctionGrammar::termID) { + if (*i->value.begin() == '*') { + assert(i->children.size() == 2); + termOp++; + EvalTreeForStringExpression(i->children.begin()); + fFuncString += " * "; + EvalTreeForStringExpression(i->children.begin()+1); + termOp--; + } else if (*i->value.begin() == '/') { + assert(i->children.size() == 2); + termOp++; + EvalTreeForStringExpression(i->children.begin()); + fFuncString += " / "; + EvalTreeForStringExpression(i->children.begin()+1); + termOp--; + } else { + assert(0); + } + } else if (i->value.id() == PFunctionGrammar::expressionID) { + if (*i->value.begin() == '+') { + assert(i->children.size() == 2); + if (termOp > 0) + fFuncString += "("; + EvalTreeForStringExpression(i->children.begin()); + fFuncString += " + "; + EvalTreeForStringExpression(i->children.begin()+1); + if (termOp > 0) + fFuncString += ")"; + } else if (*i->value.begin() == '-') { + assert(i->children.size() == 2); + if (termOp > 0) + fFuncString += "("; + EvalTreeForStringExpression(i->children.begin()); + fFuncString += " - "; + EvalTreeForStringExpression(i->children.begin()+1); + if (termOp > 0) + fFuncString += ")"; + } else { + assert(0); + } + } else if (i->value.id() == PFunctionGrammar::assignmentID) { + assert(i->children.size() == 3); + EvalTreeForStringExpression(i->children.begin()); + EvalTreeForStringExpression(i->children.begin()+1); // this is the string "=" + EvalTreeForStringExpression(i->children.begin()+2); // this is the real stuff + } else if (*i->value.begin() == '=') { + fFuncString += " = "; + } else { + assert(0); + } +} diff --git a/src/classes/PFunctionHandler.cpp b/src/classes/PFunctionHandler.cpp new file mode 100644 index 00000000..18163474 --- /dev/null +++ b/src/classes/PFunctionHandler.cpp @@ -0,0 +1,225 @@ +/*************************************************************************** + + PFunctionHandler.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include + +#include "PFunctionHandler.h" + +//------------------------------------------------------------- +// Constructor +//------------------------------------------------------------- +/** + *

+ * + * \param lines + */ +PFunctionHandler::PFunctionHandler(PMsrLines lines) +{ + fValid = true; + fLines = lines; + + cout << endl << "in PFunctionHandler(PMsrLines lines)"; +} + +//------------------------------------------------------------- +// Destructor +//------------------------------------------------------------- +/** + *

+ * + */ +PFunctionHandler::~PFunctionHandler() +{ + cout << endl << "in ~PFunctionHandler()" << endl << endl; + + fLines.clear(); + fFuncs.clear(); +} + +//------------------------------------------------------------- +// DoParse (public) +//------------------------------------------------------------- +/** + *

+ * + */ +bool PFunctionHandler::DoParse() +{ + cout << endl << "in PFunctionHandler::DoParse() ..."; + + bool success = true; + PFunctionGrammar function; + TString line; + + // feed the function block into the parser. Start with i=1, since i=0 is FUNCTIONS + for (unsigned int i=1; i info = ast_parse(line.Data(), function, space_p); + + if (info.full) { + cout << endl << "parse successfull ..." << endl; + PFunction func(info); + fFuncs.push_back(func); + } else { + cout << endl << "**ERROR**: FUNCTIONS parse failed in line " << fLines[i].fLineNo << endl; + success = false; + break; + } + } + + // check that the function numbers are unique + if (success) { + for (unsigned int i=0; i + * + * \param fileName + */ +PMsrHandler::PMsrHandler(char *fileName) +{ + // init variables + fFileName = fileName; + fMsrBlockCounter = 0; + + fTitle = ""; + + fStatistic.fChisq = true; + fStatistic.fMin = -1.0; + fStatistic.fNdf = 0; + + fFuncHandler = 0; +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ */ +PMsrHandler::~PMsrHandler() +{ + fParam.clear(); + fTheory.clear(); + fFunctions.clear(); + fRuns.clear(); + fCommands.clear(); + fPlots.clear(); + fStatistic.fStatLines.clear(); +} + +//-------------------------------------------------------------------------- +// ReadMsrFile (public) +//-------------------------------------------------------------------------- +/** + *

+ * + *

return: + * - PMUSR_SUCCESS if everything is OK + * - line number if an error in the MSR file was encountered which cannot be handled. + * + */ +int PMsrHandler::ReadMsrFile() +{ + ifstream f; + char str[256]; + TString line; + int line_no = 0; + int error = PMUSR_SUCCESS; + + PMsrLineStructure current; + + PMsrLines fit_parameter; + PMsrLines theory; + PMsrLines functions; + PMsrLines run; + PMsrLines commands; + PMsrLines plot; + PMsrLines statistic; + + // open msr-file + f.open(fFileName.Data(), iostream::in); + if (!f.is_open()) { + return PMUSR_MSR_FILE_NOT_FOUND; + } + + fMsrBlockCounter = -1; // no msr block + + // read msr-file + while (!f.eof()) { + + // read a line + f.getline(str, sizeof(str)); + line = str; + line_no++; + + current.fLineNo = line_no; + current.fLine = line; + + // if the line is not a comment line nor an empty line do something + if (!line.IsWhitespace() && !line.BeginsWith("#")) { + + // check for a msr block + if (line_no == 1) { // title + fTitle = line; + } else if (line.Contains("FITPARAMETER")) { // FITPARAMETER block tag + fMsrBlockCounter = MSR_TAG_FITPARAMETER; + } else if (line.Contains("THEORY")) { // THEORY block tag + fMsrBlockCounter = MSR_TAG_THEORY; + theory.push_back(current); + } else if (line.Contains("FUNCTIONS")) { // FUNCTIONS block tag + fMsrBlockCounter = MSR_TAG_FUNCTIONS; + functions.push_back(current); + } else if (line.Contains("RUN")) { // RUN block tag + fMsrBlockCounter = MSR_TAG_RUN; + run.push_back(current); + } else if (line.Contains("COMMANDS")) { // COMMANDS block tag + fMsrBlockCounter = MSR_TAG_COMMANDS; + commands.push_back(current); + } else if (line.Contains("PLOT")) { // PLOT block tag + fMsrBlockCounter = MSR_TAG_PLOT; + plot.push_back(current); + } else if (line.Contains("STATISTIC")) { // STATISTIC block tag + fMsrBlockCounter = MSR_TAG_STATISTIC; + statistic.push_back(current); + } else { // the read line is some real stuff + + switch (fMsrBlockCounter) { + case MSR_TAG_FITPARAMETER: // FITPARAMETER block + fit_parameter.push_back(current); + break; + case MSR_TAG_THEORY: // THEORY block + theory.push_back(current); + break; + case MSR_TAG_FUNCTIONS: // FUNCTIONS block + functions.push_back(current); + break; + case MSR_TAG_RUN: // RUN block + run.push_back(current); + break; + case MSR_TAG_COMMANDS: // COMMANDS block + commands.push_back(current); + break; + case MSR_TAG_PLOT: // PLOT block + plot.push_back(current); + break; + case MSR_TAG_STATISTIC: // STATISTIC block + statistic.push_back(current); + break; + default: + break; + } + } + } + } + + // close msr-file + f.close(); + + // execute handler of the various blocks + if (!HandleFitParameterEntry(fit_parameter)) + error = PMUSR_MSR_SYNTAX_ERROR; + if (!HandleTheoryEntry(theory)) + error = PMUSR_MSR_SYNTAX_ERROR; + if (!HandleFunctionsEntry(functions)) + error = PMUSR_MSR_SYNTAX_ERROR; + if (!HandleRunEntry(run)) + error = PMUSR_MSR_SYNTAX_ERROR; + if (!HandleCommandsEntry(commands)) + error = PMUSR_MSR_SYNTAX_ERROR; + if (!HandlePlotEntry(plot)) + error = PMUSR_MSR_SYNTAX_ERROR; + if (!HandleStatisticEntry(statistic)) + error = PMUSR_MSR_SYNTAX_ERROR; + + // clean up + fit_parameter.clear(); + theory.clear(); + functions.clear(); + run.clear(); + commands.clear(); + plot.clear(); + statistic.clear(); + + return error; +} + +//-------------------------------------------------------------------------- +// WriteMsrLogFile (public) +//-------------------------------------------------------------------------- +/** + *

+ */ +int PMsrHandler::WriteMsrLogFile() +{ + const unsigned int prec = 6; // output precision for float/doubles + + TObjArray *tokens; + TObjString *ostr; + TString str; + + // construct log file name + tokens = fFileName.Tokenize("."); + if (!tokens) + return PMUSR_TOKENIZE_ERROR; + ostr = dynamic_cast(tokens->At(0)); + str = ostr->GetString(); + str += ".mlog"; + + // clean up + if (tokens) { + delete tokens; + tokens = 0; + } + +//cout << endl << "log file name = " << str.Data() << endl << endl; + + ofstream f; + + // open mlog-file + f.open(str.Data(), iostream::out); + if (!f.is_open()) { + return PMUSR_MSR_LOG_FILE_WRITE_ERROR; + } + + // write mlog-file + + // write title + f << fTitle.Data(); + f << endl << "###############################################################"; + + // write fit parameter block + f << endl << "FITPARAMETER"; + f << endl << "# No Name Value Step Pos_Error Boundaries"; + f << endl; + PMsrParamList::iterator param_iter; + for (param_iter = fParam.begin(); param_iter != fParam.end(); ++param_iter) { + // parameter no + f.width(9); + f << right << param_iter->fNo; + f << " "; + // parameter name + f.width(11); + f << left << param_iter->fName.Data(); + f << " "; + // value of the parameter + f.width(10); + f.precision(prec); + f << left << param_iter->fValue; + // value of step/error/neg.error + f.width(12); + f.precision(prec); + f << left << param_iter->fStep; + f.width(12); + f.precision(prec); + if ((param_iter->fNoOfParams == 5) || (param_iter->fNoOfParams == 7)) // pos. error given + if (param_iter->fPosErrorPresent) // pos error is a number + f << left << param_iter->fPosError; + else // pos error is a none + f << left << "none"; + else // no pos. error + f << left << "none"; + // boundaries + if (param_iter->fNoOfParams > 5) { + f.width(8); + f.precision(prec); + f << left << param_iter->fLowerBoundary; + f.width(8); + f.precision(prec); + f << left << param_iter->fUpperBoundary; + } + // terminate line + f << endl; + } + f << endl << "###############################################################"; + + // write theory block + PMsrLines::iterator theo_iter; + for (theo_iter = fTheory.begin(); theo_iter != fTheory.end(); ++theo_iter) { + f << endl << theo_iter->fLine.Data(); + } + f << endl; + f << endl << "###############################################################"; + + // write functions block + f << endl << "FUNCTIONS"; + for (int i=0; iGetFuncString(i); + str.ToLower(); + f << endl << str.Data(); + } + f << endl; + f << endl << "###############################################################"; + + // write run block + PMsrRunList::iterator run_iter; + for (run_iter = fRuns.begin(); run_iter != fRuns.end(); ++run_iter) { + // run header + f << endl << "RUN " << run_iter->fRunName.Data() << " "; + str = run_iter->fBeamline; + str.ToUpper(); + f << str.Data() << " "; + str = run_iter->fInstitute; + str.ToUpper(); + f << str.Data() << " "; + str = run_iter->fFileFormat; + str.ToUpper(); + f << str.Data() << " (name beamline institute data-file-format)"; + // fittype + f.width(16); + switch (run_iter->fFitType) { + case MSR_FITTYPE_SINGLE_HISTO: + f << endl << left << "fittype" << MSR_FITTYPE_SINGLE_HISTO << " (single histogram fit)"; + break; + case MSR_FITTYPE_ASYM: + f << endl << left << "fittype" << MSR_FITTYPE_ASYM << " (asymmetry fit)"; + break; + case MSR_FITTYPE_ASYM_RRF: + f << endl << left << "fittype" << MSR_FITTYPE_ASYM_RRF << " (RRF asymmetry fit)"; + break; + case MSR_FITTYPE_NO_MUSR: + f << endl << left << "fittype" << MSR_FITTYPE_NO_MUSR << " (non muSR fit)"; + break; + default: + break; + } + // rrffrequency + if (run_iter->fRRFFreq != -1.0) { + f.width(16); + f << endl << left << "rrffrequency"; + f.precision(prec); + f << run_iter->fRRFFreq; + } + // rrfpacking + if (run_iter->fRRFPacking != -1) { + f.width(16); + f << endl << left << "rrfpacking"; + f.precision(prec); + f << run_iter->fRRFPacking; + } + // alpha + if (run_iter->fAlphaParamNo != -1) { + f.width(16); + f << endl << left << "alpha"; + f << run_iter->fAlphaParamNo; + } + // beta + if (run_iter->fBetaParamNo != -1) { + f.width(16); + f << endl << left << "beta"; + f << run_iter->fBetaParamNo; + } + // alpha2 + if (run_iter->fAlpha2ParamNo != -1) { + f.width(16); + f << endl << left << "alpha2"; + f << run_iter->fAlpha2ParamNo; + } + // beta2 + if (run_iter->fBeta2ParamNo != -1) { + f.width(16); + f << endl << left << "beta2"; + f << run_iter->fBeta2ParamNo; + } + // norm + if (run_iter->fNormParamNo != -1) { + f.width(16); + f << endl << left << "norm"; + // check if norm is give as a function + if (run_iter->fNormParamNo >= MSR_PARAM_FUN_OFFSET) + f << "fun" << run_iter->fNormParamNo-MSR_PARAM_FUN_OFFSET; + else + f << run_iter->fNormParamNo; + } + // backgr.fit + if (run_iter->fBkgFitParamNo != -1) { + f.width(16); + f << endl << left << "backgr.fit"; + f << run_iter->fBkgFitParamNo; + } + // rphase + if (run_iter->fPhaseParamNo != -1) { + f.width(16); + f << endl << left << "rphase"; + f << run_iter->fPhaseParamNo; + } + // lifetime + if (run_iter->fLifetimeParamNo != -1) { + f.width(16); + f << endl << left << "lifetime"; + f << run_iter->fLifetimeParamNo; + } + // lifetimecorrection + if ((run_iter->fLifetimeCorrection) && (run_iter->fFitType == MSR_FITTYPE_SINGLE_HISTO)) { + f << endl << "lifetimecorrection"; + } + // map + PIntVector::iterator map_iter; + f << endl << "map "; + for (map_iter = run_iter->fMap.begin(); map_iter != run_iter->fMap.end(); ++map_iter) { + f.width(5); + f << right << *map_iter; + } + // if there are less maps then 10 fill with zeros + if (run_iter->fMap.size() < 10) { + for (int i=run_iter->fMap.size(); i<10; i++) + f << " 0"; + } + // forward + if (run_iter->fForwardHistoNo != -1) { + f.width(16); + f << endl << left << "forward"; + f << run_iter->fForwardHistoNo; + } + // backward + if (run_iter->fBackwardHistoNo != -1) { + f.width(16); + f << endl << left << "backward"; + f << run_iter->fBackwardHistoNo; + } + // right + if (run_iter->fRightHistoNo != -1) { + f.width(16); + f << endl << left << "right"; + f << run_iter->fRightHistoNo; + } + // left + if (run_iter->fLeftHistoNo != -1) { + f.width(16); + f << endl << left << "left"; + f << run_iter->fLeftHistoNo; + } + // backgr.fix + if (!isnan(run_iter->fBkgFix[0])) { + f.width(15); + f << endl << left << "backgr.fix"; + for (int i=0; i<2; i++) { + f.precision(prec); + f.width(12); + f << left << run_iter->fBkgFix[i]; + } + } + // background + if (run_iter->fBkgRange[0] != -1) { + f.width(16); + f << endl << "background"; + for (int i=0; i<4; i++) { + if (run_iter->fBkgRange[i] == -1) + break; + f.width(8); + f << left << run_iter->fBkgRange[i]; + } + } + // data + if (run_iter->fDataRange[0] != -1) { + f.width(16); + f << endl << "data"; + for (int i=0; i<4; i++) { + if (run_iter->fDataRange[i] == -1) + break; + f.width(8); + f << left << run_iter->fDataRange[i]; + } + } + // t0 + if (run_iter->fT0[0] != -1) { + f.width(16); + f << endl << "t0"; + for (int i=0; i<2; i++) { + if (run_iter->fT0[i] == -1) + break; + f.width(8); + f << left << run_iter->fT0[i]; + } + } + // fit + if (run_iter->fFitRange[0] != -1) { + f.width(16); + f << endl << "fit"; + for (int i=0; i<2; i++) { + if (run_iter->fFitRange[i] == -1) + break; + f.width(8); + f.precision(2); + f << left << fixed << run_iter->fFitRange[i]; + } + } + // packing + f.width(16); + f << endl << left << "packing"; + f << run_iter->fPacking; + // run block done + f << endl; + } + f << endl << "###############################################################"; + + // write command block + f << endl << "COMMANDS"; + PMsrLines::iterator cmd_iter; + for (cmd_iter = fCommands.begin(); cmd_iter != fCommands.end(); ++cmd_iter) { + f << endl << cmd_iter->fLine.Data(); + } + f << endl; + f << endl << "###############################################################"; + + // write plot block + PMsrPlotList::iterator plot_iter; + for (plot_iter = fPlots.begin(); plot_iter != fPlots.end(); ++plot_iter) { + // plot header + switch (plot_iter->fPlotType) { + case MSR_PLOT_SINGLE_HISTO: + f << endl << "PLOT " << plot_iter->fPlotType << " (single histo plot)"; + break; + case MSR_PLOT_ASYM: + f << endl << "PLOT " << plot_iter->fPlotType << " (asymmetry plot)"; + break; + case MSR_PLOT_ASYM_RRF: + f << endl << "PLOT " << plot_iter->fPlotType << " (rotating reference frame plot)"; + break; + case MSR_PLOT_NO_MUSR: + f << endl << "PLOT " << plot_iter->fPlotType << " (non muSR plot)"; + break; + default: + break; + } + // runs + f << endl << "runs "; + f.precision(0); + PComplexVector::iterator r_it; + for (r_it = plot_iter->fRuns.begin(); r_it != plot_iter->fRuns.end(); ++r_it) { + if (plot_iter->fPlotType != MSR_PLOT_ASYM_RRF) { // all but MSR_PLOT_ASYM_RRF + f.width(4); + f << r_it->Re(); + } else { // MSR_PLOT_ASYM_RRF + f << r_it->Re() << "," << r_it->Im() << " "; + } + } + // range + f << endl << "range "; + f.precision(2); + f << plot_iter->fTmin << " " << plot_iter->fTmax; + if (plot_iter->fYmin != -999.0) { + f << " " << plot_iter->fYmin << " " << plot_iter->fYmax; + } + f << endl; + } + f << endl << "###############################################################"; + + // write statistic block + TDatime dt; + f << endl << "STATISTIC --- " << dt.AsSQLString(); + // if fMin and fNdf are given, make new statistic block + if ((fStatistic.fMin != -1.0) && (fStatistic.fNdf != 0)) { + // throw away the old statistics block + fStatistic.fStatLines.clear(); + // create the new statistics block + PMsrLineStructure line; + if (fStatistic.fChisq) { // chi^2 + line.fLine = " chi2 = "; + line.fLine += fStatistic.fMin; + line.fLine += ", NDF = "; + line.fLine += fStatistic.fNdf; + line.fLine += ", chi2r = chi2/NDF = "; + line.fLine += fStatistic.fMin / fStatistic.fNdf; + } else { + line.fLine = " maxLH = "; + line.fLine += fStatistic.fMin; + line.fLine += ", NDF = "; + line.fLine += fStatistic.fNdf; + line.fLine += ", maxLHr = maxLH/NDF = "; + line.fLine += fStatistic.fMin / fStatistic.fNdf; + } + fStatistic.fStatLines.push_back(line); + } + // write the statistics block + PMsrLines::iterator stat_iter; + for (stat_iter = fStatistic.fStatLines.begin(); stat_iter != fStatistic.fStatLines.end(); ++stat_iter) { + f << endl << stat_iter->fLine.Data(); + } + f << endl; + f << endl << "###############################################################"; + + + // close mlog-file + f.close(); + + return PMUSR_SUCCESS; +} + +//-------------------------------------------------------------------------- +// SetMsrParamValue (public) +//-------------------------------------------------------------------------- +/** + *

+ * + * \param i + * \param value + */ +bool PMsrHandler::SetMsrParamValue(unsigned int i, double value) +{ + if (i > fParam.size()) { + cout << endl << "PMsrHandler::SetMsrParamValue(): i = " << i << " is larger than the number of parameters " << fParam.size(); + cout << endl; + return false; + } + + fParam[i].fValue = value; + + return true; +} + +//-------------------------------------------------------------------------- +// SetMsrParamStep (public) +//-------------------------------------------------------------------------- +/** + *

+ * + * \param i + * \param value + */ +bool PMsrHandler::SetMsrParamStep(unsigned int i, double value) +{ + if (i > fParam.size()) { + cout << endl << "PMsrHandler::SetMsrParamValue(): i = " << i << " is larger than the number of parameters " << fParam.size(); + cout << endl; + return false; + } + + fParam[i].fStep = value; + + return true; +} + +//-------------------------------------------------------------------------- +// SetMsrParamPosError (public) +//-------------------------------------------------------------------------- +/** + *

+ * + * \param i + * \param value + */ +bool PMsrHandler::SetMsrParamPosError(unsigned int i, double value) +{ + if (i > fParam.size()) { + cout << endl << "PMsrHandler::SetMsrParamPosError(): i = " << i << " is larger than the number of parameters " << fParam.size(); + cout << endl; + return false; + } + + fParam[i].fPosErrorPresent = true; + fParam[i].fPosError = value; + + return true; +} + +//-------------------------------------------------------------------------- +// HandleFitParameterEntry (private) +//-------------------------------------------------------------------------- +/** + *

The routine analyze a parameter line and, if the possible parameter list + * is OK (what this means see below), it adds the parameter to the parameter list. + * + *

Possible cases: + * \code + * No Name Value Step/Neg_Error Pos_Error Boundary_Low Boundary_High + * x x x x x x x -> 7 Parameters, e.g. after a MINOS fit + * x x x x x x -> 6 Parameters, e.g. after a MIGRAD fit + * x x x x x -> 5 Parameters, e.g. after a MINOS fit + * without boundaries + * x x x x -> 4 Parameters, e.g. after MIGRAD fit + * without bounderies, or + * when starting + * \endcode + * + * \param lines is a list of lines containing the fitparameter block + */ +bool PMsrHandler::HandleFitParameterEntry(PMsrLines &lines) +{ + PMsrParamStructure param; + bool error = false; + + PMsrLines::iterator iter; + + TObjArray *tokens; + TObjString *ostr; + TString str; + + // init param structure + param.fNoOfParams = -1; + param.fNo = -1; + param.fName = TString(""); + param.fValue = nan("NAN"); + param.fStep = nan("NAN"); + param.fPosErrorPresent = nan("NAN"); + param.fPosError = nan("NAN"); + param.fLowerBoundary = nan("NAN"); + param.fUpperBoundary = nan("NAN"); + + // fill param structure + iter = lines.begin(); + while ((iter != lines.end()) && !error) { + + tokens = iter->fLine.Tokenize(" "); + if (!tokens) { + cout << endl << "SEVERE ERROR: Couldn't tokenize Parameters in line " << iter->fLineNo; + cout << endl << endl; + return false; + } + + // handle various input possiblities + if ((tokens->GetEntries() < 4) || (tokens->GetEntries() > 7)) { + error = true; + } else { // handle the first 4 parameter since they are always the same + // parameter number + ostr = dynamic_cast(tokens->At(0)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fNo = str.Atoi(); + else + error = true; + + // parameter name + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + param.fName = str; + + // parameter value + ostr = dynamic_cast(tokens->At(2)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fValue = (double)str.Atof(); + else + error = true; + + // parameter value + ostr = dynamic_cast(tokens->At(3)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fStep = (double)str.Atof(); + else + error = true; + + // 4 values, i.e. No Name Value Step + if (tokens->GetEntries() == 4) { + param.fNoOfParams = 4; + } + + // 5 values, i.e. No Name Value Neg_Error Pos_Error + if (tokens->GetEntries() == 5) { + param.fNoOfParams = 5; + + // positive error + ostr = dynamic_cast(tokens->At(4)); + str = ostr->GetString(); + if (str.IsFloat()) { + param.fPosErrorPresent = true; + param.fPosError = (double)str.Atof(); + } else { + str.ToLower(); + if (!str.CompareTo("none")) + param.fPosErrorPresent = false; + else + error = true; + } + } + + // 6 values, i.e. No Name Value Error Lower_Bounderay Upper_Boundary + if (tokens->GetEntries() == 6) { + param.fNoOfParams = 6; + + // lower boundary + ostr = dynamic_cast(tokens->At(4)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fLowerBoundary = (double)str.Atof(); + else + error = true; + + // upper boundary + ostr = dynamic_cast(tokens->At(5)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fUpperBoundary = (double)str.Atof(); + else + error = true; + } + + // 7 values, i.e. No Name Value Neg_Error Pos_Error Lower_Bounderay Upper_Boundary + if (tokens->GetEntries() == 7) { + param.fNoOfParams = 7; + + // positive error + ostr = dynamic_cast(tokens->At(4)); + str = ostr->GetString(); + if (str.IsFloat()) { + param.fPosErrorPresent = true; + param.fPosError = (double)str.Atof(); + } else { + str.ToLower(); + if (!str.CompareTo("none")) + param.fPosErrorPresent = false; + else + error = true; + } + + // lower boundary + ostr = dynamic_cast(tokens->At(5)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fLowerBoundary = (double)str.Atof(); + else + error = true; + + // upper boundary + ostr = dynamic_cast(tokens->At(6)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fUpperBoundary = (double)str.Atof(); + else + error = true; + } + } + + // check if enough elements found + if (error) { + cout << endl << "ERROR in line " << iter->fLineNo << ":"; + cout << endl << iter->fLine.Data(); + cout << endl << "A Fit Parameter line needs to have the following form: "; + cout << endl; + cout << endl << "No Name Value Step/Error [Lower_Boundary Upper_Boundary]"; + cout << endl; + cout << endl << "or"; + cout << endl; + cout << endl << "No Name Value Step/Neg_Error Pos_Error [Lower_Boundary Upper_Boundary]"; + cout << endl; + cout << endl << "No: the parameter number (an int)"; + cout << endl << "Name: the name of the parameter (less than 256 character)"; + cout << endl << "Value: the starting value of the parameter (a double)"; + cout << endl << "Step/Error,"; + cout << endl << "Step/Neg_Error: the starting step value in a fit (a double), or"; + cout << endl << " the symmetric error (MIGRAD, SIMPLEX), or"; + cout << endl << " the negative error (MINOS)"; + cout << endl << "Pos_Error: the positive error (MINOS), (a double)"; + cout << endl << "Lower_Boundary: the lower boundary allowed for the fit parameter (a double)"; + cout << endl << "Upper_Boundary: the upper boundary allowed for the fit parameter (a double)"; + cout << endl; + } else { // everything is OK, therefore add the parameter to the parameter list + fParam.push_back(param); + } + + // clean up + if (tokens) { + delete tokens; + tokens = 0; + } + + iter++; + } + + return !error; +} + +//-------------------------------------------------------------------------- +// HandleTheoryEntry (private) +//-------------------------------------------------------------------------- +/** + *

+ * + * \param lines is a list of lines containing the fitparameter block + */ +bool PMsrHandler::HandleTheoryEntry(PMsrLines &lines) +{ + // store the theory lines + fTheory = lines; + + return true; +} + +//-------------------------------------------------------------------------- +// HandleFunctionsEntry (private) +//-------------------------------------------------------------------------- +/** + *

+ * + * \param lines is a list of lines containing the fitparameter block + */ +bool PMsrHandler::HandleFunctionsEntry(PMsrLines &lines) +{ + // store the functions lines + fFunctions = lines; + + // create function handler + fFuncHandler = new PFunctionHandler(fFunctions); + if (fFuncHandler == 0) { + cout << endl << "**ERROR**: PMsrHandler::HandleFunctionsEntry: Couldn't invoke PFunctionHandler"; + return false; + } + + // do the parsing + if (!fFuncHandler->DoParse()) { + return false; + } + + return true; +} + +//-------------------------------------------------------------------------- +// HandleRunEntry (private) +//-------------------------------------------------------------------------- +/** + *

+ * + * \param lines is a list of lines containing the fitparameter block + */ +bool PMsrHandler::HandleRunEntry(PMsrLines &lines) +{ + PMsrLines::iterator iter; + PMsrRunStructure param; + bool first = true; // first run line tag + bool error = false; + + TString str; + TObjString *ostr; + TObjArray *tokens; + + iter = lines.begin(); + while ((iter != lines.end()) && !error) { + // everything to lower case first + iter->fLine.ToLower(); + + // tokenize line + tokens = iter->fLine.Tokenize(" "); + if (!tokens) { + cout << endl << "SEVERE ERROR: Couldn't tokenize Parameters in line " << iter->fLineNo; + cout << endl << endl; + return false; + } + + // RUN line ---------------------------------------------- + if (iter->fLine.BeginsWith("run")) { + + if (!first) // not the first run in the list + fRuns.push_back(param); + else + first = false; + + InitRunParameterStructure(param); + + // get run name, beamline, institute, and file-format + if (tokens->GetEntries() < 5) { + error = true; + } else { + // run name + ostr = dynamic_cast(tokens->At(1)); + param.fRunName = ostr->GetString(); + // beamline + ostr = dynamic_cast(tokens->At(2)); + param.fBeamline = ostr->GetString(); + // institute + ostr = dynamic_cast(tokens->At(3)); + param.fInstitute = ostr->GetString(); + // data file format + ostr = dynamic_cast(tokens->At(4)); + param.fFileFormat = ostr->GetString(); + } + } + + // fittype ------------------------------------------------- + if (iter->fLine.BeginsWith("fittype")) { + if (tokens->GetEntries() < 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) { + int fittype = str.Atoi(); + if ((fittype == MSR_FITTYPE_SINGLE_HISTO) || + (fittype == MSR_FITTYPE_ASYM) || + (fittype == MSR_FITTYPE_ASYM_RRF) || + (fittype == MSR_FITTYPE_NO_MUSR)) { + param.fFitType = fittype; + } else { + error = true; + } + } else { + error = true; + } + } + } + + // alpha ------------------------------------------------- + if (iter->fLine.BeginsWith("alpha")) { + if (tokens->GetEntries() < 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fAlphaParamNo = str.Atoi(); + else + error = true; + } + } + + // beta ------------------------------------------------- + if (iter->fLine.BeginsWith("beta")) { + if (tokens->GetEntries() < 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fBetaParamNo = str.Atoi(); + else + error = true; + } + } + + // norm ------------------------------------------------- + if (iter->fLine.BeginsWith("norm")) { + if (tokens->GetEntries() < 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) { + param.fNormParamNo = str.Atoi(); + } else if (str.Contains("fun")) { + int no; + if (FilterFunMapNumber(str, "fun", no)) + param.fNormParamNo = no; + else + error = true; + } else { + error = true; + } + } + } + + // backgr.fit -------------------------------------------- + if (iter->fLine.BeginsWith("backgr.fit")) { + if (tokens->GetEntries() < 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fBkgFitParamNo = str.Atoi(); + else + error = true; + } + } + + // rphase ------------------------------------------------ + if (iter->fLine.BeginsWith("rphase")) { + if (tokens->GetEntries() < 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fPhaseParamNo = str.Atoi(); + else + error = true; + } + } + + // lifetime ------------------------------------------------ + if (iter->fLine.BeginsWith("lifetime ")) { + if (tokens->GetEntries() < 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fLifetimeParamNo = str.Atoi(); + else + error = true; + } + } + + // lifetimecorrection --------------------------------------- + if (iter->fLine.BeginsWith("lifetimecorrection")) { + param.fLifetimeCorrection = true; + } + + // map ------------------------------------------------------ + if (iter->fLine.BeginsWith("map")) { + for (int i=1; iGetEntries(); i++) { + ostr = dynamic_cast(tokens->At(i)); + str = ostr->GetString(); + if (str.IsDigit()) + // only fill map vector until a first zero is encountered + if (str.Atoi() != 0) + param.fMap.push_back(str.Atoi()); + else + break; + else + error = true; + } + // check map entries, i.e. if the map values are within parameter bounds + for (unsigned int i=0; i (int) fParam.size())) { + cout << endl << "**SEVERE ERROR** in PMsrHandler::HandleRunEntry: map value " << param.fMap[i] << " in line " << iter->fLineNo << " is out of range!"; + error = true; + break; + } + } + } + + // forward ------------------------------------------------ + if (iter->fLine.BeginsWith("forward")) { + if (tokens->GetEntries() < 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fForwardHistoNo = str.Atoi(); + else + error = true; + } + } + + // backward ----------------------------------------------- + if (iter->fLine.BeginsWith("backward")) { + if (tokens->GetEntries() < 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fBackwardHistoNo = str.Atoi(); + else + error = true; + } + } + + // backgr.fix ---------------------------------------------- + if (iter->fLine.BeginsWith("backgr.fix")) { + if (tokens->GetEntries() != 3) { + error = true; + } else { + for (int i=1; i<3; i++) { + ostr = dynamic_cast(tokens->At(i)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fBkgFix[i-1] = str.Atof(); + else + error = true; + } + } + } + + // background --------------------------------------------- + if (iter->fLine.BeginsWith("background")) { + if ((tokens->GetEntries() != 3) && (tokens->GetEntries() != 5)) { + error = true; + } else { + for (int i=1; iGetEntries(); i++) { + ostr = dynamic_cast(tokens->At(i)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fBkgRange[i-1] = str.Atoi(); + else + error = true; + } + } + } + + // data -------------------------------------------------- + if (iter->fLine.BeginsWith("data")) { + if ((tokens->GetEntries() != 3) && (tokens->GetEntries() != 5)) { + error = true; + } else { + for (int i=1; iGetEntries(); i++) { + ostr = dynamic_cast(tokens->At(i)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fDataRange[i-1] = str.Atoi(); + else + error = true; + } + } + } + + // t0 ----------------------------------------------------- + if (iter->fLine.BeginsWith("t0")) { + if ((tokens->GetEntries() != 2) && (tokens->GetEntries() != 3)) { + error = true; + } else { + for (int i=1; iGetEntries(); i++) { + ostr = dynamic_cast(tokens->At(i)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fT0[i-1] = str.Atoi(); + else + error = true; + } + } + } + + // fit ----------------------------------------------------- + if (iter->fLine.BeginsWith("fit ")) { + if (tokens->GetEntries() < 3) { + error = true; + } else { + for (int i=1; i<3; i++) { + ostr = dynamic_cast(tokens->At(i)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fFitRange[i-1] = str.Atof(); + else + error = true; + } + } + } + + // packing -------------------------------------------------- + if (iter->fLine.BeginsWith("packing")) { + if (tokens->GetEntries() != 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fPacking = str.Atoi(); + else + error = true; + } + } + + // rrffrequency -------------------------------------------------- + if (iter->fLine.BeginsWith("rrffrequency")) { + if (tokens->GetEntries() != 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fRRFFreq = str.Atof(); + else + error = true; + } + } + + // rrfpacking -------------------------------------------------- + if (iter->fLine.BeginsWith("rrfpacking")) { + if (tokens->GetEntries() != 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fRRFPacking = str.Atoi(); + else + error = true; + } + } + + // alpha2 -------------------------------------------------- + if (iter->fLine.BeginsWith("alpha2")) { + if (tokens->GetEntries() != 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fAlpha2ParamNo = str.Atoi(); + else + error = true; + } + } + + // beta2 -------------------------------------------------- + if (iter->fLine.BeginsWith("beta2")) { + if (tokens->GetEntries() != 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fBeta2ParamNo = str.Atoi(); + else + error = true; + } + } + + // right -------------------------------------------------- + if (iter->fLine.BeginsWith("right")) { + if (tokens->GetEntries() != 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fRightHistoNo = str.Atoi(); + else + error = true; + } + } + + // left -------------------------------------------------- + if (iter->fLine.BeginsWith("left")) { + if (tokens->GetEntries() != 2) { + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fLeftHistoNo = str.Atoi(); + else + error = true; + } + } + + // clean up + if (tokens) { + delete tokens; + tokens = 0; + } + + ++iter; + } + + if (error) { + --iter; + cout << endl << "ERROR in line " << iter->fLineNo << ":"; + cout << endl << iter->fLine.Data(); + cout << endl << "RUN block syntax is too complex to print it here. Please check the manual."; + } else { // save last run found + fRuns.push_back(param); + } + + return !error; +} + +//-------------------------------------------------------------------------- +// InitRunParameterStructure (private) +//-------------------------------------------------------------------------- +/** + *

+ * + * \param param + */ +void PMsrHandler::InitRunParameterStructure(PMsrRunStructure ¶m) +{ + param.fRunName = ""; + param.fBeamline = ""; + param.fInstitute = ""; + param.fFileFormat = ""; + param.fFitType = -1; + param.fAlphaParamNo = -1; + param.fBetaParamNo = -1; + param.fNormParamNo = -1; + param.fBkgFitParamNo = -1; + param.fPhaseParamNo = -1; + param.fLifetimeParamNo = -1; + param.fLifetimeCorrection = true; + param.fMap.clear(); // empty list + param.fForwardHistoNo = -1; + param.fBackwardHistoNo = -1; + for (int i=0; i<2; i++) + param.fBkgFix[i] = nan("NAN"); + for (int i=0; i<4; i++) + param.fBkgRange[i] = -1; + for (int i=0; i<4; i++) + param.fDataRange[i] = -1; + for (int i=0; i<2; i++) + param.fT0[i] = -1; + for (int i=0; i<4; i++) + param.fFitRange[i] = -1; + param.fPacking = 1; + param.fRRFFreq = -1.0; + param.fRRFPacking = -1; + param.fAlpha2ParamNo = -1; + param.fBeta2ParamNo = -1; + param.fRightHistoNo = -1; + param.fLeftHistoNo = -1; +} + +//-------------------------------------------------------------------------- +// FilterFunMapNumber (private) +//-------------------------------------------------------------------------- +/** + *

Used to filter numbers from a string of the structure strX, where + * X is a number. The filter string is used to define the offset to X. + * It is used to filter strings like: map1 or fun4. At the moment only + * the filter strings 'map' and 'fun' are supported. + * + * \param str input string + * \param filter filter string + * \param no filtered number + */ +bool PMsrHandler::FilterFunMapNumber(TString str, const char *filter, int &no) +{ + int found, no_found=-1; + + // copy str to an ordinary c-like string + char *cstr; + cstr = new char[str.Sizeof()]; + strncpy(cstr, str.Data(), str.Sizeof()); + + // get number if present + if (!strcmp(filter, "fun")) { + found = sscanf(cstr, "fun%d", &no_found); + if (found == 1) + if (no_found < 1000) + no = no_found + MSR_PARAM_FUN_OFFSET; + } else if (!strcmp(filter, "map")) { + found = sscanf(cstr, "map%d", &no_found); + if (found == 1) + if (no_found < 1000) + no = no_found + MSR_PARAM_MAP_OFFSET; + } + + // clean up + if (cstr) { + delete [] cstr; + cstr = 0; + } + + if ((no_found < 0) || (no_found > 1000)) + return false; + else + return true; +} + +//-------------------------------------------------------------------------- +// HandleCommandsEntry (private) +//-------------------------------------------------------------------------- +/** + *

In the command block there shall be a new command which can be used + * to switch between chi2 and maximum_likelyhood!! + * + * \param lines is a list of lines containing the fitparameter block + */ +bool PMsrHandler::HandleCommandsEntry(PMsrLines &lines) +{ + PMsrLines::iterator iter; + + if (lines.empty()) { + cout << endl << "WARNING: There is no COMMANDS block! Do you really want this?"; + cout << endl; + } + + for (iter = lines.begin(); iter != lines.end(); ++iter) { + if (!iter->fLine.BeginsWith("COMMANDS")) + fCommands.push_back(*iter); + } + + return true; +} + +//-------------------------------------------------------------------------- +// HandlePlotEntry (private) +//-------------------------------------------------------------------------- +/** + *

+ * + * \param lines is a list of lines containing the fitparameter block + */ +bool PMsrHandler::HandlePlotEntry(PMsrLines &lines) +{ + bool error = false; + + PMsrPlotStructure param; + + PMsrLines::iterator iter1; + PMsrLines::iterator iter2; + TObjArray *tokens; + TObjArray *tokens2; + TObjString *ostr; + TString str; + TString str2; + + if (lines.empty()) { + cout << endl << "WARNING: There is no PLOT block! Do you really want this?"; + cout << endl; + } + + iter1 = lines.begin(); + while ((iter1 != lines.end()) && !error) { + + // initialize param structure + param.fPlotType = -1; + param.fTmin = -999.0; + param.fTmax = -999.0; + param.fYmin = -999.0; + param.fYmax = -999.0; + + // find next plot if any is present + iter2 = iter1; + ++iter2; + for ( ; iter2 != lines.end(); ++iter2) { + if (iter2->fLine.Contains("PLOT")) + break; + } + + // handle a single PLOT block + while ((iter1 != iter2) && !error) { + + if (iter1->fLine.Contains("PLOT")) { // handle plot header + tokens = iter1->fLine.Tokenize(" "); + if (!tokens) { + cout << endl << "SEVERE ERROR: Couldn't tokenize PLOT in line " << iter1->fLineNo; + cout << endl << endl; + return false; + } + if (tokens->GetEntries() < 2) { // plot type missing + error = true; + } else { + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsDigit()) + param.fPlotType = str.Atoi(); + else + error = true; + } + // clean up + if (tokens) { + delete tokens; + tokens = 0; + } + } + + if (iter1->fLine.Contains("runs")) { // handle plot runs + TComplex run; + switch (param.fPlotType) { + case -1: + error = true; + break; + case MSR_PLOT_SINGLE_HISTO: // like: runs 1 5 13 + case MSR_PLOT_ASYM: + case MSR_PLOT_NO_MUSR: + tokens = iter1->fLine.Tokenize(" "); + if (!tokens) { + cout << endl << "SEVERE ERROR: Couldn't tokenize PLOT in line " << iter1->fLineNo; + cout << endl << endl; + return false; + } + if (tokens->GetEntries() < 2) { // runs missing + error = true; + } else { + for (int i=1; iGetEntries(); i++) { + ostr = dynamic_cast(tokens->At(i)); + str = ostr->GetString(); + if (str.IsDigit()) { + run = TComplex(str.Atoi(),-1.0); + param.fRuns.push_back(run); + } else { + error = true; + } + } + } + // clean up + if (tokens) { + delete tokens; + tokens = 0; + } + break; + case MSR_PLOT_ASYM_RRF: // like: runs 1,1 1,2 + tokens = iter1->fLine.Tokenize(" "); + if (!tokens) { + cout << endl << "SEVERE ERROR: Couldn't tokenize PLOT in line " << iter1->fLineNo; + cout << endl << endl; + return false; + } + if (tokens->GetEntries() < 2) { // runs missing + error = true; + } else { + for (int i=1; iGetEntries(); i++) { + ostr = dynamic_cast(tokens->At(i)); // something like 1,2 + str = ostr->GetString(); + tokens2 = str.Tokenize(","); + if (!tokens2) { + error = true; + } else { + ostr = dynamic_cast(tokens2->At(0)); // real part + str = ostr->GetString(); + ostr = dynamic_cast(tokens2->At(1)); // imag part + str2 = ostr->GetString(); + if (str.IsDigit() && str2.IsDigit()) { + run = TComplex(str.Atoi(),str2.Atoi()); + param.fRuns.push_back(run); + } else { + error = true; + } + } + if (tokens2) { + delete tokens2; + tokens2 = 0; + } + } + } + // clean up + if (tokens) { + delete tokens; + tokens = 0; + } + break; + default: + error = true; + break; + } + } + + if (iter1->fLine.Contains("range")) { // handle plot range + tokens = iter1->fLine.Tokenize(" "); + if (!tokens) { + cout << endl << "SEVERE ERROR: Couldn't tokenize PLOT in line " << iter1->fLineNo; + cout << endl << endl; + return false; + } + if ((tokens->GetEntries() != 3) && (tokens->GetEntries() != 5)) { + error = true; + } else { + + // handle t_min + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fTmin = (double)str.Atof(); + else + error = true; + + // handle t_max + ostr = dynamic_cast(tokens->At(2)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fTmax = (double)str.Atof(); + else + error = true; + + if (tokens->GetEntries() == 5) { // y-axis interval given as well + + // handle y_min + ostr = dynamic_cast(tokens->At(3)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fYmin = (double)str.Atof(); + else + error = true; + + // handle y_max + ostr = dynamic_cast(tokens->At(4)); + str = ostr->GetString(); + if (str.IsFloat()) + param.fYmax = (double)str.Atof(); + else + error = true; + } + } + // clean up + if (tokens) { + delete tokens; + tokens = 0; + } + } + + ++iter1; + + } + + // analyze if the plot block is valid + if (!error) { + if (param.fRuns.empty()) { // there was no run tag + error = true; + } else { // everything ok + if ((param.fTmin != -999.0) || (param.fTmax != -999.0)) { // if range is given, check that it is ordered properly + if (param.fTmin > param.fTmax) { + double keep = param.fTmin; + param.fTmin = param.fTmax; + param.fTmax = keep; + } + } + + if ((param.fYmin != -999.0) || (param.fYmax != -999.0)) { // if range is given, check that it is ordered properly + if (param.fYmin > param.fYmax) { + double keep = param.fYmin; + param.fYmin = param.fYmax; + param.fYmax = keep; + } + } + + fPlots.push_back(param); + } + } + + if (error) { // print error message + --iter1; + cout << endl << "ERROR in line " << iter1->fLineNo << ": " << iter1->fLine.Data(); + cout << endl << "A PLOT block needs to have the following structure:"; + cout << endl; + cout << endl << "PLOT "; + cout << endl << "runs "; + cout << endl << "[range tmin tmax [ymin ymax]]"; + cout << endl; + cout << endl << "where is: 0=single histo asym,"; + cout << endl << " 2=forward-backward asym,"; + cout << endl << " 4=RRF asym (not implemented yet),"; + cout << endl << " 8=non muSR."; + cout << endl << " is the list of runs"; + cout << endl << " for 0,2,8 it is a list of run numbers, e.g. runs 1 3"; + cout << endl << " for 4 it is a list of 'complex' numbers, where"; + cout << endl << " the real part is the run number, and the"; + cout << endl << " imaginary one is 1=real part or 2=imag part, e.g."; + cout << endl << " runs 1,1 1,2"; + cout << endl << "range is optional"; + } + + param.fRuns.clear(); + + } + + return !error; +} + +//-------------------------------------------------------------------------- +// HandleStatisticEntry (private) +//-------------------------------------------------------------------------- +/** + *

+ * + * \param lines is a list of lines containing the fitparameter block + */ +bool PMsrHandler::HandleStatisticEntry(PMsrLines &lines) +{ + PMsrLines::iterator iter; + + if (lines.empty()) { + cout << endl << "WARNING: There is no STATISTIC block! Do you really want this?"; + cout << endl; + } + + for (iter = lines.begin(); iter != lines.end(); ++iter) { + if (!iter->fLine.BeginsWith("STATISTIC")) + fStatistic.fStatLines.push_back(*iter); + } + + return true; +} + +// end --------------------------------------------------------------------- diff --git a/src/classes/PRunAsymmetry.cpp b/src/classes/PRunAsymmetry.cpp new file mode 100644 index 00000000..6e9c6302 --- /dev/null +++ b/src/classes/PRunAsymmetry.cpp @@ -0,0 +1,643 @@ +/*************************************************************************** + + PRunAsymmetry.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include + +#include + +#include "PMusr.h" +#include "PRunAsymmetry.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PRunAsymmetry::PRunAsymmetry() : PRunBase() +{ + fFitStartTime = 0.0; + fFitStopTime = 0.0; + fNoOfFitBins = 0; +} + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + * \param msrInfo pointer to the msr info structure + * \param runNo number of the run of the msr-file + */ +PRunAsymmetry::PRunAsymmetry(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo) : PRunBase(msrInfo, rawData, runNo) +{ + // check if alpha and/or beta is fixed -------------------- + + PMsrParamList *param = msrInfo->GetMsrParamList(); + + // check if alpha is given + if (fRunInfo->fAlphaParamNo == -1) { // no alpha given + cout << endl << "PRunAsymmetry::PRunAsymmetry(): no alpha parameter given! This is needed for an asymmetry fit!"; + fValid = false; + return; + } + // check if alpha parameter is within proper bounds + if ((fRunInfo->fAlphaParamNo < 0) || (fRunInfo->fAlphaParamNo > (int)param->size())) { + cout << endl << "PRunAsymmetry::PRunAsymmetry(): alpha parameter no = " << fRunInfo->fAlphaParamNo; + cout << endl << " This is out of bound, since there are only " << param->size() << " parameters."; + fValid = false; + return; + } + // check if alpha is fixed + bool alphaFixedToOne = false; +//cout << endl << ">> alpha = " << (*param)[fRunInfo->fAlphaParamNo-1].fValue << ", " << (*param)[fRunInfo->fAlphaParamNo-1].fStep; + if (((*param)[fRunInfo->fAlphaParamNo-1].fStep == 0.0) && + ((*param)[fRunInfo->fAlphaParamNo-1].fValue == 1.0)) + alphaFixedToOne = true; + + // check if beta is given + bool betaFixedToOne = false; + if (fRunInfo->fBetaParamNo == -1) { // no beta given hence assuming beta == 1 + betaFixedToOne = true; + } else if ((fRunInfo->fBetaParamNo < 0) || (fRunInfo->fBetaParamNo > (int)param->size())) { // check if beta parameter is within proper bounds + cout << endl << "PRunAsymmetry::PRunAsymmetry(): beta parameter no = " << fRunInfo->fBetaParamNo; + cout << endl << " This is out of bound, since there are only " << param->size() << " parameters."; + fValid = false; + return; + } else { // check if beta is fixed + if (((*param)[fRunInfo->fBetaParamNo-1].fStep == 0.0) && + ((*param)[fRunInfo->fBetaParamNo-1].fValue == 1.0)) + betaFixedToOne = true; + } + + // set fAlphaBetaTag + if (alphaFixedToOne && betaFixedToOne) // alpha == 1, beta == 1 + fAlphaBetaTag = 1; + else if (!alphaFixedToOne && betaFixedToOne) // alpha != 1, beta == 1 + fAlphaBetaTag = 2; + else if (alphaFixedToOne && !betaFixedToOne) // alpha == 1, beta != 1 + fAlphaBetaTag = 3; + else + fAlphaBetaTag = 4; + +//cout << endl << ">> PRunAsymmetry::PRunAsymmetry(): fAlphaBetaTag = " << fAlphaBetaTag; + + // calculate fData + if (!PrepareData()) + fValid = false; +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PRunAsymmetry::~PRunAsymmetry() +{ + fForward.clear(); + fForwardErr.clear(); + fBackward.clear(); + fBackwardErr.clear(); +} + +//-------------------------------------------------------------------------- +// CalcChiSquare +//-------------------------------------------------------------------------- +/** + *

+ * + * \param par parameter vector iterated by minuit + */ +double PRunAsymmetry::CalcChiSquare(const std::vector& par) +{ + double chisq = 0.0; + double diff = 0.0; + double asymFcnValue = 0.0; + double a, b, f; + + // calculate functions + for (int i=0; iGetNoOfFuncs(); i++) { + fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), fRunInfo->fMap, par); + } + + // calculate chisq + for (unsigned int i=0; i=fFitStartTime) && (fData.fTime[i]<=fFitStopTime)) { + switch (fAlphaBetaTag) { + case 1: // alpha == 1, beta == 1 + asymFcnValue = fTheory->Func(fData.fTime[i], par, fFuncValues); + break; + case 2: // alpha != 1, beta == 1 + a = par[fRunInfo->fAlphaParamNo-1]; + f = fTheory->Func(fData.fTime[i], par, fFuncValues); + asymFcnValue = (f*(a+1.0)-(a-1.0))/((a+1.0)-f*(a-1.0)); + break; + case 3: // alpha == 1, beta != 1 + b = par[fRunInfo->fBetaParamNo-1]; + f = fTheory->Func(fData.fTime[i], par, fFuncValues); + asymFcnValue = f*(b+1.0)/(2.0-f*(b-1.0)); + break; + case 4: // alpha != 1, beta != 1 + a = par[fRunInfo->fAlphaParamNo-1]; + b = par[fRunInfo->fBetaParamNo-1]; + f = fTheory->Func(fData.fTime[i], par, fFuncValues); + asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0)); + break; + default: + break; + } +//if (i==0) cout << endl << "A(0) = " << asymFcnValue; + diff = fData.fValue[i] - asymFcnValue; + chisq += diff*diff / (fData.fError[i]*fData.fError[i]); + } + } + +//cout << endl << ">> chisq = " << chisq; + + return chisq; +} + +//-------------------------------------------------------------------------- +// CalcMaxLikelihood +//-------------------------------------------------------------------------- +/** + *

+ * + * \param par parameter vector iterated by minuit + */ +double PRunAsymmetry::CalcMaxLikelihood(const std::vector& par) +{ + cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl; + + return 1.0; +} + +//-------------------------------------------------------------------------- +// CalcTheory +//-------------------------------------------------------------------------- +/** + *

+ * + */ +void PRunAsymmetry::CalcTheory() +{ + // feed the parameter vector + std::vector par; + PMsrParamList *paramList = fMsrInfo->GetMsrParamList(); + for (unsigned int i=0; isize(); i++) + par.push_back((*paramList)[i].fValue); + + // calculate functions + for (int i=0; iGetNoOfFuncs(); i++) { + fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), fRunInfo->fMap, par); + } + + // calculate asymmetry + double asymFcnValue = 0.0; + double a, b, f; + for (unsigned int i=0; iFunc(fData.fTime[i], par, fFuncValues); + break; + case 2: // alpha != 1, beta == 1 + a = par[fRunInfo->fAlphaParamNo-1]; + f = fTheory->Func(fData.fTime[i], par, fFuncValues); + asymFcnValue = (f*(a+1.0)-(a-1.0))/((a+1.0)-f*(a-1.0)); + break; + case 3: // alpha == 1, beta != 1 + b = par[fRunInfo->fBetaParamNo-1]; + f = fTheory->Func(fData.fTime[i], par, fFuncValues); + asymFcnValue = f*(b+1.0)/(2.0-f*(b-1.0)); + break; + case 4: // alpha != 1, beta != 1 + a = par[fRunInfo->fAlphaParamNo-1]; + b = par[fRunInfo->fBetaParamNo-1]; + f = fTheory->Func(fData.fTime[i], par, fFuncValues); + asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0)); + break; + default: + asymFcnValue = 0.0; + break; + } + fData.fTheory.push_back(asymFcnValue); + } + + // clean up + par.clear(); +} + +//-------------------------------------------------------------------------- +// PrepareData +//-------------------------------------------------------------------------- +/** + *

+ * + * Error propagation for \f$ A_i = (f_i^{\rm c}-b_i^{\rm c})/(f_i^{\rm c}+b_i^{\rm c})\f$: + * \f[ \Delta A_i = \pm\frac{2}{(f_i^{\rm c}+b_i^{\rm c})^2}\left[ + * (b_i^{\rm c})^2 (\Delta f_i^{\rm c})^2 + + * (\Delta b_i^{\rm c})^2 (f_i^{\rm c})^2\right]^{1/2}\f] + */ +bool PRunAsymmetry::PrepareData() +{ +//cout << endl << "in PRunAsymmetry::PrepareData(): will feed fData"; + + // get forward/backward histo from PRunDataHandler object ------------------------ + // get the correct run + PRawRunData *runData = fRawData->GetRunData(fRunInfo->fRunName); + if (!runData) { // run not found + cout << endl << "PRunAsymmetry::PrepareData(): Couldn't get run " << fRunInfo->fRunName.Data() << "!"; + return false; + } + + // keep the time resolution in (us) + fTimeResolution = runData->fTimeResolution/1.0e3; + + // keep start/stop time for fit + fFitStartTime = fRunInfo->fFitRange[0]; + fFitStopTime = fRunInfo->fFitRange[1]; +//cout << endl << "start/stop (fit): " << fFitStartTime << ", " << fFitStopTime; + + + // check if the t0's are given in the msr-file + if (fRunInfo->fT0[0] == -1) { // t0's are NOT in the msr-file + // check if the t0's are in the data file + if (runData->fT0s.size() != 0) { // t0's in the run data + // keep the proper t0's. For asymmetry runs, forward/backward are holding the histo no + // fForwardHistoNo starts with 1 not with 0 etc. ;-) + fT0s.push_back(runData->fT0s[fRunInfo->fForwardHistoNo-1]); // forward t0 + fT0s.push_back(runData->fT0s[fRunInfo->fBackwardHistoNo-1]); // backward t0 + } else { // t0's are neither in the run data nor in the msr-file -> not acceptable! + cout << endl << "PRunAsymmetry::PrepareData(): NO t0's found, neither in the run data nor in the msr-file!"; + return false; + } + } else { // t0's in the msr-file + // check if t0's are given in the data file + if (runData->fT0s.size() != 0) { + // compare t0's of the msr-file with the one in the data file + if (fabs(fRunInfo->fT0[0]-runData->fT0s[fRunInfo->fForwardHistoNo-1])>5.0) { // given in bins!! + cout << endl << "PRunAsymmetry::PrepareData(): **WARNING**: forward histo"; + cout << endl << " t0 from the msr-file is " << fRunInfo->fT0[0]; + cout << endl << " t0 from the data file is " << runData->fT0s[fRunInfo->fForwardHistoNo-1]; + cout << endl << " This is quite a deviation! Is this done intentionally??"; + cout << endl; + } + if (fabs(fRunInfo->fT0[1]-runData->fT0s[fRunInfo->fBackwardHistoNo-1])>5.0) { // given in bins!! + cout << endl << "PRunAsymmetry::PrepareData(): **WARNING**: backward histo"; + cout << endl << " t0 from the msr-file is " << fRunInfo->fT0[1]; + cout << endl << " t0 from the data file is " << runData->fT0s[fRunInfo->fBackwardHistoNo-1]; + cout << endl << " This is quite a deviation! Is this done intentionally??"; + cout << endl; + } + } + fT0s.push_back(fRunInfo->fT0[0]); // forward t0 + fT0s.push_back(fRunInfo->fT0[1]); // backward t0 + } + + // check if post pile up data shall be used + unsigned int histoNo[2]; // forward/backward + if (fRunInfo->fFileFormat.Contains("ppc")) { + histoNo[0] = runData->fDataBin.size()/2 + fRunInfo->fForwardHistoNo-1; + histoNo[1] = runData->fDataBin.size()/2 + fRunInfo->fBackwardHistoNo-1; + } else { + histoNo[0] = fRunInfo->fForwardHistoNo-1; + histoNo[1] = fRunInfo->fBackwardHistoNo-1; + } + // first check if forward/backward given in the msr-file are valid + if ((runData->fDataBin.size() < histoNo[0]) || (histoNo[0] < 0) || + (runData->fDataBin.size() < histoNo[1]) || (histoNo[1] < 0)) { + cout << endl << "PRunAsymmetry::PrepareData(): PANIC ERROR:"; + cout << endl << " forward/backward histo no found = " << histoNo[0]; + cout << ", " << histoNo[1] << ", but there are only " << runData->fDataBin.size() << " runs!?!?"; + cout << endl << " Will quite :-("; + cout << endl; + return false; + } + // get raw forward/backward histo data + for (unsigned int i=0; ifDataBin[histoNo[0]].size(); i++) { + fForward.push_back(runData->fDataBin[histoNo[0]][i]); + fBackward.push_back(runData->fDataBin[histoNo[1]][i]); + } + + // subtract background from histogramms ------------------------------------------ + if (isnan(fRunInfo->fBkgFix[0])) { // no fixed background given + if (fRunInfo->fBkgRange[0] != 0) { + if (!SubtractEstimatedBkg()) + return false; + } else { // no background given to do the job + cout << endl << "PRunAsymmetry::PrepareData(): Neither fix background nor background bins are given!"; + cout << endl << "One of the two is needed! Will quit ..."; + return false; + } + } else { // fixed background given + if (!SubtractFixBkg()) + return false; + } + + // transform raw histo data. This is done the following way (for details see the manual): + // first rebin the data, than calculate the asymmetry + // first get start data, end data, and t0 + unsigned int start[2] = {fRunInfo->fDataRange[0], fRunInfo->fDataRange[2]}; + unsigned int end[2] = {fRunInfo->fDataRange[1], fRunInfo->fDataRange[3]}; + unsigned int t0[2] = {fT0s[0], fT0s[1]}; + // check if start, end, and t0 make any sense + // 1st check if start and end are in proper order + for (unsigned int i=0; i<2; i++) { + if (end[i] < start[i]) { // need to swap them + int keep = end[i]; + end[i] = start[i]; + start[i] = keep; + } + // 2nd check if start is within proper bounds + if ((start[i] < 0) || (start[i] > runData->fDataBin[histoNo[i]].size())) { + cout << endl << "PRunAsymmetry::PrepareData(): start data bin doesn't make any sense!"; + return false; + } + // 3rd check if end is within proper bounds + if ((end[i] < 0) || (end[i] > runData->fDataBin[histoNo[i]].size())) { + cout << endl << "PRunAsymmetry::PrepareData(): end data bin doesn't make any sense!"; + return false; + } + // 4th check if t0 is within proper bounds + if ((t0[i] < 0) || (t0[i] > runData->fDataBin[histoNo[i]].size())) { + cout << endl << "PRunAsymmetry::PrepareData(): t0 data bin doesn't make any sense!"; + return false; + } + } + + // everything looks fine, hence fill packed forward and backward histo + PRunData forwardPacked; + PRunData backwardPacked; + double value = 0.0; + double error = 0.0; + // forward + for (unsigned i=start[0]; ifPacking == 0) && (i != start[0])) { // fill data + // in order that after rebinning the fit does not need to be redone (important for plots) + // the value is normalize to per bin + value /= fRunInfo->fPacking; + // time shifted so that packing is included correctly, i.e. t0 == t0 after packing + forwardPacked.fTime.push_back(fTimeResolution*((double)i-(double)t0[0]-(double)fRunInfo->fPacking)); + forwardPacked.fValue.push_back(value); + if (value == 0.0) + forwardPacked.fError.push_back(1.0); + else + forwardPacked.fError.push_back(TMath::Sqrt(error)/fRunInfo->fPacking); + value = 0.0; + error = 0.0; + } + value += fForward[i]; + error += fForwardErr[i]*fForwardErr[i]; + } + // backward + for (unsigned i=start[1]; ifPacking == 0) && (i != start[1])) { // fill data + // in order that after rebinning the fit does not need to be redone (important for plots) + // the value is normalize to per bin + value /= fRunInfo->fPacking; + // time shifted so that packing is included correctly, i.e. t0 == t0 after packing + backwardPacked.fTime.push_back(fTimeResolution*((double)i-(double)t0[1]-(double)fRunInfo->fPacking)); + backwardPacked.fValue.push_back(value); + if (value == 0.0) + backwardPacked.fError.push_back(1.0); + else + backwardPacked.fError.push_back(TMath::Sqrt(error)/fRunInfo->fPacking); + value = 0.0; + error = 0.0; + } + value += fBackward[i]; + error += fBackwardErr[i]*fBackwardErr[i]; + } + + // check if packed forward and backward hist have the same size, otherwise something is wrong + if (forwardPacked.fTime.size() != backwardPacked.fTime.size()) { + cout << endl << "PRunAsymmetry::PrepareData(): **PANIC ERROR**:"; + cout << endl << " packed forward and backward histo should have the same number of bins!"; + cout << endl << " however found (f/b) : " << forwardPacked.fTime.size() << "/" << backwardPacked.fTime.size(); + return false; + } + + // form asymmetry including error propagation + double asym; + double f, b, ef, eb; + for (unsigned int i=0; i= fFitStartTime) && (fData.fTime[i] <= fFitStopTime)) + fNoOfFitBins++; + } + + // clean up + forwardPacked.fTime.clear(); + forwardPacked.fValue.clear(); + forwardPacked.fError.clear(); + backwardPacked.fTime.clear(); + backwardPacked.fValue.clear(); + backwardPacked.fError.clear(); + fForward.clear(); + fForwardErr.clear(); + fBackward.clear(); + fBackwardErr.clear(); + + return true; +} + +//-------------------------------------------------------------------------- +// SubtractFixBkg +//-------------------------------------------------------------------------- +/** + *

Subtracts a fixed background from the raw data. The error propagation + * is done the following way: it is assumed that the error of the background + * is Poisson like, i.e. \f$\Delta\mathrm{bkg} = \sqrt{\mathrm{bkg}}\f$. + * + * Error propagation: + * \f[ \Delta f_i^{\rm c} = \pm\left[ (\Delta f_i)^2 + (\Delta \mathrm{bkg})^2 \right]^{1/2} = + * \pm\left[ f_i + \mathrm{bkg} \right]^{1/2}, \f] + * where \f$ f_i^{\rm c} \f$ is the background corrected histogram, \f$ f_i \f$ the raw histogram + * and \f$ \mathrm{bkg} \f$ the fix given background. + */ +bool PRunAsymmetry::SubtractFixBkg() +{ + for (unsigned int i=0; ifBkgFix[0])); + fForward[i] -= fRunInfo->fBkgFix[0]; + fBackwardErr.push_back(TMath::Sqrt(fBackward[i]+fRunInfo->fBkgFix[1])); + fBackward[i] -= fRunInfo->fBkgFix[1]; + } + + return true; +} + +//-------------------------------------------------------------------------- +// SubtractEstimatedBkg +//-------------------------------------------------------------------------- +/** + *

Subtracts the background given ... + * + * The background corrected histogramms are: + * \f$ f_i^{\rm c} = f_i - \mathrm{bkg} \f$, where \f$ f_i \f$ is the raw data histogram, + * \f$ \mathrm{bkg} \f$ the background estimate, and \f$ f_i^{\rm c} \f$ background corrected + * histogram. The error on \f$ f_i^{\rm c} \f$ is + * \f[ \Delta f_i^{\rm c} = \pm \sqrt{ (\Delta f_i)^2 + (\Delta \mathrm{bkg})^2 } = + * \pm \sqrt{f_i + (\Delta \mathrm{bkg})^2} \f] + * The background error \f$ \Delta \mathrm{bkg} \f$ is + * \f[ \Delta \mathrm{bkg} = \pm\frac{1}{N}\left[\sum_{i=0}^N (\Delta f_i)^2\right]^{1/2} = + * \pm\frac{1}{N}\left[\sum_{i=0}^N f_i \right]^{1/2},\f] + * where \f$N\f$ is the number of bins over which the background is formed. + */ +bool PRunAsymmetry::SubtractEstimatedBkg() +{ + double beamPeriod = 0.0; + + // check if data are from PSI, RAL, or TRIUMF + if (fRunInfo->fInstitute.Contains("psi")) + beamPeriod = ACCEL_PERIOD_PSI; + else if (fRunInfo->fInstitute.Contains("ral")) + beamPeriod = ACCEL_PERIOD_RAL; + else if (fRunInfo->fInstitute.Contains("triumf")) + beamPeriod = ACCEL_PERIOD_TRIUMF; + else + beamPeriod = 0.0; + + // check if start and end are in proper order + unsigned int start[2] = {fRunInfo->fBkgRange[0], fRunInfo->fBkgRange[2]}; + unsigned int end[2] = {fRunInfo->fBkgRange[1], fRunInfo->fBkgRange[3]}; + for (unsigned int i=0; i<2; i++) { + if (end[i] < start[i]) { + cout << endl << "PRunAsymmetry::SubtractEstimatedBkg(): end = " << end[i] << " > start = " << start[i] << "! Will swap them!"; + unsigned int keep = end[i]; + end[i] = start[i]; + start[i] = keep; + } + } + + // calculate proper background range + for (unsigned int i=0; i<2; i++) { + if (beamPeriod != 0.0) { + double beamPeriodBins = beamPeriod/fRunInfo->fPacking; + unsigned int periods = (unsigned int)((double)(end[i] - start[i] + 1) / beamPeriodBins); + end[i] = start[i] + (unsigned int)round((double)periods*beamPeriodBins); + cout << endl << "PRunAsymmetry::SubtractEstimatedBkg(): Background " << start[i] << ", " << end[i]; + if (end[i] == start[i]) + end[i] = fRunInfo->fBkgRange[2*i+1]; + } + } + + // check if start is within histogram bounds + if ((start[0] < 0) || (start[0] >= fForward.size()) || + (start[1] < 0) || (start[1] >= fBackward.size())) { + cout << endl << "PRunAsymmetry::SubtractEstimatedBkg(): background bin values out of bound!"; + cout << endl << " histo lengths (f/b) = (" << fForward.size() << "/" << fBackward.size() << ")."; + cout << endl << " background start (f/b) = (" << start[0] << "/" << start[1] << ")."; + return false; + } + + // check if end is within histogram bounds + if ((end[0] < 0) || (end[0] >= fForward.size()) || + (end[1] < 0) || (end[1] >= fBackward.size())) { + cout << endl << "PRunAsymmetry::SubtractEstimatedBkg(): background bin values out of bound!"; + cout << endl << " histo lengths (f/b) = (" << fForward.size() << "/" << fBackward.size() << ")."; + cout << endl << " background end (f/b) = (" << end[0] << "/" << end[1] << ")."; + return false; + } + + // calculate background + double bkg[2] = {0.0, 0.0}; + double errBkg[2] = {0.0, 0.0}; + + // forward + for (unsigned int i=start[0]; i(end[0] - start[0] + 1); + + // backward + for (unsigned int i=start[1]; i(end[1] - start[1] + 1); + + // correct error for forward, backward + for (unsigned int i=0; i + +#include +#include +#include +#include +#include +#include +#include + +#include "TLemRunHeader.h" + +#include "PRunBase.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

needed otherwise vector's cannot be generated ;-) + * + */ +PRunBase::PRunBase() +{ + fRunNo = -1; + fRunInfo = 0; + fRawData = 0; + fTimeResolution = -1.0; + + fValid = true; +} + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + * \param msrInfo pointer to the msr info structure + * \param runNo number of the run of the msr-file + */ +PRunBase::PRunBase(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo) +{ + fValid = true; + + fRunNo = runNo; + if ((runNo < 0) || (runNo > msrInfo->GetMsrRunList()->size())) { + fRunInfo = 0; + return; + } + + // keep pointer to the msr-file handler + fMsrInfo = msrInfo; + + // keep the run header info for this run + fRunInfo = &(*msrInfo->GetMsrRunList())[runNo]; + + // check the parameter and map range of the functions + if (!fMsrInfo->CheckMapAndParamRange(fRunInfo->fMap.size(), fMsrInfo->GetNoOfParams())) { + cout << endl << "**SEVERE ERROR** PRunBase::PRunBase: map and/or parameter out of range in FUNCTIONS." << endl; + exit(0); + } + + // keep the raw data of the runs + fRawData = rawData; + + // init private variables + fTimeResolution = -1.0; + for (int i=0; iGetNoOfFuncs(); i++) + fFuncValues.push_back(0.0); + + // generate theory + fTheory = new PTheory(msrInfo, runNo); + if (fTheory == 0) { + cout << endl << "**SEVERE ERROR** PRunBase::PRunBase: Couldn't create an instance of PTheory :-(, will quit" << endl; + exit(0); + } + if (!fTheory->IsValid()) { + cout << endl << "**SEVERE ERROR** PRunBase::PRunBase: Theory is not valid :-(, will quit" << endl; + exit(0); + } +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PRunBase::~PRunBase() +{ + fParamNo.clear(); + + fData.fTime.clear(); + fData.fValue.clear(); + fData.fError.clear(); + fData.fTheory.clear(); + + fT0s.clear(); + + fFuncValues.clear(); +} + +//-------------------------------------------------------------------------- +// CleanUp +//-------------------------------------------------------------------------- +/** + *

Clean up all localy allocate memory + * + */ +void PRunBase::CleanUp() +{ +//cout << endl << "PRunBase::CleanUp() ..." << endl; + if (fTheory) { + delete fTheory; + fTheory = 0; + } +} diff --git a/src/classes/PRunDataHandler.cpp b/src/classes/PRunDataHandler.cpp new file mode 100644 index 00000000..54a0a4b2 --- /dev/null +++ b/src/classes/PRunDataHandler.cpp @@ -0,0 +1,811 @@ +/*************************************************************************** + + PRunDataHandler.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +using namespace std; + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "TLemRunHeader.h" +#include "PRunDataHandler.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PRunDataHandler::PRunDataHandler(PMsrHandler *msrInfo) +{ +// cout << endl << "in PRunDataHandler::PRunDataHandler()"; + + fMsrInfo = msrInfo; + + // read files + if (!ReadFile()) // couldn't read file + fAllDataAvailable = false; + else + fAllDataAvailable = true; +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PRunDataHandler::~PRunDataHandler() +{ + for (unsigned int i=0; i + * + * \param runName + */ +PRawRunData* PRunDataHandler::GetRunData(TString runName) +{ + unsigned int i; + + for (i=0; i + * + */ +bool PRunDataHandler::ReadFile() +{ + bool success = true; + + // loop over the full RUN list to see what needs to be read + PMsrRunList *runList = 0; + runList = fMsrInfo->GetMsrRunList(); + if (runList == 0) { + cout << endl << "PRunDataHandler::ReadFile(): Couldn't obtain run list from PMsrHandler: something VERY fishy"; + return false; + } + + PMsrRunList::iterator run_it; + for (run_it = runList->begin(); run_it != runList->end(); ++run_it) { +//cout << endl << "run : " << run_it->fRunName.Data(); + fRunName = run_it->fRunName; + // check is file is already read + if (FileAlreadyRead(*run_it)) + continue; + // check if file actually exists + if (!FileExistsCheck(*run_it)) + return false; + // everything looks fine, hence try to read the data file + if (!run_it->fFileFormat.CompareTo("root-npp")) // not post pile up corrected histos + success = ReadRootFile(); + else if (!run_it->fFileFormat.CompareTo("root-ppc")) // post pile up corrected histos + success = ReadRootFile(); + else if (!run_it->fFileFormat.CompareTo("nexus")) + success = ReadNexusFile(); + else if (!run_it->fFileFormat.CompareTo("psi-bin")) + success = ReadPsiBinFile(); + else if (!run_it->fFileFormat.CompareTo("mud")) + success = ReadMudFile(); + else if (!run_it->fFileFormat.CompareTo("nemu")) + success = ReadNemuFile(); + else if (!run_it->fFileFormat.CompareTo("ascii")) + success = ReadAsciiFile(); + else + success = false; + } + + return success; +} + +//-------------------------------------------------------------------------- +// FileAlreadyRead +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PRunDataHandler::FileAlreadyRead(PMsrRunStructure &runInfo) +{ + for (unsigned int i=0; i + * + */ +bool PRunDataHandler::FileExistsCheck(PMsrRunStructure &runInfo) +{ + bool success = true; + + // local init + TROOT root("PRunBase", "PRunBase", 0); + TString pathName = "???"; + TString str; + TString ext; + + runInfo.fRunName.ToLower(); + runInfo.fBeamline.ToLower(); + runInfo.fInstitute.ToLower(); + runInfo.fFileFormat.ToLower(); + + // file extensions for the various formats + if (!runInfo.fFileFormat.CompareTo("root-npp")) // not post pile up corrected histos + ext = TString("root"); + else if (!runInfo.fFileFormat.CompareTo("root-ppc")) // post pile up corrected histos + ext = TString("root"); + else if (!runInfo.fFileFormat.CompareTo("nexus")) + ext = TString("nexus"); + else if (!runInfo.fFileFormat.CompareTo("psi-bin")) + ext = TString("bin"); + else if (!runInfo.fFileFormat.CompareTo("mud")) + ext = TString("mud"); + else if (!runInfo.fFileFormat.CompareTo("nemu")) + ext = TString("nemu"); + else if (!runInfo.fFileFormat.CompareTo("ascii")) + ext = TString("dat"); + else + success = false; + + // unkown file format found + if (!success) { + str = runInfo.fFileFormat; + str.ToUpper(); + cout << endl << "File Format '" << str.Data() << "' unsupported."; + cout << endl << " support file formats are:"; + cout << endl << " ROOT-NPP -> root not post pileup corrected for lem"; + cout << endl << " ROOT-PPC -> root post pileup corrected for lem"; + cout << endl << " NEXUS -> nexus file format"; + cout << endl << " PSI-BIN -> psi bin file format"; + cout << endl << " MUD -> triumf mud file format"; + cout << endl << " NEMU -> lem ascii file format"; + cout << endl << " ASCII -> column like file format"; + cout << endl; + return success; + } + + // check if the file is in the local directory + str = runInfo.fRunName + TString(".") + ext; + if (gSystem->AccessPathName(str.Data())!=true) { // found in the local dir + pathName = str; + } + + // check if the file is found in the directory given in the startup file + // ** STILL MISSING ** + + // check if the file is found in the directories given by WKMFULLDATAPATH + const char *wkmpath = gSystem->Getenv("WKMFULLDATAPATH"); + if (pathName.CompareTo("???") == 0) { // not found in local directory search + str = TString(wkmpath); + // WKMFULLDATAPATH has the structure: path_1:path_2:...:path_n + TObjArray *tokens = str.Tokenize(":"); + TObjString *ostr; + for (int i=0; iGetEntries(); i++) { + ostr = dynamic_cast(tokens->At(i)); + str = ostr->GetString() + "/" + runInfo.fRunName + TString(".") + ext; + if (gSystem->AccessPathName(str.Data())!=true) { // found + pathName = str; + break; + } + } + } + + // check if the file is found in the WKM generated default path + if (pathName.CompareTo("???") == 0) { // not found in WKMFULLDATAPATH search + str = TString(wkmpath); + // WKMFULLDATAPATH has the structure: path_1:path_2:...:path_n + TObjArray *tokens = str.Tokenize(":"); + TObjString *ostr; + for (int i=0; iGetEntries(); i++) { + ostr = dynamic_cast(tokens->At(i)); + str = ostr->GetString() + TString("/data/") + + runInfo.fInstitute + TString("/") + + runInfo.fBeamline + TString("/") + + runInfo.fRunName + TString(".") + ext; + if (gSystem->AccessPathName(str.Data())!=true) { // found + pathName = str; + break; + } + } + } + + // no proper path name found + if (pathName.CompareTo("???") == 0) { + cout << endl << "ERROR: Couldn't find '" << runInfo.fRunName << "' in any standard path."; + cout << endl << " standard search pathes are:"; + cout << endl << " 1. the local directory"; + cout << endl << " 2. the data directory given in the startup XML file"; + cout << endl << " 3. the directories listed in WKMFULLDATAPATH"; + cout << endl << " 4. default path construct which is described in the manual"; + return false; + } + + fRunPathName = pathName; + + return true; +} + +//-------------------------------------------------------------------------- +// ReadRootFile +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PRunDataHandler::ReadRootFile() +{ + PDoubleVector histoData; + PRawRunData runData; + + TFile f(fRunPathName.Data()); + if (f.IsZombie()) { + return false; + } + + TFolder *folder; + f.GetObject("RunInfo", folder); + if (!folder) { + cout << endl << "Couldn't obtain RunInfo from " << fRunPathName.Data() << endl; + f.Close(); + return false; + } + + // read header and check if some missing run info need to be fed + TLemRunHeader *runHeader = dynamic_cast(folder->FindObjectAny("TLemRunHeader")); + + // check if run header is valid + if (!runHeader) { + cout << endl << "Couldn't obtain run header info from ROOT file " << fRunPathName.Data() << endl; + f.Close(); + return false; + } + + // get time resolution + runData.fTimeResolution = runHeader->GetTimeResolution(); + + // get number of histogramms + int noOfHistos = runHeader->GetNHist(); + + // get t0's + Int_t *t0 = runHeader->GetTimeZero(); + // check if t0's are there + if (t0[0] != -1) { // ugly, but at the moment there is no other way + // copy t0's so they are not lost + for (int i=0; i(folder->FindObjectAny(histoName)); + if (!histo) { + cout << endl << "PRunDataHandler::ReadRootFile: Couldn't get histo " << histoName; + return false; + } + // fill data + for (int j=1; jGetNbinsX(); j++) + histoData.push_back(histo->GetBinContent(j)); + // store them in runData vector + runData.fDataBin.push_back(histoData); + // clear histoData for the next histo + histoData.clear(); + } + // now read the data which ARE post pileup corrected + for (int i=0; i(folder->FindObjectAny(histoName)); + if (!histo) { + cout << endl << "PRunDataHandler::ReadRootFile: Couldn't get histo " << histoName; + return false; + } + // fill data + for (int j=1; jGetNbinsX(); j++) + histoData.push_back(histo->GetBinContent(j)); + // store them in runData vector + runData.fDataBin.push_back(histoData); + // clear histoData for the next histo + histoData.clear(); + } + + f.Close(); + + // keep run name + runData.fRunName = fRunName; + + // add run to the run list + fData.push_back(runData); + + return true; +} + +//-------------------------------------------------------------------------- +// ReadNexusFile +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PRunDataHandler::ReadNexusFile() +{ + cout << endl << "PRunDataHandler::ReadNexusFile(): Sorry, not yet implemented ..."; + return false; +} + +//-------------------------------------------------------------------------- +// ReadNemuFile +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PRunDataHandler::ReadNemuFile() +{ +// cout << endl << "PRunDataHandler::ReadNemuFile(): Sorry, not yet implemented ..."; + + PDoubleVector histoData; + PRawRunData runData; + + // init runData header info + runData.fRunName = TString(""); + runData.fRunTitle = TString(""); + runData.fSetup = TString(""); + runData.fField = nan("NAN"); + runData.fTemp = nan("NAN"); + runData.fTimeResolution = nan("NAN"); + + // open file + ifstream f; + + // open dump-file + f.open(fRunPathName.Data(), ifstream::in); + if (!f.is_open()) { + cout << endl << "Couldn't open run data (" << fRunPathName.Data() << ") file for reading, sorry ..."; + cout << endl; + return false; + } + + // read header + bool headerInfo = true; + char instr[128]; + TString line; + double dval; + int ival; + bool ok; + int groups = 0, channels = 0; + + Ssiz_t idx; + do { + f.getline(instr, sizeof(instr)); + line = TString(instr); + if (line.IsWhitespace()) { // end of header reached + headerInfo = false; + } else { // real stuff, hence filter data + if (line.Contains("Title")) { + idx = line.Index(":"); + line.Replace(0, idx+1, 0, 0); // remove 'Title:' + StripWhitespace(line); + runData.fRunTitle = line; + } else if (line.Contains("Field")) { + idx = line.Index(":"); + line.Replace(0, idx+1, 0, 0); // remove 'Field:' + StripWhitespace(line); + dval = ToDouble(line, ok); + if (ok) + runData.fField = dval; + } else if (line.Contains("Setup")) { + idx = line.Index(":"); + line.Replace(0, idx+1, 0, 0); // remove 'Setup:' + StripWhitespace(line); + runData.fSetup = line; + } else if (line.Contains("Temp")) { + idx = line.Index(":"); + line.Replace(0, idx+1, 0, 0); // remove 'Temp:' + StripWhitespace(line); + dval = ToDouble(line, ok); + if (ok) + runData.fTemp = dval; + } else if (line.Contains("Groups")) { + idx = line.Index(":"); + line.Replace(0, idx+1, 0, 0); // remove 'Groups:' + StripWhitespace(line); + ival = ToInt(line, ok); + if (ok) + groups = ival; + } else if (line.Contains("Channels")) { + idx = line.Index(":"); + line.Replace(0, idx+1, 0, 0); // remove 'Channels:' + StripWhitespace(line); + ival = ToInt(line, ok); + if (ok) + channels = ival; + } else if (line.Contains("Resolution")) { + idx = line.Index(":"); + line.Replace(0, idx+1, 0, 0); // remove 'Resolution:' + StripWhitespace(line); + dval = ToDouble(line, ok); + if (ok) + runData.fTimeResolution = dval * 1000.0; + } + } + } while (headerInfo); + + if ((groups == 0) || (channels == 0) || isnan(runData.fTimeResolution)) { + cout << endl << "PRunDataHandler::ReadNemuFile(): essential header informations are missing!"; + f.close(); + return false; + } +/* +cout << endl << ">> run title: '" << runData.fRunTitle.Data() << "'"; +cout << endl << ">> setup : '" << runData.fSetup.Data() << "'"; +cout << endl << ">> field : " << runData.fField; +cout << endl << ">> temp : " << runData.fTemp; +cout << endl << ">> groups : " << groups; +cout << endl << ">> channels : " << channels; +cout << endl << ">> time resolution : " << runData.fTimeResolution; +*/ + + // read data --------------------------------------------------------- + int status; + unsigned int group_counter = 0; + int val[10]; + while (!f.eof()) { + f.getline(instr, sizeof(instr)); + // check if empty line, i.e. new group + if (IsWhitespace(instr)) { + runData.fDataBin.push_back(histoData); + histoData.clear(); + group_counter++; + } + // extract values + status = sscanf(instr, "%d %d %d %d %d %d %d %d %d %d", + &val[0], &val[1], &val[2], &val[3], &val[4], + &val[5], &val[6], &val[7], &val[8], &val[9]); + // no values found: error + if (status == 0) { + cout << endl << "PRunDataHandler::ReadNemuFile(): **ERROR** while reading data ..."; + // clean up + for (unsigned int i=0; i + * + */ +bool PRunDataHandler::ReadPsiBinFile() +{ + cout << endl << "PRunDataHandler::ReadPsiBinFile(): Sorry, not yet implemented ..."; + return false; +} + +//-------------------------------------------------------------------------- +// ReadMudFile +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PRunDataHandler::ReadMudFile() +{ + cout << endl << "PRunDataHandler::ReadMudFile(): Sorry, not yet implemented ..."; + return false; +} + +//-------------------------------------------------------------------------- +// ReadAsciiFile +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PRunDataHandler::ReadAsciiFile() +{ + cout << endl << "PRunDataHandler::ReadAsciiFile(): Sorry, not yet implemented ..."; + return false; +} + +//-------------------------------------------------------------------------- +// StripWhitespace +//-------------------------------------------------------------------------- +/** + *

+ * + * \param str + */ +bool PRunDataHandler::StripWhitespace(TString &str) +{ + char *s = 0; + char *subs = 0; + int i; + int start; + int end; + int size; + + size = (int)str.Length(); + s = new char[size+1]; + + if (!s) + return false; + + for (int i=0; i + * + * \param str + */ +bool PRunDataHandler::IsWhitespace(const char *str) +{ + unsigned int i=0; + + while (isblank(str[i]) || (iscntrl(str[i])) && str[i] != 0) + i++; + + if (i == strlen(str)) + return true; + else + return false; +} + +//-------------------------------------------------------------------------- +// ToDouble +//-------------------------------------------------------------------------- +/** + *

+ * + * \param str + * \param ok + */ +double PRunDataHandler::ToDouble(TString &str, bool &ok) +{ + char *s; + double value; + int size, status; + + ok = true; + + size = (int)str.Length(); + s = new char[size+1]; + + if (!s) { + ok = false; + return 0.0; + } + + // copy string; stupid way but it works + for (int i=0; i + * + * \param str + * \param ok + */ +int PRunDataHandler::ToInt(TString &str, bool &ok) +{ + char *s; + int value; + int size, status; + + ok = true; + + size = (int)str.Length(); + s = new char[size+1]; + + if (!s) { + ok = false; + return 0; + } + + // copy string; stupid way but it works + for (int i=0; i + +#include "PRunListCollection.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + * \param msrInfo pointer to the msr info structure + * \param runNo number of the run of the msr-file + */ +PRunListCollection::PRunListCollection(PMsrHandler *msrInfo, PRunDataHandler *data) +{ + fMsrInfo = msrInfo; + fData = data; +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PRunListCollection::~PRunListCollection() +{ +//cout << endl << "in ~PRunListCollection() ..." << endl; +//cout << endl << ">> fRunSingleHistoList.size() = " << fRunSingleHistoList.size(); + for (unsigned int i=0; iCleanUp(); + fRunSingleHistoList.clear(); + +//cout << endl << ">> fRunAsymmetryList.size() = " << fRunAsymmetryList.size(); + for (unsigned int i=0; iCleanUp(); + fRunAsymmetryList.clear(); + +//cout << endl << ">> fRunRRFList.size() = " << fRunRRFList.size(); + for (unsigned int i=0; iCleanUp(); + fRunRRFList.clear(); + +//cout << endl << ">> fRunNonMusrList.size() = " << fRunNonMusrList.size(); + for (unsigned int i=0; iCleanUp(); + fRunNonMusrList.clear(); +} + +//-------------------------------------------------------------------------- +// Add +//-------------------------------------------------------------------------- +/** + *

+ * + * \param runNo + */ +bool PRunListCollection::Add(int runNo) +{ + bool success = true; + + PMsrRunStructure *runList = &(*fMsrInfo->GetMsrRunList())[runNo]; + + cout << endl << "PRunListCollection::Add(): will add run no " << runNo; + cout << ", name = " << runList->fRunName.Data(); + cout << ", type = " << runList->fFitType; + + int fitType = (*fMsrInfo->GetMsrRunList())[runNo].fFitType; + +PRunAsymmetry* asym; +bool status; + + switch (fitType) { + case PRUN_SINGLE_HISTO: + fRunSingleHistoList.push_back(new PRunSingleHisto(fMsrInfo, fData, runNo)); + if (!fRunSingleHistoList[fRunSingleHistoList.size()-1]->IsValid()) + success = false; + break; + case PRUN_ASYMMETRY: + fRunAsymmetryList.push_back(new PRunAsymmetry(fMsrInfo, fData, runNo)); + asym = fRunAsymmetryList[fRunAsymmetryList.size()-1]; + status = asym->IsValid(); + if (!fRunAsymmetryList[fRunAsymmetryList.size()-1]->IsValid()) + success = false; + break; + case PRUN_RRF: + fRunRRFList.push_back(new PRunRRF(fMsrInfo, fData, runNo)); + if (!fRunRRFList[fRunRRFList.size()-1]->IsValid()) + success = false; + break; + case PRUN_NON_MUSR: + fRunNonMusrList.push_back(new PRunNonMusr(fMsrInfo, fData, runNo)); + if (!fRunNonMusrList[fRunNonMusrList.size()-1]->IsValid()) + success = false; + break; + default: + success = false; + break; + } + + return success; +} + +//-------------------------------------------------------------------------- +// GetSingleHistoChisq +//-------------------------------------------------------------------------- +/** + *

+ */ +double PRunListCollection::GetSingleHistoChisq(const std::vector& par) +{ + double chisq = 0.0; + + for (unsigned int i=0; iCalcChiSquare(par); + + return chisq; +} + +//-------------------------------------------------------------------------- +// GetAsymmetryChisq +//-------------------------------------------------------------------------- +/** + *

+ */ +double PRunListCollection::GetAsymmetryChisq(const std::vector& par) +{ + double chisq = 0.0; + + for (unsigned int i=0; iCalcChiSquare(par); + + return chisq; +} + +//-------------------------------------------------------------------------- +// GetRRFChisq +//-------------------------------------------------------------------------- +/** + *

+ */ +double PRunListCollection::GetRRFChisq(const std::vector& par) +{ + double chisq = 0.0; + + for (unsigned int i=0; iCalcChiSquare(par); + + return chisq; +} + +//-------------------------------------------------------------------------- +// GetNonMusrChisq +//-------------------------------------------------------------------------- +/** + *

+ */ +double PRunListCollection::GetNonMusrChisq(const std::vector& par) +{ + double chisq = 0.0; + + for (unsigned int i=0; iCalcChiSquare(par); + + return chisq; +} + +//-------------------------------------------------------------------------- +// GetSingleHistoMaximumLikelihood +//-------------------------------------------------------------------------- +/** + *

+ */ +double PRunListCollection::GetSingleHistoMaximumLikelihood(const std::vector& par) +{ + double mlh = 0.0; + + for (unsigned int i=0; iCalcMaxLikelihood(par); + + return mlh; +} + +//-------------------------------------------------------------------------- +// GetAsymmetryMaximumLikelihood +//-------------------------------------------------------------------------- +/** + *

+ */ +double PRunListCollection::GetAsymmetryMaximumLikelihood(const std::vector& par) +{ + double mlh = 0.0; + + for (unsigned int i=0; iCalcMaxLikelihood(par); + + return mlh; +} + +//-------------------------------------------------------------------------- +// GetRRFMaximumLikelihood +//-------------------------------------------------------------------------- +/** + *

+ */ +double PRunListCollection::GetRRFMaximumLikelihood(const std::vector& par) +{ + double mlh = 0.0; + + for (unsigned int i=0; iCalcMaxLikelihood(par); + + return mlh; +} + +//-------------------------------------------------------------------------- +// GetNonMusrMaximumLikelihood +//-------------------------------------------------------------------------- +/** + *

+ */ +double PRunListCollection::GetNonMusrMaximumLikelihood(const std::vector& par) +{ + double mlh = 0.0; + + for (unsigned int i=0; iCalcMaxLikelihood(par); + + return mlh; +} + +//-------------------------------------------------------------------------- +// GetTotalNoOfBinsFitted +//-------------------------------------------------------------------------- +/** + *

+ */ +unsigned int PRunListCollection::GetTotalNoOfBinsFitted() +{ + unsigned int counts = 0; + + for (unsigned int i=0; iGetNoOfFitBins(); + + for (unsigned int i=0; iGetNoOfFitBins(); + + for (unsigned int i=0; iGetNoOfFitBins(); + + for (unsigned int i=0; iGetNoOfFitBins(); + +// cout << endl << "Total No of Bins Fitted = " << counts; + return counts; +} + +//-------------------------------------------------------------------------- +// GetSingleHisto +//-------------------------------------------------------------------------- +/** + *

+ * + * \param index + */ +PRunData* PRunListCollection::GetSingleHisto(unsigned int index) +{ + if ((index < 0) || (index > fRunSingleHistoList.size())) { + cout << endl << "PRunListCollection::GetSingleHisto: index = " << index << " out of bounds"; + return 0; + } + + fRunSingleHistoList[index]->CalcTheory(); + PRunData *data = fRunSingleHistoList[index]->GetData(); + + return data; +} + +//-------------------------------------------------------------------------- +// GetAsymmetry +//-------------------------------------------------------------------------- +/** + *

+ * + * \param index + */ +PRunData* PRunListCollection::GetAsymmetry(unsigned int index) +{ + if ((index < 0) || (index > fRunAsymmetryList.size())) { + cout << endl << "PRunListCollection::GetAsymmetry: index = " << index << " out of bounds"; + return 0; + } + + fRunAsymmetryList[index]->CalcTheory(); + PRunData *data = fRunAsymmetryList[index]->GetData(); + + return data; +} + +//-------------------------------------------------------------------------- +// GetRRF +//-------------------------------------------------------------------------- +/** + *

+ * + * \param index + */ +PRunData* PRunListCollection::GetRRF(unsigned int index) +{ + if ((index < 0) || (index > fRunRRFList.size())) { + cout << endl << "PRunListCollection::GetRRF: index = " << index << " out of bounds"; + return 0; + } + + return 0; +} + +//-------------------------------------------------------------------------- +// GetNonMusr +//-------------------------------------------------------------------------- +/** + *

+ * + * \param index + */ +PRunData* PRunListCollection::GetNonMusr(unsigned int index) +{ + if ((index < 0) || (index > fRunNonMusrList.size())) { + cout << endl << "PRunListCollection::GetNonMusr: index = " << index << " out of bounds"; + return 0; + } + + return 0; +} diff --git a/src/classes/PRunNonMusr.cpp b/src/classes/PRunNonMusr.cpp new file mode 100644 index 00000000..b360d2b0 --- /dev/null +++ b/src/classes/PRunNonMusr.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + + PRunNonMusr.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include + +#include "PRunNonMusr.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PRunNonMusr::PRunNonMusr() : PRunBase() +{ + fFitStartTime = 0.0; + fFitStopTime = 0.0; + fNoOfFitBins = 0; +} + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + * \param msrInfo pointer to the msr info structure + * \param runNo number of the run of the msr-file + */ +PRunNonMusr::PRunNonMusr(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo) : PRunBase(msrInfo, rawData, runNo) +{ + bool success; + + // calculate fData + if (success) { + success = PrepareData(); + } +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PRunNonMusr::~PRunNonMusr() +{ +} + +//-------------------------------------------------------------------------- +// CalcChiSquare +//-------------------------------------------------------------------------- +/** + *

+ * + * \param par parameter vector iterated by minuit + */ +double PRunNonMusr::CalcChiSquare(const std::vector& par) +{ + double chisq = 0.0; + double diff = 0.0; + + return chisq; +} + +//-------------------------------------------------------------------------- +// CalcMaxLikelihood +//-------------------------------------------------------------------------- +/** + *

+ * + * \param par parameter vector iterated by minuit + */ +double PRunNonMusr::CalcMaxLikelihood(const std::vector& par) +{ + cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl; + + return 1.0; +} + +//-------------------------------------------------------------------------- +// CalcTheory +//-------------------------------------------------------------------------- +/** + *

+ * + */ +void PRunNonMusr::CalcTheory() +{ +} + +//-------------------------------------------------------------------------- +// PrepareData +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PRunNonMusr::PrepareData() +{ + bool success = true; + + cout << endl << "in PRunNonMusr::PrepareData(): will feed fData"; + + // count the number of bins to be fitted + fNoOfFitBins=0; + for (unsigned int i=0; i= fFitStartTime) && (fData.fTime[i] <= fFitStopTime)) + fNoOfFitBins++; + } + + return success; +} + diff --git a/src/classes/PRunRRF.cpp b/src/classes/PRunRRF.cpp new file mode 100644 index 00000000..6b79bc94 --- /dev/null +++ b/src/classes/PRunRRF.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + + PRunRRF.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include + +#include "PRunRRF.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PRunRRF::PRunRRF() : PRunBase() +{ + fFitStartTime = 0.0; + fFitStopTime = 0.0; + fNoOfFitBins = 0; +} + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + * \param msrInfo pointer to the msr info structure + * \param runNo number of the run of the msr-file + */ +PRunRRF::PRunRRF(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo) : PRunBase(msrInfo, rawData, runNo) +{ + bool success; + + // calculate fData + if (success) { + success = PrepareData(); + } +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PRunRRF::~PRunRRF() +{ +} + +//-------------------------------------------------------------------------- +// CalcChiSquare +//-------------------------------------------------------------------------- +/** + *

+ * + * \param par parameter vector iterated by minuit + */ +double PRunRRF::CalcChiSquare(const std::vector& par) +{ + double chisq = 0.0; + double diff = 0.0; + + return chisq; +} + +//-------------------------------------------------------------------------- +// CalcMaxLikelihood +//-------------------------------------------------------------------------- +/** + *

+ * + * \param par parameter vector iterated by minuit + */ +double PRunRRF::CalcMaxLikelihood(const std::vector& par) +{ + cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl; + + return 1.0; +} + +//-------------------------------------------------------------------------- +// CalcTheory +//-------------------------------------------------------------------------- +/** + *

+ * + */ +void PRunRRF::CalcTheory() +{ +} + +//-------------------------------------------------------------------------- +// PrepareData +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PRunRRF::PrepareData() +{ + bool success = true; + + cout << endl << "in PRunRRF::PrepareData(): will feed fData"; + + // count the number of bins to be fitted + fNoOfFitBins=0; + for (unsigned int i=0; i= fFitStartTime) && (fData.fTime[i] <= fFitStopTime)) + fNoOfFitBins++; + } + + return success; +} + diff --git a/src/classes/PRunSingleHisto.cpp b/src/classes/PRunSingleHisto.cpp new file mode 100644 index 00000000..7571e31c --- /dev/null +++ b/src/classes/PRunSingleHisto.cpp @@ -0,0 +1,342 @@ +/*************************************************************************** + + PRunSingleHisto.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include + +#include "PMusr.h" +#include "PRunSingleHisto.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PRunSingleHisto::PRunSingleHisto() : PRunBase() +{ + fFitStartTime = 0.0; + fFitStopTime = 0.0; + fNoOfFitBins = 0; +} + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + * \param msrInfo pointer to the msr info structure + * \param runNo number of the run of the msr-file + */ +PRunSingleHisto::PRunSingleHisto(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo) : PRunBase(msrInfo, rawData, runNo) +{ + if (!PrepareData()) { + cout << endl << "**SEVERE ERROR**: PRunSingleHisto::PRunSingleHisto: Couldn't prepare data for fitting!"; + cout << endl << " This is very bad :-(, will quit ..."; + fValid = false; + } +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ * + */ +PRunSingleHisto::~PRunSingleHisto() +{ +} + +//-------------------------------------------------------------------------- +// CalcChiSquare +//-------------------------------------------------------------------------- +/** + *

+ * + * The return value is chisq * fRunInfo->fPacking, the reason is: + * the data d_i and the theory t_i are scaled by the packing, i.e. d_i -> d_i / packing. + * Since the error is 1/sqrt(d_i) and hence error^2 = d_i it follows that + * (d_i - t_i)^2 ~ 1/packing^2 and error^2 ~ 1/packing, and hence the chisq needs + * to be scaled by packing. + * + * \param par parameter vector iterated by minuit + */ +double PRunSingleHisto::CalcChiSquare(const std::vector& par) +{ + double chisq = 0.0; + double diff = 0.0; + + double N0; + + // check if norm is a parameter or a function + if (fRunInfo->fNormParamNo < MSR_PARAM_FUN_OFFSET) { // norm is a parameter + N0 = par[fRunInfo->fNormParamNo-1]; + } else { // norm is a function + // get function number + unsigned int funNo = fRunInfo->fNormParamNo-MSR_PARAM_FUN_OFFSET; + // evaluate function + N0 = fMsrInfo->EvalFunc(funNo,fRunInfo->fMap,par); + } + + // get tau + double tau; + if (fRunInfo->fLifetimeParamNo != -1) + tau = par[fRunInfo->fLifetimeParamNo-1]; + else + tau = PMUON_LIFETIME; + + // get background + double bkg = par[fRunInfo->fBkgFitParamNo-1]; + + // calculate functions + for (int i=0; iGetNoOfFuncs(); i++) { + int funcNo = fMsrInfo->GetFuncNo(i); +//cout << ">> i = " << i << ", funcNo = " << funcNo << endl; + fFuncValues[i] = fMsrInfo->EvalFunc(funcNo, fRunInfo->fMap, par); + } + + // calculate chi square + for (unsigned int i=0; i=fFitStartTime) && (fData.fTime[i]<=fFitStopTime)) { + diff = fData.fValue[i] - + (N0*TMath::Exp(-fData.fTime[i]/tau)*(1+fTheory->Func(fData.fTime[i], par, fFuncValues))+bkg); + chisq += diff*diff / (fData.fError[i]*fData.fError[i]); + } + } + + +// static int counter = 0; +// TString fln=fRunInfo->fRunName+"_"+(Long_t)fRunInfo->fForwardHistoNo+"_data.dat"; +// ofstream f(fln.Data(),ios_base::out); +// for (unsigned int i=0; ifRunName+"_"+(Long_t)fRunInfo->fForwardHistoNo+"_theo.dat"; +// ofstream ft(fln.Data(),ios_base::out); +// for (unsigned int i=0; iFunc(fData.fTime[i], par))+bkg; +// } +// ft.close(); +// counter++; +// if (counter == 4) exit(0); + + return chisq*fRunInfo->fPacking; +} + +//-------------------------------------------------------------------------- +// CalcMaxLikelihood +//-------------------------------------------------------------------------- +/** + *

+ * + * \param par parameter vector iterated by minuit + */ +double PRunSingleHisto::CalcMaxLikelihood(const std::vector& par) +{ + cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl; + + return 1.0; +} + +//-------------------------------------------------------------------------- +// CalcTheory +//-------------------------------------------------------------------------- +/** + *

+ * + */ +void PRunSingleHisto::CalcTheory() +{ + // feed the parameter vector + std::vector par; + PMsrParamList *paramList = fMsrInfo->GetMsrParamList(); + for (unsigned int i=0; isize(); i++) + par.push_back((*paramList)[i].fValue); + + // calculate asymmetry + double N0 = par[fRunInfo->fNormParamNo-1]; + + // get tau + double tau; + if (fRunInfo->fLifetimeParamNo != -1) + tau = par[fRunInfo->fLifetimeParamNo-1]; + else + tau = PMUON_LIFETIME; + + // get background + double bkg = par[fRunInfo->fBkgFitParamNo-1]; + + // calculate functions + for (int i=0; iGetNoOfFuncs(); i++) { + fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), fRunInfo->fMap, par); + } + + // calculate theory + for (unsigned int i=0; iFunc(fData.fTime[i], par, fFuncValues))+bkg); + } + + // clean up + par.clear(); +} + +//-------------------------------------------------------------------------- +// PrepareData +//-------------------------------------------------------------------------- +/** + *

+ * + */ +bool PRunSingleHisto::PrepareData() +{ +// cout << endl << "in PRunSingleHisto::PrepareData(): will feed fData"; + + // get the proper run + PRawRunData* runData = fRawData->GetRunData(fRunInfo->fRunName); + if (!runData) { // couldn't get run + cout << endl << "PRunSingleHisto::PrepareData(): Couldn't get run " << fRunInfo->fRunName.Data() << "!"; + return false; + } + + // keep the time resolution in (us) + fTimeResolution = runData->fTimeResolution/1.0e3; + + // keep start/stop time for fit + fFitStartTime = fRunInfo->fFitRange[0]; + fFitStopTime = fRunInfo->fFitRange[1]; +//cout << endl << "start/stop (fit): " << fFitStartTime << ", " << fFitStopTime; + + + // check if the t0's are given in the msr-file + if (fRunInfo->fT0[0] == -1) { // t0's are NOT in the msr-file + // check if the t0's are in the data file + if (runData->fT0s.size() != 0) { // t0's in the run data + // keep the proper t0's. For single histo runs, forward is holding the histo no + // fForwardHistoNo starts with 1 not with 0 ;-) + fT0s.push_back(runData->fT0s[fRunInfo->fForwardHistoNo-1]); + } else { // t0's are neither in the run data nor in the msr-file -> not acceptable! + cout << endl << "PRunSingleHisto::PrepareData(): NO t0's found, neither in the run data nor in the msr-file!"; + return false; + } + } else { // t0's in the msr-file + // check if t0's are given in the data file + if (runData->fT0s.size() != 0) { + // compare t0's of the msr-file with the one in the data file + if (fabs(fRunInfo->fT0[0]-runData->fT0s[fRunInfo->fForwardHistoNo-1])>5.0) { // given in bins!! + cout << endl << "PRunSingleHisto::PrepareData(): **WARNING**:"; + cout << endl << " t0 from the msr-file is " << fRunInfo->fT0[0]; + cout << endl << " t0 from the data file is " << runData->fT0s[fRunInfo->fForwardHistoNo-1]; + cout << endl << " This is quite a deviation! Is this done intentionally??"; + cout << endl; + } + } + fT0s.push_back(fRunInfo->fT0[0]); + } + + // check if post pile up data shall be used + unsigned int histoNo; + if (fRunInfo->fFileFormat.Contains("ppc")) { + histoNo = runData->fDataBin.size()/2 + fRunInfo->fForwardHistoNo-1; + } else { + histoNo = fRunInfo->fForwardHistoNo-1; + } + + if ((runData->fDataBin.size() < histoNo) || (histoNo < 0)) { + cout << endl << "PRunSingleHisto::PrepareData(): PANIC ERROR:"; + cout << endl << " histoNo found = " << histoNo << ", but there are only " << runData->fDataBin.size() << " runs!?!?"; + cout << endl << " Will quite :-("; + cout << endl; + return false; + } + + // transform raw histo data. This is done the following way (for details see the manual): + // for the single histo fit, just the rebinned raw data are copied + // first get start data, end data, and t0 + unsigned int start = fRunInfo->fDataRange[0]; + unsigned int end = fRunInfo->fDataRange[1]; + unsigned int t0 = fT0s[0]; + // check if start, end, and t0 make any sense + // 1st check if start and end are in proper order + if (end < start) { // need to swap them + int keep = end; + end = start; + start = keep; + } + // 2nd check if start is within proper bounds + if ((start < 0) || (start > runData->fDataBin[histoNo].size())) { + cout << endl << "PRunSingleHisto::PrepareData(): start data bin doesn't make any sense!"; + return false; + } + // 3rd check if end is within proper bounds + if ((end < 0) || (end > runData->fDataBin[histoNo].size())) { + cout << endl << "PRunSingleHisto::PrepareData(): end data bin doesn't make any sense!"; + return false; + } + // 4th check if t0 is within proper bounds + if ((t0 < 0) || (t0 > runData->fDataBin[histoNo].size())) { + cout << endl << "PRunSingleHisto::PrepareData(): t0 data bin doesn't make any sense!"; + return false; + } + // everything looks fine, hence fill data set + double value = 0.0; + for (unsigned i=start; ifPacking == 0) && (i != start)) { // fill data + // in order that after rebinning the fit does not need to be redone (important for plots) + // the value is normalize to per bin + value /= fRunInfo->fPacking; + // time shifted so that packing is included correctly, i.e. t0 == t0 after packing + fData.fTime.push_back(fTimeResolution*((double)i-(double)t0-(double)fRunInfo->fPacking)); + fData.fValue.push_back(value); + if (value == 0.0) + fData.fError.push_back(1.0); + else + fData.fError.push_back(TMath::Sqrt(value)); + value = 0.0; + } + value += runData->fDataBin[histoNo][i]; + } + + // count the number of bins to be fitted + fNoOfFitBins=0; + for (unsigned int i=0; i= fFitStartTime) && (fData.fTime[i] <= fFitStopTime)) + fNoOfFitBins++; + } + + return true; +} + + diff --git a/src/classes/PStartupHandler.cpp b/src/classes/PStartupHandler.cpp new file mode 100644 index 00000000..49cb4880 --- /dev/null +++ b/src/classes/PStartupHandler.cpp @@ -0,0 +1,55 @@ +/*************************************************************************** + + PStartupHandler.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "PStartupHandler.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/*! + *

+ */ +PStartupHandler::PStartupHandler() +{ +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/*! + *

+ */ +PStartupHandler::~PStartupHandler() +{ +} + +// end --------------------------------------------------------------------- + diff --git a/src/classes/PTheory.cpp b/src/classes/PTheory.cpp new file mode 100644 index 00000000..a4e139e9 --- /dev/null +++ b/src/classes/PTheory.cpp @@ -0,0 +1,970 @@ +/*************************************************************************** + + PTheory.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +using namespace std; + +#include +#include +#include +#include + +#include "PMsrHandler.h" +#include "PTheory.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

The theory block his parsed and mapped to a tree. Every line (except the '+') + * is a theory object by itself, i.e. the whole theory is build up recursivly. + * Example: + * Theory block: + * a 1 + * tf 2 3 + * se 4 + * + + * a 5 + * tf 6 7 + * se 8 + * + + * a 9 + * tf 10 11 + * + * This is mapped into the following binary tree: + * + * a 1 + * +/ \* + * a 5 tf 2 3 + * + / \* \ * + * a 9 a 5 se 4 + * \* \* + * tf 10 11 tf 6 7 + * \* + * se 8 + * + * \param msrInfo + * \param runNo + * \param parent needed in order to know if PTheory is the root object or a child + * false (default) -> this is the root object + * true -> this is part of an already existing object tree + */ +PTheory::PTheory(PMsrHandler *msrInfo, unsigned int runNo, const bool hasParent) +{ + // init stuff + fValid = true; + fAdd = 0; + fMul = 0; + + static unsigned int lineNo = 1; // lineNo + static unsigned int depth = 0; // needed to handle '+' properly + + if (hasParent == false) { // reset static counters if root object + lineNo = 1; // the lineNo counter and the depth counter need to be + depth = 0; // reset for every root object (new run). + } + + // get the input to be analyzed from the msr handler + PMsrLines *fullTheoryBlock = msrInfo->GetMsrTheory(); + if (lineNo > fullTheoryBlock->size()-1) { + return; + } + // get the line to be parsed + PMsrLineStructure *line = &(*fullTheoryBlock)[lineNo]; + + // copy line content to str in order to remove comments + TString str = line->fLine.Copy(); + + // remove theory line comment if present, i.e. something starting with '(' + int index = str.Index("("); + if (index > 0) // theory line comment present + str.Resize(index); + + // remove msr-file comment if present, i.e. something starting with '#' + index = str.Index("#"); + if (index > 0) // theory line comment present + str.Resize(index); + + // tokenize line + TObjArray *tokens; + TObjString *ostr; + + tokens = str.Tokenize(" "); + if (!tokens) { + cout << endl << "**SEVERE ERROR**: PTheory(): Couldn't tokenize theory block line " << line->fLineNo << "."; + cout << endl << " line content: " << line->fLine.Data(); + cout << endl; + exit(0); + } + ostr = dynamic_cast(tokens->At(0)); + str = ostr->GetString(); + + // search the theory function + unsigned int idx = SearchDataBase(str); + + // function found is not defined + if (idx == (unsigned int) THEORY_UNDEFINED) { + cout << endl << "**ERROR**: PTheory(): Theory line '" << line->fLine.Data() << "'"; + cout << endl << " in line no " << line->fLineNo << " is undefined!"; + fValid = false; + return; + } + + // line is a valid function, hence analyze parameters + if ((unsigned int)(tokens->GetEntries()-1) != fNoOfParam) { + cout << endl << "**ERROR**: PTheory(): Theory line '" << line->fLine.Data() << "'"; + cout << " in line no " << line->fLineNo; + cout << " expecting " << fgTheoDataBase[idx].fNoOfParam << ", but found " << tokens->GetEntries()-1; + fValid = false; + } + // keep function index + fType = idx; + // filter out the parameters + int status; + unsigned int value; + bool ok = false;; + for (int i=1; iGetEntries(); i++) { + ostr = dynamic_cast(tokens->At(i)); + str = ostr->GetString(); + + // check if str is map + if (str.Contains("map")) { + status = sscanf(str.Data(), "map%u", &value); + if (status == 1) { // everthing ok + ok = true; + // get parameter from map + PIntVector maps = (*msrInfo->GetMsrRunList())[runNo].fMap; + if ((value <= maps.size()) && (value > 0)) { // everything fine + fParamNo.push_back(maps[value-1]-1); + } else { // map index out of range + cout << endl << "**ERROR**: PTheory: map index " << value << " out of range! See line no " << line->fLineNo; + fValid = false; + } + } else { // something wrong + cout << endl << "**ERROR**: PTheory: map '" << str.Data() << "' not allowed. See line no " << line->fLineNo; + fValid = false; + } + } else if (str.Contains("fun")) { // check if str is fun + status = sscanf(str.Data(), "fun%u", &value); + if (status == 1) { // everthing ok + ok = true; + // handle function, i.e. get, from the function number x (FUNx), the function index, + // add function offset and fill "parameter vector" + fParamNo.push_back(msrInfo->GetFuncIndex(value)+MSR_PARAM_FUN_OFFSET); + } else { // something wrong + fValid = false; + } + } else { // check if str is param no + status = sscanf(str.Data(), "%u", &value); + if (status == 1) { // everthing ok + ok = true; + fParamNo.push_back(value-1); + } + // check if one of the valid entries was found + if (!ok) { + cout << endl << "**ERROR**: PTheory: '" << str.Data() << "' not allowed. See line no " << line->fLineNo; + fValid = false; + } + } + } + + // call the next line (only if valid so far and not the last line) + // handle '*' + if (fValid && (lineNo < fullTheoryBlock->size()-1)) { + line = &(*fullTheoryBlock)[lineNo+1]; + if (!line->fLine.Contains("+")) { // make sure next line is not a '+' + depth++; + lineNo++; + fMul = new PTheory(msrInfo, runNo, true); + depth--; + } + } + // call the next line (only if valid so far and not the last line) + // handle '+' + if (fValid && (lineNo < fullTheoryBlock->size()-1)) { + line = &(*fullTheoryBlock)[lineNo+1]; + if ((depth == 0) && line->fLine.Contains("+")) { + lineNo += 2; // go to the next theory function line + fAdd = new PTheory(msrInfo, runNo, true); + } + } + + // make clean and tidy theory block for the msr-file + if (fValid && !hasParent) { // parent theory object + MakeCleanAndTidyTheoryBlock(fullTheoryBlock); + } + + // clean up + if (tokens) { + delete tokens; + tokens = 0; + } +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ */ +PTheory::~PTheory() +{ +//cout << endl << "PTheory::~PTheory() ..." << endl; + + fParamNo.clear(); + + if (fMul) { + delete fMul; + fMul = 0; + } + + if (fAdd) { + delete fAdd; + fAdd = 0; + } +} + +//-------------------------------------------------------------------------- +// IsValid +//-------------------------------------------------------------------------- +/** + *

Checks if the theory tree is valid. Needs to be implemented!! + * + */ +bool PTheory::IsValid() +{ + + if (fMul) { + if (fAdd) { + return (fValid && fMul->IsValid() && fAdd->IsValid()); + } else { + return (fValid && fMul->IsValid()); + } + } else { + if (fAdd) { + return (fValid && fAdd->IsValid()); + } else { + return fValid; + } + } + + return false; +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t + * \param paramValues + */ +double PTheory::Func(register double t, const vector& paramValues, const vector& funcValues) const +{ + if (fMul) { + if (fAdd) { // fMul != 0 && fAdd != 0 + switch (fType) { + case THEORY_ASYMMETRY: + return Asymmetry(paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_SIMPLE_EXP: + return SimpleExp(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_GENERAL_EXP: + return GeneralExp(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_SIMPLE_GAUSS: + return SimpleGauss(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_STATIC_GAUSS_KT: + return StaticGaussKT(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_STATIC_KT_TABLE: + return StaticKTTable(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_DYNAMIC_KT_TABLE: + return DynamicKTTable(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_COMBI_LGKT: + return CombiLGKT(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_SPIN_GLASS: + return SpinGlass(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_RANDOM_ANISOTROPIC_HYPERFINE: + return RandomAnisotropicHyperfine(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_ABRAGAM: + return Abragam(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_INTERNAL_FIELD: + return InternalField(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_TF_COS: + return TFCos(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_BESSEL: + return Bessel(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_INTERNAL_BESSEL: + return InternalBessel(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; + default: + cout << endl << "**PANIC ERROR**: PTheory::Func: You never should have reached this line?!?! (" << fType << ")"; + cout << endl; + exit(0); + } + } else { // fMul !=0 && fAdd == 0 + switch (fType) { + case THEORY_ASYMMETRY: + return Asymmetry(paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_SIMPLE_EXP: + return SimpleExp(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_GENERAL_EXP: + return GeneralExp(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_SIMPLE_GAUSS: + return SimpleGauss(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_STATIC_GAUSS_KT: + return StaticGaussKT(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_STATIC_KT_TABLE: + return StaticKTTable(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_DYNAMIC_KT_TABLE: + return DynamicKTTable(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_COMBI_LGKT: + return CombiLGKT(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_SPIN_GLASS: + return SpinGlass(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_RANDOM_ANISOTROPIC_HYPERFINE: + return RandomAnisotropicHyperfine(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_ABRAGAM: + return Abragam(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_INTERNAL_FIELD: + return InternalField(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_TF_COS: + return TFCos(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_BESSEL: + return Bessel(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + case THEORY_INTERNAL_BESSEL: + return InternalBessel(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; + default: + cout << endl << "**PANIC ERROR**: PTheory::Func: You never should have reached this line?!?! (" << fType << ")"; + cout << endl; + exit(0); + } + } + } else { // fMul == 0 && fAdd != 0 + if (fAdd) { + switch (fType) { + case THEORY_ASYMMETRY: + return Asymmetry(paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_SIMPLE_EXP: + return SimpleExp(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_GENERAL_EXP: + return GeneralExp(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_SIMPLE_GAUSS: + return SimpleGauss(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_STATIC_GAUSS_KT: + return StaticGaussKT(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_STATIC_KT_TABLE: + return StaticKTTable(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_DYNAMIC_KT_TABLE: + return DynamicKTTable(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_COMBI_LGKT: + return CombiLGKT(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_SPIN_GLASS: + return SpinGlass(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_RANDOM_ANISOTROPIC_HYPERFINE: + return RandomAnisotropicHyperfine(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_ABRAGAM: + return Abragam(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_INTERNAL_FIELD: + return InternalField(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_TF_COS: + return TFCos(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_BESSEL: + return Bessel(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + case THEORY_INTERNAL_BESSEL: + return InternalBessel(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; + default: + cout << endl << "**PANIC ERROR**: PTheory::Func: You never should have reached this line?!?! (" << fType << ")"; + cout << endl; + exit(0); + } + } else { // fMul == 0 && fAdd == 0 + switch (fType) { + case THEORY_ASYMMETRY: + return Asymmetry(paramValues, funcValues); + break; + case THEORY_SIMPLE_EXP: + return SimpleExp(t, paramValues, funcValues); + break; + case THEORY_GENERAL_EXP: + return GeneralExp(t, paramValues, funcValues); + break; + case THEORY_SIMPLE_GAUSS: + return SimpleGauss(t, paramValues, funcValues); + break; + case THEORY_STATIC_GAUSS_KT: + return StaticGaussKT(t, paramValues, funcValues); + break; + case THEORY_STATIC_KT_TABLE: + return StaticKTTable(t, paramValues, funcValues); + break; + case THEORY_DYNAMIC_KT_TABLE: + return DynamicKTTable(t, paramValues, funcValues); + break; + case THEORY_COMBI_LGKT: + return CombiLGKT(t, paramValues, funcValues); + break; + case THEORY_SPIN_GLASS: + return SpinGlass(t, paramValues, funcValues); + break; + case THEORY_RANDOM_ANISOTROPIC_HYPERFINE: + return RandomAnisotropicHyperfine(t, paramValues, funcValues); + break; + case THEORY_ABRAGAM: + return Abragam(t, paramValues, funcValues); + break; + case THEORY_INTERNAL_FIELD: + return InternalField(t, paramValues, funcValues); + break; + case THEORY_TF_COS: + return TFCos(t, paramValues, funcValues); + break; + case THEORY_BESSEL: + return Bessel(t, paramValues, funcValues); + break; + case THEORY_INTERNAL_BESSEL: + return InternalBessel(t, paramValues, funcValues); + break; + default: + cout << endl << "**PANIC ERROR**: PTheory::Func: You never should have reached this line?!?! (" << fType << ")"; + cout << endl; + exit(0); + } + } + } + + return 0.0; +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param name + */ +unsigned int PTheory::SearchDataBase(TString name) +{ + unsigned int idx = THEORY_UNDEFINED; + + for (unsigned int i=0; i + * + * \param fullTheoryBlock + */ +void PTheory::MakeCleanAndTidyTheoryBlock(PMsrLines *fullTheoryBlock) +{ + PMsrLineStructure *line; + TString str, tidy; + char substr[256]; + TObjArray *tokens = 0; + TObjString *ostr; + unsigned int idx = THEORY_UNDEFINED; + + for (unsigned int i=1; isize(); i++) { + // get the line to be prettyfied + line = &(*fullTheoryBlock)[i]; + // copy line content to str in order to remove comments + str = line->fLine.Copy(); + // tokenize line + tokens = str.Tokenize(" "); + // make a handable string out of the asymmetry token + ostr = dynamic_cast(tokens->At(0)); + str = ostr->GetString(); + // check if the line is just a '+'; if so nothing to be done + if (str.Contains("+")) + continue; + // search the theory function + for (unsigned int j=0; jGetEntries() < fgTheoDataBase[idx].fNoOfParam + 1) + continue; + // make tidy string + sprintf(substr, "%-10s", fgTheoDataBase[idx].fName.Data()); + tidy = TString(substr); + for (unsigned j=1; j(tokens->At(j)); + str = ostr->GetString(); + sprintf(substr, "%6s", str.Data()); + tidy += TString(substr); + } + if (fgTheoDataBase[idx].fComment.Length() != 0) { + unsigned int size = tidy.Length(); + for (unsigned int k=0; k<35-size; k++) + tidy += TString(" "); + tidy += fgTheoDataBase[idx].fComment; + } + // write tidy string back into theory block + (*fullTheoryBlock)[i].fLine = tidy; + } + + // clean up + if (tokens) { + delete tokens; + tokens = 0; + } +} + +//-------------------------------------------------------------------------- +/** + *

Asymmetry + * \f[ = A \f] + * + *

Every theory-function handles its parameters the following way: It holds + * an array fParamNo which is holding the parameter/map/function number. The numbering + * is as such: par1, par2, ..., parX1, internalPar1, internalParX2, map1, ..., mapX3, + * fun1, ..., funX4, where X1 is the number of parameters, X2 the number of internal + * parameters, i.e. parameters listed in the runs, X3 the number of maps, and X4 the + * number of used functions. + * + * \param paramValues is an array of parameter values [par1, par2, ..., parX1, + * internalPar1, ..., internalParX2, map1, ..., mapX3, fun1, ..., funX4] + */ +double PTheory::Asymmetry(const vector& paramValues, const vector& funcValues) const +{ + double asym; + + // check if FUNCTIONS are used + if (fParamNo[0] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + asym = paramValues[fParamNo[0]]; + } else { + asym = funcValues[fParamNo[0]-MSR_PARAM_FUN_OFFSET]; + } + + return asym; +} + +//-------------------------------------------------------------------------- +/** + *

Simple exponential + * \f[ = \exp\left(-\lambda t\right) \f]. + * + *

For details concerning fParamNo and paramValues see PTheory::Asymmetry and + * PTheory::PTheory. + * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues parameter values, here only one, namely the depolarization + * rate \f$\lambda\f$ in \f$(1/\mu\mathrm{s})\f$ + */ +double PTheory::SimpleExp(register double t, const vector& paramValues, const vector& funcValues) const +{ + double lambda; + + // check if FUNCTIONS are used + if (fParamNo[0] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + lambda = paramValues[fParamNo[0]]; + } else { // function + lambda = funcValues[fParamNo[0]-MSR_PARAM_FUN_OFFSET]; + } + + return TMath::Exp(-t*lambda); +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::GeneralExp(register double t, const vector& paramValues, const vector& funcValues) const +{ + double val[2]; + + // check if FUNCTIONS are used + for (unsigned int i=0; i<2; i++) { + if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + val[i] = paramValues[fParamNo[i]]; + } else { // function + val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET]; + } + } + + return TMath::Exp(-TMath::Power(t*val[0], val[1])); +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::SimpleGauss(register double t, const vector& paramValues, const vector& funcValues) const +{ + double sigma; + + // check if FUNCTIONS are used + if (fParamNo[0] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + sigma = paramValues[fParamNo[0]]; + } else { // function + sigma = funcValues[fParamNo[0]-MSR_PARAM_FUN_OFFSET]; + } + + return TMath::Exp(-0.5*TMath::Power(t*sigma, 2.0)); +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::StaticGaussKT(register double t, const vector& paramValues, const vector& funcValues) const +{ + double sigma; + + // check if FUNCTIONS are used + if (fParamNo[0] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + sigma = paramValues[fParamNo[0]]; + } else { // function + sigma = funcValues[fParamNo[0]-MSR_PARAM_FUN_OFFSET]; + } + + double sigma_t_2 = t*t*sigma*sigma; + + return 0.333333333333333 * (1.0 + 2.0*(1.0 - sigma_t_2)*TMath::Exp(-0.5*sigma_t_2)); +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::StaticKTTable(register double t, const vector& paramValues, const vector& funcValues) const +{ + return 0.0; +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::DynamicKTTable(register double t, const vector& paramValues, const vector& funcValues) const +{ + return 0.0; +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::CombiLGKT(register double t, const vector& paramValues, const vector& funcValues) const +{ + double val[2]; + + // check if FUNCTIONS are used + for (unsigned int i=0; i<2; i++) { + if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + val[i] = paramValues[fParamNo[i]]; + } else { // function + val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET]; + } + } + + double lambdaL_t = t*val[0]; + double lambdaG_t_2 = t*t*val[1]*val[1]; + + return 0.333333333333333 * + (1.0 + 2.0*(1.0-lambdaL_t-lambdaG_t_2)*TMath::Exp(-(lambdaL_t+0.5*lambdaG_t_2))); +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::SpinGlass(register double t, const vector& paramValues, const vector& funcValues) const +{ + if (paramValues[fParamNo[0]] == 0.0) + return 1.0; + + double val[3]; + + // check if FUNCTIONS are used + for (unsigned int i=0; i<3; i++) { + if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + val[i] = paramValues[fParamNo[i]]; + } else { // function + val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET]; + } + } + + double lambda_2 = val[0]*val[0]; + double lambda_t_2_q = t*t*lambda_2*val[2]; + double rate_2 = 4.0*lambda_2*(1.0-val[2])*t/val[1]; + + double rateL = TMath::Sqrt(rate_2); + double rateT = TMath::Sqrt(rate_2+lambda_t_2_q); + + return 0.333333333333333*(TMath::Exp(-rateL) + 2.0*(1.0-lambda_t_2_q/rateT)*TMath::Exp(-rateT)); +} + +//-------------------------------------------------------------------------- +/** + *

Where does this come from ??? please give a reference + * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::RandomAnisotropicHyperfine(register double t, const vector& paramValues, const vector& funcValues) const +{ + double val[2]; + + // check if FUNCTIONS are used + for (unsigned int i=0; i<2; i++) { + if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + val[i] = paramValues[fParamNo[i]]; + } else { // function + val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET]; + } + } + + double nu_t = t*val[0]; + double lambda_t = t*val[1]; + + return 0.166666666666667*(1.0-0.5*nu_t)*TMath::Exp(-0.5*nu_t) + + 0.333333333333333*(1.0-0.25*nu_t)*TMath::Exp(-0.25*(nu_t+2.44949*lambda_t)); +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::Abragam(register double t, const vector& paramValues, const vector& funcValues) const +{ + double val[2]; + + // check if FUNCTIONS are used + for (unsigned int i=0; i<2; i++) { + if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + val[i] = paramValues[fParamNo[i]]; + } else { // function + val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET]; + } + } + + double gamma_t = t*val[1]; + + return TMath::Exp(-TMath::Power(val[0]/val[1],2.0)* + (TMath::Exp(-gamma_t)-1.0-gamma_t)); +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::InternalField(register double t, const vector& paramValues, const vector& funcValues) const +{ + double val[4]; + + // check if FUNCTIONS are used + for (unsigned int i=0; i<4; i++) { + if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + val[i] = paramValues[fParamNo[i]]; + } else { // function + val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET]; + } + } + + return 0.666666666666667* + TMath::Cos(DEG_TO_RAD*val[0])+TWO_PI*val[1]* + TMath::Exp(-val[2]*t) + + 0.333333333333333*TMath::Exp(-val[3]*t); +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::TFCos(register double t, const vector& paramValues, const vector& funcValues) const +{ + double val[2]; + + // check if FUNCTIONS are used + for (unsigned int i=0; i<2; i++) { + if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + val[i] = paramValues[fParamNo[i]]; + } else { // function + val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET]; + } + } + + return TMath::Cos(DEG_TO_RAD*val[0]+TWO_PI*val[1]*t); +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::Bessel(register double t, const vector& paramValues, const vector& funcValues) const +{ + double val[2]; + + // check if FUNCTIONS are used + for (unsigned int i=0; i<2; i++) { + if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + val[i] = paramValues[fParamNo[i]]; + } else { // function + val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET]; + } + } + + return TMath::BesselJ0(DEG_TO_RAD*val[0]+TWO_PI*val[1]*t); +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::InternalBessel(register double t, const vector& paramValues, const vector& funcValues) const +{ + double val[4]; + + // check if FUNCTIONS are used + for (unsigned int i=0; i<4; i++) { + if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map + val[i] = paramValues[fParamNo[i]]; + } else { // function + val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET]; + } + } + + return 0.666666666666667* + TMath::BesselJ0(DEG_TO_RAD*val[0]+TWO_PI*val[1])* + TMath::Exp(-val[2]*t) + + 0.333333333333333*TMath::Exp(-val[3]*t); +} + diff --git a/src/include/PFitter.h b/src/include/PFitter.h new file mode 100644 index 00000000..921eaea7 --- /dev/null +++ b/src/include/PFitter.h @@ -0,0 +1,97 @@ +/*************************************************************************** + + PFitter.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PFITTER_H_ +#define _PFITTER_H_ + +#include "Minuit2/MnUserParameters.h" +#include "Minuit2/FunctionMinimum.h" + +#include "PMsrHandler.h" +#include "PRunListCollection.h" +#include "PFitterFcn.h" + +/* +Will handle all the possible minuit commands and actually do things ... +*/ + +#define PMN_INTERACTIVE 0 +#define PMN_CONTOURS 1 +#define PMN_EIGEN 2 +#define PMN_HESSE 3 +#define PMN_MACHINE_PRECISION 4 +#define PMN_MIGRAD 5 +#define PMN_MINIMIZE 6 +#define PMN_MINOS 7 +#define PMN_PLOT 8 +#define PMN_SAVE 9 +#define PMN_SCAN 10 +#define PMN_SIMPLEX 12 +#define PMN_STRATEGY 13 +#define PMN_USER_COVARIANCE 14 +#define PMN_USER_PARAM_STATE 15 +#define PMN_PRINT 16 + +class PFitter +{ + public: + PFitter(PMsrHandler *runInfo, PRunListCollection *runListCollection); + virtual ~PFitter(); + + bool IsValid() { return fIsValid; } + bool DoFit(); + + private: + bool fIsValid; + bool fUseChi2; + + PMsrHandler *fRunInfo; + + PMsrParamList fParams; ///< msr-file parameters + + PMsrLines fCmdLines; ///< all the Minuit commands from the msr-file + PIntVector fCmdList; ///< command list + + PFitterFcn *fFitterFcn; + ROOT::Minuit2::MnUserParameters fMnUserParams; ///< minuit2 input parameter list + ROOT::Minuit2::FunctionMinimum *fFcnMin; ///< + + bool CheckCommands(); + bool SetParameters(); + + bool ExecuteMigrad(); + bool ExecuteMinimize(); + bool ExecuteMinos(); + bool ExecuteSave(); + bool ExecuteSimplex(); +}; + +#endif // _PFITTER_H_ diff --git a/src/include/PFitterFcn.h b/src/include/PFitterFcn.h new file mode 100644 index 00000000..306a1fac --- /dev/null +++ b/src/include/PFitterFcn.h @@ -0,0 +1,58 @@ +/*************************************************************************** + + PFitterFcn.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PFITTERFCN_H_ +#define _PFITTERFCN_H_ + +#include + +#include "Minuit2/FCNBase.h" + +#include "PRunListCollection.h" + +class PFitterFcn : public ROOT::Minuit2::FCNBase +{ + public: + PFitterFcn(PRunListCollection *runList, bool useChi2); + ~PFitterFcn(); + + double Up() const { return fUp; } + double operator()(const std::vector&) const; + + unsigned int GetTotalNoOfFittedBins() { return fRunListCollection->GetTotalNoOfBinsFitted(); } + + private: + double fUp; + bool fUseChi2; + PRunListCollection *fRunListCollection; +}; + +#endif // _PFITTERFCN_H_ diff --git a/src/include/PFunction.h b/src/include/PFunction.h new file mode 100644 index 00000000..b8ab4422 --- /dev/null +++ b/src/include/PFunction.h @@ -0,0 +1,114 @@ +/*************************************************************************** + + PFunction.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PFUNCTION_H_ +#define _PFUNCTION_H_ + +#include + +#include +using namespace boost::spirit; + +#include + +#include "PFunctionGrammar.h" + +//---------------------------------------------------------------------------- +#define OP_ADD 0 +#define OP_SUB 1 +#define OP_MUL 2 +#define OP_DIV 3 + +#define FUN_COS 0 +#define FUN_SIN 1 +#define FUN_TAN 2 +#define FUN_COSH 3 +#define FUN_SINH 4 +#define FUN_TANH 5 +#define FUN_ACOS 6 +#define FUN_ASIN 7 +#define FUN_ATAN 8 +#define FUN_ACOSH 9 +#define FUN_ASINH 10 +#define FUN_ATANH 11 +#define FUN_LOG 12 +#define FUN_LN 13 +#define FUN_EXP 14 + +//---------------------------------------------------------------------------- +typedef struct func_tree_node { + int fID; ///< tag showing what tree element this is + int fOperatorTag; ///< tag for '+', '-', '*', '/' + int fFunctionTag; ///< tag got "cos", "sin", ... + int fIvalue; ///< for parameter numbers and maps + double fDvalue; ///< for numbers + vector children; ///< holding sub-tree +} PFuncTreeNode; + +//---------------------------------------------------------------------------- +class PFunction { + public: + PFunction(tree_parse_info<> info); + virtual ~PFunction(); + + virtual bool IsValid() { return fValid; } + virtual int GetFuncNo() { return fFuncNo; } + virtual bool CheckMapAndParamRange(unsigned int mapSize, unsigned int paramSize); + virtual double Eval(vector param); + virtual void SetMap(vector map) { fMap = map; } + + virtual TString* GetFuncString() { return &fFuncString; } + + protected: + virtual bool SetFuncNo(); + + virtual bool FindAndCheckMapAndParamRange(PFuncTreeNode &node, unsigned int mapSize, unsigned int paramSize); + virtual bool GenerateFuncEvalTree(); + virtual void FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node); + virtual double EvalNode(PFuncTreeNode &node); + virtual void CleanupFuncEvalTree(); + virtual void CleanupNode(PFuncTreeNode &node); + + private: + tree_parse_info<> fInfo; + vector fParam; + vector fMap; + PFuncTreeNode fFunc; + + bool fValid; ///< flag showing if the function is valid + int fFuncNo; ///< function number, i.e. FUNx with x the function number + + virtual void EvalTreeForString(tree_parse_info<> info); + virtual void EvalTreeForStringExpression(iter_t const& i); + TString fFuncString; ///< clear text representation of the function +}; + +#endif // _PFUNCTION_H_ diff --git a/src/include/PFunctionGrammar.h b/src/include/PFunctionGrammar.h new file mode 100644 index 00000000..a62bfc19 --- /dev/null +++ b/src/include/PFunctionGrammar.h @@ -0,0 +1,142 @@ +/*************************************************************************** + + PFunctionGrammer.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PFUNCTIONGRAMMAR_H_ +#define _PFUNCTIONGRAMMAR_H_ + +#include +using namespace std; + +//#define BOOST_SPIRIT_DEBUG + +#include +#include +using namespace boost::spirit; + +typedef char const* iterator_t; +typedef tree_match parse_tree_match_t; +typedef parse_tree_match_t::tree_iterator iter_t; + +//-------------------------------------------------------------------------- +/** + * + */ +struct PFunctionGrammar : public grammar +{ + static const int realID = 1; + static const int funLabelID = 2; + static const int parameterID = 3; + static const int mapID = 4; + static const int functionID = 5; + static const int factorID = 6; + static const int termID = 7; + static const int expressionID = 8; + static const int assignmentID = 9; + + template + struct definition + { + definition(PFunctionGrammar const& /*self*/) + { + // Start grammar definition + real = leaf_node_d[ real_p ]; + + fun_label = leaf_node_d[ ( lexeme_d[ "FUN" >> +digit_p ] ) ]; + + parameter = leaf_node_d[ ( lexeme_d[ "PAR" >> +digit_p ] ) ]; + + map = leaf_node_d[ ( lexeme_d[ "MAP" >> +digit_p ] ) ]; + + function = str_p("COS") >> ch_p('(') >> expression >> ch_p(')') + | str_p("SIN") >> ch_p('(') >> expression >> ch_p(')') + | str_p("TAN") >> ch_p('(') >> expression >> ch_p(')') + | str_p("COSH") >> ch_p('(') >> expression >> ch_p(')') + | str_p("SINH") >> ch_p('(') >> expression >> ch_p(')') + | str_p("TANH") >> ch_p('(') >> expression >> ch_p(')') + | str_p("ACOS") >> ch_p('(') >> expression >> ch_p(')') + | str_p("ASIN") >> ch_p('(') >> expression >> ch_p(')') + | str_p("ATAN") >> ch_p('(') >> expression >> ch_p(')') + | str_p("ACOSH") >> ch_p('(') >> expression >> ch_p(')') + | str_p("ASINH") >> ch_p('(') >> expression >> ch_p(')') + | str_p("ATANH") >> ch_p('(') >> expression >> ch_p(')') + | str_p("LOG") >> ch_p('(') >> expression >> ch_p(')') + | str_p("LN") >> ch_p('(') >> expression >> ch_p(')') + | str_p("EXP") >> ch_p('(') >> expression >> ch_p(')') + ; + + factor = real + | parameter + | map + | function + | inner_node_d[ch_p('(') >> expression >> ch_p(')')] + ; + + term = factor >> + *( (root_node_d[ch_p('*')] >> factor) + | (root_node_d[ch_p('/')] >> factor) + ); + + expression = term >> + *( (root_node_d[ch_p('+')] >> term) + | (root_node_d[ch_p('-')] >> term) + ); + + assignment = (fun_label >> ch_p('=') >> expression); + // End grammar definition + + // turn on the debugging info. + BOOST_SPIRIT_DEBUG_RULE(real); + BOOST_SPIRIT_DEBUG_RULE(fun_label); + BOOST_SPIRIT_DEBUG_RULE(parameter); + BOOST_SPIRIT_DEBUG_RULE(map); + BOOST_SPIRIT_DEBUG_RULE(function); + BOOST_SPIRIT_DEBUG_RULE(factor); + BOOST_SPIRIT_DEBUG_RULE(term); + BOOST_SPIRIT_DEBUG_RULE(expression); + BOOST_SPIRIT_DEBUG_RULE(assignment); + } + + rule, parser_tag > assignment; + rule, parser_tag > expression; + rule, parser_tag > term; + rule, parser_tag > factor; + rule, parser_tag > function; + rule, parser_tag > map; + rule, parser_tag > parameter; + rule, parser_tag > fun_label; + rule, parser_tag > real; + + rule, parser_tag > const& + start() const { return assignment; } + }; +}; + +#endif // _PFUNCTIONGRAMMAR_H_ diff --git a/src/include/PFunctionHandler.h b/src/include/PFunctionHandler.h new file mode 100644 index 00000000..74eaacac --- /dev/null +++ b/src/include/PFunctionHandler.h @@ -0,0 +1,68 @@ +/*************************************************************************** + + PFunctionHandler.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PFUNCTIONHANDLER_H_ +#define _PFUNCTIONHANDLER_H_ + +#include +#include +using namespace std; + +#include + +#include "PMusr.h" +#include "PFunctionGrammar.h" +#include "PFunction.h" + +class PFunctionHandler +{ + public: + PFunctionHandler(PMsrLines lines); + virtual ~PFunctionHandler(); + + virtual bool IsValid() { return fValid; } + virtual bool DoParse(); + virtual bool CheckMapAndParamRange(unsigned int mapSize, unsigned int paramSize); + virtual double Eval(int funNo, vector map, vector param); + virtual int GetFuncNo(unsigned int idx); + virtual int GetFuncIndex(int funcNo); + virtual unsigned int GetNoOfFuncs() { return fFuncs.size(); } + virtual TString* GetFuncString(unsigned int idx); + + private: + bool fValid; + + PMsrLines fLines; + vector fFuncs; +}; + +#endif // _PFUNCTIONHANDLER_H_ + diff --git a/src/include/PMsrHandler.h b/src/include/PMsrHandler.h new file mode 100644 index 00000000..7b5a68bb --- /dev/null +++ b/src/include/PMsrHandler.h @@ -0,0 +1,114 @@ +/*************************************************************************** + + PMsrHandler.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PMSRHANDLER_H_ +#define _PMSRHANDLER_H_ + +/* +#include +using namespace std; +*/ + +#include +#include + +#include "PMusr.h" +#include "PFunctionHandler.h" +#include "PFunctionGrammar.h" +#include "PFunction.h" + +//------------------------------------------------------------- +/** + *

+ */ +class PMsrHandler +{ + public: + PMsrHandler(char *fileName); + virtual ~PMsrHandler(); + + virtual int ReadMsrFile(); + virtual int WriteMsrLogFile(); + + virtual TString* GetMsrTitle() { return &fTitle; } + virtual PMsrParamList* GetMsrParamList() { return &fParam; } + virtual PMsrLines* GetMsrTheory() { return &fTheory; } + virtual PMsrLines* GetMsrFunctions() { return &fFunctions; } + virtual PMsrRunList* GetMsrRunList() { return &fRuns; } + virtual PMsrLines* GetMsrCommands() { return &fCommands; } + virtual PMsrPlotList* GetMsrPlotList() { return &fPlots; } + virtual PMsrStatisticStructure* GetMsrStatistic() { return &fStatistic; } + + virtual unsigned int GetNoOfParams() { return fParam.size(); } + + virtual bool SetMsrParamValue(unsigned int i, double value); + virtual bool SetMsrParamStep(unsigned int i, double value); + virtual bool SetMsrParamPosError(unsigned int i, double value); + + virtual void SetMsrStatisticMin(double min) { fStatistic.fMin = min; } + virtual void SetMsrStatisticNdf(unsigned int ndf) { fStatistic.fNdf = ndf; } + + virtual int GetNoOfFuncs() { return fFuncHandler->GetNoOfFuncs(); } + virtual unsigned int GetFuncNo(int idx) { return fFuncHandler->GetFuncNo(idx); } + virtual unsigned int GetFuncIndex(int funNo) { return fFuncHandler->GetFuncIndex(funNo); } + virtual bool CheckMapAndParamRange(unsigned int mapSize, unsigned int paramSize) + { return fFuncHandler->CheckMapAndParamRange(mapSize, paramSize); } + virtual double EvalFunc(unsigned int i, vector map, vector param) + { return fFuncHandler->Eval(i,map,param); } + + private: + TString fFileName; + TString fTitle; ///< holds the title string of the msr-file + PMsrParamList fParam; ///< holds a list of the fit parameters + PMsrLines fTheory; ///< holds the theory definition + PMsrLines fFunctions; ///< holds the user defined functions + PMsrRunList fRuns; ///< holds a list of run information + PMsrLines fCommands; ///< holds a list of the minuit commands + PMsrPlotList fPlots; ///< holds a list of the plot input parameters + PMsrStatisticStructure fStatistic; ///< holds the statistic info + + int fMsrBlockCounter; ///< used to select the proper msr-block + + PFunctionHandler *fFuncHandler; ///< needed to parse functions + + virtual bool HandleFitParameterEntry(PMsrLines &line); + virtual bool HandleTheoryEntry(PMsrLines &line); + virtual bool HandleFunctionsEntry(PMsrLines &line); + virtual bool HandleRunEntry(PMsrLines &line); + virtual bool HandleCommandsEntry(PMsrLines &line); + virtual bool HandlePlotEntry(PMsrLines &line); + virtual bool HandleStatisticEntry(PMsrLines &line); + + virtual void InitRunParameterStructure(PMsrRunStructure ¶m); + virtual bool FilterFunMapNumber(TString str, const char *filter, int &no); +}; + +#endif // _PMSRHANDLER_H_ diff --git a/src/include/PMusr.h b/src/include/PMusr.h new file mode 100644 index 00000000..a7f7e15b --- /dev/null +++ b/src/include/PMusr.h @@ -0,0 +1,253 @@ +/*************************************************************************** + + PMusr.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PMUSR_H_ +#define _PMUSR_H_ + +#include +using namespace std; + +#include +#include + +#define PMUSR_SUCCESS 0 +#define PMUSR_WRONG_STARTUP_SYNTAX -1 +#define PMUSR_MSR_FILE_NOT_FOUND -2 +#define PMUSR_MSR_ALLOCATION_ERROR -3 +#define PMUSR_MSR_SYNTAX_ERROR -4 +#define PMUSR_TOKENIZE_ERROR -5 +#define PMUSR_MSR_LOG_FILE_WRITE_ERROR -6 + +#define PRUN_SINGLE_HISTO 0 +#define PRUN_ASYMMETRY 2 +#define PRUN_RRF 4 +#define PRUN_NON_MUSR 8 + +// muon life time in (us) +#define PMUON_LIFETIME 2.19705 + +// accelerator cycles in (us), needed to determine proper background +#define ACCEL_PERIOD_PSI 0.01975 +#define ACCEL_PERIOD_TRIUMF 0.04337 +#define ACCEL_PERIOD_RAL 0.0 + +// used to filter post pileup correct data histos from root files +#define POST_PILEUP_HISTO_OFFSET 20 + +//------------------------------------------------------------- +// msr block header tags +#define MSR_TAG_TITLE 0 +#define MSR_TAG_FITPARAMETER 1 +#define MSR_TAG_THEORY 2 +#define MSR_TAG_FUNCTIONS 3 +#define MSR_TAG_RUN 4 +#define MSR_TAG_COMMANDS 5 +#define MSR_TAG_PLOT 6 +#define MSR_TAG_STATISTIC 7 + +//------------------------------------------------------------- +// msr fit type tags +#define MSR_FITTYPE_SINGLE_HISTO 0 +#define MSR_FITTYPE_ASYM 2 +#define MSR_FITTYPE_ASYM_RRF 4 +#define MSR_FITTYPE_NO_MUSR 8 + +//------------------------------------------------------------- +// msr plot type tags +#define MSR_PLOT_SINGLE_HISTO 0 +#define MSR_PLOT_ASYM 2 +#define MSR_PLOT_ASYM_RRF 4 +#define MSR_PLOT_NO_MUSR 8 + +//------------------------------------------------------------- +// map and fun offsets for parameter parsing +#define MSR_PARAM_MAP_OFFSET 1000 +#define MSR_PARAM_FUN_OFFSET 2000 + +//------------------------------------------------------------- +/** + *

typedef to make to code more readable. + */ +typedef vector PIntVector; + +//------------------------------------------------------------------------ +/** + *

+ */ +typedef vector PDoubleVector; + +//------------------------------------------------------------- +/** + *

typedef to make to code more readable. + */ +typedef vector PComplexVector; + +//------------------------------------------------------------------------------------------ +/** + *

Predominantly used in PRunBase. + */ +typedef struct { + vector fTime; + vector fValue; + vector fError; + vector fTheory; +} PRunData; + +//------------------------------------------------------------------------ +/** + *

+ */ +typedef struct { + TString fRunName; ///< name of the run + TString fRunTitle; ///< run title + TString fSetup; ///< description of the setup of this run + double fField; ///< magnetic field value + double fTemp; ///< temperature during the run + double fTimeResolution; ///< time resolution of the run + vector fT0s; ///< vector of t0's of a run + vector fDataBin; ///< vector of all histos of a run +} PRawRunData; + +//------------------------------------------------------------------------ +/** + *

+ */ +typedef vector PRawRunDataList; + +//------------------------------------------------------------- +/** + *

Helper structure for parsing. Keeps a msr-file line string and the corresponding line number. + */ +typedef struct { + int fLineNo; ///< original line number of the msr-file + TString fLine; ///< msr-file line +} PMsrLineStructure; + +//------------------------------------------------------------- +/** + *

typedef to make to code more readable: list of msr-file lines. + */ +typedef vector PMsrLines; + +//------------------------------------------------------------- +/** + *

Holds the information of a parameter. + */ +typedef struct { + int fNoOfParams; ///< how many parameters are given + int fNo; ///< parameter number + TString fName; ///< name + double fValue; ///< value + double fStep; ///< step / error / neg_error, depending on the situation + bool fPosErrorPresent; ///< positive error is defined (as a number) + double fPosError; ///< positive error if present + double fLowerBoundary; ///< lower boundary for the fit parameter + double fUpperBoundary; ///< upper boundary for the fit parameter +} PMsrParamStructure; + +//------------------------------------------------------------- +/** + *

typedef to make to code more readable: vector of fit parameters. + */ +typedef vector PMsrParamList; + +//------------------------------------------------------------- +/** + *

Holds the information of a single plot block + * + */ +typedef struct { + TString fRunName; ///< name of the run file + TString fBeamline; ///< e.g. mue4, mue1, pim3, emu, m15, ... (former: run type) + TString fInstitute; ///< e.g. psi, ral, triumf (former: run format) + TString fFileFormat; ///< e.g. root, nexus, psi-bin, mud + int fFitType; ///< fit type: 0=single histo fit, 2=asymmetry fit, 4=asymmetry in RRF, 8=non muSR + int fAlphaParamNo; ///< alpha + int fBetaParamNo; ///< + int fNormParamNo; ///< + int fBkgFitParamNo; ///< + int fPhaseParamNo; ///< + int fLifetimeParamNo; ///< + bool fLifetimeCorrection; ///< + PIntVector fMap; ///< + int fForwardHistoNo; ///< + int fBackwardHistoNo; ///< + double fBkgFix[2]; ///< + int fBkgRange[4]; ///< + int fDataRange[4]; ///< + int fT0[2]; ///< + double fFitRange[2]; ///< + int fPacking; ///< + double fRRFFreq; ///< rotating reference frequency + int fRRFPacking; ///< rotating reference packing + int fAlpha2ParamNo; ///< + int fBeta2ParamNo; ///< + int fRightHistoNo; ///< + int fLeftHistoNo; ///< +} PMsrRunStructure; + +//------------------------------------------------------------- +/** + *

typedef to make to code more readable: list of runs with its parameters. + */ +typedef vector PMsrRunList; + +//------------------------------------------------------------- +/** + *

Holds the information of a single plot block + */ +typedef struct { + int fPlotType; ///< plot type + PComplexVector fRuns; ///< list of runs to be plotted + double fTmin; ///< time minimum + double fTmax; ///< time maximum + double fYmin; ///< asymmetry/counts minimum + double fYmax; ///< asymmetry/counts maximum +} PMsrPlotStructure; + +//------------------------------------------------------------- +/** + *

typedef to make to code more readable: list of plots. + */ +typedef vector PMsrPlotList; + +//------------------------------------------------------------- +/** + *

+ */ +typedef struct { + PMsrLines fStatLines; + bool fChisq; ///< flag telling if min = chi2 or min = max.likelyhood + double fMin; ///< chi2 or max. likelyhood + unsigned int fNdf; ///< number of degrees of freedom +} PMsrStatisticStructure; + +#endif // _PMUSR_H_ diff --git a/src/include/PRunAsymmetry.h b/src/include/PRunAsymmetry.h new file mode 100644 index 00000000..a0619991 --- /dev/null +++ b/src/include/PRunAsymmetry.h @@ -0,0 +1,69 @@ +/*************************************************************************** + + PRunAsymmetry.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PRUNASYMMETRY_H_ +#define _PRUNASYMMETRY_H_ + +#include "PRunBase.h" + +class PRunAsymmetry : public PRunBase +{ + public: + PRunAsymmetry(); + PRunAsymmetry(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo); + virtual ~PRunAsymmetry(); + + virtual double CalcChiSquare(const std::vector& par); + virtual double CalcMaxLikelihood(const std::vector& par); + virtual void CalcTheory(); + + virtual unsigned int GetNoOfFitBins() { return fNoOfFitBins; } + + protected: + virtual bool PrepareData(); + + private: + unsigned int fAlphaBetaTag; ///< 1-> alpha = beta = 1; 2-> alpha != 1, beta = 1; 3-> alpha = 1, beta != 1; 4-> alpha != 1, beta != 1 + + double fFitStartTime; + double fFitStopTime; + unsigned int fNoOfFitBins; + + vector fForward; ///< forward histo data + vector fForwardErr; ///< forward histo errors + vector fBackward; ///< backward histo data + vector fBackwardErr; ///< backward histo errors + + bool SubtractFixBkg(); + bool SubtractEstimatedBkg(); +}; + +#endif // _PRUNASYMMETRY_H_ diff --git a/src/include/PRunBase.h b/src/include/PRunBase.h new file mode 100644 index 00000000..53c03b15 --- /dev/null +++ b/src/include/PRunBase.h @@ -0,0 +1,97 @@ +/*************************************************************************** + + PRunBase.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PRUNBASE_H_ +#define _PRUNBASE_H_ + +#include +using namespace std; + +#include + +#include "PMusr.h" +#include "PMsrHandler.h" +#include "PRunDataHandler.h" +#include "PTheory.h" +//#include "PFunctions.h" + +//------------------------------------------------------------------------------------------ +/** + * brauche ich eine base class um zwischen den verschiedenen run-modi unterscheiden zu können? + * Ich meine: + * - single histogram + * - asymmetry + * - RRF + * - non muSR + * + * --> JA + * + * PTheory and PFunctions werden direkt für jeden run generiert, da man dann maps und functions + * direkt für den spezifischen run umsetzen kann (da man eliminiert alle maps und functions). Dies + * garantiert effiziente theory-Aufrufe da diese in chisq/maxlikelyhood x-fach aufgerufen werden. + */ +class PRunBase +{ + public: + PRunBase(); + PRunBase(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo); + virtual ~PRunBase(); + + virtual double CalcChiSquare(const vector& par) = 0; // pure virtual, i.e. needs to be implemented by the deriving class!! + virtual double CalcMaxLikelihood(const vector& par) = 0; // pure virtual, i.e. needs to be implemented by the deriving class!! + + virtual void CalcTheory() = 0; // pure virtual, i.e. needs to be implemented by the deriving class!! + + virtual PRunData* GetData() { return &fData; } + virtual void CleanUp(); + virtual bool IsValid() { return fValid; } + + protected: + bool fValid; + + unsigned int fRunNo; ///< number of the run within the msr file + PMsrHandler *fMsrInfo; ///< msr-file handler + PMsrRunStructure *fRunInfo; ///< run info used to filter out needed infos for the run + PRunDataHandler *fRawData; ///< holds the raw run data + + vector fParamNo; ///< vector of parameter numbers for the specifc run + + PRunData fData; ///< data to be fitted + double fTimeResolution; ///< time resolution + vector fT0s; ///< all t0's of a run! The derived classes will handle it + + virtual bool PrepareData() = 0; // pure virtual, i.e. needs to be implemented by the deriving class!! + + vector fFuncValues; ///< is keeping the values of the functions from the FUNCTIONS block + PTheory *fTheory; ///< theory needed to calculate chi-square +}; + +#endif // _PRUNBASE_H_ diff --git a/src/include/PRunDataHandler.h b/src/include/PRunDataHandler.h new file mode 100644 index 00000000..ac0160be --- /dev/null +++ b/src/include/PRunDataHandler.h @@ -0,0 +1,76 @@ +/*************************************************************************** + + PRunDataHandler.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PRUNDATAHANDLER_H_ +#define _PRUNDATAHANDLER_H_ + +#include +using namespace std; + +#include + +#include "PMusr.h" +#include "PMsrHandler.h" + +class PRunDataHandler +{ + public: + PRunDataHandler(PMsrHandler *msrInfo); + virtual ~PRunDataHandler(); + + virtual bool IsAllDataAvailable() { return fAllDataAvailable; } + virtual PRawRunData* GetRunData(TString runName); + + private: + PMsrHandler *fMsrInfo; + + bool fAllDataAvailable; ///< flag indicating if all data sets could be read + TString fRunName; ///< current run name + TString fRunPathName; ///< current path file name + PRawRunDataList fData; ///< keeping all the raw data + + virtual bool ReadFile(); + virtual bool FileAlreadyRead(PMsrRunStructure &runInfo); + virtual bool FileExistsCheck(PMsrRunStructure &runInfo); + virtual bool ReadRootFile(); + virtual bool ReadNexusFile(); + virtual bool ReadNemuFile(); + virtual bool ReadPsiBinFile(); + virtual bool ReadMudFile(); + virtual bool ReadAsciiFile(); + + virtual bool StripWhitespace(TString &str); + virtual bool IsWhitespace(const char *str); + virtual double ToDouble(TString &str, bool &ok); + virtual int ToInt(TString &str, bool &ok); +}; + +#endif // _PRUNDATAHANDLER_H_ diff --git a/src/include/PRunListCollection.h b/src/include/PRunListCollection.h new file mode 100644 index 00000000..d6ff5c2d --- /dev/null +++ b/src/include/PRunListCollection.h @@ -0,0 +1,86 @@ +/*************************************************************************** + + PRunListCollection.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PRUNLISTCOLLECTION_H_ +#define _PRUNLISTCOLLECTION_H_ + +#include +using namespace std; + +#include "PMusr.h" +#include "PMsrHandler.h" +#include "PRunDataHandler.h" +#include "PRunSingleHisto.h" +#include "PRunAsymmetry.h" +#include "PRunRRF.h" +#include "PRunNonMusr.h" + +class PRunListCollection +{ + public: + PRunListCollection(PMsrHandler *msrInfo, PRunDataHandler *data); + virtual ~PRunListCollection(); + + virtual bool Add(int runNo); + + virtual double GetSingleHistoChisq(const std::vector& par); + virtual double GetAsymmetryChisq(const std::vector& par); + virtual double GetRRFChisq(const std::vector& par); + virtual double GetNonMusrChisq(const std::vector& par); + + virtual double GetSingleHistoMaximumLikelihood(const std::vector& par); + virtual double GetAsymmetryMaximumLikelihood(const std::vector& par); + virtual double GetRRFMaximumLikelihood(const std::vector& par); + virtual double GetNonMusrMaximumLikelihood(const std::vector& par); + + virtual unsigned int GetTotalNoOfBinsFitted(); + + virtual unsigned int GetNoOfSingleHisto() { return fRunSingleHistoList.size(); } + virtual unsigned int GetNoOfAsymmetry() { return fRunAsymmetryList.size(); } + virtual unsigned int GetNoOfRRF() { return fRunRRFList.size(); } + virtual unsigned int GetNoOfNonMusr() { return fRunNonMusrList.size(); } + + virtual PRunData* GetSingleHisto(unsigned int index); + virtual PRunData* GetAsymmetry(unsigned int index); + virtual PRunData* GetRRF(unsigned int index); + virtual PRunData* GetNonMusr(unsigned int index); + + private: + PMsrHandler *fMsrInfo; ///< keeps all msr file info + PRunDataHandler *fData; ///< handles all raw data + + vector fRunSingleHistoList; + vector fRunAsymmetryList; + vector fRunRRFList; + vector fRunNonMusrList; +}; + +#endif // _PRUNLISTCOLLECTION_H_ diff --git a/src/include/PRunNonMusr.h b/src/include/PRunNonMusr.h new file mode 100644 index 00000000..45c1deca --- /dev/null +++ b/src/include/PRunNonMusr.h @@ -0,0 +1,59 @@ +/*************************************************************************** + + PRunNonMusr.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PRUNNONMUSR_H_ +#define _PRUNNONMUSR_H_ + +#include "PRunBase.h" + +class PRunNonMusr : public PRunBase +{ + public: + PRunNonMusr(); + PRunNonMusr(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo); + virtual ~PRunNonMusr(); + + virtual double CalcChiSquare(const std::vector& par); + virtual double CalcMaxLikelihood(const std::vector& par); + virtual void CalcTheory(); + + virtual unsigned int GetNoOfFitBins() { return fNoOfFitBins; } + + protected: + virtual bool PrepareData(); + + private: + double fFitStartTime; + double fFitStopTime; + unsigned int fNoOfFitBins; +}; + +#endif // _PRUNNONMUSR_H_ diff --git a/src/include/PRunRRF.h b/src/include/PRunRRF.h new file mode 100644 index 00000000..4304250b --- /dev/null +++ b/src/include/PRunRRF.h @@ -0,0 +1,59 @@ +/*************************************************************************** + + PRunRRF.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PRUNRRF_H_ +#define _PRUNRRF_H_ + +#include "PRunBase.h" + +class PRunRRF : public PRunBase +{ + public: + PRunRRF(); + PRunRRF(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo); + virtual ~PRunRRF(); + + virtual double CalcChiSquare(const std::vector& par); + virtual double CalcMaxLikelihood(const std::vector& par); + virtual void CalcTheory(); + + virtual unsigned int GetNoOfFitBins() { return fNoOfFitBins; } + + protected: + virtual bool PrepareData(); + + private: + double fFitStartTime; + double fFitStopTime; + unsigned int fNoOfFitBins; +}; + +#endif // _PRUNRRF_H_ diff --git a/src/include/PRunSingleHisto.h b/src/include/PRunSingleHisto.h new file mode 100644 index 00000000..f062a1b0 --- /dev/null +++ b/src/include/PRunSingleHisto.h @@ -0,0 +1,59 @@ +/*************************************************************************** + + PRunSingleHisto.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PRUNSINGLEHISTO_H_ +#define _PRUNSINGLEHISTO_H_ + +#include "PRunBase.h" + +class PRunSingleHisto : public PRunBase +{ + public: + PRunSingleHisto(); + PRunSingleHisto(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo); + virtual ~PRunSingleHisto(); + + virtual double CalcChiSquare(const std::vector& par); + virtual double CalcMaxLikelihood(const std::vector& par); + virtual void CalcTheory(); + + virtual unsigned int GetNoOfFitBins() { return fNoOfFitBins; } + + protected: + virtual bool PrepareData(); + + private: + double fFitStartTime; + double fFitStopTime; + unsigned int fNoOfFitBins; +}; + +#endif // _PRUNSINGLEHISTO_H_ diff --git a/src/include/PStartupHandler.h b/src/include/PStartupHandler.h new file mode 100644 index 00000000..2e24fa47 --- /dev/null +++ b/src/include/PStartupHandler.h @@ -0,0 +1,46 @@ +/*************************************************************************** + + PStartupHandler.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PSTARTUPHANDLER_H_ +#define _PSTARTUPHANDLER_H_ + +#include +#include + +class PStartupHandler : public TSAXParser +{ + public: + PStartupHandler(); + virtual ~PStartupHandler(); +}; + +#endif // _PSTARTUPHANDLER_H_ + diff --git a/src/include/PTheory.h b/src/include/PTheory.h new file mode 100644 index 00000000..e542de4f --- /dev/null +++ b/src/include/PTheory.h @@ -0,0 +1,202 @@ +/*************************************************************************** + + PTheory.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PTHEORY_H_ +#define _PTHEORY_H_ + +#include + +#include + +#include "PMsrHandler.h" + +// -------------------------------------------------------- +// function handling tags +// -------------------------------------------------------- + +// function tags +#define THEORY_UNDEFINED -1 +#define THEORY_ASYMMETRY 0 +#define THEORY_SIMPLE_EXP 1 +#define THEORY_GENERAL_EXP 2 +#define THEORY_SIMPLE_GAUSS 3 +#define THEORY_STATIC_GAUSS_KT 4 +#define THEORY_STATIC_KT_TABLE 5 +#define THEORY_DYNAMIC_KT_TABLE 6 +#define THEORY_COMBI_LGKT 7 +#define THEORY_SPIN_GLASS 8 +#define THEORY_RANDOM_ANISOTROPIC_HYPERFINE 9 +#define THEORY_ABRAGAM 10 +#define THEORY_INTERNAL_FIELD 11 +#define THEORY_TF_COS 12 +#define THEORY_BESSEL 13 +#define THEORY_INTERNAL_BESSEL 14 +#define THEORY_USER 15 + +// function parameter tags, i.e. how many parameters has a specific function +#define THEORY_PARAM_ASYMMETRY 1 // asymetry +#define THEORY_PARAM_SIMPLE_EXP 1 // damping +#define THEORY_PARAM_GENERAL_EXP 2 // damping, exponents +#define THEORY_PARAM_SIMPLE_GAUSS 1 // damping +#define THEORY_PARAM_STATIC_GAUSS_KT 1 // damping +#define THEORY_PARAM_STATIC_KT_TABLE 2 // frequency, damping +#define THEORY_PARAM_DYNAMIC_KT_TABLE 3 // frequency, damping, hop-rate +#define THEORY_PARAM_COMBI_LGKT 2 // Lorentz rate, Gauss rate +#define THEORY_PARAM_SPIN_GLASS 3 // rate, hop-rate, order parameter +#define THEORY_PARAM_RANDOM_ANISOTROPIC_HYPERFINE 2 // frequency, rate +#define THEORY_PARAM_ABRAGAM 2 // rate, hop-rate +#define THEORY_PARAM_INTERNAL_FIELD 4 // phase, frequency, TF damping, damping +#define THEORY_PARAM_TF_COS 2 // phase, frequency +#define THEORY_PARAM_BESSEL 2 // phase, frequency +#define THEORY_PARAM_INTERNAL_BESSEL 5 // fraction, phase, frequency, TF damping, damping + +// number of available user functions +#define THEORY_MAX 15 + +// deg -> rad factor +#define DEG_TO_RAD 0.0174532925199432955 +// 2 pi +#define TWO_PI 6.28318530717958623 + +class PTheory; + +//-------------------------------------------------------------------------------------- +/** + *

Structure holding the infos of a the available internally defined functions. + */ +typedef struct theo_data_base { + unsigned int fType; ///< function tag + unsigned int fNoOfParam; ///< number of parameters for this function + bool fTable; ///< table flag, indicating if the function is generate from a table + TString fName; ///< name of the function as written into the msr-file + TString fAbbrev; ///< abbreviation of the function name + TString fComment; ///< comment added in the msr-file theory block to help the used +} PTheoDataBase; + +//-------------------------------------------------------------------------------------- +/*! + *

Holds the functions available for the user. + */ +static PTheoDataBase fgTheoDataBase[THEORY_MAX] = { + + {THEORY_ASYMMETRY, THEORY_PARAM_ASYMMETRY, false, + "asymmetry", "a", ""}, + + {THEORY_SIMPLE_EXP, THEORY_PARAM_SIMPLE_EXP, false, + "simplExpo", "se", "(rate)"}, + + {THEORY_GENERAL_EXP, THEORY_PARAM_GENERAL_EXP, false, + "generExpo", "ge", "(rate exponent)"}, + + {THEORY_SIMPLE_GAUSS, THEORY_PARAM_SIMPLE_GAUSS, false, + "simpleGss", "sg", "(rate)"}, + + {THEORY_STATIC_GAUSS_KT, THEORY_PARAM_STATIC_GAUSS_KT, false, + "statGssKt", "stg", "(rate)"}, + + {THEORY_STATIC_KT_TABLE, THEORY_PARAM_STATIC_KT_TABLE, true, + "statKTTab", "sktt", "(frequency damping table)"}, + + {THEORY_DYNAMIC_KT_TABLE, THEORY_PARAM_DYNAMIC_KT_TABLE, true, + "dynmKTTab", "dktt", "(frequency damping hopprate table)"}, + + {THEORY_COMBI_LGKT, THEORY_PARAM_COMBI_LGKT, false, + "combiLGKT", "lgkt", "(LorentzRate GaussRate)"}, + + {THEORY_SPIN_GLASS, THEORY_PARAM_SPIN_GLASS, false, + "spinGlass", "spg", "(rate hopprate order)"}, + + {THEORY_RANDOM_ANISOTROPIC_HYPERFINE, THEORY_PARAM_RANDOM_ANISOTROPIC_HYPERFINE, false, + "rdAnisoHf", "rahf", "(frequency rate)"}, + + {THEORY_ABRAGAM, THEORY_PARAM_ABRAGAM, false, + "abragam", "ab", "(rate hopprate)"}, + + {THEORY_INTERNAL_FIELD, THEORY_PARAM_INTERNAL_FIELD, false, + "internFld", "if", "(phase frequency Trate Lrate)"}, + + {THEORY_TF_COS, THEORY_PARAM_TF_COS, false, + "TFieldCos", "tf", "(phase frequency)"}, + + {THEORY_BESSEL, THEORY_PARAM_BESSEL, false, + "bessel", "b", "(phase frequency)"}, + + {THEORY_INTERNAL_BESSEL, THEORY_PARAM_INTERNAL_BESSEL, false, + "internBsl", "ib", "(phase frequency Trate Lrate)"}}; + +//-------------------------------------------------------------------------------------- +/** + *

+ */ +class PTheory +{ + public: + PTheory(PMsrHandler *msrInfo, unsigned int runNo, const bool hasParent = false); + virtual ~PTheory(); + + virtual bool IsValid(); + virtual double Func(register double t, const vector& paramValues, const vector& funcValues) const; + + private: + virtual unsigned int SearchDataBase(TString name); + virtual void MakeCleanAndTidyTheoryBlock(PMsrLines* fullTheoryBlock); + + virtual double Asymmetry(const vector& paramValues, const vector& funcValues) const; + virtual double SimpleExp(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double GeneralExp(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double SimpleGauss(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double StaticGaussKT(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double StaticKTTable(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double DynamicKTTable(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double CombiLGKT(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double SpinGlass(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double RandomAnisotropicHyperfine(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double Abragam(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double InternalField(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double TFCos(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double Bessel(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double InternalBessel(register double t, const vector& paramValues, const vector& funcValues) const; + + // variables + bool fValid; + unsigned int fType; + vector fParamNo; ///< holds the parameter numbers for the theory (including maps and functions, see constructor desciption) + unsigned int fNoOfParam; +// PTable *fTable; + PTheory *fAdd, *fMul; +// unsigned int fTotalNoOfMsrParam; +// TString fUserFun; +// TString fUserFunPreParsed; + + PMsrHandler *fMsrInfo; +}; + +#endif // _PTHEORY_H_ diff --git a/src/msr2msr.cpp b/src/msr2msr.cpp new file mode 100644 index 00000000..35aded85 --- /dev/null +++ b/src/msr2msr.cpp @@ -0,0 +1,247 @@ +/*************************************************************************** + + msr2msr.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.ch * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +using namespace std; + +#include +#include +#include + +#include +#include +#include + +//------------------------------------------------------------- +// msr block header tags +#define MSR_TAG_TITLE 0 +#define MSR_TAG_FITPARAMETER 1 +#define MSR_TAG_THEORY 2 +#define MSR_TAG_FUNCTIONS 3 +#define MSR_TAG_RUN 4 +#define MSR_TAG_COMMANDS 5 +#define MSR_TAG_PLOT 6 +#define MSR_TAG_STATISTIC 7 +#define MSR_TAG_NO_BLOCK 8 + +//-------------------------------------------------------------------------- +void msr2msr_syntax() +{ + cout << endl << "usage: msr2msr | [--help]"; + cout << endl << " : input msr-file"; + cout << endl << " : converted msr-output-file"; + cout << endl << " if the is already in the 2008 format"; + cout << endl << " the output file will be identical to the input file."; + cout << endl << endl; +} + +//-------------------------------------------------------------------------- +bool msr2msr_run(char *str) +{ + TString run(str); + TString line(str); + TObjArray *tokens; + TObjString *ostr[2]; + + // for filtering + run.ToUpper(); + + // tokenize run + tokens = line.Tokenize(" "); + if (tokens->GetEntries() < 4) { + cout << endl << "**ERROR**: Something is wrong with the RUN block header:"; + cout << endl << " >> " << str; + cout << endl << " >> no is created"; + cout << endl; + return false; + } + + + if (run.Contains("NEMU")) { + ostr[0] = dynamic_cast(tokens->At(1)); // file name + sprintf(str, "RUN %s MUE4 PSI NEMU (name beamline institute data-file-format)", ostr[0]->GetString().Data()); + } else if (run.Contains("PSI")) { + ostr[0] = dynamic_cast(tokens->At(1)); // file name + ostr[1] = dynamic_cast(tokens->At(1)); // beamline + sprintf(str, "RUN %s %s PSI PSI-BIN (name beamline institute data-file-format)", + ostr[0]->GetString().Data(), ostr[1]->GetString().Data()); + } else if (run.Contains("TRIUMF")) { + ostr[0] = dynamic_cast(tokens->At(1)); // file name + ostr[1] = dynamic_cast(tokens->At(1)); // beamline + sprintf(str, "RUN %s %s TRIUMF MUD (name beamline institute data-file-format)", + ostr[0]->GetString().Data(), ostr[1]->GetString().Data()); + } else if (run.Contains("RAL")) { + ostr[0] = dynamic_cast(tokens->At(1)); // file name + ostr[1] = dynamic_cast(tokens->At(1)); // beamline + sprintf(str, "RUN %s %s RAL NEXUS (name beamline institute data-file-format)", + ostr[0]->GetString().Data(), ostr[1]->GetString().Data()); + } + cout << endl; + + // clean up + if (tokens) { + delete tokens; + tokens = 0; + } + + return true; +} + +//-------------------------------------------------------------------------- +void msr2msr_param(char *str, int &tag) +{ + // check for comment header which needs to be replaced + if (strstr(str, "Nr.")) { + strcpy(str, "# No Name Value Step Pos_Error Boundaries"); + return; + } + + // handle parameter line + TString line(str); + TObjArray *tokens; + TObjString *ostr[6]; + char sstr[256]; + char spaces[256]; + + tokens = line.Tokenize(" "); + unsigned int noTokens = tokens->GetEntries(); + if (noTokens == 4) { + strcat(str, " none"); + } else if (noTokens == 6) { + for (unsigned int i=0; i<6; i++) + ostr[i] = dynamic_cast(tokens->At(i)); + // number + sprintf(sstr, "%10s", ostr[0]->GetString().Data()); + // name + strcat(sstr, " "); + strcat(sstr, ostr[1]->GetString().Data()); + memset(spaces, 0, sizeof(spaces)); + memset(spaces, ' ', 12-strlen(ostr[1]->GetString().Data())); + strcat(sstr, spaces); + // value + strcat(sstr, ostr[2]->GetString().Data()); + memset(spaces, 0, sizeof(spaces)); + memset(spaces, ' ', 10-strlen(ostr[2]->GetString().Data())); + strcat(sstr, spaces); + // step + strcat(sstr, ostr[3]->GetString().Data()); + memset(spaces, 0, sizeof(spaces)); + memset(spaces, ' ', 12-strlen(ostr[3]->GetString().Data())); + strcat(sstr, spaces); + // pos. error + strcat(sstr, "none "); + // lower boundary + strcat(sstr, ostr[4]->GetString().Data()); + memset(spaces, 0, sizeof(spaces)); + memset(spaces, ' ', 8-strlen(ostr[4]->GetString().Data())); + strcat(sstr, spaces); + // upper boundary + strcat(sstr, ostr[5]->GetString().Data()); + strcpy(str, sstr); + } + + // clean up + if (tokens) { + delete tokens; + tokens = 0; + } + + // check if the end of the parameter block is reached + unsigned int i; + for (i=0; i +#include +using namespace std; + +#include "TString.h" +#include "TFile.h" +#include "TCanvas.h" +#include "TH1.h" + +#include "PMusr.h" +#include "PStartupHandler.h" +#include "PMsrHandler.h" +#include "PRunDataHandler.h" +#include "PRunListCollection.h" +#include "PFitter.h" + +//-------------------------------------------------------------------------- +/** + *

+ * + */ +void musrfit_syntax() +{ + cout << endl << "usage: musrfit [ [--debug] | [--dump ]] | --version | --help"; + cout << endl << " : msr input file"; + cout << endl << " 'msrfit ' will execute msrfit"; + cout << endl << " 'msrfit' or 'msrfit --help' will show this help"; + cout << endl << " 'msrfit --version' will print the msrfit version"; + cout << endl << " --debug is used to print additional infos"; + cout << endl << " --dump is writing a data file with the fit data and the theory"; + cout << endl << " can be 'ascii', 'root'"; + cout << endl << endl; +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param msrHandler + */ +void musrfit_debug_info(PMsrHandler* msrHandler) +{ + int i; + + // print title + cout << endl << "----------"; + cout << endl << "title = " << msrHandler->GetMsrTitle()->Data(); + + // print parameters + cout << endl << "----------"; + cout << endl << "parameters"; + PMsrParamList::iterator param_it; + for (param_it = msrHandler->GetMsrParamList()->begin(); param_it != msrHandler->GetMsrParamList()->end(); ++param_it) { + cout << endl << param_it->fNo << ": "; + cout << param_it->fName << ", "; + cout << param_it->fValue << ", "; + cout << param_it->fStep << ", "; + switch (param_it->fNoOfParams) { + case 5: + cout << param_it->fPosError; + break; + case 6: + cout << param_it->fLowerBoundary << ", "; + cout << param_it->fUpperBoundary; + break; + case 7: + cout << param_it->fPosError << ", "; + cout << param_it->fLowerBoundary << ", "; + cout << param_it->fUpperBoundary; + break; + default: + break; + } + } + + // print theory + cout << endl << "----------"; + PMsrLines::iterator theo_it; + theo_it = msrHandler->GetMsrTheory()->begin(); + for (; theo_it != msrHandler->GetMsrTheory()->end(); ++theo_it) + cout << endl << theo_it->fLine.Data(); + + // print functions + + // print run + cout << endl << "----------"; + cout << endl << "runs"; + PMsrRunList::iterator runs_it; + int runNo = 1; + for (runs_it = msrHandler->GetMsrRunList()->begin(); runs_it != msrHandler->GetMsrRunList()->end(); ++runs_it) { + cout << endl << "******"; + cout << endl << "run no " << runNo++; + cout << endl << "run (name, beamline, institute, data-file-format): "; + cout << endl << " " << runs_it->fRunName << ", " << runs_it->fBeamline << ", " << runs_it->fInstitute << ", " << runs_it->fFileFormat; + cout << endl << "fittype " << runs_it->fFitType; + cout << endl << "alpha " << runs_it->fAlphaParamNo; + cout << endl << "beta " << runs_it->fBetaParamNo; + cout << endl << "norm " << runs_it->fNormParamNo; + cout << endl << "backgr.fit " << runs_it->fBkgFitParamNo; + cout << endl << "rphase " << runs_it->fPhaseParamNo; + cout << endl << "lifetime " << runs_it->fLifetimeParamNo; + if (runs_it->fLifetimeCorrection) + cout << endl << "lifetimecorrection true"; + else + cout << endl << "lifetimecorrection false"; + cout << endl << "map "; + for (PIntVector::iterator it = runs_it->fMap.begin(); it != runs_it->fMap.end(); ++it) + cout << *it << ", "; + cout << endl << "forward " << runs_it->fForwardHistoNo; + cout << endl << "backward " << runs_it->fBackwardHistoNo; + cout << endl << "backgr.fix "; + for (int i=0; i<2; i++) + cout << runs_it->fBkgFix[i] << ", "; + cout << endl << "background "; + for (int i=0; i<4; i++) + cout << runs_it->fBkgRange[i] << ", "; + cout << endl << "data "; + for (int i=0; i<4; i++) + cout << runs_it->fDataRange[i] << ", "; + cout << endl << "t0 "; + for (int i=0; i<2; i++) + cout << runs_it->fT0[i] << ", "; + cout << endl << "fit "; + for (int i=0; i<2; i++) + cout << runs_it->fFitRange[i] << ", "; + cout << endl << "packing " << runs_it->fPacking; + cout << endl << "rrffrequency " << runs_it->fRRFFreq; + cout << endl << "rrfpacking " << runs_it->fRRFPacking; + cout << endl << "alpha2 " << runs_it->fAlpha2ParamNo; + cout << endl << "beta2 " << runs_it->fBeta2ParamNo; + cout << endl << "right " << runs_it->fRightHistoNo; + cout << endl << "left " << runs_it->fLeftHistoNo; + } + + // print commands + cout << endl << "----------"; + cout << endl << "commands"; + PMsrLines::iterator commands_it; + commands_it = msrHandler->GetMsrCommands()->begin(); + ++commands_it; // the first entry is just the COMMANDS block statment + for (; commands_it != msrHandler->GetMsrCommands()->end(); ++commands_it) + cout << endl << commands_it->fLine.Data(); + + // print plot + cout << endl << "----------"; + PMsrPlotList::iterator plot_it; + i = 1; + for (plot_it = msrHandler->GetMsrPlotList()->begin(); plot_it != msrHandler->GetMsrPlotList()->end(); ++plot_it) { + cout << endl << i++ << ". plot " << plot_it->fPlotType; + cout << endl << "runs = "; + PComplexVector::iterator plot_run_it; + for (plot_run_it = plot_it->fRuns.begin(); plot_run_it != plot_it->fRuns.end(); ++plot_run_it) { + switch (plot_it->fPlotType) { + case MSR_PLOT_SINGLE_HISTO: + case MSR_PLOT_ASYM: + case MSR_PLOT_NO_MUSR: + cout << plot_run_it->Re() << ", "; + break; + case MSR_PLOT_ASYM_RRF: + cout << "(" << plot_run_it->Re() << "," << plot_run_it->Im() << "), "; + break; + default: + cout << endl << "??"; + break; + } + } + if (plot_it->fTmin == -999.0) { + cout << endl << "range = autorange"; + } else { + if (plot_it->fYmin == -999.0) { // only time range given + cout << endl << "range = [ " << plot_it->fTmin << ", " << plot_it->fTmax << "]"; + } else { + cout << endl << "range = [ " << plot_it->fTmin << ", " << plot_it->fTmax << ", " << plot_it->fYmin << ", " << plot_it->fYmax << "]"; + } + } + } + + // print statistic + cout << endl << "----------"; + cout << endl << "statistic"; + PMsrLines::iterator statistic_it; + statistic_it = msrHandler->GetMsrStatistic()->fStatLines.begin(); + ++statistic_it; // the first entry is just the STATISTIC block statment + for (; statistic_it != msrHandler->GetMsrStatistic()->fStatLines.end(); ++statistic_it) + cout << endl << statistic_it->fLine.Data(); + + cout << endl << "----------" << endl; +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param fln + * \param data + * \param runCounter + */ +void musrfit_write_ascii(TString fln, PRunData *data, int runCounter) +{ + // generate dump file name + TString fileName = fln.Copy(); + TString count("_"); + count += runCounter; + Ssiz_t index = fln.Index("."); + fln.Insert(index, count); +//cout << endl << "fln = " << fln.Data(); + + ofstream f; + + // open dump-file + f.open(fln.Data(), iostream::out); + if (!f.is_open()) { + cout << endl << "Couldn't open dump (" << fln.Data() << ") file for writting, sorry ..."; + cout << endl; + return; + } + + // dump data + f << "% number of data values = " << data->fTime.size() << endl; + f << "% time (us), value, error, theory" << endl; + for (unsigned int i=0; ifTime.size(); i++) { + f << data->fTime[i] << ", " << data->fValue[i] << ", " << data->fError[i] << ", " << data->fTheory[i] << endl; + } + + // close file + f.close(); +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param fileName + */ +void musrfit_dump_ascii(char *fileName, PRunListCollection *runList) +{ + TString fln(fileName); + fln.ReplaceAll(".msr", ".dat"); + + // go through the run list, get the data and dump it in a file + + int runCounter = 0; + + // single histos + unsigned int size = runList->GetNoOfSingleHisto(); + PRunData *data; + if (size > 0) { + for (unsigned int i=0; iGetSingleHisto(i); + if (data) { + // dump data + musrfit_write_ascii(fln, data, runCounter); + runCounter++; + } + } + } + + // asymmetry + size = runList->GetNoOfAsymmetry(); + if (size > 0) { + for (unsigned int i=0; iGetAsymmetry(i); + if (data) { + // dump data + musrfit_write_ascii(fln, data, runCounter); + runCounter++; + } + } + } + + // rrf + size = runList->GetNoOfRRF(); + if (size > 0) { + for (unsigned int i=0; iGetRRF(i); + if (data) { + // dump data + musrfit_write_ascii(fln, data, runCounter); + runCounter++; + } + } + } + + // nonMusr + size = runList->GetNoOfNonMusr(); + if (size > 0) { + for (unsigned int i=0; iGetNonMusr(i); + if (data) { + // dump data + musrfit_write_ascii(fln, data, runCounter); + runCounter++; + } + } + } +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param f + * \param fln + * \param data + * \param runCounter + */ +void musrfit_write_root(TFile &f, TString fln, PRunData *data, int runCounter) +{ + char name[128]; + + TString title = fln.Copy(); + sprintf(name, "_%d", runCounter); + title.ReplaceAll(".root", name); + + sprintf(name, "c%d", runCounter); + + TCanvas *c = new TCanvas(name, title.Data(), 10, 10, 800, 600); + + // create histos + Double_t diff = data->fTime[1]-data->fTime[0]; + Double_t start = -diff/2.0; + Double_t end = data->fTime[data->fTime.size()-1]+diff/2.0; + TH1F *hdata = new TH1F("hdata", "run data", data->fTime.size(), start, end); + TH1F *htheo = new TH1F("htheo", "run theory", data->fTime.size(), start, end); + + // fill data + for (unsigned int i=0; ifTime.size(); i++) { + hdata->SetBinContent(i, data->fValue[i]); + hdata->SetBinError(i, data->fError[i]); + htheo->SetBinContent(i, data->fTheory[i]); + } + + hdata->SetMarkerStyle(20); + hdata->Draw("*H HIST E1"); + + htheo->SetLineColor(2); + htheo->SetLineWidth(3); + htheo->Draw("C SAME"); + + f.WriteTObject(c); + + // clean up + if (hdata) { + delete hdata; + hdata = 0; + } + if (htheo) { + delete htheo; + htheo = 0; + } + if (c) { + delete c; + c = 0; + } +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param fileName + */ +void musrfit_dump_root(char *fileName, PRunListCollection *runList) +{ + TString fln(fileName); + fln.ReplaceAll(".msr", ".root"); + + TFile f(fln.Data(), "recreate"); + + // go through the run list, get the data and dump it in a file + + int runCounter = 0; + + // single histos + unsigned int size = runList->GetNoOfSingleHisto(); + PRunData *data; + if (size > 0) { + for (unsigned int i=0; iGetSingleHisto(i); + if (data) { + // dump data + musrfit_write_root(f, fln, data, runCounter); + runCounter++; + } + } + } + + // asymmetry + size = runList->GetNoOfAsymmetry(); + if (size > 0) { + for (unsigned int i=0; iGetAsymmetry(i); + if (data) { + // dump data + musrfit_write_root(f, fln, data, runCounter); + runCounter++; + } + } + } + + // rrf + size = runList->GetNoOfRRF(); + if (size > 0) { + for (unsigned int i=0; iGetRRF(i); + if (data) { + // dump data + musrfit_write_root(f, fln, data, runCounter); + runCounter++; + } + } + } + + // nonMusr + size = runList->GetNoOfNonMusr(); + if (size > 0) { + for (unsigned int i=0; iGetNonMusr(i); + if (data) { + // dump data + musrfit_write_root(f, fln, data, runCounter); + runCounter++; + } + } + } +} + +//-------------------------------------------------------------------------- +int main(int argc, char *argv[]) +{ + bool show_syntax = false; + int status; + bool debug = false; + TString dump(""); + + // check syntax + if (argc == 2) { + if (!strcmp(argv[1], "--version")) { + cout << endl << "msrfit version: $Id$"; + cout << endl << endl; + return PMUSR_SUCCESS; + } else if (!strcmp(argv[1], "--help")) { + show_syntax = true; + } else { // assume file name + // check if filename has extension msr + if (!strstr(argv[1], ".msr")) { + cout << endl << "ERROR: " << argv[1] << " is not a msr-file!" << endl; + show_syntax = true; + } else { + show_syntax = false; + } + } + } else if (argc == 3) { + if (!strcmp(argv[2], "--debug")) + debug = true; + else + show_syntax = true; + } else if (argc == 4) { + if (!strcmp(argv[2], "--dump")) + dump = TString(argv[3]); + else + show_syntax = true; + } else { + show_syntax = true; + } + + if (show_syntax) { + musrfit_syntax(); + return PMUSR_WRONG_STARTUP_SYNTAX; + } + + // read startup file + PStartupHandler *startupHandler = new PStartupHandler(); + + // read msr-file + PMsrHandler *msrHandler = new PMsrHandler(argv[1]); + status = msrHandler->ReadMsrFile(); + if (status != PMUSR_SUCCESS) { + switch (status) { + case PMUSR_MSR_FILE_NOT_FOUND: + cout << endl << "couldn't find " << argv[1] << endl << endl; + break; + case PMUSR_MSR_SYNTAX_ERROR: + cout << endl << "syntax error in file " << argv[1] << ", full stop here." << endl << endl; + default: + cout << endl << "unkown error when trying to read the msr-file" << endl << endl; + break; + } + return status; + } + + if (debug) + musrfit_debug_info(msrHandler); + + // read all the necessary runs (raw data) + PRunDataHandler *dataHandler = new PRunDataHandler(msrHandler); + bool success = dataHandler->IsAllDataAvailable(); + if (!success) { + cout << endl << "Couldn't read all data files, will quit ..." << endl; + } + + // generate the necessary fit histogramms for the fit + PRunListCollection *runListCollection = 0; + if (success) { + // feed all the necessary histogramms for the fit + runListCollection = new PRunListCollection(msrHandler, dataHandler); + for (unsigned int i=0; i < msrHandler->GetMsrRunList()->size(); i++) { + success = runListCollection->Add(i); + if (!success) { + cout << endl << "Couldn't handle run no " << i << " "; + cout << (*msrHandler->GetMsrRunList())[i].fRunName.Data(); + break; + } + } + } + + // do fitting + PFitter *fitter = 0; + if (success) { + fitter = new PFitter(msrHandler, runListCollection); + success = fitter->IsValid(); + if (success) + fitter->DoFit(); + } + + // write log file + if (success) { + status = msrHandler->WriteMsrLogFile(); + if (status != PMUSR_SUCCESS) { + switch (status) { + case PMUSR_MSR_LOG_FILE_WRITE_ERROR: + cout << endl << "couldn't write mlog-file" << endl << endl; + break; + case PMUSR_TOKENIZE_ERROR: + cout << endl << "couldn't generate mlog-file name" << endl << endl; + break; + default: + cout << endl << "unkown error when trying to write the mlog-file" << endl << endl; + break; + } + } + } + + // check if dump is wanted + if (success && !dump.IsNull()) { + cout << endl << "will write dump file ..." << endl; + dump.ToLower(); + if (dump.Contains("ascii")) + musrfit_dump_ascii(argv[1], runListCollection); + else if (dump.Contains("root")) + musrfit_dump_root(argv[1], runListCollection); + else + cout << endl << "do not know format " << dump.Data() << ", sorry :-| " << endl; + } + + // clean up + if (startupHandler) { + delete startupHandler; + startupHandler = 0; + } + if (msrHandler) { + delete msrHandler; + msrHandler = 0; + } + if (dataHandler) { + delete dataHandler; + dataHandler = 0; + } + if (runListCollection) { + delete runListCollection; + runListCollection = 0; + } + if (fitter) { + delete fitter; + fitter = 0; + } + +cout << endl << "done ..." << endl; + + return PMUSR_SUCCESS; +} + +// end --------------------------------------------------------------------- + diff --git a/src/musrfit.pro b/src/musrfit.pro new file mode 100644 index 00000000..17c58457 --- /dev/null +++ b/src/musrfit.pro @@ -0,0 +1,25 @@ +#------------------------------------------------------ +# musrfit.pro +# qmake file for musrfit +# +# Andreas Suter, 2007/05/14 +# +# $Id$ +# +#------------------------------------------------------ + +MAKEFILE = Makefile.musrfit + +CONFIG += warn_on debug + +SOURCES = musrfit.cpp \ + +INCLUDEPATH += $$(ROOTSYS)/include +INCLUDEPATH += ./include + +PSILIBS = -lTLemRunHeader -lPMusr +ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs) +unix:LIBS += $${PSILIBS} +unix:LIBS += $${ROOTLIBS} + +TARGET=musrfit diff --git a/src/tests/fio_test/fio_test.cpp b/src/tests/fio_test/fio_test.cpp new file mode 100644 index 00000000..6e5a8bde --- /dev/null +++ b/src/tests/fio_test/fio_test.cpp @@ -0,0 +1,32 @@ +#include +using namespace std; + +int main() +{ + ofstream f; + + // open mlog-file + f.open("fio_test.txt", iostream::out); + if (!f.is_open()) { + return -1; + } + + const int prec=6; + double val = 0.258466548916354835498465; + + f.width(9); + f.precision(prec); + f << left << val; + f << " "; + f.width(9); + f.precision(prec); + f << left << val; + f << " "; + f.width(9); + f.precision(prec); + f << left << val; + + f.close(); + + return 0; +} diff --git a/src/tests/fio_test/fio_test.pro b/src/tests/fio_test/fio_test.pro new file mode 100644 index 00000000..67b93147 --- /dev/null +++ b/src/tests/fio_test/fio_test.pro @@ -0,0 +1,17 @@ +#------------------------------------------------------ +# fio_test.pro +# qmake file for fio_test +# +# Andreas Suter, 2007/05/14 +# +# $Id$ +# +#------------------------------------------------------ + +MAKEFILE = Makefile + +CONFIG += warn_on debug + +SOURCES = fio_test.cpp + +TARGET=fio_test diff --git a/src/tests/fio_test/fio_test.txt b/src/tests/fio_test/fio_test.txt new file mode 100644 index 00000000..d1403634 --- /dev/null +++ b/src/tests/fio_test/fio_test.txt @@ -0,0 +1 @@ +0.258467 0.258467 0.258467 \ No newline at end of file diff --git a/src/tests/minuit2example/PGlobalChiSquare.cpp b/src/tests/minuit2example/PGlobalChiSquare.cpp new file mode 100644 index 00000000..262aabb6 --- /dev/null +++ b/src/tests/minuit2example/PGlobalChiSquare.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** + + PGlobalChiSquare.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.ch * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include + +#include + +#include "PGlobalChiSquare.h" + +namespace ROOT { + namespace Minuit2 { + +//-------------------------------------------------------------------------- +/** + *

+ */ +PGlobalChiSquare::PGlobalChiSquare(PRunList &runList) +{ + fRunList = runList; +} + +//-------------------------------------------------------------------------- +/** + *

+ */ +PGlobalChiSquare::~PGlobalChiSquare() +{ +} + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param par + */ +double PGlobalChiSquare::operator()(const std::vector& par) const +{ + double chi2 = 0.0; + double funcValue; + double diff; + + // calculate chi2 for the given model + for (unsigned int i=0; i + +#include "Minuit2/FCNBase.h" + +#include "mn2test.h" + +namespace ROOT { + namespace Minuit2 { + +class PGlobalChiSquare : public FCNBase +{ + + public: + PGlobalChiSquare(PRunList &runList); + ~PGlobalChiSquare(); + + double Up() const { return 1.0; } + double operator()(const std::vector&) const; + + private: + PRunList fRunList; + +}; + + } // namespace Minuit2 +} // namespace ROOT + +#endif // _PGLOBALCHISQUARE_H_ diff --git a/src/tests/minuit2example/mn2test.cpp b/src/tests/minuit2example/mn2test.cpp new file mode 100644 index 00000000..40d39507 --- /dev/null +++ b/src/tests/minuit2example/mn2test.cpp @@ -0,0 +1,157 @@ +/*************************************************************************** + + mn2test.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.ch * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include + +#include +#include + +#include "Minuit2/FunctionMinimum.h" +#include "Minuit2/MnUserParameters.h" +#include "Minuit2/MnMinimize.h" +#include "Minuit2/MnMinos.h" + +#include "PGlobalChiSquare.h" + +#include "mn2test.h" + +using namespace ROOT::Minuit2; + +//---------------------------------------------------------------------------- +/** + *

generates data for testing + * model = ampl * exp(-lambda * t), where ampl is depending on the run, but + * not lambda + */ +void generateData(PRunList &data) +{ + PRun run; + const unsigned int length = 100; + double value; + + for (unsigned int i=0; i<2; i++) { // run loop + for (unsigned int j=0; j + +typedef struct { + std::vector fTime; + std::vector fValue; + std::vector fError; +} PRun; + +typedef std::vector PRunList; + +#endif // _MN2TEST_H_ diff --git a/src/tests/minuit2example/mn2test.pro b/src/tests/minuit2example/mn2test.pro new file mode 100644 index 00000000..e26a3bc3 --- /dev/null +++ b/src/tests/minuit2example/mn2test.pro @@ -0,0 +1,26 @@ +#------------------------------------------------------ +# mn2test.pro +# qmake file for mn2test +# +# Andreas Suter, 2007/10/23 +# +# $Id$ +# +#------------------------------------------------------ + +MAKEFILE = Makefile.mn2test + +CONFIG += warn_on debug + +HEADERS = PGlobalChiSquare.h + +SOURCES = mn2test.cpp \ + PGlobalChiSquare.cpp + +INCLUDEPATH += /usr/local/include +INCLUDEPATH += ./ + +unix:LIBS += -L/usr/local/lib -lMinuit2Base -lbsd -lm -ldl -lutil + +TARGET=mn2test + diff --git a/src/tests/nanTest/nanTest.cpp b/src/tests/nanTest/nanTest.cpp new file mode 100644 index 00000000..e2563036 --- /dev/null +++ b/src/tests/nanTest/nanTest.cpp @@ -0,0 +1,22 @@ +#include + +#include +using namespace std; + +int main() +{ + double value; + + value = nan("NAN"); + + if (isnan(value)) + cout << endl << "value is not a number"; + else + cout << endl << "value is a number"; + + cout << endl << "value = " << value; + + cout << endl << "done ..." << endl; + + return 0; +} diff --git a/src/tests/nanTest/nanTest.pro b/src/tests/nanTest/nanTest.pro new file mode 100644 index 00000000..4d66876f --- /dev/null +++ b/src/tests/nanTest/nanTest.pro @@ -0,0 +1,17 @@ +#------------------------------------------------------ +# nanTest.pro +# qmake file for nanTest +# +# Andreas Suter, 2007/05/14 +# +# $Id$ +# +#------------------------------------------------------ + +MAKEFILE = Makefile + +CONFIG += warn_on debug + +SOURCES = nanTest.cpp + +TARGET=nanTest diff --git a/src/tests/nemuRootFileRead/nemuRootFileRead.cpp b/src/tests/nemuRootFileRead/nemuRootFileRead.cpp new file mode 100644 index 00000000..ee7312ce --- /dev/null +++ b/src/tests/nemuRootFileRead/nemuRootFileRead.cpp @@ -0,0 +1,110 @@ +#include +using namespace std; + +#include +#include +#include +#include +#include + +#include "TLemRunHeader.h" + +int main(int argc, char *argv[]) +{ + if (argc != 2) { + cout << endl; + cout << "SYNTAX: nemuRootFileRead PathFileName"; + cout << endl; + return 1; + } + + TROOT root("nemuRootFileRead", "nemuRootFileRead", 0); + + // get file name + char *str = gSystem->ExpandPathName(argv[1]); + + // check that the file name exists + if (gSystem->AccessPathName(str)==true) { + cout << endl << "file " << str << " doesn't exist :-(" << endl; + cout << endl << "will quit now ..." << endl; + return 1; + } + + // define file + TFile f(str); + if (f.IsZombie()) { + cout << endl << "couldn't open file " << str << endl; + cout << endl << "will quit now ..." << endl; + return 1; + } + + cout << endl << "opened file " << str; + + // get RunInfo Folder + TFolder *folder = 0; + f.GetObject("RunInfo", folder); + + // check if RunInfo Folder is valid + if (!folder) { + cout << endl << "Couldn't obtain RunInfo folder from ROOT file " << str; + cout << endl << "will quit now ..." << endl; + return 1; + } + + // get run header + TLemRunHeader *runHeader = dynamic_cast(folder->FindObjectAny("TLemRunHeader")); + + // check if run header is valid + if (!runHeader) { + cout << endl << "Couldn't obtain run header info from ROOT file " << str; + cout << endl << "will quit now ..." << endl; + return 1; + } + + cout << endl << "Run No : " << runHeader->GetRunNumber(); + cout << endl << "Run Title: " << runHeader->GetRunTitle().GetString().Data(); + + // get histos folder + f.GetObject("histos", folder); + + // check if histos Folder is valid + if (!folder) { + cout << endl << "Couldn't obtain histos folder from ROOT file " << str; + cout << endl << "will quit now ..." << endl; + return 1; + } + + // get histo hDecay00 + TH1F *histo = dynamic_cast(folder->FindObject("DecayAnaModule/hDecay00")); + + // check if histo hDecay00 was found + if (!histo) { + cout << endl << "Couldn't obtain hDecay00 histo from ROOT file " << str; + cout << endl << "will quit now ..." << endl; + return 1; + } + + // print out first 10 values of hDecay00 and some other info + cout << endl << "hDecay00: No of Bins: " << histo->GetNbinsX(); + int max; + if (max > histo->GetNbinsX()) + max = histo->GetNbinsX(); + else + max = 10; + cout << endl << "hDecay00: Data:"; + for (int i=0; iGetBinContent(i+1); + } + + if (f.IsOpen()) + f.Close(); + + cout << endl << "closed file .." << endl; + + if (str) + delete str; + + cout << endl; + + return 0; +} diff --git a/src/tests/nemuRootFileRead/nemuRootFileRead.pro b/src/tests/nemuRootFileRead/nemuRootFileRead.pro new file mode 100644 index 00000000..6f3d24c2 --- /dev/null +++ b/src/tests/nemuRootFileRead/nemuRootFileRead.pro @@ -0,0 +1,23 @@ +#------------------------------------------------------ +# nemuRootFileRead.pro +# qmake file for rootSystemTest +# +# Andreas Suter, 2007/05/14 +# +# $Id$ +# +#------------------------------------------------------ + +MAKEFILE = Makefile + +CONFIG += warn_on debug + +SOURCES = nemuRootFileRead.cpp \ + +INCLUDEPATH += $$(ROOTSYS)/include + +ROOTLIBS = -lCore -lCint -lRIO -lGraf -lGraf3d -lGpad -lHist -lMatrix -lMinuit -lGui +NEMULIBS = -lTLemRunHeader +unix:LIBS += -L$$(ROOTSYS)/lib $${ROOTLIBS} $${NEMULIBS} -lbsd -lm -ldl -lutil + +TARGET=nemuRootFileRead diff --git a/src/tests/root2DHisto/root2DHisto.C b/src/tests/root2DHisto/root2DHisto.C new file mode 100644 index 00000000..b7d9ac42 --- /dev/null +++ b/src/tests/root2DHisto/root2DHisto.C @@ -0,0 +1,24 @@ +{ + gStyle->SetOptStat(000000000); + + TCanvas *cov = new TCanvas("cov", "Minuit2 Output Covariance Matrix", 500, 500); + + TH2D *f = new TH2D("f", "Minuit2 Output Covariance Matrix", 16, 0.0, 16.0, 16, 0.0, 16.0); + + double x, y, z; + + for (unsigned int i=0; i<16; i++) { + for (unsigned int j=0; j<16; j++) { + x = (double)i; + y = (double)j; + z = x/16.0-y/16.0+(x-8.0)*(y-8.0)/(8.0*8.0); + f->Fill(x,y,z); + } + } + + TFile ff("test.root", "recreate"); + cov->Draw(); + f->Draw("COLZ"); + cov->Write(); + ff.Close(); +} \ No newline at end of file diff --git a/src/tests/rootFiles/histoWithErrors.C b/src/tests/rootFiles/histoWithErrors.C new file mode 100644 index 00000000..3ca1563f --- /dev/null +++ b/src/tests/rootFiles/histoWithErrors.C @@ -0,0 +1,30 @@ +{ + TFile f("test.root", "recreate"); + + // make a histo with errors + TH1F *h = new TH1F("h", "histo test", 20, -0.05, 1.05); + TH1F *hc = new TH1F("hc", "curve", 20, -0.05, 1.05); + for (unsigned int i=0; i<20; i++) { + x = (double)i/20.0; + value = TMath::Sqrt(1.5*x+0.1*TMath::Power(x,3.0)-0.4*TMath::Power(x,5.0)); + hc->SetBinContent(i, value+0.1*TMath::Sqrt(value)-value*value); + h->SetBinContent(i, value); + h->SetBinError(i, TMath::Power(value, 5.0)); + } + + TCanvas *c1 = new TCanvas("c1", "my Canvas c1", 10, 10, 800, 600); + + h->SetMarkerStyle(20); + h->Draw("*H HIST E1"); + + hc->SetLineColor(2); + hc->SetLineWidth(3); + hc->Draw("C SAME"); + + TCanvas *c2 = new TCanvas("c2", "my Canvas c2", 10, 10, 800, 600); + h->SetMarkerStyle(23); + h->Draw("*H HIST E1"); + + f.WriteTObject(c1); + f.WriteTObject(c2); +} diff --git a/src/tests/rootMinuit2Test/minuit2test.C b/src/tests/rootMinuit2Test/minuit2test.C new file mode 100644 index 00000000..bbeaa56e --- /dev/null +++ b/src/tests/rootMinuit2Test/minuit2test.C @@ -0,0 +1,105 @@ +/******************************************************************* + minuit2test.C + + author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ +********************************************************************/ + +#include + +#include +#include +#include +#include +#include + +const double gGammaMu = TMath::TwoPi()*0.01355; +const double gTauMu = 2.19705; // in (us) + +TF1 *gFitFcn; + +//------------------------------------------------------------------ +/** + *

Background (flat for the moment) + * + * \param x + * \param par par[0] is the background + */ +Double_t Background(Double_t *x, Double_t *par) +{ + return par[0]; +} + +//------------------------------------------------------------------ +/** + *

Asymmetry + * + * \param x + * \param par par[0] = asymmetry + * par[1] = lambda + * par[2] = B + * par[3] = phase + */ +Double_t Asymmetry(Double_t *x, Double_t *par) +{ + return par[0]*TMath::Exp(-par[1]*x[0])*TMath::Cos(gGammaMu*par[2]*x[0]+par[3]/180.0*TMath::Pi()); +} + +//------------------------------------------------------------------ +/** + *

Spectrum + * + * \param x + * \param par + */ +Double_t Spectrum(Double_t *x, Double_t *par) +{ + return par[0]*TMath::Exp(-x[0]/gTauMu)*(1.0 + Asymmetry(x,&par[1])) + Background(x,&par[5]); +} + +//------------------------------------------------------------------ +/** + *

minuit2test + * + * \param x + * \param par + */ +void minuit2test() +{ + TH1::AddDirectory(kFALSE); + TCanvas *c1 = new TCanvas("c1","Fitting Test",10,10,500,500); + + // create a TF1 with the range from 0.0 to 12.0 and 6 parameters + gFitFcn = new TF1("gFitFcn", Spectrum, 0.0, 12.0, 6); + gFitFcn->SetNpx(1200); + + // set parameters + gFitFcn->SetParNames("N0", "asym", "lambda", "B", "phase", "Bkg"); + gFitFcn->SetParameter(0, 30.0); // N0 +// gFitFcn->SetParLimits(0, 0.0, 1.0e6); + gFitFcn->SetParameter(1, 0.11); // asym +// gFitFcn->SetParLimits(1, 0.0, 0.33); + gFitFcn->SetParameter(2, 0.3); // lambda +// gFitFcn->SetParLimits(2, 0.0, 100.0); + gFitFcn->SetParameter(3, 100.0); // B +// gFitFcn->SetParLimits(3, 0.0, 1000.0); + gFitFcn->SetParameter(4, 0.0); // phase +// gFitFcn->SetParLimits(4, -90.0, 90.0); + gFitFcn->SetParameter(5, 5.0); // Bkg +// gFitFcn->SetParLimits(5, 0.0, 1000.0); + + cout << endl << "gFitFcn->Integral(0.0, 12.0) = " << gFitFcn->Integral(0.0, 12.0); + cout << endl; + + // fill histo + TH1F *histo = new TH1F("histo","Minuit2 Test",1200,0.0,12.0); + histo->FillRandom("gFitFcn", 100*(int)gFitFcn->Integral(0.0, 12.0)); + histo->Rebin(5); + + histo->Draw(); + + TVirtualFitter::SetDefaultFitter("Minuit2"); + histo->Fit("gFitFcn", "LE"); // L->likleyhood, E->minos +} diff --git a/src/tests/rootSystemTest/.kdbgrc.rootSystemTest b/src/tests/rootSystemTest/.kdbgrc.rootSystemTest new file mode 100755 index 00000000..e69de29b diff --git a/src/tests/rootSystemTest/rootSystemTest.cpp b/src/tests/rootSystemTest/rootSystemTest.cpp new file mode 100644 index 00000000..e80b89cd --- /dev/null +++ b/src/tests/rootSystemTest/rootSystemTest.cpp @@ -0,0 +1,35 @@ +#include +using namespace std; + +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc != 2) { + cout << endl; + cout << "SYNTAX: rootSystemTest PathFileName"; + cout << endl; + return 1; + } + + TROOT root("rootSystemTest", "rootSystemTest", 0); + + cout << endl; + cout << "Path name: " << argv[1] << endl; + char *str = gSystem->ExpandPathName(argv[1]); + cout << "Path name expanded: " << str << endl; + + if (gSystem->AccessPathName(str)==true) { + cout << endl << "file " << str << " doesn't exist :-(" << endl; + } else { + cout << endl << "file " << str << " exists :-)" << endl; + } + + cout << "done ..." << endl; + + if (str) + delete str; + + return 0; +} diff --git a/src/tests/rootSystemTest/rootSystemTest.pro b/src/tests/rootSystemTest/rootSystemTest.pro new file mode 100644 index 00000000..68cf639b --- /dev/null +++ b/src/tests/rootSystemTest/rootSystemTest.pro @@ -0,0 +1,22 @@ +#------------------------------------------------------ +# rootSystemTest.pro +# qmake file for rootSystemTest +# +# Andreas Suter, 2007/05/14 +# +# $Id$ +# +#------------------------------------------------------ + +MAKEFILE = Makefile + +CONFIG += warn_on debug + +SOURCES = rootSystemTest.cpp \ + +INCLUDEPATH += $$(ROOTSYS)/include + +ROOTLIBS = -lCore -lCint +unix:LIBS += -L$$(ROOTSYS)/lib $${ROOTLIBS} -lbsd -lm -ldl -lutil + +TARGET=rootSystemTest diff --git a/src/tests/spirit/.kdbgrc.spirit_fcn_test b/src/tests/spirit/.kdbgrc.spirit_fcn_test new file mode 100755 index 00000000..e69de29b diff --git a/src/tests/spirit/PFunction.cpp b/src/tests/spirit/PFunction.cpp new file mode 100644 index 00000000..8e1d4e68 --- /dev/null +++ b/src/tests/spirit/PFunction.cpp @@ -0,0 +1,620 @@ +/*************************************************************************** + + PFunction.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include + +#include +using namespace std; + +#include "PFunction.h" + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

+ * + * info is an abstract syntax tree (AST) generate by the spirit parse library + * (see http://spirit.sourceforge.net/distrib/spirit_1_8_5/libs/spirit/doc/trees.html). + * It contains a single parsed msr-function in an ascii representation. + * Here it takes the from + * assignment (root node) + * |_ 'FUNx' + * |_ '=' + * |_ expression + * |_ ... + * + * Since it would be inefficient to evaluate this AST directly it is transferred to + * a more efficient tree fFuncs here in the constructor. + * + * \param info AST parse tree holding a single parsed msr-function in an ascii representation + * \param param the parameter vector + * \param map the map vector + */ +PFunction::PFunction(tree_parse_info<> info, vector param, vector map) +{ + cout << endl << "in PFunction ..."; + + fInfo = info; + fParam = param; + fMap = map; + + // init class variables + fValid = true; + fFuncNo = -1; + + // check parameter and map range + if (!CheckParameterAndMapRange()) { + fValid = false; + return; + } + + // generate function evaluation tree + if (!GenerateFuncEvalTree()) { + fValid = false; + return; + } + + EvaluateTree(info); + + cout << endl << "fFuncString: '" << fFuncString << "'"; + cout << endl; +} + +//-------------------------------------------------------------------------- +// Destructor +//-------------------------------------------------------------------------- +/** + *

+ */ +PFunction::~PFunction() +{ +// cout << endl << "in ~PFunction ..."; + fParam.clear(); + fMap.clear(); + + CleanupFuncEvalTree(); +} + +//------------------------------------------------------------- +// CheckParameterRange (protected) +//------------------------------------------------------------- +/** + *

+ * + */ +bool PFunction::CheckParameterAndMapRange() +{ + return CheckParameterAndMapInTree(fInfo.trees.begin()); +} + +//------------------------------------------------------------- +// CheckParameterAndMapInTree (protected) +//------------------------------------------------------------- +/** + *

walk through the tree and check if the parameter found + * are within a valid range given by the size of fParam. + * + * \param i + */ +bool PFunction::CheckParameterAndMapInTree(iter_t const& i) +{ + bool success = true; + int value; + + if (i->value.id() == PFunctionGrammar::funLabelID) { + assert(i->children.size() == 0); + SetFuncNo(i); + } else if (i->value.id() == PFunctionGrammar::parameterID) { + assert(i->children.size() == 0); + string str(i->value.begin(), i->value.end()); + cout << endl << "parameterID: value = " << str << endl; + sscanf(str.c_str(), "PAR%d", &value); +//cout << endl << ">> value = " << value << ", fParam.size() = " << fParam.size(); + if (value > (int)fParam.size()) { // parameter number found > number of parameters + cout << endl << "**ERROR**: found parameter " << str << " with only " << fParam.size() << " parameters present?!?"; + fValid = false; + } + } else if (i->value.id() == PFunctionGrammar::mapID) { + assert(i->children.size() == 0); + string str(i->value.begin(), i->value.end()); + cout << endl << "mapID: value = " << str << endl; + sscanf(str.c_str(), "MAP%d", &value); +//cout << endl << ">> value = " << value << ", fParam.size() = " << fParam.size(); + if (value > (int)fMap.size()) { // parameter number found > number of parameters + cout << endl << "**ERROR**: found map " << str << " with only " << fMap.size() << " maps present?!?"; + fValid = false; + } + } else if (i->value.id() == PFunctionGrammar::functionID) { +cout << endl << "children = " << i->children.size() << endl; + assert(i->children.size() == 4); + // i: 'funcName', '(', 'expression', ')' + success = CheckParameterAndMapInTree(i->children.begin()+2); // thats the real stuff + } else if (i->value.id() == PFunctionGrammar::factorID) { + // i: real | parameter | map | function | expression + assert(i->children.size() == 1); + success = CheckParameterAndMapInTree(i->children.begin()); + } else if (i->value.id() == PFunctionGrammar::termID) { + // '*'/'/' i: lhs, rhs + assert(i->children.size() == 2); + success = CheckParameterAndMapInTree(i->children.begin()); + success = CheckParameterAndMapInTree(i->children.begin()+1); + } else if (i->value.id() == PFunctionGrammar::expressionID) { + // '+'/'-' i: lhs, rhs + assert(i->children.size() == 2); + success = CheckParameterAndMapInTree(i->children.begin()); + success = CheckParameterAndMapInTree(i->children.begin()+1); + } else if (i->value.id() == PFunctionGrammar::assignmentID) { + // i: 'FUNx', '=', 'expression' + assert(i->children.size() == 3); + success = CheckParameterAndMapInTree(i->children.begin()); // FUNx + success = CheckParameterAndMapInTree(i->children.begin()+2); // this is the real stuff + } + + return success; +} + +//------------------------------------------------------------- +// SetFuncNo (protected) +//------------------------------------------------------------- +/** + *

+ * + * \param i + */ +bool PFunction::SetFuncNo(iter_t const& i) +{ + int funNo = -1; + int status; + bool success = true; + + // get string from tree + string str(i->value.begin(), i->value.end()); + + // extract function number from string + status = sscanf(str.c_str(), "FUN%d", &funNo); +//cout << endl << "SetFuncNo: status = " << status << ", funNo = " << funNo; + if (status == 1) { // found 1 int + fFuncNo = funNo; + } else { // wrong string + success = false; + } + + return success; +} + +//------------------------------------------------------------- +// GenerateFuncEvalTree (protected) +//------------------------------------------------------------- +/** + *

+ * + */ +bool PFunction::GenerateFuncEvalTree() +{ + FillFuncEvalTree(fInfo.trees.begin(), fFunc); + + return true; +} + +//------------------------------------------------------------- +// FillFuncEvalTree (protected) +//------------------------------------------------------------- +/** + *

+ * + */ +void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) +{ + double dvalue; + int ivalue; + int status; + string str; + PFuncTreeNode child; + + if (i->value.id() == PFunctionGrammar::realID) { // handle number + str = string(i->value.begin(), i->value.end()); // get string + status = sscanf(str.c_str(), "%lf", &dvalue); // convert string to double + node.fID = PFunctionGrammar::realID; // keep the ID + node.fDvalue = dvalue; // keep the value +// cout << endl << ">> realID: value = " << dvalue; + } else if (i->value.id() == PFunctionGrammar::parameterID) { // handle parameter number + str = string(i->value.begin(), i->value.end()); // get string + status = sscanf(str.c_str(), "PAR%d", &ivalue); // convert string to parameter number + node.fID = PFunctionGrammar::parameterID; // keep the ID + node.fIvalue = ivalue; // keep the value +// cout << endl << ">> parameterID: value = " << ivalue; + } else if (i->value.id() == PFunctionGrammar::mapID) { // handle map number + str = string(i->value.begin(), i->value.end()); // get string + status = sscanf(str.c_str(), "MAP%d", &ivalue); // convert string to map number + node.fID = PFunctionGrammar::mapID; // keep the ID + node.fIvalue = ivalue; // keep the value +// cout << endl << ">> mapID: value = " << ivalue; + } else if (i->value.id() == PFunctionGrammar::functionID) { // handle function like cos ... + // keep the id + node.fID = PFunctionGrammar::functionID; + // keep function tag + // i: 'funcName', '(', 'expression', ')' + iter_t it = i->children.begin(); + str = string(it->value.begin(), it->value.end()); // get string +// cout << endl << ">> functionID: value = " << str; + if (!strcmp(str.c_str(), "COS")) + node.fFunctionTag = FUN_COS; + else if (!strcmp(str.c_str(), "SIN")) + node.fFunctionTag = FUN_SIN; + else if (!strcmp(str.c_str(), "TAN")) + node.fFunctionTag = FUN_TAN; + else if (!strcmp(str.c_str(), "COSH")) + node.fFunctionTag = FUN_COSH; + else if (!strcmp(str.c_str(), "SINH")) + node.fFunctionTag = FUN_SINH; + else if (!strcmp(str.c_str(), "TANH")) + node.fFunctionTag = FUN_TANH; + else if (!strcmp(str.c_str(), "ACOS")) + node.fFunctionTag = FUN_ACOS; + else if (!strcmp(str.c_str(), "ASIN")) + node.fFunctionTag = FUN_ASIN; + else if (!strcmp(str.c_str(), "ATAN")) + node.fFunctionTag = FUN_ATAN; + else if (!strcmp(str.c_str(), "ACOSH")) + node.fFunctionTag = FUN_ACOSH; + else if (!strcmp(str.c_str(), "ASINH")) + node.fFunctionTag = FUN_ASINH; + else if (!strcmp(str.c_str(), "ATANH")) + node.fFunctionTag = FUN_ATANH; + else if (!strcmp(str.c_str(), "LOG")) + node.fFunctionTag = FUN_LOG; + else if (!strcmp(str.c_str(), "LN")) + node.fFunctionTag = FUN_LN; + else if (!strcmp(str.c_str(), "EXP")) + node.fFunctionTag = FUN_EXP; + else { + cout << endl << "**PANIC ERROR**: function " << str << " doesn't exist, but you never should have reached this point!"; + assert(0); + } + // add node + node.children.push_back(child); + // i: 'funcName', '(', 'expression', ')' + FillFuncEvalTree(i->children.begin()+2, node.children[0]); + } else if (i->value.id() == PFunctionGrammar::factorID) { +// cout << endl << ">> factorID"; + // keep the id + node.fID = PFunctionGrammar::factorID; + // add child lhs + node.children.push_back(child); + FillFuncEvalTree(i->children.begin(), node.children[0]); + } else if (i->value.id() == PFunctionGrammar::termID) { + // keep the id + node.fID = PFunctionGrammar::termID; + // keep operator tag + if (*i->value.begin() == '*') + node.fOperatorTag = OP_MUL; + else + node.fOperatorTag = OP_DIV; +/* +if (node.fOperatorTag == OP_MUL) + cout << endl << ">> termID: value = *"; +else + cout << endl << ">> termID: value = /"; +*/ + // add child lhs + node.children.push_back(child); + FillFuncEvalTree(i->children.begin(), node.children[0]); + // add child rhs + node.children.push_back(child); + FillFuncEvalTree(i->children.begin()+1, node.children[1]); + } else if (i->value.id() == PFunctionGrammar::expressionID) { // handle expression + // keep the id + node.fID = PFunctionGrammar::expressionID; + // keep operator tag + if (*i->value.begin() == '+') + node.fOperatorTag = OP_ADD; + else + node.fOperatorTag = OP_SUB; +/* +if (node.fOperatorTag == OP_ADD) + cout << endl << ">> expressionID: value = +"; +else + cout << endl << ">> expressionID: value = -"; +*/ + // add child lhs + node.children.push_back(child); + FillFuncEvalTree(i->children.begin(), node.children[0]); + // add child rhs + node.children.push_back(child); + FillFuncEvalTree(i->children.begin()+1, node.children[1]); + } else if (i->value.id() == PFunctionGrammar::assignmentID) { + // nothing to be done except to pass the next element in the ast + // i: 'funx', '=', 'expression' + FillFuncEvalTree(i->children.begin()+2, node); + } +} + +//------------------------------------------------------------- +// Eval (public) +//------------------------------------------------------------- +/** + *

+ * + */ +double PFunction::Eval() +{ + return EvalNode(fFunc); +} + +//------------------------------------------------------------- +// EvalNode (protected) +//------------------------------------------------------------- +/** + *

+ * + * \param node + */ +double PFunction::EvalNode(PFuncTreeNode &node) +{ + if (node.fID == PFunctionGrammar::realID) { + return node.fDvalue; + } else if (node.fID == PFunctionGrammar::parameterID) { + return fParam[node.fIvalue-1]; + } else if (node.fID == PFunctionGrammar::mapID) { + return fParam[fMap[node.fIvalue-1]-1]; + } else if (node.fID == PFunctionGrammar::functionID) { + if (node.fFunctionTag == FUN_COS) { + return cos(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_SIN) { + return sin(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_TAN) { + return tan(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_COSH) { + return cosh(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_SINH) { + return sinh(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_TANH) { + return tanh(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_ACOS) { + return acos(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_ASIN) { + return asin(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_ATAN) { + return atan(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_ACOSH) { + return acosh(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_ASINH) { + return asinh(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_ATANH) { + return atanh(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_LOG) { + return log(EvalNode(node.children[0]))/log(10); + } else if (node.fFunctionTag == FUN_LN) { + return log(EvalNode(node.children[0])); + } else if (node.fFunctionTag == FUN_EXP) { + return exp(EvalNode(node.children[0])); + } else { + cout << endl << "**PANIC ERROR**: PFunction::EvalNode: node.fID == PFunctionGrammar::functionID: you never should have reached this point!" << endl; + assert(0); + } + } else if (node.fID == PFunctionGrammar::factorID) { + return EvalNode(node.children[0]); + } else if (node.fID == PFunctionGrammar::termID) { + if (node.fOperatorTag == OP_MUL) { + return EvalNode(node.children[0]) * EvalNode(node.children[1]); + } else { + double denominator = EvalNode(node.children[1]); + if (denominator == 0.0) { + cout << endl << "**PANIC ERROR**: PFunction::EvalNode: division by 0.0" << endl; + assert(0); + } + return EvalNode(node.children[0]) / denominator; + } + } else if (node.fID == PFunctionGrammar::expressionID) { + if (node.fOperatorTag == OP_ADD) { + return EvalNode(node.children[0]) + EvalNode(node.children[1]); + } else { + return EvalNode(node.children[0]) - EvalNode(node.children[1]); + } + } else { + cout << endl << "**PANIC ERROR**: PFunction::EvalNode: you never should have reached this point!" << endl; + assert(0); + } + return 0.0; +} + +//------------------------------------------------------------- +// CleanupFuncEvalTree (protected) +//------------------------------------------------------------- +/** + *

+ * + */ +void PFunction::CleanupFuncEvalTree() +{ + // clean up all children + CleanupNode(fFunc); +} + +//------------------------------------------------------------- +// CleanupNode (protected) +//------------------------------------------------------------- +/** + *

+ * + * \param node + */ +void PFunction::CleanupNode(PFuncTreeNode &node) +{ + if (node.children.size() != 0) { + for (unsigned int i=0; i info) +{ + return EvalTreeExpression(info.trees.begin()); +} + +//------------------------------------------------------------- +// EvalTreeExpression (protected) +//------------------------------------------------------------- +long PFunction::EvalTreeExpression(iter_t const& i) +{ + static int counter = 0; + static int termOp = 0; + + cout << endl << counter <<": in EvalExpression. i->value = '" << + string(i->value.begin(), i->value.end()) << + "' i->children.size() = " << i->children.size() << endl; + + if (i->value.id() == PFunctionGrammar::realID) { + assert(i->children.size() == 0); + cout << endl << "realID: children = " << i->children.size(); + cout << endl << "realID: " << string(i->value.begin(), i->value.end()); + cout << endl << "-----"; + if (*i->value.begin() == '-') + fFuncString += "("; + fFuncString += string(i->value.begin(), i->value.end()); + if (*i->value.begin() == '-') + fFuncString += ")"; + } else if (i->value.id() == PFunctionGrammar::funLabelID) { + assert(i->children.size() == 0); + //SetFuncNo(i); + cout << endl << "funLabelID: children = " << i->children.size(); + cout << endl << "funLabelID: value = " << string(i->value.begin(), i->value.end()); + cout << endl << "-----"; + fFuncString += string(i->value.begin(), i->value.end()); // funx + } else if (i->value.id() == PFunctionGrammar::parameterID) { + assert(i->children.size() == 0); + cout << endl << "parameterID: children = " << i->children.size(); + cout << endl << "parameterID: value = " << string(i->value.begin(), i->value.end()); + cout << endl << "-----"; + fFuncString += string(i->value.begin(), i->value.end()); + } else if (i->value.id() == PFunctionGrammar::mapID) { + assert(i->children.size() == 0); + cout << endl << "mapID: children = " << i->children.size(); + cout << endl << "mapID: value = " << string(i->value.begin(), i->value.end()); + cout << endl << "-----"; + fFuncString += string(i->value.begin(), i->value.end()); + } else if (i->value.id() == PFunctionGrammar::functionID) { + assert(i->children.size() == 4); + cout << endl << "functionID: children = " << i->children.size(); + iter_t it = i->children.begin(); + cout << endl << "functionID: value = " << string(it->value.begin(), it->value.end()); + cout << endl << "-----"; + // funcName, '(', expression, ')' + counter++; + fFuncString += string(it->value.begin(), it->value.end()); + if (termOp == 0) + fFuncString += "("; + EvalTreeExpression(i->children.begin()+2); // the real stuff + if (termOp == 0) + fFuncString += ")"; + counter--; + } else if (i->value.id() == PFunctionGrammar::factorID) { + cout << endl << "factorID: children = " << i->children.size(); + counter++; + return EvalTreeExpression(i->children.begin()); + counter--; + } else if (i->value.id() == PFunctionGrammar::termID) { + cout << endl << "termID: children = " << i->children.size(); + if (*i->value.begin() == '*') { + cout << endl << "termID: '*'"; + assert(i->children.size() == 2); + counter++; + termOp++; + EvalTreeExpression(i->children.begin()); + fFuncString += " * "; + EvalTreeExpression(i->children.begin()+1); + termOp--; + counter--; + } else if (*i->value.begin() == '/') { + cout << endl << "termID: '/'"; + assert(i->children.size() == 2); + counter++; + termOp++; + EvalTreeExpression(i->children.begin()); + fFuncString += " / "; + EvalTreeExpression(i->children.begin()+1); + termOp--; + counter--; + } else { + assert(0); + } + } else if (i->value.id() == PFunctionGrammar::expressionID) { + cout << endl << "expressionID: children = " << i->children.size(); + if (*i->value.begin() == '+') { + cout << endl << "expressionID: '+'"; + assert(i->children.size() == 2); + counter++; + if (termOp > 0) + fFuncString += "("; + EvalTreeExpression(i->children.begin()); + fFuncString += " + "; + EvalTreeExpression(i->children.begin()+1); + if (termOp > 0) + fFuncString += ")"; + counter--; + } else if (*i->value.begin() == '-') { + cout << endl << "expressionID: '-'"; + assert(i->children.size() == 2); + counter++; + if (termOp > 0) + fFuncString += "("; + EvalTreeExpression(i->children.begin()); + fFuncString += " - "; + EvalTreeExpression(i->children.begin()+1); + if (termOp > 0) + fFuncString += ")"; + counter--; + } else { + assert(0); + } + } else if (i->value.id() == PFunctionGrammar::assignmentID) { + cout << endl << "assignmentID: children = " << i->children.size(); + assert(i->children.size() == 3); + counter++; + EvalTreeExpression(i->children.begin()); + EvalTreeExpression(i->children.begin()+1); // this is the string "=" + EvalTreeExpression(i->children.begin()+2); // this is the real stuff + counter--; + } else if (*i->value.begin() == '=') { + cout << endl << "'=' in assignment"; + fFuncString += " = "; + } else { + assert(0); + } + + return 0; +} diff --git a/src/tests/spirit/PFunction.h b/src/tests/spirit/PFunction.h new file mode 100644 index 00000000..1c419913 --- /dev/null +++ b/src/tests/spirit/PFunction.h @@ -0,0 +1,111 @@ +/*************************************************************************** + + PFunction.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PFUNCTION_H_ +#define _PFUNCTION_H_ + +#include +#include + +#include +using namespace boost::spirit; + +#include "PFunctionGrammar.h" + +//---------------------------------------------------------------------------- +#define OP_ADD 0 +#define OP_SUB 1 +#define OP_MUL 2 +#define OP_DIV 3 + +#define FUN_COS 0 +#define FUN_SIN 1 +#define FUN_TAN 2 +#define FUN_COSH 3 +#define FUN_SINH 4 +#define FUN_TANH 5 +#define FUN_ACOS 6 +#define FUN_ASIN 7 +#define FUN_ATAN 8 +#define FUN_ACOSH 9 +#define FUN_ASINH 10 +#define FUN_ATANH 11 +#define FUN_LOG 12 +#define FUN_LN 13 +#define FUN_EXP 14 + +//---------------------------------------------------------------------------- +typedef struct func_tree_node { + int fID; ///< tag showing what tree element this is + int fOperatorTag; ///< tag for '+', '-', '*', '/' + int fFunctionTag; ///< tag got "cos", "sin", ... + int fIvalue; ///< for parameter numbers and maps + double fDvalue; ///< for numbers + vector children; ///< holding sub-tree +} PFuncTreeNode; + +//---------------------------------------------------------------------------- +class PFunction { + public: + PFunction(tree_parse_info<> info, vector param, vector map); + virtual ~PFunction(); + + virtual bool IsValid() { return fValid; } + virtual int GetFuncNo() { return fFuncNo; } + virtual double Eval(); + + protected: + virtual bool CheckParameterAndMapRange(); + virtual bool CheckParameterAndMapInTree(iter_t const& i); + virtual bool SetFuncNo(iter_t const& i); + + virtual bool GenerateFuncEvalTree(); + virtual void FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node); + virtual double EvalNode(PFuncTreeNode &node); + virtual void CleanupFuncEvalTree(); + virtual void CleanupNode(PFuncTreeNode &node); + + virtual long EvaluateTree(tree_parse_info<> info); + virtual long EvalTreeExpression(iter_t const& i); + + private: + tree_parse_info<> fInfo; + vector fParam; + vector fMap; + PFuncTreeNode fFunc; + + bool fValid; ///< flag showing if the function is valid + int fFuncNo; ///< function number, i.e. FUNx with x the function number + + string fFuncString; +}; + +#endif // _PFUNCTION_H_ diff --git a/src/tests/spirit/PFunctionGrammar.h b/src/tests/spirit/PFunctionGrammar.h new file mode 100644 index 00000000..a62bfc19 --- /dev/null +++ b/src/tests/spirit/PFunctionGrammar.h @@ -0,0 +1,142 @@ +/*************************************************************************** + + PFunctionGrammer.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PFUNCTIONGRAMMAR_H_ +#define _PFUNCTIONGRAMMAR_H_ + +#include +using namespace std; + +//#define BOOST_SPIRIT_DEBUG + +#include +#include +using namespace boost::spirit; + +typedef char const* iterator_t; +typedef tree_match parse_tree_match_t; +typedef parse_tree_match_t::tree_iterator iter_t; + +//-------------------------------------------------------------------------- +/** + * + */ +struct PFunctionGrammar : public grammar +{ + static const int realID = 1; + static const int funLabelID = 2; + static const int parameterID = 3; + static const int mapID = 4; + static const int functionID = 5; + static const int factorID = 6; + static const int termID = 7; + static const int expressionID = 8; + static const int assignmentID = 9; + + template + struct definition + { + definition(PFunctionGrammar const& /*self*/) + { + // Start grammar definition + real = leaf_node_d[ real_p ]; + + fun_label = leaf_node_d[ ( lexeme_d[ "FUN" >> +digit_p ] ) ]; + + parameter = leaf_node_d[ ( lexeme_d[ "PAR" >> +digit_p ] ) ]; + + map = leaf_node_d[ ( lexeme_d[ "MAP" >> +digit_p ] ) ]; + + function = str_p("COS") >> ch_p('(') >> expression >> ch_p(')') + | str_p("SIN") >> ch_p('(') >> expression >> ch_p(')') + | str_p("TAN") >> ch_p('(') >> expression >> ch_p(')') + | str_p("COSH") >> ch_p('(') >> expression >> ch_p(')') + | str_p("SINH") >> ch_p('(') >> expression >> ch_p(')') + | str_p("TANH") >> ch_p('(') >> expression >> ch_p(')') + | str_p("ACOS") >> ch_p('(') >> expression >> ch_p(')') + | str_p("ASIN") >> ch_p('(') >> expression >> ch_p(')') + | str_p("ATAN") >> ch_p('(') >> expression >> ch_p(')') + | str_p("ACOSH") >> ch_p('(') >> expression >> ch_p(')') + | str_p("ASINH") >> ch_p('(') >> expression >> ch_p(')') + | str_p("ATANH") >> ch_p('(') >> expression >> ch_p(')') + | str_p("LOG") >> ch_p('(') >> expression >> ch_p(')') + | str_p("LN") >> ch_p('(') >> expression >> ch_p(')') + | str_p("EXP") >> ch_p('(') >> expression >> ch_p(')') + ; + + factor = real + | parameter + | map + | function + | inner_node_d[ch_p('(') >> expression >> ch_p(')')] + ; + + term = factor >> + *( (root_node_d[ch_p('*')] >> factor) + | (root_node_d[ch_p('/')] >> factor) + ); + + expression = term >> + *( (root_node_d[ch_p('+')] >> term) + | (root_node_d[ch_p('-')] >> term) + ); + + assignment = (fun_label >> ch_p('=') >> expression); + // End grammar definition + + // turn on the debugging info. + BOOST_SPIRIT_DEBUG_RULE(real); + BOOST_SPIRIT_DEBUG_RULE(fun_label); + BOOST_SPIRIT_DEBUG_RULE(parameter); + BOOST_SPIRIT_DEBUG_RULE(map); + BOOST_SPIRIT_DEBUG_RULE(function); + BOOST_SPIRIT_DEBUG_RULE(factor); + BOOST_SPIRIT_DEBUG_RULE(term); + BOOST_SPIRIT_DEBUG_RULE(expression); + BOOST_SPIRIT_DEBUG_RULE(assignment); + } + + rule, parser_tag > assignment; + rule, parser_tag > expression; + rule, parser_tag > term; + rule, parser_tag > factor; + rule, parser_tag > function; + rule, parser_tag > map; + rule, parser_tag > parameter; + rule, parser_tag > fun_label; + rule, parser_tag > real; + + rule, parser_tag > const& + start() const { return assignment; } + }; +}; + +#endif // _PFUNCTIONGRAMMAR_H_ diff --git a/src/tests/spirit/PFunctionHandler.cpp b/src/tests/spirit/PFunctionHandler.cpp new file mode 100644 index 00000000..90f93bd7 --- /dev/null +++ b/src/tests/spirit/PFunctionHandler.cpp @@ -0,0 +1,417 @@ +/*************************************************************************** + + PFunctionHandler.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "PFunctionHandler.h" + +//------------------------------------------------------------- +// Constructor +//------------------------------------------------------------- +/** + *

+ * + * \param fln + */ +PFunctionHandler::PFunctionHandler(char *fln) +{ + fValid = true; + fFileName = QString(fln); + + cout << endl << "in PFunctionHandler(char *fln)"; + cout << endl << "fFileName = " << fFileName.latin1(); + + fValid = ReadFile(); + if (fValid) + fValid = MapsAreValid(); +} + +//------------------------------------------------------------- +// Constructor +//------------------------------------------------------------- +/** + *

+ * + * \param lines + */ +PFunctionHandler::PFunctionHandler(vector lines) +{ + fValid = true; + fFileName = ""; + + cout << endl << "in PFunctionHandler(vector lines)"; + + if (lines.size() == 0) { + fValid = false; + return; + } + + // analyze input + bool done = false; + int status; + int val[10]; + double dval[10]; + bool inFcnBlock = false; + for (unsigned int i=0; i + * + */ +PFunctionHandler::~PFunctionHandler() +{ + cout << endl << "in ~PFunctionHandler()" << endl << endl; + fParam.clear(); + fMap.clear(); + fLines.clear(); + + fFuncs.clear(); +} + +//------------------------------------------------------------- +// DoParse (public) +//------------------------------------------------------------- +/** + *

+ * + */ +bool PFunctionHandler::DoParse() +{ + cout << endl << "in PFunctionHandler::DoParse() ..."; + + bool success = true; + PFunctionGrammar function; + + for (unsigned int i=0; i info = ast_parse(fLines[i].latin1(), function, space_p); + + if (info.full) { + cout << endl << "parse successfull ..." << endl; + PFunction func(info, fParam, fMap); + fFuncs.push_back(func); + } else { + cout << endl << "parse failed ... (" << i << ")" << endl; + success = false; + break; + } + } + + // check that all functions are valid. It could be that parsing was fine but + // the parameter index, or map index was out of range + if (success) { + for (unsigned int i=0; i + * + */ +bool PFunctionHandler::MapsAreValid() +{ + bool success = true; + + int maxParam = fParam.size(); + for (unsigned int i=0; i maxParam) + success = false; + + if (!success) + cout << endl << "invalid MAP found ..."; + + return success; +} + +//------------------------------------------------------------- +// GetFuncIndex (private) +//------------------------------------------------------------- +/** + *

+ * + * \param funcNo + */ +int PFunctionHandler::GetFuncIndex(int funcNo) +{ + int index = -1; + + for (unsigned int i=0; i +#include +using namespace std; + +#include + +#include "PFunctionGrammar.h" +#include "PFunction.h" + +class PFunctionHandler +{ + public: + PFunctionHandler(char *fln); + PFunctionHandler(vector lines); + virtual ~PFunctionHandler(); + + virtual bool IsValid() { return fValid; } + virtual bool DoParse(); + virtual double Eval(int i); + virtual unsigned int GetFuncNo(unsigned int i); + virtual unsigned int GetNoOfFuncs() { return fFuncs.size(); } + + private: + bool fValid; + + QString fFileName; + + vector fParam; + vector fMap; + vector fLines; + + vector fFuncs; + + virtual bool ReadFile(); + virtual bool MapsAreValid(); + virtual int GetFuncIndex(int funcNo); +}; + +// cint dictionary stuff -------------------------------------- +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class PFunctionHandler+; + +#endif // end __CINT__ +//------------------------------------------------------------- + +#endif // _PFUNCTIONHANDLER_H_ + diff --git a/src/tests/spirit/fcnInput.txt b/src/tests/spirit/fcnInput.txt new file mode 100644 index 00000000..a0db5a19 --- /dev/null +++ b/src/tests/spirit/fcnInput.txt @@ -0,0 +1,28 @@ +#---------------------------------------------- +# function input file +#---------------------------------------------- +# +# '#' are comment lines +# +# The file has the following structure: +# +# PAR ... +# MAP ... +# FUNCTIONS +# fun1 = +# fun2 = +# funX = +# END +#---------------------------------------------- +PAR 1.0 2.1 3.5 -0.87 0.87 +MAP 2 1 4 5 +FUNCTIONS +fun0 = sin(par3/(par1+map2)) +#fun0 = par1 + map3 * cos(cos(par2 - map1)) +#fun8 = log(sin(par1)) + exp(-1.0*map2) +#fun1 = par1 + map1 * (0.01355+par1*(2.1 - (-2.3 / 3.4))) +#fun2 = par1 * par2 - map3 +#fun3 = -3.2 + (par2-par1)/(map2+map3) +#fun7 = 1.2 +END +#---------------------------------------------- diff --git a/src/tests/spirit/spirit.pdf b/src/tests/spirit/spirit.pdf new file mode 100644 index 00000000..05cd0bcb Binary files /dev/null and b/src/tests/spirit/spirit.pdf differ diff --git a/src/tests/spirit/spirit_fcn_test.cpp b/src/tests/spirit/spirit_fcn_test.cpp new file mode 100644 index 00000000..d720673e --- /dev/null +++ b/src/tests/spirit/spirit_fcn_test.cpp @@ -0,0 +1,100 @@ +#include +using namespace std; + +#include "PFunctionHandler.h" + +//----------------------------------------------------- +void syntax() +{ + cout << endl << "spirit_fcn_test [--file ] | [--help]"; + cout << endl << " without arguments: interactive mode"; + cout << endl << " --file : function block etc. from file"; + cout << endl << " --help: this help"; + cout << endl << endl; +} + +//----------------------------------------------------- +void handle_input(vector &lines) +{ + cout << endl << "will handle input ..."; + cout << endl << "you should provide a PAR, a MAP, and a FUNCTION block"; + cout << endl << " Map block:"; + cout << endl << " MAP ... "; + cout << endl << " Parameter block:"; + cout << endl << " PAR ... "; + cout << endl << " Function Block:"; + cout << endl << " FUNCTION"; + cout << endl << " fun1 = "; + cout << endl << " fun2 = "; + cout << endl << " ..."; + cout << endl << " funX = "; + cout << endl << " END"; + cout << endl << "to get out of the input handle type '.q'"; + cout << endl; + bool done = false; + char str[128]; + do { + cout << ">> "; + cin.getline(str, sizeof(str)); + if (!strcmp(str, ".q")) + done = true; + else + lines.push_back(str); + } while (!done); +} + +//----------------------------------------------------- +int main(int argc, char *argv[]) +{ + bool inputFile = false; + + if (argc > 3) { + syntax(); + return 0; + } else if (argc == 2) { + syntax(); + return 0; + } else if (argc == 3) { + if (strcmp(argv[1], "--file")) { + syntax(); + return 0; + } else { + inputFile = true; + } + } + + PFunctionHandler *fcnHandler = 0; + + if (inputFile) { + fcnHandler = new PFunctionHandler(argv[2]); + } else { + vector lines; + handle_input(lines); +cout << endl << "lines.size() = " << lines.size(); + fcnHandler = new PFunctionHandler(lines); + } + + if (fcnHandler == 0) { + cout << endl << "Couldn't invoke function handler, sorry ..." << endl; + return 0; + } + + bool go_on = fcnHandler->IsValid(); + + if (go_on) { + cout << endl << "will do the parsing ..."; + if (fcnHandler->DoParse()) { + cout << endl << "will do the evaluation ..."; + for (unsigned int i=0; iGetNoOfFuncs(); i++) + cout << endl << "FUN" << fcnHandler->GetFuncNo(i) << " = " << fcnHandler->Eval(fcnHandler->GetFuncNo(i)); + } + } + + // clean up + if (fcnHandler) { + delete fcnHandler; + fcnHandler = 0; + } + + return 1; +} diff --git a/src/tests/spirit/spirit_fcn_test.pro b/src/tests/spirit/spirit_fcn_test.pro new file mode 100644 index 00000000..0103ad86 --- /dev/null +++ b/src/tests/spirit/spirit_fcn_test.pro @@ -0,0 +1,24 @@ +#------------------------------------------------------ +# spirit_fcn_test.pro +# qmake file for spirit_fcn_test +# +# Andreas Suter, 2007/12/10 +# +# $Id$ +# +#------------------------------------------------------ + +MAKEFILE = Makefile + +CONFIG += warn_on debug + +HEADERS = PFunctionGrammar.h \ + PFunction.h \ + PFunctionHandler.h + +SOURCES = spirit_fcn_test.cpp \ + PFunction.cpp \ + PFunctionHandler.cpp + +TARGET=spirit_fcn_test + diff --git a/src/tests/stl_check/.kdbgrc.stl_check b/src/tests/stl_check/.kdbgrc.stl_check new file mode 100755 index 00000000..e69de29b diff --git a/src/tests/stl_check/PPointObj.cpp b/src/tests/stl_check/PPointObj.cpp new file mode 100644 index 00000000..58365b31 --- /dev/null +++ b/src/tests/stl_check/PPointObj.cpp @@ -0,0 +1,37 @@ +#include +using namespace std; + +#include "PPointObj.h" + +PPointObj::PPointObj(unsigned int counter) : fCounter(counter) +{ + fTest = new int[5]; + + for (unsigned int i=0; i<5; i++) + fTest[i] = 10*counter+i; + + cout << endl << "in PPointObj() " << fCounter << ": fTest = " << fTest; + cout << endl; +} + +PPointObj::~PPointObj() +{ + cout << endl << "in ~PPointObj() " << fCounter << ": fTest = " << fTest; + cout << endl; +} + +void PPointObj::PrintTest() +{ + cout << endl << fCounter << ": "; + for (unsigned int i=0; i<5; i++) + cout << fTest[i] << ", "; + cout << endl; +} + +void PPointObj::CleanUp() +{ + if (fTest) { + delete [] fTest; + fTest = 0; + } +} diff --git a/src/tests/stl_check/PPointObj.h b/src/tests/stl_check/PPointObj.h new file mode 100644 index 00000000..1c8aed95 --- /dev/null +++ b/src/tests/stl_check/PPointObj.h @@ -0,0 +1,17 @@ +#ifndef _PPOINTOBJ_H_ +#define _PPOINTOBJ_H_ + +class PPointObj { + public: + PPointObj(unsigned int counter); + ~PPointObj(); + + void PrintTest(); + void CleanUp(); + + private: + int fCounter; + int *fTest; +}; + +#endif // _PPOINTOBJ_H_ diff --git a/src/tests/stl_check/PStlCheck.cpp b/src/tests/stl_check/PStlCheck.cpp new file mode 100644 index 00000000..3368f52e --- /dev/null +++ b/src/tests/stl_check/PStlCheck.cpp @@ -0,0 +1,10 @@ +#include "PStlCheck.h" + +PStlCheck::PStlCheck() +{ +} + +PStlCheck::~PStlCheck() +{ + fPpo.clear(); +} diff --git a/src/tests/stl_check/PStlCheck.h b/src/tests/stl_check/PStlCheck.h new file mode 100644 index 00000000..462c28a2 --- /dev/null +++ b/src/tests/stl_check/PStlCheck.h @@ -0,0 +1,17 @@ +#ifndef _PSTLCHECK_H_ +#define _PSTLCHECK_H_ + +#include +using namespace std; + +#include "PPointObj.h" + +class PStlCheck { + public: + PStlCheck(); + ~PStlCheck(); + + list fPpo; +}; + +#endif // _PSTLCHECK_H_ diff --git a/src/tests/stl_check/stl_check.cpp b/src/tests/stl_check/stl_check.cpp new file mode 100644 index 00000000..21870fe3 --- /dev/null +++ b/src/tests/stl_check/stl_check.cpp @@ -0,0 +1,28 @@ +#include +#include +using namespace std; + +#include "PStlCheck.h" + +int main() +{ + PStlCheck check; + unsigned int counter = 0; + + for (unsigned int i=0; i<2; i++) { + check.fPpo.push_back(PPointObj(counter++)); + cout << endl << "----------"; + } + + cout << endl << "size = " << check.fPpo.size(); + cout << endl; + + list::iterator iter; + for (iter=check.fPpo.begin(); iter!=check.fPpo.end(); ++iter) + iter->PrintTest(); + + for (iter=check.fPpo.begin(); iter!=check.fPpo.end(); ++iter) + iter->CleanUp(); + + return 0; +} diff --git a/src/tests/stl_check/stl_check.pro b/src/tests/stl_check/stl_check.pro new file mode 100644 index 00000000..11be44ab --- /dev/null +++ b/src/tests/stl_check/stl_check.pro @@ -0,0 +1,22 @@ +#------------------------------------------------------ +# stl_check.pro +# qmake file for stl_check +# +# Andreas Suter, 2007/05/14 +# +# $Id$ +# +#------------------------------------------------------ + +MAKEFILE = Makefile.stl_check + +CONFIG += warn_on debug + +HEADERS = PStlCheck.h \ + PPointObj.h + +SOURCES = stl_check.cpp \ + PStlCheck.cpp \ + PPointObj.cpp + +TARGET=stl_check diff --git a/src/tests/stl_check_2/PPointObj.cpp b/src/tests/stl_check_2/PPointObj.cpp new file mode 100644 index 00000000..64eab8e9 --- /dev/null +++ b/src/tests/stl_check_2/PPointObj.cpp @@ -0,0 +1,36 @@ +#include +using namespace std; + +#include "PPointObj.h" + +#define PPO_SIZE 100 + +PPointObj::PPointObj(unsigned int counter) : fCounter(counter) +{ + fTest = new int[PPO_SIZE]; + + for (unsigned int i=0; i~PPointObj(); + } +} + +void PStlCheck::PrintTest() +{ + for (unsigned int i=0; iPrintTest(); +} + diff --git a/src/tests/stl_check_2/PStlCheck.h b/src/tests/stl_check_2/PStlCheck.h new file mode 100644 index 00000000..a55e1dee --- /dev/null +++ b/src/tests/stl_check_2/PStlCheck.h @@ -0,0 +1,22 @@ +#ifndef _PSTLCHECK_H_ +#define _PSTLCHECK_H_ + +#include +using namespace std; + +#include "PPointObj.h" + +class PStlCheck { + public: + PStlCheck(); + ~PStlCheck(); + + void Add(unsigned int count); + void CleanUp(); + void PrintTest(); + + private: + vector fPpo; +}; + +#endif // _PSTLCHECK_H_ diff --git a/src/tests/stl_check_2/stl_check_2.cpp b/src/tests/stl_check_2/stl_check_2.cpp new file mode 100644 index 00000000..fb34bb83 --- /dev/null +++ b/src/tests/stl_check_2/stl_check_2.cpp @@ -0,0 +1,21 @@ +#include +#include +using namespace std; + +#include "PStlCheck.h" + +int main() +{ + PStlCheck check; + + for (unsigned int i=0; i<2; i++) { + check.Add(i); + cout << endl << "----------"; + } + + check.PrintTest(); + + check.CleanUp(); + + return 0; +} diff --git a/src/tests/stl_check_2/stl_check_2.pro b/src/tests/stl_check_2/stl_check_2.pro new file mode 100644 index 00000000..6a0d185c --- /dev/null +++ b/src/tests/stl_check_2/stl_check_2.pro @@ -0,0 +1,22 @@ +#------------------------------------------------------ +# stl_check_2.pro +# qmake file for stl_check_2 +# +# Andreas Suter, 2007/05/14 +# +# $Id$ +# +#------------------------------------------------------ + +MAKEFILE = Makefile.stl_check_2 + +CONFIG += warn_on debug + +HEADERS = PStlCheck.h \ + PPointObj.h + +SOURCES = stl_check_2.cpp \ + PStlCheck.cpp \ + PPointObj.cpp + +TARGET=stl_check_2 diff --git a/templates/cpp b/templates/cpp new file mode 100755 index 00000000..bb3f316f --- /dev/null +++ b/templates/cpp @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.ch * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ diff --git a/templates/h b/templates/h new file mode 100755 index 00000000..923f9e9d --- /dev/null +++ b/templates/h @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2007 by Andreas Suter * + * andreas.suter@psi.c * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/