newly added. Not for productive used yetsvn diff | grep Index:
This commit is contained in:
commit
c6cc508aaf
340
copying
Executable file
340
copying
Executable 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
239
doc/man/logo_n.eps
Executable 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
351
doc/man/musrfit.tex
Executable 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
1283
doc/musrfit_dox.cfg
Normal file
File diff suppressed because it is too large
Load Diff
18
src/.kdbgrc.musrfit
Executable file
18
src/.kdbgrc.musrfit
Executable 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
66
src/ToDo.txt
Normal 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
31
src/classes/BUILD
Normal 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
138
src/classes/Makefile.PMusr
Normal 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
478
src/classes/PFitter.cpp
Normal 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;
|
||||||
|
}
|
99
src/classes/PFitterFcn.cpp
Normal file
99
src/classes/PFitterFcn.cpp
Normal 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
562
src/classes/PFunction.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
225
src/classes/PFunctionHandler.cpp
Normal file
225
src/classes/PFunctionHandler.cpp
Normal 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
1780
src/classes/PMsrHandler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
643
src/classes/PRunAsymmetry.cpp
Normal file
643
src/classes/PRunAsymmetry.cpp
Normal 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
149
src/classes/PRunBase.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
811
src/classes/PRunDataHandler.cpp
Normal file
811
src/classes/PRunDataHandler.cpp
Normal 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;
|
||||||
|
}
|
366
src/classes/PRunListCollection.cpp
Normal file
366
src/classes/PRunListCollection.cpp
Normal 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
144
src/classes/PRunNonMusr.cpp
Normal 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
144
src/classes/PRunRRF.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
342
src/classes/PRunSingleHisto.cpp
Normal file
342
src/classes/PRunSingleHisto.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
55
src/classes/PStartupHandler.cpp
Normal file
55
src/classes/PStartupHandler.cpp
Normal 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
970
src/classes/PTheory.cpp
Normal 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
97
src/include/PFitter.h
Normal 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
58
src/include/PFitterFcn.h
Normal 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
114
src/include/PFunction.h
Normal 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_
|
142
src/include/PFunctionGrammar.h
Normal file
142
src/include/PFunctionGrammar.h
Normal 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_
|
68
src/include/PFunctionHandler.h
Normal file
68
src/include/PFunctionHandler.h
Normal 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
114
src/include/PMsrHandler.h
Normal 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 ¶m);
|
||||||
|
virtual bool FilterFunMapNumber(TString str, const char *filter, int &no);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _PMSRHANDLER_H_
|
253
src/include/PMusr.h
Normal file
253
src/include/PMusr.h
Normal 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_
|
69
src/include/PRunAsymmetry.h
Normal file
69
src/include/PRunAsymmetry.h
Normal 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
97
src/include/PRunBase.h
Normal 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_
|
76
src/include/PRunDataHandler.h
Normal file
76
src/include/PRunDataHandler.h
Normal 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_
|
86
src/include/PRunListCollection.h
Normal file
86
src/include/PRunListCollection.h
Normal 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
59
src/include/PRunNonMusr.h
Normal 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
59
src/include/PRunRRF.h
Normal 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_
|
59
src/include/PRunSingleHisto.h
Normal file
59
src/include/PRunSingleHisto.h
Normal 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_
|
46
src/include/PStartupHandler.h
Normal file
46
src/include/PStartupHandler.h
Normal 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
202
src/include/PTheory.h
Normal 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
247
src/msr2msr.cpp
Normal 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
22
src/msr2msr.pro
Normal 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
615
src/musrfit.cpp
Normal 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
25
src/musrfit.pro
Normal 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
|
32
src/tests/fio_test/fio_test.cpp
Normal file
32
src/tests/fio_test/fio_test.cpp
Normal 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;
|
||||||
|
}
|
17
src/tests/fio_test/fio_test.pro
Normal file
17
src/tests/fio_test/fio_test.pro
Normal 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
|
1
src/tests/fio_test/fio_test.txt
Normal file
1
src/tests/fio_test/fio_test.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
0.258467 0.258467 0.258467
|
84
src/tests/minuit2example/PGlobalChiSquare.cpp
Normal file
84
src/tests/minuit2example/PGlobalChiSquare.cpp
Normal 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
|
||||||
|
|
62
src/tests/minuit2example/PGlobalChiSquare.h
Normal file
62
src/tests/minuit2example/PGlobalChiSquare.h
Normal 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_
|
157
src/tests/minuit2example/mn2test.cpp
Normal file
157
src/tests/minuit2example/mn2test.cpp
Normal 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;
|
||||||
|
}
|
45
src/tests/minuit2example/mn2test.h
Normal file
45
src/tests/minuit2example/mn2test.h
Normal 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_
|
26
src/tests/minuit2example/mn2test.pro
Normal file
26
src/tests/minuit2example/mn2test.pro
Normal 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
|
||||||
|
|
22
src/tests/nanTest/nanTest.cpp
Normal file
22
src/tests/nanTest/nanTest.cpp
Normal 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;
|
||||||
|
}
|
17
src/tests/nanTest/nanTest.pro
Normal file
17
src/tests/nanTest/nanTest.pro
Normal 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
|
110
src/tests/nemuRootFileRead/nemuRootFileRead.cpp
Normal file
110
src/tests/nemuRootFileRead/nemuRootFileRead.cpp
Normal 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;
|
||||||
|
}
|
23
src/tests/nemuRootFileRead/nemuRootFileRead.pro
Normal file
23
src/tests/nemuRootFileRead/nemuRootFileRead.pro
Normal 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
|
24
src/tests/root2DHisto/root2DHisto.C
Normal file
24
src/tests/root2DHisto/root2DHisto.C
Normal 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();
|
||||||
|
}
|
30
src/tests/rootFiles/histoWithErrors.C
Normal file
30
src/tests/rootFiles/histoWithErrors.C
Normal 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);
|
||||||
|
}
|
105
src/tests/rootMinuit2Test/minuit2test.C
Normal file
105
src/tests/rootMinuit2Test/minuit2test.C
Normal 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
|
||||||
|
}
|
0
src/tests/rootSystemTest/.kdbgrc.rootSystemTest
Executable file
0
src/tests/rootSystemTest/.kdbgrc.rootSystemTest
Executable file
35
src/tests/rootSystemTest/rootSystemTest.cpp
Normal file
35
src/tests/rootSystemTest/rootSystemTest.cpp
Normal 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;
|
||||||
|
}
|
22
src/tests/rootSystemTest/rootSystemTest.pro
Normal file
22
src/tests/rootSystemTest/rootSystemTest.pro
Normal 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
|
0
src/tests/spirit/.kdbgrc.spirit_fcn_test
Executable file
0
src/tests/spirit/.kdbgrc.spirit_fcn_test
Executable file
620
src/tests/spirit/PFunction.cpp
Normal file
620
src/tests/spirit/PFunction.cpp
Normal 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;
|
||||||
|
}
|
111
src/tests/spirit/PFunction.h
Normal file
111
src/tests/spirit/PFunction.h
Normal 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_
|
142
src/tests/spirit/PFunctionGrammar.h
Normal file
142
src/tests/spirit/PFunctionGrammar.h
Normal 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_
|
417
src/tests/spirit/PFunctionHandler.cpp
Normal file
417
src/tests/spirit/PFunctionHandler.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
86
src/tests/spirit/PFunctionHandler.h
Normal file
86
src/tests/spirit/PFunctionHandler.h
Normal 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_
|
||||||
|
|
28
src/tests/spirit/fcnInput.txt
Normal file
28
src/tests/spirit/fcnInput.txt
Normal 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
BIN
src/tests/spirit/spirit.pdf
Normal file
Binary file not shown.
100
src/tests/spirit/spirit_fcn_test.cpp
Normal file
100
src/tests/spirit/spirit_fcn_test.cpp
Normal 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;
|
||||||
|
}
|
24
src/tests/spirit/spirit_fcn_test.pro
Normal file
24
src/tests/spirit/spirit_fcn_test.pro
Normal 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
|
||||||
|
|
0
src/tests/stl_check/.kdbgrc.stl_check
Executable file
0
src/tests/stl_check/.kdbgrc.stl_check
Executable file
37
src/tests/stl_check/PPointObj.cpp
Normal file
37
src/tests/stl_check/PPointObj.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
17
src/tests/stl_check/PPointObj.h
Normal file
17
src/tests/stl_check/PPointObj.h
Normal 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_
|
10
src/tests/stl_check/PStlCheck.cpp
Normal file
10
src/tests/stl_check/PStlCheck.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "PStlCheck.h"
|
||||||
|
|
||||||
|
PStlCheck::PStlCheck()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PStlCheck::~PStlCheck()
|
||||||
|
{
|
||||||
|
fPpo.clear();
|
||||||
|
}
|
17
src/tests/stl_check/PStlCheck.h
Normal file
17
src/tests/stl_check/PStlCheck.h
Normal 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_
|
28
src/tests/stl_check/stl_check.cpp
Normal file
28
src/tests/stl_check/stl_check.cpp
Normal 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;
|
||||||
|
}
|
22
src/tests/stl_check/stl_check.pro
Normal file
22
src/tests/stl_check/stl_check.pro
Normal 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
|
36
src/tests/stl_check_2/PPointObj.cpp
Normal file
36
src/tests/stl_check_2/PPointObj.cpp
Normal 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;
|
||||||
|
}
|
16
src/tests/stl_check_2/PPointObj.h
Normal file
16
src/tests/stl_check_2/PPointObj.h
Normal 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_
|
29
src/tests/stl_check_2/PStlCheck.cpp
Normal file
29
src/tests/stl_check_2/PStlCheck.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
|
22
src/tests/stl_check_2/PStlCheck.h
Normal file
22
src/tests/stl_check_2/PStlCheck.h
Normal 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_
|
21
src/tests/stl_check_2/stl_check_2.cpp
Normal file
21
src/tests/stl_check_2/stl_check_2.cpp
Normal 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;
|
||||||
|
}
|
22
src/tests/stl_check_2/stl_check_2.pro
Normal file
22
src/tests/stl_check_2/stl_check_2.pro
Normal 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
19
templates/cpp
Executable 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
19
templates/h
Executable 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. *
|
||||||
|
***************************************************************************/
|
Loading…
x
Reference in New Issue
Block a user