diff --git a/.arcconfig b/.arcconfig new file mode 100644 --- /dev/null +++ b/.arcconfig @@ -0,0 +1,3 @@ +{ + "phabricator.uri" : "https://phab.hepforge.org" +} diff --git a/.gitignore b/.gitignore new file mode 100644 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# Text Editor Temp Files +*~ +*.swp + +# Mac Filesystem +.DS_Store? + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,97 @@ +# Top level CMakeLists.txt for Laura++ + +# Enforce an out-of-source build. +# Should be the first action in the top level CMakeLists.txt +if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) + message(STATUS "Laura++ requires an out-of-source build.") + message(STATUS "Please remove these files from ${CMAKE_BINARY_DIR} first:") + message(STATUS " CMakeCache.txt") + message(STATUS " CMakeFiles") + message(STATUS "Once these files are removed, create a separate directory") + message(STATUS "and run CMake from there, pointing it to:") + message(STATUS " ${CMAKE_SOURCE_DIR}") + message(FATAL_ERROR "in-source build detected") +endif() + +# Also require a minimum version of CMake +cmake_minimum_required(VERSION 3.12.0) + +# Project setup +project(Laura++ VERSION 3.6.0 + DESCRIPTION "A maximum likelihood fitting package for performing Dalitz-plot analysis." + HOMEPAGE_URL "https://laura.hepforge.org" + ) + +# Option to enable/disable compilation of the RooFit task class +option(LAURA_BUILD_ROOFIT_TASK "Enable/disable compilation of RooFit task class" OFF) + +# Option to enable/disable building of the Doxygen documentation +option(LAURA_BUILD_DOCS "Enable/disable building of Doxygen documentation" OFF) + +# Options to enable/disable compilation of the example/test executables +option(LAURA_BUILD_EXAMPLES "Enable/disable compilation of example executables" OFF) +option(LAURA_BUILD_TESTS "Enable/disable compilation of test executables" OFF) + +message(STATUS "Laura++: Optional compilation of RooFit task class LAURA_BUILD_ROOFIT_TASK ${LAURA_BUILD_ROOFIT_TASK}") +message(STATUS "Laura++: Optional building of Doxygen documentation LAURA_BUILD_DOCS ${LAURA_BUILD_DOCS}") +message(STATUS "Laura++: Optional building of example executables LAURA_BUILD_EXAMPLES ${LAURA_BUILD_EXAMPLES}") +message(STATUS "Laura++: Optional building of test executables LAURA_BUILD_TESTS ${LAURA_BUILD_TESTS}") + +# Prepend this project's custom module path(s) to CMAKE_MODULE_PATH +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules ${CMAKE_MODULE_PATH}) + +# Include needed modules and perform any custom setup +# Install paths +include(GNUInstallDirs) +# Compilation/linking flags and related settings +include(LauraCompilerFlags) +# External dependencies +include(LauraExternalDependencies) + +# Create the documentation +if(LAURA_BUILD_DOCS) + add_subdirectory(doc) +endif() + +# Install the headers +add_subdirectory(inc) + +# Now build and install the library +add_subdirectory(src) + +# Build and install the executables in the examples directory +if(LAURA_BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + +if(LAURA_BUILD_TESTS) + add_subdirectory(test) +endif() + +# Generate CMake config files, which can be used by other projects +include(CMakePackageConfigHelpers) + +set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}) +set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}) +set(DATA_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}) + +configure_package_config_file(cmake/Templates/LauraConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/LauraConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}/cmake + PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR DATA_INSTALL_DIR + ) + +write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/LauraConfigVersion.cmake + COMPATIBILITY AnyNewerVersion + ) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/LauraConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/LauraConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}/cmake + ) + +install( + EXPORT "LauraTargets" + NAMESPACE "Laura::" + DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}/cmake + ) diff --git a/doc/LICENSE-2.0 b/LICENSE-2.0 rename from doc/LICENSE-2.0 rename to LICENSE-2.0 diff --git a/Makefile b/Makefile deleted file mode 100644 --- a/Makefile +++ /dev/null @@ -1,196 +0,0 @@ - ############################################################################ - # Copyright 2004 University of Warwick # - # # - # Licensed under the Apache License, Version 2.0 (the "License"); # - # you may not use this file except in compliance with the License. # - # You may obtain a copy of the License at # - # # - # http://www.apache.org/licenses/LICENSE-2.0 # - # # - # Unless required by applicable law or agreed to in writing, software # - # distributed under the License is distributed on an "AS IS" BASIS, # - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # - # See the License for the specific language governing permissions and # - # limitations under the License. # - # # - # Laura++ package authors: # - # John Back # - # Paul Harrison # - # Thomas Latham # - # # - ############################################################################ - # # - # ------------------------------- # - # Standalone Makefile for Laura++ # - # ------------------------------- # - # # - # Instructions # - # - Review 'external configuration' section below # - # to match systems compilers setup # - # # - # - Make sure the ROOTSYS environment variable is set and points # - # to your ROOT release or the root-config script is in your PATH # - # # - # - run 'make ' # - # # - # Build targets # - # lib - make libLaura++.a # - # shlib - make libLaura++.so (default) # - # clean - delete all intermediate and final build objects # - # # - ############################################################################ - - -# --- External configuration ---------------------------------- - -# first check that ROOTSYS is defined -ifndef ROOTSYS - ROOTSYS := $(shell root-config --prefix) - ROOTBINDIR := $(shell root-config --bindir) - ifeq ($(ROOTSYS), ) - $(error running of root-config failed or reported null value) - endif -else - ROOTBINDIR := $(ROOTSYS)/bin -endif - -ROOTCONFIG := $(ROOTBINDIR)/root-config -ARCH := $(shell $(ROOTCONFIG) --arch) -PLATFORM := $(shell $(ROOTCONFIG) --platform) -ROOTVERSION := $(shell $(ROOTCONFIG) --version | awk -F. '{print $$1}') - -INCLUDES = -SRCDIR = src -INCDIR = inc -LIBDIR = lib -WORKDIR = tmp -# By default, don't build the LauRooFitSlave class since it depends on RooFit -# and we don't want to pull in that library if we don't have to. -# If you want to build it, just set the SKIPLIST variable to be empty. -SKIPLIST = LauRooFitSlave - -ifeq ($(findstring linux, $(ARCH)),linux) -# This set here should work for Linux. -CXX = g++ -LD = g++ -CXXFLAGS = -g -O2 -Wall -Wextra -Wshadow -Woverloaded-virtual -Werror -fPIC -std=c++11 -#CXXFLAGS = -g -O2 -Wall -Wextra -Wshadow -Woverloaded-virtual -fPIC -std=c++11 -MFLAGS = -MM -LDFLAGS = -shared -endif - -ifeq ($(ARCH),macosx64) -# This set here should work for MacOSX. -CXX = g++ -LD = g++ -CXXFLAGS = -g -O3 -Wall -Wextra -Wshadow -Woverloaded-virtual -Werror -fPIC -#CXXFLAGS = -g -O3 -Wall -Wextra -Wshadow -Woverloaded-virtual -fPIC -std=c++11 -MFLAGS = -MM -LDFLAGS = -dynamiclib -single_module -undefined dynamic_lookup -endif - -# --- Internal configuration ---------------------------------- -PACKAGE=Laura++ -DEPDIR=$(WORKDIR)/dependencies -OBJDIR=$(WORKDIR)/objects - -INCLUDES += -I$(INCDIR) -CXXFLAGS += $(INCLUDES) -CXXFLAGS += $(shell $(ROOTCONFIG) --cflags) -LDFLAGS += $(shell $(ROOTCONFIG) --ldflags) -CINTFILE = $(WORKDIR)/$(PACKAGE)Cint.cc -CINTOBJ = $(OBJDIR)/$(PACKAGE)Cint.o -LIBFILE = $(LIBDIR)/lib$(PACKAGE).a -SHLIBFILE = $(LIBDIR)/lib$(PACKAGE).so -ROOTMAPFILE = $(patsubst %.so,%.rootmap,$(SHLIBFILE)) - -ROOTLIBS = libCore.so libEG.so libHist.so libMathCore.so libMatrix.so libNet.so libRIO.so libTree.so -DEFINES = -ifeq ($(strip $(SKIPLIST)),) - ROOTLIBS += libRooFitCore.so libRooFit.so - DEFINES += -DDOLAUROOFITSLAVE -endif - -default: shlib - -# List of all header files -HHLIST:=$(filter-out $(addprefix $(INCDIR)/, $(addsuffix .hh, $(SKIPLIST))),$(wildcard $(INCDIR)/*.hh)) - -# List of all source files to build -CCLIST:=$(filter-out $(addprefix $(SRCDIR)/, $(addsuffix .cc, $(SKIPLIST))),$(wildcard $(SRCDIR)/*.cc)) - -# List of all object files to build -OLIST:=$(patsubst %.cc,%.o,$(addprefix $(OBJDIR)/,$(notdir $(CCLIST)))) - -# List of all dependency files to make -DLIST:=$(patsubst %.cc,%.d,$(addprefix $(DEPDIR)/,$(notdir $(CCLIST)))) - -# Implicit rule making all dependency Makefiles included at the end of this makefile -$(DEPDIR)/%.d: $(SRCDIR)/%.cc - @echo "Making $@" - @mkdir -p $(DEPDIR) - @set -e; $(CXX) $(MFLAGS) $(CXXFLAGS) $< \ - | sed 's#\($(notdir $*)\)\.o[ :]*#$(OBJDIR)/\1.o $@ : #g' > $@; \ - [ -s $@ ] || rm -f $@ - -# Implicit rule to compile all classes -$(OBJDIR)/%.o : $(SRCDIR)/%.cc - @echo "Compiling $<" - @mkdir -p $(OBJDIR) - @$(CXX) $(CXXFLAGS) -c $< -o $@ - -# Rule to make ROOTCINT output file -$(CINTOBJ): $(HHLIST) $(INCDIR)/$(PACKAGE)_LinkDef.h - @mkdir -p $(OBJDIR) - @mkdir -p $(LIBDIR) -ifeq ($(ROOTVERSION),5) - @echo "Running rootcint" - @$(ROOTBINDIR)/rootcint -f $(CINTFILE) -c $(INCLUDES) $(DEFINES) $(notdir $(HHLIST)) $(INCDIR)/$(PACKAGE)_LinkDef.h -else - @echo "Running rootcling" - @$(ROOTBINDIR)/rootcling -f $(CINTFILE) -s $(SHLIBFILE) -rml $(SHLIBFILE) $(addprefix -rml , $(ROOTLIBS)) -rmf $(ROOTMAPFILE) -I$(PWD)/$(INCDIR) $(DEFINES) $(notdir $(HHLIST)) $(INCDIR)/$(PACKAGE)_LinkDef.h -endif - @echo "Compiling $(CINTFILE)" - @$(CXX) $(CXXFLAGS) -c $(CINTFILE) -o $(CINTOBJ) - -# Rule to combine objects into a library -$(LIBFILE): $(OLIST) $(CINTOBJ) - @echo "Making $(LIBFILE)" - @mkdir -p $(LIBDIR) - @rm -f $(LIBFILE) - @ar rcs $(LIBFILE) $(OLIST) $(CINTOBJ) - -# Rule to combine objects into a shared library -$(SHLIBFILE): $(OLIST) $(CINTOBJ) - @echo "Making $(SHLIBFILE)" - @mkdir -p $(LIBDIR) - @rm -f $(SHLIBFILE) - @$(CXX) $(OLIST) $(CINTOBJ) $(LDFLAGS) -o $(SHLIBFILE) - -ifeq ($(ROOTVERSION),5) -# Rule to create rootmap file -$(ROOTMAPFILE): $(SHLIBFILE) - @echo "Making $(ROOTMAPFILE)" - @mkdir -p $(LIBDIR) - @rm -f $(ROOTMAPFILE) - @rlibmap -f -o $(ROOTMAPFILE) -l $(SHLIBFILE) -d $(ROOTLIBS) -c $(INCDIR)/$(PACKAGE)_LinkDef.h -endif - -# Useful build targets -lib: $(LIBFILE) - -ifeq ($(ROOTVERSION),5) -shlib: $(SHLIBFILE) $(ROOTMAPFILE) -else -shlib: $(SHLIBFILE) -endif - -clean: - rm -rf $(WORKDIR) - rm -f $(LIBFILE) - rm -f $(SHLIBFILE) - rm -f $(ROOTMAPFILE) - -.PHONY : shlib lib default clean - --include $(DLIST) diff --git a/doc/README b/README.md rename from doc/README rename to README.md --- a/doc/README +++ b/README.md @@ -1,14 +1,6 @@ -///////////////////////////////////////////////////////// -/// /// -/// README of the Laura++ package /// -/// /// -/// Contact: Tom Latham (laura@projects.hepforge.org) /// -/// /// -///////////////////////////////////////////////////////// - - Introduction - ------------ +# Laura++ README +## Introduction This package is a C++ development of LAURA, the FORTRAN "Likelihood Analysis Unofficial RooFitDalitz Alternative" code written by Paul Harrison for performing Dalitz plot analyses of 3-body decays of B mesons at BaBar. @@ -16,19 +8,25 @@ developed by Tom Latham with continuting contributions from John Back and others. - Structure of the Package - ------------------------ - +## Structure of the Package The package consists of the following directories and files: -. -├── Doxyfile - configuration file for building Doxygen documentation -├── Makefile - GNU make configuration file for building the Laura++ (shared) library -├── doc - directory containing documentation-related files -│   ├── LICENSE-2.0 - the Apache License, Version 2.0 -│   ├── README - this README file -│   ├── mainpage.dox - front page of the Doxygen documents -│   └── release.notes - history of commits to the package +``` +laura.git +├── CMakeLists.txt - the top-level CMake configuration file +├── LICENSE-2.0 - the Apache License, Version 2.0 +├── README.md - this README file +├── cmake - directory containing custom CMake modules and templates +│   ├── Modules +│   │   ├── LauraCompilerFlags.cmake +│   │   └── LauraExternalDependencies.cmake +│   └── Templates +│   └── LauraConfig.cmake.in +├── doc - directory related to building Doxygen documentation +│   ├── CMakeLists.txt - CMake configuration file +│   ├── Doxyfile.in - Doxygen configuration file +│   ├── mainpage.dox.in - front page of the Doxygen documents +│   └── ReleaseNotes.md - history of commits to the package ├── examples - directory containing code examples and their associated data files and job scripts │   ├── B3piKMNoAdler.dat │   ├── B3piKMPoles.dat @@ -36,9 +34,8 @@ │   ├── B3piKMatrixCoeff.dat │   ├── B3piKMatrixMassProj.cc │   ├── B3piKMatrixPlots.cc +│   ├── CMakeLists.txt │   ├── CalcChiSq.cc -│   ├── CalcChiSq.hh -│   ├── CalcChiSqMain.cc │   ├── DToKspipiKMatrixCoeff.dat │   ├── FOCUSD3pi.dat │   ├── GenFit3K.cc @@ -55,26 +52,22 @@ │   ├── KMatrixExample.cc │   ├── LauKMatrixCoeff.dat │   ├── LauKMatrixCoeff2.dat -│   ├── Makefile - GNU make configuration file for building the code examples -│   ├── Master.cc │   ├── MergeDataFiles.cc -│   ├── MergeDataFiles.hh -│   ├── MergeDataFilesMain.cc │   ├── PlotKMatrixTAmp.cc │   ├── PlotResults.cc │   ├── ResultsExtractor.cc -│   ├── ResultsExtractor.hh -│   ├── ResultsExtractorMain.cc -│   ├── Slave.cc -│   ├── SlaveRooFit.cc +│   ├── SimFitCoordinator.cc +│   ├── SimFitTask.cc +│   ├── SimFitTaskRooFit.cc │   ├── chiSqInput.txt │   ├── mixedSampleTest.cc │   ├── point2PointTestSample.cc -│   ├── runMasterRooFitSlave.sh -│   ├── runMasterSlave.sh +│   ├── runCoordinatorRooFitTask.sh +│   ├── runCoordinatorTask.sh │   ├── runPoint2PointTest.sh │   └── usfactor.dat ├── inc - directory containing the header files for the Laura++ library +│   ├── CMakeLists.txt │   ├── Lau1DCubicSpline.hh │   ├── Lau1DHistPdf.hh │   ├── Lau2DAbsDP.hh @@ -109,6 +102,7 @@ │   ├── LauBreitWignerRes.hh │   ├── LauCPFitModel.hh │   ├── LauCacheData.hh +│   ├── LauCalcChiSq.hh │   ├── LauCartesianCPCoeffSet.hh │   ├── LauCartesianGammaCPCoeffSet.hh │   ├── LauChebychevPdf.hh @@ -155,6 +149,7 @@ │   ├── LauLinearPdf.hh │   ├── LauMagPhaseCPCoeffSet.hh │   ├── LauMagPhaseCoeffSet.hh +│   ├── LauMergeDataFiles.hh │   ├── LauMinuit.hh │   ├── LauModIndPartWaveMagPhase.hh │   ├── LauModIndPartWaveRealImag.hh @@ -165,23 +160,29 @@ │   ├── LauParametricStepFuncPdf.hh │   ├── LauParticlePDG.hh │   ├── LauPolNR.hh +│   ├── LauPolarFormFactorNR.hh +│   ├── LauPolarFormFactorSymNR.hh │   ├── LauPolarGammaCPCoeffSet.hh +│   ├── LauPoleRes.hh │   ├── LauPrint.hh │   ├── LauRandom.hh │   ├── LauRealImagCPCoeffSet.hh │   ├── LauRealImagCoeffSet.hh │   ├── LauRealImagGammaCPCoeffSet.hh │   ├── LauRelBreitWignerRes.hh +│   ├── LauRescattering2Res.hh +│   ├── LauRescatteringRes.hh │   ├── LauResonanceInfo.hh │   ├── LauResonanceMaker.hh +│   ├── LauResultsExtractor.hh │   ├── LauRhoOmegaMix.hh -│   ├── LauRooFitSlave.hh +│   ├── LauRooFitTask.hh │   ├── LauSPlot.hh │   ├── LauScfMap.hh │   ├── LauSigmaRes.hh │   ├── LauSigmoidPdf.hh -│   ├── LauSimFitMaster.hh -│   ├── LauSimFitSlave.hh +│   ├── LauSimFitCoordinator.hh +│   ├── LauSimFitTask.hh │   ├── LauSimpleFitModel.hh │   ├── LauString.hh │   ├── LauSumPdf.hh @@ -196,6 +197,7 @@ │   ├── plotCorrsFromToy.C │   └── plotDataIsobars.C ├── src - directory containing the source files for the Laura++ library +│   ├── CMakeLists.txt │   ├── Lau1DCubicSpline.cc │   ├── Lau1DHistPdf.cc │   ├── Lau2DAbsHistDP.cc @@ -225,6 +227,7 @@ │   ├── LauBreitWignerRes.cc │   ├── LauCPFitModel.cc │   ├── LauCacheData.cc +│   ├── LauCalcChiSq.cc │   ├── LauCartesianCPCoeffSet.cc │   ├── LauCartesianGammaCPCoeffSet.cc │   ├── LauChebychevPdf.cc @@ -270,6 +273,7 @@ │   ├── LauLinearPdf.cc │   ├── LauMagPhaseCPCoeffSet.cc │   ├── LauMagPhaseCoeffSet.cc +│   ├── LauMergeDataFiles.cc │   ├── LauMinuit.cc │   ├── LauModIndPartWaveMagPhase.cc │   ├── LauModIndPartWaveRealImag.cc @@ -279,23 +283,29 @@ │   ├── LauParametricStepFuncPdf.cc │   ├── LauParticlePDG.cc │   ├── LauPolNR.cc +│   ├── LauPolarFormFactorNR.cc +│   ├── LauPolarFormFactorSymNR.cc │   ├── LauPolarGammaCPCoeffSet.cc +│   ├── LauPoleRes.cc │   ├── LauPrint.cc │   ├── LauRandom.cc │   ├── LauRealImagCPCoeffSet.cc │   ├── LauRealImagCoeffSet.cc │   ├── LauRealImagGammaCPCoeffSet.cc │   ├── LauRelBreitWignerRes.cc +│   ├── LauRescattering2Res.cc +│   ├── LauRescatteringRes.cc │   ├── LauResonanceInfo.cc │   ├── LauResonanceMaker.cc +│   ├── LauResultsExtractor.cc │   ├── LauRhoOmegaMix.cc -│   ├── LauRooFitSlave.cc +│   ├── LauRooFitTask.cc │   ├── LauSPlot.cc │   ├── LauScfMap.cc │   ├── LauSigmaRes.cc │   ├── LauSigmoidPdf.cc -│   ├── LauSimFitMaster.cc -│   ├── LauSimFitSlave.cc +│   ├── LauSimFitCoordinator.cc +│   ├── LauSimFitTask.cc │   ├── LauSimpleFitModel.cc │   ├── LauString.cc │   ├── LauSumPdf.cc @@ -303,84 +313,162 @@ │   ├── LauVetoes.cc │   └── LauWeightedSumEffModel.cc └── test - directory containing code for some test executables - ├── Makefile - GNU make configuration file for building the test executables + ├── CMakeLists.txt ├── TestCovariant.cc ├── TestCovariant2.cc └── TestNewKinematicsMethods.cc +``` + +## Building the library + +### Prerequisites +Compilation of Laura++ on a UNIX operating system requires: +* the [CMake](https://www.cmake.org) build tool +* a C++14 compatible compiler ([GCC](https://gcc.gnu.org) 8 or better, [Clang](https://clang.llvm.org) 8 or better are recommended) +* [GNU Make](https://www.gnu.org/software/make/) or [Ninja](https://ninja-build.org) (not currently tested) + +The package depends only on [ROOT](https://root.cern.ch). +Before building the code, it is necessary that the ROOT package be findable by CMake, which can be achieved by doing one of the following: +- the `ROOTSYS` environment variable is set to the directory of the ROOT package +- the directory containing the `root-config` program is in the `PATH` environment variable +- the ROOT cmake directory is in the `CMAKE_PREFIX_PATH` environment variable + +In order to setup an environment that satifies all of the above requirements we highly recommend use of the [LCG views](https://lcginfo.cern.ch). +For example, on a machine with the [CVMFS client](https://cvmfs.readthedocs.io/en/stable/) installed, one can do: +``` +source /cvmfs/sft.cern.ch/lcg/views/setupViews.(c)sh +``` +for example: +``` +source /cvmfs/sft.cern.ch/lcg/views/setupViews.sh LCG_96b x86_64-centos7-gcc9-opt +``` -6 directories, 282 files +### Build procedure +To build from a clone of this repository, open a terminal window +and change directory into that holding this README file. +Create a build directory in which to run `cmake` and the build, and change into +it by doing the following: +``` +$ mkdir ../laura.build +$ cd ../laura.build +``` - Building the Code - ----------------- +It is best to install the package after building. +You can either install into an existing location or you can create an install +directory specifically for Laura++ (we assume the latter in the following +instructions): -The package depends only on ROOT. Before building the code, it is necessary -that either the ROOTSYS environment variable be set or that the root-config -program be in the PATH. +``` +$ mkdir ../laura.install +``` -To build the shared library: +Run `cmake` in this directory, pointing it to the directory holding this +README, and consequently the top level CMake script for the project: -cd Laura++ -make +``` +$ cmake ../ -DCMAKE_INSTALL_PREFIX=../laura.install +... system specific output ... +-- Configuring done +-- Generating done +-- Build files have been written to: ... your build dir path ... +$ +``` -A shared library will be created in the lib sub-directory: +The exact output will depend on your system, compiler and build directory +location, but you should not see any errors. +CMake will generate Makefiles by default on UNIX platforms, so to build, simply +run `make` in the build directory: -lib/libLaura++.so +``` +$ make +... verbose output ... +[100%] Built target Laura++ +... +$ make install +Install the project... +... verbose output ... +$ +``` -(It has been reported that when compiling on Ubuntu 16.04 LTS with gcc 5.4.0 -the build will fail due to, apparently spurious, "variable defined but not -used" errors related to the constants defined in the LauConstants.hh header -file. The workaround is to add the option -Wno-error=unused-variable to the -CXXFLAGS variable in the Makefile.) +Again, the exact output will be system specific, but you should see the +`Laura++` target built without error and that the installation was successful. +If compiling with gcc 5, see [the corresponding note](#notes). - Examples and Documentation - -------------------------- + +## Examples and documentation Example code is included in the examples directory. -To build the example code: -cd examples -make +To enable the building and installation of the example executables you need to +supply the following option when running `cmake`: +``` +-DLAURA_BUILD_EXAMPLES=ON +``` +After building and installing, the example executables will be in the `bin` +directory in the install location. -(On MacOSX it is currently necessary to also do: -ln -s ../lib . -in order to successfully run the examples. -We hope to have a solution to avoid this step soon.) +To build the Doxygen documentation you need to supply the following option when +running `cmake`: +``` +-DLAURA_BUILD_DOCS=ON +``` +After building and installing, you can load the +`share/doc/Laura++/html/index.html` file (found in the install location) into +your web browser. -To build the online doxygen documentation just run doxygen in the top level -Laura++ directory and then load the index.html file found in doxygen/html. -A quick-start guide and further documentation are being worked on. +## Building your own code -Please contact Tom Latham (laura@projects.hepforge.org) with any questions. +If you wish to build your own code that uses the Laura++ library you should add the Laura++ installation area to the `CMAKE_PREFIX_PATH` environment variable. +You can then add lines like the following to your own `CMakeLists.txt` file: +```cmake +# Find ROOT and Laura++ +find_package(Laura REQUIRED) +find_package(ROOT REQUIRED) +# Now build the executable +add_executable(MyExe MyExe.cc) +target_link_libraries(MyExe PRIVATE Laura::Laura++) +``` - Authors and Contributors - ------------------------ -As mentioned in the Introduction above, the authors of the package are: +## Authors and contributors -Thomas Latham -John Back +As mentioned in the Introduction above, the authors of the package are: +Thomas Latham +John Back Paul Harrison The authors would also like to thank the following people for their invaluable -contributions: - -Sian Morgan -Tim Gershon -Pablo del Amo Sanchez -Jelena Ilic -Eugenia Puccio -Mark Whitehead -Daniel Craik -Rafael Coutinho -Charlotte Wallace -Juan Otalora -Wenbin Qian +contributions: +Sian Morgan +Tim Gershon +Pablo del Amo Sanchez +Jelena Ilic +Eugenia Puccio +Mark Whitehead +Daniel Craik +Rafael Coutinho +Charlotte Wallace +Juan Otalora +Wenbin Qian Daniel O'Hanlon -Many thanks also go to numerous members of the BaBar, Belle and LHCb +Many thanks also go to numerous members of the BaBar, Belle, and LHCb collaborations for their helpful input. +Contact: Tom Latham (laura@projects.hepforge.org) + + +## Notes {#notes} + +* [It has been reported](https://laura.hepforge.org/trac/ticket/67) that when + compiling on Ubuntu 16.04 LTS with gcc 5.4.0 the build will fail due to, + apparently spurious, "variable defined but not used" errors related to the + constants defined in the `LauConstants.hh` header file. + The workaround is to add the option `-Wno-error=unused-variable` to the + `CMAKE_CXX_FLAGS` variable in the file: + cmake/Modules/LauraCompilerFlags.cmake + diff --git a/cmake/Modules/LauraCompilerFlags.cmake b/cmake/Modules/LauraCompilerFlags.cmake new file mode 100644 --- /dev/null +++ b/cmake/Modules/LauraCompilerFlags.cmake @@ -0,0 +1,55 @@ + +# Set the build type (if not already specified) +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Laura++: Setting build type to 'Release' as none was specified") + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Release, MinSizeRel, Debug, RelWithDebInfo" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") +elseif(CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Laura++: Build type '${CMAKE_BUILD_TYPE}'") +endif() + +# Set the warning/optimise/debug flags for each build type +if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang" ) + message(STATUS "Laura++: Customising warning/optimise/debug flags for each build type") + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsigned-char -Wall -Wextra -Wshadow -Woverloaded-virtual") + + if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" ) + set(CMAKE_CXX_FLAGS_DEBUG "-Og -g3") + set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG") + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g3") + elseif( ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang" ) + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") + set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG") + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") + endif() +else() + message(WARNING "Laura++: No customisation of warning/optimise/debug flags implemented for compiler: ${CMAKE_CXX_COMPILER_ID}") +endif() + +# Make sure our project's include directories always come first +set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON) + +# Control verbosity of the build +set(CMAKE_VERBOSE_MAKEFILE OFF CACHE BOOL "Control verbosity of generated Makefiles") + +# C++ standard settings +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard") +set(CMAKE_CXX_STANDARD_REQUIRED ON) +message(STATUS "Laura++: Using C++${CMAKE_CXX_STANDARD} standard") + +# Special linker flags for MacOSX +if (APPLE) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -single_module -undefined dynamic_lookup") +endif() + +# RPATH handling +set(CMAKE_MACOSX_RPATH TRUE) +set(CMAKE_SKIP_BUILD_RPATH FALSE) +set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) +set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + diff --git a/cmake/Modules/LauraExternalDependencies.cmake b/cmake/Modules/LauraExternalDependencies.cmake new file mode 100644 --- /dev/null +++ b/cmake/Modules/LauraExternalDependencies.cmake @@ -0,0 +1,32 @@ +# Laura++ needs ROOT, we just require that it is a version that exports CMake targets properly +# We may depend on other things in the future, e.g. JSON or YAML for easier configuration of particle properties etc. + +if(DEFINED ENV{ROOTSYS}) + list(APPEND CMAKE_PREFIX_PATH $ENV{ROOTSYS}) +endif() + +if(LAURA_BUILD_ROOFIT_TASK) + find_package(ROOT 6.14 REQUIRED COMPONENTS EG RooFitCore RooFit) +else() + find_package(ROOT 6.14 REQUIRED COMPONENTS EG) +endif() + +#message(STATUS "ROOT include directories: ${ROOT_INCLUDE_DIRS}") +#message(STATUS "ROOT libraries: ${ROOT_LIBRARIES}") +#message(STATUS "ROOT definitions: ${ROOT_DEFINITIONS}") +#message(STATUS "ROOT CXX flags: ${ROOT_CXX_FLAGS}") +#message(STATUS "ROOT CC flags: ${ROOT_CC_FLAGS}") +#message(STATUS "ROOT use file: ${ROOT_USE_FILE}") +# Don't want to do this because it uses old-style CMake +#include(${ROOT_USE_FILE}) + +if(EXISTS "${ROOT_DIR}/RootMacros.cmake") + message(STATUS "Laura++: Including ROOT macros module: ${ROOT_DIR}/RootMacros.cmake") + include(${ROOT_DIR}/RootMacros.cmake) +elseif(EXISTS "${ROOT_DIR}/modules/RootNewMacros.cmake") + message(STATUS "Laura++: Including ROOT macros module: ${ROOT_DIR}/modules/RootNewMacros.cmake") + include(${ROOT_DIR}/modules/RootNewMacros.cmake) +else() + message(WARNING "Laura++: Cannot locate ROOT macros module in ${ROOT_DIR}") +endif() + diff --git a/cmake/Templates/LauraConfig.cmake.in b/cmake/Templates/LauraConfig.cmake.in new file mode 100644 --- /dev/null +++ b/cmake/Templates/LauraConfig.cmake.in @@ -0,0 +1,9 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/LauraTargets.cmake") + +set_and_check(LAURA_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") +set_and_check(LAURA_LIB_DIR "@PACKAGE_LIB_INSTALL_DIR@") +set_and_check(LAURA_DATA_DIR "@PACKAGE_DATA_INSTALL_DIR@") + +check_required_components("@PROJECT_NAME@") diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,45 @@ +# - CMake buildscript for documentation subdirectory + +# - Doxygen documentation +# Find an install of Doxygen (we're not too fussy about the version) using CMake's find_package command +find_package(Doxygen REQUIRED) + +# Configure+Copy Doxygen template file from current source dir to current binary dir +# '@ONLY' means replace any instances of '@VARIABLE@' in the input file with +# the value of the CMake variable named 'VARIABLE' in the output file +configure_file(Doxyfile.in Doxyfile @ONLY) +configure_file(mainpage.dox.in mainpage.dox @ONLY) + +# Run Doxygen +add_custom_command( + # What this command generates + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/html/index.html" + # Actually run doxygen + COMMAND ${DOXYGEN_EXECUTABLE} + # ... in the same directory as we generated the Doxyfile... + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + # Output requires regeneration when + # i - we modify the Doxygen configuration + # ii - the sources being documented change + # iii - any auxillary inputs change + DEPENDS Doxyfile.in mainpage.dox.in ReleaseNotes.md ${PROJECT_SOURCE_DIR}/README.md ${PROJECT_SOURCE_DIR}/inc ${PROJECT_SOURCE_DIR}/src + # Log that the command is run + COMMENT "Building Doxygen for ${PROJECT_NAME}" + ) + +# However, adding a command doesn't change anything in the build +# system - need to create a target that depends on the output of the +# command. +add_custom_target( + # Name of the target - e.g. in Makefiles we can run 'make doc' + doc + # Add this target to the default target - i.e. documentation is + # always built when building the whole project + ALL + # Make it depend on the output of the custom command + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/html/index.html" + ) + +# Install the documentation +install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION ${CMAKE_INSTALL_DOCDIR}) + diff --git a/Doxyfile b/doc/Doxyfile.in rename from Doxyfile rename to doc/Doxyfile.in --- a/Doxyfile +++ b/doc/Doxyfile.in @@ -32,19 +32,19 @@ # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = Laura++ +PROJECT_NAME = "@PROJECT_NAME@" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = v3r5 +PROJECT_NUMBER = "@PROJECT_VERSION@" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = "A maximum likelihood fitting package for performing Dalitz-plot analysis." +PROJECT_BRIEF = "@PROJECT_DESCRIPTION@" # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 @@ -58,7 +58,7 @@ # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = doxygen +OUTPUT_DIRECTORY = "@CMAKE_CURRENT_BINARY_DIR@" # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and @@ -161,7 +161,7 @@ # specify the list of include paths that are normally passed to the compiler # using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = "@PROJECT_SOURCE_DIR@/inc" # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't @@ -780,9 +780,11 @@ # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = inc \ - src \ - doc/mainpage.dox +INPUT = "@PROJECT_SOURCE_DIR@/inc" \ + "@PROJECT_SOURCE_DIR@/src" \ + "@PROJECT_SOURCE_DIR@/README.md" \ + "@PROJECT_SOURCE_DIR@/doc/ReleaseNotes.md" \ + "@PROJECT_BINARY_DIR@/doc/mainpage.dox" # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -807,13 +809,13 @@ # *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, # *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. -FILE_PATTERNS = +FILE_PATTERNS = *.cc *.hh # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. -RECURSIVE = YES +RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a @@ -1028,7 +1030,7 @@ # generated with the -Duse-libclang=ON option for CMake. # The default value is: NO. -CLANG_ASSISTED_PARSING = NO +#CLANG_ASSISTED_PARSING = NO # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that @@ -1036,7 +1038,7 @@ # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. -CLANG_OPTIONS = +#CLANG_OPTIONS = #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index @@ -1047,7 +1049,7 @@ # classes, structs, unions or interfaces. # The default value is: YES. -ALPHABETICAL_INDEX = NO +ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. @@ -1541,7 +1543,7 @@ # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. -SEARCHENGINE = NO +SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. There @@ -1615,7 +1617,7 @@ # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # The default value is: YES. -GENERATE_LATEX = YES +GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -2030,7 +2032,7 @@ # preprocessor. # This tag requires that the tag SEARCH_INCLUDES is set to YES. -INCLUDE_PATH = inc +INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the @@ -2115,12 +2117,6 @@ EXTERNAL_PAGES = YES -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of 'which perl'). -# The default file (with absolute path) is: /usr/bin/perl. - -PERL_PATH = /usr/bin/perl - #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- @@ -2134,15 +2130,6 @@ CLASS_DIAGRAMS = YES -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see: -# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The # DIA_PATH tag allows you to specify the directory where the dia binary resides. @@ -2414,7 +2401,7 @@ # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_TRANSPARENT = YES +DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This diff --git a/doc/release.notes b/doc/ReleaseNotes.md rename from doc/release.notes rename to doc/ReleaseNotes.md --- a/doc/release.notes +++ b/doc/ReleaseNotes.md @@ -1,12 +1,40 @@ -/////////////////////////////////////////////////////////////// -/// /// -/// This is the History file for the Laura++ package. /// -/// /// -/////////////////////////////////////////////////////////////// +# Laura++ release notes -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v3r5 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +3rd February 2020 Dan Johnson +* Extend the K-matrix implementation to handle non-zero spin + +2nd December 2020 Thomas Latham +* Fix LauFormulaPar to follow change in behaviour of TFormula + - see https://phab.hepforge.org/T129 + +27th November 2020 Dan Johnson +* Allow slope of NR exponential model to vary negative - improves fit stability in low-statistics fits + - see https://phab.hepforge.org/T128 + +17th September 2020 Mark Whitehead +* Begin updates to use inclusive language. Simultaneous fits now handled by Coordinator and Tasks + - see https://phab.hepforge.org/T112 + +19th August 2020 Thomas Latham +* Remove explicit normalisation of numerator Blatt-Weisskopf factors + - See https://phab.hepforge.org/T93 + +22nd May 2020 Thomas Latham +* Fix uninitialised variable (related to rho-omega mixing) in LauIsobarDynamics + +12th December 2019 Thomas Latham & Daniel Johnson +* Fix issue with generation of events for categories with small expected yield + - See https://phab.hepforge.org/T76 + +21st November 2019 Thomas Latham +* Add QuasiFlatSqDalitz example, which generates toy according to EvtGen's FLATSQDALITZ model + +6th - 20th November 2019 Thomas Latham +* Adopt CMake as the build system + - See https://phab.hepforge.org/T33 + +=== +## Laura++ v3r5 6th August 2019 Thomas Latham * Add some extra charmonium states to list of known resonances @@ -63,9 +91,8 @@ 23rd January 2018 Daniel O'Hanlon * Calculate separate rho and omega fit-fractions for LauRhoOmegaMix, when turned on with calculateRhoOmegaFitFractions in LauIsobarDynamics. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v3r4 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v3r4 16th January 2018 Thomas Latham * Update licence for all files to the Apache Software License Version 2.0 @@ -90,9 +117,8 @@ 29th November 2017 Thomas Latham * Improve error messages in LauCPFitModel::weightEvents -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v3r3 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v3r3 23rd November 2017 Thomas Latham * Add an example written as a python script: GenFit3pi.py @@ -108,9 +134,8 @@ f_Adler rather than being multiplied by it - only affected case where using LauFlatteRes to describe K_0*(1430) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v3r2 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v3r2 18th October 2017 Thomas Latham * Modify LauDaughters::testDPSymmetry to: @@ -256,12 +281,10 @@ * Add calculation of so-called covariant factors for spin amplitude -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v3r1 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v3r1 9th September 2016 Thomas Latham - * Modification of LauFitNtuple to check the size of the covariance matrix wrt known number of parameters and act accordingly: - If it is empty, just fill a diagonal correlation matrix and issue a warning. - If it results from a failed first stage of a two-stage fit then the correlation matrix is padded with 1s and 0s for the parameters that were fixed in the first stage. @@ -269,7 +292,6 @@ * Minor fix to LauAbsCoeffSet: the names of parameters would be mangled if they were the same as the basename, e.g. A1_A would become A1_ while A1_B would be correct. 8th September 2016 Thomas Latham - * Modifications to LauResonanceInfo to allow customisation of which extra parameters are shared between charge conjugate or shared-parameter records. - Where the parameters are not shared they are independently created instead of being cloned. * Modification of LauRhoOmegaMix to take advantage of the above to have the magB and phiB parameters independent. @@ -277,7 +299,6 @@ * Minor unrelated improvement to information messages in LauIsobarDynamics. 25th August 2016 John Back - * Modified LauRhoOmegaMix to allow either a RelBW or GS lineshape for the rho, as well as allowing the option to set the second-order denominator term to be equal to unity. Also fixed the bug where the spinTerm was not included in the rho-omega amplitude. @@ -296,25 +317,20 @@ This is used in the LauRhoOmegaMix for the omega lineshape where its width does not depend on momentum 23rd May 2016 John Back - * Added new lineshape model for rho-omega mass mixing, LauRhoOmegaMix. 12th April 2016 Thomas Latham - * Switch to integrating in square DP when narrow resonances are found in m12. - The integration grid size can be specified by the user 19th January 2016 John Back - * Correct the f(m^2) factor in the denominator of the LauGounarisSakuraiRes lineshape to use Gamma_0 instead of Gamma(m) 14th January 2016 Thomas Latham - * Documentation improvements 7th December 2015 Thomas Latham - * Resolve bug that meant the order of resonances in LauIsobarDynamics was assumed to match with the order in which the complex coefficients are supplied to the fit model - The ordering of resonances is defined by LauIsobarDynamics: - Firstly all coherent resonances in order of addition @@ -324,79 +340,64 @@ - Doxygen updated to reflect these changes 12th November 2015 Daniel Craik - * Added support for Akima splines and linear interpolation to Lau1DCubicSpline * LauAbsModIndPartWave, LauModIndPartWaveRealImag and LauModIndPartWaveMagPhase updated to allow choice of spline interpolation method * LauEFKLLMRes updated to use Akima splines 10th November 2015 Thomas Latham & Daniel Craik - * Add the EFKLLM form-factor model for the Kpi S-wave and an example using this lineshape * Modify LauResonanceMaker::getResonance to use a switch for greater clarity and easier checking on missing cases 4th November 2015 Daniel Craik - * Add checks to LauIsobarDynamics::addResonance and LauIsobarDynamics::addIncohResonance to stop the wrong type of LauResonanceModel being used - LauAbsResonance::isIncoherentModel method added to identify incoherent models 8th September 2015 Mark Whitehead - * Add the ability to modify the error of parameters via the CoeffSet - setParameterError added to LauAbsCoeffSet * Tweak the handling of initial error values passed to MINUIT (to determine initial step size) in LauMinuit 7th September 2015 Mark Whitehead - * Add the ability to Gaussian constrain parameters via the CoeffSet - addGaussianConstraint added to LauAbsCoeffSet 12th June 2015 Thomas Latham - * Modifications to Belle-style nonresonant models - LauBelleNR modified to use pure Legendre polynomials of cos(theta) in the spin term (i.e. to remove the q*p factors) - New form added to LauBelleSymNR (LauAbsResonance::BelleSymNRNoInter) that removes the interference term between the two DP halves - The new form also works with non-zero spin (warning added if non-zero spin specified for BelleSymNR and TaylorNR) 8th June 2015 Thomas Latham - * Further work on the blinding mechanism: - New method added LauParameter::blindParameter that activates the blinding. - The rest of the framework updated to use another new method LauParameter::unblindedValue in all likelihood calculations etc. - Example GenFitNoDP updated to include lines to optionally blind the yield parameters. 29th May 2015 Daniel Craik - * Added LauBlind class for blinding and unblinding a value with an offset based on a blinding string 26th May 2015 Daniel Craik - * Stopped LauCPFitModel passing fixed signal/background yields or asymmetries to Minuit to avoid hitting limit of 101 fixed parameters 22nd April 2015 Daniel Craik - * Updated MIPW classes to use Lau1DCubicSpline 19th April 2015 Daniel Craik - * Added Lau1DCubicSpline class for 1D spline interpolation 26th March 2015 Thomas Latham - * Reworked MIPW code into abstract base class and derived classes to allow different representations of the amplitude at each knot 31st December 2015 Daniel Craik - * Added unbinned goodness of fit tests to examples 12th January 2015 Daniel Craik - * Calculate effective masses for virtual resonances above the upper kinematic limit 10th December 2014 Daniel Craik - * Added coefficient sets to extract gamma from a simultaneous fit to CP and nonCP final states, such as the B0->D_CP K pi and B0->D0bar K pi Dalitz plots, as proposed in Phys. Rev. D79, 051301 (2009) - LauPolarGammaCPCoeffSet uses the CP parameters r, delta and gamma directly @@ -407,63 +408,51 @@ - LauPolarGammaCPCoeffSet allows for a single gamma parameter to be shared between multiple resonances - LauAbsCoeffSet::adjustName made virtual to allow global variables such as gamma to not receive a prefix -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v3r0p1 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v3r0p1 19th June 2015 Thomas Latham - * Factor out the JFit slave code from LauAbsFitModel into a new base class LauSimFitSlave 19th June 2015 Thomas Latham - * Fix check in LauIsobarDynamics::calcDPNormalisationScheme to avoid using hardcoded number -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v3r0 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v3r0 24th October 2014 Thomas Latham - * Fixed bug in floating of Blatt-Weisskopf barrier radii - The values at the pole mass were not being updated when the radii changed 21st October 2014 Daniel Craik - * Fixed bug in LauIsobarDynamics where multiple incoherent amplitudes led to nonsensical fit fractions 17th October 2014 John Back - * Added the ability to calculate the transition amplitude matrix T in LauKMatrixPropagator, as well as a few other minor speed-up changes and code checks. Example/PlotKMatrixTAmp.cc can be used to check the T amplitude variation, phase shift and inelasticity, for a given K matrix channel, as a function of the invariant mass squared variable s 15th October 2014 Thomas Latham - * Add methods to LauIsobarDynamics to make the integration binning more tunable by the user: - setNarrowResonanceThreshold - modify the value below which a resonance is considered to be narrow (defaults to 0.02 GeV/c2) - setIntegralBinningFactor - modify the factor by which the narrow resonance width is divided to obtain the bin size (defaults to 100) * Print warning messages if the memory usage is likely to be very large 13th October 2014 Thomas Latham - * Modify Makefile to allow compilation with ROOT 6 (in addition to maintaining support for ROOT 5) * Fix a few compilation errors on MacOSX 10.9 13th October 2014 Daniel Craik - * Update LauModIndPartWave to allow knots at kinematic limits to be modified - Add new method setKnotAmp to modify existing knots (and the knot at the upper kinematic limit which is automatically added at initialisation) * Update doxygen for LauIsobarDynamics::addIncoherentResonance to mention that incoherent resonances must be added last 10th October 2014 Thomas Latham - * Add new method to LauResonanceMaker to set whether the radius of a given Blatt-Weisskopf category should be fixed of floated * Modify the methods of LauResonanceMaker to set the radius value and whether it should be floated so that they work before and after the resonances have been created 9th October 2014 John Back - * Corrected the eta-eta' and 4pi phase space factors in LauKMatrixPropagator, which is used for the K-matrix amplitude: - calcEtaEtaPRho() does not include the mass difference term m_eta - m_eta' @@ -474,11 +463,9 @@ going on and the reason for the choices made 6th October 2014 Thomas Latham - * Implement the mechanism for floating Blatt-Weisskopf barrier factor radius parameters 30th September 2014 Thomas Latham - * Fix issue in the checks on toy MC generation validity - in the case of exceeding max iterations it was possible to enter an infinite loop - the checks now detect all three possible states: @@ -489,7 +476,6 @@ * Modify behaviour when TTree objects are saved into files to avoid having multiple cycle numbers present 29th September 2014 Daniel Craik - * Add support for incoherent resonances in the signal model - LauIsobarDynamics updated to include incoherent terms - ABC for incoherent resonances, LauAbsIncohRes, added deriving from LauAbsResonance @@ -500,31 +486,25 @@ * Updated parameters in LauConstants to match PDG 2014 14th July 2014 Thomas Latham - * Add intial support for fully-symmetric final states such as B0 -> KS KS KS - Performs the symmetrisation of the signal model - Background (and efficiency) histogram classes need some work if the user wants to provide folded histograms 8th July 2014 Daniel Craik - * Add class for model-independent partial wave - Uses splines to produce a smooth amplitude from a set of magnitude and phase values at given invariant masses - The individual magnitudes and phases can be floated in the fit 16th June 2014 Thomas Latham - * Allow floating of resonance parameters in simultaneous fits 13th June 2014 Thomas Latham - * Fix bug in LauResonanceInfo cloning method, where the width parameter was given a clone of the mass 10th June 2014 Thomas Latham - * Add new function to allow sharing of resonance parameters between components that are not charged conjugates, e.g. LASS_BW and LASS_NR 9th June 2014 Thomas Latham and Daniel Craik - * Fix bug in the new integration scheme - Was not accounting for cases where several resonances share a floating parameter - Meant that the integrals and caches for that resonance were not being updated @@ -535,46 +515,38 @@ - Therefore results are not necessarily comparable between fits run before and after this changeset. - This change will first be released in v3r0. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v2r2 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v2r2 5th June 2014 Thomas Latham - * Fix issue in asymmetric efficiency histogram errors - Fluctuation of bins was incorrectly sampling - assumed area each side of peak was the same 5th June 2014 Thomas Latham (in branch for release in v3r0) - * Introduce intelligent calculation of amplitudes during recalculation of integrals and recaching of data points - Floating resonance parameters is now much more efficient * Make resonance parameters second-stage, also improves fit timing when floating them 3rd June 2014 Rafael Coutinho - * Implement generation of toy MC from fit results in fitSlave 27th May 2014 Thomas Latham (in branch for release in v3r0) - * Complete audit of special functions * Remove unncessary LauAbsDPDynamics base class and move all functionality into LauIsobarDynamics 20th May 2014 Daniel Craik (in branch for release in v3r0) - * Add support for K*_0(1430) and a_0(980) to LauFlatteRes 16th-19th May 2014 Thomas Latham and Daniel Craik (in branch for release in v3r0) - * Update all other lineshapes so that their parameters can float - The only resonance parameters that now cannot float are the Blatt-Weisskopf barrier factor radii 15th May 2014 Thomas Latham (in branch for release in v3r0) - * Change the mechanism for getting floating resonance parameters into the fit - Moved from LauResonanceMaker to the resonances themselves - Lays some groundwork for improving the efficiency of recalculating the integrals @@ -582,42 +554,36 @@ 13th May 2014 Daniel Craik (in branch for release in v3r0) - * Fix bug where illegal characters were being propagated from resonance names into TBranch names 6th May 2014 Thomas Latham (in branch for release in v3r0) - * Provide accessors for mass and width parameters 5th May 2014 Louis Henry - * Fix compilation problem by making LauDatabasePDG destructor virtual 4th May 2014 Thomas Latham - -* Provide a new argument to Lau*FitModel::splitSignalComponent to allow fluctuation of the bins on the SCF fraction histogram +* Provide a new argument to LauSimpleFitModel::splitSignalComponent and + LauCPFitModel::splitSignalComponent to allow fluctuation of the bins on the + SCF fraction histogram 29th April 2014 Thomas Latham - * Fix bug in the determination of the integration scheme - Nearby narrow resonances caused problems if their "zones" overlap - These zones are now merged together 29th April 2014 Thomas Latham (in branch for release in v3r0) - * Some improvments to integration scheme storage 26th April 2014 Juan Otalora (in branch for release in v3r0) - * Make integation scheme fixed after first determination - is stored in a new class LauDPPartialIntegralInfo - used on subsequent re-evaluations of the integrals 23rd April 2014 Thomas Latham - * Attempt to improve clarity of LauIsobarDynamics::addResonance function - the 3rd argument is now an enumeration of the various resonance models - removed the optional arguments regarding the change of mass, width & spin @@ -629,7 +595,6 @@ * All examples updated to use new interface 23rd April 2014 Thomas Latham - * Address issue of setting values of resonance parameters for all models - decided to do away with need to have LauIsobarDynamics know everything - LauIsobarDynamics::addResonance now returns a pointer to LauAbsResonance @@ -638,82 +603,67 @@ - Update GenFit3pi example to demonstrate mechanism 22nd April 2014 Thomas Latham - * Allow Gaussian constraints to be added in simultaneous fitting - constraints will be ignored by the slaves - those added directly to fit parameters will be propogated to the master and handled there - those on combinations of parameters should be added in the master process 22nd April 2014 Mark Whitehead - * Update Laura to cope with resonances of spin 4 and spin 5 - Zemach spin terms added to src/LauAbsResonance.cc - BW barrier factors added to src/LauRelBreitWignerRes.cc 19th April 2014 Daniel Craik - * Add LauWeightedSumEffModel which gives an efficiency model from the weighted sum of several LauEffModel objects. * Added pABC, LauAbsEffModel, for LauEffModel and LauWeightedSumEffModel. * Various classes updated to use pointers to LauAbsEffModel instead of LauEffModel. 15th April 2014 Daniel Craik - * Enable LauEfficiencyModel to contain several Lau2DAbsDP objects with the total efficiency calculated as the product. 10th April 2014 Mark Whitehead - * Fix an issue with the likelihood penalty term for Gaussian constraints - Factor two missing in the denominator - New penalty term is: ( x-mean )^2 / 2*(width^2) 4th April 2014 Thomas Latham - * Add storage of fit fractions that have not been efficiency corrected -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v2r1 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v2r1 1st April 2014 Thomas Latham - * Fix issue in LauFitter that prevents compilation with g++ 4.8 - Missing virtual destructor - Take opportunity to audit other special functions 31st March 2014 Mark Whitehead (in branch for release in v2r1) - * Added an efficiency branch to the ntuple produced for toy data samples - Both LauSimpleFitModel and LauCPFitModel updated 28th March 2014 Daniel Craik (in branch for release in v2r2) - * Added support for asymmetric errors to Lau2DHistDP, Lau2DSplineDP and LauEffModel. 27th March 2014 Daniel Craik - * Changed histogram classes to use seeded random number generator for fluctuation and raising or lowering of bins and updated doxygen. 20th March 2014 Mark Whitehead (in branch for release in v2r1) - * Added the ability to add Gaussian contraints to LauFormulaPars of fit parameters - User supplies the information but the LauFormulaPar is constructed behind the scenes 18th March 2014 Thomas Latham - * Improve behaviour of toy generation from fit results 13th March 2014 Juan Otalora (in branch for release in v3r0) - * Extended ability to float mass and width to other resonance lineshapes (Flatte, LASS and G-S) 11th March 2014 Mark Whitehead (in branch for release in v2r1) - * Added the functionality to make LauFormulaPars usable in fits - Added a new class LauAbsRValue which LauParameter and LauFormularPar inherit from - Many files updated to accept LauAbsRValues instead of LauParameters @@ -722,19 +672,16 @@ 10th March 2014 Thomas Latham (in branch for release in v3r0) - * First attempt at floating resonance parameters (work mostly from Juan) - Only works for RelBW lineshape - Can only float mass and width - Works nicely! - Still needs much work to generalise and make more efficient -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v2r0 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v2r0 8th March 2014 Thomas Latham - * Some additional functionality for the CoeffSet classes: - allow the parameter values to be set (optionally setting the initial and generated values as well) - allow the parameters to be set to float or to be fixed in the fit @@ -747,11 +694,9 @@ * Add -Werror to compiler flags (treats warnings as errors) 5th March 2014 Thomas Latham - * Some improvements to LauPolNR to speed up amplitude calculation 2nd March 2014 Thomas Latham - * A number of updates to the CoeffSet classes: - allow specification of the basename just after construction (before being given to the fit model) - allow configuration of the parameter fit ranges (through static methods of base class) @@ -760,41 +705,33 @@ * Some improvements to the Doxygen and runtime information printouts 20th February 2014 Louis Henry - * Add LauPolNR - class for modelling the nonresonant contribution based on BaBar 3K model (arXiv:1201.5897) 6th February 2014 Thomas Latham - * Correct helicity convention information in Doxygen for LauKinematics -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v1r2 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v1r2 5th February 2014 Thomas Latham - * Add rule to the Makefile that creates a rootmap file for the library 4th February 2014 Daniel Craik - * Fixed bug in Lau2DSplineDPPdf - normalisation was not being calculated * Added out-of-range warning in LauBkgndDPModel and supressed excessive warnings 3rd February 2014 Mark Whitehead (in branch for release in v2r0) - * Added a new class to allow parameters to be a function of other parameters - inc/LauFormulaPar.hh - src/LauFormulaPar.cc 28th January 2014 Daniel Craik - * Improved out-of-range efficiency warnings in LauEffModel and supressed excessive errors * Modified LauIsobarDynamics to allow LASS parameters to be configured for LauLASSBWRes and LauLASSNRRes 27th January 2014 Daniel Craik - * Added spline interpolation to DP backgrounds - Added Lau2DSplineDPPdf which uses a spline to model a normalised PDF across a DP - Added pABC, Lau2DAbsDPPdf, for Lau2DHistDPPdf and Lau2DSplineDPPdf and moved common @@ -803,19 +740,16 @@ - setBkgndSpline method added to LauBkgndDPModel to allow use of splines 22nd January 2014 Thomas Latham - * Improve some error checks and corresponding warning messages in LauCPFitModel::setSignalDPParameters 16th January 2014 Thomas Latham - * Add LauRealImagCPCoeffSet, which provides an (x,y), (xbar,ybar) way of parametrising the complex coefficients. * Try to improve timing in the *CoeffSet classes by making the complex coeffs into member variables. 20th December 2013 Daniel Craik - * Added Lau2DCubicSpline which provides cubic spline interpolation of a histogram - Added Lau2DSplineDP which uses a spline to model variation across a DP (eg efficiency) - Added pABC, Lau2DAbsDP, for Lau2DHistDP and Lau2DSplineDP and moved common code @@ -827,7 +761,6 @@ 18th December 2013 Mark Whitehead (in branch for release in v2r0) - * Added functionality to include Gaussian constraints on floated parameters in the fit. The files updated are: @@ -837,53 +770,42 @@ - src/LauParameter.cc 5th December 2013 Thomas Latham - * Fix small bug in GenFitKpipi example where background asymmetry parameter had its limits the wrong way around 4th December 2013 Daniel Craik - * Updated 2D chi-squared code to use adaptive binning. 3rd December 2013 Thomas Latham - * Generalise the Makefile in the examples directory - results in minor changes to the names of 3 of the binaries 3rd December 2013 Thomas Latham (in branch for release in v2r0) - * Have the master save an ntuple with all fitter parameters and the full correlation matrix information. 29th November 2013 Thomas Latham - * Fixed bug in ResultsExtractor where the output file was not written 29th November 2013 Thomas Latham (in branch for release in v2r0) - * Allow the slave ntuples to store the partial covariance matrices in the simultaneous fitting 26th November 2013 Thomas Latham (in branch for release in v2r0) - * Added first version of the simultaneous fitting framework -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v1r1p1 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v1r1p1 22nd November 2013 Thomas Latham - * Fixed bug in LauCPFitModel where values of q = -1 extra PDFs were used regardless of the event charge. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v1r1 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v1r1 20th November 2013 Mark Whitehead - * Changed convention for the barrier factors, swapping from p* to p. This seems to give more physically reasonable results. The files updated are: @@ -891,16 +813,13 @@ - src/LauRelBreitWignerRes.cc 18th October 2013 Thomas Latham - * Fix dependency problem in Makefile 8th October 2013 Thomas Latham - * Some fixes to yield implementation * Minor bug fix in DP background histogram class 7th October 2013 Mark Whitehead - * Update to accept the yields and yield asymmetries as LauParameters. All examples have been updated to reflect this change. This updated the following files: @@ -913,11 +832,9 @@ * Addition of the following particles to src/LauResonanceMaker.cc Ds*+-, Ds0*(2317)+-, Ds2*(2573)+-, Ds1*(2700)+- and Bs*0 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - Laura++ v1r0 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +=== +## Laura++ v1r0 13th September 2013 Thomas Latham - * Initial import of the package into HEPforge diff --git a/doc/mainpage.dox b/doc/mainpage.dox.in rename from doc/mainpage.dox rename to doc/mainpage.dox.in --- a/doc/mainpage.dox +++ b/doc/mainpage.dox.in @@ -23,7 +23,11 @@ /*! \mainpage -Welcome to the Laura++ documentation, please use the links at the top of the page to navigate to particular classes or namespaces.
-The Laura++ project can be found at https://laura.hepforge.org +Welcome to the Laura++ documentation, please use the links at the top of the page to navigate to particular classes or namespaces. + +The Laura++ project webpages can be found at @PROJECT_HOMEPAGE_URL@ + +See also the [README](@PROJECT_SOURCE_DIR@/README.md) and [release notes](@PROJECT_SOURCE_DIR@/doc/ReleaseNotes.md) for more information. + */ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,42 @@ + +list(APPEND EXAMPLE_SOURCES + B3piKMatrixMassProj + B3piKMatrixPlots + CalcChiSq + GenFit3K + GenFit3KS + GenFit3pi + GenFitBelleCPKpipi + GenFitDs2KKpi + GenFitEFKLLM + GenFitKpipi + GenFitNoDP + GenFitNoDPMultiDim + KMatrixDto3pi + KMatrixExample + MergeDataFiles + mixedSampleTest + PlotKMatrixTAmp + PlotResults + point2PointTestSample + QuasiFlatSqDalitz + ResultsExtractor + SimFitCoordinator + SimFitTask + SimFitTaskRooFit + ) + +if(NOT LAURA_BUILD_ROOFIT_TASK) + list(REMOVE_ITEM EXAMPLE_SOURCES SimFitTaskRooFit) +endif() + +foreach( _example ${EXAMPLE_SOURCES}) + add_executable(${_example} ${_example}.cc) + target_link_libraries(${_example} PRIVATE Laura++) + install(TARGETS ${_example} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endforeach() + +# Also install the python script version of GenFit3pi +configure_file(GenFit3pi.py.in GenFit3pi.py @ONLY) +install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/GenFit3pi.py DESTINATION ${CMAKE_INSTALL_BINDIR}) + diff --git a/examples/GenFit3pi.py b/examples/GenFit3pi.py.in rename from examples/GenFit3pi.py rename to examples/GenFit3pi.py.in --- a/examples/GenFit3pi.py +++ b/examples/GenFit3pi.py.in @@ -1,3 +1,4 @@ +#!/usr/bin/env python """ Copyright 2017 University of Warwick @@ -24,9 +25,9 @@ # Process the command-line arguments def usage( progName ) : - print 'Usage:' - print '%s gen [nExpt = 1] [firstExpt = 0]' % progName - print '%s fit [nExpt = 1] [firstExpt = 0]' % progName + print('Usage:') + print('%s gen [nExpt = 1] [firstExpt = 0]' % progName) + print('%s fit [nExpt = 1] [firstExpt = 0]' % progName) if len(sys.argv) < 2 : usage( sys.argv[0] ) @@ -58,13 +59,14 @@ # Import ROOT and load the appropriate libraries import ROOT +ROOT.gSystem.AddDynamicPath('@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@') ROOT.gSystem.Load('libEG') ROOT.gSystem.Load('libHist') ROOT.gSystem.Load('libMatrix') ROOT.gSystem.Load('libTree') ROOT.gSystem.Load('libTreePlayer') ROOT.gSystem.Load('libMinuit') -ROOT.gSystem.Load('../lib/libLaura++.so') +ROOT.gSystem.Load('libLaura++') # If you want to use square DP histograms for efficiency, # backgrounds or you just want the square DP co-ordinates diff --git a/examples/Makefile b/examples/Makefile deleted file mode 100644 --- a/examples/Makefile +++ /dev/null @@ -1,150 +0,0 @@ - ############################################################################ - # Copyright 2005 University of Warwick # - # # - # Licensed under the Apache License, Version 2.0 (the "License"); # - # you may not use this file except in compliance with the License. # - # You may obtain a copy of the License at # - # # - # http://www.apache.org/licenses/LICENSE-2.0 # - # # - # Unless required by applicable law or agreed to in writing, software # - # distributed under the License is distributed on an "AS IS" BASIS, # - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # - # See the License for the specific language governing permissions and # - # limitations under the License. # - # # - # Laura++ package authors: # - # John Back # - # Paul Harrison # - # Thomas Latham # - # # - ############################################################################ - # # - # ---------------------------------------- # - # Standalone Makefile for Laura++ examples # - # ---------------------------------------- # - # # - # Instructions # - # - Review 'external configuration' section below # - # to match systems compilers setup # - # # - # - Make sure the ROOTSYS environment variable is set and points # - # to your ROOT release or the root-config script is in your PATH # - # # - # - run 'make ' # - # # - # Build targets # - # bin - make all examples (default) # - # - make the specific example # - # clean - delete all intermediate and final build objects # - # # - ############################################################################ - -# --- External configuration ---------------------------------- - -# first check that ROOTSYS is defined -ifndef ROOTSYS - ROOTSYS := $(shell root-config --prefix) - ROOTBINDIR := $(shell root-config --bindir) - ifeq ($(ROOTSYS), ) - $(error running of root-config failed or reported null value) - endif -else - ROOTBINDIR := $(ROOTSYS)/bin -endif - -# By default, don't build the LauRooFitSlave class since it depends on RooFit -# and we don't want to pull in that library if we don't have to. -# If you want to build it, just set the SKIPLIST variable to be empty. -SKIPLIST = SlaveRooFit.cc - -ROOTCONFIG := $(ROOTBINDIR)/root-config -ARCH := $(shell $(ROOTCONFIG) --arch) -PLATFORM := $(shell $(ROOTCONFIG) --platform) - -INCLUDES = -WORKDIR = tmp - -ifeq ($(findstring linux, $(ARCH)),linux) -# This set here should work for Linux. -CXX = g++ -LD = g++ -CXXFLAGS = -g -O2 -Wall -Wextra -Wshadow -Woverloaded-virtual -Werror -fPIC -MFLAGS = -MM -LDFLAGS = -g -SOFLAGS = -shared -endif - -ifeq ($(ARCH),macosx64) -# For Mac OS X you may need to put -m64 in CXXFLAGS and SOFLAGS. -CXX = g++ -LD = g++ -CXXFLAGS = -g -O3 -Wall -Wextra -Wshadow -Woverloaded-virtual -Werror -fPIC -m64 -MFLAGS = -MM -LDFLAGS = -g -SOFLAGS = -m64 -dynamiclib -single_module -undefined dynamic_lookup -endif - -# --- Internal configuration ---------------------------------- -INCDIR=../inc -DEPDIR=$(WORKDIR)/dependencies -OBJDIR=$(WORKDIR)/objects - -ROOTCFLAGS := $(shell $(ROOTCONFIG) --cflags) -ROOTLIBS := $(shell $(ROOTCONFIG) --libs) -ROOTLIBS += -lEG -ROOTLIBS += -lMinuit -ROOTLIBS += -lTreePlayer -ifeq ($(strip $(SKIPLIST)),) - ROOTLIBS += -lRooFitCore - ROOTLIBS += -lRooFit -endif -LAURALIBDIR=$(shell pwd | xargs dirname)/lib -LAURALIB = $(LAURALIBDIR)/libLaura++.so - -INCLUDES += -I$(INCDIR) -CXXFLAGS += $(INCLUDES) -CXXFLAGS += $(ROOTCFLAGS) - -default: bin - -# List of all source files -CCLIST:=$(filter-out $(SKIPLIST), $(wildcard *.cc)) - -# List of all object files to build -OLIST:=$(patsubst %.cc,%.o,$(addprefix $(OBJDIR)/,$(notdir $(CCLIST)))) - -# List of all dependency files to make -DLIST:=$(patsubst %.cc,%.d,$(addprefix $(DEPDIR)/,$(notdir $(CCLIST)))) - -# List of all binary files to make -BINLIST:=$(patsubst %.cc,%,$(notdir $(CCLIST))) - -# Implicit rule making all dependency Makefiles included at the end of this makefile -$(DEPDIR)/%.d: %.cc - @echo "Making $@" - @mkdir -p $(DEPDIR) - @set -e; $(CXX) $(MFLAGS) $(CXXFLAGS) $< \ - | sed 's#\($(notdir $*)\)\.o[ :]*#$(OBJDIR)/\1.o $@ : #g' > $@; \ - [ -s $@ ] || rm -f $@ - -# Implicit rule to compile all sources -$(OBJDIR)/%.o : %.cc - @echo "Compiling $<" - @mkdir -p $(OBJDIR) - @$(CXX) $(CXXFLAGS) -c $< -o $@ - -# Rule to compile all binaries -% : $(OBJDIR)/%.o $(LAURALIB) - @echo "Linking $@" - @$(CXX) $(LDFLAGS) $< -o $@ $(LAURALIB) $(ROOTLIBS) - -bin: $(BINLIST) - -clean: - rm -f $(BINLIST) - rm -rf $(WORKDIR) - -.PHONY : bin default clean - --include $(DLIST) diff --git a/examples/QuasiFlatSqDalitz.cc b/examples/QuasiFlatSqDalitz.cc new file mode 100644 --- /dev/null +++ b/examples/QuasiFlatSqDalitz.cc @@ -0,0 +1,122 @@ + +/* +Copyright 2018 University of Warwick + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Laura++ package authors: +John Back +Paul Harrison +Thomas Latham +*/ + +#include +#include +#include +#include + +#include "TFile.h" +#include "TRandom.h" +#include "TTree.h" + +#include "LauDaughters.hh" +#include "LauKinematics.hh" +#include "LauRandom.hh" + +/* + * Generates toy MC according to EvtGen's FLATSQDALITZ model + * + * Usage: QuasiFlatSqDalitz + */ + +int main( int argc, char** argv ) +{ + // Convert the command-line arguments into a useful format + const std::vector cmdLineArgs{ argv, argv+argc }; + + if ( cmdLineArgs.size() != 6 ) { + std::cout << "Usage: " << cmdLineArgs[0] << " " << std::endl; + return 0; + } + + const TString& parent { cmdLineArgs[1] }; + const TString& child_1 { cmdLineArgs[2] }; + const TString& child_2 { cmdLineArgs[3] }; + const TString& child_3 { cmdLineArgs[4] }; + const ULong_t nEvents { std::stoul( cmdLineArgs[5].Data() ) }; + + // If you want to use square DP histograms for efficiency, + // backgrounds or you just want the square DP co-ordinates + // stored in the toy MC ntuple then set this to kTRUE + Bool_t squareDP { kTRUE }; + + // This defines the DP => decay is B+ -> pi+ pi+ pi- + // Particle 1 = pi+ + // Particle 2 = pi+ + // Particle 3 = pi- + // The DP is defined in terms of m13Sq and m23Sq + LauDaughters* daughters { new LauDaughters(parent, child_1, child_2, child_3, squareDP) }; + + LauKinematics* kinematics { daughters->getKinematics() }; + + Double_t m12Sq{0.0}, m13Sq{0.0}, m23Sq{0.0}, mPrime{0.0}, thPrime{0.0}, jacobian{0.0}, invJacobian{0.0}, randomNum{0.0}; + + TString fileName { TString::Format( "%s_%s_%s_%s.root", daughters->getSanitisedNameParent().Data(), daughters->getSanitisedNameDaug1().Data(), daughters->getSanitisedNameDaug2().Data(), daughters->getSanitisedNameDaug3().Data() ) }; + TFile * file { TFile::Open(fileName,"recreate") }; + TTree * tree { new TTree("genResults","genResults") }; + + tree->Branch("m12Sq",&m12Sq,"m12Sq/D"); + tree->Branch("m13Sq",&m13Sq,"m13Sq/D"); + tree->Branch("m23Sq",&m23Sq,"m23Sq/D"); + tree->Branch("mPrime",&mPrime,"mPrime/D"); + tree->Branch("thPrime",&thPrime,"thPrime/D"); + tree->Branch("jacobian",&jacobian,"jacobian/D"); + tree->Branch("invJacobian",&invJacobian,"invJacobian/D"); + tree->Branch("randomNum",&randomNum,"randomNum/D"); + + Bool_t evtAccepted{kFALSE}; + for ( ULong_t i{0}; i < nEvents; ++i ) { + + if ( nEvents > 1000 && i%(nEvents/1000)==0 ) { + std::cout << "Generating event " << i << std::endl; + } + + evtAccepted = kFALSE; + + while ( !evtAccepted ) { + kinematics->genFlatPhaseSpace( m13Sq, m23Sq ); + kinematics->updateKinematics( m13Sq, m23Sq ); + jacobian = kinematics->calcSqDPJacobian(); + invJacobian = (jacobian<1.0) ? 1.0 : 1.0/jacobian; + + randomNum = LauRandom::randomFun()->Rndm(); + if ( randomNum < invJacobian ) { + evtAccepted = kTRUE; + m12Sq = kinematics->getm12Sq(); + mPrime = kinematics->getmPrime(); + thPrime = kinematics->getThetaPrime(); + + tree->Fill(); + } + } + } + + file->Write(); + file->Close(); + delete file; + + return EXIT_SUCCESS; +} + diff --git a/examples/Master.cc b/examples/SimFitCoordinator.cc rename from examples/Master.cc rename to examples/SimFitCoordinator.cc --- a/examples/Master.cc +++ b/examples/SimFitCoordinator.cc @@ -32,12 +32,12 @@ #include "TString.h" #include "TSystem.h" -#include "LauSimFitMaster.hh" +#include "LauSimFitCoordinator.hh" void usage( std::ostream& out, const TString& progName ) { out<<"Usage:\n"; - out< [firstExpt = 0] [numSlaves = 2] [port = 0]\n"; + out< [firstExpt = 0] [numTasks = 2] [port = 0]\n"; } int main(const int argc, const char ** argv) @@ -50,7 +50,7 @@ UInt_t iFit = atoi( argv[1] ); UInt_t nExpt = atoi( argv[2] ); UInt_t firstExpt = 0; - UInt_t nSlaves = 2; + UInt_t nTasks = 2; UInt_t port = 0; Bool_t useAsymmErrors = kFALSE; @@ -60,7 +60,7 @@ firstExpt = atoi( argv[3] ); if ( argc > 4 ) { - nSlaves = atoi( argv[4] ); + nTasks = atoi( argv[4] ); if ( argc > 5 ) { port = atoi( argv[5] ); @@ -68,12 +68,12 @@ } } - TString ntupleName = "master-ntuple-"; + TString ntupleName = "coordinator-ntuple-"; ntupleName += iFit; ntupleName += ".root"; - LauSimFitMaster master( nSlaves, port ); - master.runSimFit( ntupleName, nExpt, firstExpt, useAsymmErrors, twoStageFit ); + LauSimFitCoordinator coordinator( nTasks, port ); + coordinator.runSimFit( ntupleName, nExpt, firstExpt, useAsymmErrors, twoStageFit ); return EXIT_SUCCESS; } diff --git a/examples/Slave.cc b/examples/SimFitTask.cc rename from examples/Slave.cc rename to examples/SimFitTask.cc --- a/examples/Slave.cc +++ b/examples/SimFitTask.cc @@ -52,9 +52,9 @@ { // Process command-line arguments // Usage: - // ./Slave gen [nExpt = 1] [firstExpt = 0] + // ./SimFitTask gen [nExpt = 1] [firstExpt = 0] // or - // ./Slave fit [nExpt = 1] [firstExpt = 0] + // ./SimFitTask fit [nExpt = 1] [firstExpt = 0] if ( argc < 3 ) { usage( std::cerr, argv[0] ); return EXIT_FAILURE; @@ -214,7 +214,7 @@ // Generate toy from the fitted parameters //TString fitToyFileName("fitToyMC_"); //fitToyFileName += category; - //fitToyFileName += "-Slave_"; + //fitToyFileName += "-Task_"; //fitToyFileName += iFit; //fitToyFileName += ".root"; //fitModel->compareFitData(100, fitToyFileName); @@ -222,30 +222,30 @@ // Write out per-event likelihoods and sWeights //TString splotFileName("splot_"); //splotFileName += category; - //splotFileName += "-Slave_"; + //splotFileName += "-Task_"; //splotFileName += iFit; //splotFileName += ".root"; //fitModel->writeSPlotData(splotFileName, "splot", kFALSE); // Set the names of the files to read/write - TString dataFile("gen-"); dataFile += category; dataFile += "-Slave.root"; + TString dataFile("gen-"); dataFile += category; dataFile += "-Task.root"; TString treeName("genResults"); TString rootFileName(""); TString tableFileName(""); if (command == "fit") { - rootFileName = "fit"; rootFileName += category; rootFileName += "-Slave_"; rootFileName += iFit; + rootFileName = "fit"; rootFileName += category; rootFileName += "-Task_"; rootFileName += iFit; rootFileName += "_expt_"; rootFileName += firstExpt; rootFileName += "-"; rootFileName += (firstExpt+nExpt-1); rootFileName += ".root"; - tableFileName = "fit"; tableFileName += category; tableFileName += "SlaveResults_"; tableFileName += iFit; + tableFileName = "fit"; tableFileName += category; tableFileName += "TaskResults_"; tableFileName += iFit; } else { rootFileName = "dummy.root"; - tableFileName = "gen"; tableFileName += category; tableFileName += "SlaveResults_"; + tableFileName = "gen"; tableFileName += category; tableFileName += "TaskResults_"; } // Execute the generation/fit if ( command == "fit" ) { - fitModel->runSlave( dataFile, treeName, rootFileName, tableFileName, hostname, port ); + fitModel->runTask( dataFile, treeName, rootFileName, tableFileName, hostname, port ); } else { fitModel->run( command, dataFile, treeName, rootFileName, tableFileName ); } diff --git a/examples/SlaveRooFit.cc b/examples/SimFitTaskRooFit.cc rename from examples/SlaveRooFit.cc rename to examples/SimFitTaskRooFit.cc --- a/examples/SlaveRooFit.cc +++ b/examples/SimFitTaskRooFit.cc @@ -37,7 +37,7 @@ #include "TString.h" #include "TTree.h" -#include "LauRooFitSlave.hh" +#include "LauRooFitTask.hh" void usage( std::ostream& out, const TString& progName ) { @@ -51,9 +51,9 @@ { // Process command-line arguments // Usage: - // ./SlaveRooFit gen [nExpt = 1] [firstExpt = 0] + // ./SimFitTaskRooFit gen [nExpt = 1] [firstExpt = 0] // or - // ./SlaveRooFit fit [nExpt = 1] [firstExpt = 0] + // ./SimFitTaskRooFit fit [nExpt = 1] [firstExpt = 0] if ( argc < 3 ) { usage( std::cerr, argv[0] ); return EXIT_FAILURE; @@ -158,9 +158,9 @@ // Execute the generation/fit if ( command == "fit" ) { - // Create the slave instance - LauRooFitSlave fitModel(model, kTRUE, RooArgSet(mB)); - fitModel.runSlave( dataFile, treeName, rootFileName, tableFileName, "localhost", port ); + // Create the task instance + LauRooFitTask fitModel(model, kTRUE, RooArgSet(mB)); + fitModel.runTask( dataFile, treeName, rootFileName, tableFileName, "localhost", port ); } else { std::cerr << "Can't do this yet" << std::endl; //RooDataSet* data = model.generate( RooArgSet(mB), nTotEvents ); diff --git a/examples/runMasterRooFitSlave.sh b/examples/runCoordinatorRooFitTask.sh rename from examples/runMasterRooFitSlave.sh rename to examples/runCoordinatorRooFitTask.sh --- a/examples/runMasterRooFitSlave.sh +++ b/examples/runCoordinatorRooFitTask.sh @@ -22,20 +22,20 @@ if [ $# -lt 1 ] then - echo "Usage: $0 [firstExpt = 0] [numSlaves = 2]" + echo "Usage: $0 [firstExpt = 0] [numTasks = 2]" exit 1 fi nexpt=$1 firstexpt=0 -numslaves=2 +numtasks=2 if [ $# -gt 1 ] then firstexpt=$2 if [ $# -gt 2 ] then - numslaves=$3 + numtasks=$3 fi fi @@ -45,20 +45,20 @@ # Generate the toy MC #echo "Generating MC" -#./SlaveRooFit gen DD $nexpt $firstexpt > gen-log-DD.out 2>&1 -#./SlaveRooFit gen LL $nexpt $firstexpt > gen-log-LL.out 2>&1 +#./SimFitTaskRooFit gen DD $nexpt $firstexpt > gen-log-DD.out 2>&1 +#./SimFitTaskRooFit gen LL $nexpt $firstexpt > gen-log-LL.out 2>&1 # Do the simultaneous fit -./Master 0 $nexpt $firstexpt $numslaves > master-log.out 2>&1 & +./SimFitCoordinator 0 $nexpt $firstexpt $numtasks > coordinator-log.out 2>&1 & sleep 5 -port=`tail -1 master-log.out | awk '{print $NF}'` +port=`tail -1 coordinator-log.out | awk '{print $NF}'` echo $port -./SlaveRooFit fit DD $port > slave-dd-log.out 2>&1 & +./SimFitTaskRooFit fit DD $port > task-dd-log.out 2>&1 & sleep 1 -./SlaveRooFit fit LL $port > slave-ll-log.out 2>&1 +./SimFitTaskRooFit fit LL $port > task-ll-log.out 2>&1 diff --git a/examples/runMasterSlave.sh b/examples/runCoordinatorTask.sh rename from examples/runMasterSlave.sh rename to examples/runCoordinatorTask.sh --- a/examples/runMasterSlave.sh +++ b/examples/runCoordinatorTask.sh @@ -28,7 +28,7 @@ nexpt=$1 firstexpt=0 -numslaves=2 +numtasks=2 if [ $# -gt 1 ] then @@ -40,15 +40,15 @@ # Generate the toy MC -if [ ! -e gen-DD-Slave.root ] +if [ ! -e gen-DD-Task.root ] then echo "Generating MC for DD category" - ./Slave gen DD $nexpt $firstexpt > gen-log-DD.out 2>&1 + ./SimFitTask gen DD $nexpt $firstexpt > gen-log-DD.out 2>&1 fi -if [ ! -e gen-LL-Slave.root ] +if [ ! -e gen-LL-Task.root ] then echo "Generating MC for LL category" - ./Slave gen LL $nexpt $firstexpt > gen-log-LL.out 2>&1 + ./SimFitTask gen LL $nexpt $firstexpt > gen-log-LL.out 2>&1 fi # Do the simultaneous fit @@ -56,21 +56,21 @@ do echo "Running fit $ifit" - ./Master $ifit $nexpt $firstexpt $numslaves > master-log-$ifit.out 2>&1 & + ./SimFitCoordinator $ifit $nexpt $firstexpt $numtasks > coordinator-log-$ifit.out 2>&1 & sleep 5 - NUMOFLINES=$(wc -l < "master-log-$ifit.out") + NUMOFLINES=$(wc -l < "coordinator-log-$ifit.out") while [ $NUMOFLINES -lt 1 ] do sleep 5 - NUMOFLINES=$(wc -l < "master-log-$ifit.out") + NUMOFLINES=$(wc -l < "coordinator-log-$ifit.out") done - port=`tail -1 master-log-$ifit.out | awk '{print $NF}'` + port=`tail -1 coordinator-log-$ifit.out | awk '{print $NF}'` - ./Slave fit DD $ifit $port localhost > slave-dd-log-$ifit.out 2>&1 & + ./SimFitTask fit DD $ifit $port localhost > task-dd-log-$ifit.out 2>&1 & sleep 1 - ./Slave fit LL $ifit $port localhost > slave-ll-log-$ifit.out 2>&1 + ./SimFitTask fit LL $ifit $port localhost > task-ll-log-$ifit.out 2>&1 done # Extract the best fit @@ -78,11 +78,11 @@ ls fitDD*.root > input-list-DD.txt ls fitLL*.root > input-list-LL.txt -ls master-ntuple-*.root > input-list-master.txt +ls coordinator-ntuple-*.root > input-list-coordinator.txt ./ResultsExtractorMain $nexpt input-list-DD.txt best-fits-DD.root > resultsextractor-DD.out 2>&1 ./ResultsExtractorMain $nexpt input-list-LL.txt best-fits-LL.root > resultsextractor-LL.out 2>&1 -./ResultsExtractorMain $nexpt input-list-master.txt best-fits-master.root > resultsextractor-master.out 2>&1 +./ResultsExtractorMain $nexpt input-list-coordinator.txt best-fits-coordinator.root > resultsextractor-coordinator.out 2>&1 diff --git a/inc/CMakeLists.txt b/inc/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/inc/CMakeLists.txt @@ -0,0 +1,5 @@ + +# Install the headers +file(GLOB LAURA_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hh) +install(FILES ${LAURA_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}) + diff --git a/inc/LauAbsFitModel.hh b/inc/LauAbsFitModel.hh --- a/inc/LauAbsFitModel.hh +++ b/inc/LauAbsFitModel.hh @@ -73,7 +73,7 @@ #include "LauFitObject.hh" #include "LauFormulaPar.hh" -#include "LauSimFitSlave.hh" +#include "LauSimFitTask.hh" // LauSPlot included to get LauSPlot::NameSet typedef #include "LauSPlot.hh" @@ -84,7 +84,7 @@ class LauAbsRValue; class LauParameter; -class LauAbsFitModel : public LauSimFitSlave { +class LauAbsFitModel : public LauSimFitTask { public: //! Constructor @@ -448,7 +448,7 @@ */ virtual void setupResultsOutputs( const TString& histFileName, const TString& tableFileName ); - //! Package the initial fit parameters for transmission to the master + //! Package the initial fit parameters for transmission to the coordinator /*! \param [out] array the array to be filled with the LauParameter objects */ @@ -456,16 +456,16 @@ //! Perform all finalisation actions /*! - - Receive the results of the fit from the master + - Receive the results of the fit from the coordinator - Perform any finalisation routines - - Package the finalised fit parameters for transmission back to the master + - Package the finalised fit parameters for transmission back to the coordinator \param [in] fitStat the status of the fit, e.g. status code, EDM, NLL - \param [in] parsFromMaster the parameters at the fit minimum + \param [in] parsFromCoordinator the parameters at the fit minimum \param [in] covMat the fit covariance matrix - \param [out] parsToMaster the array to be filled with the finalised LauParameter objects + \param [out] parsToCoordinator the array to be filled with the finalised LauParameter objects */ - virtual void finaliseExperiment( const LauAbsFitter::FitStatus& fitStat, const TObjArray* parsFromMaster, const TMatrixD* covMat, TObjArray& parsToMaster ); + virtual void finaliseExperiment( const LauAbsFitter::FitStatus& fitStat, const TObjArray* parsFromCoordinator, const TMatrixD* covMat, TObjArray& parsToCoordinator ); //! Write the results of the fit into the ntuple /*! diff --git a/inc/LauAbsResonance.hh b/inc/LauAbsResonance.hh --- a/inc/LauAbsResonance.hh +++ b/inc/LauAbsResonance.hh @@ -64,10 +64,11 @@ LASS_BW, /*!< the resonant part of the LASS amplitude */ LASS_NR, /*!< the nonresonant part of the LASS amplitude */ EFKLLM, /*!< a form-factor-based description of the Kpi S-wave */ - KMatrix, /*!< S-wave description using K-matrix and P-vector */ + KMatrix, /*!< description using K-matrix and P-vector */ FlatNR, /*!< a uniform nonresonant amplitude */ NRModel, /*!< a theoretical model nonresonant amplitude */ BelleNR, /*!< an empirical exponential nonresonant amplitude */ + RescatterThreshold, /*!< a theoretical model to account for rescattering from a nearby-threshold channel */ PowerLawNR, /*!< an empirical power law nonresonant amplitude */ BelleSymNR, /*!< an empirical exponential nonresonant amplitude for symmetrised DPs */ BelleSymNRNoInter, /*!< an empirical exponential nonresonant amplitude for symmetrised DPs without interference */ @@ -117,8 +118,9 @@ \param [in] resName the name of the component \param [in] resPairAmpInt the number of the daughter not produced by the resonance \param [in] daughters the daughter particles + \param [in] resSpin the spin of the final channel into which the K-matrix scatters */ - LauAbsResonance(const TString& resName, const Int_t resPairAmpInt, const LauDaughters* daughters); + LauAbsResonance(const TString& resName, const Int_t resPairAmpInt, const LauDaughters* daughters, const Int_t resSpin); //! Destructor virtual ~LauAbsResonance(); @@ -473,37 +475,37 @@ LauAbsResonance& operator=(const LauAbsResonance& rhs); //! Information on the resonance - LauResonanceInfo* resInfo_; + LauResonanceInfo* resInfo_{0}; //! Information on the particles const LauDaughters* daughters_; //! Parent name - TString nameParent_; + TString nameParent_{""}; //! Daughter 1 name - TString nameDaug1_; + TString nameDaug1_{""}; //! Daughter 2 name - TString nameDaug2_; + TString nameDaug2_{""}; //! Bachelor name - TString nameBachelor_; + TString nameBachelor_{""}; //! Parent charge - Int_t chargeParent_; + Int_t chargeParent_{0}; //! Daughter 1 charge - Int_t chargeDaug1_; + Int_t chargeDaug1_{0}; //! Daughter 2 charge - Int_t chargeDaug2_; + Int_t chargeDaug2_{0}; //! Bachelor charge - Int_t chargeBachelor_; + Int_t chargeBachelor_{0}; //! Parent mass - Double_t massParent_; + Double_t massParent_{0.0}; //! Daughter 1 mass - Double_t massDaug1_; + Double_t massDaug1_{0.0}; //! Daughter 2 mass - Double_t massDaug2_; + Double_t massDaug2_{0.0}; // Bachelor mass - Double_t massBachelor_; + Double_t massBachelor_{0.0}; //! Resonance name TString resName_; @@ -512,49 +514,49 @@ TString sanitisedName_; //! Resonance mass - LauParameter* resMass_; + LauParameter* resMass_{0}; //! Resonance width - LauParameter* resWidth_; + LauParameter* resWidth_{0}; //! All parameters of the resonance std::vector resParameters_; //! Resonance spin - Int_t resSpin_; + Int_t resSpin_; //! Resonance charge - Int_t resCharge_; + Int_t resCharge_{0}; //! DP axis identifier Int_t resPairAmpInt_; //! Blatt Weisskopf barrier for parent decay - LauBlattWeisskopfFactor* parBWFactor_; + LauBlattWeisskopfFactor* parBWFactor_{0}; //! Blatt Weisskopf barrier for resonance decay - LauBlattWeisskopfFactor* resBWFactor_; + LauBlattWeisskopfFactor* resBWFactor_{0}; //! Spin formalism - LauSpinType spinType_; + LauSpinType spinType_{Zemach_P}; //! Boolean to flip helicity - Bool_t flipHelicity_; + Bool_t flipHelicity_{kFALSE}; //! Boolean to ignore the momentum factors in both the spin factor and the mass-dependent width - Bool_t ignoreMomenta_; + Bool_t ignoreMomenta_{kFALSE}; //! Boolean to set the spinTerm to unity always - Bool_t ignoreSpin_; + Bool_t ignoreSpin_{kFALSE}; //! Boolean to ignore barrier factor scaling in the amplitude numerator, they are still used for the mass-dependent width - Bool_t ignoreBarrierScaling_; + Bool_t ignoreBarrierScaling_{kFALSE}; // Event kinematics information //! Invariant mass - Double_t mass_; + Double_t mass_{0.0}; //! Helicity angle cosine - Double_t cosHel_; + Double_t cosHel_{0.0}; //! Daughter momentum in resonance rest frame - Double_t q_; + Double_t q_{0.0}; //! Bachelor momentum in resonance rest frame - Double_t p_; + Double_t p_{0.0}; //! Bachelor momentum in parent rest frame - Double_t pstar_; + Double_t pstar_{0.0}; //! Covariant factor /*! @@ -566,10 +568,10 @@ \see LauKinematics::getcov13 \see LauKinematics::getcov23 */ - Double_t erm_; + Double_t erm_{1.0}; //! Covariant factor (full spin-dependent expression) - Double_t covFactor_; + Double_t covFactor_{1.0}; ClassDef(LauAbsResonance,0) // Abstract resonance class diff --git a/inc/LauBlattWeisskopfFactor.hh b/inc/LauBlattWeisskopfFactor.hh --- a/inc/LauBlattWeisskopfFactor.hh +++ b/inc/LauBlattWeisskopfFactor.hh @@ -90,7 +90,7 @@ /*! \param newSpin the value of the spin to use for the created instance */ - LauBlattWeisskopfFactor* createClone( const UInt_t newSpin ); + LauBlattWeisskopfFactor* createClone( const UInt_t newSpin , const BarrierType newBarrierType ); //! Retrieve the radius parameter const LauParameter* getRadiusParameter() const { return radius_; } @@ -116,7 +116,7 @@ private: //! Copy constructor - LauBlattWeisskopfFactor( const LauBlattWeisskopfFactor& other, const UInt_t newSpin ); + LauBlattWeisskopfFactor( const LauBlattWeisskopfFactor& other, const UInt_t newSpin, const BarrierType newBarrierType ); //! Copy assignment operator (not implemented) LauBlattWeisskopfFactor& operator=( const LauBlattWeisskopfFactor& other ); diff --git a/inc/LauCalcChiSq.hh b/inc/LauCalcChiSq.hh --- a/inc/LauCalcChiSq.hh +++ b/inc/LauCalcChiSq.hh @@ -23,6 +23,7 @@ */ #include "TH2Poly.h" +#include "TGraph.h" #include "TString.h" #include @@ -115,6 +116,8 @@ TString treeName1_; //! Name of the high stats data tree TString treeName2_; + //! Experiment number in the toy file + TString iExpt_; //! Name of the x-coordinate branch in tree 1 TString xName1_; @@ -124,6 +127,10 @@ TString yName1_; //! Name of the y-coordinate branch in tree 2 TString yName2_; + //! Title of the x-coordinate for drawing + TString xTitle_; + //! Title of the y-coordinate for drawing + TString yTitle_; //! The minimum bin content Float_t minContent_; @@ -140,7 +147,11 @@ TH2Poly* chiSqHisto_; //! Histogram (constructed from template) filled with signed chisq of tree1 vs tree2 TH2Poly* chiSqSignedHisto_; - + //! Graph for data + TGraph* g_data_; + //! Graph for toy + TGraph* g_toy_; + //! Minimum x coordinate of histograms Float_t xMin_; //! Maximum x coordinate of histograms diff --git a/inc/LauConstants.hh b/inc/LauConstants.hh --- a/inc/LauConstants.hh +++ b/inc/LauConstants.hh @@ -38,30 +38,35 @@ namespace LauConstants { + //! Mass of D*(2010)+ (GeV/c^2) + const Double_t mDst = 2.0102600000; // NEW! 18/1/19 + //! Mass of K*(892)0 (GeV/c^2) + const Double_t mKst0 = 0.8955500000; // NEW! 18/1/19 + //! Mass of charged D (GeV/c^2) - const Double_t mD = 1.86961; + const Double_t mD = 1.8696500000; // NEW! 18/1/19 //! Mass of neutral D (GeV/c^2) - const Double_t mD0 = 1.86484; + const Double_t mD0 = 1.8648300000; // NEW! 18/1/19 //! Mass of Ds (GeV/c^2) - const Double_t mDs = 1.96830; + const Double_t mDs = 1.9683400000; // NEW! 18/1/19 //! Mass of charged B (GeV/c^2) - const Double_t mB = 5.27926; + const Double_t mB = 5.2793200000; // NEW! 18/1/19 //! Mass of neutral B_d (GeV/c^2) - const Double_t mB0 = 5.27958; + const Double_t mB0 = 5.2796300000; // NEW! 18/1/19 //! Mass of neutral B_s (GeV/c^2) - const Double_t mBs0 = 5.36677; + const Double_t mBs0 = 5.3668900000; // NEW! 18/1/19 //! Mass of pi+- (GeV/c^2) - const Double_t mPi = 0.13957018; + const Double_t mPi = 0.1395706100; // NEW! 18/1/19 //! Mass of pi0 (GeV/c^2) const Double_t mPi0 = 0.1349766; //! Mass of K+- (GeV/c^2) - const Double_t mK = 0.493677; + const Double_t mK = 0.493677; //! Mass of K0 (GeV/c^2) const Double_t mK0 = 0.497614; //! Mass of eta (GeV/c^2) const Double_t mEta = 0.547862; //! Mass of eta' (GeV/c^2) - const Double_t mEtaPrime = 0.95778; + const Double_t mEtaPrime = 0.95778; //! Square of charged D mass const Double_t mDSq = mD*mD; diff --git a/inc/LauFormulaPar.hh b/inc/LauFormulaPar.hh --- a/inc/LauFormulaPar.hh +++ b/inc/LauFormulaPar.hh @@ -166,9 +166,7 @@ //! Vector of LauParameters in the formula std::vector paramVec_; - //! Array - Double_t* dummy_; - //! Array + //! Array to hold parameter values to pass to formula Double_t* paramArray_; //! Choice to use Gaussian constraint diff --git a/inc/LauGounarisSakuraiRes.hh b/inc/LauGounarisSakuraiRes.hh --- a/inc/LauGounarisSakuraiRes.hh +++ b/inc/LauGounarisSakuraiRes.hh @@ -88,12 +88,6 @@ //! Momentum of the daughters in the resonance rest frame (at pole mass) Double_t q0_; - //! Momentum of the bachelor in the resonance rest frame (at pole mass) - Double_t p0_; - //! Momentum of the bachelor in the parent rest frame (at pole mass) - Double_t pstar0_; - //! Covariant factor (at pole mass) - Double_t erm0_; //! The resonance mass Double_t resMass_; //! Square of the resonance mass @@ -124,8 +118,6 @@ Double_t d_; //! Value of the form factor for resonance decay (at pole mass) Double_t FR0_; - //! Value of the form factor for parent decay (at pole mass) - Double_t FP0_; ClassDef(LauGounarisSakuraiRes,0) // Gounaris-Sakurai resonance model diff --git a/inc/LauKMatrixProdPole.hh b/inc/LauKMatrixProdPole.hh --- a/inc/LauKMatrixProdPole.hh +++ b/inc/LauKMatrixProdPole.hh @@ -44,7 +44,7 @@ class LauKMatrixProdPole : public LauAbsResonance { - public: + public: //! Constructor /*! \param [in] poleName name of the pole @@ -54,34 +54,38 @@ \param [in] daughters the daughter particles \param [in] useProdAdler boolean to turn on/off the production Adler zero factor */ - LauKMatrixProdPole(const TString& poleName, Int_t poleIndex, Int_t resPairAmpInt, - LauKMatrixPropagator* propagator, const LauDaughters* daughters, - Bool_t useProdAdler = kFALSE); + LauKMatrixProdPole( const TString& poleName, Int_t poleIndex, Int_t resPairAmpInt, + LauKMatrixPropagator* propagator, const LauDaughters* daughters, + Bool_t useProdAdler = kFALSE); //! Destructor - virtual ~LauKMatrixProdPole(); + virtual ~LauKMatrixProdPole(); // Initialise the model - virtual void initialise() {return;} - - //! The amplitude calculation - /*! - \param [in] kinematics the kinematic variables of the current event - \return the complex amplitude - */ - virtual LauComplex amplitude(const LauKinematics* kinematics); + virtual void initialise() {return;} //! Get the resonance model type - /*! - \return the resonance model type - */ + /*! + \return the resonance model type + */ virtual LauAbsResonance::LauResonanceModel getResonanceModel() const {return LauAbsResonance::KMatrix;} + //! Retrieve the resonance parameters, e.g. so that they can be loaded into a fit + /*! + \return floating parameters of the resonance + */ + virtual const std::vector& getFloatingParameters(); + protected: - //! Function not meant to be called, amplitude is called directly in this case - virtual LauComplex resAmp(Double_t mass, Double_t spinTerm); + //! The amplitude calculation + /*! + \param [in] mass the invariant-mass for the channel + \param [in] spinTerm the spin-term for the final channel + \return the complex amplitude + */ + virtual LauComplex resAmp(const Double_t mass, const Double_t spinTerm); - private: + private: //! Copy constructor (not implemented) LauKMatrixProdPole(const LauKMatrixProdPole& rhs); @@ -89,14 +93,14 @@ LauKMatrixProdPole& operator=(const LauKMatrixProdPole& rhs); //! The K-matrix propagator - LauKMatrixPropagator* thePropagator_; + LauKMatrixPropagator* thePropagator_; //! The number of the pole Int_t poleIndex_; - //! Boolean to turn on/off the production Adler zero factor - Bool_t useProdAdler_; + //! Boolean to turn on/off the production Adler zero factor + Bool_t useProdAdler_; - ClassDef(LauKMatrixProdPole, 0) // K-matrix production pole + ClassDef(LauKMatrixProdPole, 0) // K-matrix production pole }; diff --git a/inc/LauKMatrixProdSVP.hh b/inc/LauKMatrixProdSVP.hh --- a/inc/LauKMatrixProdSVP.hh +++ b/inc/LauKMatrixProdSVP.hh @@ -44,7 +44,7 @@ class LauKMatrixProdSVP : public LauAbsResonance { - public: + public: //! Constructor /*! \param [in] SVPName name of the slowly varying part (SVP) @@ -53,33 +53,37 @@ \param [in] propagator a K-matrix propagator \param [in] daughters the daughter particles \param [in] useProdAdler boolean to turn on/off the production Adler zero factor - */ - LauKMatrixProdSVP(const TString& SVPName, Int_t channelIndex, Int_t resPairAmpInt, - LauKMatrixPropagator* propagator, const LauDaughters* daughters, - Bool_t useProdAdler = kFALSE); + */ + LauKMatrixProdSVP( const TString& SVPName, Int_t channelIndex, Int_t resPairAmpInt, + LauKMatrixPropagator* propagator, const LauDaughters* daughters, + Bool_t useProdAdler = kFALSE); //! Destructor virtual ~LauKMatrixProdSVP(); //! Initialise the model - virtual void initialise() {return;} - - //! The amplitude calculation - /*! - \param [in] kinematics the kinematic variables of the current event - \return the complex amplitude - */ - virtual LauComplex amplitude(const LauKinematics* kinematics); + virtual void initialise() {return;} //! Get the resonance model type - /*! - \return the resonance model type - */ + /*! + \return the resonance model type + */ virtual LauAbsResonance::LauResonanceModel getResonanceModel() const {return LauAbsResonance::KMatrix;} - + + //! Retrieve the resonance parameters, e.g. so that they can be loaded into a fit + /*! + \return floating parameters of the resonance + */ + const std::vector& getFloatingParameters(); + protected: - //! Function not meant to be called - virtual LauComplex resAmp(Double_t mass, Double_t spinTerm); + //! The amplitude calculation + /*! + \param [in] mass the invariant-mass for the channel + \param [in] spinTerm the spin-term for the final channel + \return the complex amplitude + */ + virtual LauComplex resAmp(const Double_t mass, const Double_t spinTerm); private: //! Copy constructor (not implemented) @@ -89,15 +93,15 @@ LauKMatrixProdSVP& operator=(const LauKMatrixProdSVP& rhs); //! The K-matrix propagator - LauKMatrixPropagator* thePropagator_; + LauKMatrixPropagator* thePropagator_; //! The number of the channel Int_t channelIndex_; - //! Boolean to turn on/off the production Adler zero factor - Bool_t useProdAdler_; + //! Boolean to turn on/off the production Adler zero factor + Bool_t useProdAdler_; ClassDef(LauKMatrixProdSVP, 0) // K-matrix production SVP term }; -#endif +#endif \ No newline at end of file diff --git a/inc/LauKMatrixPropagator.hh b/inc/LauKMatrixPropagator.hh --- a/inc/LauKMatrixPropagator.hh +++ b/inc/LauKMatrixPropagator.hh @@ -6,7 +6,7 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -23,23 +23,23 @@ */ /*! \file LauKMatrixPropagator.hh - \brief File containing declaration of LauKMatrixPropagator class. + \brief File containing declaration of LauKMatrixPropagator class. */ /*! \class LauKMatrixPropagator - \brief Class for defining a K-matrix propagator. + \brief Class for defining a K-matrix propagator. - Class used to define a K-matrix propagator. - See the following papers for info: - hep-ph/0204328, hep-ex/0312040, [hep-ex]0804.2089 and hep-ph/9705401. + Class used to define a K-matrix propagator. + See the following papers for info: + hep-ph/0204328, hep-ex/0312040, [hep-ex]0804.2089 and hep-ph/9705401. */ #ifndef LAU_KMATRIX_PROPAGATOR #define LAU_KMATRIX_PROPAGATOR -#include "LauComplex.hh" -#include "LauKinematics.hh" -#include "LauParameter.hh" +#include "LauConstants.hh" +#include "LauResonanceMaker.hh" +#include "LauResonanceInfo.hh" #include "TMatrixD.h" #include "TString.h" @@ -47,9 +47,13 @@ #include #include +class LauParameter; +class LauKinematics; +class LauComplex; + class LauKMatrixPropagator { - public: + public: //! Constructor /*! \param [in] name name of the propagator @@ -59,69 +63,87 @@ \param [in] nPoles the number of poles \param [in] rowIndex this specifies which row of the propagator should be used when summing over the amplitude channels */ - LauKMatrixPropagator(const TString& name, const TString& paramFileName, - Int_t resPairAmpInt, Int_t nChannels, Int_t nPoles, - Int_t rowIndex = 1); + LauKMatrixPropagator( const TString& name, const TString& paramFileName, + const Int_t resPairAmpInt, const Int_t nChannels, const Int_t nPoles, + const Int_t rowIndex = 1 ); //! Destructor - virtual ~LauKMatrixPropagator(); - - //! Calculate the invariant mass squared s - /*! - \param [in] kinematics the kinematics of the current event - */ - void updatePropagator(const LauKinematics* kinematics); + virtual ~LauKMatrixPropagator(); //! Calculate the K-matrix propagator for the given s value /*! \param [in] s the invariant mass squared */ - void updatePropagator(Double_t s); + void updatePropagator(const Double_t s); //! Read an input file to set parameters /*! \param [in] inputFile name of the input file */ - void setParameters(const TString& inputFile); + void setParameters(const TString& inputFile); + + //! Set flag to ignore Blatt-Weisskopf-like barrier factor + void ignoreBWBarrierFactor() {includeBWBarrierFactor_=kFALSE;} - //! Get the scattering K matrix - /*! - \return the real, symmetric scattering K matrix + //! Get the scattering K matrix + /*! + \return the real, symmetric scattering K matrix */ - TMatrixD getKMatrix() const {return ScattKMatrix_;} + TMatrixD getKMatrix() const {return ScattKMatrix_;} - //! Get the real part of the propagator full matrix - /*! - \return the real part of the propagator full matrix - */ - TMatrixD getRealPropMatrix() const {return realProp_;} + //! Get the real part of the propagator full matrix + /*! + \return the real part of the propagator full matrix + */ + TMatrixD getRealPropMatrix() const {return realProp_;} - //! Get the negative imaginary part of the full propagator matrix - /*! - \return the negative imaginary part of the full propagator matrix - */ - TMatrixD getNegImagPropMatrix() const {return negImagProp_;} + //! Get the negative imaginary part of the full propagator matrix + /*! + \return the negative imaginary part of the full propagator matrix + */ + TMatrixD getNegImagPropMatrix() const {return negImagProp_;} //! Get the real part of the term of the propagator /*! \param [in] channelIndex the channel number \return the real part of the propagator term */ - Double_t getRealPropTerm(Int_t channelIndex) const; + Double_t getRealPropTerm(const Int_t channelIndex) const; //! Get the imaginary part of the term of the propagator /*! \param [in] channelIndex the channel number \return the imaginiary part of the propagator term */ - Double_t getImagPropTerm(Int_t channelIndex) const; + Double_t getImagPropTerm(const Int_t channelIndex) const; //! Get the 1/(m_pole^2 -s) terms for the scattering and production K-matrix formulae /*! \param [in] poleIndex the number of the pole required \return the value of 1/(m_pole^2 -s) */ - Double_t getPoleDenomTerm(Int_t poleIndex) const; + Double_t getPoleDenomTerm(const Int_t poleIndex) const; + + //! Get spin of K-matrix + /*! + \param [in] iChannel the index of the channel + \return the value of the orbital angular momentum, L_, for this channel + */ + Int_t getL(const Int_t iChannel) const {return L_[iChannel];} + + //! Get index of final channel + /*! + \return the index of the channel into which the scattering happens + */ + Int_t getIndex() const {return index_;}; + + //! Get pole mass parameters, set according to the input file + /*! + \param [in] poleIndex number of the required pole + \param [in] channelIndex number of the required channel + \return the parameter of the pole mass + */ + LauParameter& getPoleMassSqParameter(const Int_t poleIndex); //! Get coupling constants that were loaded from the input file /*! @@ -129,7 +151,15 @@ \param [in] channelIndex number of the required channel \return the value of the coupling constant */ - Double_t getCouplingConstant(Int_t poleIndex, Int_t channelIndex) const; + Double_t getCouplingConstant(const Int_t poleIndex, const Int_t channelIndex) const; + + //! Get coupling parameters, set according to the input file + /*! + \param [in] poleIndex number of the required pole + \param [in] channelIndex number of the required channel + \return the parameter of the coupling constant + */ + LauParameter& getCouplingParameter(const Int_t poleIndex, const Int_t channelIndex); //! Get scattering constants that were loaded from the input file /*! @@ -137,7 +167,45 @@ \param [in] channel2Index number of the second channel index \return the value of the scattering constant */ - Double_t getScatteringConstant(Int_t channel1Index, Int_t channel2Index) const; + Double_t getScatteringConstant(const Int_t channel1Index, const Int_t channel2Index) const; + + //! Get scattering parameters, set according to the input file + /*! + \param [in] channel1Index number of the first channel index + \param [in] channel2Index number of the second channel index + \return the parameter of the scattering constant + */ + LauParameter& getScatteringParameter(const Int_t channel1Index, const Int_t channel2Index); + + //! Get mSq0 production parameter + /*! + \return the mSq0 parameter + */ + LauParameter& getmSq0() {return mSq0_;} + + //! Get s0Scatt production parameter + /*! + \return the s0Scatt parameter + */ + LauParameter& gets0Scatt() {return s0Scatt_;} + + //! Get s0 production parameter + /*! + \return the s0Prod parameter + */ + LauParameter& gets0Prod() {return s0Prod_;} + + //! Get sA production parameter + /*! + \return the sA parameter + */ + LauParameter& getsA() {return sA_;} + + //! Get sA0 production parameter + /*! + \return the sA0 parameter + */ + LauParameter& getsA0() {return sA0_;} //! Get the "slowly-varying part" term of the amplitude /*! @@ -150,139 +218,170 @@ \param [in] channelIndex the number of the required channel \return the complex propagator term */ - LauComplex getPropTerm(Int_t channelIndex) const; + LauComplex getPropTerm(const Int_t channelIndex) const; //! Get the DP axis identifier /*! - /return the value to identify the DP axis in question + \return the value to identify the DP axis in question */ Int_t getResPairAmpInt() const {return resPairAmpInt_;} //! Get the number of channels /*! - /return the number of channels + \return the number of channels */ Int_t getNChannels() const {return nChannels_;} //! Get the number of poles /*! - /return the number of poles + \return the number of poles */ Int_t getNPoles() const {return nPoles_;} //! Get the propagator name /*! - /return the name of the propagator + \return the name of the propagator */ TString getName() const {return name_;} - //! Get the unitary transition amplitude for the given channel - /*! - \param [in] s The invariant mass squared - \param [in] channel The index number of the channel process - \return the complex amplitude T + //! Get the unitary transition amplitude for the given channel + /*! + \param [in] s The invariant mass squared + \param [in] channel The index number of the channel process + \return the complex amplitude T */ - LauComplex getTransitionAmp(Double_t s, Int_t channel); - + LauComplex getTransitionAmp(const Double_t s, const Int_t channel); - //! Get the complex phase space term for the given channel and invariant mass squared - /*! - \param [in] s The invariant mass squared - \param [in] channel The index number of the channel process - \return the complex phase space term rho(channel, channel) + //! Get the complex phase space term for the given channel and invariant mass squared + /*! + \param [in] s The invariant mass squared + \param [in] channel The index number of the channel process + \return the complex phase space term rho(channel, channel) */ - LauComplex getPhaseSpaceTerm(Double_t s, Int_t channel); + LauComplex getPhaseSpaceTerm(const Double_t s, const Int_t channel); - //! Get the Adler zero factor, which is set when updatePropagator is called - /*! - \return the Adler zero factor + //! Get the Adler zero factor, which is set when updatePropagator is called + /*! + \return the Adler zero factor */ - Double_t getAdlerZero() const {return adlerZeroFactor_;} - + Double_t getAdlerZero() const {return adlerZeroFactor_;} - //! Get the THat amplitude for the given s and channel number - /*! - \param [in] s The invariant mass squared + //! Get the THat amplitude for the given s and channel number + /*! + \param [in] s The invariant mass squared \param [in] channel The index number of the channel process \return the complex THat amplitude */ - LauComplex getTHat(Double_t s, Int_t channel); + LauComplex getTHat(const Double_t s, const Int_t channel); + protected: + // Integers to specify the allowed channels for the phase space calculations. + // Please keep Zero at the start and leave TotChannels at the end + // whenever more channels are added to this. + //! Integers to specify the allowed channels for the phase space calculations + enum class KMatrixChannels {Zero, PiPi, KK, FourPi, EtaEta, EtaEtaP, + KPi, KEtaP, KThreePi, D0K, Dstar0K, TotChannels}; - protected: //! Calculate the scattering K-matrix for the given value of s /*! \param [in] s the invariant mass squared */ - void calcScattKMatrix(Double_t s); + void calcScattKMatrix(const Double_t s); //! Calculate the real and imaginary part of the phase space density diagonal matrix /*! \param [in] s the invariant mass squared */ - void calcRhoMatrix(Double_t s); + void calcRhoMatrix(const Double_t s); + + //! Calculate the (real) gamma angular-momentum barrier matrix + /*! + \param [in] s the invariant mass squared + */ + void calcGammaMatrix(const Double_t s); + + //! Calculate the DK P-wave gamma angular-momentum barrier + /*! + \param [in] s the invariant mass squared + \return the centrifugal barrier factor for L=0,1, or 2 + */ + Double_t calcGamma(const Int_t iCh, const Double_t s, KMatrixChannels phaseSpaceIndex) const; //! Calulate the term 1/(m_pole^2 - s) for the scattering and production K-matrix formulae /*! \param [in] s the invariant mass squared */ - void calcPoleDenomVect(Double_t s); + void calcPoleDenomVect(const Double_t s); + + //! Calculate the D0K+ phase space factor + /*! + \param [in] s the invariant mass squared + \return the complex phase space factor + */ + LauComplex calcD0KRho(const Double_t s) const; + + //! Calculate the D*0K+ phase space factor + /*! + \param [in] s the invariant mass squared + \return the complex phase space factor + */ + LauComplex calcDstar0KRho(const Double_t s) const; //! Calculate the pipi phase space factor /*! \param [in] s the invariant mass squared \return the complex phase space factor */ - LauComplex calcPiPiRho(Double_t s) const; + LauComplex calcPiPiRho(const Double_t s) const; //! Calculate the KK phase space factor /*! \param [in] s the invariant mass squared \return the complex phase space factor */ - LauComplex calcKKRho(Double_t s) const; + LauComplex calcKKRho(const Double_t s) const; //! Calculate the 4 pi phase space factor /*! \param [in] s the invariant mass squared \return the complex phase space factor */ - LauComplex calcFourPiRho(Double_t s) const; + LauComplex calcFourPiRho(const Double_t s) const; //! Calculate the eta-eta phase space factor /*! \param [in] s the invariant mass squared \return the complex phase space factor */ - LauComplex calcEtaEtaRho(Double_t s) const; + LauComplex calcEtaEtaRho(const Double_t s) const; //! Calculate the eta-eta' phase space factor /*! \param [in] s the invariant mass squared \return the complex phase space factor */ - LauComplex calcEtaEtaPRho(Double_t s) const; + LauComplex calcEtaEtaPRho(const Double_t s) const; //! Calculate the Kpi phase space factor /*! \param [in] s the invariant mass squared \return the complex phase space factor */ - LauComplex calcKPiRho(Double_t s) const; + LauComplex calcKPiRho(const Double_t s) const; //! Calculate the K-eta' phase space factor /*! \param [in] s the invariant mass squared \return the complex phase space factor */ - LauComplex calcKEtaPRho(Double_t s) const; + LauComplex calcKEtaPRho(const Double_t s) const; //! Calculate the Kpipipi phase space factor /*! \param [in] s the invariant mass squared \return the complex phase space factor */ - LauComplex calcKThreePiRho(Double_t s) const; + LauComplex calcKThreePiRho(const Double_t s) const; //! Calculate the "slow-varying part" /*! @@ -290,90 +389,107 @@ \param [in] s0 the invariant mass squared at the Adler zero \return the SVP term */ - Double_t calcSVPTerm(Double_t s, Double_t s0) const; + Double_t calcSVPTerm(const Double_t s, const Double_t s0) const; //! Update the scattering "slowly-varying part" /*! \param [in] s the invariant mass squared */ - void updateScattSVPTerm(Double_t s); + void updateScattSVPTerm(const Double_t s); //! Update the production "slowly-varying part" /*! \param [in] s the invariant mass squared */ - void updateProdSVPTerm(Double_t s); + void updateProdSVPTerm(const Double_t s); //! Calculate the multiplicative factor containing severa Adler zero constants /*! \param [in] s the invariant mass squared */ - void updateAdlerZeroFactor(Double_t s); + void updateAdlerZeroFactor(const Double_t s); //! Check the phase space factors that need to be used /*! \param [in] phaseSpaceInt phase space types \return true of false */ - Bool_t checkPhaseSpaceType(Int_t phaseSpaceInt) const; + Bool_t checkPhaseSpaceType(const Int_t phaseSpaceInt) const; - //! Get the unitary transition amplitude matrix for the given kinematics - /*! - \param [in] kinematics The pointer to the constant kinematics + //! Get the unitary transition amplitude matrix for the given kinematics + /*! + \param [in] kinematics The pointer to the constant kinematics */ - void getTMatrix(const LauKinematics* kinematics); + void getTMatrix(const LauKinematics* kinematics); - //! Get the unitary transition amplitude matrix for the given kinematics - /*! - \param [in] s The invariant mass squared of the system + //! Get the unitary transition amplitude matrix for the given kinematics + /*! + \param [in] s The invariant mass squared of the system */ - void getTMatrix(Double_t s); + void getTMatrix(const Double_t s); + + //! Get the square root of the phase space matrix + void getSqrtRhoMatrix(); - //! Get the square root of the phase space matrix - void getSqrtRhoMatrix(); - - private: + private: //! Copy constructor (not implemented) - LauKMatrixPropagator(const LauKMatrixPropagator& rhs); + LauKMatrixPropagator(const LauKMatrixPropagator& rhs)=delete; //! Copy assignment operator (not implemented) - LauKMatrixPropagator& operator=(const LauKMatrixPropagator& rhs); + LauKMatrixPropagator& operator=(const LauKMatrixPropagator& rhs)=delete; - //! Create a map for the K-matrix parameters - typedef std::map > KMatrixParamMap; + //! Initialise and set the dimensions for the internal matrices and parameter arrays + void initialiseMatrices(); + //! Store the (phase space) channel indices from a line in the parameter file + /*! + \param [in] theLine Vector of strings corresponding to the line from the parameter file + */ + void storeChannels(const std::vector& theLine); + + //! Store the pole mass and couplings from a line in the parameter file + /*! + \param [in] theLine Vector of strings corresponding to the line from the parameter file + */ + void storePole(const std::vector& theLine); - //! Initialise and set the dimensions for the internal matrices and parameter arrays - void initialiseMatrices(); + //! Store the scattering coefficients from a line in the parameter file + /*! + \param [in] theLine Vector of strings corresponding to the line from the parameter file + */ + void storeScattering(const std::vector& theLine); - //! Store the (phase space) channel indices from a line in the parameter file - /*! - \param [in] theLine Vector of strings corresponding to the line from the parameter file + //! Store the channels' characteristic radii from a line in the parameter file + /*! + \param [in] theLine Vector of strings corresponding to the line from the parameter file */ - void storeChannels(const std::vector& theLine); - - //! Store the pole mass and couplings from a line in the parameter file - /*! - \param [in] theLine Vector of strings corresponding to the line from the parameter file + void storeRadii(const std::vector& theLine); + + //! Store the channels' angular momenta from a line in the parameter file + /*! + \param [in] theLine Vector of strings corresponding to the line from the parameter file + \param [in] a Vector of integers corresponding to parameter in the propagator denominator */ - void storePole(const std::vector& theLine); + void storeOrbitalAngularMomenta(const std::vector& theLine, std::vector a); - //! Store the scattering coefficients from a line in the parameter file - /*! - \param [in] theLine Vector of strings corresponding to the line from the parameter file + //! Store the barrier-factor parameter from a line in the parameter file + /*! + \param [in] theLine Vector of strings corresponding to the line from the parameter file + \param [in] a Vector of integers corresponding to parameter in the propagator denominator */ - void storeScattering(const std::vector& theLine); + void storeBarrierFactorParameter(const std::vector& theLine, std::vector a); + - //! Store miscelleanous parameters from a line in the parameter file - /*! - \param [in] keyword the name of the parameter to be set - \param [in] parString the string containing the value of the parameter + //! Store miscelleanous parameters from a line in the parameter file + /*! + \param [in] keyword the name of the parameter to be set + \param [in] parString the string containing the value of the parameter */ - void storeParameter(const TString& keyword, const TString& parString); + void storeParameter(const TString& keyword, const TString& parString); - //! String to store the propagator name + //! String to store the propagator name TString name_; //! Name of the input parameter file TString paramFileName_; @@ -383,29 +499,24 @@ Int_t index_; //! s value of the previous pole - Double_t previousS_; + Double_t previousS_{0.0}; //! "slowly-varying part" for the scattering K-matrix - Double_t scattSVP_; + Double_t scattSVP_{0.0}; //! "slowly-varying part" for the production K-matrix - Double_t prodSVP_; + Double_t prodSVP_{0.0}; //! Real part of the propagator matrix TMatrixD realProp_; //! Imaginary part of the propagator matrix TMatrixD negImagProp_; - // Integers to specify the allowed channels for the phase space calculations. - // Please keep Zero at the start and leave TotChannels at the end - // whenever more channels are added to this. - //! Integers to specify the allowed channels for the phase space calculations - enum KMatrixChannels {Zero, PiPi, KK, FourPi, EtaEta, EtaEtaP, - KPi, KEtaP, KThreePi, TotChannels}; - //! Scattering K-matrix TMatrixD ScattKMatrix_; //! Real part of the phase space density diagonal matrix TMatrixD ReRhoMatrix_; //! Imaginary part of the phase space density diagonal matrix TMatrixD ImRhoMatrix_; + //! Gamma angular-momentum barrier matrix + TMatrixD GammaMatrix_; //! Identity matrix TMatrixD IMatrix_; //! Null matrix @@ -415,26 +526,36 @@ TMatrixD ReSqrtRhoMatrix_; //! Imaginary part of the square root of the phase space density diagonal matrix TMatrixD ImSqrtRhoMatrix_; - //! Real part of the unitary T matrix - TMatrixD ReTMatrix_; - //! Imaginary part of the unitary T matrix - TMatrixD ImTMatrix_; + //! Real part of the unitary T matrix + TMatrixD ReTMatrix_; + //! Imaginary part of the unitary T matrix + TMatrixD ImTMatrix_; //! Number of channels Int_t nChannels_; //! Number of poles Int_t nPoles_; + //! Vector of orbital angular momenta + std::vector L_; + //! Boolean to indicate whether storeBarrierFactorParameter has been called + Bool_t haveCalled_storeBarrierFactorParameter{kFALSE}; + //! Boolean to dictate whether to include Blatt-Weisskopf-like denominator in K-matrix centrifugal barrier factor + Bool_t includeBWBarrierFactor_{kTRUE}; //! Vector of squared pole masses - std::vector mSqPoles_; + std::vector mSqPoles_; //! Array of coupling constants - LauParArray gCouplings_; + LauParArray gCouplings_; //! Array of scattering SVP values - LauParArray fScattering_; + LauParArray fScattering_; + //! Vector of characteristic radii + std::vector radii_; + //! Vector of ratio a/R^2 + std::vector gamAInvRadSq_; //! Vector of phase space types - std::vector phaseSpaceTypes_; + std::vector phaseSpaceTypes_; //! Vector of squared masses std::vector mSumSq_; //! Vector of mass differences @@ -454,44 +575,53 @@ LauParameter sA0_; //! Defined as 0.5*sA*mPi*mPi - Double_t sAConst_; + Double_t sAConst_{0.0}; + //! Defined as 4*mPi*mPi - Double_t m2piSq_; + const Double_t m2piSq_{4.0*LauConstants::mPiSq}; //! Defined as 4*mK*mK - Double_t m2KSq_; + const Double_t m2KSq_{4.0*LauConstants::mKSq}; //! Defined as 4*mEta*mEta - Double_t m2EtaSq_; + const Double_t m2EtaSq_{4.0*LauConstants::mEtaSq}; //! Defined as (mEta+mEta')^2 - Double_t mEtaEtaPSumSq_; + const Double_t mEtaEtaPSumSq_{(LauConstants::mEta + LauConstants::mEtaPrime)*(LauConstants::mEta + LauConstants::mEtaPrime)}; //! Defined as (mEta-mEta')^2 - Double_t mEtaEtaPDiffSq_; + const Double_t mEtaEtaPDiffSq_{(LauConstants::mEta - LauConstants::mEtaPrime)*(LauConstants::mEta - LauConstants::mEtaPrime)}; //! Defined as (mK+mPi)^2 - Double_t mKpiSumSq_; + const Double_t mKpiSumSq_{(LauConstants::mK + LauConstants::mPi)*(LauConstants::mK + LauConstants::mPi)}; //! Defined as (mK-mPi)^2 - Double_t mKpiDiffSq_; + const Double_t mKpiDiffSq_{(LauConstants::mK - LauConstants::mPi)*(LauConstants::mK - LauConstants::mPi)}; //! Defined as (mK+mEta')^2 - Double_t mKEtaPSumSq_; + const Double_t mKEtaPSumSq_{(LauConstants::mK + LauConstants::mEtaPrime)*(LauConstants::mK + LauConstants::mEtaPrime)}; //! Defined as (mK-mEta')^2 - Double_t mKEtaPDiffSq_; + const Double_t mKEtaPDiffSq_{(LauConstants::mK - LauConstants::mEtaPrime)*(LauConstants::mK - LauConstants::mEtaPrime)}; //! Defined as (mK-3*mPi)^2 - Double_t mK3piDiffSq_; + const Double_t mK3piDiffSq_{(LauConstants::mK - 3.0*LauConstants::mPi)*(LauConstants::mK - 3.0*LauConstants::mPi)}; //! Factor used to calculate the Kpipipi phase space term - Double_t k3piFactor_; + const Double_t k3piFactor_{TMath::Power((1.44 - mK3piDiffSq_)/1.44, -2.5)}; //! Factor used to calculate the pipipipi phase space term - Double_t fourPiFactor1_; + const Double_t fourPiFactor1_{16.0*LauConstants::mPiSq}; //! Factor used to calculate the pipipipi phase space term - Double_t fourPiFactor2_; + const Double_t fourPiFactor2_{TMath::Sqrt(1.0 - fourPiFactor1_)}; + //! Defined as (mD0+mK)^2 + const Double_t mD0KSumSq_{(LauConstants::mD0 + LauConstants::mK)*(LauConstants::mD0 + LauConstants::mK)}; + //! Defined as (mD0-mK)^2 + const Double_t mD0KDiffSq_{(LauConstants::mD0 - LauConstants::mK)*(LauConstants::mD0 - LauConstants::mK)}; + //! Defined as (mD*0+mK)^2 + const Double_t mDstar0KSumSq_{(LauResonanceMaker::get().getResInfo("D*0")->getMass()->value() + LauConstants::mK)*(LauResonanceMaker::get().getResInfo("D*0")->getMass()->value() + LauConstants::mK)}; + //! Defined as (mD*0-mK)^2 + const Double_t mDstar0KDiffSq_{(LauResonanceMaker::get().getResInfo("D*0")->getMass()->value() - LauConstants::mK)*(LauResonanceMaker::get().getResInfo("D*0")->getMass()->value() - LauConstants::mK)}; //! Multiplicative factor containing various Adler zero constants - Double_t adlerZeroFactor_; + Double_t adlerZeroFactor_{0.0}; //! Tracks if all params have been set - Bool_t parametersSet_; + Bool_t parametersSet_{kFALSE}; //! Control the output of the functions - Bool_t verbose_; + static constexpr Bool_t verbose_{kFALSE}; - //! Control if scattering constants are channel symmetric: f_ji = f_ij - Bool_t scattSymmetry_; + //! Control if scattering constants are channel symmetric: f_ji = f_ij + Bool_t scattSymmetry_{kFALSE}; ClassDef(LauKMatrixPropagator,0) // K-matrix amplitude model }; diff --git a/inc/LauRelBreitWignerRes.hh b/inc/LauRelBreitWignerRes.hh --- a/inc/LauRelBreitWignerRes.hh +++ b/inc/LauRelBreitWignerRes.hh @@ -96,12 +96,6 @@ //! Momentum of the daughters in the resonance rest frame (at pole mass) Double_t q0_; - //! Momentum of the bachelor in the resonance rest frame (at pole mass) - Double_t p0_; - //! Momentum of the bachelor in the parent rest frame (at pole mass) - Double_t pstar0_; - //! Covariant factor (at pole mass) - Double_t erm0_; //! The resonance mass Double_t resMass_; //! Square of the resonance mass @@ -126,8 +120,6 @@ Double_t mBachSq_; //! Value of the form factor for resonance decay (at pole mass) Double_t FR0_; - //! Value of the form factor for parent decay (at pole mass) - Double_t FP0_; ClassDef(LauRelBreitWignerRes,0) // Relativistic Breit-Wigner resonance model diff --git a/inc/LauRescatterThreshold.hh b/inc/LauRescatterThreshold.hh new file mode 100644 --- /dev/null +++ b/inc/LauRescatterThreshold.hh @@ -0,0 +1,220 @@ + +/* +Copyright 2004 University of Warwick + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Laura++ package authors: +John Back +Paul Harrison +Thomas Latham +*/ + +/*! \file LauRescatterThreshold.hh + \brief File containing declaration of LauRescatterThreshold class. +*/ + +/*! \class LauRescatterThreshold + \brief Class for defining the threshold-rescattering model. + + Defines a threshold-rescattering model. +*/ + +#ifndef LAU_RESCATTER_THRESHOLD +#define LAU_RESCATTER_THRESHOLD + +#include "TString.h" + +#include "LauComplex.hh" +#include "LauAbsResonance.hh" + +class LauKinematics; +class LauParameter; + + +class LauRescatterThreshold : public LauAbsResonance { + + public: + //! Constructor + /*! + \param [in] resInfo the object containing information on the resonance name, mass, width, spin, charge, etc. + \param [in] resType the model of the resonance + \param [in] resPairAmpInt the number of the daughter not produced by the resonance + \param [in] daughters the daughter particles + */ + LauRescatterThreshold(LauResonanceInfo* resInfo, const Int_t resPairAmpInt, const LauDaughters* daughters); + + //! Destructor + virtual ~LauRescatterThreshold(); + + //! Override the enforcement of pure Legendre polynomial spin factors + /*! + By default this model uses pure Legendre polynomial + spin factors, regardless of the default type set in + LauResonanceMaker or any specific request from the user. + This function allows the enforcement to be overridden. + + \param [in] forceLegendre boolean flag (kTRUE, the default, implies enforcement of pure Legendre spin factors, kFALSE overrides this to allow use of other formalisms) + */ + void enforceLegendreSpinFactors( const Bool_t forceLegendre ) { forceLegendre_ = forceLegendre; } + + //! Initialise the model + virtual void initialise(); + + //! Get the resonance model type + /*! + \return the resonance model type + */ + virtual LauAbsResonance::LauResonanceModel getResonanceModel() const {return LauAbsResonance::RescatterThreshold;} + + //! Compute phasespace factor + virtual LauComplex phspFactor(const Double_t mass, const Double_t m1, const Double_t m2); + + //! Set value of the various parameters + /*! + \param [in] name the name of the parameter to be changed + \param [in] value the new parameter value + */ + virtual void setResonanceParameter(const TString& name, const Double_t value); + + //! Allow the various parameters to float in the fit + /*! + \param [in] name the name of the parameter to be floated + */ + virtual void floatResonanceParameter(const TString& name); + + //! Access the given resonance parameter + /*! + \param [in] name the name of the parameter + \return the corresponding parameter + */ + virtual LauParameter* getResonanceParameter(const TString& name); + + //! Retrieve the resonance parameters, e.g. so that they can be loaded into a fit + /*! + \return floating parameters of the resonance + */ + virtual const std::vector& getFloatingParameters(); + + protected: + //! Set the parameter c11, the coupling strength for self-scattering from/to the near-threshold channel + /*! + \param [in] c11, the new coupling strength value + */ + void set_c11(const Double_t c11); + + //! Set the parameter c12, the coupling strength for scattering from the near-threshold channel to the observation channel + /*! + \param [in] c12, the new coupling strength value + */ + void set_c12(const Double_t c12); + + //! Set the parameter rescatterChannel_massDaug1, the mass of the first (of two) members of the near-threshold channel + /*! + \param [in] rescatterChannel_massDaug1, the new mass of the first member of the near-threshold channel + */ + void set_rescatterChannel_massDaug1(const Double_t rescatterChannel_massDaug1); + + //! Set the parameter rescatterChannel_massDaug2, the mass of the second (of two) members of the near-threshold channel + /*! + \param [in] rescatterChannel_massDaug2, the new mass of the second member of the near-threshold channel + */ + void set_rescatterChannel_massDaug2(const Double_t rescatterChannel_massDaug2); + + //! Get the c11 coupling strength parameter + /*! + \return the c11 coupling strength parameter + */ + Double_t get_c11() const {return (_c11!=0) ? _c11->unblindValue() : 0.0;} + + //! Get the c12 coupling strength parameter + /*! + \return the c12 coupling strength parameter + */ + Double_t get_c12() const {return (_c12!=0) ? _c12->unblindValue() : 0.0;} + + //! Get the rescatterChannel_massDaug1 coupling strength parameter + /*! + \return the rescatterChannel_massDaug1 coupling strength parameter + */ + Double_t get_rescatterChannel_massDaug1() const {return (_rescatterChannel_massDaug1!=0) ? _rescatterChannel_massDaug1->unblindValue() : 0.0;} + + //! Get the rescatterChannel_massDaug2 coupling strength parameter + /*! + \return the rescatterChannel_massDaug2 coupling strength parameter + */ + Double_t get_rescatterChannel_massDaug2() const {return (_rescatterChannel_massDaug2!=0) ? _rescatterChannel_massDaug2->unblindValue() : 0.0;} + + //! See if the c11 parameter is fixed or floating + /*! + \return kTRUE if the c11 coupling strength parameter is fixed, kFALSE otherwise + */ + Bool_t fix_c11() const {return (_c11!=0) ? _c11->fixed() : kTRUE;} + + //! See if the c12 parameter is fixed or floating + /*! + \return kTRUE if the c12 coupling strength parameter is fixed, kFALSE otherwise + */ + Bool_t fix_c12() const {return (_c12!=0) ? _c12->fixed() : kTRUE;} + + //! See if the rescatterChannel_massDaug1 parameter is fixed or floating + /*! + \return kTRUE if the rescatterChannel_massDaug1 mass parameter is fixed, kFALSE otherwise + */ + Bool_t fix_rescatterChannel_massDaug1() const {return (_rescatterChannel_massDaug1!=0) ? _rescatterChannel_massDaug1->fixed() : kTRUE;} + + //! See if the rescatterChannel_massDaug2 parameter is fixed or floating + /*! + \return kTRUE if the rescatterChannel_massDaug2 mass parameter is fixed, kFALSE otherwise + */ + Bool_t fix_rescatterChannel_massDaug2() const {return (_rescatterChannel_massDaug2!=0) ? _rescatterChannel_massDaug2->fixed() : kTRUE;} + + //! Complex resonant amplitude + /*! + \param [in] mass appropriate invariant mass for the resonance + \param [in] spinTerm spin term + */ + virtual LauComplex resAmp(Double_t mass, Double_t spinTerm); + + private: + //! Copy constructor (not implemented) + LauRescatterThreshold(const LauRescatterThreshold& rhs); + + //! Copy assignment operator (not implemented) + LauRescatterThreshold& operator=(const LauRescatterThreshold& rhs); + + //! The c11 parameter + LauParameter* _c11; + + //! The c12 parameter + LauParameter* _c12; + + //! The rescatterChannel_massDaug1 parameter + LauParameter* _rescatterChannel_massDaug1; + + //! The rescatterChannel_massDaug2 parameter + LauParameter* _rescatterChannel_massDaug2; + + //! Force use of Legendre spin factors + Bool_t forceLegendre_; + + //! Mass of daughters + Double_t _massDaug1; + Double_t _massDaug2; + + ClassDef(LauRescatterThreshold,0) +}; + +#endif diff --git a/inc/LauResonanceMaker.hh b/inc/LauResonanceMaker.hh --- a/inc/LauResonanceMaker.hh +++ b/inc/LauResonanceMaker.hh @@ -127,6 +127,9 @@ */ LauResonanceInfo* getResInfo(const TString& resName) const; + //! Retrieve parent Blatt-Weisskopf factor (for use by K-matrix pole/SVP which doesn't have a `resInfo') + LauBlattWeisskopfFactor* getParentBWFactor(Int_t newSpin, LauBlattWeisskopfFactor::BarrierType barrierType); + protected: //! Create the list of known resonances void createResonanceVector(); diff --git a/inc/LauRooFitSlave.hh b/inc/LauRooFitTask.hh rename from inc/LauRooFitSlave.hh rename to inc/LauRooFitTask.hh --- a/inc/LauRooFitSlave.hh +++ b/inc/LauRooFitTask.hh @@ -22,19 +22,20 @@ Thomas Latham */ -/*! \file LauRooFitSlave.hh - \brief File containing declaration of LauRooFitSlave class. +/*! \file LauRooFitTask.hh + \brief File containing declaration of LauRooFitTask class. */ -/*! \class LauRooFitSlave - \brief A class for creating a RooFit-based slave process for simultaneous/combined fits +/*! \class LauRooFitTask + \brief A class for creating a RooFit-based task process for simultaneous/combined fits Implementation of the JFit method described in arXiv:1409.5080 [physics.data-an]. */ -#ifndef LAU_ROO_FIT_SLAVE -#define LAU_ROO_FIT_SLAVE +#ifndef LAU_ROO_FIT_TASK +#define LAU_ROO_FIT_TASK +#include #include #include @@ -45,19 +46,19 @@ #include "TMatrixDfwd.h" #include "TString.h" -#include "LauSimFitSlave.hh" +#include "LauSimFitTask.hh" class LauParameter; -class LauRooFitSlave : public LauSimFitSlave { +class LauRooFitTask : public LauSimFitTask { public: //! Constructor - LauRooFitSlave( RooAbsPdf& model, const Bool_t extended, const RooArgSet& vars, const TString& weightVarName = "" ); + LauRooFitTask( RooAbsPdf& model, const Bool_t extended, const RooArgSet& vars, const TString& weightVarName = "" ); //! Destructor - virtual ~LauRooFitSlave(); + virtual ~LauRooFitTask(); //! Initialise the fit model virtual void initialise(); @@ -74,7 +75,7 @@ protected: - //! Package the initial fit parameters for transmission to the master + //! Package the initial fit parameters for transmission to the coordinator /*! \param [out] array the array to be filled with the LauParameter objects */ @@ -96,16 +97,16 @@ //! Perform all finalisation actions /*! - - Receive the results of the fit from the master + - Receive the results of the fit from the coordinator - Perform any finalisation routines - - Package the finalised fit parameters for transmission back to the master + - Package the finalised fit parameters for transmission back to the coordinator \param [in] fitStat the status of the fit, e.g. status code, EDM, NLL - \param [in] parsFromMaster the parameters at the fit minimum + \param [in] parsFromCoordinator the parameters at the fit minimum \param [in] covMat the fit covariance matrix - \param [out] parsToMaster the array to be filled with the finalised LauParameter objects + \param [out] parsToCoordinator the array to be filled with the finalised LauParameter objects */ - virtual void finaliseExperiment( const LauAbsFitter::FitStatus& fitStat, const TObjArray* parsFromMaster, const TMatrixD* covMat, TObjArray& parsToMaster ); + virtual void finaliseExperiment( const LauAbsFitter::FitStatus& fitStat, const TObjArray* parsFromCoordinator, const TMatrixD* covMat, TObjArray& parsToCoordinator ); //! Open the input file and verify that all required variables are present /*! @@ -128,10 +129,10 @@ void cleanData(); //! Copy constructor (not implemented) - LauRooFitSlave(const LauRooFitSlave& rhs); + LauRooFitTask(const LauRooFitTask& rhs); //! Copy assignment operator (not implemented) - LauRooFitSlave& operator=(const LauRooFitSlave& rhs); + LauRooFitTask& operator=(const LauRooFitTask& rhs); //! The model RooAbsPdf& model_; @@ -155,7 +156,7 @@ const Bool_t extended_; //! The experiment category variable - RooCategory iExptCat_; + std::set iExptSet_; //! The NLL variable RooNLLVar* nllVar_; @@ -166,7 +167,7 @@ //! The fit parameters (as LauParameter's) std::vector fitPars_; - ClassDef(LauRooFitSlave,0); + ClassDef(LauRooFitTask,0); }; #endif diff --git a/inc/LauSimFitMaster.hh b/inc/LauSimFitCoordinator.hh rename from inc/LauSimFitMaster.hh rename to inc/LauSimFitCoordinator.hh --- a/inc/LauSimFitMaster.hh +++ b/inc/LauSimFitCoordinator.hh @@ -22,20 +22,20 @@ Thomas Latham */ -/*! \file LauSimFitMaster.hh - \brief File containing declaration of LauSimFitMaster class. +/*! \file LauSimFitCoordinator.hh + \brief File containing declaration of LauSimFitCoordinator class. */ -/*! \class LauSimFitMaster - \brief The master process for simultaneous/combined fits +/*! \class LauSimFitCoordinator + \brief The coordinator process for simultaneous/combined fits Implementation of the JFit method described in arXiv:1409.5080 [physics.data-an]. - This class acts as the interface between the slave processes and the minimiser. + This class acts as the interface between the task processes and the minimiser. */ -#ifndef LAU_SIM_FIT_MASTER -#define LAU_SIM_FIT_MASTER +#ifndef LAU_SIM_FIT_COORDINATOR +#define LAU_SIM_FIT_COORDINATOR #include #include @@ -54,18 +54,18 @@ class LauFitNtuple; -class LauSimFitMaster : public LauFitObject { +class LauSimFitCoordinator : public LauFitObject { public: //! Constructor /*! - \param [in] numSlaves the number of slaves processes to expect connections from - \param [in] port the port on which to listen for connections from the slaves + \param [in] numTasks the number of tasks processes to expect connections from + \param [in] port the port on which to listen for connections from the tasks */ - LauSimFitMaster( UInt_t numSlaves, UInt_t port = 9090 ); + LauSimFitCoordinator( UInt_t numTasks, UInt_t port = 9090 ); //! Destructor - virtual ~LauSimFitMaster(); + virtual ~LauSimFitCoordinator(); //! Run the fit /*! @@ -115,17 +115,17 @@ //! Initialise void initialise(); - //! Initialise socket connections for the slaves + //! Initialise socket connections for the tasks void initSockets(); - //! Determine/update the parameter initial values from all slaves - void getParametersFromSlaves(); + //! Determine/update the parameter initial values from all tasks + void getParametersFromTasks(); - //! Determine the parameter names and initial values from all slaves - void getParametersFromSlavesFirstTime(); + //! Determine the parameter names and initial values from all tasks + void getParametersFromTasksFirstTime(); - //! Update and verify the parameter initial values from all slaves - void updateParametersFromSlaves(); + //! Update and verify the parameter initial values from all tasks + void updateParametersFromTasks(); //! Check for compatibility between two same-named parameters, which should therefore be identical void checkParameter( const LauParameter* param, UInt_t index ) const; @@ -136,13 +136,13 @@ //! Calculate the penalty terms to the log likelihood from Gaussian constraints Double_t getLogLikelihoodPenalty(); - //! Instruct the slaves to read the input data for the given experiment + //! Instruct the tasks to read the input data for the given experiment /*! \return success/failure of the reading operations */ Bool_t readData(); - //! Instruct the slaves to perform the caching + //! Instruct the tasks to perform the caching /*! \return success/failure of the caching operations */ @@ -151,46 +151,46 @@ //! Perform the fit for the current experiment void fitExpt(); - //! Instruct the slaves to update the initial fit parameter values, if required + //! Instruct the tasks to update the initial fit parameter values, if required void checkInitFitParams(); - //! Return the final parameters to the slaves and instruct them to perform their finalisation + //! Return the final parameters to the tasks and instruct them to perform their finalisation Bool_t finalise(); - //! Instruct the slaves to write out the fit results + //! Instruct the tasks to write out the fit results Bool_t writeOutResults(); private: //! Copy constructor (not implemented) - LauSimFitMaster(const LauSimFitMaster& rhs); + LauSimFitCoordinator(const LauSimFitCoordinator& rhs); //! Copy assignment operator (not implemented) - LauSimFitMaster& operator=(const LauSimFitMaster& rhs); + LauSimFitCoordinator& operator=(const LauSimFitCoordinator& rhs); //! Store the constraints for fit parameters until initialisation is complete std::vector storeCon_; - //! The number of slaves - const UInt_t nSlaves_; + //! The number of tasks + const UInt_t nTasks_; //! The requested port const UInt_t reqPort_; - //! The covariance sub-matrices for each slave + //! The covariance sub-matrices for each task std::vector covMatrices_; //! Parallel setup monitor TMonitor* socketMonitor_; - //! Sockets for each of the slaves - std::vector sSlaves_; + //! Sockets for each of the tasks + std::vector socketTasks_; - //! Messages to slaves - std::vector messagesToSlaves_; + //! Messages to tasks + std::vector messagesToTasks_; - //! Message from slaves to the master - TMessage* messageFromSlave_; + //! Message from tasks to the coordinator + TMessage* messageFromTask_; //! Map of parameter names to index in the values vector std::map< TString, UInt_t > parIndices_; @@ -207,16 +207,16 @@ //! Parameter values std::vector parValues_; - //! Lists of indices for each slave - std::vector< std::vector > slaveIndices_; + //! Lists of indices for each task + std::vector< std::vector > taskIndices_; - //! Lists of indices of free parameters for each slave - std::vector< std::vector > slaveFreeIndices_; + //! Lists of indices of free parameters for each task + std::vector< std::vector > taskFreeIndices_; - //! Parameter values to send to the slaves + //! Parameter values to send to the tasks std::vector vectorPar_; - //! Likelihood values returned from the slaves + //! Likelihood values returned from the tasks std::vector vectorRes_; //! The fit timer @@ -228,7 +228,7 @@ //! The fit results ntuple LauFitNtuple* fitNtuple_; - ClassDef(LauSimFitMaster,0); + ClassDef(LauSimFitCoordinator,0); }; #endif diff --git a/inc/LauSimFitSlave.hh b/inc/LauSimFitTask.hh rename from inc/LauSimFitSlave.hh rename to inc/LauSimFitTask.hh --- a/inc/LauSimFitSlave.hh +++ b/inc/LauSimFitTask.hh @@ -22,21 +22,21 @@ Thomas Latham */ -/*! \file LauSimFitSlave.hh - \brief File containing declaration of LauSimFitSlave class. +/*! \file LauSimFitTask.hh + \brief File containing declaration of LauSimFitTask class. */ -/*! \class LauSimFitSlave - \brief The base class for any slave process for simultaneous/combined fits +/*! \class LauSimFitTask + \brief The base class for any task process for simultaneous/combined fits Implementation of the JFit method described in arXiv:1409.5080 [physics.data-an]. - This class acts as the base class from which slaves should inherit. + This class acts as the base class from which tasks should inherit. This allows any fitting framework to plug in to the JFit method. */ -#ifndef LAU_SIM_FIT_SLAVE -#define LAU_SIM_FIT_SLAVE +#ifndef LAU_SIM_FIT_TASK +#define LAU_SIM_FIT_TASK #include "TMatrixDfwd.h" @@ -48,33 +48,33 @@ class LauFitNtuple; -class LauSimFitSlave : public LauFitObject { +class LauSimFitTask : public LauFitObject { public: //! Constructor - LauSimFitSlave(); + LauSimFitTask(); //! Destructor - virtual ~LauSimFitSlave(); + virtual ~LauSimFitTask(); - //! Obtain the number of slaves - UInt_t nSlaves() const {return nSlaves_;} + //! Obtain the number of tasks + UInt_t nTasks() const {return nTasks_;} - //! Obtain the ID number of this slave - UInt_t slaveId() const {return slaveId_;} + //! Obtain the ID number of this task + UInt_t taskId() const {return taskId_;} - //! Start the slave process for simultaneous fitting + //! Start the task process for simultaneous fitting /*! \param [in] dataFileName the name of the input data file \param [in] dataTreeName the name of the tree containing the data \param [in] histFileName the file name for the output histograms \param [in] tableFileName the file name for the latex output file - \param [in] addressMaster the hostname of the machine running the master process - \param [in] portMaster the port number on which the master process is listening + \param [in] addressCoordinator the hostname of the machine running the coordinator process + \param [in] portCoordinator the port number on which the coordinator process is listening */ - virtual void runSlave(const TString& dataFileName, const TString& dataTreeName, + virtual void runTask(const TString& dataFileName, const TString& dataTreeName, const TString& histFileName, const TString& tableFileName = "", - const TString& addressMaster = "localhost", const UInt_t portMaster = 9090); + const TString& addressCoordinator = "localhost", const UInt_t portCoordinator = 9090); //! Initialise the fit model /*! @@ -100,15 +100,15 @@ //! Access to the fit ntuple LauFitNtuple* fitNtuple() {return fitNtuple_;} - //! Establish the connection to the master process + //! Establish the connection to the coordinator process /*! - \param [in] addressMaster the hostname of the machine running the master process - \param [in] portMaster the port number on which the master process is listening + \param [in] addressCoordinator the hostname of the machine running the coordinator process + \param [in] portCoordinator the port number on which the coordinator process is listening */ - void connectToMaster( const TString& addressMaster, const UInt_t portMaster ); + void connectToCoordinator( const TString& addressCoordinator, const UInt_t portCoordinator ); - //! Listen for requests from the master and act accordingly - void processMasterRequests(); + //! Listen for requests from the coordinator and act accordingly + void processCoordinatorRequests(); //! Setup saving of fit results to ntuple/LaTeX table etc. /*! @@ -120,7 +120,7 @@ */ virtual void setupResultsOutputs( const TString& histFileName, const TString& tableFileName ); - //! Package the initial fit parameters for transmission to the master + //! Package the initial fit parameters for transmission to the coordinator /*! \param [out] array the array to be filled with the LauParameter objects */ @@ -128,16 +128,16 @@ //! Perform all finalisation actions /*! - - Receive the results of the fit from the master + - Receive the results of the fit from the coordinator - Perform any finalisation routines - - Package the finalised fit parameters for transmission back to the master + - Package the finalised fit parameters for transmission back to the coordinator \param [in] fitStat the status of the fit, e.g. status code, EDM, NLL - \param [in] parsFromMaster the parameters at the fit minimum + \param [in] parsFromCoordinator the parameters at the fit minimum \param [in] covMat the fit covariance matrix - \param [out] parsToMaster the array to be filled with the finalised LauParameter objects + \param [out] parsToCoordinator the array to be filled with the finalised LauParameter objects */ - virtual void finaliseExperiment( const LauAbsFitter::FitStatus& fitStat, const TObjArray* parsFromMaster, const TMatrixD* covMat, TObjArray& parsToMaster ) = 0; + virtual void finaliseExperiment( const LauAbsFitter::FitStatus& fitStat, const TObjArray* parsFromCoordinator, const TMatrixD* covMat, TObjArray& parsToCoordinator ) = 0; //! Open the input file and verify that all required variables are present /*! @@ -160,30 +160,30 @@ private: //! Copy constructor (not implemented) - LauSimFitSlave(const LauSimFitSlave& rhs); + LauSimFitTask(const LauSimFitTask& rhs); //! Copy assignment operator (not implemented) - LauSimFitSlave& operator=(const LauSimFitSlave& rhs); + LauSimFitTask& operator=(const LauSimFitTask& rhs); //! A socket to enable parallel setup - TSocket* sMaster_; + TSocket* socketCoordinator_; - //! Message from master to the slaves - TMessage* messageFromMaster_; + //! Message from coordinator to the tasks + TMessage* messageFromCoordinator_; - //! Slave id number - UInt_t slaveId_; + //! Task id number + UInt_t taskId_; - //! The total number of slaves - UInt_t nSlaves_; + //! The total number of tasks + UInt_t nTasks_; - //! Parameter values array (for reading from the master) + //! Parameter values array (for reading from the coordinator) Double_t* parValues_; //! The fit ntuple LauFitNtuple* fitNtuple_; - ClassDef(LauSimFitSlave,0); + ClassDef(LauSimFitTask,0); }; #endif diff --git a/inc/Laura++_LinkDef.h b/inc/Laura++_LinkDef.h --- a/inc/Laura++_LinkDef.h +++ b/inc/Laura++_LinkDef.h @@ -54,6 +54,7 @@ #pragma link C++ class LauAsymmCalc+; #pragma link C++ class LauBelleCPCoeffSet+; #pragma link C++ class LauBelleNR+; +#pragma link C++ class LauRescatterThreshold+; #pragma link C++ class LauBelleSymNR+; #pragma link C++ class LauBifurcatedGaussPdf+; #pragma link C++ class LauBkgndDPModel+; @@ -134,15 +135,15 @@ #pragma link C++ class LauResonanceMaker+; #pragma link C++ class LauResultsExtractor+; #pragma link C++ class LauRhoOmegaMix+; -#ifdef DOLAUROOFITSLAVE -#pragma link C++ class LauRooFitSlave+; +#ifdef DOLAUROOFITTASK +#pragma link C++ class LauRooFitTask+; #endif #pragma link C++ class LauScfMap+; #pragma link C++ class LauSigmaRes+; #pragma link C++ class LauSigmoidPdf+; #pragma link C++ class LauSimpleFitModel+; -#pragma link C++ class LauSimFitMaster+; -#pragma link C++ class LauSimFitSlave+; +#pragma link C++ class LauSimFitCoordinator+; +#pragma link C++ class LauSimFitTask+; #pragma link C++ class LauSPlot+; #pragma link C++ class LauString+; #pragma link C++ class LauSumPdf+; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,54 @@ +# Set the include directory (unfortunately this old-style stuff is necessary for the ROOT_GENERATE_DICTIONARY macro) +include_directories(${PROJECT_SOURCE_DIR}/inc) + +# Use glob to find the headers and sources +file(GLOB LAURA_HEADERS ${PROJECT_SOURCE_DIR}/inc/*.hh) +file(GLOB LAURA_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cc) +if (NOT LAURA_BUILD_ROOFIT_TASK) + list(REMOVE_ITEM LAURA_HEADERS ${PROJECT_SOURCE_DIR}/inc/LauRooFitTask.hh) + list(REMOVE_ITEM LAURA_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/LauRooFitTask.cc) +endif() + +# Generate the rootcint file +set(LAURA_LINKDEF ${PROJECT_SOURCE_DIR}/inc/Laura++_LinkDef.h) +set(LAURA_DICTIONARY_ROOT G__Laura++) +set(LAURA_DICTIONARY ${LAURA_DICTIONARY_ROOT}.cxx) +if (LAURA_BUILD_ROOFIT_TASK) + ROOT_GENERATE_DICTIONARY( + ${LAURA_DICTIONARY_ROOT} + ${LAURA_HEADERS} + LINKDEF ${LAURA_LINKDEF} + OPTIONS -DDOLAUROOFITTASK + ) +else() + ROOT_GENERATE_DICTIONARY( + ${LAURA_DICTIONARY_ROOT} + ${LAURA_HEADERS} + LINKDEF ${LAURA_LINKDEF} + ) +endif() + +# Build the shared library +add_library(Laura++ SHARED ${LAURA_SOURCES} ${LAURA_DICTIONARY}) +set_target_properties(Laura++ PROPERTIES OUTPUT_NAME Laura++) +set_target_properties(Laura++ PROPERTIES VERSION ${CMAKE_PROJECT_VERSION} SOVERSION ${CMAKE_PROJECT_VERSION_MAJOR}) +set_target_properties(Laura++ PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) +target_include_directories(Laura++ PUBLIC $ $) +target_link_libraries(Laura++ ROOT::Core ROOT::Hist ROOT::Matrix ROOT::Physics ROOT::Minuit ROOT::EG ROOT::Tree) +if (LAURA_BUILD_ROOFIT_TASK) + target_link_libraries(Laura++ ROOT::RooFit ROOT::RooFitCore) +endif() + +# Install the libraries +install( + TARGETS Laura++ + EXPORT "LauraTargets" + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + +# Install the pcm and rootmap files generated by ROOT_GENERATE_DICTIONARY +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/libLaura++.rootmap ${CMAKE_CURRENT_BINARY_DIR}/libLaura++_rdict.pcm + DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + diff --git a/src/LauAbsFitModel.cc b/src/LauAbsFitModel.cc --- a/src/LauAbsFitModel.cc +++ b/src/LauAbsFitModel.cc @@ -513,7 +513,7 @@ void LauAbsFitModel::setupResultsOutputs( const TString& histFileName, const TString& tableFileName ) { - this->LauSimFitSlave::setupResultsOutputs( histFileName, tableFileName ); + this->LauSimFitTask::setupResultsOutputs( histFileName, tableFileName ); outputTableName_ = tableFileName; } @@ -1001,29 +1001,29 @@ this->startNewFit( nPars, nFreePars ); } -void LauAbsFitModel::finaliseExperiment( const LauAbsFitter::FitStatus& fitStat, const TObjArray* parsFromMaster, const TMatrixD* covMat, TObjArray& parsToMaster ) +void LauAbsFitModel::finaliseExperiment( const LauAbsFitter::FitStatus& fitStat, const TObjArray* parsFromCoordinator, const TMatrixD* covMat, TObjArray& parsToCoordinator ) { // Copy the fit status information this->storeFitStatus( fitStat, *covMat ); // Now process the parameters const UInt_t nPars = this->nTotParams(); - UInt_t nParsFromMaster = parsFromMaster->GetEntries(); - if ( nParsFromMaster != nPars ) { - std::cerr << "ERROR in LauAbsFitModel::finaliseExperiment : Unexpected number of parameters received from master" << std::endl; - std::cerr << " : Received " << nParsFromMaster << " when expecting " << nPars << std::endl; + UInt_t nParsFromCoordinator = parsFromCoordinator->GetEntries(); + if ( nParsFromCoordinator != nPars ) { + std::cerr << "ERROR in LauAbsFitModel::finaliseExperiment : Unexpected number of parameters received from coordinator" << std::endl; + std::cerr << " : Received " << nParsFromCoordinator << " when expecting " << nPars << std::endl; gSystem->Exit( EXIT_FAILURE ); } - for ( UInt_t iPar(0); iPar < nParsFromMaster; ++iPar ) { - LauParameter* parameter = dynamic_cast( (*parsFromMaster)[iPar] ); + for ( UInt_t iPar(0); iPar < nParsFromCoordinator; ++iPar ) { + LauParameter* parameter = dynamic_cast( (*parsFromCoordinator)[iPar] ); if ( ! parameter ) { - std::cerr << "ERROR in LauAbsFitModel::finaliseExperiment : Error reading parameter from master" << std::endl; + std::cerr << "ERROR in LauAbsFitModel::finaliseExperiment : Error reading parameter from coordinator" << std::endl; gSystem->Exit( EXIT_FAILURE ); } if ( parameter->name() != fitVars_[iPar]->name() ) { - std::cerr << "ERROR in LauAbsFitModel::finaliseExperiment : Error reading parameter from master" << std::endl; + std::cerr << "ERROR in LauAbsFitModel::finaliseExperiment : Error reading parameter from coordinator" << std::endl; gSystem->Exit( EXIT_FAILURE ); } @@ -1046,7 +1046,7 @@ // Send the finalised fit parameters for ( LauParameterPList::iterator iter = fitVars_.begin(); iter != fitVars_.end(); ++iter ) { - parsToMaster.Add( *iter ); + parsToCoordinator.Add( *iter ); } } diff --git a/src/LauAbsResonance.cc b/src/LauAbsResonance.cc --- a/src/LauAbsResonance.cc +++ b/src/LauAbsResonance.cc @@ -56,6 +56,7 @@ case FlatNR: case NRModel: case BelleNR: + case RescatterThreshold: case PowerLawNR: case BelleSymNR: case BelleSymNRNoInter: @@ -85,30 +86,13 @@ LauAbsResonance::LauAbsResonance(LauResonanceInfo* resInfo, const Int_t resPairAmpInt, const LauDaughters* daughters) : resInfo_(resInfo), daughters_(daughters), - nameParent_(""), nameDaug1_(""), nameDaug2_(""), nameBachelor_(""), - chargeParent_(0), chargeDaug1_(0), chargeDaug2_(0), chargeBachelor_(0), - massParent_(0.0), massDaug1_(0.0), massDaug2_(0.0), massBachelor_(0.0), resName_( (resInfo!=0) ? resInfo->getName() : "" ), sanitisedName_( (resInfo!=0) ? resInfo->getSanitisedName() : "" ), resMass_( (resInfo!=0) ? resInfo->getMass() : 0 ), resWidth_( (resInfo!=0) ? resInfo->getWidth() : 0 ), resSpin_( (resInfo!=0) ? resInfo->getSpin() : 0 ), resCharge_( (resInfo!=0) ? resInfo->getCharge() : 0 ), - resPairAmpInt_(resPairAmpInt), - parBWFactor_(0), - resBWFactor_(0), - spinType_(Zemach_P), - flipHelicity_(kFALSE), - ignoreMomenta_(kFALSE), - ignoreSpin_(kFALSE), - ignoreBarrierScaling_(kFALSE), - mass_(0.0), - cosHel_(0.0), - q_(0.0), - p_(0.0), - pstar_(0.0), - erm_(1.0), - covFactor_(1.0) + resPairAmpInt_(resPairAmpInt) { if ( resInfo == 0 ) { std::cerr << "ERROR in LauAbsResonance constructor : null LauResonanceInfo object provided" << std::endl; @@ -142,33 +126,12 @@ } // Constructor -LauAbsResonance::LauAbsResonance(const TString& resName, const Int_t resPairAmpInt, const LauDaughters* daughters) : - resInfo_(0), +LauAbsResonance::LauAbsResonance(const TString& resName, const Int_t resPairAmpInt, const LauDaughters* daughters, const Int_t resSpin) : daughters_(daughters), - nameParent_(""), nameDaug1_(""), nameDaug2_(""), nameBachelor_(""), - chargeParent_(0), chargeDaug1_(0), chargeDaug2_(0), chargeBachelor_(0), - massParent_(0.0), massDaug1_(0.0), massDaug2_(0.0), massBachelor_(0.0), resName_(resName), sanitisedName_(resName), - resMass_(0), - resWidth_(0), - resSpin_(0), - resCharge_(0), - resPairAmpInt_(resPairAmpInt), - parBWFactor_(0), - resBWFactor_(0), - spinType_(Zemach_P), - flipHelicity_(kFALSE), - ignoreMomenta_(kFALSE), - ignoreSpin_(kFALSE), - ignoreBarrierScaling_(kFALSE), - mass_(0.0), - cosHel_(0.0), - q_(0.0), - p_(0.0), - pstar_(0.0), - erm_(1.0), - covFactor_(1.0) + resSpin_(resSpin), + resPairAmpInt_(resPairAmpInt) { if ( daughters_ == 0 ) { std::cerr << "ERROR in LauAbsResonance constructor : null LauDaughters object provided" << std::endl; diff --git a/src/LauBelleNR.cc b/src/LauBelleNR.cc --- a/src/LauBelleNR.cc +++ b/src/LauBelleNR.cc @@ -49,7 +49,7 @@ parName += "_alpha"; alpha_ = resInfo->getExtraParameter( parName ); if ( alpha_ == 0 ) { - alpha_ = new LauParameter( parName, 0.0, 0.0, 10.0, kTRUE ); + alpha_ = new LauParameter( parName, 0.0, -2.0, 10.0, kTRUE ); alpha_->secondStage(kTRUE); resInfo->addExtraParameter( alpha_ ); } diff --git a/src/LauBlattWeisskopfFactor.cc b/src/LauBlattWeisskopfFactor.cc --- a/src/LauBlattWeisskopfFactor.cc +++ b/src/LauBlattWeisskopfFactor.cc @@ -62,10 +62,10 @@ { } -LauBlattWeisskopfFactor::LauBlattWeisskopfFactor( const LauBlattWeisskopfFactor& other, const UInt_t newSpin ) : +LauBlattWeisskopfFactor::LauBlattWeisskopfFactor( const LauBlattWeisskopfFactor& other, const UInt_t newSpin, const BarrierType newBarrierType ) : spin_(newSpin), radius_(other.radius_->createClone()), - barrierType_(other.barrierType_), + barrierType_(newBarrierType), restFrame_(other.restFrame_) { } @@ -129,9 +129,9 @@ return categoryName; } -LauBlattWeisskopfFactor* LauBlattWeisskopfFactor::createClone( const UInt_t newSpin ) +LauBlattWeisskopfFactor* LauBlattWeisskopfFactor::createClone( const UInt_t newSpin, const BarrierType newBarrierType ) { - LauBlattWeisskopfFactor* clone = new LauBlattWeisskopfFactor( *this, newSpin ); + LauBlattWeisskopfFactor* clone = new LauBlattWeisskopfFactor( *this, newSpin, newBarrierType ); return clone; } diff --git a/src/LauCPFitModel.cc b/src/LauCPFitModel.cc --- a/src/LauCPFitModel.cc +++ b/src/LauCPFitModel.cc @@ -1423,16 +1423,17 @@ Bool_t blind = kFALSE; // Signal + if ( signalEvents_->blind() ) { + blind = kTRUE; + } + Double_t evtWeight(1.0); Double_t nEvts = signalEvents_->genValue(); if ( nEvts < 0.0 ) { evtWeight = -1.0; nEvts = TMath::Abs( nEvts ); } - if ( signalEvents_->blind() ) { - blind = kTRUE; - } - Double_t asym(0.0); + Double_t sigAsym(0.0); // need to include this as an alternative in case the DP isn't in the model if ( !this->useDP() || forceAsym_ ) { @@ -1447,40 +1448,49 @@ sigAsym = (negRate-posRate)/(negRate+posRate); } } - asym = sigAsym; - Int_t nPosEvts = static_cast((nEvts/2.0 * (1.0 - asym)) + 0.5); - Int_t nNegEvts = static_cast((nEvts/2.0 * (1.0 + asym)) + 0.5); + Double_t nPosEvts = (nEvts/2.0 * (1.0 - sigAsym)); + Double_t nNegEvts = (nEvts/2.0 * (1.0 + sigAsym)); + + Int_t nPosEvtsToGen { static_cast(nPosEvts) }; + Int_t nNegEvtsToGen { static_cast(nNegEvts) }; if (this->doPoissonSmearing()) { - nNegEvts = LauRandom::randomFun()->Poisson(nNegEvts); - nPosEvts = LauRandom::randomFun()->Poisson(nPosEvts); + nPosEvtsToGen = LauRandom::randomFun()->Poisson(nPosEvts); + nNegEvtsToGen = LauRandom::randomFun()->Poisson(nNegEvts); } - nEvtsGen[std::make_pair("signal",-1)] = std::make_pair(nNegEvts,evtWeight); - nEvtsGen[std::make_pair("signal",+1)] = std::make_pair(nPosEvts,evtWeight); + + nEvtsGen[std::make_pair("signal",+1)] = std::make_pair(nPosEvtsToGen,evtWeight); + nEvtsGen[std::make_pair("signal",-1)] = std::make_pair(nNegEvtsToGen,evtWeight); // backgrounds const UInt_t nBkgnds = this->nBkgndClasses(); for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) { - const TString& bkgndClass = this->bkgndClassName(bkgndID); const LauAbsRValue* evtsPar = bkgndEvents_[bkgndID]; const LauAbsRValue* asymPar = bkgndAsym_[bkgndID]; if ( evtsPar->blind() || asymPar->blind() ) { blind = kTRUE; } + evtWeight = 1.0; - nEvts = TMath::FloorNint( evtsPar->genValue() ); + nEvts = evtsPar->genValue(); if ( nEvts < 0 ) { evtWeight = -1.0; nEvts = TMath::Abs( nEvts ); } - asym = asymPar->genValue(); - nPosEvts = static_cast((nEvts/2.0 * (1.0 - asym)) + 0.5); - nNegEvts = static_cast((nEvts/2.0 * (1.0 + asym)) + 0.5); + + const Double_t asym = asymPar->genValue(); + nPosEvts = (nEvts/2.0 * (1.0 - asym)); + nNegEvts = (nEvts/2.0 * (1.0 + asym)); + + nPosEvtsToGen = static_cast(nPosEvts); + nNegEvtsToGen = static_cast(nNegEvts); if (this->doPoissonSmearing()) { - nNegEvts = LauRandom::randomFun()->Poisson(nNegEvts); - nPosEvts = LauRandom::randomFun()->Poisson(nPosEvts); + nPosEvtsToGen = LauRandom::randomFun()->Poisson(nPosEvts); + nNegEvtsToGen = LauRandom::randomFun()->Poisson(nNegEvts); } - nEvtsGen[std::make_pair(bkgndClass,-1)] = std::make_pair(nNegEvts,evtWeight); - nEvtsGen[std::make_pair(bkgndClass,+1)] = std::make_pair(nPosEvts,evtWeight); + + const TString& bkgndClass = this->bkgndClassName(bkgndID); + nEvtsGen[std::make_pair(bkgndClass,+1)] = std::make_pair(nPosEvtsToGen,evtWeight); + nEvtsGen[std::make_pair(bkgndClass,-1)] = std::make_pair(nNegEvtsToGen,evtWeight); } // Print out the information on what we're generating, but only if none of the parameters are blind (otherwise we risk unblinding them!) diff --git a/src/LauCalcChiSq.cc b/src/LauCalcChiSq.cc --- a/src/LauCalcChiSq.cc +++ b/src/LauCalcChiSq.cc @@ -22,31 +22,30 @@ Thomas Latham */ -// Code to produce an adaptive binning scheme and calculate the 2D chi-square between -// two datasets (e.g. low-stat data and high-stat toyMC). -// To run the code, do "./CalcChiSq chiSqInput.txt", where chiSqInput.txt is -// an input control file, and contains the following lines: -// Low_stat_file_name Low_stat_histo_name -// High_stat_file_name High_stat_histo_name -// Min_bin_content N_free_params Low/high stat_histo_ratio - -// Note that the low and high stat histograms must have the same bin axes -// ranges and number of bins. - -// It works by using the low stat (first) histogram to find a binning scheme such -// that the total number of entries in each bin is >= Min_bin_content. The number -// of entries in the histogram is divided by the desired minimum bin content to -// give a target number of bins. The largest number of bins that can be expressed -// as a product of powers of four, nine, 25, 49 and 121 that does not exceed the -// target value is chosen. The histogram is the recursively subdivided in 2x2, 3x3, -// 5x5, 7x7 or 11x11 bins. For each stage of the subdivision, each bin is first -// divided into equally populated bins in x then each of these is further divded -// into equally popiulated bins in y. - -// The (Pearson) chi-squared is then the sum of the chi-squared contributions -// of all bins: -// (low_stat_number - high_stat_number)^2/(high_stat_number) -// The nDof = number of bins - number of free params - 1 +/*! \file LauCalcChiSq.cc + \brief File containing implementation of LauCalcChiSq class. + + Code to produce an adaptive binning scheme and calculate the 2D chi-square + between two datasets (e.g. low-stat data and high-stat toyMC). + + Note that the low and high stat histograms must have the same bin axes ranges + and number of bins. + + It works by using the low stat (first) histogram to find a binning scheme such + that the total number of entries in each bin is >= Min_bin_content. The number + of entries in the histogram is divided by the desired minimum bin content to + give a target number of bins. The largest number of bins that can be expressed + as a product of powers of 4, 9, 25, 49 and 121 that does not exceed the target + value is chosen. The histogram is the recursively subdivided in 2x2, 3x3, 5x5, + 7x7 or 11x11 bins. For each stage of the subdivision, each bin is first + divided into equally populated bins in x then each of these is further divded + into equally popiulated bins in y. + + The (Pearson) chi-squared is then the sum of the chi-squared contributions of + all bins: + (low_stat_number - high_stat_number)^2/(high_stat_number) + The nDof = number of bins - number of free params - 1 + */ #include "LauCalcChiSq.hh" @@ -193,9 +192,14 @@ histo1_->SetTitleSize(0.06,"y"); histo1_->SetLabelSize(0.05,"x"); histo1_->SetLabelSize(0.05,"y"); - histo1_->SetXTitle(xName1_); - histo1_->SetYTitle(yName1_); - histo1_->Draw("colz"); + histo1_->SetMarkerColor(0); + g_data_->SetMarkerStyle(20); + g_data_->SetMarkerSize(.5); + g_data_->Draw("ap"); + g_data_->GetXaxis()->SetTitle(xTitle_); + g_data_->GetYaxis()->SetTitle(yTitle_); + //histo1_->Draw("colztextsame"); + histo1_->Draw("colzsame"); can.SaveAs("data.pdf"); histo2_->SetLabelFont(62,"x"); @@ -208,10 +212,20 @@ histo2_->SetLabelSize(0.05,"y"); histo2_->SetXTitle(xName1_); histo2_->SetYTitle(yName1_); - histo2_->Draw("colz"); - can.SaveAs("toy.pdf"); - - if(-1.*pullHisto_->GetMinimum() > pullHisto_->GetMaximum()) pullHisto_->SetMaximum(-1.*pullHisto_->GetMinimum()); + histo2_->SetMarkerColor(0); + g_toy_->SetMarkerStyle(20); + g_toy_->SetMarkerSize(.5); + g_toy_->Draw("ap"); + g_toy_->GetXaxis()->SetTitle(xTitle_); + g_toy_->GetYaxis()->SetTitle(yTitle_); + //histo2_->Draw("colztextsame"); + histo2_->Draw("colzsame"); + can.SaveAs("toy.png"); + + if(-1.*pullHisto_->GetMinimum() > pullHisto_->GetMaximum()) { + pullHisto_->SetMinimum(pullHisto_->GetMinimum()); // Required to workaround a bug in TH2Poly where, if SetMinimum is not called, negative entries are not drawn by "Draw("text")" + pullHisto_->SetMaximum(-1.*pullHisto_->GetMinimum()); + } else pullHisto_->SetMinimum(-1.*pullHisto_->GetMaximum()); pullHisto_->SetLabelFont(62,"x"); @@ -222,10 +236,20 @@ pullHisto_->SetTitleSize(0.06,"y"); pullHisto_->SetLabelSize(0.05,"x"); pullHisto_->SetLabelSize(0.05,"y"); - pullHisto_->SetXTitle(xName1_); - pullHisto_->SetYTitle(yName1_); - pullHisto_->Draw("colz"); + pullHisto_->SetMarkerColor(0); + pullHisto_->SetMinimum(-9.); + pullHisto_->SetMaximum(9.); + g_data_->SetTitle("(data - toy) / error"); + g_data_->Draw("ap"); + gStyle->SetPaintTextFormat(".2f"); + pullHisto_->SetLineWidth(1); + pullHisto_->SetLineColor(kBlack); + pullHisto_->SetLineStyle(1); + //pullHisto_->Draw("colztextsame"); + pullHisto_->Draw("colzsame"); + g_data_->Draw("psame"); can.SaveAs("pull.pdf"); + can.SaveAs("pull.C"); chiSqHisto_->SetLabelFont(62,"x"); chiSqHisto_->SetLabelFont(62,"y"); @@ -235,9 +259,10 @@ chiSqHisto_->SetTitleSize(0.06,"y"); chiSqHisto_->SetLabelSize(0.05,"x"); chiSqHisto_->SetLabelSize(0.05,"y"); - chiSqHisto_->SetXTitle(xName1_); - chiSqHisto_->SetYTitle(yName1_); - chiSqHisto_->Draw("colz"); + chiSqHisto_->SetMarkerColor(0); + g_data_->Draw("ap"); + //chiSqHisto_->Draw("colztextsame"); + chiSqHisto_->Draw("colzsame"); can.SaveAs("chiSq.pdf"); chiSqSignedHisto_->SetLabelFont(62,"x"); @@ -248,9 +273,12 @@ chiSqSignedHisto_->SetTitleSize(0.06,"y"); chiSqSignedHisto_->SetLabelSize(0.05,"x"); chiSqSignedHisto_->SetLabelSize(0.05,"y"); - chiSqSignedHisto_->SetXTitle(xName1_); - chiSqSignedHisto_->SetYTitle(yName1_); - chiSqSignedHisto_->Draw("colz"); + chiSqSignedHisto_->SetXTitle(xTitle_); + chiSqSignedHisto_->SetYTitle(yTitle_); + chiSqSignedHisto_->SetMarkerColor(0); + g_data_->Draw("ap"); + //chiSqSignedHisto_->Draw("colztextsame"); + chiSqSignedHisto_->Draw("colzsame"); can.SaveAs("chiSqSigned.pdf"); } @@ -259,13 +287,18 @@ { // Open the input control file: - // Low_stat_file_name Low_stat_tree_name Low_stat_x_axis_name Low_stat_y_axis_name + // Low_stat_file_name Low_stat_tree_name iExpt Low_stat_x_axis_name Low_stat_y_axis_name // High_stat_file_name High_stat_tree_name High_stat_x_axis_name High_stat_y_axis_name // Min_bin_content N_free_params Low/high_stat_histo_ratio xMin xMax yMin yMax std::ifstream getData(inputFileName_.Data()); // get the info on the low stat histo - getData >> fileName1_ >> treeName1_ >> xName1_ >> yName1_; + getData >> fileName1_ >> treeName1_ >> iExpt_ >> xName1_ >> yName1_ >> xTitle_ >> yTitle_; + + // Hack to introduce spaces in axis titles + xTitle_=xTitle_.ReplaceAll("SPACE"," "); + yTitle_=yTitle_.ReplaceAll("SPACE"," "); + if (!getData.good()) { std::cerr<<"Error. Could not read first line of the input file "<Exit(EXIT_FAILURE); @@ -276,8 +309,9 @@ if (file1 == 0) {gSystem->Exit(EXIT_FAILURE);} - // retrieve the low stat histogram - TTree* tree1 = dynamic_cast(file1->Get(treeName1_.Data())); + // retrieve the low stat histogram and extract the experiment + TTree* tree1temp = dynamic_cast(file1->Get(treeName1_.Data())); + TTree* tree1 = tree1temp->CopyTree("iExpt=="+iExpt_); if (tree1 == 0) { std::cerr<<"Error. Could not find the tree "<SetBranchAddress(xName1_.Data(),&x); + tree2->SetBranchAddress(yName1_.Data(),&y); + Int_t nEntries_toy = 5000;//tree2->GetEntries(); + Double_t* xs_toy = new Double_t[nEntries_toy]; + Double_t* ys_toy = new Double_t[nEntries_toy]; + for ( Int_t i=0; i < nEntries_toy; ++i ) { + tree2->GetEntry( i ); + xs_toy[i] = x; + ys_toy[i] = y; + } + + g_toy_ = new TGraph(nEntries_toy,xs_toy,ys_toy); + theHisto_ = new TH2Poly("theHisto_", "", xMin_, xMax_, yMin_, yMax_); //select the number of divisions to get us closest to minContent entries per bin diff --git a/src/LauDabbaRes.cc b/src/LauDabbaRes.cc --- a/src/LauDabbaRes.cc +++ b/src/LauDabbaRes.cc @@ -24,6 +24,7 @@ /*! \file LauDabbaRes.cc \brief File containing implementation of LauDabbaRes class. + Formulae and data values from arXiv:0901.2217 - author D.V.Bugg */ diff --git a/src/LauFormulaPar.cc b/src/LauFormulaPar.cc --- a/src/LauFormulaPar.cc +++ b/src/LauFormulaPar.cc @@ -46,8 +46,7 @@ name_(forName), formula_(forName,formula), paramVec_(params), - dummy_(0), - paramArray_(0), + paramArray_(nullptr), gaussConstraint_(kFALSE), constraintMean_(0.0), constraintWidth_(0.0) @@ -59,21 +58,17 @@ gSystem->Exit(EXIT_FAILURE); } - if (formula_.GetNdim() != 1){ - std::cerr<<"ERROR in LauFormulaPar::evaluate : Given formula of dimension: "<Exit(EXIT_FAILURE); } - // Dummy array for TFormula - dummy_ = new Double_t[1]; - // Array of input parameters paramArray_ = new Double_t[nPars]; } LauFormulaPar::~LauFormulaPar() { - delete[] dummy_; delete[] paramArray_; } @@ -81,8 +76,7 @@ name_(rhs.name_), formula_(rhs.formula_), paramVec_(rhs.paramVec_), - dummy_(0), - paramArray_(0), + paramArray_(nullptr), gaussConstraint_(rhs.gaussConstraint_), constraintMean_(rhs.constraintMean_), constraintWidth_(rhs.constraintWidth_) @@ -94,14 +88,11 @@ gSystem->Exit(EXIT_FAILURE); } - if (formula_.GetNdim() != 1){ - std::cerr<<"ERROR in LauFormulaPar::evaluate : Given formula of dimension: "<Exit(EXIT_FAILURE); } - // Dummy array for TFormula - dummy_ = new Double_t[1]; - // Array of input parameters paramArray_ = new Double_t[nPars]; } @@ -121,8 +112,6 @@ paramArray_ = new Double_t[nNewPars]; } - // NB no need to recreate dummy_ - gaussConstraint_ = rhs.gaussConstraint_; constraintMean_ = rhs.constraintMean_; constraintWidth_ = rhs.constraintWidth_; @@ -139,7 +128,7 @@ paramArray_[i] = paramVec_[i]->value(); } - return formula_.EvalPar(dummy_,paramArray_); + return formula_.EvalPar(nullptr,paramArray_); } Double_t LauFormulaPar::unblindValue() const @@ -151,7 +140,7 @@ paramArray_[i] = paramVec_[i]->unblindValue(); } - return formula_.EvalPar(dummy_,paramArray_); + return formula_.EvalPar(nullptr,paramArray_); } Double_t LauFormulaPar::genValue() const @@ -163,7 +152,7 @@ paramArray_[i] = paramVec_[i]->genValue(); } - return formula_.EvalPar(dummy_,paramArray_); + return formula_.EvalPar(nullptr,paramArray_); } Double_t LauFormulaPar::initValue() const @@ -175,7 +164,7 @@ paramArray_[i] = paramVec_[i]->initValue(); } - return formula_.EvalPar(dummy_,paramArray_); + return formula_.EvalPar(nullptr,paramArray_); } Bool_t LauFormulaPar::fixed() const diff --git a/src/LauGounarisSakuraiRes.cc b/src/LauGounarisSakuraiRes.cc --- a/src/LauGounarisSakuraiRes.cc +++ b/src/LauGounarisSakuraiRes.cc @@ -37,9 +37,6 @@ LauGounarisSakuraiRes::LauGounarisSakuraiRes(LauResonanceInfo* resInfo, const Int_t resPairAmpInt, const LauDaughters* daughters) : LauAbsResonance(resInfo, resPairAmpInt, daughters), q0_(0.0), - p0_(0.0), - pstar0_(0.0), - erm0_(0.0), resMass_(0.0), resMassSq_(0.0), resWidth_(0.0), @@ -54,8 +51,7 @@ h0_(0.0), dhdm0_(0.0), d_(0.0), - FR0_(1.0), - FP0_(1.0) + FR0_(1.0) { } @@ -95,76 +91,45 @@ mParentSq_ = massParent*massParent; mBachSq_ = massBachelor*massBachelor; + // Create an effective resonance pole mass to protect against resonances + // that are below threshold + Double_t effResMass = resMass_; + Double_t effResMassSq = resMassSq_; + if ( resMassSq_ - mDaugSumSq_ < 0.0 ) { + Double_t minMass = mDaugSum_; + Double_t maxMass = massParent - massBachelor; + Double_t tanhTerm = std::tanh( (resMass_ - ((minMass + maxMass)/2))/(maxMass-minMass)); + effResMass = minMass + (maxMass-minMass)*(1+tanhTerm)/2; + effResMassSq = effResMass*effResMass; + } + // Decay momentum of either daughter in the resonance rest frame // when resonance mass = rest-mass value, m_0 (PDG value) - Double_t term1 = resMassSq_ - mDaugSumSq_; - Double_t term2 = resMassSq_ - mDaugDiffSq_; + Double_t term1 = effResMassSq - mDaugSumSq_; + Double_t term2 = effResMassSq - mDaugDiffSq_; Double_t term12 = term1*term2; if (term12 > 0.0) { - q0_ = TMath::Sqrt(term12)/(2.0*resMass_); + q0_ = TMath::Sqrt(term12)/(2.0*effResMass); } else { q0_ = 0.0; } - // Momentum of the bachelor particle in the resonance rest frame - // when resonance mass = rest-mass value, m_0 (PDG value) - Double_t eBach = (mParentSq_ - resMassSq_ - mBachSq_)/(2.0*resMass_); - Double_t termBach = eBach*eBach - mBachSq_; - if ( eBach<0.0 || termBach<0.0 ) { - p0_ = 0.0; - } else { - p0_ = TMath::Sqrt( termBach ); - } - - // Momentum of the bachelor particle in the parent rest frame - // when resonance mass = rest-mass value, m_0 (PDG value) - Double_t eStarBach = (mParentSq_ + mBachSq_ - resMassSq_)/(2.0*massParent); - Double_t termStarBach = eStarBach*eStarBach - mBachSq_; - if ( eStarBach<0.0 || termStarBach<0.0 ) { - pstar0_ = 0.0; - } else { - pstar0_ = TMath::Sqrt( termStarBach ); - } - - // Covariant factor when resonance mass = rest-mass value, m_0 (PDF value) - erm0_ = (mParentSq_ + resMassSq_ - mBachSq_)/(2.0*massParent*resMass_); - this->calcCovFactor( erm0_ ); - // Calculate the Blatt-Weisskopf form factor for the case when m = m_0 FR0_ = 1.0; - FP0_ = 1.0; - if ( resSpin > 0 ) { + if ( this->getSpin() > 0 ) { const LauBlattWeisskopfFactor* resBWFactor = this->getResBWFactor(); - const LauBlattWeisskopfFactor* parBWFactor = this->getParBWFactor(); - FR0_ = (resBWFactor!=0) ? resBWFactor->calcFormFactor(q0_) : 1.0; - switch ( parBWFactor->getRestFrame() ) { - case LauBlattWeisskopfFactor::ResonanceFrame: - FP0_ = (parBWFactor!=0) ? parBWFactor->calcFormFactor(p0_) : 1.0; - break; - case LauBlattWeisskopfFactor::ParentFrame: - FP0_ = (parBWFactor!=0) ? parBWFactor->calcFormFactor(pstar0_) : 1.0; - break; - case LauBlattWeisskopfFactor::Covariant: - { - Double_t covFactor = this->getCovFactor(); - if ( resSpin > 2 ) { - covFactor = TMath::Power( covFactor, 1.0/resSpin ); - } else if ( resSpin == 2 ) { - covFactor = TMath::Sqrt( covFactor ); - } - FP0_ = (parBWFactor!=0) ? parBWFactor->calcFormFactor(pstar0_*covFactor) : 1.0; - break; - } + if ( resBWFactor != nullptr ) { + FR0_ = resBWFactor->calcFormFactor(q0_); } } // Calculate the extra things needed by the G-S shape - h0_ = 2.0*LauConstants::invPi * q0_/resMass_ * TMath::Log((resMass_ + 2.0*q0_)/(2.0*LauConstants::mPi)); - dhdm0_ = h0_ * (1.0/(8.0*q0_*q0_) - 1.0/(2.0*resMassSq_)) + 1.0/(LauConstants::twoPi*resMassSq_); + h0_ = 2.0*LauConstants::invPi * q0_/effResMass * TMath::Log((effResMass + 2.0*q0_)/(2.0*LauConstants::mPi)); + dhdm0_ = h0_ * (1.0/(8.0*q0_*q0_) - 1.0/(2.0*effResMassSq)) + 1.0/(LauConstants::twoPi*effResMassSq); d_ = 3.0*LauConstants::invPi * LauConstants::mPi*LauConstants::mPi/(q0_*q0_) - * TMath::Log((resMass_ + 2.0*q0_)/(2.0*LauConstants::mPi)) - + resMass_/(LauConstants::twoPi*q0_) - - LauConstants::mPi*LauConstants::mPi*resMass_/(LauConstants::pi*q0_*q0_*q0_); + * TMath::Log((effResMass + 2.0*q0_)/(2.0*LauConstants::mPi)) + + effResMass/(LauConstants::twoPi*q0_) + - LauConstants::mPi*LauConstants::mPi*effResMass/(LauConstants::pi*q0_*q0_*q0_); } LauComplex LauGounarisSakuraiRes::resAmp(Double_t mass, Double_t spinTerm) @@ -212,30 +177,34 @@ Double_t fFactorB(1.0); if ( resSpin > 0 ) { const LauBlattWeisskopfFactor* resBWFactor = this->getResBWFactor(); + if ( resBWFactor != nullptr ) { + fFactorR = resBWFactor->calcFormFactor(q); + } + const LauBlattWeisskopfFactor* parBWFactor = this->getParBWFactor(); - fFactorR = (resBWFactor!=0) ? resBWFactor->calcFormFactor(q) : 1.0; - switch ( parBWFactor->getRestFrame() ) { - case LauBlattWeisskopfFactor::ResonanceFrame: - fFactorB = (parBWFactor!=0) ? parBWFactor->calcFormFactor(p) : 1.0; - break; - case LauBlattWeisskopfFactor::ParentFrame: - fFactorB = (parBWFactor!=0) ? parBWFactor->calcFormFactor(pstar) : 1.0; - break; - case LauBlattWeisskopfFactor::Covariant: + if ( parBWFactor != nullptr ) { + switch ( parBWFactor->getRestFrame() ) { + case LauBlattWeisskopfFactor::ResonanceFrame: + fFactorB = parBWFactor->calcFormFactor(p); + break; + case LauBlattWeisskopfFactor::ParentFrame: + fFactorB = parBWFactor->calcFormFactor(pstar); + break; + case LauBlattWeisskopfFactor::Covariant: { - Double_t covFactor = this->getCovFactor(); - if ( resSpin > 2 ) { - covFactor = TMath::Power( covFactor, 1.0/resSpin ); - } else if ( resSpin == 2 ) { - covFactor = TMath::Sqrt( covFactor ); - } - fFactorB = (parBWFactor!=0) ? parBWFactor->calcFormFactor(pstar*covFactor) : 1.0; - break; + Double_t covFactor = this->getCovFactor(); + if ( resSpin > 2 ) { + covFactor = TMath::Power( covFactor, 1.0/resSpin ); + } else if ( resSpin == 2 ) { + covFactor = TMath::Sqrt( covFactor ); + } + fFactorB = parBWFactor->calcFormFactor(pstar*covFactor); + break; } + } } } const Double_t fFactorRRatio = fFactorR/FR0_; - const Double_t fFactorBRatio = fFactorB/FP0_; const Double_t qRatio = q/q0_; const Double_t qTerm = qRatio*qRatio*qRatio; @@ -254,7 +223,7 @@ // Scale by the denominator factor, as well as the spin term and Blatt-Weisskopf factors Double_t numerFactor = spinTerm*(1.0 + d_ * resWidth/resMass); if (!this->ignoreBarrierScaling()) { - numerFactor *= fFactorRRatio*fFactorBRatio; + numerFactor *= fFactorR * fFactorB; } const Double_t denomFactor = (massSqTerm + f)*(massSqTerm + f) + resMassSq_*totWidth*totWidth; resAmplitude.rescale(numerFactor/denomFactor); diff --git a/src/LauIsobarDynamics.cc b/src/LauIsobarDynamics.cc --- a/src/LauIsobarDynamics.cc +++ b/src/LauIsobarDynamics.cc @@ -100,7 +100,8 @@ aSqMaxSet_(1.25), aSqMaxVar_(0.0), flipHelicity_(kTRUE), - recalcNormalisation_(kFALSE) + recalcNormalisation_(kFALSE), + calculateRhoOmegaFitFractions_(kFALSE) { if (daughters != 0) { symmetricalDP_ = daughters->gotSymmetricalDP(); @@ -163,7 +164,8 @@ aSqMaxSet_(1.25), aSqMaxVar_(0.0), flipHelicity_(kTRUE), - recalcNormalisation_(kFALSE) + recalcNormalisation_(kFALSE), + calculateRhoOmegaFitFractions_(kFALSE) { // Constructor for the isobar signal model if (daughters != 0) { diff --git a/src/LauKMatrixProdPole.cc b/src/LauKMatrixProdPole.cc --- a/src/LauKMatrixProdPole.cc +++ b/src/LauKMatrixProdPole.cc @@ -28,47 +28,40 @@ #include "LauKMatrixProdPole.hh" #include "LauKMatrixPropagator.hh" +#include "LauResonanceMaker.hh" #include ClassImp(LauKMatrixProdPole) -LauKMatrixProdPole::LauKMatrixProdPole(const TString& poleName, Int_t poleIndex, Int_t resPairAmpInt, - LauKMatrixPropagator* propagator, const LauDaughters* daughters, - Bool_t useProdAdler) : - LauAbsResonance(poleName, resPairAmpInt, daughters), +LauKMatrixProdPole::LauKMatrixProdPole( const TString& poleName, Int_t poleIndex, Int_t resPairAmpInt, + LauKMatrixPropagator* propagator, const LauDaughters* daughters, + Bool_t useProdAdler) : + LauAbsResonance( poleName, resPairAmpInt, daughters, propagator->getL(propagator->getIndex()) ), thePropagator_(propagator), - poleIndex_(poleIndex - 1), // poleIndex goes from 1 to nPoles - useProdAdler_(useProdAdler) + poleIndex_(poleIndex - 1), // poleIndex goes from 1 to nPoles + useProdAdler_(useProdAdler) { - if (useProdAdler_) { - std::cout<<"Creating K matrix production pole "<setBarrierRadii( nullptr,LauResonanceMaker::get().getParentBWFactor( propagator->getL(propagator->getIndex()), LauBlattWeisskopfFactor::BWBarrier ) ); } LauKMatrixProdPole::~LauKMatrixProdPole() { } -LauComplex LauKMatrixProdPole::resAmp(Double_t mass, Double_t spinTerm) +LauComplex LauKMatrixProdPole::resAmp(const Double_t mass, const Double_t spinTerm) { - std::cerr << "ERROR in LauKMatrixProdPole::resAmp : This method shouldn't get called." << std::endl; - std::cerr << " Returning zero amplitude for mass = " << mass << " and spinTerm = " << spinTerm << "." << std::endl; - return LauComplex(0.0, 0.0); -} - -LauComplex LauKMatrixProdPole::amplitude(const LauKinematics* kinematics) -{ - // Calculate the amplitude for the K-matrix production pole. - // First, make sure the K-matrix propagator is up-to-date for - // the given centre-of-mass squared value ("s") from the kinematics. LauComplex amp(0.0, 0.0); if (thePropagator_ == 0) { @@ -76,7 +69,40 @@ return amp; } - thePropagator_->updatePropagator(kinematics); + // Get barrier factors ('resonance' factor is already accounted for internally via propagator 'Gamma' matrix) + Double_t fFactorB(1.0); + + const Int_t resSpin = this->getSpin(); + const Double_t pstar = this->getPstar(); + + if ( resSpin > 0 ) { + const LauBlattWeisskopfFactor* parBWFactor = this->getParBWFactor(); + if ( parBWFactor != nullptr ) { + switch ( parBWFactor->getRestFrame() ) { + case LauBlattWeisskopfFactor::ResonanceFrame: + fFactorB = parBWFactor->calcFormFactor(this->getP()); + break; + case LauBlattWeisskopfFactor::ParentFrame: + fFactorB = parBWFactor->calcFormFactor(pstar); + break; + case LauBlattWeisskopfFactor::Covariant: + { + Double_t covFactor = this->getCovFactor(); + if ( resSpin > 2 ) { + covFactor = TMath::Power( covFactor, 1.0/resSpin ); + } else if ( resSpin == 2 ) { + covFactor = TMath::Sqrt( covFactor ); + } + fFactorB = parBWFactor->calcFormFactor(pstar*covFactor); + break; + } + } + } + } + + // Make sure the K-matrix propagator is up-to-date for + // the given centre-of-mass squared value ("s") + thePropagator_->updatePropagator(mass*mass); // Sum the pole denominator terms over all channels j, multiplying by // the propagator terms. Note that we do not sum over poles, since we @@ -103,6 +129,40 @@ amp.rescale(poleDenom*adlerZero); + // Scale by the spin term + Double_t scale = spinTerm; + + // Include Blatt-Weisskopf barrier factor for parent + scale *= fFactorB; + + amp.rescale(scale); + return amp; } + +const std::vector& LauKMatrixProdPole::getFloatingParameters() +{ + + this->clearFloatingParameters(); + + Int_t nChannels = thePropagator_->getNChannels(); + + for (int jChannel = 0 ; jChannel < nChannels ; jChannel++) + { + LauParameter& par_gj_ = thePropagator_->getCouplingParameter(poleIndex_, jChannel); + if ( !par_gj_.fixed() ) + { + this->addFloatingParameter( &par_gj_ ); + } + } + + LauParameter& par_polemasssq_ = thePropagator_->getPoleMassSqParameter(poleIndex_); + if ( !par_polemasssq_.fixed() ) + { + this->addFloatingParameter( &par_polemasssq_ ); + } + + return this->getParameters(); + +} diff --git a/src/LauKMatrixProdSVP.cc b/src/LauKMatrixProdSVP.cc --- a/src/LauKMatrixProdSVP.cc +++ b/src/LauKMatrixProdSVP.cc @@ -33,24 +33,23 @@ ClassImp(LauKMatrixProdSVP) -LauKMatrixProdSVP::LauKMatrixProdSVP(const TString& SVPName, Int_t channelIndex, Int_t resPairAmpInt, - LauKMatrixPropagator* propagator, const LauDaughters* daughters, - Bool_t useProdAdler) : - LauAbsResonance(SVPName, resPairAmpInt, daughters), +LauKMatrixProdSVP::LauKMatrixProdSVP( const TString& SVPName, Int_t channelIndex, Int_t resPairAmpInt, + LauKMatrixPropagator* propagator, const LauDaughters* daughters, + Bool_t useProdAdler) : + LauAbsResonance( SVPName, resPairAmpInt, daughters, propagator->getL(propagator->getIndex()) ), thePropagator_(propagator), - channelIndex_(channelIndex - 1), // channelIndex goes from 1 to nChannels. - useProdAdler_(useProdAdler) + channelIndex_(channelIndex - 1), // channelIndex goes from 1 to nChannels. + useProdAdler_(useProdAdler) { // Constructor - if (useProdAdler_) { - std::cout<<"Creating K matrix production SVP "<updatePropagator(kinematics); + // Get barrier factors ('resonance' factor is already accounted for internally via propagator 'Gamma' matrix) + Double_t fFactorB(1.0); + + const Int_t resSpin = this->getSpin(); + const Double_t pstar = this->getPstar(); + + if ( resSpin > 0 ) { + const LauBlattWeisskopfFactor* parBWFactor = this->getParBWFactor(); + if ( parBWFactor != nullptr ) { + switch ( parBWFactor->getRestFrame() ) { + case LauBlattWeisskopfFactor::ResonanceFrame: + fFactorB = parBWFactor->calcFormFactor(this->getP()); + break; + case LauBlattWeisskopfFactor::ParentFrame: + fFactorB = parBWFactor->calcFormFactor(pstar); + break; + case LauBlattWeisskopfFactor::Covariant: + { + Double_t covFactor = this->getCovFactor(); + if ( resSpin > 2 ) { + covFactor = TMath::Power( covFactor, 1.0/resSpin ); + } else if ( resSpin == 2 ) { + covFactor = TMath::Sqrt( covFactor ); + } + fFactorB = parBWFactor->calcFormFactor(pstar*covFactor); + break; + } + } + } + } + + thePropagator_->updatePropagator(mass*mass); Double_t SVPTerm = thePropagator_->getProdSVPTerm(); @@ -90,7 +113,65 @@ amp.rescale(SVPTerm*adlerZero); + // Scale by the spin term + Double_t scale = spinTerm; + + // Include Blatt-Weisskopf barrier factor for parent + scale *= fFactorB; + + amp.rescale(scale); + return amp; } +const std::vector& LauKMatrixProdSVP::getFloatingParameters() +{ + + this->clearFloatingParameters(); + + Int_t nChannels = thePropagator_->getNChannels(); + + for (int jChannel = 0 ; jChannel < nChannels ; jChannel++) + { + LauParameter& par_f_ = thePropagator_->getScatteringParameter(channelIndex_, jChannel); + if ( !par_f_.fixed() ) + { + this->addFloatingParameter( &par_f_ ); + } + + } + + LauParameter& par_mSq0_ = thePropagator_->getmSq0(); + if ( !par_mSq0_.fixed() ) + { + this->addFloatingParameter( &par_mSq0_ ); + } + + LauParameter& par_s0Scatt_ = thePropagator_->gets0Scatt(); + if ( !par_s0Scatt_.fixed() ) + { + this->addFloatingParameter( &par_s0Scatt_ ); + } + + LauParameter& par_s0Prod_ = thePropagator_->gets0Prod(); + if ( !par_s0Prod_.fixed() ) + { + this->addFloatingParameter( &par_s0Prod_ ); + } + + LauParameter& par_sA_ = thePropagator_->getsA(); + if ( !par_sA_.fixed() ) + { + this->addFloatingParameter( &par_sA_ ); + } + + LauParameter& par_sA0_ = thePropagator_->getsA0(); + if ( !par_sA0_.fixed() ) + { + this->addFloatingParameter( &par_sA0_ ); + } + + return this->getParameters(); + +} \ No newline at end of file diff --git a/src/LauKMatrixPropagator.cc b/src/LauKMatrixPropagator.cc --- a/src/LauKMatrixPropagator.cc +++ b/src/LauKMatrixPropagator.cc @@ -6,7 +6,7 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -23,12 +23,13 @@ */ /*! \file LauKMatrixPropagator.cc - \brief File containing implementation of LauKMatrixPropagator class. + \brief File containing implementation of LauKMatrixPropagator class. */ #include "LauKMatrixPropagator.hh" -#include "LauConstants.hh" #include "LauTextFileParser.hh" +#include "LauKinematics.hh" +#include "LauComplex.hh" #include "TMath.h" #include "TSystem.h" @@ -45,43 +46,22 @@ ClassImp(LauKMatrixPropagator) LauKMatrixPropagator::LauKMatrixPropagator(const TString& name, const TString& paramFile, - Int_t resPairAmpInt, Int_t nChannels, - Int_t nPoles, Int_t rowIndex) : + Int_t resPairAmpInt, Int_t nChannels, + Int_t nPoles, Int_t rowIndex) : name_(name), paramFileName_(paramFile), resPairAmpInt_(resPairAmpInt), index_(rowIndex - 1), - previousS_(0.0), - scattSVP_(0.0), - prodSVP_(0.0), nChannels_(nChannels), - nPoles_(nPoles), - sAConst_(0.0), - m2piSq_(4.0*LauConstants::mPiSq), - m2KSq_( 4.0*LauConstants::mKSq), - m2EtaSq_(4.0*LauConstants::mEtaSq), - mEtaEtaPSumSq_((LauConstants::mEta + LauConstants::mEtaPrime)*(LauConstants::mEta + LauConstants::mEtaPrime)), - mEtaEtaPDiffSq_((LauConstants::mEta - LauConstants::mEtaPrime)*(LauConstants::mEta - LauConstants::mEtaPrime)), - mKpiSumSq_((LauConstants::mK + LauConstants::mPi)*(LauConstants::mK + LauConstants::mPi)), - mKpiDiffSq_((LauConstants::mK - LauConstants::mPi)*(LauConstants::mK - LauConstants::mPi)), - mKEtaPSumSq_((LauConstants::mK + LauConstants::mEtaPrime)*(LauConstants::mK + LauConstants::mEtaPrime)), - mKEtaPDiffSq_((LauConstants::mK - LauConstants::mEtaPrime)*(LauConstants::mK - LauConstants::mEtaPrime)), - mK3piDiffSq_((LauConstants::mK - 3.0*LauConstants::mPi)*(LauConstants::mK - 3.0*LauConstants::mPi)), - k3piFactor_(TMath::Power((1.44 - mK3piDiffSq_)/1.44, -2.5)), - fourPiFactor1_(16.0*LauConstants::mPiSq), - fourPiFactor2_(TMath::Sqrt(1.0 - fourPiFactor1_)), - adlerZeroFactor_(0.0), - parametersSet_(kFALSE), - verbose_(kFALSE), - scattSymmetry_(kTRUE) + nPoles_(nPoles) { // Constructor - // Check that the index is OK - if (index_ < 0 || index_ >= nChannels_) { - std::cerr << "ERROR in LauKMatrixPropagator constructor. The rowIndex, which is set to " - << rowIndex << ", must be between 1 and the number of channels " - << nChannels_ << std::endl; + // Check that the index is OK + if (index_ < 0 || index_ >= nChannels_) { + std::cerr << "ERROR in LauKMatrixPropagator constructor. The rowIndex, which is set to " + << rowIndex << ", must be between 1 and the number of channels " + << nChannels_ << std::endl; gSystem->Exit(EXIT_FAILURE); } @@ -93,16 +73,17 @@ // Destructor realProp_.Clear(); negImagProp_.Clear(); - ScattKMatrix_.Clear(); - ReRhoMatrix_.Clear(); - ImRhoMatrix_.Clear(); + ScattKMatrix_.Clear(); + ReRhoMatrix_.Clear(); + ImRhoMatrix_.Clear(); + GammaMatrix_.Clear(); ReTMatrix_.Clear(); ImTMatrix_.Clear(); IMatrix_.Clear(); zeroMatrix_.Clear(); } -LauComplex LauKMatrixPropagator::getPropTerm(Int_t channel) const +LauComplex LauKMatrixPropagator::getPropTerm(const Int_t channel) const { // Get the (i,j) = (index_, channel) term of the propagator // matrix. This allows us not to return the full propagator matrix. @@ -114,7 +95,7 @@ } -Double_t LauKMatrixPropagator::getRealPropTerm(Int_t channel) const +Double_t LauKMatrixPropagator::getRealPropTerm(const Int_t channel) const { // Get the real part of the (i,j) = (index_, channel) term of the propagator // matrix. This allows us not to return the full propagator matrix. @@ -125,7 +106,7 @@ } -Double_t LauKMatrixPropagator::getImagPropTerm(Int_t channel) const +Double_t LauKMatrixPropagator::getImagPropTerm(const Int_t channel) const { // Get the imaginary part of the (i,j) = (index_, channel) term of the propagator // matrix. This allows us not to return the full propagator matrix. @@ -136,36 +117,9 @@ } -void LauKMatrixPropagator::updatePropagator(const LauKinematics* kinematics) +void LauKMatrixPropagator::updatePropagator(const Double_t s) { - - // Calculate the K-matrix propagator for the given s value. - // The K-matrix amplitude is given by - // T_i = sum_{ij} (I - iK*rho)^-1 * P_j, where P is the production K-matrix. - // i = index for the state (e.g. S-wave index = 0). - // Here, we only find the (I - iK*rho)^-1 matrix part. - - if (!kinematics) {return;} - - // Get the invariant mass squared (s) from the kinematics object. - // Use the resPairAmpInt to find which mass-squared combination to use. - Double_t s(0.0); - - if (resPairAmpInt_ == 1) { - s = kinematics->getm23Sq(); - } else if (resPairAmpInt_ == 2) { - s = kinematics->getm13Sq(); - } else if (resPairAmpInt_ == 3) { - s = kinematics->getm12Sq(); - } - - this->updatePropagator(s); - -} - -void LauKMatrixPropagator::updatePropagator(Double_t s) -{ - // Calculate the K-matrix propagator for the given s value. + // Calculate the K-matrix propagator for the given s value. // The K-matrix amplitude is given by // T_i = sum_{ij} (I - iK*rho)^-1 * P_j, where P is the production K-matrix. // i = index for the state (e.g. S-wave index = 0). @@ -193,20 +147,29 @@ // if the quantity s is below various threshold values (analytic continuation). this->calcRhoMatrix(s); - // Calculate K*rho (real and imaginary parts, since rho can be complex) - TMatrixD K_realRho(ScattKMatrix_); - K_realRho *= ReRhoMatrix_; - TMatrixD K_imagRho(ScattKMatrix_); - K_imagRho *= ImRhoMatrix_; + // Calculate the angular momentum barrier matrix, which is real and diagonal + this->calcGammaMatrix(s); + + // Calculate K*rho*(gamma^2) (real and imaginary parts, since rho can be complex) + TMatrixD GammaMatrixSq = (GammaMatrix_*GammaMatrix_); + TMatrixD K_realRhoGammaSq(ScattKMatrix_); + + K_realRhoGammaSq *= ReRhoMatrix_; + K_realRhoGammaSq *= GammaMatrixSq; + TMatrixD K_imagRhoGammaSq(ScattKMatrix_); - // A = I + K*Imag(rho), B = -K*Real(Rho) + K_imagRhoGammaSq *= ImRhoMatrix_; + K_imagRhoGammaSq *= GammaMatrixSq; + + + // A = I + K*Imag(rho)Gamma^2, B = -K*Real(Rho)Gamma^2 // Calculate C and D matrices such that (A + iB)*(C + iD) = I, - // ie. C + iD = (I - i K*rho)^-1, separated into real and imaginary parts. + // ie. C + iD = (I - i K*rhoGamma^2)^-1, separated into real and imaginary parts. // realProp C = (A + B A^-1 B)^-1, imagProp D = -A^-1 B C TMatrixD A(IMatrix_); - A += K_imagRho; + A += K_imagRhoGammaSq; TMatrixD B(zeroMatrix_); - B -= K_realRho; + B -= K_realRhoGammaSq; TMatrixD invA(TMatrixD::kInverted, A); TMatrixD invA_B(invA); @@ -216,7 +179,6 @@ TMatrixD invC(A); invC += B_invA_B; - // Set the real part of the propagator matrix ("C") realProp_ = TMatrixD(TMatrixD::kInverted, invC); @@ -226,6 +188,29 @@ negImagProp_ = TMatrixD(invA); negImagProp_ *= BC; + // Pre-multiply by the Gamma matrix: + realProp_ = GammaMatrix_ * realProp_; + negImagProp_ = GammaMatrix_ * negImagProp_; + + if(verbose_) + { + std::cout << "In LauKMatrixPropagator::updatePropagator(s). D[1-iKrhoD^2]^-1: " << std::endl; + TString realOutput("Real part:"), imagOutput("Imag part:"); + for (int iChannel = 0; iChannel < nChannels_; iChannel++) + { + for (int jChannel = 0; jChannel < nChannels_; jChannel++) + { + realOutput += Form("\t%.6f",realProp_[iChannel][jChannel]); + imagOutput += Form("\t%.6f",-1*negImagProp_[iChannel][jChannel]); + } + realOutput += "\n "; + imagOutput += "\n "; + } + std::cout << realOutput << std::endl; + std::cout << imagOutput << std::endl; + } + + // Also calculate the production SVP term, since this uses Adler-zero parameters // defined in the parameter file. this->updateProdSVPTerm(s); @@ -250,7 +235,8 @@ cout<<"nChannels = "<Exit(EXIT_FAILURE); + gSystem->Exit(EXIT_FAILURE); } UInt_t iLine(0); @@ -305,6 +300,21 @@ // Scattering terms this->storeScattering(theLine); + } else if (!keyword.CompareTo("angularmomentum")) { + + // Orbital angular momentum state for each channel & set default a values if called before storeBarrierFactorParameter + this->storeOrbitalAngularMomenta(theLine, a); + + } else if (!keyword.CompareTo("barrierfactorparameter")) { + + // Value of parameter "a" in denominator of centrifugal barrier factor, gamma + this->storeBarrierFactorParameter(theLine, a); + + } else if (!keyword.CompareTo("radii")) { + + // Values of characteristic radius + this->storeRadii(theLine); + } else { // Usually Adler-zero constants @@ -331,6 +341,11 @@ } } + // Now that radii and barrier-factor-denominator parameters have been set, cache the value of "a/(R*R)" + for (Int_t iChannel = 0; iChannel < nChannels_; iChannel++) { + gamAInvRadSq_[iChannel] = a[iChannel]/(radii_[iChannel]*radii_[iChannel]); + } + // All required parameters have been set parametersSet_ = kTRUE; @@ -365,14 +380,30 @@ ReRhoMatrix_.ResizeTo(nChannels_, nChannels_); ImRhoMatrix_.ResizeTo(nChannels_, nChannels_); + // Gamma matrices + GammaMatrix_.Clear(); + GammaMatrix_.ResizeTo(nChannels_, nChannels_); + + // Vector of orbital angular momenta for the channels (default is S-wave everywhere) + L_.clear(); + L_.assign(nChannels_,0); + + // Characteristic radius (diagonal) vector (default to 3.0) + radii_.clear(); + radii_.assign(nChannels_,3.0); + + // Vector to cache ratio a/R^2 + gamAInvRadSq_.clear(); + gamAInvRadSq_.resize(nChannels_); + // Square-root phase space matrices ReSqrtRhoMatrix_.Clear(); ImSqrtRhoMatrix_.Clear(); ReSqrtRhoMatrix_.ResizeTo(nChannels_, nChannels_); ImSqrtRhoMatrix_.ResizeTo(nChannels_, nChannels_); // T matrices - ReTMatrix_.Clear(); ImTMatrix_.Clear(); - ReTMatrix_.ResizeTo(nChannels_, nChannels_); + ReTMatrix_.Clear(); ImTMatrix_.Clear(); + ReTMatrix_.ResizeTo(nChannels_, nChannels_); ImTMatrix_.ResizeTo(nChannels_, nChannels_); // For the coupling and scattering constants, use LauParArrays instead of TMatrices @@ -403,7 +434,7 @@ } -void LauKMatrixPropagator::storeChannels(const std::vector& theLine) +void LauKMatrixPropagator::storeChannels(const std::vector& theLine) { // Get the list of channel indices to specify what phase space factors should be used @@ -413,7 +444,7 @@ Int_t nTypes = static_cast(theLine.size()) - 1; if (nTypes != nChannels_) { cerr<<"Error in LauKMatrixPropagator::storeChannels. The input file defines " - <(phaseSpaceInt); } else { cerr<<"Phase space channel index "<(LauKMatrixPropagator::KMatrixChannels::TotChannels)-1<& theLine) @@ -499,11 +529,11 @@ for (Int_t iChannel = 0; iChannel < nChannels_; iChannel++) { Double_t scattConst = std::atof(theLine[iChannel+2].c_str()); - LauParameter scattParam(scattConst); + LauParameter scattParam(Form("KM_%s_fScatteringConst_%i_%i",name_.Data(),scattIndex,iChannel),scattConst); fScattering_[scattIndex][iChannel] = scattParam; cout<<"Added scattering parameter f("<& theLine, std::vector& a) +{ + + // Store the orbital angular momentum for each channel + // Each line will contain: angularmomentum OrbitalAngularMomentumPerChannel + + // Check that the line has nChannels_ + 1 strings + Int_t nWords = static_cast(theLine.size()); + Int_t nExpect = nChannels_ + 1; + + if (nWords == nExpect) { + + for (Int_t iChannel = 0; iChannel < nChannels_; iChannel++) { + + Int_t angularMomentum = std::atoi(theLine[iChannel+1].c_str()); + L_[iChannel] = angularMomentum; + + cout<<"Defined K-matrix orbital angular momentum "<Exit(EXIT_FAILURE); + } + } } +} + +void LauKMatrixPropagator::storeRadii(const std::vector& theLine) +{ + + // Store the characteristic radii (measured in GeV^{-1}) + // Each line will contain: Radii RadiusConstantsPerChannel + + // Check that the line has nChannels_ + 1 strings + Int_t nWords = static_cast(theLine.size()); + Int_t nExpect = nChannels_ + 1; + + if (nWords == nExpect) { + + for (Int_t iChannel = 0; iChannel < nChannels_; iChannel++) { + + Double_t radiusConst = std::atof(theLine[iChannel+1].c_str()); + radii_[iChannel] = radiusConst; + + cout<<"Added K-matrix radius "<& theLine, std::vector& a) +{ + + // Store the parameter of the barrier factor + // Each line will contain: barrierfactorparameter ParameterValuePerchannel + + // Check that the line has nChannels_ + 1 strings + Int_t nWords = static_cast(theLine.size()); + Int_t nExpect = nChannels_ + 1; + if (nWords == nExpect) { + + for (Int_t iChannel = 0; iChannel < nChannels_; iChannel++) { + + Double_t parameterValue = std::atof(theLine[iChannel+1].c_str()); + a[iChannel] = parameterValue; + + cout<<"Added K-matrix barrier factor parameter value "<= nPoles_) ) { + std::cerr << "ERROR from LauKMatrixPropagator::getPoleMassSqParameter(). Invalid pole." << std::endl; + gSystem->Exit(EXIT_FAILURE); + } + + return mSqPoles_[poleIndex]; +} + +Double_t LauKMatrixPropagator::getCouplingConstant(const Int_t poleIndex, const Int_t channelIndex) const { if (parametersSet_ == kFALSE) {return 0.0;} @@ -663,8 +821,20 @@ } +LauParameter& LauKMatrixPropagator::getCouplingParameter(const Int_t poleIndex, const Int_t channelIndex) +{ + + if ( (parametersSet_ == kFALSE) || (poleIndex < 0 || poleIndex >= nPoles_) || (channelIndex < 0 || channelIndex >= nChannels_) ) { + std::cerr << "ERROR from LauKMatrixPropagator::getCouplingParameter(). Invalid coupling." << std::endl; + gSystem->Exit(EXIT_FAILURE); + } -Double_t LauKMatrixPropagator::getScatteringConstant(Int_t channel1Index, Int_t channel2Index) const + //std::cout << "Minvalue + range for " << poleIndex << ", " << channelIndex << ": " << gCouplings_[poleIndex][channelIndex].minValue() << " => + " << gCouplings_[poleIndex][channelIndex].range() << + // " and init value: " << gCouplings_[poleIndex][channelIndex].initValue() << std::endl; + return gCouplings_[poleIndex][channelIndex]; +} + +Double_t LauKMatrixPropagator::getScatteringConstant(const Int_t channel1Index, const Int_t channel2Index) const { if (parametersSet_ == kFALSE) {return 0.0;} @@ -676,7 +846,18 @@ } -Double_t LauKMatrixPropagator::calcSVPTerm(Double_t s, Double_t s0) const +LauParameter& LauKMatrixPropagator::getScatteringParameter(const Int_t channel1Index, const Int_t channel2Index) +{ + + if ( (parametersSet_ == kFALSE) || (channel1Index < 0 || channel1Index >= nChannels_) || (channel2Index < 0 || channel2Index >= nChannels_) ) { + std::cerr << "ERROR from LauKMatrixPropagator::getScatteringParameter(). Invalid chanel index." << std::endl; + gSystem->Exit(EXIT_FAILURE); + } + + return fScattering_[channel1Index][channel2Index]; +} + +Double_t LauKMatrixPropagator::calcSVPTerm(const Double_t s, const Double_t s0) const { if (parametersSet_ == kFALSE) {return 0.0;} @@ -686,27 +867,27 @@ Double_t deltaS = s - s0; if (TMath::Abs(deltaS) > 1.0e-6) { result = (mSq0_.unblindValue() - s0)/deltaS; - } + } return result; } -void LauKMatrixPropagator::updateScattSVPTerm(Double_t s) +void LauKMatrixPropagator::updateScattSVPTerm(const Double_t s) { // Update the scattering "slowly-varying part" (SVP) Double_t s0Scatt = s0Scatt_.unblindValue(); scattSVP_ = this->calcSVPTerm(s, s0Scatt); } -void LauKMatrixPropagator::updateProdSVPTerm(Double_t s) +void LauKMatrixPropagator::updateProdSVPTerm(const Double_t s) { // Update the production "slowly-varying part" (SVP) Double_t s0Prod = s0Prod_.unblindValue(); prodSVP_ = this->calcSVPTerm(s, s0Prod); } -void LauKMatrixPropagator::updateAdlerZeroFactor(Double_t s) +void LauKMatrixPropagator::updateAdlerZeroFactor(const Double_t s) { // Calculate the multiplicative factor containing various Adler zero @@ -717,11 +898,79 @@ Double_t deltaS = s - sA0Val; if (TMath::Abs(deltaS) > 1e-6) { adlerZeroFactor_ = (s - sAConst_)*(1.0 - sA0Val)/deltaS; - } + } + +} + +void LauKMatrixPropagator::calcGammaMatrix(const Double_t s) +{ + // Calculate the gamma angular momentum barrier matrix + // for the given invariant mass squared quantity, s. + + // Initialise all entries to zero + GammaMatrix_.Zero(); + + Double_t gamma(0.0); + + for (Int_t iChannel (0); iChannel < nChannels_; ++iChannel) { + + LauKMatrixPropagator::KMatrixChannels phaseSpaceIndex = phaseSpaceTypes_[iChannel]; + + if ( L_[iChannel] != 0 ) { + gamma = this->calcGamma(iChannel,s,phaseSpaceIndex); + } else { + gamma = 1.0; // S-wave + } + + if (verbose_) { + cout<<"GammaMatrix("<Exit(EXIT_FAILURE); + } + + gamma = pow(q,L_[iCh]); + if (includeBWBarrierFactor_) + { + gamma /= pow( q*q + gamAInvRadSq_[iCh] , L_[iCh]/2. ); + } + + if(verbose_) + { + std::cout << "In LauKMatrixPropagator::calcGamma(iCh=" << iCh << ", s=" << s << ", prop). "; + std::cout << "|q(iCh="<calcPiPiRho(s); - } else if (phaseSpaceIndex == LauKMatrixPropagator::KK) { + } else if (phaseSpaceIndex == LauKMatrixPropagator::KMatrixChannels::KK) { rho = this->calcKKRho(s); - } else if (phaseSpaceIndex == LauKMatrixPropagator::FourPi) { + } else if (phaseSpaceIndex == LauKMatrixPropagator::KMatrixChannels::FourPi) { rho = this->calcFourPiRho(s); - } else if (phaseSpaceIndex == LauKMatrixPropagator::EtaEta) { + } else if (phaseSpaceIndex == LauKMatrixPropagator::KMatrixChannels::EtaEta) { rho = this->calcEtaEtaRho(s); - } else if (phaseSpaceIndex == LauKMatrixPropagator::EtaEtaP) { + } else if (phaseSpaceIndex == LauKMatrixPropagator::KMatrixChannels::EtaEtaP) { rho = this->calcEtaEtaPRho(s); - } else if (phaseSpaceIndex == LauKMatrixPropagator::KPi) { + } else if (phaseSpaceIndex == LauKMatrixPropagator::KMatrixChannels::KPi) { rho = this->calcKPiRho(s); - } else if (phaseSpaceIndex == LauKMatrixPropagator::KEtaP) { + } else if (phaseSpaceIndex == LauKMatrixPropagator::KMatrixChannels::KEtaP) { rho = this->calcKEtaPRho(s); - } else if (phaseSpaceIndex == LauKMatrixPropagator::KThreePi) { + } else if (phaseSpaceIndex == LauKMatrixPropagator::KMatrixChannels::KThreePi) { rho = this->calcKThreePiRho(s); + } else if (phaseSpaceIndex == LauKMatrixPropagator::KMatrixChannels::D0K) { + rho = this->calcD0KRho(s); + } else if (phaseSpaceIndex == LauKMatrixPropagator::KMatrixChannels::Dstar0K) { + rho = this->calcDstar0KRho(s); } if (verbose_) { @@ -763,13 +1015,49 @@ } ReRhoMatrix_(iChannel, iChannel) = rho.re(); - ImRhoMatrix_(iChannel, iChannel) = rho.im(); + ImRhoMatrix_(iChannel, iChannel) = rho.im(); } } -LauComplex LauKMatrixPropagator::calcPiPiRho(Double_t s) const +LauComplex LauKMatrixPropagator::calcD0KRho(const Double_t s) const +{ + // Calculate the D0K+ phase space factor + LauComplex rho(0.0, 0.0); + if (TMath::Abs(s) < 1e-10) {return rho;} + + Double_t sqrtTerm1 = (-mD0KSumSq_/s) + 1.0; + Double_t sqrtTerm2 = (-mD0KDiffSq_/s) + 1.0; + Double_t sqrtTerm = sqrtTerm1*sqrtTerm2; + if (sqrtTerm < 0.0) { + rho.setImagPart( TMath::Sqrt(-sqrtTerm) ); + } else { + rho.setRealPart( TMath::Sqrt(sqrtTerm) ); + } + + return rho; +} + +LauComplex LauKMatrixPropagator::calcDstar0KRho(const Double_t s) const +{ + // Calculate the Dstar0K+ phase space factor + LauComplex rho(0.0, 0.0); + if (TMath::Abs(s) < 1e-10) {return rho;} + + Double_t sqrtTerm1 = (-mDstar0KSumSq_/s) + 1.0; + Double_t sqrtTerm2 = (-mDstar0KDiffSq_/s) + 1.0; + Double_t sqrtTerm = sqrtTerm1*sqrtTerm2; + if (sqrtTerm < 0.0) { + rho.setImagPart( TMath::Sqrt(-sqrtTerm) ); + } else { + rho.setRealPart( TMath::Sqrt(sqrtTerm) ); + } + + return rho; +} + +LauComplex LauKMatrixPropagator::calcPiPiRho(const Double_t s) const { // Calculate the pipi phase space factor LauComplex rho(0.0, 0.0); @@ -785,7 +1073,7 @@ return rho; } -LauComplex LauKMatrixPropagator::calcKKRho(Double_t s) const +LauComplex LauKMatrixPropagator::calcKKRho(const Double_t s) const { // Calculate the KK phase space factor LauComplex rho(0.0, 0.0); @@ -801,33 +1089,33 @@ return rho; } -LauComplex LauKMatrixPropagator::calcFourPiRho(Double_t s) const +LauComplex LauKMatrixPropagator::calcFourPiRho(const Double_t s) const { // Calculate the 4pi phase space factor. This uses a 6th-order polynomial - // parameterisation that approximates the multi-body phase space double integral - // defined in Eq 4 of the A&S paper hep-ph/0204328. This form agrees with the - // BaBar model (another 6th order polynomial from s^4 down to 1/s^2), but avoids the - // exponential increase at small values of s (~< 0.1) arising from 1/s and 1/s^2. - // Eq 4 is evaluated for each value of s by assuming incremental steps of 1e-3 GeV^2 - // for s1 and s2, the invariant energy squared of each of the di-pion states, - // with the integration limits of s1 = (2*mpi)^2 to (sqrt(s) - 2*mpi)^2 and - // s2 = (2*mpi)^2 to (sqrt(s) - sqrt(s1))^2. The mass M of the rho is taken to be - // 0.775 GeV and the energy-dependent width of the 4pi system - // Gamma(s) = gamma_0*rho1^3(s), where rho1 = sqrt(1.0 - 4*mpiSq/s) and gamma_0 is - // the "width" of the 4pi state at s = 1, which is taken to be 0.3 GeV - // (~75% of the total width from PDG estimates of the f0(1370) -> 4pi state). - // The normalisation term rho_0 is found by ensuring that the phase space integral - // at s = 1 is equal to sqrt(1.0 - 16*mpiSq/s). Note that the exponent for this - // factor in hep-ph/0204328 is wrong; it should be 0.5, i.e. sqrt, not n = 1 to 5. - // Plotting the value of this double integral as a function of s can then be fitted - // to a 6th-order polynomial (for s < 1), which is the result used below + // parameterisation that approximates the multi-body phase space double integral + // defined in Eq 4 of the A&S paper hep-ph/0204328. This form agrees with the + // BaBar model (another 6th order polynomial from s^4 down to 1/s^2), but avoids the + // exponential increase at small values of s (~< 0.1) arising from 1/s and 1/s^2. + // Eq 4 is evaluated for each value of s by assuming incremental steps of 1e-3 GeV^2 + // for s1 and s2, the invariant energy squared of each of the di-pion states, + // with the integration limits of s1 = (2*mpi)^2 to (sqrt(s) - 2*mpi)^2 and + // s2 = (2*mpi)^2 to (sqrt(s) - sqrt(s1))^2. The mass M of the rho is taken to be + // 0.775 GeV and the energy-dependent width of the 4pi system + // Gamma(s) = gamma_0*rho1^3(s), where rho1 = sqrt(1.0 - 4*mpiSq/s) and gamma_0 is + // the "width" of the 4pi state at s = 1, which is taken to be 0.3 GeV + // (~75% of the total width from PDG estimates of the f0(1370) -> 4pi state). + // The normalisation term rho_0 is found by ensuring that the phase space integral + // at s = 1 is equal to sqrt(1.0 - 16*mpiSq/s). Note that the exponent for this + // factor in hep-ph/0204328 is wrong; it should be 0.5, i.e. sqrt, not n = 1 to 5. + // Plotting the value of this double integral as a function of s can then be fitted + // to a 6th-order polynomial (for s < 1), which is the result used below LauComplex rho(0.0, 0.0); if (TMath::Abs(s) < 1e-10) {return rho;} if (s <= 1.0) { - Double_t rhoTerm = ((1.07885*s + 0.13655)*s - 0.29744)*s - 0.20840; - rhoTerm = ((rhoTerm*s + 0.13851)*s - 0.01933)*s + 0.00051; + Double_t rhoTerm = ((1.07885*s + 0.13655)*s - 0.29744)*s - 0.20840; + rhoTerm = ((rhoTerm*s + 0.13851)*s - 0.01933)*s + 0.00051; // For some values of s (below 2*mpi), this term is a very small // negative number. Check for this and set the rho term to zero. if (rhoTerm < 0.0) {rhoTerm = 0.0;} @@ -839,7 +1127,7 @@ return rho; } -LauComplex LauKMatrixPropagator::calcEtaEtaRho(Double_t s) const +LauComplex LauKMatrixPropagator::calcEtaEtaRho(const Double_t s) const { // Calculate the eta-eta phase space factor LauComplex rho(0.0, 0.0); @@ -855,18 +1143,18 @@ return rho; } -LauComplex LauKMatrixPropagator::calcEtaEtaPRho(Double_t s) const +LauComplex LauKMatrixPropagator::calcEtaEtaPRho(const Double_t s) const { // Calculate the eta-eta' phase space factor. Note that the - // mass difference term m_eta - m_eta' is not included, - // since this corresponds to a "t or u-channel crossing", - // which means that we cannot simply analytically continue - // this part of the phase space factor below threshold, which - // we can do for s-channel contributions. This is actually an - // unsolved problem, e.g. see Guo et al 1409.8652, and - // Danilkin et al 1409.7708. Anisovich and Sarantsev in - // hep-ph/0204328 "solve" this issue by setting the mass - // difference term to unity, which is what we do here... + // mass difference term m_eta - m_eta' is not included, + // since this corresponds to a "t or u-channel crossing", + // which means that we cannot simply analytically continue + // this part of the phase space factor below threshold, which + // we can do for s-channel contributions. This is actually an + // unsolved problem, e.g. see Guo et al 1409.8652, and + // Danilkin et al 1409.7708. Anisovich and Sarantsev in + // hep-ph/0204328 "solve" this issue by setting the mass + // difference term to unity, which is what we do here... LauComplex rho(0.0, 0.0); if (TMath::Abs(s) < 1e-10) {return rho;} @@ -875,14 +1163,14 @@ if (sqrtTerm < 0.0) { rho.setImagPart( TMath::Sqrt(-sqrtTerm) ); } else { - rho.setRealPart( TMath::Sqrt(sqrtTerm) ); + rho.setRealPart( TMath::Sqrt(sqrtTerm) ); } return rho; } -LauComplex LauKMatrixPropagator::calcKPiRho(Double_t s) const +LauComplex LauKMatrixPropagator::calcKPiRho(const Double_t s) const { // Calculate the K-pi phase space factor LauComplex rho(0.0, 0.0); @@ -900,7 +1188,7 @@ return rho; } -LauComplex LauKMatrixPropagator::calcKEtaPRho(Double_t s) const +LauComplex LauKMatrixPropagator::calcKEtaPRho(const Double_t s) const { // Calculate the K-eta' phase space factor LauComplex rho(0.0, 0.0); @@ -918,7 +1206,7 @@ return rho; } -LauComplex LauKMatrixPropagator::calcKThreePiRho(Double_t s) const +LauComplex LauKMatrixPropagator::calcKThreePiRho(const Double_t s) const { // Calculate the Kpipipi + multimeson phase space factor. // Use the simplest definition in hep-ph/9705401 (Eq 14), which is the form @@ -943,51 +1231,49 @@ return rho; } -Bool_t LauKMatrixPropagator::checkPhaseSpaceType(Int_t phaseSpaceInt) const +Bool_t LauKMatrixPropagator::checkPhaseSpaceType(const Int_t phaseSpaceInt) const { Bool_t passed(kFALSE); - if (phaseSpaceInt >= 1 && phaseSpaceInt < LauKMatrixPropagator::TotChannels) { + if (phaseSpaceInt >= 1 && phaseSpaceInt < static_cast(LauKMatrixPropagator::KMatrixChannels::TotChannels)) { passed = kTRUE; } return passed; } -LauComplex LauKMatrixPropagator::getTransitionAmp(Double_t s, Int_t channel) +LauComplex LauKMatrixPropagator::getTransitionAmp(const Double_t s, const Int_t channel) { - // Get the complex (unitary) transition amplitude T for the given channel + // Get the complex (unitary) transition amplitude T for the given channel LauComplex TAmp(0.0, 0.0); - channel -= 1; - if (channel < 0 || channel >= nChannels_) {return TAmp;} + if (channel <= 0 || channel > nChannels_) {return TAmp;} - this->getTMatrix(s); + this->getTMatrix(s); - TAmp.setRealPart(ReTMatrix_[index_][channel]); - TAmp.setImagPart(ImTMatrix_[index_][channel]); + TAmp.setRealPart(ReTMatrix_[index_][channel-1]); + TAmp.setImagPart(ImTMatrix_[index_][channel-1]); return TAmp; } -LauComplex LauKMatrixPropagator::getPhaseSpaceTerm(Double_t s, Int_t channel) +LauComplex LauKMatrixPropagator::getPhaseSpaceTerm(const Double_t s, const Int_t channel) { - // Get the complex (unitary) transition amplitude T for the given channel + // Get the complex (unitary) transition amplitude T for the given channel LauComplex rho(0.0, 0.0); - channel -= 1; - if (channel < 0 || channel >= nChannels_) {return rho;} + if (channel <= 0 || channel > nChannels_) {return rho;} // If s has changed from the previous value, recalculate rho if (TMath::Abs(s - previousS_) > 1e-6*s) { - this->calcRhoMatrix(s); + this->calcRhoMatrix(s); } - rho.setRealPart(ReRhoMatrix_[channel][channel]); - rho.setImagPart(ImRhoMatrix_[channel][channel]); + rho.setRealPart(ReRhoMatrix_[channel][channel-1]); + rho.setImagPart(ImRhoMatrix_[channel][channel-1]); return rho; @@ -995,11 +1281,11 @@ void LauKMatrixPropagator::getTMatrix(const LauKinematics* kinematics) { - // Find the unitary T matrix, where T = [sqrt(rho)]^{*} T_hat sqrt(rho), - // and T_hat = (I - i K rho)^-1 * K is the Lorentz-invariant T matrix, - // which has phase-space factors included (rho). This function is not - // needed to calculate the K-matrix amplitudes, but allows us - // to check the variation of T as a function of s (kinematics) + // Find the unitary T matrix, where T = [sqrt(rho)]^{*} T_hat sqrt(rho), + // and T_hat = (I - i K rho)^-1 * K is the Lorentz-invariant T matrix, + // which has phase-space factors included (rho). This function is not + // needed to calculate the K-matrix amplitudes, but allows us + // to check the variation of T as a function of s (kinematics) if (!kinematics) {return;} @@ -1020,25 +1306,25 @@ } -void LauKMatrixPropagator::getTMatrix(Double_t s) +void LauKMatrixPropagator::getTMatrix(const Double_t s) { - // Find the unitary transition T matrix, where - // T = [sqrt(rho)]^{*} T_hat sqrt(rho), and - // T_hat = (I - i K rho)^-1 * K is the Lorentz-invariant T matrix, - // which has phase-space factors included (rho). Note that the first - // sqrt of the rho matrix is complex conjugated. + // Find the unitary transition T matrix, where + // T = [sqrt(rho)]^{*} T_hat sqrt(rho), and + // T_hat = (I - i K rho)^-1 * K is the Lorentz-invariant T matrix, + // which has phase-space factors included (rho). Note that the first + // sqrt of the rho matrix is complex conjugated. - // This function is not needed to calculate the K-matrix amplitudes, but - // allows us to check the variation of T as a function of s (kinematics) + // This function is not needed to calculate the K-matrix amplitudes, but + // allows us to check the variation of T as a function of s (kinematics) - // Initialse the real and imaginary parts of the T matrix to zero - ReTMatrix_.Zero(); ImTMatrix_.Zero(); + // Initialse the real and imaginary parts of the T matrix to zero + ReTMatrix_.Zero(); ImTMatrix_.Zero(); - if (parametersSet_ == kFALSE) {return;} + if (parametersSet_ == kFALSE) {return;} - // Update K, rho and the propagator (I - i K rho)^-1 - this->updatePropagator(s); + // Update K, rho and the propagator (I - i K rho)^-1 + this->updatePropagator(s); // Find the real and imaginary T_hat matrices TMatrixD THatReal = realProp_*ScattKMatrix_; @@ -1075,46 +1361,45 @@ void LauKMatrixPropagator::getSqrtRhoMatrix() { - // Find the square root of the (current) phase space matrix so that - // we can find T = [sqrt(rho)}^{*} T_hat sqrt(rho), where T_hat is the - // Lorentz-invariant T matrix = (I - i K rho)^-1 * K; note that the first - // sqrt of rho matrix is complex conjugated + // Find the square root of the (current) phase space matrix so that + // we can find T = [sqrt(rho)}^{*} T_hat sqrt(rho), where T_hat is the + // Lorentz-invariant T matrix = (I - i K rho)^-1 * K; note that the first + // sqrt of rho matrix is complex conjugated - // If rho = rho_i + i rho_r = a + i b, then sqrt(rho) = c + i d, where - // c = sqrt(0.5*(r+a)) and d = sqrt(0.5(r-a)), where r = sqrt(a^2 + b^2). - // Since rho is diagonal, then the square root of rho will also be diagonal, - // with its real and imaginary matrix elements equal to c and d, respectively + // If rho = rho_i + i rho_r = a + i b, then sqrt(rho) = c + i d, where + // c = sqrt(0.5*(r+a)) and d = sqrt(0.5(r-a)), where r = sqrt(a^2 + b^2). + // Since rho is diagonal, then the square root of rho will also be diagonal, + // with its real and imaginary matrix elements equal to c and d, respectively - // Initialise the real and imaginary parts of the square root of - // the rho matrix to zero - ReSqrtRhoMatrix_.Zero(); ImSqrtRhoMatrix_.Zero(); + // Initialise the real and imaginary parts of the square root of + // the rho matrix to zero + ReSqrtRhoMatrix_.Zero(); ImSqrtRhoMatrix_.Zero(); - for (Int_t iChannel (0); iChannel < nChannels_; ++iChannel) { + for (Int_t iChannel (0); iChannel < nChannels_; ++iChannel) { - Double_t realRho = ReRhoMatrix_[iChannel][iChannel]; - Double_t imagRho = ImRhoMatrix_[iChannel][iChannel]; + Double_t realRho = ReRhoMatrix_[iChannel][iChannel]; + Double_t imagRho = ImRhoMatrix_[iChannel][iChannel]; Double_t rhoMag = sqrt(realRho*realRho + imagRho*imagRho); - Double_t rhoSum = rhoMag + realRho; - Double_t rhoDiff = rhoMag - realRho; + Double_t rhoSum = rhoMag + realRho; + Double_t rhoDiff = rhoMag - realRho; - Double_t reSqrtRho(0.0), imSqrtRho(0.0); - if (rhoSum > 0.0) {reSqrtRho = sqrt(0.5*rhoSum);} + Double_t reSqrtRho(0.0), imSqrtRho(0.0); + if (rhoSum > 0.0) {reSqrtRho = sqrt(0.5*rhoSum);} if (rhoDiff > 0.0) {imSqrtRho = sqrt(0.5*rhoDiff);} - ReSqrtRhoMatrix_[iChannel][iChannel] = reSqrtRho; - ImSqrtRhoMatrix_[iChannel][iChannel] = imSqrtRho; - - } + ReSqrtRhoMatrix_[iChannel][iChannel] = reSqrtRho; + ImSqrtRhoMatrix_[iChannel][iChannel] = imSqrtRho; + } } -LauComplex LauKMatrixPropagator::getTHat(Double_t s, Int_t channel) { +LauComplex LauKMatrixPropagator::getTHat(const Double_t s, const Int_t channel) { + + LauComplex THat(0.0, 0.0); - LauComplex THat(0.0, 0.0); - channel -= 1; - if (channel < 0 || channel >= nChannels_) {return THat;} + if (channel <= 0 || channel > nChannels_) {return THat;} this->updatePropagator(s); @@ -1124,8 +1409,8 @@ THatImag -= negImagProp_*ScattKMatrix_; // Return the specific THat component - THat.setRealPart(THatReal[index_][channel]); - THat.setImagPart(THatImag[index_][channel]); + THat.setRealPart(THatReal[index_][channel-1]); + THat.setImagPart(THatImag[index_][channel-1]); return THat; diff --git a/src/LauMergeDataFiles.cc b/src/LauMergeDataFiles.cc --- a/src/LauMergeDataFiles.cc +++ b/src/LauMergeDataFiles.cc @@ -22,6 +22,10 @@ Thomas Latham */ +/*! \file LauMergeDataFiles.cc + \brief File containing implementation of LauMergeDataFiles class. + */ + #include "LauMergeDataFiles.hh" #include diff --git a/src/LauPolNR.cc b/src/LauPolNR.cc --- a/src/LauPolNR.cc +++ b/src/LauPolNR.cc @@ -62,6 +62,7 @@ this->setOmega( omega ); TString name = this->getResonanceName(); + name = name.ReplaceAll("+",""); // strip off any trailing ++ if (name.EndsWith("0",TString::kExact)){ order_ = 0; } @@ -77,7 +78,8 @@ else{ std::cerr << "ERROR in LauPolNR::initialise : Resonance order unknown (known orders : 0, 1, 2 and 3)" << std::endl; std::cerr << " : Defaulting to 0." << std::endl; - } + } + std::cout << "Setting order of LauPolNR as " << order_ << std::endl; } LauComplex LauPolNR::resAmp(Double_t mass, Double_t spinTerm) diff --git a/src/LauRelBreitWignerRes.cc b/src/LauRelBreitWignerRes.cc --- a/src/LauRelBreitWignerRes.cc +++ b/src/LauRelBreitWignerRes.cc @@ -37,9 +37,6 @@ LauRelBreitWignerRes::LauRelBreitWignerRes(LauResonanceInfo* resInfo, const Int_t resPairAmpInt, const LauDaughters* daughters) : LauAbsResonance(resInfo, resPairAmpInt, daughters), q0_(0.0), - p0_(0.0), - pstar0_(0.0), - erm0_(0.0), resMass_(0.0), resMassSq_(0.0), resWidth_(0.0), @@ -51,8 +48,7 @@ mDaugDiffSq_(0.0), mParentSq_(0.0), mBachSq_(0.0), - FR0_(1.0), - FP0_(1.0) + FR0_(1.0) { } @@ -88,7 +84,7 @@ // that are below threshold Double_t effResMass = resMass_; Double_t effResMassSq = resMassSq_; - if (resMassSq_ - mDaugSumSq_ < 0.0 || resMass_ > massParent - massBachelor){ + if ( resMassSq_ - mDaugSumSq_ < 0.0 ) { Double_t minMass = mDaugSum_; Double_t maxMass = massParent - massBachelor; Double_t tanhTerm = std::tanh( (resMass_ - ((minMass + maxMass)/2))/(maxMass-minMass)); @@ -107,56 +103,12 @@ q0_ = 0.0; } - // Momentum of the bachelor particle in the resonance rest frame - // when resonance mass = rest-mass value, m_0 (PDG value) - Double_t eBach = (mParentSq_ - effResMassSq - mBachSq_)/(2.0*effResMass); - Double_t termBach = eBach*eBach - mBachSq_; - if ( eBach<0.0 || termBach<0.0 ) { - p0_ = 0.0; - } else { - p0_ = TMath::Sqrt( termBach ); - } - - // Momentum of the bachelor particle in the parent rest frame - // when resonance mass = rest-mass value, m_0 (PDG value) - Double_t eStarBach = (mParentSq_ + mBachSq_ - effResMassSq)/(2.0*massParent); - Double_t termStarBach = eStarBach*eStarBach - mBachSq_; - if ( eStarBach<0.0 || termStarBach<0.0 ) { - pstar0_ = 0.0; - } else { - pstar0_ = TMath::Sqrt( termStarBach ); - } - - // Covariant factor when resonance mass = rest-mass value, m_0 (PDF value) - erm0_ = (mParentSq_ + effResMassSq - mBachSq_)/(2.0*massParent*effResMass); - this->calcCovFactor( erm0_ ); - - // Calculate the Blatt-Weisskopf form factor for the case when m = m_0 + // Calculate the resonance Blatt-Weisskopf form factor for the case when m = m_0 FR0_ = 1.0; - FP0_ = 1.0; - const Int_t resSpin = this->getSpin(); - if ( resSpin > 0 ) { + if ( this->getSpin() > 0 ) { const LauBlattWeisskopfFactor* resBWFactor = this->getResBWFactor(); - const LauBlattWeisskopfFactor* parBWFactor = this->getParBWFactor(); - FR0_ = (resBWFactor!=0) ? resBWFactor->calcFormFactor(q0_) : 1.0; - switch ( parBWFactor->getRestFrame() ) { - case LauBlattWeisskopfFactor::ResonanceFrame: - FP0_ = (parBWFactor!=0) ? parBWFactor->calcFormFactor(p0_) : 1.0; - break; - case LauBlattWeisskopfFactor::ParentFrame: - FP0_ = (parBWFactor!=0) ? parBWFactor->calcFormFactor(pstar0_) : 1.0; - break; - case LauBlattWeisskopfFactor::Covariant: - { - Double_t covFactor = this->getCovFactor(); - if ( resSpin > 2 ) { - covFactor = TMath::Power( covFactor, 1.0/resSpin ); - } else if ( resSpin == 2 ) { - covFactor = TMath::Sqrt( covFactor ); - } - FP0_ = (parBWFactor!=0) ? parBWFactor->calcFormFactor(pstar0_*covFactor) : 1.0; - break; - } + if ( resBWFactor != nullptr ) { + FR0_ = resBWFactor->calcFormFactor(q0_); } } } @@ -208,30 +160,33 @@ Double_t fFactorB(1.0); if ( resSpin > 0 ) { const LauBlattWeisskopfFactor* resBWFactor = this->getResBWFactor(); + if ( resBWFactor != nullptr ) { + fFactorR = resBWFactor->calcFormFactor(q); + } + const LauBlattWeisskopfFactor* parBWFactor = this->getParBWFactor(); - fFactorR = (resBWFactor!=0) ? resBWFactor->calcFormFactor(q) : 1.0; - switch ( parBWFactor->getRestFrame() ) { - case LauBlattWeisskopfFactor::ResonanceFrame: - fFactorB = (parBWFactor!=0) ? parBWFactor->calcFormFactor(p) : 1.0; - break; - case LauBlattWeisskopfFactor::ParentFrame: - fFactorB = (parBWFactor!=0) ? parBWFactor->calcFormFactor(pstar) : 1.0; - break; - case LauBlattWeisskopfFactor::Covariant: + if ( parBWFactor != nullptr ) { + switch ( parBWFactor->getRestFrame() ) { + case LauBlattWeisskopfFactor::ResonanceFrame: + fFactorB = parBWFactor->calcFormFactor(p); + break; + case LauBlattWeisskopfFactor::ParentFrame: + fFactorB = parBWFactor->calcFormFactor(pstar); + break; + case LauBlattWeisskopfFactor::Covariant: { - Double_t covFactor = this->getCovFactor(); - if ( resSpin > 2 ) { - covFactor = TMath::Power( covFactor, 1.0/resSpin ); - } else if ( resSpin == 2 ) { - covFactor = TMath::Sqrt( covFactor ); - } - fFactorB = (parBWFactor!=0) ? parBWFactor->calcFormFactor(pstar*covFactor) : 1.0; - break; + Double_t covFactor = this->getCovFactor(); + if ( resSpin > 2 ) { + covFactor = TMath::Power( covFactor, 1.0/resSpin ); + } else if ( resSpin == 2 ) { + covFactor = TMath::Sqrt( covFactor ); + } + fFactorB = parBWFactor->calcFormFactor(pstar*covFactor); + break; } + } } } - const Double_t fFactorRRatio = fFactorR/FR0_; - const Double_t fFactorBRatio = fFactorB/FP0_; // If ignoreMomenta is set, set the total width simply as the pole width, and do // not include any momentum-dependent barrier factors (set them to unity) @@ -251,6 +206,8 @@ qTerm = TMath::Power(qRatio, 2.0*resSpin + 1.0); } + const Double_t fFactorRRatio = fFactorR/FR0_; + totWidth = resWidth*qTerm*(resMass/mass)*fFactorRRatio*fFactorRRatio; } @@ -266,7 +223,7 @@ // Include Blatt-Weisskopf barrier factors if (!this->ignoreBarrierScaling()) { - scale *= fFactorRRatio*fFactorBRatio; + scale *= fFactorR * fFactorB; } resAmplitude.rescale(scale); diff --git a/src/LauRescatterThreshold.cc b/src/LauRescatterThreshold.cc new file mode 100644 --- /dev/null +++ b/src/LauRescatterThreshold.cc @@ -0,0 +1,267 @@ + +/* +Copyright 2004 University of Warwick + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Laura++ package authors: +John Back +Paul Harrison +Thomas Latham +*/ + +/*! \file LauRescatterThreshold.cc + \brief File containing implementation of LauRescatterThreshold class. +*/ + +#include +#include "LauRescatterThreshold.hh" +#include "LauDaughters.hh" +#include "LauParameter.hh" +#include "LauResonanceInfo.hh" + +ClassImp(LauRescatterThreshold) + + +LauRescatterThreshold::LauRescatterThreshold(LauResonanceInfo* resInfo, const Int_t resPairAmpInt, const LauDaughters* daughters) : + LauAbsResonance(resInfo, resPairAmpInt, daughters), + _c11(0), + _c12(0), + _rescatterChannel_massDaug1(0), + _rescatterChannel_massDaug2(0), + forceLegendre_(kTRUE) +{ + TString baseParName = this->getSanitisedName(); + + TString parName = baseParName+"_c11"; + _c11 = resInfo->getExtraParameter( parName ); + if ( _c11 == 0 ) { + _c11 = new LauParameter( parName, 0.0, -1.0, 1.0, kTRUE ); + _c11->secondStage(kTRUE); + resInfo->addExtraParameter( _c11 ); + } + + parName = baseParName+"_c12"; + _c12 = resInfo->getExtraParameter( parName ); + if ( _c12 == 0 ) { + _c12 = new LauParameter( parName, 0.0, -2.0, 10.0, kTRUE ); + _c12->secondStage(kTRUE); + resInfo->addExtraParameter( _c12 ); + } + + parName = baseParName+"_rescatterChannel_massDaug1"; + _rescatterChannel_massDaug1 = resInfo->getExtraParameter( parName ); + if ( _rescatterChannel_massDaug1 == 0 ) { + _rescatterChannel_massDaug1 = new LauParameter( parName, 0.0, 0.0, 10.0, kTRUE ); + _rescatterChannel_massDaug1->secondStage(kTRUE); + resInfo->addExtraParameter( _rescatterChannel_massDaug1 ); + } + + parName = baseParName+"_rescatterChannel_massDaug2"; + _rescatterChannel_massDaug2 = resInfo->getExtraParameter( parName ); + if ( _rescatterChannel_massDaug2 == 0 ) { + _rescatterChannel_massDaug2 = new LauParameter( parName, 0.0, 0.0, 10.0, kTRUE ); + _rescatterChannel_massDaug2->secondStage(kTRUE); + resInfo->addExtraParameter( _rescatterChannel_massDaug2 ); + } +} + +LauRescatterThreshold::~LauRescatterThreshold() +{ +} + +void LauRescatterThreshold::initialise() +{ + _massDaug1 = this->getMassDaug1(); + _massDaug2 = this->getMassDaug2(); +} + +LauComplex LauRescatterThreshold::resAmp(Double_t mass, Double_t spinTerm) +{ + // This function returns the complex dynamical amplitude for a rescattering channel near-threshold, + // given the invariant mass . + + // need: + // - coupling strength: near-threshold channel self-coupling [p0] + // - coupling strength: near-treshold channel -> observation channel [p1] + // - phasespace factor: near-threshold channel + // - mass + // - masses of near-threshold channel particles (will need to be set) [p2,p3] + // - masses of observation-channel particles (use daughters) + + //std::cout<< "Params - c11: " << _c11->value() << std::endl; + //std::cout<< "Params - c12: " << _c12->value() << std::endl; + //std::cout<< "Params - rescatterChannel_massDaug1: " << _rescatterChannel_massDaug1->value() << std::endl; + //std::cout<< "Params - rescatterChannel_massDaug2: " << _rescatterChannel_massDaug2->value() << std::endl; + + //std::cout<< "ResProps - massResDaug1: " << _massDaug1 << std::endl; + //std::cout<< "ResProps - massResDaug2: " << _massDaug2 << std::endl; + + //std::cout<< "Calc - mass: " << mass << std::endl; + //std::cout<< "Calc - spinTerm: " << spinTerm << std::endl; + + LauComplex phspFactor1 = phspFactor(mass,_rescatterChannel_massDaug1->value(),_rescatterChannel_massDaug2->value()); + LauComplex phspFactor2 = phspFactor(mass,_massDaug1,_massDaug2); + + //std::cout<< "Calc - phspFactor1: " << phspFactor1 << std::endl; + //std::cout<< "Calc - phspFactor2: " << phspFactor2 << std::endl; + + LauComplex num = LauComplex(-_c12->value(),0) / phspFactor2 ; + LauComplex im(0,1); + LauComplex den = LauComplex( _c11->value(),0) - im*phspFactor1 - im*LauComplex(_c12->value()*_c12->value(),0)/phspFactor2 ; + + LauComplex resAmplitude = num / den ; + + //std::cout<< "Calc - num: " << num << std::endl; + //std::cout<< "Calc - den: " << den << std::endl; + + //std::cout<< "Calc - amp before scale: " << resAmplitude << std::endl; + + resAmplitude.rescale(spinTerm); + + //std::cout<< "Calc - amp after scale: " << resAmplitude << std::endl; + + return resAmplitude; +} + +LauComplex LauRescatterThreshold::phspFactor(Double_t mass, Double_t m1, Double_t m2) +{ + LauComplex phspFactor(1,0); + Double_t _fact = (mass*mass - (m1+m2)*(m1+m2)) * (mass*mass - (m1-m2)*(m1-m2)); + if (_fact>0) phspFactor = LauComplex(std::sqrt(_fact),0); + else phspFactor = LauComplex(0,std::sqrt(-1*_fact)); + phspFactor.rescale(1./mass); + + return phspFactor; +} + +const std::vector& LauRescatterThreshold::getFloatingParameters() +{ + this->clearFloatingParameters(); + + if ( ! this->fix_c11() ) { + this->addFloatingParameter( _c11 ); + } + if ( ! this->fix_c12() ) { + this->addFloatingParameter( _c12 ); + } + if ( ! this->fix_rescatterChannel_massDaug1() ) { + this->addFloatingParameter( _rescatterChannel_massDaug1 ); + } + if ( ! this->fix_rescatterChannel_massDaug2() ) { + this->addFloatingParameter( _rescatterChannel_massDaug2 ); + } + + return this->getParameters(); +} + +void LauRescatterThreshold::setResonanceParameter(const TString& name, const Double_t value) +{ + // Set various parameters for the lineshape + if (name == "c11") { + this->set_c11(value); + std::cout << "INFO in LauRescatterThreshold::setResonanceParameter : Setting parameter c11 = " << this->get_c11() << std::endl; + } else if (name == "c12") { + this->set_c12(value); + std::cout << "INFO in LauRescatterThreshold::setResonanceParameter : Setting parameter c12 = " << this->get_c12() << std::endl; + } else if (name == "rescatterChannel_massDaug1") { + this->set_rescatterChannel_massDaug1(value); + std::cout << "INFO in LauRescatterThreshold::setResonanceParameter : Setting parameter rescatterChannel_massDaug1 = " << this->get_rescatterChannel_massDaug1() << std::endl; + } else if (name == "rescatterChannel_massDaug2") { + this->set_rescatterChannel_massDaug2(value); + std::cout << "INFO in LauRescatterThreshold::setResonanceParameter : Setting parameter rescatterChannel_massDaug2 = " << this->get_rescatterChannel_massDaug2() << std::endl; + } else { + std::cerr << "WARNING in LauRescatterThreshold::setResonanceParameter: Parameter name not reconised. No parameter changes made." << std::endl; + } +} + +void LauRescatterThreshold::floatResonanceParameter(const TString& name) +{ + if (name == "c11") { + if ( _c11->fixed() ) { + _c11->fixed( kFALSE ); + this->addFloatingParameter( _c11 ); + } else { + std::cerr << "WARNING in LauRescatterThreshold::floatResonanceParameter: Parameter already floating. No parameter changes made." << std::endl; + } + } else if (name == "c12") { + if ( _c12->fixed() ) { + _c12->fixed( kFALSE ); + this->addFloatingParameter( _c12 ); + } else { + std::cerr << "WARNING in LauRescatterThreshold::floatResonanceParameter: Parameter already floating. No parameter changes made." << std::endl; + } + } else if (name == "rescatterChannel_massDaug1") { + if ( _rescatterChannel_massDaug1->fixed() ) { + _rescatterChannel_massDaug1->fixed( kFALSE ); + this->addFloatingParameter( _rescatterChannel_massDaug1 ); + } else { + std::cerr << "WARNING in LauRescatterThreshold::floatResonanceParameter: Parameter already floating. No parameter changes made." << std::endl; + } + } else if (name == "rescatterChannel_massDaug2") { + if ( _rescatterChannel_massDaug2->fixed() ) { + _rescatterChannel_massDaug2->fixed( kFALSE ); + this->addFloatingParameter( _rescatterChannel_massDaug2 ); + } else { + std::cerr << "WARNING in LauRescatterThreshold::floatResonanceParameter: Parameter already floating. No parameter changes made." << std::endl; + } + } else { + std::cerr << "WARNING in LauRescatterThreshold::fixResonanceParameter: Parameter name not reconised. No parameter changes made." << std::endl; + } +} + +LauParameter* LauRescatterThreshold::getResonanceParameter(const TString& name) +{ + if (name == "c11") { + return _c11; + } else if (name == "c12") { + return _c12; + } else if (name == "rescatterChannel_massDaug1") { + return _rescatterChannel_massDaug1; + } else if (name == "rescatterChannel_massDaug2") { + return _rescatterChannel_massDaug2; + } else { + std::cerr << "WARNING in LauRescatterThreshold::getResonanceParameter: Parameter name not reconised." << std::endl; + return 0; + } +} + +void LauRescatterThreshold::set_c11(const Double_t c11) +{ + _c11->value( c11 ); + _c11->genValue( c11 ); + _c11->initValue( c11 ); +} + +void LauRescatterThreshold::set_c12(const Double_t c12) +{ + _c12->value( c12 ); + _c12->genValue( c12 ); + _c12->initValue( c12 ); +} + +void LauRescatterThreshold::set_rescatterChannel_massDaug1(const Double_t rescatterChannel_massDaug1) +{ + _rescatterChannel_massDaug1->value( rescatterChannel_massDaug1 ); + _rescatterChannel_massDaug1->genValue( rescatterChannel_massDaug1 ); + _rescatterChannel_massDaug1->initValue( rescatterChannel_massDaug1 ); +} + +void LauRescatterThreshold::set_rescatterChannel_massDaug2(const Double_t rescatterChannel_massDaug2) +{ + _rescatterChannel_massDaug2->value( rescatterChannel_massDaug2 ); + _rescatterChannel_massDaug2->genValue( rescatterChannel_massDaug2 ); + _rescatterChannel_massDaug2->initValue( rescatterChannel_massDaug2 ); +} \ No newline at end of file diff --git a/src/LauResonanceMaker.cc b/src/LauResonanceMaker.cc --- a/src/LauResonanceMaker.cc +++ b/src/LauResonanceMaker.cc @@ -30,6 +30,7 @@ #include "LauAbsResonance.hh" #include "LauBelleNR.hh" +#include "LauRescatterThreshold.hh" #include "LauBelleSymNR.hh" #include "LauBreitWignerRes.hh" #include "LauDabbaRes.hh" @@ -110,7 +111,181 @@ // Define the resonance names and store them in the array resInfo_.clear(); - resInfo_.reserve(100); + resInfo_.reserve(100); + + /////////////////////////////////////////////////////////// + // Resonances for DDK Analysis + /////////////////////////////////////////////////////////// + // name, mass, width, spin, charge, default BW category, BW radius parameter (defaults to 4.0) + // Charmonium + neutral = new LauResonanceInfo("psi(3770)", 3.7781, 0.0272, 1, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("X(3842)", 3.84271, 0.0279, 3, 0, LauBlattWeisskopfFactor::Charmonium ); //Vanya's new state + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("chi_c0(3860)", 3.862, 0.201, 0, 0, LauBlattWeisskopfFactor::Charmonium ); //https://inspirehep.net/record/1590028 + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("chi_c2_2P", 3.92190, 0.03664, 2, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("chi_c0_2P", 3.92190, 0.03664, 0, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("chi_c1_2P", 3.92190, 0.03664, 1, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("X_0(4020)", 4.0241, 0.013, 0, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("X_1(4020)", 4.0241, 0.013, 1, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("psi(4040)", 4.039, 0.080, 1, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("psi(4160)", 4.191, 0.070, 1, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("psi(4230)", 4.218, 0.059, 1, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("psi(4260)", 4.230, 0.055, 1, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("psi(4320)", 4.320, 0.1014, 1, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("psi(4390)", 4.392, 0.140, 1, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("psi(4415)", 4.421, 0.062, 1, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("psi(4500)", 4.506, 0.092, 0, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("psi(4700)", 4.704, 0.120, 0, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + + // Excited Ds + // Ds0*(2317) + positve = new LauResonanceInfo("Ds*+_0(2317)", 2.3177, 0.0038, 0, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + // Ds2*(2573) + positve = new LauResonanceInfo("Ds*+_2(2573)", 2.5719, 0.017, 2, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + // Ds1*(2700) + positve = new LauResonanceInfo("Ds*+_1(2700)", 2.709, 0.117, 1, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + // Ds1*(2700) with BW radius 2.0 + positve = new LauResonanceInfo("Ds*+_1(2700)_BW2", 2.709, 0.117, 1, 1, LauBlattWeisskopfFactor::StrangeCharm , 2.0 ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + // Ds1*(2700) with BW radius 3.0 + positve = new LauResonanceInfo("Ds*+_1(2700)_BW3", 2.709, 0.117, 1, 1, LauBlattWeisskopfFactor::StrangeCharm , 3.0 ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + // Ds1*(2700) with BW radius 5.0 + positve = new LauResonanceInfo("Ds*+_1(2700)_BW5", 2.709, 0.117, 1, 1, LauBlattWeisskopfFactor::StrangeCharm , 5.0 ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + // Ds1*(2700) with BW radius 6.0 + positve = new LauResonanceInfo("Ds*+_1(2700)_BW6", 2.709, 0.117, 1, 1, LauBlattWeisskopfFactor::StrangeCharm , 6.0 ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + // Ds1*(2860) + positve = new LauResonanceInfo("Ds*+_1(2860)", 2.862, 0.180, 1, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + // Ds3*(2860) + positve = new LauResonanceInfo("Ds*+_3(2860)", 2.862, 0.058, 3, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + + // Extra resonances to introduce complexity or answer questions + // (D0 D0bar) or (D+ D-) + // Specific + neutral = new LauResonanceInfo("X3915_S", 3.9184, 0.020, 0, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("X3915_D", 3.9184, 0.020, 2, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + // Generic + neutral = new LauResonanceInfo("DDK_DD_S_0", 4.24, 0.100, 0, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("DDK_DD_P_0", 4.24, 0.100, 1, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("DDK_DD_D_0", 4.24, 0.100, 2, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("DDK_DD_F_0", 4.24, 0.100, 3, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + // D0 K+ + positve = new LauResonanceInfo("DDK_D0Kp_S_+", 2.9, 0.100, 0, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + positve = new LauResonanceInfo("DDK_D0Kp_P_+", 2.9, 0.100, 1, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + positve = new LauResonanceInfo("DDK_D0Kp_D_+", 2.9, 0.100, 2, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + positve = new LauResonanceInfo("DDK_D0Kp_F_+", 2.9, 0.100, 3, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + // D0bar K+ + positve = new LauResonanceInfo("DDK_D0barKp_S_+", 2.9, 0.100, 0, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + positve = new LauResonanceInfo("DDK_D0barKp_P_+", 2.9, 0.100, 1, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + positve = new LauResonanceInfo("DDK_D0barKp_D_+", 2.9, 0.100, 2, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + positve = new LauResonanceInfo("DDK_D0barKp_F_+", 2.9, 0.100, 3, 1, LauBlattWeisskopfFactor::StrangeCharm ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + // D0 D- + negatve = new LauResonanceInfo("DDK_D0Dm_S_-", 4.24, 0.100, 0, -1, LauBlattWeisskopfFactor::Charmonium ); + positve = negatve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + negatve = new LauResonanceInfo("DDK_D0Dm_P_-", 4.24, 0.100, 1, -1, LauBlattWeisskopfFactor::Charmonium ); + positve = negatve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + negatve = new LauResonanceInfo("DDK_D0Dm_D_-", 4.24, 0.100, 2, -1, LauBlattWeisskopfFactor::Charmonium ); + positve = negatve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + negatve = new LauResonanceInfo("DDK_D0Dm_F_-", 4.24, 0.100, 3, -1, LauBlattWeisskopfFactor::Charmonium ); + positve = negatve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + // D- K+ + neutral = new LauResonanceInfo("DDK_DmKp_S_0", 2.9, 0.100, 0, 0, LauBlattWeisskopfFactor::StrangeCharm ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("DDK_DmKp_P_0", 2.9, 0.100, 1, 0, LauBlattWeisskopfFactor::StrangeCharm ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("DDK_DmKp_D_0", 2.9, 0.100, 2, 0, LauBlattWeisskopfFactor::StrangeCharm ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("DDK_DmKp_F_0", 2.9, 0.100, 3, 0, LauBlattWeisskopfFactor::StrangeCharm ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("DDK_DmKp2_S_0", 3.0, 0.050, 0, 0, LauBlattWeisskopfFactor::StrangeCharm ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("DDK_DmKp2_P_0", 3.0, 0.050, 1, 0, LauBlattWeisskopfFactor::StrangeCharm ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("RescatterThreshold_S", 0.0, 0.0, 0, 0, LauBlattWeisskopfFactor::Light ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("RescatterThreshold_P", 0.0, 0.0, 1, 0, LauBlattWeisskopfFactor::Light ); + resInfo_.push_back( neutral ); + + // STANDARD LAURA++ RESONANCES // rho resonances name, mass, width, spin, charge, default BW category, BW radius parameter (defaults to 4.0) // rho(770) neutral = new LauResonanceInfo("rho0(770)", 0.77526, 0.1478, 1, 0, LauBlattWeisskopfFactor::Light, 5.3); @@ -301,6 +476,13 @@ resInfo_.push_back( negatve ); // charmonium resonances name, mass, width, spin, charge, BW category, BW radius parameter (defaults to 4.0) + + // chi_c resonances for Dan + neutral = new LauResonanceInfo("chi_c0_1P", 3.41475, 0.0105, 0, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + neutral = new LauResonanceInfo("chi_c2_1P", 3.55620, 0.00198, 2, 0, LauBlattWeisskopfFactor::Charmonium ); + resInfo_.push_back( neutral ); + // chi_c0 neutral = new LauResonanceInfo("chi_c0", 3.41475, 0.0105, 0, 0, LauBlattWeisskopfFactor::Charmonium ); resInfo_.push_back( neutral ); @@ -310,15 +492,9 @@ // chi_c2 neutral = new LauResonanceInfo("chi_c2", 3.55620, 0.00193, 2, 0, LauBlattWeisskopfFactor::Charmonium ); resInfo_.push_back( neutral ); - // psi(3770) - neutral = new LauResonanceInfo("psi(3770)", 3.77313, 0.0272, 1, 0, LauBlattWeisskopfFactor::Charmonium ); - resInfo_.push_back( neutral ); // X(3872) neutral = new LauResonanceInfo("X(3872)", 3.87169, 0.0012, 1, 0, LauBlattWeisskopfFactor::Charmonium ); resInfo_.push_back( neutral ); - // chi_c2(2P) - neutral = new LauResonanceInfo("chi_c2(2P)", 3.9272, 0.024, 2, 0, LauBlattWeisskopfFactor::Charmonium ); - resInfo_.push_back( neutral ); // unknown scalars name, mass, width, spin, charge, BW category, BW radius parameter (defaults to 4.0) // sigma @@ -404,31 +580,6 @@ negatve = positve->createChargeConjugate(); resInfo_.push_back( positve ); resInfo_.push_back( negatve ); - // Ds0*(2317) - positve = new LauResonanceInfo("Ds*+_0(2317)", 2.3177, 0.0038, 0, 1, LauBlattWeisskopfFactor::StrangeCharm ); - negatve = positve->createChargeConjugate(); - resInfo_.push_back( positve ); - resInfo_.push_back( negatve ); - // Ds2*(2573) - positve = new LauResonanceInfo("Ds*+_2(2573)", 2.5719, 0.017, 2, 1, LauBlattWeisskopfFactor::StrangeCharm ); - negatve = positve->createChargeConjugate(); - resInfo_.push_back( positve ); - resInfo_.push_back( negatve ); - // Ds1*(2700) - positve = new LauResonanceInfo("Ds*+_1(2700)", 2.709, 0.117, 1, 1, LauBlattWeisskopfFactor::StrangeCharm ); - negatve = positve->createChargeConjugate(); - resInfo_.push_back( positve ); - resInfo_.push_back( negatve ); - // Ds1*(2860) - positve = new LauResonanceInfo("Ds*+_1(2860)", 2.862, 0.180, 1, 1, LauBlattWeisskopfFactor::StrangeCharm ); - negatve = positve->createChargeConjugate(); - resInfo_.push_back( positve ); - resInfo_.push_back( negatve ); - // Ds3*(2860) - positve = new LauResonanceInfo("Ds*+_3(2860)", 2.862, 0.058, 3, 1, LauBlattWeisskopfFactor::StrangeCharm ); - negatve = positve->createChargeConjugate(); - resInfo_.push_back( positve ); - resInfo_.push_back( negatve ); // excited bottom states name, mass, width, spin, charge, BW category, BW radius parameter (defaults to 4.0) // B* @@ -451,6 +602,17 @@ // Theory-based nonresonant model neutral = new LauResonanceInfo("NRModel", 0.0, 0.0, 0, 0, LauBlattWeisskopfFactor::Light ); resInfo_.push_back( neutral ); + // Babar nonresonant polynomial model + neutral = new LauResonanceInfo("BabarNR", 0.0, 0.0, 0, 0, LauBlattWeisskopfFactor::Light ); + resInfo_.push_back( neutral ); + positve = new LauResonanceInfo("BabarNR+", 0.0, 0.0, 0, 1, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + positve = new LauResonanceInfo("BabarNR++", 0.0, 0.0, 0, 2, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); // Belle nonresonant models neutral = new LauResonanceInfo("BelleSymNR", 0.0, 0.0, 0, 0, LauBlattWeisskopfFactor::Light ); resInfo_.push_back( neutral ); @@ -460,16 +622,28 @@ negatve = positve->createChargeConjugate(); resInfo_.push_back( positve ); resInfo_.push_back( negatve ); + positve = new LauResonanceInfo("BelleNR++", 0.0, 0.0, 0, 2, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); neutral = new LauResonanceInfo("BelleNR_Swave", 0.0, 0.0, 0, 0, LauBlattWeisskopfFactor::Light ); resInfo_.push_back( neutral ); positve = new LauResonanceInfo("BelleNR_Swave+",0.0, 0.0, 0, 1, LauBlattWeisskopfFactor::Light ); negatve = positve->createChargeConjugate(); resInfo_.push_back( positve ); resInfo_.push_back( negatve ); + positve = new LauResonanceInfo("BelleNR_Swave++",0.0, 0.0, 0, 2, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); neutral = new LauResonanceInfo("BelleNR_Pwave", 0.0, 0.0, 1, 0, LauBlattWeisskopfFactor::Light ); resInfo_.push_back( neutral ); positve = new LauResonanceInfo("BelleNR_Pwave+",0.0, 0.0, 1, 1, LauBlattWeisskopfFactor::Light ); negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + positve = new LauResonanceInfo("BelleNR_Pwave++",0.0, 0.0, 1, 2, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); resInfo_.push_back( positve ); resInfo_.push_back( negatve ); neutral = new LauResonanceInfo("BelleNR_Dwave", 0.0, 0.0, 2, 0, LauBlattWeisskopfFactor::Light ); @@ -500,7 +674,39 @@ resInfo_.push_back( neutral ); neutral = new LauResonanceInfo("PolNR_P2", 0.0, 0.0, 1, 0, LauBlattWeisskopfFactor::Light ); resInfo_.push_back( neutral ); - + // Polynomial nonresonant models ++ + positve = new LauResonanceInfo("PolNR_S0++", 0.0, 0.0, 0, 2, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + positve = new LauResonanceInfo("PolNR_S1++", 0.0, 0.0, 0, 2, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + positve = new LauResonanceInfo("PolNR_S2++", 0.0, 0.0, 0, 2, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + positve = new LauResonanceInfo("PolNR_P0++", 0.0, 0.0, 1, 2, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + positve = new LauResonanceInfo("PolNR_P1++", 0.0, 0.0, 1, 2, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + positve = new LauResonanceInfo("PolNR_P2++", 0.0, 0.0, 1, 2, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + // Model-independent partial wave + // MIPW nonresonant models name, mass, width, spin, charge, BW category, BW radius parameter (defaults to 4.0) + neutral = new LauResonanceInfo("MIPW_RI", 0.0, 0.0, 0, 0, LauBlattWeisskopfFactor::Light ); + resInfo_.push_back( neutral ); + positve = new LauResonanceInfo("MIPW_RI+", 0.0, 0.0, 0, 1, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + positve = new LauResonanceInfo("MIPW_RI++", 0.0, 0.0, 0, 2, LauBlattWeisskopfFactor::Light ); + negatve = positve->createChargeConjugate(); + resInfo_.push_back( positve ); + resInfo_.push_back( negatve ); + neutral = new LauResonanceInfo("MIPWSPIN1_RI", 0.0, 0.0, 1, 0, LauBlattWeisskopfFactor::Light ); + resInfo_.push_back( neutral ); // Fake resonances for S-Wave splines neutral = new LauResonanceInfo("Spline_S0", 0.0, 0.0, 0, 0, LauBlattWeisskopfFactor::Light ); resInfo_.push_back( neutral ); @@ -625,6 +831,29 @@ } } +LauBlattWeisskopfFactor* LauResonanceMaker::getParentBWFactor(Int_t resSpin, LauBlattWeisskopfFactor::BarrierType barrierType) +{ + LauBlattWeisskopfFactor* bwFactor(0); + + // Look up the category in the category information map + BWFactorCategoryMap::iterator factor_iter = bwFactors_.find( LauBlattWeisskopfFactor::Parent ); + + if ( factor_iter != bwFactors_.end() ) { + // If it exists, we can check if the factor object has been created + BlattWeisskopfCategoryInfo& categoryInfo = factor_iter->second; + + if ( categoryInfo.bwFactor_ != 0 ) { + // If so, simply clone it + bwFactor = categoryInfo.bwFactor_->createClone( resSpin, barrierType ); + } + } + + if ( bwFactor==0 ) { + std::cerr<<"ERROR in LauResonanceMaker::getParentBWFactor : No parent Blatt-Weisskopf factor found to be cloned for K-matrix."<getSpin(); - bwFactor = categoryInfo.bwFactor_->createClone( resSpin ); + bwFactor = categoryInfo.bwFactor_->createClone( resSpin, categoryInfo.bwFactor_->getBarrierType() ); } else { // Otherwise we need to create it, using the default value if it has been set if ( categoryInfo.defaultRadius_ >= 0.0 ) { @@ -836,7 +1065,7 @@ break; case LauAbsResonance::KMatrix : - // K-matrix description of S-wave + // K-matrix description std::cerr<<"ERROR in LauResonanceMaker::getResonance : K-matrix type specified, which should be separately handled."< diff --git a/src/LauRooFitSlave.cc b/src/LauRooFitTask.cc rename from src/LauRooFitSlave.cc rename to src/LauRooFitTask.cc --- a/src/LauRooFitSlave.cc +++ b/src/LauRooFitTask.cc @@ -22,13 +22,14 @@ Thomas Latham */ -/*! \file LauRooFitSlave.cc - \brief File containing implementation of LauRooFitSlave class. +/*! \file LauRooFitTask.cc + \brief File containing implementation of LauRooFitTask class. */ #include #include +#include "RooFormulaVar.h" #include "RooRealVar.h" #include "RooDataSet.h" #include "TFile.h" @@ -38,14 +39,14 @@ #include "LauFitNtuple.hh" #include "LauParameter.hh" -#include "LauSimFitSlave.hh" -#include "LauRooFitSlave.hh" +#include "LauSimFitTask.hh" +#include "LauRooFitTask.hh" -ClassImp(LauRooFitSlave) +ClassImp(LauRooFitTask) -LauRooFitSlave::LauRooFitSlave( RooAbsPdf& model, const Bool_t extended, const RooArgSet& vars, const TString& weightVarName ) : - LauSimFitSlave(), +LauRooFitTask::LauRooFitTask( RooAbsPdf& model, const Bool_t extended, const RooArgSet& vars, const TString& weightVarName ) : + LauSimFitTask(), model_(model), dataVars_(vars), weightVarName_(weightVarName), @@ -53,18 +54,18 @@ dataTree_(0), exptData_(0), extended_(extended), - iExptCat_("iExpt","Expt Number"), + iExptSet_(), nllVar_(0) { } -LauRooFitSlave::~LauRooFitSlave() +LauRooFitTask::~LauRooFitTask() { delete nllVar_; nllVar_ = 0; this->cleanData(); } -void LauRooFitSlave::cleanData() +void LauRooFitTask::cleanData() { if ( dataFile_ != 0 ) { dataFile_->Close(); @@ -76,7 +77,7 @@ exptData_ = 0; } -void LauRooFitSlave::initialise() +void LauRooFitTask::initialise() { if ( weightVarName_ != "" ) { Bool_t weightVarFound = kFALSE; @@ -90,14 +91,14 @@ } } if ( ! weightVarFound ) { - std::cerr << "ERROR in LauRooFitSlave::initialise : The set of data variables does not contain the weighting variable \"" << weightVarName_ << std::endl; + std::cerr << "ERROR in LauRooFitTask::initialise : The set of data variables does not contain the weighting variable \"" << weightVarName_ << std::endl; std::cerr << " : Weighting will be disabled." << std::endl; weightVarName_ = ""; } } } -Bool_t LauRooFitSlave::verifyFitData(const TString& dataFileName, const TString& dataTreeName) +Bool_t LauRooFitTask::verifyFitData(const TString& dataFileName, const TString& dataTreeName) { // Clean-up from any previous runs if ( dataFile_ != 0 ) { @@ -107,14 +108,14 @@ // Open the data file dataFile_ = TFile::Open( dataFileName ); if ( ! dataFile_ ) { - std::cerr << "ERROR in LauRooFitSlave::verifyFitData : Problem opening data file \"" << dataFileName << "\"" << std::endl; + std::cerr << "ERROR in LauRooFitTask::verifyFitData : Problem opening data file \"" << dataFileName << "\"" << std::endl; return kFALSE; } // Retrieve the tree dataTree_ = dynamic_cast( dataFile_->Get( dataTreeName ) ); if ( ! dataTree_ ) { - std::cerr << "ERROR in LauRooFitSlave::verifyFitData : Problem retrieving tree \"" << dataTreeName << "\" from data file \"" << dataFileName << "\"" << std::endl; + std::cerr << "ERROR in LauRooFitTask::verifyFitData : Problem retrieving tree \"" << dataTreeName << "\" from data file \"" << dataFileName << "\"" << std::endl; dataFile_->Close(); delete dataFile_; dataFile_ = 0; @@ -129,7 +130,7 @@ TString name = param->GetName(); TBranch* branch = dataTree_->GetBranch( name ); if ( branch == 0 ) { - std::cerr << "ERROR in LauRooFitSlave::verifyFitData : The data tree does not contain a branch for fit variable \"" << name << std::endl; + std::cerr << "ERROR in LauRooFitTask::verifyFitData : The data tree does not contain a branch for fit variable \"" << name << std::endl; allOK = kFALSE; } } @@ -140,25 +141,25 @@ // Check whether the tree has the branch iExpt TBranch* branch = dataTree_->GetBranch("iExpt"); if ( branch == 0 ) { - std::cout << "WARNING in LauRooFitSlave::verifyFitData : Cannot find branch \"iExpt\" in the tree, will treat all data as being from a single experiment" << std::endl; + std::cout << "WARNING in LauRooFitTask::verifyFitData : Cannot find branch \"iExpt\" in the tree, will treat all data as being from a single experiment" << std::endl; } else { - // Define the valid values for the iExpt RooCategory - iExptCat_.clearTypes(); + // Define the valid values for iExpt + iExptSet_.clear(); const UInt_t firstExp = dataTree_->GetMinimum("iExpt"); const UInt_t lastExp = dataTree_->GetMaximum("iExpt"); for ( UInt_t iExp = firstExp; iExp <= lastExp; ++iExp ) { - iExptCat_.defineType( TString::Format("expt%d",iExp), iExp ); + iExptSet_.insert( iExp ); } } return kTRUE; } -void LauRooFitSlave::prepareInitialParArray( TObjArray& array ) +void LauRooFitTask::prepareInitialParArray( TObjArray& array ) { // Check that the NLL variable has been initialised if ( ! nllVar_ ) { - std::cerr << "ERROR in LauRooFitSlave::prepareInitialParArray : NLL var not initialised" << std::endl; + std::cerr << "ERROR in LauRooFitTask::prepareInitialParArray : NLL var not initialised" << std::endl; return; } @@ -193,7 +194,7 @@ } else { RooFormulaVar* rfvar = dynamic_cast( param ); if ( rfvar == 0 ) { - std::cerr << "ERROR in LauRooFitSlave::prepareInitialParArray : The parameter is neither a RooRealVar nor a RooFormulaVar, don't know what to do" << std::endl; + std::cerr << "ERROR in LauRooFitTask::prepareInitialParArray : The parameter is neither a RooRealVar nor a RooFormulaVar, don't know what to do" << std::endl; continue; } std::vector< std::pair > lpars = this->convertToLauParameters( rfvar ); @@ -219,12 +220,12 @@ this->startNewFit( nFreePars, nFreePars ); } -LauParameter* LauRooFitSlave::convertToLauParameter( const RooRealVar* rooParameter ) const +LauParameter* LauRooFitTask::convertToLauParameter( const RooRealVar* rooParameter ) const { return new LauParameter( rooParameter->GetName(), rooParameter->getVal(), rooParameter->getMin(), rooParameter->getMax(), rooParameter->isConstant() ); } -std::vector< std::pair > LauRooFitSlave::convertToLauParameters( const RooFormulaVar* rooFormula ) const +std::vector< std::pair > LauRooFitTask::convertToLauParameters( const RooFormulaVar* rooFormula ) const { // Create the empty vector std::vector< std::pair > lauParameters; @@ -256,20 +257,20 @@ } // If neither of those worked we don't know what to do, so print an error message and continue - std::cerr << "ERROR in LauRooFitSlave::convertToLauParameters : One of the parameters is not a RooRealVar nor a RooFormulaVar, it is a: " << rabsarg->ClassName() << std::endl; + std::cerr << "ERROR in LauRooFitTask::convertToLauParameters : One of the parameters is not a RooRealVar nor a RooFormulaVar, it is a: " << rabsarg->ClassName() << std::endl; std::cerr << " : Do not know how to process that - it will be skipped." << std::endl; } return lauParameters; } -Double_t LauRooFitSlave::getTotNegLogLikelihood() +Double_t LauRooFitTask::getTotNegLogLikelihood() { Double_t nLL = (nllVar_ != 0) ? nllVar_->getVal() : 0.0; return nLL; } -void LauRooFitSlave::setParsFromMinuit(Double_t* par, Int_t npar) +void LauRooFitTask::setParsFromMinuit(Double_t* par, Int_t npar) { // This function sets the internal parameters based on the values // that Minuit is using when trying to minimise the total likelihood function. @@ -279,7 +280,7 @@ const UInt_t nFreePars = this->nFreeParams(); if ( ! this->withinAsymErrorCalc() ) { if (static_cast(npar) != nFreePars) { - std::cerr << "ERROR in LauRooFitSlave::setParsFromMinuit : Unexpected number of free parameters: " << npar << ".\n"; + std::cerr << "ERROR in LauRooFitTask::setParsFromMinuit : Unexpected number of free parameters: " << npar << ".\n"; std::cerr << " Expected: " << nFreePars << ".\n" << std::endl; gSystem->Exit(EXIT_FAILURE); } @@ -299,15 +300,15 @@ } } -UInt_t LauRooFitSlave::readExperimentData() +UInt_t LauRooFitTask::readExperimentData() { // check that we're being asked to read a valid index const UInt_t exptIndex = this->iExpt(); - if ( iExptCat_.numTypes() == 0 && exptIndex != 0 ) { - std::cerr << "ERROR in LauRooFitSlave::readExperimentData : Invalid experiment number " << exptIndex << ", data contains only one experiment" << std::endl; + if ( iExptSet_.empty() && exptIndex != 0 ) { + std::cerr << "ERROR in LauRooFitTask::readExperimentData : Invalid experiment number " << exptIndex << ", data contains only one experiment" << std::endl; return 0; - } else if ( ! iExptCat_.isValidIndex( exptIndex ) ) { - std::cerr << "ERROR in LauRooFitSlave::readExperimentData : Invalid experiment number " << exptIndex << std::endl; + } else if ( iExptSet_.find( exptIndex ) == iExptSet_.end() ) { + std::cerr << "ERROR in LauRooFitTask::readExperimentData : Invalid experiment number " << exptIndex << std::endl; return 0; } @@ -315,7 +316,7 @@ delete exptData_; // retrieve the data and find out how many events have been read - if ( iExptCat_.numTypes() == 0 ) { + if ( iExptSet_.empty() ) { exptData_ = new RooDataSet( TString::Format("expt%dData",exptIndex), "", dataTree_, dataVars_, "", (weightVarName_ != "") ? weightVarName_.Data() : 0 ); } else { const TString selectionString = TString::Format("iExpt==%d",exptIndex); @@ -329,7 +330,7 @@ return nEvent; } -void LauRooFitSlave::cacheInputFitVars() +void LauRooFitTask::cacheInputFitVars() { // cleanup the old NLL info delete nllVar_; @@ -338,29 +339,29 @@ nllVar_ = new RooNLLVar("nllVar", "", model_, *exptData_, extended_); } -void LauRooFitSlave::finaliseExperiment( const LauAbsFitter::FitStatus& fitStat, const TObjArray* parsFromMaster, const TMatrixD* covMat, TObjArray& parsToMaster ) +void LauRooFitTask::finaliseExperiment( const LauAbsFitter::FitStatus& fitStat, const TObjArray* parsFromCoordinator, const TMatrixD* covMat, TObjArray& parsToCoordinator ) { // Copy the fit status information this->storeFitStatus( fitStat, *covMat ); // Now process the parameters const UInt_t nFreePars = this->nFreeParams(); - UInt_t nPars = parsFromMaster->GetEntries(); + UInt_t nPars = parsFromCoordinator->GetEntries(); if ( nPars != nFreePars ) { - std::cerr << "ERROR in LauRooFitSlave::finaliseExperiment : Unexpected number of parameters received from master" << std::endl; + std::cerr << "ERROR in LauRooFitTask::finaliseExperiment : Unexpected number of parameters received from coordinator" << std::endl; std::cerr << " : Received " << nPars << " when expecting " << nFreePars << std::endl; gSystem->Exit( EXIT_FAILURE ); } for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { - LauParameter* parameter = dynamic_cast( (*parsFromMaster)[iPar] ); + LauParameter* parameter = dynamic_cast( (*parsFromCoordinator)[iPar] ); if ( ! parameter ) { - std::cerr << "ERROR in LauRooFitSlave::finaliseExperiment : Error reading parameter from master" << std::endl; + std::cerr << "ERROR in LauRooFitTask::finaliseExperiment : Error reading parameter from coordinator" << std::endl; gSystem->Exit( EXIT_FAILURE ); } if ( parameter->name() != fitPars_[iPar]->name() ) { - std::cerr << "ERROR in LauRooFitSlave::finaliseExperiment : Error reading parameter from master" << std::endl; + std::cerr << "ERROR in LauRooFitTask::finaliseExperiment : Error reading parameter from coordinator" << std::endl; gSystem->Exit( EXIT_FAILURE ); } @@ -373,10 +374,10 @@ } // Update the pulls and add each finalised fit parameter to the list to - // send back to the master + // send back to the coordinator for ( std::vector::iterator iter = fitPars_.begin(); iter != fitPars_.end(); ++iter ) { (*iter)->updatePull(); - parsToMaster.Add( *iter ); + parsToCoordinator.Add( *iter ); } // Write the results into the ntuple diff --git a/src/LauSimFitMaster.cc b/src/LauSimFitCoordinator.cc rename from src/LauSimFitMaster.cc rename to src/LauSimFitCoordinator.cc --- a/src/LauSimFitMaster.cc +++ b/src/LauSimFitCoordinator.cc @@ -22,8 +22,8 @@ Thomas Latham */ -/*! \file LauSimFitMaster.cc - \brief File containing implementation of LauSimFitMaster class. +/*! \file LauSimFitCoordinator.cc + \brief File containing implementation of LauSimFitCoordinator class. */ #include @@ -46,39 +46,39 @@ #include "LauFormulaPar.hh" #include "LauParameter.hh" #include "LauParamFixed.hh" -#include "LauSimFitMaster.hh" +#include "LauSimFitCoordinator.hh" -ClassImp(LauSimFitMaster) +ClassImp(LauSimFitCoordinator) -LauSimFitMaster::LauSimFitMaster( UInt_t numSlaves, UInt_t port ) : - nSlaves_(numSlaves), +LauSimFitCoordinator::LauSimFitCoordinator( UInt_t numTasks, UInt_t port ) : + nTasks_(numTasks), reqPort_(port), socketMonitor_(0), - messageFromSlave_(0), + messageFromTask_(0), fitNtuple_(0) { - messagesToSlaves_.resize( nSlaves_ ); - for ( UInt_t iSlave(0); iSlave < nSlaves_; ++iSlave ) { - messagesToSlaves_[iSlave] = new TMessage(); + messagesToTasks_.resize( nTasks_ ); + for ( UInt_t iTask(0); iTask < nTasks_; ++iTask ) { + messagesToTasks_[iTask] = new TMessage(); } } -LauSimFitMaster::~LauSimFitMaster() +LauSimFitCoordinator::~LauSimFitCoordinator() { delete socketMonitor_; socketMonitor_ = 0; - // Tell all slaves that they are finished and delete corresponding socket + // Tell all tasks that they are finished and delete corresponding socket TString msgStr("Finish"); TMessage message( kMESS_STRING ); message.WriteTString(msgStr); - for ( std::vector::iterator iter = sSlaves_.begin(); iter != sSlaves_.end(); ++iter ) { + for ( std::vector::iterator iter = socketTasks_.begin(); iter != socketTasks_.end(); ++iter ) { (*iter)->Send(message); (*iter)->Close(); delete (*iter); } - sSlaves_.clear(); + socketTasks_.clear(); // Remove the components created to apply constraints to fit parameters for (std::vector::iterator iter = conVars_.begin(); iter != conVars_.end(); ++iter){ @@ -100,20 +100,20 @@ } vectorPar_.clear(); - delete messageFromSlave_; messageFromSlave_ = 0; + delete messageFromTask_; messageFromTask_ = 0; - for ( std::vector::iterator iter = messagesToSlaves_.begin(); iter != messagesToSlaves_.end(); ++iter ) { + for ( std::vector::iterator iter = messagesToTasks_.begin(); iter != messagesToTasks_.end(); ++iter ) { delete (*iter); } - messagesToSlaves_.clear(); + messagesToTasks_.clear(); delete fitNtuple_; } -void LauSimFitMaster::initSockets() +void LauSimFitCoordinator::initSockets() { if ( socketMonitor_ != 0 ) { - std::cerr << "ERROR in LauSimFitMaster::initSockets : Sockets already initialised." << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::initSockets : Sockets already initialised." << std::endl; return; } @@ -123,26 +123,26 @@ TServerSocket *ss = new TServerSocket( reqPort_, kFALSE ); UInt_t actual_port = ss->GetLocalPort(); - std::cout << "INFO in LauSimFitMaster::initSockets : Waiting for connection with " << nSlaves_ << " workers on port " << actual_port << std::endl; + std::cout << "INFO in LauSimFitCoordinator::initSockets : Waiting for connection with " << nTasks_ << " workers on port " << actual_port << std::endl; - sSlaves_.resize(nSlaves_); - for ( UInt_t iSlave(0); iSlaveAccept(); - std::cout << " : Added slave " << iSlave << std::endl; + socketTasks_.resize(nTasks_); + for ( UInt_t iTask(0); iTaskAccept(); + std::cout << " : Added task " << iTask << std::endl; } // tell the clients to start - std::cout << "INFO in LauSimFitMaster::initSockets : Initialising slaves" << std::endl; - for ( UInt_t iSlave(0); iSlaveuseAsymmFitErrors()); - sSlaves_[iSlave]->Send(message); + socketTasks_[iTask]->Send(message); - socketMonitor_->Add(sSlaves_[iSlave]); + socketMonitor_->Add(socketTasks_[iTask]); } std::cout << " : Now start fit\n" << std::endl; @@ -152,33 +152,33 @@ /* * OLD VERSION THAT JUST GETS THE NAMES - COULD HAVE A SERIES OF EXCHANGES TO GET THE NAMES, INIT VALUES, RANGES, ETC. INSTEAD OF PASSING PARAMETERS - * THIS INCREASES THE GENERALITY OF THE CODE, I.E. THERE IS NO NEED FOR THE SLAVES TO KNOW ANY LAURA++ CLASS BUT THIS ONE, BUT MAKES IT RATHER MORE DENSE + * THIS INCREASES THE GENERALITY OF THE CODE, I.E. THERE IS NO NEED FOR THE TASKS TO KNOW ANY LAURA++ CLASS BUT THIS ONE, BUT MAKES IT RATHER MORE DENSE * FOR THE MOMENT I WILL STICK WITH THE METHOD OF PASSING LAUPARAMETER OBJECTS AROUND AND CONSIDER GOING BACK TO THIS GENERAL METHOD ONCE EVERYTHING IS WORKING * -void LauSimFitMaster::getParametersFromSlavesFirstTime() +void LauSimFitCoordinator::getParametersFromTasksFirstTime() { - slaveIndices_.resize( nSlaves_ ); + taskIndices_.resize( nTasks_ ); TSocket* sActive(0); - for ( UInt_t iSlave(0); iSlaveSend(message); + socketTasks_[iTask]->Send(message); - // Wait to receive the response and check that it has come from the slave we just requested from + // Wait to receive the response and check that it has come from the task we just requested from sActive = socketMonitor_->Select(); - if ( sActive != sSlaves_[iSlave] ) { - std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlavesFirstTime : Received message from a different slave than expected!" << std::endl; + if ( sActive != socketTasks_[iTask] ) { + std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Received message from a different task than expected!" << std::endl; gSystem->Exit(1); } // Read the object and extract the parameter names - sSlaves_[iSlave]->Recv( messageFromSlave_ ); - TObjArray * objarray = dynamic_cast( messageFromSlave_->ReadObject( messageFromSlave_->GetClass() ) ); + socketTasks_[iTask]->Recv( messageFromTask_ ); + TObjArray * objarray = dynamic_cast( messageFromTask_->ReadObject( messageFromTask_->GetClass() ) ); if ( ! objarray ) { - std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlavesFirstTime : Error reading parameter names from slave" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Error reading parameter names from task" << std::endl; gSystem->Exit(1); } @@ -186,7 +186,7 @@ for ( Int_t iPar(0); iPar < nPars; ++iPar ) { TObjString* objstring = dynamic_cast( (*objarray)[iPar] ); if ( ! objstring ) { - std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlavesFirstTime : Error reading parameter names from slave" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Error reading parameter names from task" << std::endl; gSystem->Exit(1); } TString parname = objstring->GetString(); @@ -194,17 +194,17 @@ std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname ); if ( iter != parIndices_.end() ) { UInt_t index = iter->second; - slaveIndices_[iSlave].push_back( index ); + taskIndices_[iTask].push_back( index ); } else { UInt_t index = parIndices_.size(); parIndices_.insert( std::make_pair( parname, index ) ); parNames_.insert( std::make_pair( index, parname ) ); - slaveIndices_[iSlave].push_back( index ); + taskIndices_[iTask].push_back( index ); } } delete objarray; objarray = 0; - delete messageFromSlave_; messageFromSlave_ = 0; + delete messageFromTask_; messageFromTask_ = 0; } UInt_t nPars = parNames_.size(); @@ -212,24 +212,24 @@ } */ -void LauSimFitMaster::getParametersFromSlaves() +void LauSimFitCoordinator::getParametersFromTasks() { if ( socketMonitor_ == 0 ) { - std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlaves : Sockets not initialised." << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasks : Sockets not initialised." << std::endl; return; } if ( params_.empty() ) { - this->getParametersFromSlavesFirstTime(); + this->getParametersFromTasksFirstTime(); // Add variables to Gaussian constrain to a list this->addConParameters(); } else { - this->updateParametersFromSlaves(); + this->updateParametersFromTasks(); } } -void LauSimFitMaster::updateParametersFromSlaves() +void LauSimFitCoordinator::updateParametersFromTasks() { TSocket* sActive(0); @@ -238,22 +238,22 @@ TMessage message( kMESS_STRING ); message.WriteTString( msgStr ); - for ( UInt_t iSlave(0); iSlaveSend(message); + for ( UInt_t iTask(0); iTaskSend(message); - // Wait to receive the response and check that it has come from the slave we just requested from + // Wait to receive the response and check that it has come from the task we just requested from sActive = socketMonitor_->Select(); - if ( sActive != sSlaves_[iSlave] ) { - std::cerr << "ERROR in LauSimFitMaster::updateParametersFromSlaves : Received message from a different slave than expected!" << std::endl; + if ( sActive != socketTasks_[iTask] ) { + std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Received message from a different task than expected!" << std::endl; gSystem->Exit(1); } // Read the object and extract the parameter names - sSlaves_[iSlave]->Recv( messageFromSlave_ ); - TObjArray * objarray = dynamic_cast( messageFromSlave_->ReadObject( messageFromSlave_->GetClass() ) ); + socketTasks_[iTask]->Recv( messageFromTask_ ); + TObjArray * objarray = dynamic_cast( messageFromTask_->ReadObject( messageFromTask_->GetClass() ) ); if ( ! objarray ) { - std::cerr << "ERROR in LauSimFitMaster::updateParametersFromSlaves : Error reading parameter names from slave" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Error reading parameter names from task" << std::endl; gSystem->Exit(1); } @@ -261,15 +261,15 @@ objarray->SetOwner(kTRUE); const UInt_t nPars = objarray->GetEntries(); - if ( nPars != slaveIndices_[iSlave].size() ) { - std::cerr << "ERROR in LauSimFitMaster::updateParametersFromSlaves : Unexpected number of parameters received from slave" << std::endl; + if ( nPars != taskIndices_[iTask].size() ) { + std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Unexpected number of parameters received from task" << std::endl; gSystem->Exit(1); } for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { LauParameter* parameter = dynamic_cast( (*objarray)[iPar] ); if ( ! parameter ) { - std::cerr << "ERROR in LauSimFitMaster::updateParametersFromSlaves : Error reading parameter from slave" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Error reading parameter from task" << std::endl; gSystem->Exit(1); } @@ -278,33 +278,33 @@ std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname ); if ( iter == parIndices_.end() ) { - std::cerr << "ERROR in LauSimFitMaster::updateParametersFromSlaves : Unexpected parameter name received from slave" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Unexpected parameter name received from task" << std::endl; gSystem->Exit(1); } const UInt_t index = iter->second; - if ( slaveIndices_[iSlave][iPar] != index ) { - std::cerr << "ERROR in LauSimFitMaster::updateParametersFromSlaves : Unexpected parameter received from slave" << std::endl; + if ( taskIndices_[iTask][iPar] != index ) { + std::cerr << "ERROR in LauSimFitCoordinator::updateParametersFromTasks : Unexpected parameter received from task" << std::endl; gSystem->Exit(1); } params_[index]->initValue( parvalue ); parValues_[index] = parvalue; - vectorPar_[iSlave][iPar] = parvalue; + vectorPar_[iTask][iPar] = parvalue; this->checkParameter( parameter, index ); } delete objarray; objarray = 0; - delete messageFromSlave_; messageFromSlave_ = 0; + delete messageFromTask_; messageFromTask_ = 0; } } -void LauSimFitMaster::getParametersFromSlavesFirstTime() +void LauSimFitCoordinator::getParametersFromTasksFirstTime() { - slaveIndices_.resize( nSlaves_ ); - slaveFreeIndices_.resize( nSlaves_ ); - vectorPar_.resize( nSlaves_ ); - vectorRes_.resize( nSlaves_ ); + taskIndices_.resize( nTasks_ ); + taskFreeIndices_.resize( nTasks_ ); + vectorPar_.resize( nTasks_ ); + vectorRes_.resize( nTasks_ ); TSocket* sActive(0); @@ -313,33 +313,33 @@ TMessage message( kMESS_STRING ); message.WriteTString( msgStr ); - for ( UInt_t iSlave(0); iSlaveSend(message); + for ( UInt_t iTask(0); iTaskSend(message); - // Wait to receive the response and check that it has come from the slave we just requested from + // Wait to receive the response and check that it has come from the task we just requested from sActive = socketMonitor_->Select(); - if ( sActive != sSlaves_[iSlave] ) { - std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlavesFirstTime : Received message from a different slave than expected!" << std::endl; + if ( sActive != socketTasks_[iTask] ) { + std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Received message from a different task than expected!" << std::endl; gSystem->Exit(1); } // Read the object and extract the parameter names - sSlaves_[iSlave]->Recv( messageFromSlave_ ); - TObjArray * objarray = dynamic_cast( messageFromSlave_->ReadObject( messageFromSlave_->GetClass() ) ); + socketTasks_[iTask]->Recv( messageFromTask_ ); + TObjArray * objarray = dynamic_cast( messageFromTask_->ReadObject( messageFromTask_->GetClass() ) ); if ( ! objarray ) { - std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlavesFirstTime : Error reading parameters from slave" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Error reading parameters from task" << std::endl; gSystem->Exit(1); } const UInt_t nPars = objarray->GetEntries(); - vectorPar_[iSlave] = new Double_t[nPars]; + vectorPar_[iTask] = new Double_t[nPars]; for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { LauParameter* parameter = dynamic_cast( (*objarray)[iPar] ); if ( ! parameter ) { - std::cerr << "ERROR in LauSimFitMaster::getParametersFromSlavesFirstTime : Error reading parameter from slave" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::getParametersFromTasksFirstTime : Error reading parameter from task" << std::endl; gSystem->Exit(1); } @@ -350,42 +350,42 @@ std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname ); if ( iter != parIndices_.end() ) { UInt_t index = iter->second; - slaveIndices_[iSlave].push_back( index ); + taskIndices_[iTask].push_back( index ); if ( ! parfixed ) { - slaveFreeIndices_[iSlave].push_back( index ); + taskFreeIndices_[iTask].push_back( index ); } this->checkParameter( parameter, index ); } else { UInt_t index = parIndices_.size(); parIndices_.insert( std::make_pair( parname, index ) ); parNames_.insert( std::make_pair( index, parname ) ); - slaveIndices_[iSlave].push_back( index ); + taskIndices_[iTask].push_back( index ); if ( ! parfixed ) { - slaveFreeIndices_[iSlave].push_back( index ); + taskFreeIndices_[iTask].push_back( index ); } params_.push_back( parameter ); parValues_.push_back( parvalue ); } - vectorPar_[iSlave][iPar] = parvalue; + vectorPar_[iTask][iPar] = parvalue; } delete objarray; objarray = 0; - delete messageFromSlave_; messageFromSlave_ = 0; + delete messageFromTask_; messageFromTask_ = 0; } } -void LauSimFitMaster::printParInfo() const +void LauSimFitCoordinator::printParInfo() const { - for ( UInt_t iSlave(0); iSlave& indices = slaveIndices_[iSlave]; + for ( UInt_t iTask(0); iTask& indices = taskIndices_[iTask]; - std::cout << "INFO in LauSimFitMaster::printParInfo : Slave " << iSlave << " has the following parameters:\n"; + std::cout << "INFO in LauSimFitCoordinator::printParInfo : Task " << iTask << " has the following parameters:\n"; for ( std::vector::const_iterator iter = indices.begin(); iter != indices.end(); ++iter ) { const TString& parName = parNames_.find(*iter)->second; Double_t parValue = parValues_[*iter]; const LauParameter* par = params_[*iter]; if ( par->name() != parName || par->initValue() != parValue ) { - std::cerr << "ERROR in LauSimFitMaster::printParInfo : Discrepancy in parameter name and value records, this is very strange!!" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::printParInfo : Discrepancy in parameter name and value records, this is very strange!!" << std::endl; } std::cout << " : " << parName << " = " << parValue << " and has index " << *iter << "\n"; @@ -394,40 +394,40 @@ std::cout << std::endl; } - std::cout << "INFO in LauSimFitMaster::printParInfo : " << "There are " << params_.size() << " parameters in total" << std::endl; + std::cout << "INFO in LauSimFitCoordinator::printParInfo : " << "There are " << params_.size() << " parameters in total" << std::endl; } -void LauSimFitMaster::checkParameter( const LauParameter* param, UInt_t index ) const +void LauSimFitCoordinator::checkParameter( const LauParameter* param, UInt_t index ) const { const LauParameter* storedPar = params_[index]; TString parName = storedPar->name(); if ( param->name() != parName ) { - std::cerr << "ERROR in LauSimFitMaster::checkParameter : Parameter name is different!! This shouldn't happen!!" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::checkParameter : Parameter name is different!! This shouldn't happen!!" << std::endl; } if ( param->initValue() != storedPar->initValue() ) { - std::cerr << "WARNING in LauSimFitMaster::checkParameter : Initial value for parameter " << parName << " is different, will use the value first set: " << storedPar->initValue() << std::endl; + std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Initial value for parameter " << parName << " is different, will use the value first set: " << storedPar->initValue() << std::endl; } if ( param->minValue() != storedPar->minValue() ) { - std::cerr << "WARNING in LauSimFitMaster::checkParameter : Minimum allowed value for parameter " << parName << " is different, will use the value first set: " << storedPar->minValue() << std::endl; + std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Minimum allowed value for parameter " << parName << " is different, will use the value first set: " << storedPar->minValue() << std::endl; } if ( param->maxValue() != storedPar->maxValue() ) { - std::cerr << "WARNING in LauSimFitMaster::checkParameter : Maximum allowed value for parameter " << parName << " is different, will use the value first set: " << storedPar->maxValue() << std::endl; + std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Maximum allowed value for parameter " << parName << " is different, will use the value first set: " << storedPar->maxValue() << std::endl; } if ( param->fixed() != storedPar->fixed() ) { - std::cerr << "WARNING in LauSimFitMaster::checkParameter : Fixed/floating property of parameter " << parName << " is different, will use the value first set: " << (storedPar->fixed() ? "fixed" : "floating") << std::endl; + std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Fixed/floating property of parameter " << parName << " is different, will use the value first set: " << (storedPar->fixed() ? "fixed" : "floating") << std::endl; } if ( param->secondStage() != storedPar->secondStage() ) { - std::cerr << "WARNING in LauSimFitMaster::checkParameter : Second stage property of parameter " << parName << " is different, will use the value first set: " << (storedPar->secondStage() ? "true" : "false") << std::endl; + std::cerr << "WARNING in LauSimFitCoordinator::checkParameter : Second stage property of parameter " << parName << " is different, will use the value first set: " << (storedPar->secondStage() ? "true" : "false") << std::endl; } } -void LauSimFitMaster::initialise() +void LauSimFitCoordinator::initialise() { this->initSockets(); } -void LauSimFitMaster::runSimFit( const TString& fitNtupleFileName, const UInt_t nExp, const UInt_t firstExp, const Bool_t useAsymmErrors, const Bool_t doTwoStageFit ) +void LauSimFitCoordinator::runSimFit( const TString& fitNtupleFileName, const UInt_t nExp, const UInt_t firstExp, const Bool_t useAsymmErrors, const Bool_t doTwoStageFit ) { // Routine to perform the total fit. @@ -436,8 +436,8 @@ this->twoStageFit(doTwoStageFit); this->initialise(); - std::cout << "INFO in LauSimFitMaster::runSimFit : First experiment = " << firstExp << std::endl; - std::cout << "INFO in LauSimFitMaster::runSimFit : Number of experiments = " << nExp << std::endl; + std::cout << "INFO in LauSimFitCoordinator::runSimFit : First experiment = " << firstExp << std::endl; + std::cout << "INFO in LauSimFitCoordinator::runSimFit : Number of experiments = " << nExp << std::endl; // Start the cumulative timer cumulTimer_.Start(); @@ -445,7 +445,7 @@ this->resetFitCounters(); // Create and setup the fit results ntuple - std::cout << "INFO in LauSimFitMaster::runSimFit : Creating fit ntuple." << std::endl; + std::cout << "INFO in LauSimFitCoordinator::runSimFit : Creating fit ntuple." << std::endl; if (fitNtuple_ != 0) {delete fitNtuple_; fitNtuple_ = 0;} fitNtuple_ = new LauFitNtuple(fitNtupleFileName, useAsymmErrors); @@ -457,15 +457,15 @@ this->setCurrentExperiment( iExp ); - // Instruct the slaves to read the data for this experiment + // Instruct the tasks to read the data for this experiment Bool_t readOK = this->readData(); if ( ! readOK ) { - std::cerr << "ERROR in LauSimFitMaster::runSimFit : One or more slaves reported problems with reading data for experiment " << iExp << ", skipping..." << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::runSimFit : One or more tasks reported problems with reading data for experiment " << iExp << ", skipping..." << std::endl; timer_.Stop(); continue; } - // Instruct the slaves to perform the caching + // Instruct the tasks to perform the caching this->cacheInputData(); // Do the fit @@ -475,65 +475,65 @@ timer_.Stop(); timer_.Print(); - // Instruct the slaves to finalise the results + // Instruct the tasks to finalise the results this->finalise(); } // Print out total timing info. - std::cout << "INFO in LauSimFitMaster::runSimFit : Cumulative timing:" << std::endl; + std::cout << "INFO in LauSimFitCoordinator::runSimFit : Cumulative timing:" << std::endl; cumulTimer_.Stop(); cumulTimer_.Print(); // Print out stats on OK fits. const UInt_t nOKFits = this->numberOKFits(); const UInt_t nBadFits = this->numberBadFits(); - std::cout << "INFO in LauSimFitMaster::runSimFit : Number of OK Fits = " << nOKFits << std::endl; - std::cout << "INFO in LauSimFitMaster::runSimFit : Number of Failed Fits = " << nBadFits << std::endl; + std::cout << "INFO in LauSimFitCoordinator::runSimFit : Number of OK Fits = " << nOKFits << std::endl; + std::cout << "INFO in LauSimFitCoordinator::runSimFit : Number of Failed Fits = " << nBadFits << std::endl; Double_t fitEff(0.0); if (nExp != 0) {fitEff = nOKFits/(1.0*nExp);} - std::cout << "INFO in LauSimFitMaster::runSimFit : Fit efficiency = " << fitEff*100.0 << "%." << std::endl; + std::cout << "INFO in LauSimFitCoordinator::runSimFit : Fit efficiency = " << fitEff*100.0 << "%." << std::endl; - // Instruct the slaves to write out any fit results (ntuples etc...). + // Instruct the tasks to write out any fit results (ntuples etc...). this->writeOutResults(); } -void LauSimFitMaster::withinAsymErrorCalc(const Bool_t inAsymErrCalc) +void LauSimFitCoordinator::withinAsymErrorCalc(const Bool_t inAsymErrCalc) { this->LauFitObject::withinAsymErrorCalc(inAsymErrCalc); if ( socketMonitor_ == 0 ) { - std::cerr << "ERROR in LauSimFitMaster::withinAsymErrorCalc : Sockets not initialised." << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::withinAsymErrorCalc : Sockets not initialised." << std::endl; return; } - // Construct a message, informing the slaves whether or not we are now within the asymmetric error calculation + // Construct a message, informing the tasks whether or not we are now within the asymmetric error calculation TString msgStr("Asym Error Calc"); const Bool_t asymErrorCalc( this->withinAsymErrorCalc() ); TMessage message( kMESS_STRING ); message.WriteTString( msgStr ); message.WriteBool( asymErrorCalc ); - // Send the message to the slaves - for ( UInt_t iSlave(0); iSlaveSend(message); + // Send the message to the tasks + for ( UInt_t iTask(0); iTaskSend(message); } TSocket* sActive(0); UInt_t responsesReceived(0); - while ( responsesReceived != nSlaves_ ) { + while ( responsesReceived != nTasks_ ) { // Get the next queued response sActive = socketMonitor_->Select(); - // Extract from the message the ID of the slave and the number of events read + // Extract from the message the ID of the task and the number of events read Bool_t response(kTRUE); - UInt_t iSlave(0); - sActive->Recv( messageFromSlave_ ); - messageFromSlave_->ReadUInt( iSlave ); - messageFromSlave_->ReadBool( response ); + UInt_t iTask(0); + sActive->Recv( messageFromTask_ ); + messageFromTask_->ReadUInt( iTask ); + messageFromTask_->ReadBool( response ); if ( response != asymErrorCalc ) { - std::cerr << "WARNING in LauSimFitMaster::withinAsymErrorCalc : Problem informing slave " << iSlave << std::endl; + std::cerr << "WARNING in LauSimFitCoordinator::withinAsymErrorCalc : Problem informing task " << iTask << std::endl; } ++responsesReceived; @@ -541,10 +541,10 @@ } -Bool_t LauSimFitMaster::readData() +Bool_t LauSimFitCoordinator::readData() { if ( socketMonitor_ == 0 ) { - std::cerr << "ERROR in LauSimFitMaster::readData : Sockets not initialised." << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::readData : Sockets not initialised." << std::endl; return kFALSE; } @@ -555,31 +555,31 @@ message.WriteTString( msgStr ); message.WriteUInt( iExp ); - // Send the message to the slaves - for ( UInt_t iSlave(0); iSlaveSend(message); + // Send the message to the tasks + for ( UInt_t iTask(0); iTaskSend(message); } TSocket* sActive(0); UInt_t responsesReceived(0); Bool_t ok(kTRUE); - while ( responsesReceived != nSlaves_ ) { + while ( responsesReceived != nTasks_ ) { // Get the next queued response sActive = socketMonitor_->Select(); - // Extract from the message the ID of the slave and the number of events read - sActive->Recv( messageFromSlave_ ); - UInt_t iSlave(0); + // Extract from the message the ID of the task and the number of events read + sActive->Recv( messageFromTask_ ); + UInt_t iTask(0); UInt_t nEvents(0); - messageFromSlave_->ReadUInt( iSlave ); - messageFromSlave_->ReadUInt( nEvents ); + messageFromTask_->ReadUInt( iTask ); + messageFromTask_->ReadUInt( nEvents ); if ( nEvents <= 0 ) { - std::cerr << "ERROR in LauSimFitMaster::readData : Slave " << iSlave << " reports no events found for experiment " << iExp << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::readData : Task " << iTask << " reports no events found for experiment " << iExp << std::endl; ok = kFALSE; } else { - std::cerr << "INFO in LauSimFitMaster::readData : Slave " << iSlave << " reports " << nEvents << " events found for experiment " << iExp << std::endl; + std::cerr << "INFO in LauSimFitCoordinator::readData : Task " << iTask << " reports " << nEvents << " events found for experiment " << iExp << std::endl; } ++responsesReceived; @@ -588,10 +588,10 @@ return ok; } -Bool_t LauSimFitMaster::cacheInputData() +Bool_t LauSimFitCoordinator::cacheInputData() { if ( socketMonitor_ == 0 ) { - std::cerr << "ERROR in LauSimFitMaster::cacheInputData : Sockets not initialised." << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::cacheInputData : Sockets not initialised." << std::endl; return kFALSE; } @@ -600,28 +600,28 @@ TMessage message( kMESS_STRING ); message.WriteTString( msgStr ); - for ( UInt_t iSlave(0); iSlaveSend(message); + for ( UInt_t iTask(0); iTaskSend(message); } TSocket* sActive(0); UInt_t responsesReceived(0); Bool_t allOK(kTRUE); - while ( responsesReceived != nSlaves_ ) { + while ( responsesReceived != nTasks_ ) { // Get the next queued response sActive = socketMonitor_->Select(); - // Extract from the message the ID of the slave and the success/failure flag - sActive->Recv( messageFromSlave_ ); - UInt_t iSlave(0); + // Extract from the message the ID of the task and the success/failure flag + sActive->Recv( messageFromTask_ ); + UInt_t iTask(0); Bool_t ok(kTRUE); - messageFromSlave_->ReadUInt( iSlave ); - messageFromSlave_->ReadBool( ok ); + messageFromTask_->ReadUInt( iTask ); + messageFromTask_->ReadBool( ok ); if ( ! ok ) { - std::cerr << "ERROR in LauSimFitMaster::cacheInputData : Slave " << iSlave << " reports an error performing caching" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::cacheInputData : Task " << iTask << " reports an error performing caching" << std::endl; allOK = kFALSE; } @@ -631,17 +631,17 @@ return allOK; } -void LauSimFitMaster::checkInitFitParams() +void LauSimFitCoordinator::checkInitFitParams() { - this->getParametersFromSlaves(); + this->getParametersFromTasks(); this->printParInfo(); } -void LauSimFitMaster::fitExpt() +void LauSimFitCoordinator::fitExpt() { // Routine to perform the actual fit for the given experiment - // Instruct the slaves to update initial fit parameters if required (e.g. if using random numbers). + // Instruct the tasks to update initial fit parameters if required (e.g. if using random numbers). this->checkInitFitParams(); // Initialise the fitter @@ -652,14 +652,14 @@ this->startNewFit( LauFitter::fitter()->nParameters(), LauFitter::fitter()->nFreeParameters() ); // Now ready for minimisation step - std::cout << "\nINFO in LauSimFitMaster::fitExpt : Start minimisation...\n"; + std::cout << "\nINFO in LauSimFitCoordinator::fitExpt : Start minimisation...\n"; LauAbsFitter::FitStatus fitResult = LauFitter::fitter()->minimise(); // If we're doing a two stage fit we can now release (i.e. float) // the 2nd stage parameters and re-fit if (this->twoStageFit()) { if ( fitResult.status != 3 ) { - std::cerr << "ERROR in LauSimFitMaster:fitExpt : Not running second stage fit since first stage failed." << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator:fitExpt : Not running second stage fit since first stage failed." << std::endl; LauFitter::fitter()->releaseSecondStageParameters(); } else { LauFitter::fitter()->releaseSecondStageParameters(); @@ -677,7 +677,7 @@ LauFitter::fitter()->updateParameters(); } -void LauSimFitMaster::setParsFromMinuit(Double_t* par, Int_t npar) +void LauSimFitCoordinator::setParsFromMinuit(Double_t* par, Int_t npar) { // This function sets the internal parameters based on the values // that Minuit is using when trying to minimise the total likelihood function. @@ -687,7 +687,7 @@ if ( ! this->withinAsymErrorCalc() ) { const UInt_t nFreePars = this->nFreeParams(); if (static_cast(npar) != nFreePars) { - std::cerr << "ERROR in LauSimFitMaster::setParsFromMinuit : Unexpected number of free parameters: " << npar << ".\n"; + std::cerr << "ERROR in LauSimFitCoordinator::setParsFromMinuit : Unexpected number of free parameters: " << npar << ".\n"; std::cerr << " Expected: " << nFreePars << ".\n" << std::endl; gSystem->Exit(EXIT_FAILURE); } @@ -697,7 +697,7 @@ // the par array actually contains all the parameters, // free and floating... // Update all the parameters with their new values. - // Change the value in the array to be sent out to the slaves and the + // Change the value in the array to be sent out to the tasks and the // parameters themselves (so that constraints are correctly calculated) for (UInt_t i(0); inTotParams(); ++i) { if (!params_[i]->fixed()) { @@ -707,43 +707,43 @@ } } -Double_t LauSimFitMaster::getTotNegLogLikelihood() +Double_t LauSimFitCoordinator::getTotNegLogLikelihood() { if ( socketMonitor_ == 0 ) { - std::cerr << "ERROR in LauSimFitMaster::getTotNegLogLikelihood : Sockets not initialised." << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::getTotNegLogLikelihood : Sockets not initialised." << std::endl; return 0.0; } - // Send current values of the parameters to the slaves. - for ( UInt_t iSlave(0); iSlave& indices = slaveIndices_[iSlave]; - std::vector& freeIndices = slaveFreeIndices_[iSlave]; + std::vector& indices = taskIndices_[iTask]; + std::vector& freeIndices = taskFreeIndices_[iTask]; UInt_t nPars = indices.size(); UInt_t nFreePars = freeIndices.size(); for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { - vectorPar_[iSlave][iPar] = parValues_[ indices[iPar] ]; + vectorPar_[iTask][iPar] = parValues_[ indices[iPar] ]; } - TMessage* message = messagesToSlaves_[iSlave]; + TMessage* message = messagesToTasks_[iTask]; message->Reset( kMESS_ANY ); message->WriteUInt( nPars ); message->WriteUInt( nFreePars ); - message->WriteFastArray( vectorPar_[iSlave], nPars ); + message->WriteFastArray( vectorPar_[iTask], nPars ); - sSlaves_[iSlave]->Send(*message); + socketTasks_[iTask]->Send(*message); } Double_t negLogLike(0.0); TSocket *sActive(0); UInt_t responsesReceived(0); Bool_t allOK(kTRUE); - while ( responsesReceived != nSlaves_ ) { + while ( responsesReceived != nTasks_ ) { sActive = socketMonitor_->Select(); - sActive->Recv(messageFromSlave_); + sActive->Recv(messageFromTask_); - messageFromSlave_->ReadDouble( vectorRes_[responsesReceived] ); + messageFromTask_->ReadDouble( vectorRes_[responsesReceived] ); Double_t& nLL = vectorRes_[responsesReceived]; if ( nLL == 0.0 || TMath::IsNaN(nLL) || !TMath::Finite(nLL) ) { @@ -762,7 +762,7 @@ const Double_t worstNegLogLike = -1.0*this->worstLogLike(); if ( ! allOK ) { - std::cerr << "WARNING in LauSimFitMaster::getTotNegLogLikelihood : Strange NLL value returned by one or more slaves\n"; + std::cerr << "WARNING in LauSimFitCoordinator::getTotNegLogLikelihood : Strange NLL value returned by one or more tasks\n"; std::cerr << " : Returning worst NLL found so far to force MINUIT out of this region." << std::endl; negLogLike = worstNegLogLike; } else if ( negLogLike > worstNegLogLike ) { @@ -772,7 +772,7 @@ return negLogLike; } -Double_t LauSimFitMaster::getLogLikelihoodPenalty() +Double_t LauSimFitCoordinator::getLogLikelihoodPenalty() { Double_t penalty(0.0); @@ -788,7 +788,7 @@ return penalty; } -void LauSimFitMaster::addConParameters() +void LauSimFitCoordinator::addConParameters() { // Add penalties from the constraints to fit parameters @@ -796,7 +796,7 @@ for ( std::vector::const_iterator iter = params_.begin(); iter != params_.end(); ++iter ) { if ( (*iter)->gaussConstraint() ) { conVars_.push_back( *iter ); - std::cout << "INFO in LauSimFitMaster::addConParameters : Added Gaussian constraint to parameter "<< (*iter)->name() << std::endl; + std::cout << "INFO in LauSimFitCoordinator::addConParameters : Added Gaussian constraint to parameter "<< (*iter)->name() << std::endl; } } @@ -815,7 +815,7 @@ // If the parameters are not found, skip it if ( params.size() != (*iter).conPars_.size() ) { - std::cerr << "WARNING in LauSimFitMaster::addConParameters: Could not find parameters to constrain in the formula... skipping" << std::endl; + std::cerr << "WARNING in LauSimFitCoordinator::addConParameters: Could not find parameters to constrain in the formula... skipping" << std::endl; continue; } @@ -823,7 +823,7 @@ formPar->addGaussianConstraint( (*iter).mean_, (*iter).width_ ); conVars_.push_back(formPar); - std::cout << "INFO in LauSimFitMaster::addConParameters : Added Gaussian constraint to formula\n"; + std::cout << "INFO in LauSimFitCoordinator::addConParameters : Added Gaussian constraint to formula\n"; std::cout << " : Formula: " << (*iter).formula_ << std::endl; for ( std::vector::iterator iterparam = params.begin(); iterparam != params.end(); ++iterparam ) { std::cout << " : Parameter: " << (*iterparam)->name() << std::endl; @@ -832,16 +832,16 @@ } -Bool_t LauSimFitMaster::finalise() +Bool_t LauSimFitCoordinator::finalise() { if ( socketMonitor_ == 0 ) { - std::cerr << "ERROR in LauSimFitMaster::finalise : Sockets not initialised." << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::finalise : Sockets not initialised." << std::endl; return kFALSE; } // Prepare the covariance matrices const TMatrixD& covMatrix = this->covarianceMatrix(); - covMatrices_.resize( nSlaves_ ); + covMatrices_.resize( nTasks_ ); LauParamFixed pred; @@ -856,14 +856,14 @@ } } - for ( UInt_t iSlave(0); iSlave freeIndices; freeIndices.reserve( nPar ); for ( UInt_t iPar(0); iPar < nPar; ++iPar ) { - UInt_t index = slaveIndices_[iSlave][iPar]; + UInt_t index = taskIndices_[iTask][iPar]; std::map::iterator freeIter = freeParIndices.find(index); if ( freeIter == freeParIndices.end() ) { continue; @@ -873,7 +873,7 @@ } const UInt_t nFreePars = freeIndices.size(); - TMatrixD& covMat = covMatrices_[iSlave]; + TMatrixD& covMat = covMatrices_[iTask]; covMat.ResizeTo( nFreePars, nFreePars ); for ( UInt_t iPar(0); iPar < nFreePars; ++iPar ) { @@ -888,12 +888,12 @@ // The array to hold the parameters TObjArray array; - // Send messages to all slaves containing the final parameters and fit status, NLL - for ( UInt_t iSlave(0); iSlave& indices = slaveIndices_[iSlave]; + std::vector& indices = taskIndices_[iTask]; UInt_t nPars = indices.size(); for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { array.Add( params_[ indices[iPar] ] ); @@ -902,9 +902,9 @@ const Int_t status = this->statusCode(); const Double_t NLL = this->nll(); const Double_t EDM = this->edm(); - TMatrixD& covMat = covMatrices_[iSlave]; + TMatrixD& covMat = covMatrices_[iTask]; - TMessage* message = messagesToSlaves_[iSlave]; + TMessage* message = messagesToTasks_[iTask]; message->Reset( kMESS_OBJECT ); message->WriteInt( status ); message->WriteDouble( NLL ); @@ -912,42 +912,42 @@ message->WriteObject( &array ); message->WriteObject( &covMat ); - sSlaves_[iSlave]->Send(*message); + socketTasks_[iTask]->Send(*message); } TSocket *sActive(0); UInt_t responsesReceived(0); Bool_t allOK(kTRUE); - while ( responsesReceived != nSlaves_ ) { + while ( responsesReceived != nTasks_ ) { // Get the next queued response sActive = socketMonitor_->Select(); - // Extract from the message the ID of the slave and the number of events read - sActive->Recv( messageFromSlave_ ); - UInt_t iSlave(0); + // Extract from the message the ID of the task and the number of events read + sActive->Recv( messageFromTask_ ); + UInt_t iTask(0); Bool_t ok(kTRUE); - messageFromSlave_->ReadUInt( iSlave ); - messageFromSlave_->ReadBool( ok ); + messageFromTask_->ReadUInt( iTask ); + messageFromTask_->ReadBool( ok ); if ( ok ) { - TObjArray * objarray = dynamic_cast( messageFromSlave_->ReadObject( messageFromSlave_->GetClass() ) ); + TObjArray * objarray = dynamic_cast( messageFromTask_->ReadObject( messageFromTask_->GetClass() ) ); if ( ! objarray ) { - std::cerr << "ERROR in LauSimFitMaster::finalise : Error reading finalised parameters from slave" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::finalise : Error reading finalised parameters from task" << std::endl; allOK = kFALSE; } else { // We want to auto-delete the supplied parameters since we only copy their values in this case objarray->SetOwner(kTRUE); const UInt_t nPars = objarray->GetEntries(); - if ( nPars != slaveIndices_[iSlave].size() ) { - std::cerr << "ERROR in LauSimFitMaster::finalise : Unexpected number of finalised parameters received from slave" << std::endl; + if ( nPars != taskIndices_[iTask].size() ) { + std::cerr << "ERROR in LauSimFitCoordinator::finalise : Unexpected number of finalised parameters received from task" << std::endl; allOK = kFALSE; } else { for ( UInt_t iPar(0); iPar < nPars; ++iPar ) { LauParameter* parameter = dynamic_cast( (*objarray)[iPar] ); if ( ! parameter ) { - std::cerr << "ERROR in LauSimFitMaster::finalise : Error reading parameter from slave" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::finalise : Error reading parameter from task" << std::endl; allOK = kFALSE; continue; } @@ -956,14 +956,14 @@ std::map< TString, UInt_t >::iterator iter = parIndices_.find( parname ); if ( iter == parIndices_.end() ) { - std::cerr << "ERROR in LauSimFitMaster::finalise : Unexpected parameter name received from slave" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::finalise : Unexpected parameter name received from task" << std::endl; allOK = kFALSE; continue; } const UInt_t index = iter->second; - if ( slaveIndices_[iSlave][iPar] != index ) { - std::cerr << "ERROR in LauSimFitMaster::finalise : Unexpected parameter received from slave" << std::endl; + if ( taskIndices_[iTask][iPar] != index ) { + std::cerr << "ERROR in LauSimFitCoordinator::finalise : Unexpected parameter received from task" << std::endl; allOK = kFALSE; continue; } @@ -971,13 +971,13 @@ Double_t parvalue = parameter->value(); params_[index]->value( parvalue ); parValues_[index] = parvalue; - vectorPar_[iSlave][iPar] = parvalue; + vectorPar_[iTask][iPar] = parvalue; } } delete objarray; } } else { - std::cerr << "ERROR in LauSimFitMaster::finalise : Slave " << iSlave << " reports an error performing finalisation" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::finalise : Task " << iTask << " reports an error performing finalisation" << std::endl; allOK = kFALSE; } @@ -1000,10 +1000,10 @@ return allOK; } -Bool_t LauSimFitMaster::writeOutResults() +Bool_t LauSimFitCoordinator::writeOutResults() { if ( socketMonitor_ == 0 ) { - std::cerr << "ERROR in LauSimFitMaster::writeOutResults : Sockets not initialised." << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::writeOutResults : Sockets not initialised." << std::endl; return kFALSE; } @@ -1012,28 +1012,28 @@ TMessage message( kMESS_STRING ); message.WriteTString( msgStr ); - // Send the message to the slaves - for ( UInt_t iSlave(0); iSlaveSend(message); + // Send the message to the tasks + for ( UInt_t iTask(0); iTaskSend(message); } TSocket *sActive(0); UInt_t responsesReceived(0); Bool_t allOK(kTRUE); - while ( responsesReceived != nSlaves_ ) { + while ( responsesReceived != nTasks_ ) { // Get the next queued response sActive = socketMonitor_->Select(); - // Extract from the message the ID of the slave and the number of events read - sActive->Recv( messageFromSlave_ ); - UInt_t iSlave(0); + // Extract from the message the ID of the task and the number of events read + sActive->Recv( messageFromTask_ ); + UInt_t iTask(0); Bool_t ok(kTRUE); - messageFromSlave_->ReadUInt( iSlave ); - messageFromSlave_->ReadBool( ok ); + messageFromTask_->ReadUInt( iTask ); + messageFromTask_->ReadBool( ok ); if ( ! ok ) { - std::cerr << "ERROR in LauSimFitMaster::writeOutResults : Slave " << iSlave << " reports an error performing finalisation" << std::endl; + std::cerr << "ERROR in LauSimFitCoordinator::writeOutResults : Task " << iTask << " reports an error performing finalisation" << std::endl; allOK = kFALSE; } diff --git a/src/LauSimFitSlave.cc b/src/LauSimFitSlave.cc deleted file mode 100644 --- a/src/LauSimFitSlave.cc +++ /dev/null @@ -1,310 +0,0 @@ - -/* -Copyright 2015 University of Warwick - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* -Laura++ package authors: -John Back -Paul Harrison -Thomas Latham -*/ - -/*! \file LauSimFitSlave.cc - \brief File containing implementation of LauSimFitSlave class. -*/ - -#include -#include - -#include "TMatrixD.h" -#include "TMessage.h" -#include "TObjArray.h" -#include "TObjString.h" -#include "TSocket.h" -#include "TSystem.h" - -#include "LauSimFitSlave.hh" -#include "LauFitNtuple.hh" - - -ClassImp(LauSimFitSlave) - - -LauSimFitSlave::LauSimFitSlave() : - sMaster_(0), - messageFromMaster_(0), - slaveId_(0), - nSlaves_(0), - parValues_(0), - fitNtuple_(0) -{ -} - -LauSimFitSlave::~LauSimFitSlave() -{ - delete sMaster_; - delete messageFromMaster_; - delete[] parValues_; - delete fitNtuple_; -} - -void LauSimFitSlave::runSlave(const TString& dataFileName, const TString& dataTreeName, - const TString& histFileName, const TString& tableFileName, - const TString& addressMaster, const UInt_t portMaster) -{ - // Establish the connection to the master process - this->connectToMaster( addressMaster, portMaster ); - - // Initialise the fit model - this->initialise(); - - // NB call to addConParameters() is intentionally not included here cf. - // LauAbsFitModel::run() since this has to be dealt with by the master - // to avoid multiple inclusions of each penalty term - // Print a warning if constraints on combinations of parameters have been specified - const std::vector& storeCon = this->constraintsStore(); - if ( ! storeCon.empty() ) { - std::cerr << "WARNING in LauSimFitSlave::runSlave : Constraints have been added but these will be ignored - they should have been added to the master process" << std::endl; - } - - // Setup saving of fit results to ntuple/LaTeX table etc. - this->setupResultsOutputs( histFileName, tableFileName ); - - // This reads in the given dataFile and creates an input - // fit data tree that stores them for all events and experiments. - Bool_t dataOK = this->verifyFitData(dataFileName,dataTreeName); - if (!dataOK) { - std::cerr << "ERROR in LauSimFitSlave::runSlave : Problem caching the fit data." << std::endl; - return; - } - - // Now process the various requests from the master - this->processMasterRequests(); - - std::cout << "INFO in LauSimFitSlave::runSlave : Fit slave " << this->slaveId() << " has finished successfully" << std::endl; -} - -void LauSimFitSlave::setupResultsOutputs( const TString& histFileName, const TString& /*tableFileName*/ ) -{ - // Create and setup the fit results ntuple - std::cout << "INFO in LauSimFitSlave::setupResultsOutputs : Creating fit ntuple." << std::endl; - if (fitNtuple_ != 0) {delete fitNtuple_; fitNtuple_ = 0;} - fitNtuple_ = new LauFitNtuple(histFileName, this->useAsymmFitErrors()); -} - -void LauSimFitSlave::connectToMaster( const TString& addressMaster, const UInt_t portMaster ) -{ - if ( sMaster_ != 0 ) { - std::cerr << "ERROR in LauSimFitSlave::connectToMaster : master socket already present" << std::endl; - return; - } - - // Open connection to master - sMaster_ = new TSocket(addressMaster, portMaster); - sMaster_->Recv( messageFromMaster_ ); - - messageFromMaster_->ReadUInt( slaveId_ ); - messageFromMaster_->ReadUInt( nSlaves_ ); - - Bool_t useAsymErrs(kFALSE); - messageFromMaster_->ReadBool( useAsymErrs ); - this->useAsymmFitErrors(useAsymErrs); - - delete messageFromMaster_; - messageFromMaster_ = 0; - - std::cout << "INFO in LauSimFitSlave::connectToMaster : Established connection to master on port " << portMaster << std::endl; - std::cout << " : We are slave " << slaveId_ << " of " << nSlaves_ << std::endl; - if ( useAsymErrs ) { - std::cout << " : The fit will determine asymmetric errors" << std::endl; - } -} - -void LauSimFitSlave::processMasterRequests() -{ - // Listen for requests from the master and act accordingly - - TMessage messageToMaster(kMESS_ANY); - - while ( kTRUE ) { - - sMaster_->Recv( messageFromMaster_ ); - - if ( messageFromMaster_->What() == kMESS_STRING ) { - - TString msgStr; - messageFromMaster_->ReadTString( msgStr ); - - std::cout << "INFO in LauSimFitSlave::processMasterRequests : Received message from master: " << msgStr << std::endl; - - if ( msgStr == "Send Parameters" ) { - - // Send the fit parameters - - TObjArray array; - this->prepareInitialParArray( array ); - - // Create array to efficiently exchange parameter values with master - if ( parValues_ != 0 ) { - delete[] parValues_; - parValues_ = 0; - } - UInt_t nPar = array.GetEntries(); - parValues_ = new Double_t[nPar]; - - messageToMaster.Reset( kMESS_OBJECT ); - messageToMaster.WriteObject( &array ); - sMaster_->Send( messageToMaster ); - - } else if ( msgStr == "Read Expt" ) { - - // Read the data for this experiment - UInt_t iExp(0); - messageFromMaster_->ReadUInt( iExp ); - - this->setCurrentExperiment( iExp ); - - UInt_t nEvents = this->readExperimentData(); - if ( nEvents < 1 ) { - std::cerr << "WARNING in LauSimFitSlave::processMasterRequests : Zero events in experiment " << iExp << ", the master should skip this experiment..." << std::endl; - } - - messageToMaster.Reset( kMESS_ANY ); - messageToMaster.WriteUInt( slaveId_ ); - messageToMaster.WriteUInt( nEvents ); - sMaster_->Send( messageToMaster ); - - } else if ( msgStr == "Cache" ) { - - // Perform the caching - - this->cacheInputFitVars(); - - messageToMaster.Reset( kMESS_ANY ); - messageToMaster.WriteUInt( slaveId_ ); - messageToMaster.WriteBool( kTRUE ); - sMaster_->Send( messageToMaster ); - - } else if ( msgStr == "Asym Error Calc" ) { - - Bool_t asymErrorCalc(kFALSE); - messageFromMaster_->ReadBool( asymErrorCalc ); - this->withinAsymErrorCalc( asymErrorCalc ); - - messageToMaster.Reset( kMESS_ANY ); - messageToMaster.WriteUInt( slaveId_ ); - messageToMaster.WriteBool( asymErrorCalc ); - sMaster_->Send( messageToMaster ); - - } else if ( msgStr == "Write Results" ) { - - this->writeOutAllFitResults(); - - messageToMaster.Reset( kMESS_ANY ); - messageToMaster.WriteUInt( slaveId_ ); - messageToMaster.WriteBool( kTRUE ); - sMaster_->Send( messageToMaster ); - - } else if ( msgStr == "Finish" ) { - - std::cout << "INFO in LauSimFitSlave::processMasterRequests : Message from master to finish" << std::endl; - break; - - } else { - - std::cerr << "ERROR in LauSimFitSlave::processMasterRequests : Unexpected message from master" << std::endl; - gSystem->Exit( EXIT_FAILURE ); - - } - - } else if ( messageFromMaster_->What() == kMESS_OBJECT ) { - - std::cout << "INFO in LauSimFitSlave::processMasterRequests : Received message from master: Finalise" << std::endl; - - Int_t status(0); - Double_t NLL(0.0); - Double_t EDM(0.0); - messageFromMaster_->ReadInt( status ); - messageFromMaster_->ReadDouble( NLL ); - messageFromMaster_->ReadDouble( EDM ); - - TObjArray * objarray = dynamic_cast( messageFromMaster_->ReadObject( messageFromMaster_->GetClass() ) ); - if ( ! objarray ) { - std::cerr << "ERROR in LauSimFitSlave::processMasterRequests : Error reading parameters from master" << std::endl; - gSystem->Exit( EXIT_FAILURE ); - } - - TMatrixD * covMat = dynamic_cast( messageFromMaster_->ReadObject( messageFromMaster_->GetClass() ) ); - if ( ! covMat ) { - std::cerr << "ERROR in LauSimFitSlave::processMasterRequests : Error reading covariance matrix from master" << std::endl; - gSystem->Exit( EXIT_FAILURE ); - } - - TObjArray array; - LauAbsFitter::FitStatus fitStat { status, NLL, EDM }; - this->finaliseExperiment( fitStat, objarray, covMat, array ); - - delete objarray; objarray = 0; - delete covMat; covMat = 0; - - // Send the finalised parameters back to the master - messageToMaster.Reset( kMESS_ANY ); - messageToMaster.WriteUInt( slaveId_ ); - messageToMaster.WriteBool( kTRUE ); - messageToMaster.WriteObject( &array ); - sMaster_->Send( messageToMaster ); - - } else if ( messageFromMaster_->What() == kMESS_ANY ) { - - UInt_t nPars(0); - UInt_t nFreePars(0); - messageFromMaster_->ReadUInt( nPars ); - messageFromMaster_->ReadUInt( nFreePars ); - - if ( nPars != this->nTotParams() ) { - std::cerr << "ERROR in LauSimFitSlave::processMasterRequests : Unexpected number of parameters received from master" << std::endl; - std::cerr << " : Received " << nPars << " when expecting " << this->nTotParams() << std::endl; - gSystem->Exit( EXIT_FAILURE ); - } - - messageFromMaster_->ReadFastArray( parValues_, nPars ); - - this->setParsFromMinuit( parValues_, nFreePars ); - - Double_t negLogLike = this->getTotNegLogLikelihood(); - - messageToMaster.Reset( kMESS_ANY ); - messageToMaster.WriteDouble( negLogLike ); - sMaster_->Send( messageToMaster ); - - } else { - std::cerr << "ERROR in LauSimFitSlave::processMasterRequests : Unexpected message type" << std::endl; - gSystem->Exit( EXIT_FAILURE ); - } - - delete messageFromMaster_; - messageFromMaster_ = 0; - } -} - -void LauSimFitSlave::writeOutAllFitResults() -{ - // Write out histograms at end - if (fitNtuple_ != 0) { - fitNtuple_->writeOutFitResults(); - } -} - diff --git a/src/LauSimFitTask.cc b/src/LauSimFitTask.cc new file mode 100644 --- /dev/null +++ b/src/LauSimFitTask.cc @@ -0,0 +1,310 @@ + +/* +Copyright 2015 University of Warwick + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Laura++ package authors: +John Back +Paul Harrison +Thomas Latham +*/ + +/*! \file LauSimFitTask.cc + \brief File containing implementation of LauSimFitTask class. +*/ + +#include +#include + +#include "TMatrixD.h" +#include "TMessage.h" +#include "TObjArray.h" +#include "TObjString.h" +#include "TSocket.h" +#include "TSystem.h" + +#include "LauSimFitTask.hh" +#include "LauFitNtuple.hh" + + +ClassImp(LauSimFitTask) + + +LauSimFitTask::LauSimFitTask() : + socketCoordinator_(0), + messageFromCoordinator_(0), + taskId_(0), + nTasks_(0), + parValues_(0), + fitNtuple_(0) +{ +} + +LauSimFitTask::~LauSimFitTask() +{ + delete socketCoordinator_; + delete messageFromCoordinator_; + delete[] parValues_; + delete fitNtuple_; +} + +void LauSimFitTask::runTask(const TString& dataFileName, const TString& dataTreeName, + const TString& histFileName, const TString& tableFileName, + const TString& addressCoordinator, const UInt_t portCoordinator) +{ + // Establish the connection to the coordinator process + this->connectToCoordinator( addressCoordinator, portCoordinator ); + + // Initialise the fit model + this->initialise(); + + // NB call to addConParameters() is intentionally not included here cf. + // LauAbsFitModel::run() since this has to be dealt with by the coordinator + // to avoid multiple inclusions of each penalty term + // Print a warning if constraints on combinations of parameters have been specified + const std::vector& storeCon = this->constraintsStore(); + if ( ! storeCon.empty() ) { + std::cerr << "WARNING in LauSimFitTask::runTask : Constraints have been added but these will be ignored - they should have been added to the coordinator process" << std::endl; + } + + // Setup saving of fit results to ntuple/LaTeX table etc. + this->setupResultsOutputs( histFileName, tableFileName ); + + // This reads in the given dataFile and creates an input + // fit data tree that stores them for all events and experiments. + Bool_t dataOK = this->verifyFitData(dataFileName,dataTreeName); + if (!dataOK) { + std::cerr << "ERROR in LauSimFitTask::runTask : Problem caching the fit data." << std::endl; + return; + } + + // Now process the various requests from the coordinator + this->processCoordinatorRequests(); + + std::cout << "INFO in LauSimFitTask::runTask : Fit task " << this->taskId() << " has finished successfully" << std::endl; +} + +void LauSimFitTask::setupResultsOutputs( const TString& histFileName, const TString& /*tableFileName*/ ) +{ + // Create and setup the fit results ntuple + std::cout << "INFO in LauSimFitTask::setupResultsOutputs : Creating fit ntuple." << std::endl; + if (fitNtuple_ != 0) {delete fitNtuple_; fitNtuple_ = 0;} + fitNtuple_ = new LauFitNtuple(histFileName, this->useAsymmFitErrors()); +} + +void LauSimFitTask::connectToCoordinator( const TString& addressCoordinator, const UInt_t portCoordinator ) +{ + if ( socketCoordinator_ != 0 ) { + std::cerr << "ERROR in LauSimFitTask::connectToCoordinator : coordinator socket already present" << std::endl; + return; + } + + // Open connection to coordinator + socketCoordinator_ = new TSocket(addressCoordinator, portCoordinator); + socketCoordinator_->Recv( messageFromCoordinator_ ); + + messageFromCoordinator_->ReadUInt( taskId_ ); + messageFromCoordinator_->ReadUInt( nTasks_ ); + + Bool_t useAsymErrs(kFALSE); + messageFromCoordinator_->ReadBool( useAsymErrs ); + this->useAsymmFitErrors(useAsymErrs); + + delete messageFromCoordinator_; + messageFromCoordinator_ = 0; + + std::cout << "INFO in LauSimFitTask::connectToCoordinator : Established connection to coordinator on port " << portCoordinator << std::endl; + std::cout << " : We are task " << taskId_ << " of " << nTasks_ << std::endl; + if ( useAsymErrs ) { + std::cout << " : The fit will determine asymmetric errors" << std::endl; + } +} + +void LauSimFitTask::processCoordinatorRequests() +{ + // Listen for requests from the coordinator and act accordingly + + TMessage messageToCoordinator(kMESS_ANY); + + while ( kTRUE ) { + + socketCoordinator_->Recv( messageFromCoordinator_ ); + + if ( messageFromCoordinator_->What() == kMESS_STRING ) { + + TString msgStr; + messageFromCoordinator_->ReadTString( msgStr ); + + std::cout << "INFO in LauSimFitTask::processCoordinatorRequests : Received message from coordinator: " << msgStr << std::endl; + + if ( msgStr == "Send Parameters" ) { + + // Send the fit parameters + + TObjArray array; + this->prepareInitialParArray( array ); + + // Create array to efficiently exchange parameter values with coordinator + if ( parValues_ != 0 ) { + delete[] parValues_; + parValues_ = 0; + } + UInt_t nPar = array.GetEntries(); + parValues_ = new Double_t[nPar]; + + messageToCoordinator.Reset( kMESS_OBJECT ); + messageToCoordinator.WriteObject( &array ); + socketCoordinator_->Send( messageToCoordinator ); + + } else if ( msgStr == "Read Expt" ) { + + // Read the data for this experiment + UInt_t iExp(0); + messageFromCoordinator_->ReadUInt( iExp ); + + this->setCurrentExperiment( iExp ); + + UInt_t nEvents = this->readExperimentData(); + if ( nEvents < 1 ) { + std::cerr << "WARNING in LauSimFitTask::processCoordinatorRequests : Zero events in experiment " << iExp << ", the coordinator should skip this experiment..." << std::endl; + } + + messageToCoordinator.Reset( kMESS_ANY ); + messageToCoordinator.WriteUInt( taskId_ ); + messageToCoordinator.WriteUInt( nEvents ); + socketCoordinator_->Send( messageToCoordinator ); + + } else if ( msgStr == "Cache" ) { + + // Perform the caching + + this->cacheInputFitVars(); + + messageToCoordinator.Reset( kMESS_ANY ); + messageToCoordinator.WriteUInt( taskId_ ); + messageToCoordinator.WriteBool( kTRUE ); + socketCoordinator_->Send( messageToCoordinator ); + + } else if ( msgStr == "Asym Error Calc" ) { + + Bool_t asymErrorCalc(kFALSE); + messageFromCoordinator_->ReadBool( asymErrorCalc ); + this->withinAsymErrorCalc( asymErrorCalc ); + + messageToCoordinator.Reset( kMESS_ANY ); + messageToCoordinator.WriteUInt( taskId_ ); + messageToCoordinator.WriteBool( asymErrorCalc ); + socketCoordinator_->Send( messageToCoordinator ); + + } else if ( msgStr == "Write Results" ) { + + this->writeOutAllFitResults(); + + messageToCoordinator.Reset( kMESS_ANY ); + messageToCoordinator.WriteUInt( taskId_ ); + messageToCoordinator.WriteBool( kTRUE ); + socketCoordinator_->Send( messageToCoordinator ); + + } else if ( msgStr == "Finish" ) { + + std::cout << "INFO in LauSimFitTask::processCoordinatorRequests : Message from coordinator to finish" << std::endl; + break; + + } else { + + std::cerr << "ERROR in LauSimFitTask::processCoordinatorRequests : Unexpected message from coordinator" << std::endl; + gSystem->Exit( EXIT_FAILURE ); + + } + + } else if ( messageFromCoordinator_->What() == kMESS_OBJECT ) { + + std::cout << "INFO in LauSimFitTask::processCoordinatorRequests : Received message from coordinator: Finalise" << std::endl; + + Int_t status(0); + Double_t NLL(0.0); + Double_t EDM(0.0); + messageFromCoordinator_->ReadInt( status ); + messageFromCoordinator_->ReadDouble( NLL ); + messageFromCoordinator_->ReadDouble( EDM ); + + TObjArray * objarray = dynamic_cast( messageFromCoordinator_->ReadObject( messageFromCoordinator_->GetClass() ) ); + if ( ! objarray ) { + std::cerr << "ERROR in LauSimFitTask::processCoordinatorRequests : Error reading parameters from coordinator" << std::endl; + gSystem->Exit( EXIT_FAILURE ); + } + + TMatrixD * covMat = dynamic_cast( messageFromCoordinator_->ReadObject( messageFromCoordinator_->GetClass() ) ); + if ( ! covMat ) { + std::cerr << "ERROR in LauSimFitTask::processCoordinatorRequests : Error reading covariance matrix from coordinator" << std::endl; + gSystem->Exit( EXIT_FAILURE ); + } + + TObjArray array; + LauAbsFitter::FitStatus fitStat { status, NLL, EDM }; + this->finaliseExperiment( fitStat, objarray, covMat, array ); + + delete objarray; objarray = 0; + delete covMat; covMat = 0; + + // Send the finalised parameters back to the coordinator + messageToCoordinator.Reset( kMESS_ANY ); + messageToCoordinator.WriteUInt( taskId_ ); + messageToCoordinator.WriteBool( kTRUE ); + messageToCoordinator.WriteObject( &array ); + socketCoordinator_->Send( messageToCoordinator ); + + } else if ( messageFromCoordinator_->What() == kMESS_ANY ) { + + UInt_t nPars(0); + UInt_t nFreePars(0); + messageFromCoordinator_->ReadUInt( nPars ); + messageFromCoordinator_->ReadUInt( nFreePars ); + + if ( nPars != this->nTotParams() ) { + std::cerr << "ERROR in LauSimFitTask::processCoordinatorRequests : Unexpected number of parameters received from coordinator" << std::endl; + std::cerr << " : Received " << nPars << " when expecting " << this->nTotParams() << std::endl; + gSystem->Exit( EXIT_FAILURE ); + } + + messageFromCoordinator_->ReadFastArray( parValues_, nPars ); + + this->setParsFromMinuit( parValues_, nFreePars ); + + Double_t negLogLike = this->getTotNegLogLikelihood(); + + messageToCoordinator.Reset( kMESS_ANY ); + messageToCoordinator.WriteDouble( negLogLike ); + socketCoordinator_->Send( messageToCoordinator ); + + } else { + std::cerr << "ERROR in LauSimFitTask::processCoordinatorRequests : Unexpected message type" << std::endl; + gSystem->Exit( EXIT_FAILURE ); + } + + delete messageFromCoordinator_; + messageFromCoordinator_ = 0; + } +} + +void LauSimFitTask::writeOutAllFitResults() +{ + // Write out histograms at end + if (fitNtuple_ != 0) { + fitNtuple_->writeOutFitResults(); + } +} + diff --git a/src/LauSimpleFitModel.cc b/src/LauSimpleFitModel.cc --- a/src/LauSimpleFitModel.cc +++ b/src/LauSimpleFitModel.cc @@ -851,38 +851,46 @@ Bool_t blind = kFALSE; // Signal + if ( signalEvents_->blind() ) { + blind = kTRUE; + } + Double_t evtWeight(1.0); - Int_t nEvts = TMath::FloorNint(signalEvents_->genValue()); + Double_t nEvts = signalEvents_->genValue(); if ( nEvts < 0 ) { evtWeight = -1.0; nEvts = TMath::Abs( nEvts ); } + + Int_t nEvtsToGen { static_cast(nEvts) }; if (this->doPoissonSmearing()) { - nEvts = LauRandom::randomFun()->Poisson(nEvts); - } - nEvtsGen["signal"] = std::make_pair( nEvts, evtWeight ); - if ( signalEvents_->blind() ) { - blind = kTRUE; + nEvtsToGen = LauRandom::randomFun()->Poisson(nEvts); } + nEvtsGen["signal"] = std::make_pair( nEvtsToGen, evtWeight ); + // Backgrounds const UInt_t nBkgnds = this->nBkgndClasses(); for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) { - const TString& bkgndClass = this->bkgndClassName(bkgndID); const LauAbsRValue* evtsPar = bkgndEvents_[bkgndID]; + if ( evtsPar->blind() ) { + blind = kTRUE; + } + evtWeight = 1.0; - nEvts = TMath::FloorNint( evtsPar->genValue() ); + nEvts = evtsPar->genValue(); if ( nEvts < 0 ) { evtWeight = -1.0; nEvts = TMath::Abs( nEvts ); } + + nEvtsToGen = static_cast(nEvts); if (this->doPoissonSmearing()) { - nEvts = LauRandom::randomFun()->Poisson(nEvts); - } - nEvtsGen[bkgndClass] = std::make_pair( nEvts, evtWeight ); - if ( evtsPar->blind() ) { - blind = kTRUE; + nEvtsToGen = LauRandom::randomFun()->Poisson(nEvts); } + + const TString& bkgndClass = this->bkgndClassName(bkgndID); + nEvtsGen[bkgndClass] = std::make_pair( nEvtsToGen, evtWeight ); } return std::make_pair( nEvtsGen, blind ); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,13 @@ + +list(APPEND TEST_SOURCES + TestCovariant + TestCovariant2 + TestNewKinematicsMethods + ) + +foreach( _test ${TEST_SOURCES}) + add_executable(${_test} ${_test}.cc) + target_link_libraries(${_test} PRIVATE Laura++) + #install(TARGETS ${_test} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endforeach() + diff --git a/test/Makefile b/test/Makefile deleted file mode 100644 --- a/test/Makefile +++ /dev/null @@ -1,152 +0,0 @@ - ############################################################################ - # Copyright 2017 University of Warwick # - # # - # Licensed under the Apache License, Version 2.0 (the "License"); # - # you may not use this file except in compliance with the License. # - # You may obtain a copy of the License at # - # # - # http://www.apache.org/licenses/LICENSE-2.0 # - # # - # Unless required by applicable law or agreed to in writing, software # - # distributed under the License is distributed on an "AS IS" BASIS, # - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # - # See the License for the specific language governing permissions and # - # limitations under the License. # - # # - # Laura++ package authors: # - # John Back # - # Paul Harrison # - # Thomas Latham # - # # - ############################################################################ - # # - # ------------------------------------- # - # Standalone Makefile for Laura++ tests # - # ------------------------------------- # - # # - # Instructions # - # - Review 'external configuration' section below # - # to match systems compilers setup # - # # - # - Make sure the ROOTSYS environment variable is set and points # - # to your ROOT release or the root-config script is in your PATH # - # # - # - run 'make ' # - # # - # Build targets # - # bin - make all examples (default) # - # - make the specific example # - # clean - delete all intermediate and final build objects # - # # - ############################################################################ - - -# --- External configuration ---------------------------------- - -# first check that ROOTSYS is defined -ifndef ROOTSYS - ROOTSYS := $(shell root-config --prefix) - ROOTBINDIR := $(shell root-config --bindir) - ifeq ($(ROOTSYS), ) - $(error running of root-config failed or reported null value) - endif -else - ROOTBINDIR := $(ROOTSYS)/bin -endif - -# If you don't want to build one or more tests, just add them to the SKIPLIST variable -SKIPLIST = - -ROOTCONFIG := $(ROOTBINDIR)/root-config -ARCH := $(shell $(ROOTCONFIG) --arch) -PLATFORM := $(shell $(ROOTCONFIG) --platform) - -INCLUDES = -WORKDIR = tmp - -ifeq ($(findstring linux, $(ARCH)),linux) -# This set here should work for Linux. -CXX = g++ -LD = g++ -CXXFLAGS = -g -O2 -Wall -Wextra -Wshadow -Woverloaded-virtual -Werror -fPIC -MFLAGS = -MM -LDFLAGS = -g -SOFLAGS = -shared -endif - -ifeq ($(ARCH),macosx64) -# For Mac OS X you may need to put -m64 in CXXFLAGS and SOFLAGS. -CXX = g++ -LD = g++ -CXXFLAGS = -g -O3 -Wall -Wextra -Wshadow -Woverloaded-virtual -Werror -fPIC -m64 -MFLAGS = -MM -LDFLAGS = -g -SOFLAGS = -m64 -dynamiclib -single_module -undefined dynamic_lookup -endif - -# --- Internal configuration ---------------------------------- -INCDIR=../inc -DEPDIR=$(WORKDIR)/dependencies -OBJDIR=$(WORKDIR)/objects - -ROOTCFLAGS := $(shell $(ROOTCONFIG) --cflags) -ROOTLIBS := $(shell $(ROOTCONFIG) --libs) -ROOTLIBS += -lEG -ROOTLIBS += -lMinuit -ROOTLIBS += -lTreePlayer -ifeq ($(strip $(SKIPLIST)),) - ROOTLIBS += -lRooFitCore - ROOTLIBS += -lRooFit -endif -LAURALIBDIR=$(shell pwd | xargs dirname)/lib -LAURALIB = $(LAURALIBDIR)/libLaura++.so - -INCLUDES += -I$(INCDIR) -CXXFLAGS += $(INCLUDES) -CXXFLAGS += $(ROOTCFLAGS) - -default: bin - -# List of all source files -CCLIST:=$(filter-out $(SKIPLIST), $(wildcard *.cc)) - -# List of all source files that contain main functions -BINCCLIST:=$(shell egrep -l "^[[:space:]]*int[[:space:]]*main\>" $(CCLIST)) - -# List of all object files to build -BINOLIST:=$(patsubst %.cc,%.o,$(addprefix $(OBJDIR)/,$(notdir $(BINCCLIST)))) - -# List of all dependency files to make -DLIST:=$(patsubst %.cc,%.d,$(addprefix $(DEPDIR)/,$(notdir $(CCLIST)))) - -# List of all binary files to make -BINLIST:=$(patsubst %.cc,%,$(notdir $(BINCCLIST))) - -# Implicit rule making all dependency Makefiles included at the end of this makefile -$(DEPDIR)/%.d: %.cc - @echo "Making $@" - @mkdir -p $(DEPDIR) - @set -e; $(CXX) $(MFLAGS) $(CXXFLAGS) $< \ - | sed 's#\($(notdir $*)\)\.o[ :]*#$(OBJDIR)/\1.o $@ : #g' > $@; \ - [ -s $@ ] || rm -f $@ - -# Implicit rule to compile all sources -$(OBJDIR)/%.o : %.cc - @echo "Compiling $<" - @mkdir -p $(OBJDIR) - @$(CXX) $(CXXFLAGS) -c $< -o $@ - -# Rule to compile all binaries -% : $(OBJDIR)/%.o $(LAURALIB) - @echo "Linking $@" - @$(CXX) $(LDFLAGS) $< -o $@ $(LAURALIB) $(ROOTLIBS) - -bin: $(BINLIST) - -clean: - rm -f $(BINLIST) - rm -rf $(WORKDIR) - -.PHONY : bin default clean - --include $(DLIST)