newly added. Not for productive used yetsvn diff | grep Index:

This commit is contained in:
nemu 2008-01-08 08:31:58 +00:00
commit c6cc508aaf
85 changed files with 14397 additions and 0 deletions

340
copying Executable file
View File

@ -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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
<signature of Ty Coon>, 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.

239
doc/man/logo_n.eps Executable file
View File

@ -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

351
doc/man/musrfit.tex Executable file
View File

@ -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!<no> <name> <value> <step>!
\item \verb!<no> <name> <value> <step> <lower boundary> <upper boundary>!
\item \verb!<no> <name> <value> <step> <pos.error> <lower boundary> <upper boundary>!
\end{enumerate}
\noindent where \verb!<no>! is the parameter number, \verb!<name>! is the parameter name\footnote{The parameter name is limited to 10 characters, and furthermore no spaces are allowed!}, \verb!<value>! is the initial guess of the parameter, \verb!<step>! the inital step width, \verb!<lower/upper boundary>! 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!<value>! will be the \textsc{Minuit} fit value, \verb!<step>! will contain the error estimate (or the negative error estimate if \textsc{Minos} was successfully used), \verb!<pos.error>! 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 <run-file-name> <beamline> <institute> <file-format>
\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{<run-file-name>} & sub path and filename without extension \\ \hline
\texttt{<beamline>} & \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{<institute>} & \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>} & 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}

1283
doc/musrfit_dox.cfg Normal file

File diff suppressed because it is too large Load Diff

18
src/.kdbgrc.musrfit Executable file
View File

@ -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

66
src/ToDo.txt Normal file
View File

@ -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.

31
src/classes/BUILD Normal file
View File

@ -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

138
src/classes/Makefile.PMusr Normal file
View File

@ -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

478
src/classes/PFitter.cpp Normal file
View File

@ -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 <iostream>
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
//--------------------------------------------------------------------------
/**
* <p>
*
* \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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PFitter::~PFitter()
{
fCmdList.clear();
if (fFitterFcn) {
delete fFitterFcn;
fFitterFcn = 0;
}
}
//--------------------------------------------------------------------------
// DoFit
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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<fCmdList.size(); i++) {
switch (fCmdList[i]) {
case PMN_INTERACTIVE:
break;
case PMN_CONTOURS:
break;
case PMN_EIGEN:
break;
case PMN_HESSE:
break;
case PMN_MACHINE_PRECISION:
break;
case PMN_MIGRAD:
status = ExecuteMigrad();
break;
case PMN_MINIMIZE:
status = ExecuteMinimize();
break;
case PMN_MINOS:
status = ExecuteMinos();
break;
case PMN_PLOT:
break;
case PMN_SAVE:
status = ExecuteSave();
break;
case PMN_SCAN:
break;
case PMN_SIMPLEX:
status = ExecuteSimplex();
break;
case PMN_USER_COVARIANCE:
break;
case PMN_USER_PARAM_STATE:
break;
case PMN_PRINT:
break;
default:
cout << endl << "**PANIC ERROR**: PFitter::DoFit(): You should never have reached this point" << endl;
exit(0);
break;
}
}
return true;
}
//--------------------------------------------------------------------------
// CheckCommands
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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; i<fParams.size(); i++) {
fRunInfo->SetMsrParamValue(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; i<fParams.size(); i++) {
if (min.UserState().Error(i) != 0.0)
ndf -= 1;
}
// feed run info with new statistics info
fRunInfo->SetMsrStatisticMin(minVal);
fRunInfo->SetMsrStatisticNdf(ndf);
return true;
}
//--------------------------------------------------------------------------
// ExecuteMinimize
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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; i<fParams.size(); i++) {
fRunInfo->SetMsrParamValue(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; i<fParams.size(); i++) {
if (min.UserState().Error(i) != 0.0)
ndf -= 1;
}
// feed run info with new statistics info
fRunInfo->SetMsrStatisticMin(minVal);
fRunInfo->SetMsrStatisticNdf(ndf);
return true;
}
//--------------------------------------------------------------------------
// ExecuteMinos
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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<fParams.size(); i++) {
// only try to call minos if the parameter is not fixed!!
if (fMnUserParams.Error(i) != 0) {
// 1-sigma MINOS errors
std::pair<double, double> err = minos(i);
// fill msr-file structure
fRunInfo->SetMsrParamStep(i, err.first);
fRunInfo->SetMsrParamPosError(i, err.second);
}
}
return true;
}
//--------------------------------------------------------------------------
// ExecuteSave
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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; i<fParams.size(); i++) {
fRunInfo->SetMsrParamValue(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; i<fParams.size(); i++) {
if (min.UserState().Error(i) != 0.0)
ndf -= 1;
}
// feed run info with new statistics info
fRunInfo->SetMsrStatisticMin(minVal);
fRunInfo->SetMsrStatisticNdf(ndf);
return true;
}

View File

@ -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 <iostream>
using namespace std;
#include "PFitterFcn.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \param runList
* \param fitType
*/
PFitterFcn::PFitterFcn(PRunListCollection *runList, bool useChi2)
{
fUseChi2 = useChi2;
if (fUseChi2)
fUp = 1.0;
else
fUp = 0.5;
fRunListCollection = runList;
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*/
PFitterFcn::~PFitterFcn()
{
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par
*/
double PFitterFcn::operator()(const std::vector<double>& 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<par.size(); i++) {
// cout << par[i] << ", ";
// }
//cout << endl << "chisq = " << value;
// cout << endl << "------" << endl;
return value;
}

562
src/classes/PFunction.cpp Normal file
View File

@ -0,0 +1,562 @@
/***************************************************************************
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<cmath>
#include <iostream>
using namespace std;
#include "PFunction.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* 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
//--------------------------------------------------------------------------
/**
* <p>
*/
PFunction::~PFunction()
{
// cout << endl << "in ~PFunction ...";
fParam.clear();
fMap.clear();
CleanupFuncEvalTree();
}
//-------------------------------------------------------------
// SetFuncNo (protected)
//-------------------------------------------------------------
/**
* <p>
*
* \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)
//-------------------------------------------------------------
/**
* <p>
*
*/
bool PFunction::GenerateFuncEvalTree()
{
FillFuncEvalTree(fInfo.trees.begin(), fFunc);
return true;
}
//-------------------------------------------------------------
// FillFuncEvalTree (protected)
//-------------------------------------------------------------
/**
* <p>
*
*/
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)
//-------------------------------------------------------------
/**
* <p>
*
* \param mapSize
* \param paramSize
*/
bool PFunction::CheckMapAndParamRange(unsigned int mapSize, unsigned int paramSize)
{
return FindAndCheckMapAndParamRange(fFunc, mapSize, paramSize);
}
//-------------------------------------------------------------
// FindAndCheckMapAndParamRange (protected)
//-------------------------------------------------------------
/**
* <p>
*
* \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)
//-------------------------------------------------------------
/**
* <p>
*
*/
double PFunction::Eval(vector<double> param)
{
fParam = param;
return EvalNode(fFunc);
}
//-------------------------------------------------------------
// EvalNode (protected)
//-------------------------------------------------------------
/**
* <p>
*
* \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)
//-------------------------------------------------------------
/**
* <p>
*
*/
void PFunction::CleanupFuncEvalTree()
{
// clean up all children
CleanupNode(fFunc);
}
//-------------------------------------------------------------
// CleanupNode (protected)
//-------------------------------------------------------------
/**
* <p>
*
* \param node
*/
void PFunction::CleanupNode(PFuncTreeNode &node)
{
if (node.children.size() != 0) {
for (unsigned int i=0; i<node.children.size(); i++) {
CleanupNode(node.children[i]);
}
node.children.clear();
}
}
//-------------------------------------------------------------
// EvalTreeForString (private)
//-------------------------------------------------------------
/**
* <p>
*
* \param info
*/
void PFunction::EvalTreeForString(tree_parse_info<> info)
{
fFuncString = "";
EvalTreeForStringExpression(info.trees.begin());
}
//-------------------------------------------------------------
// EvalTreeForStringExpression (private)
//-------------------------------------------------------------
/**
* <p>
*
* \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);
}
}

View File

@ -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 <string>
#include <cassert>
#include "PFunctionHandler.h"
//-------------------------------------------------------------
// Constructor
//-------------------------------------------------------------
/**
* <p>
*
* \param lines
*/
PFunctionHandler::PFunctionHandler(PMsrLines lines)
{
fValid = true;
fLines = lines;
cout << endl << "in PFunctionHandler(PMsrLines lines)";
}
//-------------------------------------------------------------
// Destructor
//-------------------------------------------------------------
/**
* <p>
*
*/
PFunctionHandler::~PFunctionHandler()
{
cout << endl << "in ~PFunctionHandler()" << endl << endl;
fLines.clear();
fFuncs.clear();
}
//-------------------------------------------------------------
// DoParse (public)
//-------------------------------------------------------------
/**
* <p>
*
*/
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<fLines.size(); i++) {
cout << endl << "fLines[" << i << "] = '" << fLines[i].fLine.Data() << "'";
// function line to upper case
line = fLines[i].fLine;
line.ToUpper();
// do parsing
tree_parse_info<> 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<fFuncs.size(); i++) {
for (unsigned int j=i+1; j<fFuncs.size(); j++) {
if (fFuncs[i].GetFuncNo() == fFuncs[j].GetFuncNo()) {
cout << endl << "**ERROR**: function number " << fFuncs[i].GetFuncNo();
cout << " is at least twice present! Fix this first.";
success = false;
}
}
}
}
if (success) {
for (unsigned int i=0; i<fFuncs.size(); i++)
cout << endl << "func number = " << fFuncs[i].GetFuncNo();
}
return success;
}
//-------------------------------------------------------------
// CheckMapAndParamRange (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param mapSize
* \param paramSize
*/
bool PFunctionHandler::CheckMapAndParamRange(unsigned int mapSize, unsigned int paramSize)
{
bool success = true;
for (unsigned int i=0; i<fFuncs.size(); i++) {
success = fFuncs[i].CheckMapAndParamRange(mapSize, paramSize);
if (!success)
break;
}
return success;
}
//-------------------------------------------------------------
// Eval (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param funNo
*/
double PFunctionHandler::Eval(int funNo, vector<int> map, vector<double> param)
{
if (GetFuncIndex(funNo) == -1) {
cout << endl << "**ERROR**: Couldn't find FUN" << funNo << " for evaluation";
return 0.0;
}
//cout << endl << "PFunctionHandler::Eval: GetFuncIndex("<<funNo<<") = " << GetFuncIndex(funNo);
//cout << endl;
// set correct map
fFuncs[GetFuncIndex(funNo)].SetMap(map);
// return evaluated function
return fFuncs[GetFuncIndex(funNo)].Eval(param);
}
//-------------------------------------------------------------
// GetFuncNo (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param idx
*/
int PFunctionHandler::GetFuncNo(unsigned int idx)
{
if (idx > fFuncs.size())
return -1;
return fFuncs[idx].GetFuncNo();
}
//-------------------------------------------------------------
// GetFuncIndex (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param funcNo
*/
int PFunctionHandler::GetFuncIndex(int funcNo)
{
int index = -1;
for (unsigned int i=0; i<fFuncs.size(); i++) {
if (fFuncs[i].GetFuncNo() == funcNo) {
index = i;
break;
}
}
return index;
}
//-------------------------------------------------------------
// GetFuncString (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param idx
*/
TString* PFunctionHandler::GetFuncString(unsigned int idx)
{
if (idx > fFuncs.size())
return 0;
return fFuncs[idx].GetFuncString();
}

1780
src/classes/PMsrHandler.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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 <stdio.h>
#include <iostream>
#include "PMusr.h"
#include "PRunAsymmetry.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunAsymmetry::PRunAsymmetry() : PRunBase()
{
fFitStartTime = 0.0;
fFitStopTime = 0.0;
fNoOfFitBins = 0;
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunAsymmetry::~PRunAsymmetry()
{
fForward.clear();
fForwardErr.clear();
fBackward.clear();
fBackwardErr.clear();
}
//--------------------------------------------------------------------------
// CalcChiSquare
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunAsymmetry::CalcChiSquare(const std::vector<double>& par)
{
double chisq = 0.0;
double diff = 0.0;
double asymFcnValue = 0.0;
double a, b, f;
// calculate functions
for (int i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), fRunInfo->fMap, par);
}
// calculate chisq
for (unsigned int i=0; i<fData.fValue.size(); i++) {
if ((fData.fTime[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
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunAsymmetry::CalcMaxLikelihood(const std::vector<double>& par)
{
cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl;
return 1.0;
}
//--------------------------------------------------------------------------
// CalcTheory
//--------------------------------------------------------------------------
/**
* <p>
*
*/
void PRunAsymmetry::CalcTheory()
{
// feed the parameter vector
std::vector<double> par;
PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
for (unsigned int i=0; i<paramList->size(); i++)
par.push_back((*paramList)[i].fValue);
// calculate functions
for (int i=0; i<fMsrInfo->GetNoOfFuncs(); 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; i<fData.fTime.size(); i++) {
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:
asymFcnValue = 0.0;
break;
}
fData.fTheory.push_back(asymFcnValue);
}
// clean up
par.clear();
}
//--------------------------------------------------------------------------
// PrepareData
//--------------------------------------------------------------------------
/**
* <p>
*
* 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; i<runData->fDataBin[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]; i<end[0]; i++) {
if (((i-start[0]) % fRunInfo->fPacking == 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]; i<end[1]; i++) {
if (((i-start[1]) % fRunInfo->fPacking == 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<forwardPacked.fTime.size(); i++) {
// check that forward time == backward time!!
if (forwardPacked.fTime[i] != backwardPacked.fTime[i]) {
cout << endl << "PRunAsymmetry::PrepareData(): **PANIC ERROR**:";
cout << endl << " forward/backward time are not equal! This cannot be handled";
return false;
}
fData.fTime.push_back(forwardPacked.fTime[i]);
// to make the formulae more readable
f = forwardPacked.fValue[i];
b = backwardPacked.fValue[i];
ef = forwardPacked.fError[i];
eb = backwardPacked.fError[i];
// check that there are indeed bins
if (f+b != 0.0)
asym = (f-b) / (f+b);
else
asym = 0.0;
fData.fValue.push_back(asym);
// calculate the error
if (f+b != 0.0)
error = 2.0/((f+b)*(f+b))*TMath::Sqrt(b*b*ef*ef+eb*eb*f*f);
else
error = 1.0;
fData.fError.push_back(error);
}
/*
FILE *fp = fopen("asym.dat", "w");
for (unsigned int i=0; i<fData.fTime.size(); i++) {
fprintf(fp, "%lf, %lf, %lf\n", fData.fTime[i], fData.fValue[i], fData.fError[i]);
}
fclose(fp);
return false;
*/
// count the number of bins to be fitted
fNoOfFitBins=0;
for (unsigned int i=0; i<fData.fValue.size(); i++) {
if ((fData.fTime[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
//--------------------------------------------------------------------------
/**
* <p>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; i<fForward.size(); i++) {
fForwardErr.push_back(TMath::Sqrt(fForward[i]+fRunInfo->fBkgFix[0]));
fForward[i] -= fRunInfo->fBkgFix[0];
fBackwardErr.push_back(TMath::Sqrt(fBackward[i]+fRunInfo->fBkgFix[1]));
fBackward[i] -= fRunInfo->fBkgFix[1];
}
return true;
}
//--------------------------------------------------------------------------
// SubtractEstimatedBkg
//--------------------------------------------------------------------------
/**
* <p>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]; i++)
bkg[0] += fForward[i];
errBkg[0] = TMath::Sqrt(bkg[0])/(end[0] - start[0] + 1);
bkg[0] /= static_cast<double>(end[0] - start[0] + 1);
// backward
for (unsigned int i=start[1]; i<end[1]; i++)
bkg[1] += fBackward[i];
errBkg[1] = TMath::Sqrt(bkg[1])/(end[0] - start[0] + 1);
bkg[1] /= static_cast<double>(end[1] - start[1] + 1);
// correct error for forward, backward
for (unsigned int i=0; i<fForward.size(); i++) {
fForwardErr.push_back(TMath::Sqrt(fForward[i]+errBkg[0]*errBkg[0]));
fBackwardErr.push_back(TMath::Sqrt(fBackward[i]+errBkg[1]*errBkg[1]));
}
// subtract background from data
for (unsigned int i=0; i<fForward.size(); i++) {
fForward[i] -= bkg[0];
fBackward[i] -= bkg[1];
}
return true;
}

149
src/classes/PRunBase.cpp Normal file
View File

@ -0,0 +1,149 @@
/***************************************************************************
PRunBase.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 <iostream>
#include <TROOT.h>
#include <TSystem.h>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TFile.h>
#include <TFolder.h>
#include "TLemRunHeader.h"
#include "PRunBase.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p> needed otherwise vector's cannot be generated ;-)
*
*/
PRunBase::PRunBase()
{
fRunNo = -1;
fRunInfo = 0;
fRawData = 0;
fTimeResolution = -1.0;
fValid = true;
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \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; i<fMsrInfo->GetNoOfFuncs(); 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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunBase::~PRunBase()
{
fParamNo.clear();
fData.fTime.clear();
fData.fValue.clear();
fData.fError.clear();
fData.fTheory.clear();
fT0s.clear();
fFuncValues.clear();
}
//--------------------------------------------------------------------------
// CleanUp
//--------------------------------------------------------------------------
/**
* <p> Clean up all localy allocate memory
*
*/
void PRunBase::CleanUp()
{
//cout << endl << "PRunBase::CleanUp() ..." << endl;
if (fTheory) {
delete fTheory;
fTheory = 0;
}
}

View File

@ -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 <iostream>
#include <fstream>
using namespace std;
#include <TROOT.h>
#include <TSystem.h>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TFile.h>
#include <TFolder.h>
#include <TH1F.h>
#include "TLemRunHeader.h"
#include "PRunDataHandler.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunDataHandler::~PRunDataHandler()
{
for (unsigned int i=0; i<fData.size(); i++) {
fData[i].fT0s.clear();
for (unsigned int j=0; j<fData[i].fDataBin.size(); j++)
fData[i].fDataBin[j].clear();
}
fData.clear();
}
//--------------------------------------------------------------------------
// GetRunData
//--------------------------------------------------------------------------
/**
* <p>
*
* \param runName
*/
PRawRunData* PRunDataHandler::GetRunData(TString runName)
{
unsigned int i;
for (i=0; i<fData.size(); i++) {
if (!fData[i].fRunName.CompareTo(runName)) // run found
break;
}
if (i == fData.size())
return 0;
else
return &fData[i];
}
//--------------------------------------------------------------------------
// ReadFile
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::FileAlreadyRead(PMsrRunStructure &runInfo)
{
for (unsigned int i=0; i<fData.size(); i++) {
if (!fData[i].fRunName.CompareTo(runInfo.fRunName)) // run alread read
return true;
}
return false;
}
//--------------------------------------------------------------------------
// FileExistsCheck
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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<TLemRunHeader*>(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<noOfHistos; i++)
runData.fT0s.push_back(t0[i]);
}
// read data ---------------------------------------------------------
// check if histos folder is found
f.GetObject("histos", folder);
if (!folder) {
cout << endl << "Couldn't obtain histos from " << fRunPathName.Data() << endl;
f.Close();
return false;
}
// get all the data
char histoName[32];
// read first the data which are NOT post pileup corrected
for (int i=0; i<noOfHistos; i++) {
sprintf(histoName, "hDecay%02d", i);
TH1F *histo = dynamic_cast<TH1F*>(folder->FindObjectAny(histoName));
if (!histo) {
cout << endl << "PRunDataHandler::ReadRootFile: Couldn't get histo " << histoName;
return false;
}
// fill data
for (int j=1; j<histo->GetNbinsX(); 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<noOfHistos; i++) {
sprintf(histoName, "hDecay%02d", i+POST_PILEUP_HISTO_OFFSET);
TH1F *histo = dynamic_cast<TH1F*>(folder->FindObjectAny(histoName));
if (!histo) {
cout << endl << "PRunDataHandler::ReadRootFile: Couldn't get histo " << histoName;
return false;
}
// fill data
for (int j=1; j<histo->GetNbinsX(); 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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::ReadNexusFile()
{
cout << endl << "PRunDataHandler::ReadNexusFile(): Sorry, not yet implemented ...";
return false;
}
//--------------------------------------------------------------------------
// ReadNemuFile
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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<group_counter; i++)
runData.fDataBin[i].clear();
runData.fDataBin.clear();
return false;
}
// feed data
for (int i=0; i<status; i++)
histoData.push_back(val[i]);
}
// save the last histo
runData.fDataBin.push_back(histoData);
histoData.clear();
// close file
f.close();
// check if all groups are found
if ((int) runData.fDataBin.size() != groups) {
cout << endl << "PRunDataHandler::ReadNemuFile(): **ERROR**";
cout << endl << " expected " << groups << " histos, but found " << runData.fDataBin.size();
// clean up
for (unsigned int i=0; i<runData.fDataBin.size(); i++)
runData.fDataBin[i].clear();
runData.fDataBin.clear();
return false;
}
// check if all groups have enough channels
for (unsigned int i=0; i<runData.fDataBin.size(); i++) {
if ((int) runData.fDataBin[i].size() != channels) {
cout << endl << "PRunDataHandler::ReadNemuFile(): **ERROR**";
cout << endl << " expected " << channels << " bins in histo " << i << ", but found " << runData.fDataBin[i].size();
// clean up
for (unsigned int i=0; i<runData.fDataBin.size(); i++)
runData.fDataBin[i].clear();
runData.fDataBin.clear();
return false;
}
}
// keep run name
runData.fRunName = fRunName;
// add run to the run list
fData.push_back(runData);
return true;
}
//--------------------------------------------------------------------------
// ReadPsiBinFile
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::ReadPsiBinFile()
{
cout << endl << "PRunDataHandler::ReadPsiBinFile(): Sorry, not yet implemented ...";
return false;
}
//--------------------------------------------------------------------------
// ReadMudFile
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::ReadMudFile()
{
cout << endl << "PRunDataHandler::ReadMudFile(): Sorry, not yet implemented ...";
return false;
}
//--------------------------------------------------------------------------
// ReadAsciiFile
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::ReadAsciiFile()
{
cout << endl << "PRunDataHandler::ReadAsciiFile(): Sorry, not yet implemented ...";
return false;
}
//--------------------------------------------------------------------------
// StripWhitespace
//--------------------------------------------------------------------------
/**
* <p>
*
* \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<size+1; i++)
s[i] = str[i];
s[size] = 0;
// check for whitespaces at the beginning of the string
i = 0;
while (isblank(s[i]) || iscntrl(s[i])) {
i++;
}
start = i;
// check for whitespaces at the end of the string
i = strlen(s);
while (isblank(s[i]) || iscntrl(s[i])) {
i--;
}
end = i;
if (end < start)
return false;
// make substring
subs = new char[end-start+2];
if (!subs)
return false;
strncpy(subs, s+start, end-start+1);
subs[end-start+1] = 0;
str = TString(subs);
// clean up
if (subs) {
delete [] subs;
subs = 0;
}
if (s) {
delete [] s;
s = 0;
}
return true;
}
//--------------------------------------------------------------------------
// IsWhitespace
//--------------------------------------------------------------------------
/**
* <p>
*
* \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
//--------------------------------------------------------------------------
/**
* <p>
*
* \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<size+1; i++)
s[i] = str[i];
s[size] = 0;
// extract value
status = sscanf(s, "%lf", &value);
if (status != 1) {
ok = false;
return 0.0;
}
// clean up
if (s) {
delete [] s;
s = 0;
}
return value;
}
//--------------------------------------------------------------------------
// ToInt
//--------------------------------------------------------------------------
/**
* <p>
*
* \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<size+1; i++)
s[i] = str[i];
s[size] = 0;
// extract value
status = sscanf(s, "%d", &value);
if (status != 1) {
ok = false;
return 0;
}
// clean up
if (s) {
delete [] s;
s = 0;
}
return value;
}

View File

@ -0,0 +1,366 @@
/***************************************************************************
PRunListCollection.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 <iostream>
#include "PRunListCollection.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunListCollection::~PRunListCollection()
{
//cout << endl << "in ~PRunListCollection() ..." << endl;
//cout << endl << ">> fRunSingleHistoList.size() = " << fRunSingleHistoList.size();
for (unsigned int i=0; i<fRunSingleHistoList.size(); i++)
fRunSingleHistoList[i]->CleanUp();
fRunSingleHistoList.clear();
//cout << endl << ">> fRunAsymmetryList.size() = " << fRunAsymmetryList.size();
for (unsigned int i=0; i<fRunAsymmetryList.size(); i++)
fRunAsymmetryList[i]->CleanUp();
fRunAsymmetryList.clear();
//cout << endl << ">> fRunRRFList.size() = " << fRunRRFList.size();
for (unsigned int i=0; i<fRunRRFList.size(); i++)
fRunRRFList[i]->CleanUp();
fRunRRFList.clear();
//cout << endl << ">> fRunNonMusrList.size() = " << fRunNonMusrList.size();
for (unsigned int i=0; i<fRunNonMusrList.size(); i++)
fRunNonMusrList[i]->CleanUp();
fRunNonMusrList.clear();
}
//--------------------------------------------------------------------------
// Add
//--------------------------------------------------------------------------
/**
* <p>
*
* \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
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetSingleHistoChisq(const std::vector<double>& par)
{
double chisq = 0.0;
for (unsigned int i=0; i<fRunSingleHistoList.size(); i++)
chisq += fRunSingleHistoList[i]->CalcChiSquare(par);
return chisq;
}
//--------------------------------------------------------------------------
// GetAsymmetryChisq
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetAsymmetryChisq(const std::vector<double>& par)
{
double chisq = 0.0;
for (unsigned int i=0; i<fRunAsymmetryList.size(); i++)
chisq += fRunAsymmetryList[i]->CalcChiSquare(par);
return chisq;
}
//--------------------------------------------------------------------------
// GetRRFChisq
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetRRFChisq(const std::vector<double>& par)
{
double chisq = 0.0;
for (unsigned int i=0; i<fRunRRFList.size(); i++)
chisq += fRunRRFList[i]->CalcChiSquare(par);
return chisq;
}
//--------------------------------------------------------------------------
// GetNonMusrChisq
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetNonMusrChisq(const std::vector<double>& par)
{
double chisq = 0.0;
for (unsigned int i=0; i<fRunNonMusrList.size(); i++)
chisq += fRunNonMusrList[i]->CalcChiSquare(par);
return chisq;
}
//--------------------------------------------------------------------------
// GetSingleHistoMaximumLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetSingleHistoMaximumLikelihood(const std::vector<double>& par)
{
double mlh = 0.0;
for (unsigned int i=0; i<fRunSingleHistoList.size(); i++)
mlh += fRunSingleHistoList[i]->CalcMaxLikelihood(par);
return mlh;
}
//--------------------------------------------------------------------------
// GetAsymmetryMaximumLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetAsymmetryMaximumLikelihood(const std::vector<double>& par)
{
double mlh = 0.0;
for (unsigned int i=0; i<fRunAsymmetryList.size(); i++)
mlh += fRunAsymmetryList[i]->CalcMaxLikelihood(par);
return mlh;
}
//--------------------------------------------------------------------------
// GetRRFMaximumLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetRRFMaximumLikelihood(const std::vector<double>& par)
{
double mlh = 0.0;
for (unsigned int i=0; i<fRunRRFList.size(); i++)
mlh += fRunRRFList[i]->CalcMaxLikelihood(par);
return mlh;
}
//--------------------------------------------------------------------------
// GetNonMusrMaximumLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetNonMusrMaximumLikelihood(const std::vector<double>& par)
{
double mlh = 0.0;
for (unsigned int i=0; i<fRunNonMusrList.size(); i++)
mlh += fRunNonMusrList[i]->CalcMaxLikelihood(par);
return mlh;
}
//--------------------------------------------------------------------------
// GetTotalNoOfBinsFitted
//--------------------------------------------------------------------------
/**
* <p>
*/
unsigned int PRunListCollection::GetTotalNoOfBinsFitted()
{
unsigned int counts = 0;
for (unsigned int i=0; i<fRunSingleHistoList.size(); i++)
counts += fRunSingleHistoList[i]->GetNoOfFitBins();
for (unsigned int i=0; i<fRunAsymmetryList.size(); i++)
counts += fRunAsymmetryList[i]->GetNoOfFitBins();
for (unsigned int i=0; i<fRunRRFList.size(); i++)
counts += fRunRRFList[i]->GetNoOfFitBins();
for (unsigned int i=0; i<fRunNonMusrList.size(); i++)
counts += fRunNonMusrList[i]->GetNoOfFitBins();
// cout << endl << "Total No of Bins Fitted = " << counts;
return counts;
}
//--------------------------------------------------------------------------
// GetSingleHisto
//--------------------------------------------------------------------------
/**
* <p>
*
* \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
//--------------------------------------------------------------------------
/**
* <p>
*
* \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
//--------------------------------------------------------------------------
/**
* <p>
*
* \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
//--------------------------------------------------------------------------
/**
* <p>
*
* \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;
}

144
src/classes/PRunNonMusr.cpp Normal file
View File

@ -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 <iostream>
#include "PRunNonMusr.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunNonMusr::PRunNonMusr() : PRunBase()
{
fFitStartTime = 0.0;
fFitStopTime = 0.0;
fNoOfFitBins = 0;
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunNonMusr::~PRunNonMusr()
{
}
//--------------------------------------------------------------------------
// CalcChiSquare
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunNonMusr::CalcChiSquare(const std::vector<double>& par)
{
double chisq = 0.0;
double diff = 0.0;
return chisq;
}
//--------------------------------------------------------------------------
// CalcMaxLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunNonMusr::CalcMaxLikelihood(const std::vector<double>& par)
{
cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl;
return 1.0;
}
//--------------------------------------------------------------------------
// CalcTheory
//--------------------------------------------------------------------------
/**
* <p>
*
*/
void PRunNonMusr::CalcTheory()
{
}
//--------------------------------------------------------------------------
// PrepareData
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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<fData.fValue.size(); i++) {
if ((fData.fTime[i] >= fFitStartTime) && (fData.fTime[i] <= fFitStopTime))
fNoOfFitBins++;
}
return success;
}

144
src/classes/PRunRRF.cpp Normal file
View File

@ -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 <iostream>
#include "PRunRRF.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunRRF::PRunRRF() : PRunBase()
{
fFitStartTime = 0.0;
fFitStopTime = 0.0;
fNoOfFitBins = 0;
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunRRF::~PRunRRF()
{
}
//--------------------------------------------------------------------------
// CalcChiSquare
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunRRF::CalcChiSquare(const std::vector<double>& par)
{
double chisq = 0.0;
double diff = 0.0;
return chisq;
}
//--------------------------------------------------------------------------
// CalcMaxLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunRRF::CalcMaxLikelihood(const std::vector<double>& par)
{
cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl;
return 1.0;
}
//--------------------------------------------------------------------------
// CalcTheory
//--------------------------------------------------------------------------
/**
* <p>
*
*/
void PRunRRF::CalcTheory()
{
}
//--------------------------------------------------------------------------
// PrepareData
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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<fData.fValue.size(); i++) {
if ((fData.fTime[i] >= fFitStartTime) && (fData.fTime[i] <= fFitStopTime))
fNoOfFitBins++;
}
return success;
}

View File

@ -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 <iostream>
#include <fstream>
#include "PMusr.h"
#include "PRunSingleHisto.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunSingleHisto::PRunSingleHisto() : PRunBase()
{
fFitStartTime = 0.0;
fFitStopTime = 0.0;
fNoOfFitBins = 0;
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \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
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunSingleHisto::~PRunSingleHisto()
{
}
//--------------------------------------------------------------------------
// CalcChiSquare
//--------------------------------------------------------------------------
/**
* <p>
*
* 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<double>& 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; i<fMsrInfo->GetNoOfFuncs(); 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<fData.fValue.size(); i++) {
if ((fData.fTime[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; i<fData.fValue.size(); i++) {
// f << endl << fData.fTime[i] << " " << fData.fValue[i] << " " << fData.fError[i];
// }
// f.close();
//
// fln=fRunInfo->fRunName+"_"+(Long_t)fRunInfo->fForwardHistoNo+"_theo.dat";
// ofstream ft(fln.Data(),ios_base::out);
// for (unsigned int i=0; i<fData.fValue.size(); i++) {
// ft << endl << fData.fTime[i] << " " << N0*TMath::Exp(-fData.fTime[i]/tau)*(1+fTheory->Func(fData.fTime[i], par))+bkg;
// }
// ft.close();
// counter++;
// if (counter == 4) exit(0);
return chisq*fRunInfo->fPacking;
}
//--------------------------------------------------------------------------
// CalcMaxLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunSingleHisto::CalcMaxLikelihood(const std::vector<double>& par)
{
cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl;
return 1.0;
}
//--------------------------------------------------------------------------
// CalcTheory
//--------------------------------------------------------------------------
/**
* <p>
*
*/
void PRunSingleHisto::CalcTheory()
{
// feed the parameter vector
std::vector<double> par;
PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
for (unsigned int i=0; i<paramList->size(); 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; i<fMsrInfo->GetNoOfFuncs(); i++) {
fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), fRunInfo->fMap, par);
}
// calculate theory
for (unsigned int i=0; i<fData.fTime.size(); i++) {
fData.fTheory.push_back(N0*TMath::Exp(-fData.fTime[i]/tau)*(1+fTheory->Func(fData.fTime[i], par, fFuncValues))+bkg);
}
// clean up
par.clear();
}
//--------------------------------------------------------------------------
// PrepareData
//--------------------------------------------------------------------------
/**
* <p>
*
*/
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; i<end; i++) {
if (((i-start) % fRunInfo->fPacking == 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<fData.fValue.size(); i++) {
if ((fData.fTime[i] >= fFitStartTime) && (fData.fTime[i] <= fFitStopTime))
fNoOfFitBins++;
}
return true;
}

View File

@ -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
//--------------------------------------------------------------------------
/*!
* <p>
*/
PStartupHandler::PStartupHandler()
{
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/*!
* <p>
*/
PStartupHandler::~PStartupHandler()
{
}
// end ---------------------------------------------------------------------

970
src/classes/PTheory.cpp Normal file
View File

@ -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 <iostream>
using namespace std;
#include <TString.h>
#include <TObjString.h>
#include <TObjArray.h>
#include <TMath.h>
#include "PMsrHandler.h"
#include "PTheory.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p> 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<TObjString*>(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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(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
//--------------------------------------------------------------------------
/**
* <p>
*/
PTheory::~PTheory()
{
//cout << endl << "PTheory::~PTheory() ..." << endl;
fParamNo.clear();
if (fMul) {
delete fMul;
fMul = 0;
}
if (fAdd) {
delete fAdd;
fAdd = 0;
}
}
//--------------------------------------------------------------------------
// IsValid
//--------------------------------------------------------------------------
/**
* <p>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;
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t
* \param paramValues
*/
double PTheory::Func(register double t, const vector<double>& paramValues, const vector<double>& 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;
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param name
*/
unsigned int PTheory::SearchDataBase(TString name)
{
unsigned int idx = THEORY_UNDEFINED;
for (unsigned int i=0; i<THEORY_MAX; i++) {
if (!name.CompareTo(fgTheoDataBase[i].fName, TString::kIgnoreCase) ||
!name.CompareTo(fgTheoDataBase[i].fAbbrev, TString::kIgnoreCase)) {
idx = fgTheoDataBase[i].fType;
fType = idx;
fNoOfParam = fgTheoDataBase[i].fNoOfParam;
}
}
return idx;
}
//--------------------------------------------------------------------------
// MakeCleanAndTidyTheoryBlock private
//--------------------------------------------------------------------------
/**
* <p>
*
* \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; i<fullTheoryBlock->size(); 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<TObjString*>(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; j<THEORY_MAX; j++) {
if (!str.CompareTo(fgTheoDataBase[j].fName, TString::kIgnoreCase) ||
!str.CompareTo(fgTheoDataBase[j].fAbbrev, TString::kIgnoreCase)) {
idx = fgTheoDataBase[j].fType;
}
}
// check if theory is indeed defined. This should not be necessay at this point but ...
if (idx == (unsigned int)THEORY_UNDEFINED)
continue;
// check that there enough tokens. This should not be necessay at this point but ...
if ((unsigned int)tokens->GetEntries() < fgTheoDataBase[idx].fNoOfParam + 1)
continue;
// make tidy string
sprintf(substr, "%-10s", fgTheoDataBase[idx].fName.Data());
tidy = TString(substr);
for (unsigned j=1; j<fgTheoDataBase[idx].fNoOfParam+1; j++) {
ostr = dynamic_cast<TObjString*>(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;
}
}
//--------------------------------------------------------------------------
/**
* <p> Asymmetry
* \f[ = A \f]
*
* <p> 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<double>& paramValues, const vector<double>& 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;
}
//--------------------------------------------------------------------------
/**
* <p> Simple exponential
* \f[ = \exp\left(-\lambda t\right) \f].
*
* <p> 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<double>& paramValues, const vector<double>& 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);
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::GeneralExp(register double t, const vector<double>& paramValues, const vector<double>& 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]));
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::SimpleGauss(register double t, const vector<double>& paramValues, const vector<double>& 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));
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::StaticGaussKT(register double t, const vector<double>& paramValues, const vector<double>& 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));
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::StaticKTTable(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
return 0.0;
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::DynamicKTTable(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
return 0.0;
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::CombiLGKT(register double t, const vector<double>& paramValues, const vector<double>& 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)));
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::SpinGlass(register double t, const vector<double>& paramValues, const vector<double>& 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));
}
//--------------------------------------------------------------------------
/**
* <p>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<double>& paramValues, const vector<double>& 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));
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::Abragam(register double t, const vector<double>& paramValues, const vector<double>& 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));
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::InternalField(register double t, const vector<double>& paramValues, const vector<double>& 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);
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::TFCos(register double t, const vector<double>& paramValues, const vector<double>& 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);
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::Bessel(register double t, const vector<double>& paramValues, const vector<double>& 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);
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::InternalBessel(register double t, const vector<double>& paramValues, const vector<double>& 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);
}

97
src/include/PFitter.h Normal file
View File

@ -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_

58
src/include/PFitterFcn.h Normal file
View File

@ -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 <vector>
#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<double>&) const;
unsigned int GetTotalNoOfFittedBins() { return fRunListCollection->GetTotalNoOfBinsFitted(); }
private:
double fUp;
bool fUseChi2;
PRunListCollection *fRunListCollection;
};
#endif // _PFITTERFCN_H_

114
src/include/PFunction.h Normal file
View File

@ -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 <vector>
#include <boost/spirit/tree/ast.hpp>
using namespace boost::spirit;
#include <TString.h>
#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<func_tree_node> 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<double> param);
virtual void SetMap(vector<int> 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<double> fParam;
vector<int> 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_

View File

@ -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 <iostream>
using namespace std;
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/core.hpp>
#include <boost/spirit/tree/ast.hpp>
using namespace boost::spirit;
typedef char const* iterator_t;
typedef tree_match<iterator_t> parse_tree_match_t;
typedef parse_tree_match_t::tree_iterator iter_t;
//--------------------------------------------------------------------------
/**
*
*/
struct PFunctionGrammar : public grammar<PFunctionGrammar>
{
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 <typename ScannerT>
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<ScannerT, parser_context<>, parser_tag<assignmentID> > assignment;
rule<ScannerT, parser_context<>, parser_tag<expressionID> > expression;
rule<ScannerT, parser_context<>, parser_tag<termID> > term;
rule<ScannerT, parser_context<>, parser_tag<factorID> > factor;
rule<ScannerT, parser_context<>, parser_tag<functionID> > function;
rule<ScannerT, parser_context<>, parser_tag<mapID> > map;
rule<ScannerT, parser_context<>, parser_tag<parameterID> > parameter;
rule<ScannerT, parser_context<>, parser_tag<funLabelID> > fun_label;
rule<ScannerT, parser_context<>, parser_tag<realID> > real;
rule<ScannerT, parser_context<>, parser_tag<assignmentID> > const&
start() const { return assignment; }
};
};
#endif // _PFUNCTIONGRAMMAR_H_

View File

@ -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 <iostream>
#include <vector>
using namespace std;
#include <TString.h>
#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<int> map, vector<double> 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<PFunction> fFuncs;
};
#endif // _PFUNCTIONHANDLER_H_

114
src/include/PMsrHandler.h Normal file
View File

@ -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 <vector>
using namespace std;
*/
#include <TString.h>
#include <TComplex.h>
#include "PMusr.h"
#include "PFunctionHandler.h"
#include "PFunctionGrammar.h"
#include "PFunction.h"
//-------------------------------------------------------------
/**
* <p>
*/
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<int> map, vector<double> 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 &param);
virtual bool FilterFunMapNumber(TString str, const char *filter, int &no);
};
#endif // _PMSRHANDLER_H_

253
src/include/PMusr.h Normal file
View File

@ -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 <vector>
using namespace std;
#include <TComplex.h>
#include <TString.h>
#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
//-------------------------------------------------------------
/**
* <p> typedef to make to code more readable.
*/
typedef vector<int> PIntVector;
//------------------------------------------------------------------------
/**
* <p>
*/
typedef vector<double> PDoubleVector;
//-------------------------------------------------------------
/**
* <p> typedef to make to code more readable.
*/
typedef vector<TComplex> PComplexVector;
//------------------------------------------------------------------------------------------
/**
* <p>Predominantly used in PRunBase.
*/
typedef struct {
vector<double> fTime;
vector<double> fValue;
vector<double> fError;
vector<double> fTheory;
} PRunData;
//------------------------------------------------------------------------
/**
* <p>
*/
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<unsigned int> fT0s; ///< vector of t0's of a run
vector<PDoubleVector> fDataBin; ///< vector of all histos of a run
} PRawRunData;
//------------------------------------------------------------------------
/**
* <p>
*/
typedef vector<PRawRunData> PRawRunDataList;
//-------------------------------------------------------------
/**
* <p> 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;
//-------------------------------------------------------------
/**
* <p> typedef to make to code more readable: list of msr-file lines.
*/
typedef vector<PMsrLineStructure> PMsrLines;
//-------------------------------------------------------------
/**
* <p> 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;
//-------------------------------------------------------------
/**
* <p> typedef to make to code more readable: vector of fit parameters.
*/
typedef vector<PMsrParamStructure> PMsrParamList;
//-------------------------------------------------------------
/**
* <p> 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;
//-------------------------------------------------------------
/**
* <p> typedef to make to code more readable: list of runs with its parameters.
*/
typedef vector<PMsrRunStructure> PMsrRunList;
//-------------------------------------------------------------
/**
* <p> 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;
//-------------------------------------------------------------
/**
* <p> typedef to make to code more readable: list of plots.
*/
typedef vector<PMsrPlotStructure> PMsrPlotList;
//-------------------------------------------------------------
/**
* <p>
*/
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_

View File

@ -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<double>& par);
virtual double CalcMaxLikelihood(const std::vector<double>& 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<double> fForward; ///< forward histo data
vector<double> fForwardErr; ///< forward histo errors
vector<double> fBackward; ///< backward histo data
vector<double> fBackwardErr; ///< backward histo errors
bool SubtractFixBkg();
bool SubtractEstimatedBkg();
};
#endif // _PRUNASYMMETRY_H_

97
src/include/PRunBase.h Normal file
View File

@ -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 <vector>
using namespace std;
#include <TString.h>
#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<double>& par) = 0; // pure virtual, i.e. needs to be implemented by the deriving class!!
virtual double CalcMaxLikelihood(const vector<double>& 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<int> fParamNo; ///< vector of parameter numbers for the specifc run
PRunData fData; ///< data to be fitted
double fTimeResolution; ///< time resolution
vector<int> 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<double> fFuncValues; ///< is keeping the values of the functions from the FUNCTIONS block
PTheory *fTheory; ///< theory needed to calculate chi-square
};
#endif // _PRUNBASE_H_

View File

@ -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 <vector>
using namespace std;
#include <TString.h>
#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_

View File

@ -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 <vector>
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<double>& par);
virtual double GetAsymmetryChisq(const std::vector<double>& par);
virtual double GetRRFChisq(const std::vector<double>& par);
virtual double GetNonMusrChisq(const std::vector<double>& par);
virtual double GetSingleHistoMaximumLikelihood(const std::vector<double>& par);
virtual double GetAsymmetryMaximumLikelihood(const std::vector<double>& par);
virtual double GetRRFMaximumLikelihood(const std::vector<double>& par);
virtual double GetNonMusrMaximumLikelihood(const std::vector<double>& 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<PRunSingleHisto*> fRunSingleHistoList;
vector<PRunAsymmetry*> fRunAsymmetryList;
vector<PRunRRF*> fRunRRFList;
vector<PRunNonMusr*> fRunNonMusrList;
};
#endif // _PRUNLISTCOLLECTION_H_

59
src/include/PRunNonMusr.h Normal file
View File

@ -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<double>& par);
virtual double CalcMaxLikelihood(const std::vector<double>& 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_

59
src/include/PRunRRF.h Normal file
View File

@ -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<double>& par);
virtual double CalcMaxLikelihood(const std::vector<double>& 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_

View File

@ -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<double>& par);
virtual double CalcMaxLikelihood(const std::vector<double>& 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_

View File

@ -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 <TSAXParser.h>
#include <TString.h>
class PStartupHandler : public TSAXParser
{
public:
PStartupHandler();
virtual ~PStartupHandler();
};
#endif // _PSTARTUPHANDLER_H_

202
src/include/PTheory.h Normal file
View File

@ -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 <vector>
#include <TString.h>
#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;
//--------------------------------------------------------------------------------------
/**
* <p>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;
//--------------------------------------------------------------------------------------
/*!
* <p> 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)"}};
//--------------------------------------------------------------------------------------
/**
* <p>
*/
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<double>& paramValues, const vector<double>& funcValues) const;
private:
virtual unsigned int SearchDataBase(TString name);
virtual void MakeCleanAndTidyTheoryBlock(PMsrLines* fullTheoryBlock);
virtual double Asymmetry(const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double SimpleExp(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double GeneralExp(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double SimpleGauss(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double StaticGaussKT(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double StaticKTTable(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double DynamicKTTable(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double CombiLGKT(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double SpinGlass(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double RandomAnisotropicHyperfine(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double Abragam(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double InternalField(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double TFCos(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double Bessel(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double InternalBessel(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
// variables
bool fValid;
unsigned int fType;
vector<unsigned int> 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_

247
src/msr2msr.cpp Normal file
View File

@ -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 <iostream>
#include <fstream>
using namespace std;
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
//-------------------------------------------------------------
// 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 <msr-file-in> <msr-file-out> | [--help]";
cout << endl << " <msr-file-in> : input msr-file";
cout << endl << " <msr-file-out>: converted msr-output-file";
cout << endl << " if the <msr-file-in> 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 <msr-file-out> is created";
cout << endl;
return false;
}
if (run.Contains("NEMU")) {
ostr[0] = dynamic_cast<TObjString*>(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<TObjString*>(tokens->At(1)); // file name
ostr[1] = dynamic_cast<TObjString*>(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<TObjString*>(tokens->At(1)); // file name
ostr[1] = dynamic_cast<TObjString*>(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<TObjString*>(tokens->At(1)); // file name
ostr[1] = dynamic_cast<TObjString*>(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<TObjString*>(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<strlen(str); i++) {
if (!isblank(str[i]) || !iscntrl(str[i]))
break;
}
if (i == strlen(str)) // end reached
tag = MSR_TAG_NO_BLOCK;
}
//--------------------------------------------------------------------------
int main(int argc, char *argv[])
{
// check the number of arguments
if (argc != 3) {
msr2msr_syntax();
return 0;
}
// open input msr-file
ifstream fin;
fin.open(argv[1], iostream::in);
if (!fin.is_open()) {
cout << endl << "**ERROR**: Couldn't open input msr-file " << argv[1];
cout << endl << " Will quit." << endl;
return 0;
}
// open input msr-file
ofstream fout;
fout.open(argv[2], iostream::out);
if (!fout.is_open()) {
cout << endl << "**ERROR**: Couldn't open output msr-file " << argv[2];
cout << endl << " Will quit." << endl;
fin.close();
return 0;
}
// read input file and write output file
char str[256];
int tag;
bool success = true;
while (!fin.eof() && success) {
fin.getline(str, sizeof(str));
if (strstr(str, "FITPARAMETER")) {
tag = MSR_TAG_FITPARAMETER;
} else if (strstr(str, "RUN")) { // analyze and change header
success = msr2msr_run(str);
}
if (tag == MSR_TAG_FITPARAMETER) {
msr2msr_param(str, tag);
}
fout << str << endl;
}
// close files
fout.close();
fin.close();
// check if conversion seems to be OK
if (!success) {
sprintf(str, "rm -rf %s", argv[2]);
system(str);
}
// clean up
return 1;
}

22
src/msr2msr.pro Normal file
View File

@ -0,0 +1,22 @@
#------------------------------------------------------
# msr2msr.pro
# qmake file for msr2msr
#
# Andreas Suter, 2008/01/03
#
# $Id$
#
#------------------------------------------------------
MAKEFILE = Makefile.msr2msr
CONFIG += warn_on debug
SOURCES = msr2msr.cpp \
INCLUDEPATH += $$(ROOTSYS)/include
ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs)
unix:LIBS += $${ROOTLIBS}
TARGET=msr2msr

615
src/musrfit.cpp Normal file
View File

@ -0,0 +1,615 @@
/***************************************************************************
musrfit.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 <iostream>
#include <fstream>
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"
//--------------------------------------------------------------------------
/**
* <p>
*
*/
void musrfit_syntax()
{
cout << endl << "usage: musrfit [<msr-file> [--debug] | [--dump <type>]] | --version | --help";
cout << endl << " <msr-file>: msr input file";
cout << endl << " 'msrfit <msf-file>' 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 <type> is writing a data file with the fit data and the theory";
cout << endl << " <type> can be 'ascii', 'root'";
cout << endl << endl;
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \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;
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \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; i<data->fTime.size(); i++) {
f << data->fTime[i] << ", " << data->fValue[i] << ", " << data->fError[i] << ", " << data->fTheory[i] << endl;
}
// close file
f.close();
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \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; i<size; i++) {
data = runList->GetSingleHisto(i);
if (data) {
// dump data
musrfit_write_ascii(fln, data, runCounter);
runCounter++;
}
}
}
// asymmetry
size = runList->GetNoOfAsymmetry();
if (size > 0) {
for (unsigned int i=0; i<size; i++) {
data = runList->GetAsymmetry(i);
if (data) {
// dump data
musrfit_write_ascii(fln, data, runCounter);
runCounter++;
}
}
}
// rrf
size = runList->GetNoOfRRF();
if (size > 0) {
for (unsigned int i=0; i<size; i++) {
data = runList->GetRRF(i);
if (data) {
// dump data
musrfit_write_ascii(fln, data, runCounter);
runCounter++;
}
}
}
// nonMusr
size = runList->GetNoOfNonMusr();
if (size > 0) {
for (unsigned int i=0; i<size; i++) {
data = runList->GetNonMusr(i);
if (data) {
// dump data
musrfit_write_ascii(fln, data, runCounter);
runCounter++;
}
}
}
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \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; i<data->fTime.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;
}
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \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; i<size; i++) {
data = runList->GetSingleHisto(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; i<size; i++) {
data = runList->GetAsymmetry(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; i<size; i++) {
data = runList->GetRRF(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; i<size; i++) {
data = runList->GetNonMusr(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 ---------------------------------------------------------------------

25
src/musrfit.pro Normal file
View File

@ -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

View File

@ -0,0 +1,32 @@
#include <fstream>
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;
}

View File

@ -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

View File

@ -0,0 +1 @@
0.258467 0.258467 0.258467

View File

@ -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 <math.h>
#include <iostream>
#include "PGlobalChiSquare.h"
namespace ROOT {
namespace Minuit2 {
//--------------------------------------------------------------------------
/**
* <p>
*/
PGlobalChiSquare::PGlobalChiSquare(PRunList &runList)
{
fRunList = runList;
}
//--------------------------------------------------------------------------
/**
* <p>
*/
PGlobalChiSquare::~PGlobalChiSquare()
{
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par
*/
double PGlobalChiSquare::operator()(const std::vector<double>& par) const
{
double chi2 = 0.0;
double funcValue;
double diff;
// calculate chi2 for the given model
for (unsigned int i=0; i<fRunList.size(); i++) { // run loop
for (unsigned int j=0; j<fRunList[i].fTime.size(); j++) { // data loop
funcValue = par[i]*exp(-par[2]*fRunList[i].fTime[j]); // par[i] since par[0] = ampl of run 0, etc.
diff = funcValue - fRunList[i].fValue[j];
chi2 += diff*diff/(fRunList[i].fError[j]*fRunList[i].fError[j]);
}
}
return chi2;
}
} // namespace Minuit2
} // namespace ROOT

View File

@ -0,0 +1,62 @@
/***************************************************************************
PGlobalChiSquare.h
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. *
***************************************************************************/
#ifndef _PGLOBALCHISQUARE_H_
#define _PGLOBALCHISQUARE_H_
#include <vector>
#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<double>&) const;
private:
PRunList fRunList;
};
} // namespace Minuit2
} // namespace ROOT
#endif // _PGLOBALCHISQUARE_H_

View File

@ -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 <stdlib.h>
#include <math.h>
#include <iostream>
#include <vector>
#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;
//----------------------------------------------------------------------------
/**
* <p>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<length; j++) { // data loop
run.fTime.push_back((double)j/(double)length);
value = (2*i+10)*exp(-1.7*(double)j/(double)length);
value += 2.0*sqrt(value)*((double)random()/(double)RAND_MAX-0.5);
run.fValue.push_back(value);
run.fError.push_back(sqrt(value/4.0));
}
data.push_back(run);
// clean up
run.fTime.clear();
run.fValue.clear();
run.fError.clear();
}
}
//----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
if (argc || argv);
int success = 1;
PRunList runs;
generateData(runs);
unsigned int max = 25;
if (runs[0].fTime.size() < max)
max = runs[0].fTime.size();
for (unsigned int i=0; i<runs.size(); i++) { // run loop
std::cout << std::endl << "run " << i;
for (unsigned int j=0; j<max; j++) { // data loop
std::cout << std::endl << runs[i].fTime[j] << ", " << runs[i].fValue[j] << ", " << runs[i].fError[j];
}
std::cout << std::endl;
}
PGlobalChiSquare chi2(runs); // chi2 object derived from ROOT::Minuit2::FCNBase
// create parameters ---------------------------------
MnUserParameters upar;
// model = ampl_i * exp(-lambda * t), i = run no.
upar.Add("ampl1", 10.0, 1.0); // ampl1
upar.Add("ampl2", 12.0, 1.0); // ampl2
upar.Add("lambda", 0.1, 0.01); // lambda
// create minimizer ---------------------------------
MnMinimize minimize(chi2, upar);
// minimize
FunctionMinimum min = minimize();
if (min.IsValid()) {
std::cout << std::endl << "minimize (MIGRAD/SIMPLEX) found minimum ...";
} else {
std::cout << std::endl << "minimize (MIGRAD/SIMPLEX) failed to find minimum ...";
}
std::cout << std::endl << "Chi2 = " << min.Fval()
<< ", NDF = " << 2*runs[0].fTime.size()-3
<< ", Chi2r = " << min.Fval()/((double)(2*runs[0].fTime.size()-3)) << std::endl;
// make minos analysis
MnMinos minos(chi2, min);
// 1-sigma MINOS errors
std::pair<double, double> e0 = minos(0);
std::pair<double, double> e1 = minos(1);
std::pair<double, double> e2 = minos(2);
// print out parameters
unsigned int i=0;
std::cout << std::endl << "1-sigma minos errors:" << std::endl;
i=0;
std::cout << std::endl << upar.Name(i) << ": "
<< min.UserState().Value(i) << " "
<< e0.first << " "
<< e0.second;
i++;
std::cout << std::endl << upar.Name(i) << ": "
<< min.UserState().Value(i) << " "
<< e1.first << " "
<< e1.second;
i++;
std::cout << std::endl << upar.Name(i) << ": "
<< min.UserState().Value(i) << " "
<< e2.first << " "
<< e2.second;
std::cout << std::endl << std::endl;
// clean up
runs.clear();
return success;
}

View File

@ -0,0 +1,45 @@
/***************************************************************************
mn2test.h
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. *
***************************************************************************/
#ifndef _MN2TEST_H_
#define _MN2TEST_H_
#include <vector>
typedef struct {
std::vector<double> fTime;
std::vector<double> fValue;
std::vector<double> fError;
} PRun;
typedef std::vector<PRun> PRunList;
#endif // _MN2TEST_H_

View File

@ -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

View File

@ -0,0 +1,22 @@
#include <math.h>
#include <iostream>
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;
}

View File

@ -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

View File

@ -0,0 +1,110 @@
#include <iostream>
using namespace std;
#include <TROOT.h>
#include <TSystem.h>
#include <TFile.h>
#include <TFolder.h>
#include <TH1F.h>
#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<TLemRunHeader*>(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<TH1F*>(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; i<max; i++) {
cout << endl << i << ": " << histo->GetBinContent(i+1);
}
if (f.IsOpen())
f.Close();
cout << endl << "closed file .." << endl;
if (str)
delete str;
cout << endl;
return 0;
}

View File

@ -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

View File

@ -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();
}

View File

@ -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);
}

View File

@ -0,0 +1,105 @@
/*******************************************************************
minuit2test.C
author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
********************************************************************/
#include <iostream>
#include <TF1.h>
#include <TH1.h>
#include <TVirtualFitter.h>
#include <TCanvas.h>
#include <TMath.h>
const double gGammaMu = TMath::TwoPi()*0.01355;
const double gTauMu = 2.19705; // in (us)
TF1 *gFitFcn;
//------------------------------------------------------------------
/**
* <p>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];
}
//------------------------------------------------------------------
/**
* <p>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());
}
//------------------------------------------------------------------
/**
* <p>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]);
}
//------------------------------------------------------------------
/**
* <p>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
}

View File

@ -0,0 +1,35 @@
#include <iostream>
using namespace std;
#include <TROOT.h>
#include <TSystem.h>
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;
}

View File

@ -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

View File

View File

@ -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<cmath>
#include <iostream>
using namespace std;
#include "PFunction.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* 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<double> param, vector<int> 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
//--------------------------------------------------------------------------
/**
* <p>
*/
PFunction::~PFunction()
{
// cout << endl << "in ~PFunction ...";
fParam.clear();
fMap.clear();
CleanupFuncEvalTree();
}
//-------------------------------------------------------------
// CheckParameterRange (protected)
//-------------------------------------------------------------
/**
* <p>
*
*/
bool PFunction::CheckParameterAndMapRange()
{
return CheckParameterAndMapInTree(fInfo.trees.begin());
}
//-------------------------------------------------------------
// CheckParameterAndMapInTree (protected)
//-------------------------------------------------------------
/**
* <p> 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)
//-------------------------------------------------------------
/**
* <p>
*
* \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)
//-------------------------------------------------------------
/**
* <p>
*
*/
bool PFunction::GenerateFuncEvalTree()
{
FillFuncEvalTree(fInfo.trees.begin(), fFunc);
return true;
}
//-------------------------------------------------------------
// FillFuncEvalTree (protected)
//-------------------------------------------------------------
/**
* <p>
*
*/
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)
//-------------------------------------------------------------
/**
* <p>
*
*/
double PFunction::Eval()
{
return EvalNode(fFunc);
}
//-------------------------------------------------------------
// EvalNode (protected)
//-------------------------------------------------------------
/**
* <p>
*
* \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)
//-------------------------------------------------------------
/**
* <p>
*
*/
void PFunction::CleanupFuncEvalTree()
{
// clean up all children
CleanupNode(fFunc);
}
//-------------------------------------------------------------
// CleanupNode (protected)
//-------------------------------------------------------------
/**
* <p>
*
* \param node
*/
void PFunction::CleanupNode(PFuncTreeNode &node)
{
if (node.children.size() != 0) {
for (unsigned int i=0; i<node.children.size(); i++) {
CleanupNode(node.children[i]);
}
node.children.clear();
}
}
//-------------------------------------------------------------
// EvaluateTree (protected)
//-------------------------------------------------------------
long PFunction::EvaluateTree(tree_parse_info<> 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;
}

View File

@ -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 <vector>
#include <string>
#include <boost/spirit/tree/ast.hpp>
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<func_tree_node> children; ///< holding sub-tree
} PFuncTreeNode;
//----------------------------------------------------------------------------
class PFunction {
public:
PFunction(tree_parse_info<> info, vector<double> param, vector<int> 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<double> fParam;
vector<int> 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_

View File

@ -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 <iostream>
using namespace std;
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/core.hpp>
#include <boost/spirit/tree/ast.hpp>
using namespace boost::spirit;
typedef char const* iterator_t;
typedef tree_match<iterator_t> parse_tree_match_t;
typedef parse_tree_match_t::tree_iterator iter_t;
//--------------------------------------------------------------------------
/**
*
*/
struct PFunctionGrammar : public grammar<PFunctionGrammar>
{
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 <typename ScannerT>
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<ScannerT, parser_context<>, parser_tag<assignmentID> > assignment;
rule<ScannerT, parser_context<>, parser_tag<expressionID> > expression;
rule<ScannerT, parser_context<>, parser_tag<termID> > term;
rule<ScannerT, parser_context<>, parser_tag<factorID> > factor;
rule<ScannerT, parser_context<>, parser_tag<functionID> > function;
rule<ScannerT, parser_context<>, parser_tag<mapID> > map;
rule<ScannerT, parser_context<>, parser_tag<parameterID> > parameter;
rule<ScannerT, parser_context<>, parser_tag<funLabelID> > fun_label;
rule<ScannerT, parser_context<>, parser_tag<realID> > real;
rule<ScannerT, parser_context<>, parser_tag<assignmentID> > const&
start() const { return assignment; }
};
};
#endif // _PFUNCTIONGRAMMAR_H_

View File

@ -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 <string>
#include <cassert>
#include <qfile.h>
#include <qtextstream.h>
#include <qstring.h>
#include "PFunctionHandler.h"
//-------------------------------------------------------------
// Constructor
//-------------------------------------------------------------
/**
* <p>
*
* \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
//-------------------------------------------------------------
/**
* <p>
*
* \param lines
*/
PFunctionHandler::PFunctionHandler(vector<QString> lines)
{
fValid = true;
fFileName = "";
cout << endl << "in PFunctionHandler(vector<QString> 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<lines.size(); i++) {
if (lines[i].startsWith("#")) // comment hence ignore
continue;
lines[i] = lines[i].upper();
if (lines[i].startsWith("PAR")) {
cout << endl << "this is a parameter line ...";
status = sscanf(lines[i].latin1(), "PAR %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
&dval[0], &dval[1], &dval[2], &dval[3], &dval[4],
&dval[5], &dval[6], &dval[7], &dval[8], &dval[9]);
if (status < 0) {
done = true;
fValid = false;
cout << endl << "invalid PAR line, sorry ...";
} else { // fill map
cout << endl << "PAR line, status = " << status;
for (int i=0; i<status; i++)
fParam.push_back(dval[i]);
}
} else if (lines[i].startsWith("MAP")) {
cout << endl << "this is a map line ...";
status = sscanf(lines[i].latin1(), "MAP %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]);
if (status < 0) {
done = true;
fValid = false;
cout << endl << "invalid MAP line, sorry ...";
} else { // fill map
cout << endl << "MAP line, status = " << status;
for (int i=0; i<status; i++)
fMap.push_back(val[i]);
}
} else if (lines[i].startsWith("FUNCTIONS")) {
cout << endl << "the functions block start ...";
inFcnBlock = true;
} else if (lines[i].startsWith("END")) {
cout << endl << "end tag found; rest will be ignored";
done = true;
} else if (inFcnBlock) {
fLines.push_back(lines[i]);
}
}
// check if all blocks are given
if ((fMap.size() == 0) || (fParam.size() == 0) || (fLines.size() == 0)) {
if (fMap.size() == 0)
cout << endl << "MAP block is missing ...";
if (fParam.size() == 0)
cout << endl << "PAR block is missing ...";
if (fLines.size() == 0)
cout << endl << "FUNCTION block is missing ...";
fValid = false;
}
fValid = MapsAreValid();
if (fValid) {
cout << endl << "Functions: ";
for (unsigned int i=0; i<fLines.size(); i++)
cout << endl << fLines[i].latin1();
}
}
//-------------------------------------------------------------
// Destructor
//-------------------------------------------------------------
/**
* <p>
*
*/
PFunctionHandler::~PFunctionHandler()
{
cout << endl << "in ~PFunctionHandler()" << endl << endl;
fParam.clear();
fMap.clear();
fLines.clear();
fFuncs.clear();
}
//-------------------------------------------------------------
// DoParse (public)
//-------------------------------------------------------------
/**
* <p>
*
*/
bool PFunctionHandler::DoParse()
{
cout << endl << "in PFunctionHandler::DoParse() ...";
bool success = true;
PFunctionGrammar function;
for (unsigned int i=0; i<fLines.size(); i++) {
cout << endl << "fLines[" << i << "] = '" << fLines[i].latin1() << "'";
tree_parse_info<> 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<fFuncs.size(); i++) {
if (!fFuncs[i].IsValid()) {
cout << endl << "**ERROR**: function fun" << fFuncs[i].GetFuncNo();
cout << " has a problem with either parameter or map out of range!";
success = false;
break;
}
}
}
// check that the function numbers are unique
if (success) {
for (unsigned int i=0; i<fFuncs.size(); i++) {
for (unsigned int j=i+1; j<fFuncs.size(); j++) {
if (fFuncs[i].GetFuncNo() == fFuncs[j].GetFuncNo()) {
cout << endl << "**ERROR**: function number " << fFuncs[i].GetFuncNo();
cout << " is at least twice present! Fix this first.";
success = false;
}
}
}
}
if (success) {
for (unsigned int i=0; i<fFuncs.size(); i++)
cout << endl << "func number = " << fFuncs[i].GetFuncNo();
}
return success;
}
//-------------------------------------------------------------
// Eval (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param i
*/
double PFunctionHandler::Eval(int i)
{
if (GetFuncIndex(i) == -1) {
cout << endl << "**ERROR**: Couldn't find FUN" << i << " for evaluation";
return 0.0;
}
cout << endl << "PFunctionHandler::Eval: GetFuncIndex("<<i<<") = " << GetFuncIndex(i);
cout << endl;
return fFuncs[GetFuncIndex(i)].Eval();
}
//-------------------------------------------------------------
// GetFuncNo (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param i
*/
unsigned int PFunctionHandler::GetFuncNo(unsigned int i)
{
if (i > fFuncs.size())
return -1;
return fFuncs[i].GetFuncNo();
}
//-------------------------------------------------------------
// ReadFile (private)
//-------------------------------------------------------------
/**
* <p>
*
*/
bool PFunctionHandler::ReadFile()
{
cout << endl << "in ~PFunctionHandler::ReadFile()";
if (fFileName.isEmpty()) {
cout << endl << "PFunctionHandler::ReadFile(): **ERROR**";
cout << endl << " no file name given :-(. Will quit";
return false;
}
QFile f(fFileName);
if (!f.exists()) {
cout << endl << "PFunctionHandler::ReadFile(): **ERROR**";
cout << endl << " File '" << fFileName.latin1() << "' does not exist.";
return false;
}
if (!f.open(IO_ReadOnly)) {
cout << endl << "PFunctionHandler::ReadFile(): **ERROR**";
cout << endl << " File '" << fFileName.latin1() << "' couldn't being opened.";
return false;
}
QTextStream stream(&f);
QString line;
bool done = false;
bool success = true;
int status;
int val[10];
double dval[10];
bool inFcnBlock = false;
while ( !stream.atEnd() && !done) {
line = stream.readLine(); // line of text excluding '\n'
if (line.startsWith("#")) // comment hence ignore
continue;
line = line.upper();
if (line.startsWith("PAR")) {
cout << endl << "this is a parameter line ...";
status = sscanf(line.latin1(), "PAR %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
&dval[0], &dval[1], &dval[2], &dval[3], &dval[4],
&dval[5], &dval[6], &dval[7], &dval[8], &dval[9]);
if (status < 0) {
done = true;
success = false;
cout << endl << "invalid PAR line, sorry ...";
} else { // fill map
cout << endl << "PAR line, status = " << status;
for (int i=0; i<status; i++)
fParam.push_back(dval[i]);
}
} else if (line.startsWith("MAP")) {
cout << endl << "this is a map line ...";
status = sscanf(line.latin1(), "MAP %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]);
if (status < 0) {
done = true;
success = false;
cout << endl << "invalid MAP line, sorry ...";
} else { // fill map
cout << endl << "MAP line, status = " << status;
for (int i=0; i<status; i++)
fMap.push_back(val[i]);
}
} else if (line.startsWith("FUNCTIONS")) {
cout << endl << "the functions block start ...";
inFcnBlock = true;
} else if (line.startsWith("END")) {
cout << endl << "end tag found; rest will be ignored";
done = true;
} else if (inFcnBlock) {
fLines.push_back(line);
}
}
f.close();
// check if all blocks are given
if ((fMap.size() == 0) || (fParam.size() == 0) || (fLines.size() == 0)) {
if (fMap.size() == 0)
cout << endl << "MAP block is missing ...";
if (fParam.size() == 0)
cout << endl << "PAR block is missing ...";
if (fLines.size() == 0)
cout << endl << "FUNCTION block is missing ...";
success = false;
}
if (success) {
cout << endl << "Functions: ";
for (unsigned int i=0; i<fLines.size(); i++)
cout << endl << fLines[i].latin1();
}
return success;
}
//-------------------------------------------------------------
// MapsAreValid (private)
//-------------------------------------------------------------
/**
* <p>
*
*/
bool PFunctionHandler::MapsAreValid()
{
bool success = true;
int maxParam = fParam.size();
for (unsigned int i=0; i<fMap.size(); i++)
if (fMap[i] > maxParam)
success = false;
if (!success)
cout << endl << "invalid MAP found ...";
return success;
}
//-------------------------------------------------------------
// GetFuncIndex (private)
//-------------------------------------------------------------
/**
* <p>
*
* \param funcNo
*/
int PFunctionHandler::GetFuncIndex(int funcNo)
{
int index = -1;
for (unsigned int i=0; i<fFuncs.size(); i++) {
if (fFuncs[i].GetFuncNo() == funcNo) {
index = i;
break;
}
}
return index;
}

View File

@ -0,0 +1,86 @@
/***************************************************************************
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 <iostream>
#include <vector>
using namespace std;
#include <qstring.h>
#include "PFunctionGrammar.h"
#include "PFunction.h"
class PFunctionHandler
{
public:
PFunctionHandler(char *fln);
PFunctionHandler(vector<QString> 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<double> fParam;
vector<int> fMap;
vector<QString> fLines;
vector<PFunction> 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_

View File

@ -0,0 +1,28 @@
#----------------------------------------------
# function input file
#----------------------------------------------
#
# '#' are comment lines
#
# The file has the following structure:
#
# PAR <par1> <par2> ... <parN>
# MAP <map1> <map2> ... <mapM>
# FUNCTIONS
# fun1 = <function>
# fun2 = <function>
# funX = <function>
# 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
#----------------------------------------------

BIN
src/tests/spirit/spirit.pdf Normal file

Binary file not shown.

View File

@ -0,0 +1,100 @@
#include <iostream>
using namespace std;
#include "PFunctionHandler.h"
//-----------------------------------------------------
void syntax()
{
cout << endl << "spirit_fcn_test [--file <filename>] | [--help]";
cout << endl << " without arguments: interactive mode";
cout << endl << " --file <filename>: function block etc. from file";
cout << endl << " --help: this help";
cout << endl << endl;
}
//-----------------------------------------------------
void handle_input(vector<QString> &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 <map1> <map2> ... <mapM>";
cout << endl << " Parameter block:";
cout << endl << " PAR <par1> <par2> ... <parN>";
cout << endl << " Function Block:";
cout << endl << " FUNCTION";
cout << endl << " fun1 = <function1>";
cout << endl << " fun2 = <function2>";
cout << endl << " ...";
cout << endl << " funX = <functionX>";
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<QString> 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; i<fcnHandler->GetNoOfFuncs(); i++)
cout << endl << "FUN" << fcnHandler->GetFuncNo(i) << " = " << fcnHandler->Eval(fcnHandler->GetFuncNo(i));
}
}
// clean up
if (fcnHandler) {
delete fcnHandler;
fcnHandler = 0;
}
return 1;
}

View File

@ -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

View File

View File

@ -0,0 +1,37 @@
#include <iostream>
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;
}
}

View File

@ -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_

View File

@ -0,0 +1,10 @@
#include "PStlCheck.h"
PStlCheck::PStlCheck()
{
}
PStlCheck::~PStlCheck()
{
fPpo.clear();
}

View File

@ -0,0 +1,17 @@
#ifndef _PSTLCHECK_H_
#define _PSTLCHECK_H_
#include <list>
using namespace std;
#include "PPointObj.h"
class PStlCheck {
public:
PStlCheck();
~PStlCheck();
list<PPointObj> fPpo;
};
#endif // _PSTLCHECK_H_

View File

@ -0,0 +1,28 @@
#include <iostream>
#include <list>
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<PPointObj>::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;
}

View File

@ -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

View File

@ -0,0 +1,36 @@
#include <iostream>
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<PPO_SIZE; i++)
fTest[i] = 2*PPO_SIZE*counter+i;
cout << endl << "in PPointObj() " << fCounter << ": fTest = " << fTest;
cout << endl;
}
PPointObj::~PPointObj()
{
if (fTest) {
delete [] fTest;
fTest = 0;
}
cout << endl << "in ~PPointObj() " << fCounter << ": fTest = " << fTest;
cout << endl;
}
void PPointObj::PrintTest()
{
cout << endl << fCounter << ": ";
for (unsigned int i=0; i<PPO_SIZE; i++)
cout << fTest[i] << ", ";
cout << endl;
}

View File

@ -0,0 +1,16 @@
#ifndef _PPOINTOBJ_H_
#define _PPOINTOBJ_H_
class PPointObj {
public:
PPointObj(unsigned int counter);
~PPointObj();
void PrintTest();
private:
int fCounter;
int *fTest;
};
#endif // _PPOINTOBJ_H_

View File

@ -0,0 +1,29 @@
#include "PStlCheck.h"
PStlCheck::PStlCheck()
{
}
PStlCheck::~PStlCheck()
{
fPpo.clear();
}
void PStlCheck::Add(unsigned int count)
{
fPpo.push_back(new PPointObj(count));
}
void PStlCheck::CleanUp()
{
for (unsigned int i=0; i<fPpo.size(); i++) {
fPpo[i]->~PPointObj();
}
}
void PStlCheck::PrintTest()
{
for (unsigned int i=0; i<fPpo.size(); i++)
fPpo[i]->PrintTest();
}

View File

@ -0,0 +1,22 @@
#ifndef _PSTLCHECK_H_
#define _PSTLCHECK_H_
#include <vector>
using namespace std;
#include "PPointObj.h"
class PStlCheck {
public:
PStlCheck();
~PStlCheck();
void Add(unsigned int count);
void CleanUp();
void PrintTest();
private:
vector<PPointObj*> fPpo;
};
#endif // _PSTLCHECK_H_

View File

@ -0,0 +1,21 @@
#include <iostream>
#include <vector>
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;
}

View File

@ -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

19
templates/cpp Executable file
View File

@ -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. *
***************************************************************************/

19
templates/h Executable file
View File

@ -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. *
***************************************************************************/