Pushing FCNC fitter. Removed tmp files accidentaly pushed
This commit is contained in:
parent
e49c224d67
commit
6b17868719
91
Code/FCNCFitter/Bp2Kstmumu_predictions.py
Normal file
91
Code/FCNCFitter/Bp2Kstmumu_predictions.py
Normal file
@ -0,0 +1,91 @@
|
||||
import flavio
|
||||
from wilson import Wilson
|
||||
from uncertainties import ufloat
|
||||
|
||||
angobs = ['FL', 'S3', 'S4', 'S5', 'AFB', 'S7', 'S8', 'S9']
|
||||
#angobs = ['P1', 'P2', 'P3', 'P4p', 'P5p', 'P6p', 'P8p']
|
||||
|
||||
#q2bins = [[0.1, 0.98], [1.1, 2.5], [2.5, 4], [4, 6], [6, 8], [11, 12.5], [15, 17], [17, 19]]
|
||||
q2bins = [[0.1, 4.0],[4.0,5.0]]#, [4, 8], [11.0,12.5], [15.0,19.0]]
|
||||
SMpred, NPpred = {}, {} # to be filled
|
||||
|
||||
# setting Wilson coefficients for NP
|
||||
w = Wilson({ 'C9_bsmumu': -1}, scale=160, eft='WET', basis='flavio')
|
||||
|
||||
doNP = False
|
||||
doSM = True
|
||||
# getting predictions for both SM and NP
|
||||
for ibin, q2bin in enumerate(q2bins):
|
||||
print(f'Bin {q2bin}')
|
||||
SMpred[ibin], NPpred[ibin] = {}, {}
|
||||
if (doSM):
|
||||
for o in angobs:
|
||||
SMpred[ibin][o] = ufloat(flavio.sm_prediction(f'<{o}>(B+->K*mumu)',
|
||||
q2min=q2bin[0], q2max=q2bin[1]),
|
||||
flavio.sm_uncertainty(f'<{o}>(B+->K*mumu)',
|
||||
q2min=q2bin[0], q2max=q2bin[1], N=100)) #N=10k for the final plots, N=100 for the fitter
|
||||
if (doNP):
|
||||
for o in angobs:
|
||||
NPpred[ibin][o] = ufloat(flavio.np_prediction(f'<{o}>(B+->K*mumu)', w,
|
||||
q2min=q2bin[0], q2max=q2bin[1]),
|
||||
flavio.np_uncertainty(f'<{o}>(B+->K*mumu)', w,
|
||||
q2min=q2bin[0], q2max=q2bin[1]))
|
||||
|
||||
# Just printing everything out in human-readable format here
|
||||
def printout(dic):
|
||||
for ibin, q2bin in enumerate(q2bins):
|
||||
print(f'Bin {q2bin}')
|
||||
for o in angobs:
|
||||
if o=='FL':
|
||||
print(f'\tS1s = {3/4*(1-dic[ibin][o])}')
|
||||
elif o=='AFB':
|
||||
print(f'\tS6s = {4/3*dic[ibin][o]}')
|
||||
else:
|
||||
print(f'\t{o} = {dic[ibin][o]}')
|
||||
|
||||
def printoutCpp(dic):
|
||||
for o in angobs:
|
||||
if o=='FL':
|
||||
print('\tS1s[8] = {')
|
||||
elif o=='AFB':
|
||||
print('\tS6s[8] = {')
|
||||
else:
|
||||
print(f'\t{o}[8] = {{')
|
||||
for ibin, q2bin in enumerate(q2bins):
|
||||
if o=='FL':
|
||||
print(f'{3/4*(1-dic[ibin][o].n)},', end='')
|
||||
elif o=='AFB':
|
||||
print(f'{4/3*dic[ibin][o].n},', end='')
|
||||
else:
|
||||
print(f'{dic[ibin][o].n},', end='')
|
||||
print(f'}};')
|
||||
for o in angobs:
|
||||
if o=='FL':
|
||||
print('\tS1s_error[8] = {')
|
||||
elif o=='AFB':
|
||||
print('\tS6s_error[8] = {')
|
||||
else:
|
||||
print(f'\t{o}_error[8] = {{')
|
||||
for ibin, q2bin in enumerate(q2bins):
|
||||
if o=='FL':
|
||||
print(f'{3/4*(dic[ibin][o].s)},', end='')
|
||||
elif o=='AFB':
|
||||
print(f'{4/3*dic[ibin][o].s},', end='')
|
||||
else:
|
||||
print(f'{dic[ibin][o].s},', end='')
|
||||
print('};')
|
||||
|
||||
|
||||
if(doSM):
|
||||
print('############## SM predictions #################')
|
||||
printout(SMpred)
|
||||
|
||||
printoutCpp(SMpred)
|
||||
|
||||
print('\n\n\n')
|
||||
|
||||
if(doNP):
|
||||
print('############## NP predictions #################')
|
||||
printout(NPpred)
|
||||
|
||||
printoutCpp(NPpred)
|
95
Code/FCNCFitter/CMakeLists.txt
Normal file
95
Code/FCNCFitter/CMakeLists.txt
Normal file
@ -0,0 +1,95 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
set(CMAKE_VERBOSE_MAKEFILE True)
|
||||
|
||||
project(FCNCFitter)
|
||||
|
||||
#get the SPDlog
|
||||
set(SPDLOG_INCLUDE_DIR "~/B2KstarMuMu/code/spdlog/include/")
|
||||
set(SPDLOG_INCLUDE_DIR_TWO "~/B2KstarMuMu/code/spdlog/include/spdlog/")
|
||||
|
||||
#Get the source dir
|
||||
set(SOURCE_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/sources/")
|
||||
|
||||
#get the GSL
|
||||
include(FindGSL.cmake)
|
||||
|
||||
#try to get ROOT
|
||||
include(FindROOT.cmake)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-g -Wall -O3 -std=c++11")
|
||||
|
||||
#specify directories
|
||||
include_directories(
|
||||
${ROOT_INCLUDE_DIR}
|
||||
${SPDLOG_INCLUDE_DIR}
|
||||
${SPDLOG_INCLUDE_DIR_TWO}
|
||||
${PROJECT_BINARY_DIR}
|
||||
${GSL_INCLUDE_DIRS}
|
||||
${SOURCE_INCLUDE_DIR}
|
||||
${SOURCE_INCLUDE_DIR}Helpers
|
||||
${SOURCE_INCLUDE_DIR}Core
|
||||
${SOURCE_INCLUDE_DIR}Run
|
||||
${SOURCE_INCLUDE_DIR}Params
|
||||
)
|
||||
link_directories(
|
||||
${ROOT_LIBRARY_DIR}
|
||||
${GSL_LIBRARY_DIRS}
|
||||
${SOURCE_INCLUDE_DIR}
|
||||
${SOURCE_INCLUDE_DIR}Helpers
|
||||
${SOURCE_INCLUDE_DIR}Core
|
||||
${SOURCE_INCLUDE_DIR}Run
|
||||
${SOURCE_INCLUDE_DIR}Params
|
||||
)
|
||||
|
||||
|
||||
# ------------------------------ Bu 2 Kst mu mu ----------------------------#
|
||||
add_executable(bu2kstarmumu bu2kstarmumu.cc
|
||||
${SOURCE_INCLUDE_DIR}Helpers/helpers.cc
|
||||
${SOURCE_INCLUDE_DIR}Core/options.cc
|
||||
${SOURCE_INCLUDE_DIR}paths.cc
|
||||
${SOURCE_INCLUDE_DIR}parse.cc
|
||||
${SOURCE_INCLUDE_DIR}Params/constants.cc
|
||||
${SOURCE_INCLUDE_DIR}Params/parameters.cc
|
||||
${SOURCE_INCLUDE_DIR}Params/parameterscan.cc
|
||||
${SOURCE_INCLUDE_DIR}Helpers/design.cc
|
||||
${SOURCE_INCLUDE_DIR}Core/fitter.cc
|
||||
${SOURCE_INCLUDE_DIR}Core/folder.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/mcfit.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/massfit.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/mainfit.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/backgroundfit.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/genlvlfit.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/momfit.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/toysfit.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/angularcorr.cc
|
||||
${SOURCE_INCLUDE_DIR}Core/bu2kstarmumu_pdf.cc
|
||||
${SOURCE_INCLUDE_DIR}Core/bu2kstarmumu_parameters.cc
|
||||
${SOURCE_INCLUDE_DIR}Core/bu2kstarmumu_generator.cc
|
||||
${SOURCE_INCLUDE_DIR}Core/bu2kstarmumu_plotter.cc
|
||||
${SOURCE_INCLUDE_DIR}Core/bu2kstarmumu_loader.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/multifit.cc
|
||||
${SOURCE_INCLUDE_DIR}Core/funcs.cc
|
||||
${SOURCE_INCLUDE_DIR}Core/integrals.cc
|
||||
${SOURCE_INCLUDE_DIR}Core/event.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/angularcorr.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/generatetoys.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/pulls.cc
|
||||
${SOURCE_INCLUDE_DIR}help.cc
|
||||
${SOURCE_INCLUDE_DIR}tests.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/likelihoodscan.cc
|
||||
${SOURCE_INCLUDE_DIR}Run/feldman_cousins.cc
|
||||
${SOURCE_INCLUDE_DIR}Scripts/RunningScripts.cc
|
||||
${SOURCE_INCLUDE_DIR}Scripts/ScriptHelpers.cc
|
||||
${SOURCE_INCLUDE_DIR}Scripts/ReferencePlots.cc
|
||||
${SOURCE_INCLUDE_DIR}Scripts/GenLvlvsMC.cc
|
||||
${SOURCE_INCLUDE_DIR}Scripts/EvaluateToys.cc
|
||||
${SOURCE_INCLUDE_DIR}Scripts/GetMeanError.cc
|
||||
)
|
||||
|
||||
#link in these libraries
|
||||
target_link_libraries(
|
||||
bu2kstarmumu
|
||||
${ROOT_LIBRARIES} Minuit MathCore GenVector pthread MathMore gsl gslcblas RooFitCore RooFit
|
||||
)
|
||||
|
||||
|
126
Code/FCNCFitter/Coeffs/Coeffs_KplusPi0Resolved_Run1.txt
Normal file
126
Code/FCNCFitter/Coeffs/Coeffs_KplusPi0Resolved_Run1.txt
Normal file
@ -0,0 +1,126 @@
|
||||
1.507323382429900e+00
|
||||
-5.613459181592237e-01
|
||||
-1.396539684676599e+00
|
||||
1.983790804262259e+00
|
||||
1.099832513149885e-01
|
||||
-2.960130056065321e+00
|
||||
-8.187336300741772e-02
|
||||
-3.952269555379559e-01
|
||||
1.902473503564140e+00
|
||||
1.291016482104303e+00
|
||||
-3.044469238695420e+00
|
||||
-1.804014854108751e+00
|
||||
-1.361226650837114e+00
|
||||
8.184400573186876e-01
|
||||
2.188187203378385e+00
|
||||
-5.268186533667468e+00
|
||||
-5.195967261112107e-01
|
||||
6.647385323311585e+00
|
||||
-1.762717917089729e-01
|
||||
-6.288537612127318e-01
|
||||
1.481671395194009e+00
|
||||
-1.329083440491552e+00
|
||||
-1.344976403314151e+00
|
||||
2.265252888334087e+00
|
||||
1.296995380042890e-01
|
||||
5.561799558311068e-01
|
||||
-2.191671996448252e+00
|
||||
-1.166820051612482e+00
|
||||
3.290509301920541e+00
|
||||
1.444268719410366e+00
|
||||
2.952333101187788e-01
|
||||
-2.679087845180141e-01
|
||||
-2.766919899388740e+00
|
||||
7.553625609611633e+00
|
||||
2.018757191268887e+00
|
||||
-8.466577152377019e+00
|
||||
3.428774063411943e-02
|
||||
3.189236174613467e-01
|
||||
-6.247951417803510e-01
|
||||
3.532986332980050e-01
|
||||
6.660176321117172e-01
|
||||
-6.783329810934459e-01
|
||||
-5.326990625397907e-02
|
||||
-1.841701555167321e-01
|
||||
8.702448804063465e-01
|
||||
1.087521378610431e-01
|
||||
-1.278422788350668e+00
|
||||
-1.481036116778629e-01
|
||||
7.077764062651405e-02
|
||||
6.735349589285888e-02
|
||||
7.946513765494528e-01
|
||||
-3.138093850225143e+00
|
||||
-6.708174701497344e-01
|
||||
3.325058606097596e+00
|
||||
-2.042990555796284e-03
|
||||
-6.101419131394252e-02
|
||||
1.120351640144091e-01
|
||||
-5.617086304979706e-02
|
||||
-1.323009868002902e-01
|
||||
1.080962174293581e-01
|
||||
1.087555224021463e-02
|
||||
2.108138237484863e-02
|
||||
-1.625620726429654e-01
|
||||
6.541798314265089e-02
|
||||
2.318935115760752e-01
|
||||
-6.898604266766525e-02
|
||||
-2.647732855321056e-02
|
||||
-1.276105538490090e-02
|
||||
-8.732345927716964e-02
|
||||
5.663342493001184e-01
|
||||
8.428725540316630e-02
|
||||
-5.842603840687339e-01
|
||||
-1.729471478606428e-05
|
||||
5.342588040003147e-03
|
||||
-1.014659802328625e-02
|
||||
5.632334609953240e-03
|
||||
1.288390058161915e-02
|
||||
-9.681241631728722e-03
|
||||
-1.139208040412161e-03
|
||||
-8.631017076588197e-04
|
||||
1.540969215410285e-02
|
||||
-1.299870138751872e-02
|
||||
-2.132315500901466e-02
|
||||
1.407968081921587e-02
|
||||
3.092489772137845e-03
|
||||
1.329021820636794e-03
|
||||
3.369803886853596e-03
|
||||
-5.142994389491435e-02
|
||||
-4.136109126106910e-03
|
||||
5.261930213060970e-02
|
||||
3.356572617668553e-06
|
||||
-2.157766379251036e-04
|
||||
4.550553445790157e-04
|
||||
-3.115654729962487e-04
|
||||
-6.027734180344174e-04
|
||||
4.626890113905933e-04
|
||||
5.696446128918103e-05
|
||||
2.855781915769282e-06
|
||||
-7.098611712007801e-04
|
||||
8.210790139906973e-04
|
||||
9.591944591790252e-04
|
||||
-8.946194333053164e-04
|
||||
-1.591053820078826e-04
|
||||
-7.535884994557332e-05
|
||||
2.602983157685458e-05
|
||||
2.342626014941303e-03
|
||||
2.714574860772960e-05
|
||||
-2.401103804179887e-03
|
||||
-4.616325947783928e-08
|
||||
3.248544926215157e-06
|
||||
-7.971468229930025e-06
|
||||
6.878251229529367e-06
|
||||
1.077620280883021e-05
|
||||
-9.033462116805898e-06
|
||||
-1.073160891944817e-06
|
||||
3.461138887560188e-07
|
||||
1.257790573371964e-05
|
||||
-1.709479499601841e-05
|
||||
-1.674682301220750e-05
|
||||
1.869135235670497e-05
|
||||
3.043794935918759e-06
|
||||
1.788377958539638e-06
|
||||
-3.035174991266011e-06
|
||||
-4.264198150380982e-05
|
||||
2.136482341139993e-06
|
||||
4.393697931906842e-05
|
560
Code/FCNCFitter/Coeffs/Coeffs_KplusPi0Resolved_Run12.txt
Normal file
560
Code/FCNCFitter/Coeffs/Coeffs_KplusPi0Resolved_Run12.txt
Normal file
@ -0,0 +1,560 @@
|
||||
1.438775795892140e+00
|
||||
0.000000000000000e+00
|
||||
-5.320173364832224e-01
|
||||
0.000000000000000e+00
|
||||
-3.344212851882981e-01
|
||||
0.000000000000000e+00
|
||||
-5.754925163685108e+00
|
||||
0.000000000000000e+00
|
||||
1.816007109971708e+00
|
||||
0.000000000000000e+00
|
||||
1.912798962994150e+01
|
||||
0.000000000000000e+00
|
||||
-5.294311772743945e+00
|
||||
0.000000000000000e+00
|
||||
-1.765717474764447e+01
|
||||
0.000000000000000e+00
|
||||
1.035719343875640e-01
|
||||
0.000000000000000e+00
|
||||
3.505275673679937e-01
|
||||
0.000000000000000e+00
|
||||
-1.182431181762031e+00
|
||||
0.000000000000000e+00
|
||||
-1.104518853405788e+01
|
||||
0.000000000000000e+00
|
||||
1.368758570762299e+01
|
||||
0.000000000000000e+00
|
||||
4.213895081025900e+01
|
||||
0.000000000000000e+00
|
||||
-2.057659828966389e+01
|
||||
0.000000000000000e+00
|
||||
-3.965291029373369e+01
|
||||
0.000000000000000e+00
|
||||
2.105191789829710e-02
|
||||
0.000000000000000e+00
|
||||
-1.076042568396231e+00
|
||||
0.000000000000000e+00
|
||||
-4.838828348266116e+00
|
||||
0.000000000000000e+00
|
||||
2.867608106739681e+01
|
||||
0.000000000000000e+00
|
||||
-1.449205650435084e+00
|
||||
0.000000000000000e+00
|
||||
-9.460419277002873e+01
|
||||
0.000000000000000e+00
|
||||
1.957689792126931e+01
|
||||
0.000000000000000e+00
|
||||
8.318481759121497e+01
|
||||
0.000000000000000e+00
|
||||
-1.175921822659067e-01
|
||||
0.000000000000000e+00
|
||||
-9.980101411716920e-02
|
||||
0.000000000000000e+00
|
||||
5.496903124677671e-01
|
||||
0.000000000000000e+00
|
||||
8.916891917008284e+00
|
||||
0.000000000000000e+00
|
||||
-1.170580962348195e+01
|
||||
0.000000000000000e+00
|
||||
-3.746018825427566e+01
|
||||
0.000000000000000e+00
|
||||
1.856713806050986e+01
|
||||
0.000000000000000e+00
|
||||
3.571052274314119e+01
|
||||
0.000000000000000e+00
|
||||
-1.576684974996945e+00
|
||||
0.000000000000000e+00
|
||||
1.160940662441611e+00
|
||||
0.000000000000000e+00
|
||||
6.936392259471095e+00
|
||||
0.000000000000000e+00
|
||||
-2.095850982890060e+01
|
||||
0.000000000000000e+00
|
||||
-6.387583012722485e+00
|
||||
0.000000000000000e+00
|
||||
7.444771339228321e+01
|
||||
0.000000000000000e+00
|
||||
-9.533586483509936e+00
|
||||
0.000000000000000e+00
|
||||
-6.469243238612529e+01
|
||||
0.000000000000000e+00
|
||||
3.786957453615991e-02
|
||||
0.000000000000000e+00
|
||||
3.717500226174972e-01
|
||||
0.000000000000000e+00
|
||||
-2.462493212458895e+00
|
||||
0.000000000000000e+00
|
||||
1.093956581812932e+00
|
||||
0.000000000000000e+00
|
||||
5.473950337904350e+00
|
||||
0.000000000000000e+00
|
||||
-8.745028987540548e+00
|
||||
0.000000000000000e+00
|
||||
-1.536248451391230e+00
|
||||
0.000000000000000e+00
|
||||
9.860862753636210e+00
|
||||
0.000000000000000e+00
|
||||
4.621331372544226e-02
|
||||
0.000000000000000e+00
|
||||
-4.579595632364576e-01
|
||||
0.000000000000000e+00
|
||||
-1.299154177622542e+00
|
||||
0.000000000000000e+00
|
||||
1.787533356786050e+01
|
||||
0.000000000000000e+00
|
||||
-1.437119161537443e+01
|
||||
0.000000000000000e+00
|
||||
-6.542883645795507e+01
|
||||
0.000000000000000e+00
|
||||
2.730054668591722e+01
|
||||
0.000000000000000e+00
|
||||
6.011327044891651e+01
|
||||
0.000000000000000e+00
|
||||
-1.864698783685063e+00
|
||||
0.000000000000000e+00
|
||||
-1.634967689639657e+00
|
||||
0.000000000000000e+00
|
||||
1.692921886694123e+01
|
||||
0.000000000000000e+00
|
||||
-6.127192950135031e+00
|
||||
0.000000000000000e+00
|
||||
-3.915030529639013e+01
|
||||
0.000000000000000e+00
|
||||
4.392774373294450e+01
|
||||
0.000000000000000e+00
|
||||
1.904377272188025e+01
|
||||
0.000000000000000e+00
|
||||
-4.301303029651035e+01
|
||||
0.000000000000000e+00
|
||||
-1.259938774581686e-01
|
||||
0.000000000000000e+00
|
||||
2.403374440219687e-01
|
||||
0.000000000000000e+00
|
||||
3.920058464318085e+00
|
||||
0.000000000000000e+00
|
||||
-1.780158724917398e+01
|
||||
0.000000000000000e+00
|
||||
8.535552497391024e+00
|
||||
0.000000000000000e+00
|
||||
6.674324979688666e+01
|
||||
0.000000000000000e+00
|
||||
-2.370770680180561e+01
|
||||
0.000000000000000e+00
|
||||
-6.041670678251972e+01
|
||||
0.000000000000000e+00
|
||||
2.087628522607423e+00
|
||||
0.000000000000000e+00
|
||||
2.464770771469158e+00
|
||||
0.000000000000000e+00
|
||||
-1.921939028738314e+01
|
||||
0.000000000000000e+00
|
||||
-5.229842394469818e-01
|
||||
0.000000000000000e+00
|
||||
5.130799215963741e+01
|
||||
0.000000000000000e+00
|
||||
-2.655248636059042e+01
|
||||
0.000000000000000e+00
|
||||
-3.360773122099580e+01
|
||||
0.000000000000000e+00
|
||||
2.475557501813477e+01
|
||||
0.000000000000000e+00
|
||||
-7.838698322371812e-02
|
||||
0.000000000000000e+00
|
||||
-2.965297143504900e-01
|
||||
0.000000000000000e+00
|
||||
1.457502312799310e+00
|
||||
0.000000000000000e+00
|
||||
8.930152409856069e-01
|
||||
0.000000000000000e+00
|
||||
-3.868115258581269e+00
|
||||
0.000000000000000e+00
|
||||
4.226114862515917e-01
|
||||
0.000000000000000e+00
|
||||
2.273180546899596e+00
|
||||
0.000000000000000e+00
|
||||
-1.646140420403231e+00
|
||||
0.000000000000000e+00
|
||||
-9.668116287533587e-02
|
||||
0.000000000000000e+00
|
||||
-2.805849371310622e-02
|
||||
0.000000000000000e+00
|
||||
1.752211731814707e+00
|
||||
0.000000000000000e+00
|
||||
-6.318249208106420e+00
|
||||
0.000000000000000e+00
|
||||
3.199216300242701e+00
|
||||
0.000000000000000e+00
|
||||
2.513222127535989e+01
|
||||
0.000000000000000e+00
|
||||
-9.657830202851095e+00
|
||||
0.000000000000000e+00
|
||||
-2.376837728625016e+01
|
||||
0.000000000000000e+00
|
||||
9.053204467103039e-01
|
||||
0.000000000000000e+00
|
||||
1.853910151336333e+00
|
||||
0.000000000000000e+00
|
||||
-9.164297735637788e+00
|
||||
0.000000000000000e+00
|
||||
-7.249514664566603e+00
|
||||
0.000000000000000e+00
|
||||
2.500666446675933e+01
|
||||
0.000000000000000e+00
|
||||
5.967401217112787e+00
|
||||
0.000000000000000e+00
|
||||
-1.750289158375252e+01
|
||||
0.000000000000000e+00
|
||||
-7.559396024990840e-01
|
||||
0.000000000000000e+00
|
||||
1.676033098208083e-01
|
||||
0.000000000000000e+00
|
||||
1.252871664355280e-01
|
||||
0.000000000000000e+00
|
||||
-3.450371185792210e+00
|
||||
0.000000000000000e+00
|
||||
6.180513796734813e+00
|
||||
0.000000000000000e+00
|
||||
6.272055273600520e-01
|
||||
0.000000000000000e+00
|
||||
-2.520713723518794e+01
|
||||
0.000000000000000e+00
|
||||
7.324827447589672e+00
|
||||
0.000000000000000e+00
|
||||
2.350577922709661e+01
|
||||
0.000000000000000e+00
|
||||
-7.820867167399690e-01
|
||||
0.000000000000000e+00
|
||||
-2.296502092281568e+00
|
||||
0.000000000000000e+00
|
||||
9.940559181227361e+00
|
||||
0.000000000000000e+00
|
||||
1.012736855723503e+01
|
||||
0.000000000000000e+00
|
||||
-3.006999831887735e+01
|
||||
0.000000000000000e+00
|
||||
-1.377134621329661e+01
|
||||
0.000000000000000e+00
|
||||
2.362261550086852e+01
|
||||
0.000000000000000e+00
|
||||
8.905596442335503e+00
|
||||
0.000000000000000e+00
|
||||
2.149207116460980e-02
|
||||
0.000000000000000e+00
|
||||
7.031058856992323e-02
|
||||
0.000000000000000e+00
|
||||
-3.123031180728542e-01
|
||||
0.000000000000000e+00
|
||||
-3.007799949021578e-01
|
||||
0.000000000000000e+00
|
||||
8.574732574133230e-01
|
||||
0.000000000000000e+00
|
||||
2.344905997231403e-01
|
||||
0.000000000000000e+00
|
||||
-5.652896727683847e-01
|
||||
0.000000000000000e+00
|
||||
7.286199721180446e-02
|
||||
0.000000000000000e+00
|
||||
3.023742831366822e-02
|
||||
0.000000000000000e+00
|
||||
4.297485729087461e-02
|
||||
0.000000000000000e+00
|
||||
-4.866306704261839e-01
|
||||
0.000000000000000e+00
|
||||
9.553783890047559e-01
|
||||
0.000000000000000e+00
|
||||
-2.339255342425295e-01
|
||||
0.000000000000000e+00
|
||||
-4.245197536727919e+00
|
||||
0.000000000000000e+00
|
||||
1.578384106607524e+00
|
||||
0.000000000000000e+00
|
||||
4.162531720344779e+00
|
||||
0.000000000000000e+00
|
||||
-1.743057528061254e-01
|
||||
0.000000000000000e+00
|
||||
-4.968851391432376e-01
|
||||
0.000000000000000e+00
|
||||
1.913858332257758e+00
|
||||
0.000000000000000e+00
|
||||
2.649020922190229e+00
|
||||
0.000000000000000e+00
|
||||
-5.519125958406552e+00
|
||||
0.000000000000000e+00
|
||||
-4.442474893656162e+00
|
||||
0.000000000000000e+00
|
||||
4.257728468427891e+00
|
||||
0.000000000000000e+00
|
||||
2.701925485057490e+00
|
||||
0.000000000000000e+00
|
||||
-4.854858473238228e-02
|
||||
0.000000000000000e+00
|
||||
-6.048564208859245e-02
|
||||
0.000000000000000e+00
|
||||
8.752156884131288e-01
|
||||
0.000000000000000e+00
|
||||
-8.890918857551118e-01
|
||||
0.000000000000000e+00
|
||||
-6.330570323714021e-01
|
||||
0.000000000000000e+00
|
||||
4.106787453833199e+00
|
||||
0.000000000000000e+00
|
||||
-1.056194598185934e+00
|
||||
0.000000000000000e+00
|
||||
-3.997273913028845e+00
|
||||
0.000000000000000e+00
|
||||
1.383613819479332e-01
|
||||
0.000000000000000e+00
|
||||
5.940126065333567e-01
|
||||
0.000000000000000e+00
|
||||
-2.027521466150096e+00
|
||||
0.000000000000000e+00
|
||||
-3.341998889425934e+00
|
||||
0.000000000000000e+00
|
||||
6.419584474162086e+00
|
||||
0.000000000000000e+00
|
||||
6.322776810847349e+00
|
||||
0.000000000000000e+00
|
||||
-5.374585908504311e+00
|
||||
0.000000000000000e+00
|
||||
-4.522040918298464e+00
|
||||
0.000000000000000e+00
|
||||
-2.352897656066623e-03
|
||||
0.000000000000000e+00
|
||||
-7.447989204307380e-03
|
||||
0.000000000000000e+00
|
||||
3.103352874560045e-02
|
||||
0.000000000000000e+00
|
||||
3.553383173326718e-02
|
||||
0.000000000000000e+00
|
||||
-8.621110594635656e-02
|
||||
0.000000000000000e+00
|
||||
-4.053840362135074e-02
|
||||
0.000000000000000e+00
|
||||
5.991926216536642e-02
|
||||
0.000000000000000e+00
|
||||
7.847601421659699e-03
|
||||
0.000000000000000e+00
|
||||
-3.742085432487565e-03
|
||||
0.000000000000000e+00
|
||||
-6.534570918236404e-03
|
||||
0.000000000000000e+00
|
||||
5.549239473395826e-02
|
||||
0.000000000000000e+00
|
||||
-7.398274330638235e-02
|
||||
0.000000000000000e+00
|
||||
4.719128880467884e-04
|
||||
0.000000000000000e+00
|
||||
3.654114392965154e-01
|
||||
0.000000000000000e+00
|
||||
-1.351046414076875e-01
|
||||
0.000000000000000e+00
|
||||
-3.695230579318745e-01
|
||||
0.000000000000000e+00
|
||||
1.638424923566694e-02
|
||||
0.000000000000000e+00
|
||||
5.578652299592122e-02
|
||||
0.000000000000000e+00
|
||||
-1.888745480474452e-01
|
||||
0.000000000000000e+00
|
||||
-3.350704991167671e-01
|
||||
0.000000000000000e+00
|
||||
5.587587719988736e-01
|
||||
0.000000000000000e+00
|
||||
6.517132932317535e-01
|
||||
0.000000000000000e+00
|
||||
-4.529197999738007e-01
|
||||
0.000000000000000e+00
|
||||
-4.372176049571402e-01
|
||||
0.000000000000000e+00
|
||||
5.776903423777896e-03
|
||||
0.000000000000000e+00
|
||||
7.741740246597733e-03
|
||||
0.000000000000000e+00
|
||||
-9.547086666506932e-02
|
||||
0.000000000000000e+00
|
||||
6.683341051161629e-02
|
||||
0.000000000000000e+00
|
||||
8.601895187072051e-02
|
||||
0.000000000000000e+00
|
||||
-3.454137856068547e-01
|
||||
0.000000000000000e+00
|
||||
8.501531873758481e-02
|
||||
0.000000000000000e+00
|
||||
3.488252097716409e-01
|
||||
0.000000000000000e+00
|
||||
-1.256900059103441e-02
|
||||
0.000000000000000e+00
|
||||
-6.654167688682400e-02
|
||||
0.000000000000000e+00
|
||||
1.967100373274677e-01
|
||||
0.000000000000000e+00
|
||||
4.178703916393939e-01
|
||||
0.000000000000000e+00
|
||||
-6.358440838511148e-01
|
||||
0.000000000000000e+00
|
||||
-8.728629242960712e-01
|
||||
0.000000000000000e+00
|
||||
5.517358147655766e-01
|
||||
0.000000000000000e+00
|
||||
6.372890315878379e-01
|
||||
0.000000000000000e+00
|
||||
1.140696533038911e-04
|
||||
0.000000000000000e+00
|
||||
3.663922480127318e-04
|
||||
0.000000000000000e+00
|
||||
-1.458502153390674e-03
|
||||
0.000000000000000e+00
|
||||
-1.858183660669370e-03
|
||||
0.000000000000000e+00
|
||||
4.093404793891319e-03
|
||||
0.000000000000000e+00
|
||||
2.524988035341650e-03
|
||||
0.000000000000000e+00
|
||||
-2.957863177921585e-03
|
||||
0.000000000000000e+00
|
||||
-9.282734944998121e-04
|
||||
0.000000000000000e+00
|
||||
2.035662853579077e-04
|
||||
0.000000000000000e+00
|
||||
3.717913837572671e-04
|
||||
0.000000000000000e+00
|
||||
-2.827739409223422e-03
|
||||
0.000000000000000e+00
|
||||
2.929121145905270e-03
|
||||
0.000000000000000e+00
|
||||
5.397922551179735e-04
|
||||
0.000000000000000e+00
|
||||
-1.573383251203580e-02
|
||||
0.000000000000000e+00
|
||||
5.886912059317175e-03
|
||||
0.000000000000000e+00
|
||||
1.627351618259381e-02
|
||||
0.000000000000000e+00
|
||||
-7.472977440972072e-04
|
||||
0.000000000000000e+00
|
||||
-2.833919021575961e-03
|
||||
0.000000000000000e+00
|
||||
8.884769325996444e-03
|
||||
0.000000000000000e+00
|
||||
1.826391554363844e-02
|
||||
0.000000000000000e+00
|
||||
-2.665885357580526e-02
|
||||
0.000000000000000e+00
|
||||
-3.818505305612446e-02
|
||||
0.000000000000000e+00
|
||||
2.232208217654531e-02
|
||||
0.000000000000000e+00
|
||||
2.666374076623913e-02
|
||||
0.000000000000000e+00
|
||||
-3.062274077050677e-04
|
||||
0.000000000000000e+00
|
||||
-3.926269966852447e-04
|
||||
0.000000000000000e+00
|
||||
4.728538004443471e-03
|
||||
0.000000000000000e+00
|
||||
-2.707697250967722e-03
|
||||
0.000000000000000e+00
|
||||
-4.470975428314534e-03
|
||||
0.000000000000000e+00
|
||||
1.488416284326369e-02
|
||||
0.000000000000000e+00
|
||||
-3.753974599926874e-03
|
||||
0.000000000000000e+00
|
||||
-1.537816905205145e-02
|
||||
0.000000000000000e+00
|
||||
5.642369912874341e-04
|
||||
0.000000000000000e+00
|
||||
3.404070095285076e-03
|
||||
0.000000000000000e+00
|
||||
-9.139585579346044e-03
|
||||
0.000000000000000e+00
|
||||
-2.280842720270515e-02
|
||||
0.000000000000000e+00
|
||||
2.983199107666091e-02
|
||||
0.000000000000000e+00
|
||||
5.014487914108524e-02
|
||||
0.000000000000000e+00
|
||||
-2.652645201170698e-02
|
||||
0.000000000000000e+00
|
||||
-3.698380769982702e-02
|
||||
0.000000000000000e+00
|
||||
-2.065795427176309e-06
|
||||
0.000000000000000e+00
|
||||
-6.805488452400124e-06
|
||||
0.000000000000000e+00
|
||||
2.624990916899325e-05
|
||||
0.000000000000000e+00
|
||||
3.633634590260819e-05
|
||||
0.000000000000000e+00
|
||||
-7.457195654258806e-05
|
||||
0.000000000000000e+00
|
||||
-5.566854143366552e-05
|
||||
0.000000000000000e+00
|
||||
5.576523316450006e-05
|
||||
0.000000000000000e+00
|
||||
2.613309135430335e-05
|
||||
0.000000000000000e+00
|
||||
-4.054639045630379e-06
|
||||
0.000000000000000e+00
|
||||
-7.364031032797539e-06
|
||||
0.000000000000000e+00
|
||||
5.335436131562981e-05
|
||||
0.000000000000000e+00
|
||||
-4.724298518908045e-05
|
||||
0.000000000000000e+00
|
||||
-1.462581314186175e-05
|
||||
0.000000000000000e+00
|
||||
2.685741849262721e-04
|
||||
0.000000000000000e+00
|
||||
-1.026565264923978e-04
|
||||
0.000000000000000e+00
|
||||
-2.819096106126082e-04
|
||||
0.000000000000000e+00
|
||||
1.320860423575568e-05
|
||||
0.000000000000000e+00
|
||||
5.373200137240333e-05
|
||||
0.000000000000000e+00
|
||||
-1.604323462283919e-04
|
||||
0.000000000000000e+00
|
||||
-3.636290109404678e-04
|
||||
0.000000000000000e+00
|
||||
4.857371511248402e-04
|
||||
0.000000000000000e+00
|
||||
7.956041706547389e-04
|
||||
0.000000000000000e+00
|
||||
-4.166319904317815e-04
|
||||
0.000000000000000e+00
|
||||
-5.687490529226589e-04
|
||||
0.000000000000000e+00
|
||||
5.984661520442252e-06
|
||||
0.000000000000000e+00
|
||||
6.959044921584107e-06
|
||||
0.000000000000000e+00
|
||||
-8.741418289565478e-05
|
||||
0.000000000000000e+00
|
||||
4.716232550343118e-05
|
||||
0.000000000000000e+00
|
||||
8.132057161200026e-05
|
||||
0.000000000000000e+00
|
||||
-2.598884274079568e-04
|
||||
0.000000000000000e+00
|
||||
6.965843319857185e-05
|
||||
0.000000000000000e+00
|
||||
2.707702291959757e-04
|
||||
0.000000000000000e+00
|
||||
-9.896688255823778e-06
|
||||
0.000000000000000e+00
|
||||
-6.508132303629572e-05
|
||||
0.000000000000000e+00
|
||||
1.636642455810912e-04
|
||||
0.000000000000000e+00
|
||||
4.552717134254304e-04
|
||||
0.000000000000000e+00
|
||||
-5.365008619516782e-04
|
||||
0.000000000000000e+00
|
||||
-1.034352404051811e-03
|
||||
0.000000000000000e+00
|
||||
4.858636040291626e-04
|
||||
0.000000000000000e+00
|
||||
7.683610839659139e-04
|
||||
0.000000000000000e+00
|
126
Code/FCNCFitter/Coeffs/Coeffs_KplusPi0Resolved_Run2.txt
Normal file
126
Code/FCNCFitter/Coeffs/Coeffs_KplusPi0Resolved_Run2.txt
Normal file
@ -0,0 +1,126 @@
|
||||
1.425748136766992e+00
|
||||
-1.125449036737295e+00
|
||||
-7.136744552272524e-01
|
||||
1.578305680181076e+00
|
||||
-4.377763974159898e-01
|
||||
-2.387538789410834e+00
|
||||
-8.192845344202955e-02
|
||||
-2.569889874363624e-01
|
||||
1.050389756021345e+00
|
||||
1.508358445254409e+00
|
||||
-1.709255073896953e+00
|
||||
-1.623905914817130e+00
|
||||
-9.987961638321898e-01
|
||||
1.238913826227640e+00
|
||||
-9.257039680312273e-01
|
||||
-3.262549344763562e+00
|
||||
2.790493060780307e+00
|
||||
5.258765220248638e+00
|
||||
-3.341911492172595e-02
|
||||
6.634160854582765e-01
|
||||
-5.153661149169929e-01
|
||||
-3.527294079469729e+00
|
||||
1.173951841944042e+00
|
||||
4.572466870718657e+00
|
||||
1.361616155836471e-01
|
||||
4.242729976067579e-01
|
||||
-1.744690199403312e+00
|
||||
-2.054796238211036e+00
|
||||
2.584640329295740e+00
|
||||
2.044285596404793e+00
|
||||
-2.369016946464934e-01
|
||||
-1.024326449238952e+00
|
||||
2.826580857637501e+00
|
||||
5.773731831490826e+00
|
||||
-4.577594345717358e+00
|
||||
-8.396164861706662e+00
|
||||
-4.700809613086387e-02
|
||||
-3.269680764772347e-01
|
||||
3.231259522763095e-01
|
||||
1.767539903326413e+00
|
||||
-5.786873772580493e-01
|
||||
-2.175521709997738e+00
|
||||
-6.331829359515367e-02
|
||||
-2.566340000037504e-01
|
||||
8.559476486570767e-01
|
||||
1.108290964043222e+00
|
||||
-1.242684217346282e+00
|
||||
-1.054089502509917e+00
|
||||
2.812292170758831e-01
|
||||
5.026814704650281e-01
|
||||
-1.403922731117348e+00
|
||||
-2.872901368663196e+00
|
||||
1.975855755802969e+00
|
||||
3.832681927283749e+00
|
||||
1.578748431273701e-02
|
||||
6.645169556355776e-02
|
||||
-7.730007858648250e-02
|
||||
-3.591182262380354e-01
|
||||
1.236061140846164e-01
|
||||
4.329110772318094e-01
|
||||
1.278085349117730e-02
|
||||
6.255803569109382e-02
|
||||
-1.753366943832027e-01
|
||||
-2.547190900416993e-01
|
||||
2.536385138348534e-01
|
||||
2.355652880287911e-01
|
||||
-6.338268751841022e-02
|
||||
-1.063582509805134e-01
|
||||
2.820726456611351e-01
|
||||
5.695638526536142e-01
|
||||
-3.745466604631191e-01
|
||||
-7.295677187875779e-01
|
||||
-1.842172996187120e-03
|
||||
-6.517383409436638e-03
|
||||
8.445085684208537e-03
|
||||
3.467474981121118e-02
|
||||
-1.277067496391555e-02
|
||||
-4.138470574691289e-02
|
||||
-1.247283942855627e-03
|
||||
-6.966658753004382e-03
|
||||
1.712580067989015e-02
|
||||
2.755171176799024e-02
|
||||
-2.487604500572418e-02
|
||||
-2.502134412061325e-02
|
||||
6.284727380487962e-03
|
||||
1.030474700520226e-02
|
||||
-2.727953805369800e-02
|
||||
-5.338299121672108e-02
|
||||
3.542039807667625e-02
|
||||
6.720039830249271e-02
|
||||
9.136215946218000e-05
|
||||
3.038524035658523e-04
|
||||
-4.222017254808240e-04
|
||||
-1.588575902326166e-03
|
||||
6.240737517321463e-04
|
||||
1.888228339227199e-03
|
||||
5.832444635778836e-05
|
||||
3.571774675736975e-04
|
||||
-7.943607158280465e-04
|
||||
-1.394302758459940e-03
|
||||
1.162747702632733e-03
|
||||
1.251779251004430e-03
|
||||
-2.917657559835222e-04
|
||||
-4.634935104904542e-04
|
||||
1.259015675253705e-03
|
||||
2.383921872787487e-03
|
||||
-1.627806229955408e-03
|
||||
-2.982637657996925e-03
|
||||
-1.660539161064591e-06
|
||||
-5.377994080863866e-06
|
||||
7.868603066291942e-06
|
||||
2.779884342547798e-05
|
||||
-1.156420644896280e-05
|
||||
-3.302485938687721e-05
|
||||
-1.050839536278033e-06
|
||||
-6.848855984921923e-06
|
||||
1.409170019941946e-05
|
||||
2.662548870051602e-05
|
||||
-2.081343532119322e-05
|
||||
-2.373813615589443e-05
|
||||
5.159095194771221e-06
|
||||
7.914832466953750e-06
|
||||
-2.223685773065029e-05
|
||||
-4.098491476249987e-05
|
||||
2.889349837723718e-05
|
||||
5.122450688753855e-05
|
104
Code/FCNCFitter/FCNCFitter.pro
Normal file
104
Code/FCNCFitter/FCNCFitter.pro
Normal file
@ -0,0 +1,104 @@
|
||||
TEMPLATE = app
|
||||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
CONFIG -= qt
|
||||
|
||||
SOURCES += bu2kstarmumu.cc \
|
||||
sources/Core/bu2kstarmumu_generator.cc \
|
||||
sources/Core/bu2kstarmumu_loader.cc \
|
||||
sources/Core/bu2kstarmumu_parameters.cc \
|
||||
sources/Core/bu2kstarmumu_pdf.cc \
|
||||
sources/Core/bu2kstarmumu_plotter.cc \
|
||||
sources/Core/event.cc \
|
||||
sources/Core/fitter.cc \
|
||||
sources/Core/folder.cc \
|
||||
sources/Core/funcs.cc \
|
||||
sources/Core/integrals.cc \
|
||||
sources/Core/options.cc \
|
||||
sources/Core/toystudy.cc \
|
||||
sources/Helpers/design.cc \
|
||||
sources/Helpers/helpers.cc \
|
||||
sources/Params/constants.cc \
|
||||
sources/Params/parameters.cc \
|
||||
sources/Params/parameterscan.cc \
|
||||
sources/Run/angularcorr.cc \
|
||||
sources/Run/backgroundfit.cc \
|
||||
sources/Run/feldman_cousins.cc \
|
||||
sources/Run/generatetoys.cc \
|
||||
sources/Run/genlvlfit.cc \
|
||||
sources/Run/likelihoodscan.cc \
|
||||
sources/Run/mainfit.cc \
|
||||
sources/Run/massfit.cc \
|
||||
sources/Run/mcfit.cc \
|
||||
sources/Run/momfit.cc \
|
||||
sources/Run/multifit.cc \
|
||||
sources/Run/pulls.cc \
|
||||
sources/Run/toysfit.cc \
|
||||
sources/Scripts/GenLvlvsMC.cc \
|
||||
sources/Scripts/GetMeanError.cc \
|
||||
sources/Scripts/PlotMCfit.cc \
|
||||
sources/Scripts/ReferencePlots.cc \
|
||||
sources/Scripts/RunningScripts.cc \
|
||||
sources/Scripts/ScriptHelpers.cc \
|
||||
sources/Scripts/EvaluateToys.cc \
|
||||
sources/help.cc \
|
||||
sources/parse.cc \
|
||||
sources/paths.cc \
|
||||
sources/tests.cc
|
||||
|
||||
HEADERS += sources/Core/bu2kstarmumu_generator.hh \
|
||||
sources/Core/bu2kstarmumu_loader.hh \
|
||||
sources/Core/bu2kstarmumu_parameters.hh \
|
||||
sources/Core/bu2kstarmumu_pdf.hh \
|
||||
sources/Core/bu2kstarmumu_plotter.hh \
|
||||
sources/Core/event.hh \
|
||||
sources/Core/fitter.hh \
|
||||
sources/Core/folder.hh \
|
||||
sources/Core/funcs.hh \
|
||||
sources/Core/generator.hh \
|
||||
sources/Core/integrals.hh \
|
||||
sources/Core/options.hh \
|
||||
sources/Core/pdf.hh \
|
||||
sources/Core/plotter.hh \
|
||||
sources/Core/toystudy.hh \
|
||||
sources/Helpers/colors.hh \
|
||||
sources/Helpers/design.hh \
|
||||
sources/Helpers/helpers.hh \
|
||||
sources/Params/constants.hh \
|
||||
sources/Params/parameters.hh \
|
||||
sources/Params/parameterscan.hh \
|
||||
sources/Params/values.hh \
|
||||
sources/Run/angularcorr.hh \
|
||||
sources/Run/backgroundfit.hh \
|
||||
sources/Run/feldman_cousins.hh \
|
||||
sources/Run/generatetoys.hh \
|
||||
sources/Run/genlvlfit.hh \
|
||||
sources/Run/likelihoodscan.hh \
|
||||
sources/Run/mainfit.hh \
|
||||
sources/Run/massfit.hh \
|
||||
sources/Run/mcfit.hh \
|
||||
sources/Run/momfit.hh \
|
||||
sources/Run/multifit.hh \
|
||||
sources/Run/pulls.hh \
|
||||
sources/Run/toysfit.hh \
|
||||
sources/Scripts/GenLvlvsMC.hh \
|
||||
sources/Scripts/GetMeanError.hh \
|
||||
sources/Scripts/PlotMCfit.hh \
|
||||
sources/Scripts/ReferencePlots.hh \
|
||||
sources/Scripts/RunningScripts.hh \
|
||||
sources/Scripts/ScriptHelpers.hh \
|
||||
sources/Scripts/EvaluateToys.hh \
|
||||
sources/help.hh \
|
||||
sources/parse.hh \
|
||||
sources/paths.hh \
|
||||
sources/tests.hh
|
||||
|
||||
INCLUDEPATH +=/home/renata/B2KMuMu/sigma0/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter/sources/
|
||||
INCLUDEPATH +=/home/renata/B2KMuMu/sigma0/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter/sources/Core/
|
||||
INCLUDEPATH +=/home/renata/B2KMuMu/sigma0/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter/sources/Helpers/
|
||||
INCLUDEPATH +=/home/renata/B2KMuMu/sigma0/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter/sources/Params/
|
||||
INCLUDEPATH +=/home/renata/B2KMuMu/sigma0/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter/sources/Run/
|
||||
INCLUDEPATH +=/home/lhcb/kopecna/B2KstarMuMu/code/spdlog/include/spdlog/
|
||||
|
||||
unix: CONFIG += link_pkgconfig
|
||||
unix: PKGCONFIG += /usr/local/root/build/lib/pkgconfig/liblzma.pc
|
153
Code/FCNCFitter/FindGSL.cmake
Normal file
153
Code/FCNCFitter/FindGSL.cmake
Normal file
@ -0,0 +1,153 @@
|
||||
# Try to find gnu scientific library GSL
|
||||
# See
|
||||
# http://www.gnu.org/software/gsl/ and
|
||||
# http://gnuwin32.sourceforge.net/packages/gsl.htm
|
||||
#
|
||||
# Based on a script of Felix Woelk and Jan Woetzel
|
||||
# (www.mip.informatik.uni-kiel.de)
|
||||
#
|
||||
# It defines the following variables:
|
||||
# GSL_FOUND - system has GSL lib
|
||||
# GSL_INCLUDE_DIRS - where to find headers
|
||||
# GSL_LIBRARIES - full path to the libraries
|
||||
# GSL_LIBRARY_DIRS, the directory where the PLplot library is found.
|
||||
# GSL_CFLAGS, additional c (c++) required
|
||||
|
||||
message(STATUS "Look for GSL in folder: $ENV{GSL_DIR}")
|
||||
|
||||
set( GSL_FOUND OFF )
|
||||
set( GSL_CBLAS_FOUND OFF )
|
||||
|
||||
if(GSL_INCLUDE_DIR OR GSL_CONFIG_EXECUTABLE)
|
||||
set(GSL_FIND_QUIETLY 1)
|
||||
endif()
|
||||
|
||||
# Windows, but not for Cygwin and MSys where gsl-config is available
|
||||
if( WIN32 AND NOT CYGWIN AND NOT MSYS )
|
||||
# look for headers
|
||||
find_path( GSL_INCLUDE_DIR
|
||||
NAMES gsl/gsl_cdf.h gsl/gsl_randist.h
|
||||
PATHS $ENV{GSL_DIR}/include ${GSL_DIR}/include
|
||||
)
|
||||
if( GSL_INCLUDE_DIR )
|
||||
# look for gsl library
|
||||
find_library( GSL_LIBRARY
|
||||
NAMES gsl
|
||||
PATHS $ENV{GSL_DIR}/lib ${GSL_DIR}/lib
|
||||
)
|
||||
if( GSL_LIBRARY )
|
||||
set( GSL_INCLUDE_DIRS ${GSL_INCLUDE_DIR} )
|
||||
get_filename_component( GSL_LIBRARY_DIRS ${GSL_LIBRARY} PATH )
|
||||
set( GSL_FOUND ON )
|
||||
endif( GSL_LIBRARY )
|
||||
|
||||
# look for gsl cblas library
|
||||
find_library( GSL_CBLAS_LIBRARY
|
||||
NAMES gslcblas
|
||||
PATHS $ENV{GSL_DIR}/lib ${GSL_DIR}/lib
|
||||
)
|
||||
if( GSL_CBLAS_LIBRARY )
|
||||
set( GSL_CBLAS_FOUND ON )
|
||||
endif( GSL_CBLAS_LIBRARY )
|
||||
|
||||
set( GSL_LIBRARIES ${GSL_LIBRARY} ${GSL_CBLAS_LIBRARY} )
|
||||
set( GSL_CFLAGS "-DGSL_DLL")
|
||||
endif( GSL_INCLUDE_DIR )
|
||||
|
||||
mark_as_advanced(
|
||||
GSL_INCLUDE_DIR
|
||||
GSL_LIBRARY
|
||||
GSL_CBLAS_LIBRARY
|
||||
)
|
||||
else( WIN32 AND NOT CYGWIN AND NOT MSYS )
|
||||
if( UNIX OR MSYS )
|
||||
find_program( GSL_CONFIG_EXECUTABLE gsl-config
|
||||
$ENV{GSL_DIR}/bin
|
||||
${GSL_DIR}/bin
|
||||
/usr/bin/
|
||||
/usr/local/bin
|
||||
)
|
||||
|
||||
if( GSL_CONFIG_EXECUTABLE )
|
||||
set( GSL_FOUND ON )
|
||||
|
||||
# run the gsl-config program to get cxxflags
|
||||
execute_process(
|
||||
COMMAND sh "${GSL_CONFIG_EXECUTABLE}" --cflags
|
||||
OUTPUT_VARIABLE GSL_CFLAGS
|
||||
RESULT_VARIABLE RET
|
||||
ERROR_QUIET
|
||||
)
|
||||
if( RET EQUAL 0 )
|
||||
string( STRIP "${GSL_CFLAGS}" GSL_CFLAGS )
|
||||
separate_arguments( GSL_CFLAGS )
|
||||
|
||||
# parse definitions from cflags; drop -D* from CFLAGS
|
||||
string( REGEX MATCHALL "-D[^;]+"
|
||||
GSL_DEFINITIONS "${GSL_CFLAGS}" )
|
||||
string( REGEX REPLACE "-D[^;]+;" ""
|
||||
GSL_CFLAGS "${GSL_CFLAGS}" )
|
||||
|
||||
# parse include dirs from cflags; drop -I prefix
|
||||
string( REGEX MATCHALL "-I[^;]+"
|
||||
GSL_INCLUDE_DIRS "${GSL_CFLAGS}" )
|
||||
string( REPLACE "-I" ""
|
||||
GSL_INCLUDE_DIRS "${GSL_INCLUDE_DIRS}")
|
||||
string( REGEX REPLACE "-I[^;]+;" ""
|
||||
GSL_CFLAGS "${GSL_CFLAGS}")
|
||||
else( RET EQUAL 0 )
|
||||
set( GSL_FOUND FALSE )
|
||||
endif( RET EQUAL 0 )
|
||||
|
||||
# run the gsl-config program to get the libs
|
||||
execute_process(
|
||||
COMMAND sh "${GSL_CONFIG_EXECUTABLE}" --libs
|
||||
OUTPUT_VARIABLE GSL_LIBRARIES
|
||||
RESULT_VARIABLE RET
|
||||
ERROR_QUIET
|
||||
)
|
||||
if( RET EQUAL 0 )
|
||||
string(STRIP "${GSL_LIBRARIES}" GSL_LIBRARIES )
|
||||
separate_arguments( GSL_LIBRARIES )
|
||||
|
||||
# extract linkdirs (-L) for rpath (i.e., LINK_DIRECTORIES)
|
||||
string( REGEX MATCHALL "-L[^;]+"
|
||||
GSL_LIBRARY_DIRS "${GSL_LIBRARIES}" )
|
||||
string( REPLACE "-L" ""
|
||||
GSL_LIBRARY_DIRS "${GSL_LIBRARY_DIRS}" )
|
||||
else( RET EQUAL 0 )
|
||||
set( GSL_FOUND FALSE )
|
||||
endif( RET EQUAL 0 )
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
GSL_CFLAGS
|
||||
)
|
||||
if(NOT GSL_FIND_QUIETLY)
|
||||
execute_process(
|
||||
COMMAND sh "${GSL_CONFIG_EXECUTABLE}" --prefix
|
||||
OUTPUT_VARIABLE GSL_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
message( STATUS "Using GSL from ${GSL_PREFIX}")
|
||||
endif()
|
||||
else( GSL_CONFIG_EXECUTABLE )
|
||||
message( STATUS "FindGSL: gsl-config not found.")
|
||||
endif( GSL_CONFIG_EXECUTABLE )
|
||||
endif( UNIX OR MSYS )
|
||||
endif( WIN32 AND NOT CYGWIN AND NOT MSYS )
|
||||
|
||||
if( GSL_FOUND )
|
||||
if( NOT GSL_FIND_QUIETLY )
|
||||
message( STATUS "Found GSL: ${GSL_INCLUDE_DIRS} ${GSL_LIBRARIES}" )
|
||||
endif( NOT GSL_FIND_QUIETLY )
|
||||
else( GSL_FOUND )
|
||||
if( GSL_FIND_REQUIRED )
|
||||
message( FATAL_ERROR "FindGSL: Could not find GSL headers or library" )
|
||||
endif( GSL_FIND_REQUIRED )
|
||||
endif( GSL_FOUND )
|
||||
|
||||
mark_as_advanced(
|
||||
GSL_CONFIG_EXECUTABLE
|
||||
GSL_INCLUDE_DIR
|
||||
GSL_LIBRARY
|
||||
GSL_CBLAS_LIBRARY
|
||||
)
|
||||
|
270
Code/FCNCFitter/FindROOT.cmake
Normal file
270
Code/FCNCFitter/FindROOT.cmake
Normal file
@ -0,0 +1,270 @@
|
||||
# - Find ROOT instalation
|
||||
# This module tries to find the ROOT installation on your system.
|
||||
# It tries to find the root-config script which gives you all the needed information.
|
||||
# If the system variable ROOTSYS is set this is straight forward.
|
||||
# If not the module uses the pathes given in ROOT_CONFIG_SEARCHPATH.
|
||||
# If you need an other path you should add this path to this varaible.
|
||||
# The root-config script is then used to detect basically everything else.
|
||||
# This module defines a number of key variables and macros.
|
||||
|
||||
# F.Uhlig@gsi.de (fairroot.gsi.de)
|
||||
|
||||
|
||||
MESSAGE(STATUS "Looking for Root...")
|
||||
|
||||
SET(ROOT_CONFIG_SEARCHPATH
|
||||
${SIMPATH}/tools/root/bin
|
||||
$ENV{ROOTSYS}/bin
|
||||
/usr/bin
|
||||
)
|
||||
|
||||
SET(ROOT_DEFINITIONS "")
|
||||
|
||||
SET(ROOT_INSTALLED_VERSION_TOO_OLD FALSE)
|
||||
|
||||
SET(ROOT_CONFIG_EXECUTABLE ROOT_CONFIG_EXECUTABLE-NOTFOUND)
|
||||
|
||||
FIND_PROGRAM(ROOT_CONFIG_EXECUTABLE NAMES root-config PATHS
|
||||
${ROOT_CONFIG_SEARCHPATH}
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
IF (${ROOT_CONFIG_EXECUTABLE} MATCHES "ROOT_CONFIG_EXECUTABLE-NOTFOUND")
|
||||
MESSAGE( FATAL_ERROR "ROOT not installed in the searchpath and ROOTSYS is not set. Please
|
||||
set ROOTSYS or add the path to your ROOT installation in the Macro FindROOT.cmake in the
|
||||
subdirectory cmake/modules.")
|
||||
ELSE (${ROOT_CONFIG_EXECUTABLE} MATCHES "ROOT_CONFIG_EXECUTABLE-NOTFOUND")
|
||||
STRING(REGEX REPLACE "(^.*)/bin/root-config" "\\1" test ${ROOT_CONFIG_EXECUTABLE})
|
||||
SET( ENV{ROOTSYS} ${test})
|
||||
set( ROOTSYS ${test})
|
||||
ENDIF (${ROOT_CONFIG_EXECUTABLE} MATCHES "ROOT_CONFIG_EXECUTABLE-NOTFOUND")
|
||||
|
||||
|
||||
IF (ROOT_CONFIG_EXECUTABLE)
|
||||
|
||||
SET(ROOT_FOUND FALSE)
|
||||
|
||||
EXEC_PROGRAM(${ROOT_CONFIG_EXECUTABLE} ARGS "--version" OUTPUT_VARIABLE ROOTVERSION)
|
||||
|
||||
MESSAGE(STATUS "Looking for Root... - found $ENV{ROOTSYS}/bin/root")
|
||||
MESSAGE(STATUS "Looking for Root... - version ${ROOTVERSION} ")
|
||||
|
||||
# we need at least version 6.00/00
|
||||
IF (NOT ROOT_MIN_VERSION)
|
||||
SET(ROOT_MIN_VERSION "6.00/00")
|
||||
ENDIF (NOT ROOT_MIN_VERSION)
|
||||
|
||||
# now parse the parts of the user given version string into variables
|
||||
STRING(REGEX REPLACE "^([0-9]+)\\.[0-9][0-9]+\\/[0-9][0-9]+" "\\1" req_root_major_vers "${ROOT_MIN_VERSION}")
|
||||
STRING(REGEX REPLACE "^[0-9]+\\.([0-9][0-9])+\\/[0-9][0-9]+.*" "\\1" req_root_minor_vers "${ROOT_MIN_VERSION}")
|
||||
STRING(REGEX REPLACE "^[0-9]+\\.[0-9][0-9]+\\/([0-9][0-9]+)" "\\1" req_root_patch_vers "${ROOT_MIN_VERSION}")
|
||||
|
||||
# and now the version string given by qmake
|
||||
STRING(REGEX REPLACE "^([0-9]+)\\.[0-9][0-9]+\\/[0-9][0-9]+.*" "\\1" found_root_major_vers "${ROOTVERSION}")
|
||||
STRING(REGEX REPLACE "^[0-9]+\\.([0-9][0-9])+\\/[0-9][0-9]+.*" "\\1" found_root_minor_vers "${ROOTVERSION}")
|
||||
STRING(REGEX REPLACE "^[0-9]+\\.[0-9][0-9]+\\/([0-9][0-9]+).*" "\\1" found_root_patch_vers "${ROOTVERSION}")
|
||||
|
||||
IF (found_root_major_vers LESS 5)
|
||||
MESSAGE( FATAL_ERROR "Invalid ROOT version \"${ROOTERSION}\", at least major version 4 is required, e.g. \"5.00/00\"")
|
||||
ENDIF (found_root_major_vers LESS 5)
|
||||
|
||||
# compute an overall version number which can be compared at once
|
||||
MATH(EXPR req_vers "${req_root_major_vers}*10000 + ${req_root_minor_vers}*100 + ${req_root_patch_vers}")
|
||||
MATH(EXPR found_vers "${found_root_major_vers}*10000 + ${found_root_minor_vers}*100 + ${found_root_patch_vers}")
|
||||
|
||||
IF (found_vers LESS req_vers)
|
||||
SET(ROOT_FOUND FALSE)
|
||||
SET(ROOT_INSTALLED_VERSION_TOO_OLD TRUE)
|
||||
ELSE (found_vers LESS req_vers)
|
||||
SET(ROOT_FOUND TRUE)
|
||||
ENDIF (found_vers LESS req_vers)
|
||||
|
||||
ENDIF (ROOT_CONFIG_EXECUTABLE)
|
||||
|
||||
|
||||
IF (ROOT_FOUND)
|
||||
|
||||
# ask root-config for the library dir
|
||||
# Set ROOT_LIBRARY_DIR
|
||||
|
||||
EXEC_PROGRAM( ${ROOT_CONFIG_EXECUTABLE}
|
||||
ARGS "--libdir"
|
||||
OUTPUT_VARIABLE ROOT_LIBRARY_DIR_TMP )
|
||||
|
||||
IF(EXISTS "${ROOT_LIBRARY_DIR_TMP}")
|
||||
SET(ROOT_LIBRARY_DIR ${ROOT_LIBRARY_DIR_TMP} )
|
||||
ELSE(EXISTS "${ROOT_LIBRARY_DIR_TMP}")
|
||||
MESSAGE("Warning: ROOT_CONFIG_EXECUTABLE reported ${ROOT_LIBRARY_DIR_TMP} as library path,")
|
||||
MESSAGE("Warning: but ${ROOT_LIBRARY_DIR_TMP} does NOT exist, ROOT must NOT be installed correctly.")
|
||||
ENDIF(EXISTS "${ROOT_LIBRARY_DIR_TMP}")
|
||||
|
||||
# ask root-config for the binary dir
|
||||
EXEC_PROGRAM(${ROOT_CONFIG_EXECUTABLE}
|
||||
ARGS "--bindir"
|
||||
OUTPUT_VARIABLE root_bins )
|
||||
SET(ROOT_BINARY_DIR ${root_bins})
|
||||
|
||||
# ask root-config for the include dir
|
||||
EXEC_PROGRAM( ${ROOT_CONFIG_EXECUTABLE}
|
||||
ARGS "--incdir"
|
||||
OUTPUT_VARIABLE root_headers )
|
||||
SET(ROOT_INCLUDE_DIR ${root_headers})
|
||||
# CACHE INTERNAL "")
|
||||
|
||||
# ask root-config for the library varaibles
|
||||
EXEC_PROGRAM( ${ROOT_CONFIG_EXECUTABLE}
|
||||
# ARGS "--noldflags --noauxlibs --libs"
|
||||
ARGS "--glibs"
|
||||
OUTPUT_VARIABLE root_flags )
|
||||
|
||||
# STRING(REGEX MATCHALL "([^ ])+" root_libs_all ${root_flags})
|
||||
# STRING(REGEX MATCHALL "-L([^ ])+" root_library ${root_flags})
|
||||
# REMOVE_FROM_LIST(root_flags "${root_libs_all}" "${root_library}")
|
||||
|
||||
SET(ROOT_LIBRARIES ${root_flags})
|
||||
|
||||
# Make variables changeble to the advanced user
|
||||
MARK_AS_ADVANCED( ROOT_LIBRARY_DIR ROOT_INCLUDE_DIR ROOT_DEFINITIONS)
|
||||
|
||||
# Set ROOT_INCLUDES
|
||||
SET( ROOT_INCLUDES ${ROOT_INCLUDE_DIR})
|
||||
|
||||
SET(LD_LIBRARY_PATH ${LD_LIBRARY_PATH} ${ROOT_LIBRARY_DIR})
|
||||
|
||||
#######################################
|
||||
#
|
||||
# Check the executables of ROOT
|
||||
# ( rootcint )
|
||||
#
|
||||
#######################################
|
||||
|
||||
FIND_PROGRAM(ROOT_CINT_EXECUTABLE
|
||||
NAMES rootcint
|
||||
PATHS ${ROOT_BINARY_DIR}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
ENDIF (ROOT_FOUND)
|
||||
|
||||
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Macros for building ROOT dictionary
|
||||
#
|
||||
###########################################
|
||||
|
||||
MACRO (ROOT_GENERATE_DICTIONARY_OLD )
|
||||
|
||||
set(INFILES "")
|
||||
|
||||
foreach (_current_FILE ${ARGN})
|
||||
|
||||
IF (${_current_FILE} MATCHES "^.*\\.h$")
|
||||
IF (${_current_FILE} MATCHES "^.*Link.*$")
|
||||
set(LINKDEF_FILE ${_current_FILE})
|
||||
ELSE (${_current_FILE} MATCHES "^.*Link.*$")
|
||||
set(INFILES ${INFILES} ${_current_FILE})
|
||||
ENDIF (${_current_FILE} MATCHES "^.*Link.*$")
|
||||
ELSE (${_current_FILE} MATCHES "^.*\\.h$")
|
||||
IF (${_current_FILE} MATCHES "^.*\\.cxx$")
|
||||
set(OUTFILE ${_current_FILE})
|
||||
ELSE (${_current_FILE} MATCHES "^.*\\.cxx$")
|
||||
set(INCLUDE_DIRS ${INCLUDE_DIRS} -I${_current_FILE})
|
||||
ENDIF (${_current_FILE} MATCHES "^.*\\.cxx$")
|
||||
ENDIF (${_current_FILE} MATCHES "^.*\\.h$")
|
||||
|
||||
endforeach (_current_FILE ${ARGN})
|
||||
|
||||
# MESSAGE("INFILES: ${INFILES}")
|
||||
# MESSAGE("OutFILE: ${OUTFILE}")
|
||||
# MESSAGE("LINKDEF_FILE: ${LINKDEF_FILE}")
|
||||
# MESSAGE("INCLUDE_DIRS: ${INCLUDE_DIRS}")
|
||||
|
||||
STRING(REGEX REPLACE "(^.*).cxx" "\\1.h" bla "${OUTFILE}")
|
||||
# MESSAGE("BLA: ${bla}")
|
||||
SET (OUTFILES ${OUTFILE} ${bla})
|
||||
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${OUTFILES}
|
||||
COMMAND ${ROOT_CINT_EXECUTABLE}
|
||||
ARGS -f ${OUTFILE} -c -DHAVE_CONFIG_H ${INCLUDE_DIRS} ${INFILES} ${LINKDEF_FILE} DEPENDS ${INFILES})
|
||||
|
||||
# MESSAGE("ROOT_CINT_EXECUTABLE has created the dictionary ${OUTFILE}")
|
||||
|
||||
ENDMACRO (ROOT_GENERATE_DICTIONARY_OLD)
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Macros for building ROOT dictionary
|
||||
#
|
||||
###########################################
|
||||
|
||||
MACRO (ROOT_GENERATE_DICTIONARY INFILES LINKDEF_FILE OUTFILE INCLUDE_DIRS_IN)
|
||||
|
||||
set(INCLUDE_DIRS)
|
||||
|
||||
foreach (_current_FILE ${INCLUDE_DIRS_IN})
|
||||
set(INCLUDE_DIRS ${INCLUDE_DIRS} -I${_current_FILE})
|
||||
endforeach (_current_FILE ${INCLUDE_DIRS_IN})
|
||||
|
||||
|
||||
# MESSAGE("INFILES: ${INFILES}")
|
||||
# MESSAGE("OutFILE: ${OUTFILE}")
|
||||
# MESSAGE("LINKDEF_FILE: ${LINKDEF_FILE}")
|
||||
# MESSAGE("INCLUDE_DIRS: ${INCLUDE_DIRS}")
|
||||
|
||||
STRING(REGEX REPLACE "^(.*)\\.(.*)$" "\\1.h" bla "${OUTFILE}")
|
||||
# MESSAGE("BLA: ${bla}")
|
||||
SET (OUTFILES ${OUTFILE} ${bla})
|
||||
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES Linux)
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${OUTFILES}
|
||||
COMMAND LD_LIBRARY_PATH=${ROOT_LIBRARY_DIR} ROOTSYS=${ROOTSYS} ${ROOT_CINT_EXECUTABLE}
|
||||
ARGS -f ${OUTFILE} -c -DHAVE_CONFIG_H ${INCLUDE_DIRS} ${INFILES} ${LINKDEF_FILE} DEPENDS ${INFILES} ${LINKDEF_FILE})
|
||||
else (CMAKE_SYSTEM_NAME MATCHES Linux)
|
||||
if (CMAKE_SYSTEM_NAME MATCHES Darwin)
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${OUTFILES}
|
||||
COMMAND DYLD_LIBRARY_PATH=${ROOT_LIBRARY_DIR} ROOTSYS=${ROOTSYS} ${ROOT_CINT_EXECUTABLE}
|
||||
ARGS -f ${OUTFILE} -c -DHAVE_CONFIG_H ${INCLUDE_DIRS} ${INFILES} ${LINKDEF_FILE} DEPENDS ${INFILES} ${LINKDEF_FILE})
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES Darwin)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES Linux)
|
||||
|
||||
ENDMACRO (ROOT_GENERATE_DICTIONARY)
|
||||
|
||||
MACRO (GENERATE_ROOT_TEST_SCRIPT SCRIPT_FULL_NAME)
|
||||
|
||||
get_filename_component(path_name ${SCRIPT_FULL_NAME} PATH)
|
||||
get_filename_component(file_extension ${SCRIPT_FULL_NAME} EXT)
|
||||
get_filename_component(file_name ${SCRIPT_FULL_NAME} NAME_WE)
|
||||
set(shell_script_name "${file_name}.sh")
|
||||
|
||||
#MESSAGE("PATH: ${path_name}")
|
||||
#MESSAGE("Ext: ${file_extension}")
|
||||
#MESSAGE("Name: ${file_name}")
|
||||
#MESSAGE("Shell Name: ${shell_script_name}")
|
||||
|
||||
string(REPLACE ${PROJECT_SOURCE_DIR}
|
||||
${PROJECT_BINARY_DIR} new_path ${path_name}
|
||||
)
|
||||
|
||||
#MESSAGE("New PATH: ${new_path}")
|
||||
|
||||
file(MAKE_DIRECTORY ${new_path}/data)
|
||||
|
||||
CONVERT_LIST_TO_STRING(${LD_LIBRARY_PATH})
|
||||
set(MY_LD_LIBRARY_PATH ${output})
|
||||
set(my_script_name ${SCRIPT_FULL_NAME})
|
||||
|
||||
if(CMAKE_SYSTEM MATCHES Darwin)
|
||||
configure_file(${PROJECT_SOURCE_DIR}/cmake/scripts/root_macro_macos.sh.in
|
||||
${new_path}/${shell_script_name}
|
||||
)
|
||||
else(CMAKE_SYSTEM MATCHES Darwin)
|
||||
configure_file(${PROJECT_SOURCE_DIR}/cmake/scripts/root_macro.sh.in
|
||||
${new_path}/${shell_script_name}
|
||||
)
|
||||
endif(CMAKE_SYSTEM MATCHES Darwin)
|
||||
|
||||
EXEC_PROGRAM(/bin/chmod ARGS "u+x ${new_path}/${shell_script_name}")
|
||||
|
||||
ENDMACRO (GENERATE_ROOT_TEST_SCRIPT)
|
0
Code/FCNCFitter/LaTeXfiles/fileForGit
Normal file
0
Code/FCNCFitter/LaTeXfiles/fileForGit
Normal file
4
Code/FCNCFitter/SetPaths.sh
Normal file
4
Code/FCNCFitter/SetPaths.sh
Normal file
@ -0,0 +1,4 @@
|
||||
#configuration of source and lib paths to compile FCNCfitter
|
||||
LD_LIBRARY_PATH=/cvmfs/lhcb.cern.ch/lib/lcg/releases/gcc/4.9.3/x86_64-slc6/lib64:/cvmfs/lhcb.cern.ch/lib/lcg/releases/LCG_84/ROOT/6.06.02/x86_64-slc6-gcc49-opt/lib
|
||||
|
||||
PATH=/cvmfs/lhcb.cern.ch/lib/lcg/releases/LCG_84/gcc/4.9.3/x86_64-slc6/bin:/cvmfs/lhcb.cern.ch/lib/lcg/releases/LCG_84/ROOT/6.06.02/x86_64-slc6-gcc49-opt/bin:/cvmfs/lhcb.cern.ch/lib/lcg/releases/gcc/4.9.3/x86_64-slc6/bin:/usr/sue/bin:/usr/lib64/qt-3.3/bin:/cvmfs/lhcb.cern.ch/lib/bin/x86_64-slc6:/cvmfs/lhcb.cern.ch/lib/bin/Linux-x86_64:/cvmfs/lhcb.cern.ch/lib/bin:/cvmfs/lhcb.cern.ch/lib/var/lib/LbEnv/1020/stable/linux-64/bin:/bin:/usr/bin:/usr/sbin:/sbin
|
412
Code/FCNCFitter/bu2kstarmumu.cc
Normal file
412
Code/FCNCFitter/bu2kstarmumu.cc
Normal file
@ -0,0 +1,412 @@
|
||||
/**
|
||||
* @file bu2kstarmumu.cc
|
||||
* @author Christoph Langenbruch, David Gerick, Renata Kopecna
|
||||
* @date 2020-30-11
|
||||
*
|
||||
* Main control file for the Bu -> K*+mumu analysis
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
|
||||
//Yes, I know that <> is not ideal for compilation time,
|
||||
//but I was lazy to always put the correct path there at the begining
|
||||
//when files were moved around rather often
|
||||
#include <parameters.hh>
|
||||
#include <parse.hh>
|
||||
#include <toystudy.hh>
|
||||
#include <angularcorr.hh>
|
||||
#include <massfit.hh>
|
||||
#include <mainfit.hh>
|
||||
#include <backgroundfit.hh>
|
||||
#include <mcfit.hh>
|
||||
#include <momfit.hh>
|
||||
#include <genlvlfit.hh>
|
||||
#include <toysfit.hh>
|
||||
#include <help.hh>
|
||||
#include <constants.hh>
|
||||
#include <generatetoys.hh>
|
||||
#include <helpers.hh>
|
||||
#include <event.hh>
|
||||
#include <design.hh>
|
||||
#include <paths.hh>
|
||||
|
||||
#include "sources/Scripts/RunningScripts.hh"
|
||||
|
||||
#include <TROOT.h>
|
||||
#include <colors.hh>
|
||||
|
||||
|
||||
int main ( int argc, char *argv[] )
|
||||
{
|
||||
//Set gROOT and gStyle
|
||||
gROOT->SetStyle("Plain");
|
||||
set_gStyle();
|
||||
//Initiliaze pretty colors
|
||||
myColorScheme::init();
|
||||
//gStyle->SetPaintTextFormat("4.1f m");
|
||||
//gStyle->SetCanvasPreferGL(true);
|
||||
|
||||
///set the fitting options
|
||||
fcnc::options opts;
|
||||
opts = fcnc::options("-1");
|
||||
|
||||
//how many events should be taken per Test/ToyFit?
|
||||
UInt_t nMCEvents = 350;
|
||||
|
||||
|
||||
//Retun errors:
|
||||
//1: wrong options
|
||||
//5: Inexplicable stuff
|
||||
//404: not found
|
||||
|
||||
basic_params pars = basic_params();
|
||||
basic_actions acts = basic_actions();
|
||||
//The pars and acts are a bit wonky at the moment, hopefully as I progress this will get better
|
||||
if (parseOpts(argc, argv, pars, acts, nMCEvents) == 1) return 1;
|
||||
if (checkOpts(pars,acts) == 1) return 1;
|
||||
|
||||
//Set opts.folding according to the parsed options
|
||||
//default should be -1
|
||||
opts.folding = pars.folding;
|
||||
|
||||
////////////////////////////////////////////
|
||||
// [START] GLOBAL OPTIONS
|
||||
////////////////////////////////////////////
|
||||
|
||||
//Use only DTF, could be removed
|
||||
opts.DTF = true;
|
||||
|
||||
//SET OUTPUT DESIGN
|
||||
reset_spdlog();
|
||||
set_spdlog_level(pars.verbosity);
|
||||
|
||||
//Make ROOT shut up
|
||||
gStyle -> SetOptStat(0);
|
||||
gROOT->SetBatch(kTRUE);
|
||||
gErrorIgnoreLevel = kWarning;
|
||||
//gErrorIgnoreLevel = kError;
|
||||
|
||||
opts.ncores = NCORES;
|
||||
if(opts.ncores > 1) spdlog::info("[CPU]\tUse parallelisation on {0:d} CPU cores", opts.ncores);
|
||||
|
||||
//FIXED to true, since we have flatQ2 phase-space MC
|
||||
opts.IsFlatQ2 = true;
|
||||
|
||||
//get individual angular acceptance corrections for every year
|
||||
opts.angacccorrperyear = false;
|
||||
//Decide in what format everything should be saved in
|
||||
opts.write_eps = true;
|
||||
opts.write_C = false;
|
||||
opts.write_jpg = false;
|
||||
opts.write_pdf = true;
|
||||
|
||||
//Set the default path for plots_folder, somehow it doesn't want to accept PLOTS_PATH in the options constructor, possibly fix TODO
|
||||
opts.plot_folder = PLOTS_PATH;
|
||||
|
||||
//fit pdfs over complete phi range [-pi, +pi]
|
||||
opts.full_angular = opts.folding == -1;
|
||||
//use a two tailed CrystalBall function instead of a Gaussian
|
||||
opts.twotailedcrystalball = DOUBLE_CB;
|
||||
opts.crystalball = !DOUBLE_CB;
|
||||
//No exponential, but flat background model
|
||||
opts.flat_bkg = false;
|
||||
|
||||
//////////////////////////
|
||||
// HARDCODED FUNCTIONS: //
|
||||
//////////////////////////
|
||||
|
||||
//default is NOT Kshort channel:
|
||||
opts.KS = false;
|
||||
|
||||
//Set 'globally' fl and afb to (not) be used
|
||||
opts.fit_fl = true;
|
||||
opts.fit_afb = true;
|
||||
|
||||
//Set 'globaly' to use lambda in the background fit
|
||||
//fit exponential with exp(-lambda*x) instead of exp(-x/tau), it has better precision
|
||||
opts.fit_lambda = true;
|
||||
|
||||
//Assymetries to be included in the fit itself
|
||||
opts.fit_asymmetries = false; //you don't have enough stats for this to be true
|
||||
|
||||
/////////////////////////////////////
|
||||
// Set the order of the polynomial //
|
||||
/////////////////////////////////////
|
||||
opts.bkg_order_costhetal = 2; //TODO: put as a const into constants.cc and modify it accordingly in options.cc
|
||||
opts.bkg_order_costhetak = 5;
|
||||
|
||||
////////////////////////
|
||||
// ANGULAR RESOLUTION //
|
||||
////////////////////////
|
||||
|
||||
//Set the order of legendre polynomial
|
||||
opts.eff_order_costhetal = ORDER_COSTHETAL;
|
||||
opts.eff_order_costhetak = ORDER_COSTHETAK;
|
||||
opts.eff_order_phi = ORDER_PHI;
|
||||
opts.eff_order_q2 = ORDER_Q2;
|
||||
|
||||
std::vector<std::vector<double>> resolution = get_resolution();
|
||||
|
||||
//Have angular correction per each Run (false)
|
||||
opts.angacccorrbothruns = false;
|
||||
|
||||
//Don't use angular acceptance convoluted in the likelihood (false)
|
||||
opts.use_angular_acc = false;
|
||||
|
||||
////////////////////////////////////////////
|
||||
// GLOBAL OPTIONS //
|
||||
////////////////////////////////////////////
|
||||
|
||||
//TODO fix this (actually nice, but can be done elsewhere)
|
||||
//maximum range of considered B mass:
|
||||
opts.m_low = B_MASS_LOW;
|
||||
opts.m_high = B_MASS_HIGH;
|
||||
//signal window of B mass:
|
||||
opts.m_min = PDGMASS_B-B_MASS_TIGHT_WINDOW;
|
||||
opts.m_max = PDGMASS_B+B_MASS_TIGHT_WINDOW;
|
||||
|
||||
//If MC, use MC weights//TODO: check for data
|
||||
opts.multiply_eff = pars.dataset >0;
|
||||
|
||||
//TODO move to paths
|
||||
std::string angularsuffix = opts.full_angular ? "full_angular" : "folding"+std::to_string(opts.folding);
|
||||
|
||||
|
||||
//generate vector with years for every run option, including just one year
|
||||
std::vector<Int_t>years = (pars.Run == 0 ? std::vector<Int_t>{pars.year} : get_years(pars.Run, pars.dataset==1, pars.dataset==2));
|
||||
spdlog::debug("Using years: " + convert_vector_to_string(years));
|
||||
|
||||
//---------------------------------------------
|
||||
// Put stuff from pars and acts into opts
|
||||
//---------------------------------------------
|
||||
//yes it is dumb but I cannot be bothered to change the whole options
|
||||
opts.verbose = pars.verbosity;
|
||||
opts.run = pars.Run; //This is not ideal when fitting per year,
|
||||
//From now on passing the pars as well
|
||||
opts.useMC = pars.dataset > 0;
|
||||
opts.fit_pprimes = pars.usePprime;
|
||||
|
||||
//-------------------------------
|
||||
// Get corresponding Q2 bins
|
||||
//-------------------------------
|
||||
if (pars.reference) pars.nBins = 1; //For reference, always use 1 bin
|
||||
opts.TheQ2binsmin = get_TheQ2binsmin(pars.nBins, pars.reference);
|
||||
opts.TheQ2binsmax = get_TheQ2binsmax(pars.nBins, pars.reference);
|
||||
|
||||
spdlog::debug("Using {0:d} q2 bins.", opts.TheQ2binsmax.size());
|
||||
|
||||
if (spdlog::default_logger_raw()->level()==spdlog::level::info){
|
||||
spdlog::info("Using the following binning scheme:");
|
||||
for(UInt_t b = 0; b < opts.TheQ2binsmin.size(); b++){
|
||||
assert(opts.TheQ2binsmin.at(b) != 0.0);
|
||||
assert(opts.TheQ2binsmax.at(b) != 0.0);
|
||||
assert(opts.TheQ2binsmin.at(b) < opts.TheQ2binsmax.at(b));
|
||||
std::cout << std::fixed << std::setprecision(2) << "\tbin" << b+1 << ": [" << opts.TheQ2binsmin.at(b) << "-" << opts.TheQ2binsmax.at(b) << "] GeV^2/c^4" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// Set ranges of the angles
|
||||
//-------------------------------
|
||||
//Not ideal to have it as an opts and as a constant, but this is how it is going to be now
|
||||
opts.reset_angle_ranges();
|
||||
//The ranges might change in the folding, hence I will keep the opts.angle_min/max for this case
|
||||
|
||||
|
||||
//Check if something is wrong; if any task is assigned, raise this flag
|
||||
bool isItDoingAnything_flag = false;
|
||||
int returnCode = 0;
|
||||
|
||||
//-------------------------------
|
||||
// create branches for FCNCfitter
|
||||
//-------------------------------
|
||||
if(acts.convert){ //these booleans are only for running, used only here
|
||||
//maybe put it into a new class //TODO
|
||||
isItDoingAnything_flag = true;
|
||||
return convert_tuples(pars.dataset, get_theFCNCpath(pars.dataset, opts.run), opts,years);
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// scan angular acceptance max. order of legendre
|
||||
//-------------------------------
|
||||
if(acts.angCorrScan){
|
||||
isItDoingAnything_flag = true;
|
||||
bool quickTest = false;
|
||||
bool test_4times1D = false;
|
||||
bool checkSignificance = false;
|
||||
bool runMinuit = false;
|
||||
bool checkFactorization = false;
|
||||
bool do3Dmoments = false;
|
||||
const bool assumePhiEven = IS_PHI_EVEN;
|
||||
spdlog::debug("Scanning angular acceptance corrections...");
|
||||
returnCode = scan_max_order_angular_ccorrection(opts, assumePhiEven, quickTest, test_4times1D,
|
||||
checkSignificance, runMinuit, checkFactorization, do3Dmoments);
|
||||
if (returnCode!=0) return returnCode;
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// fit angular acceptance
|
||||
//-------------------------------
|
||||
if (acts.angCorr){
|
||||
if (pars.testInt > -1) sanityCheck_MC(opts);
|
||||
else{
|
||||
isItDoingAnything_flag = true;
|
||||
bool testSaving = false;
|
||||
spdlog::debug("Calculating angular acceptance correction parameters...");
|
||||
returnCode = get_angular_acceptance(opts, testSaving);
|
||||
if (returnCode!=0) return returnCode;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
// FIT MASS
|
||||
//--------------------------------
|
||||
if(acts.fitType == 2){
|
||||
isItDoingAnything_flag = true;
|
||||
bool splitRuns = true;
|
||||
massfit(opts, pars.reference, splitRuns, pars);
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
// MC FIT
|
||||
//--------------------------------
|
||||
if(acts.fitType == 4){
|
||||
isItDoingAnything_flag = true;
|
||||
opts.only_angles = false;//(nBins == 8); //Do not fit the mass, just angles //Apply only when fitting B0 binning
|
||||
//Reference MC is broken (K* is PHSP), so when fitting the reference, fit only mass
|
||||
opts.only_Bmass = pars.reference; //Do not fit the angles, just mass
|
||||
opts.initSM = !pars.reference; //Set to true only for reference
|
||||
returnCode = mcfit_4D(opts, pars.reference, pars.dataset==3, pars);
|
||||
//yes, fitRef could be included in params, but I like to keep my options open :)
|
||||
if (returnCode!=0) return returnCode;
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
// COMPLETE FIT
|
||||
//--------------------------------
|
||||
if(acts.fitType == 1){
|
||||
isItDoingAnything_flag = true;
|
||||
bool fitToy = pars.testInt > -1; //If test, then do fit toys
|
||||
if (pars.folding == 5){ //We do not need this here, we can run the code 5 times, no?
|
||||
for (int f = 0; f < 5; f++){
|
||||
pars.folding = f;
|
||||
opts.folding = f;
|
||||
spdlog::debug("Fitting with folding={0:d}", pars.folding);
|
||||
mainfit(opts, pars, pars.reference, fitToy, pars.likelyhood, pars.FeldCous);
|
||||
}
|
||||
}
|
||||
else {
|
||||
mainfit(opts, pars, pars.reference, fitToy, pars.likelyhood, pars.FeldCous);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
// BACKGROUND ONLY FIT
|
||||
//--------------------------------
|
||||
if(acts.fitType == 0){
|
||||
isItDoingAnything_flag = true;
|
||||
|
||||
//Clear the bkgFit file
|
||||
clear_Latex_noteFile("_bkgFit");
|
||||
|
||||
//Set options
|
||||
//One can also fit only upper/lower mass sideband, to set this use -index
|
||||
bool LowMassFit = (pars.index == 1);
|
||||
bool HighMassFit = (pars.index == 2);
|
||||
bool Use2DAngularBins = false;
|
||||
bool fitKpiMass = true;
|
||||
|
||||
//Run the background only fit
|
||||
int bkgfit = 0;
|
||||
if (pars.folding == 5){ //We do not need this here, we can run the code 5 times, no?
|
||||
for (int f = 0; f < 5; f++){
|
||||
pars.folding = f;
|
||||
opts.folding = f;
|
||||
bkgfit =+ backgroundfit(opts, pars.reference,
|
||||
LowMassFit, HighMassFit, fitKpiMass,
|
||||
Use2DAngularBins, pars);
|
||||
}
|
||||
}
|
||||
else bkgfit = backgroundfit(opts, pars.reference,
|
||||
LowMassFit, HighMassFit, fitKpiMass,
|
||||
Use2DAngularBins, pars);
|
||||
if (bkgfit != 0) return bkgfit;
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
// start GENERATOR LEVEL MC FIT
|
||||
//--------------------------------
|
||||
if(acts.fitType == 5){
|
||||
isItDoingAnything_flag = true;
|
||||
opts.initSM = pars.nBins != 8; //SM for 8 bins not implemented
|
||||
genlvlfit(opts, pars.dataset==4, pars);
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
// method of moment fit
|
||||
//--------------------------------
|
||||
//TODO
|
||||
if(acts.fitType == 3){
|
||||
isItDoingAnything_flag = true;
|
||||
bool blind = true;
|
||||
bool Fit2bins = false, Fit1bin = false, FitAllbins = false; //TODO: remove
|
||||
momfit(opts, pars.nBins==0, pars.dataset==1, pars.dataset==0, blind,
|
||||
Fit1bin, Fit2bins, FitAllbins);
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
// BEGIN angular resolution
|
||||
//--------------------------------
|
||||
|
||||
if(acts.angRes){
|
||||
isItDoingAnything_flag = true;
|
||||
get_angular_resolution(opts, get_years(opts.run, true, false));
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// generate Toy events
|
||||
//-------------------------------
|
||||
|
||||
if (acts.genToys){
|
||||
isItDoingAnything_flag = true;
|
||||
spdlog::debug("Generating and fitting toys");
|
||||
|
||||
bool onlySig = true;
|
||||
bool onlyBkg = false;
|
||||
if (pars.folding == 5){ //We do not need this here, we can run the code 5 times, no?
|
||||
for (int f = 0; f < 5; f++){
|
||||
pars.folding = f;
|
||||
opts.folding = f;
|
||||
spdlog::debug("Generating and fitting a toy sample with folding={0:d}", pars.folding);
|
||||
toysfit(opts, pars.nBins, pars.reference, pars, onlySig, onlyBkg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pars.testInt > -1)saveToys(pars, opts, pars.dataset>0, false); //if MC generate without bkg
|
||||
else{
|
||||
if(pars.folding != -1)spdlog::debug("Generating and fitting a toy sample with folding={0:d}", pars.folding);
|
||||
toysfit(opts, pars.nBins, pars.reference, pars, onlySig, onlyBkg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
// Run whatever script you decide to run
|
||||
//-------------------------------------------
|
||||
//Yes, this is tedious, but I don't want to hardcode everything just so root is happy
|
||||
//nor I wanna compile everything, so here we are
|
||||
if(acts.script){
|
||||
isItDoingAnything_flag = true;
|
||||
int status = runWhatever(pars, acts); //FILL IN RunningScripts.cc BY HAND
|
||||
if(status)return status;
|
||||
}
|
||||
|
||||
|
||||
if (!isItDoingAnything_flag) spdlog::warn("Nothing to do! Exitting.");
|
||||
else spdlog::info("Done with everything. Exit.");
|
||||
return 0;
|
||||
}
|
32
Code/FCNCFitter/cmake.sh
Normal file
32
Code/FCNCFitter/cmake.sh
Normal file
@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
##export CMTCONFIG=x86_64-slc6-gcc49-opt
|
||||
. /cvmfs/lhcb.cern.ch/lib/lcg/releases/LCG_84/ROOT/6.06.02/x86_64-slc6-gcc49-opt/bin/thisroot.sh
|
||||
. /cvmfs/lhcb.cern.ch/lib/lcg/releases/gcc/4.9.3/x86_64-slc6/setup.sh
|
||||
export GSL_DIR=/cvmfs/lhcb.cern.ch/lib/lcg/releases/GSL/2.1-36ee5/x86_64-slc6-gcc49-opt
|
||||
|
||||
if [ "$1" == '--clear' ] || [ "$1" == '-clear' ]; then
|
||||
echo "Cleaning up all cmake files to start over freshly"
|
||||
if [ -e 'CMakeFiles/' ]; then
|
||||
rm -r CMakeFiles/
|
||||
fi
|
||||
if [ -e 'CMakeCache.txt' ]; then
|
||||
rm CMakeCache.txt
|
||||
fi
|
||||
fi
|
||||
|
||||
#build make files
|
||||
cmake .
|
||||
#using 4 cores. why not?
|
||||
make -j8
|
||||
#make
|
||||
|
||||
#export CMTCONFIG=x86_64-slc6-gcc49-opt
|
||||
#. /cvmfs/lhcb.cern.ch/lib/lcg/releases/LCG_84/ROOT/6.06.02/x86_64-slc6-gcc49-opt/bin/thisroot.sh
|
||||
#. /cvmfs/lhcb.cern.ch/lib/lcg/releases/gcc/4.9.3/x86_64-slc6/setup.sh
|
||||
#export GSL_DIR=/cvmfs/lhcb.cern.ch/lib/lcg/releases/GSL/2.1-36ee5/x86_64-slc6-gcc49-opt
|
||||
|
||||
#export CMTCONFIG=x86_64-centos7-gcc9-opt
|
||||
#. /cvmfs/lhcb.cern.ch/lib/lcg/releases/LCG_97/ROOT/v6.20.02/x86_64-centos7-gcc9-opt/bin/thisroot.sh
|
||||
#. /cvmfs/lhcb.cern.ch/lib/lcg/releases/gcc/9.2.0/x86_64-centos7/setup.sh
|
||||
#export GSL_DIR=/cvmfs/lhcb.cern.ch/lib/lcg/releases/GSL/2.6-ecdfc/x86_64-centos7-gcc9-opt
|
37
Code/FCNCFitter/condor/output/checkConvergence.py
Normal file
37
Code/FCNCFitter/condor/output/checkConvergence.py
Normal file
@ -0,0 +1,37 @@
|
||||
from os import walk #Used to list all files in directory
|
||||
|
||||
debug = False
|
||||
|
||||
jobID = str(input("Enter the jobID:"))
|
||||
PATH = "/home/lhcb/kopecna/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter/condor/output/"
|
||||
|
||||
PATH = PATH + jobID +"/"
|
||||
|
||||
_, _, fileList = next(walk(PATH), (None, None, []))
|
||||
#Walk returns dirpath, dirnames, filenames, so we don't care about the first two
|
||||
|
||||
if (debug): print(fileList)
|
||||
|
||||
nFiles = len(fileList)
|
||||
if (nFiles==0):
|
||||
raise ValueError('No files found.')
|
||||
|
||||
if (debug): print(nFiles)
|
||||
|
||||
nFailedHesse = 0
|
||||
nFailedSquaredHesse = 0
|
||||
|
||||
for outFile in fileList:
|
||||
with open(PATH+outFile) as f:
|
||||
#Read leaves a cursor at the end of the file, reading twice then is not an option
|
||||
#Let's be safe here and instead of saving f.read in memore, let's call seek to return the cursor to the beginning
|
||||
if '[warning] Hesse returns 2: Full, forced pos def' in f.read(): nFailedHesse+=1
|
||||
f.seek(0)
|
||||
if "[warning] Squared Hesse returns 2: Full, forced pos def" in f.read(): nFailedSquaredHesse+=1
|
||||
|
||||
if (debug):
|
||||
print ("Failed hesse: ",nFailedHesse)
|
||||
print ("Failed sqaured hesse: ",nFailedSquaredHesse)
|
||||
|
||||
print ("Failed hesse: {0:.1f}% ".format(nFailedHesse/nFiles*100.0))
|
||||
print ("Failed sqaured hesse: {0:.1f} %".format(nFailedSquaredHesse/nFiles*100.0))
|
48
Code/FCNCFitter/condor/output/cleanup.sh
Executable file
48
Code/FCNCFitter/condor/output/cleanup.sh
Executable file
@ -0,0 +1,48 @@
|
||||
#!/bin/sh
|
||||
|
||||
#Set the main dir (no capital letters as it is best practice not to mess up with system variables
|
||||
main_dir=/home/lhcb/kopecna/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter/condor
|
||||
|
||||
# Used to clean up the mess condor created by default
|
||||
for CondorID in {500..650}
|
||||
do
|
||||
mkdir $main_dir/error/$CondorID
|
||||
mkdir $main_dir/output/$CondorID
|
||||
|
||||
#Delete empty error messages
|
||||
find $main_dir/error/toys_$CondorID* -size 0 -exec rm {} \;
|
||||
find $main_dir/Folding0/error/toys_$CondorID* -size 0 -exec rm {} \;
|
||||
find $main_dir/Folding1/error/toys_$CondorID* -size 0 -exec rm {} \;
|
||||
find $main_dir/Folding2/error/toys_$CondorID* -size 0 -exec rm {} \;
|
||||
find $main_dir/Folding3/error/toys_$CondorID* -size 0 -exec rm {} \;
|
||||
find $main_dir/Folding4/error/toys_$CondorID* -size 0 -exec rm {} \;
|
||||
|
||||
#Move the error messages into a subfolder
|
||||
mv "$main_dir/error/toys_$CondorID"* "$main_dir/error/$CondorID/"
|
||||
mv "$main_dir/Folding0/error/toys_$CondorID"* "$main_dir/error/$CondorID/"
|
||||
mv "$main_dir/Folding1/error/toys_$CondorID"* "$main_dir/error/$CondorID/"
|
||||
mv "$main_dir/Folding2/error/toys_$CondorID"* "$main_dir/error/$CondorID/"
|
||||
mv "$main_dir/Folding3/error/toys_$CondorID"* "$main_dir/error/$CondorID/"
|
||||
mv "$main_dir/Folding4/error/toys_$CondorID"* "$main_dir/error/$CondorID/"
|
||||
#rm "$MAIN_DIR/error/toys_$CondorID"*
|
||||
|
||||
#Move the output file into a subfodler
|
||||
mv "$main_dir/output/toys_$CondorID"* "$main_dir/output/$CondorID/"
|
||||
mv "$main_dir/Folding0/output/toys_$CondorID"* "$main_dir/output/$CondorID/"
|
||||
mv "$main_dir/Folding1/output/toys_$CondorID"* "$main_dir/output/$CondorID/"
|
||||
mv "$main_dir/Folding2/output/toys_$CondorID"* "$main_dir/output/$CondorID/"
|
||||
mv "$main_dir/Folding3/output/toys_$CondorID"* "$main_dir/output/$CondorID/"
|
||||
mv "$main_dir/Folding4/output/toys_$CondorID"* "$main_dir/output/$CondorID/"
|
||||
|
||||
#Move the log from the folding folder
|
||||
|
||||
mv "$main_dir/Folding0/log/toys_$CondorID"* "$main_dir/log/"
|
||||
mv "$main_dir/Folding1/log/toys_$CondorID"* "$main_dir/log/"
|
||||
mv "$main_dir/Folding2/log/toys_$CondorID"* "$main_dir/log/"
|
||||
mv "$main_dir/Folding3/log/toys_$CondorID"* "$main_dir/log/"
|
||||
mv "$main_dir/Folding4/log/toys_$CondorID"* "$main_dir/log/"
|
||||
|
||||
#Echo we are done :)
|
||||
echo "Cleaned."
|
||||
done
|
||||
|
31
Code/FCNCFitter/condor/output/condor.sh
Normal file
31
Code/FCNCFitter/condor/output/condor.sh
Normal file
@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
ProcID="$1"
|
||||
ClusterID="$2"
|
||||
# More or less gneric PI LHCb HTCondor script, to run something within singularity
|
||||
#
|
||||
# Where we should work
|
||||
working_dir=/home/lhcb/kopecna/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter/condor
|
||||
# What start in singularity (current directory will be current in singularity as well)
|
||||
to_run="/home/lhcb/kopecna/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter/condor/job.sh"
|
||||
|
||||
|
||||
# Singularity image to use (can point to CERN CVMFS...)
|
||||
# Can be constructer by yourself... like
|
||||
# OS_IMAGE=/work/zhelezov/singularity/CentOS7.simg
|
||||
# Taken from "generic" CERN, unfortunately without graphic libraries...
|
||||
#OS_IMAGE=/cvmfs/unpacked.cern.ch/registry.hub.docker.com/library/centos\:centos7
|
||||
# That seems like work for the perpose at the moment... Not perfect, I know.
|
||||
OS_IMAGE=/cvmfs/unpacked.cern.ch/registry.hub.docker.com/cmssw/cc7\:amd64
|
||||
|
||||
# We will work here. Local Condor has no "shared filesystem" (yet, unclear if it should/will),
|
||||
# so jobs start in a dedicated local directory on working nodes.
|
||||
cd $working_dir || exit 1
|
||||
# That defines where is singularity
|
||||
export PATH=/work/software/singularity/latest/`/work/software/os_version`/bin:$PATH
|
||||
# Just for info under which OS we are running
|
||||
echo "Batch execution OS: `/work/software/os_version`"
|
||||
#In case cvmfs is not available for whatever reason
|
||||
while [ ! -e "$OS_IMAGE" ]; do echo "Waiting for image..." >&1; /bin/sleep 300; done
|
||||
# That starts singularity with image and final script
|
||||
exec singularity exec --bind /cvmfs,/auto,/auto/home:/home,/auto/work:/work $OS_IMAGE $to_run "$@"
|
||||
|
32
Code/FCNCFitter/condor/output/job.sh
Executable file
32
Code/FCNCFitter/condor/output/job.sh
Executable file
@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
|
||||
# LHCb group_login.sh destroy arguments...
|
||||
ProcID="$1"
|
||||
ClusterID="$2"
|
||||
|
||||
# If something from there is required...
|
||||
source /cvmfs/lhcb.cern.ch/group_login.sh
|
||||
|
||||
# real job (since I work in my directory, I have to set path explicity)
|
||||
from_dir=/home/lhcb/kopecna/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter
|
||||
|
||||
#That can work, with a bit of luck...
|
||||
# source $FROM_DIR/SetPaths.sh
|
||||
#
|
||||
# But there are more standard and so stable way to setup CVMFS environment.
|
||||
# For "generic CERN" (not LHCb specific):
|
||||
# The list of possible views:
|
||||
# source /cvmfs/sft.cern.ch/lcg/views/setupViews.sh gives the list..
|
||||
# The list of binary tags for views:
|
||||
# source /cvmfs/sft.cern.ch/lcg/views/setupViews.sh <view>
|
||||
# And so, for LCG_84 and x86_64-slc6-gcc49-opt
|
||||
source /cvmfs/sft.cern.ch/lcg/views/setupViews.sh LCG_84 x86_64-slc6-gcc49-opt
|
||||
echo "Job execution OS: `/work/software/os_version`"
|
||||
echo "Args: '$ProcID' '$ClusterID'"
|
||||
|
||||
#$from_dir/bu2kstarmumu -r 12 -d 0 -u 1 -q -w -e 13000 -j $ProcID -i $ClusterID -v 3
|
||||
#$from_dir/bu2kstarmumu -r 12 -d 0 -u 1 -q -w -e 52000 -j $ProcID -i $ClusterID -v 3
|
||||
$from_dir/bu2kstarmumu -r 12 -d 0 -u 1 -q -w -e 65000 -j $ProcID -i $ClusterID -v 3
|
||||
#$from_dir/bu2kstarmumu -r 12 -d 0 -u 5 -w -e 8710 -j $ProcID -i $ClusterID -v 3
|
||||
#$from_dir/bu2kstarmumu -r 12 -d 0 -u 5 -w -e 871 -j $ProcID -i $ClusterID -v 3
|
||||
|
19
Code/FCNCFitter/condor/output/runToysHD.sub
Normal file
19
Code/FCNCFitter/condor/output/runToysHD.sub
Normal file
@ -0,0 +1,19 @@
|
||||
executable = condor.sh
|
||||
arguments = $(ProcId) $(ClusterId)
|
||||
should_transfer_files = YES
|
||||
output = output/toys_$(ClusterId)_$(ProcId).txt
|
||||
error = error/toys_$(ClusterId)_$(ProcId).err
|
||||
log = log/toys_$(ClusterId).log
|
||||
#getenv = True #Alexey says this should be commented out
|
||||
#requirements = (OpSysAndVer =?= "CentOS7")
|
||||
transfer_executable = True
|
||||
##+JobFlavour = "microcentury"
|
||||
|
||||
# The following flag disable special job interpretation when you submit from CentOS7 container
|
||||
+FromVIRTC = ""
|
||||
|
||||
# The following flag can be used to exclude old server (which don't support some recent LHCb software)
|
||||
# +WantCPUCap = 2020
|
||||
|
||||
|
||||
queue 500
|
BIN
Code/FCNCFitter/config/phspweightq2.root
Normal file
BIN
Code/FCNCFitter/config/phspweightq2.root
Normal file
Binary file not shown.
0
Code/FCNCFitter/dummy
Normal file
0
Code/FCNCFitter/dummy
Normal file
15
Code/FCNCFitter/makefolders.sh
Normal file
15
Code/FCNCFitter/makefolders.sh
Normal file
@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
declare -a folders=(fitResults fitResults/angReso fitResults/angular fitResults/bkgFit fitResults/GenLvlFit fitResults/MainFit fitResults/MassFit fitResults/MCfit fitResults/Scans fitResults/ToysFit LaTeXfiles plots plots/angReso plots/angular plots/bkgFit plots/GenLvlFit plots/MainFit plots/MassFit plots/MCfit plots/MCfit/Signal plots/Scans plots/Toys log Toys)
|
||||
|
||||
|
||||
#generate all folders in the array if they are not existing:
|
||||
for folder in "${folders[@]}"; do
|
||||
if [ -d $folder ]; then
|
||||
echo "Folder '$folder' is already existing"
|
||||
else
|
||||
echo "Creating new folder: '$folder'"
|
||||
mkdir $folder
|
||||
fi
|
||||
done
|
||||
|
||||
|
24
Code/FCNCFitter/moveToys.sh
Executable file
24
Code/FCNCFitter/moveToys.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
#Read the jobID
|
||||
JobID="$1"
|
||||
|
||||
#Set the main dir (no capital letters as it is best practice not to mess up with system variables
|
||||
main_dir=/home/lhcb/kopecna/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter/plots/Toys
|
||||
|
||||
mkdir "$main_dir/$JobID"
|
||||
|
||||
#Move the files into a folder
|
||||
#list=("$main_dir/*_${JobID}_*")
|
||||
#echo ${list[@]}
|
||||
mv $main_dir/*_${JobID}_*.eps $main_dir/${JobID}/
|
||||
mv $main_dir/*_${JobID}_*.root $main_dir/${JobID}/
|
||||
|
||||
|
||||
#Remove the Run1 and Run2 only plots
|
||||
rm $main_dir/$JobID/*_Run1_*
|
||||
rm $main_dir/$JobID/*_Run2_*
|
||||
|
||||
#Echo we are done :)
|
||||
echo "Cleaned."
|
||||
|
99
Code/FCNCFitter/push.py
Normal file
99
Code/FCNCFitter/push.py
Normal file
@ -0,0 +1,99 @@
|
||||
# Renata Kopecna
|
||||
|
||||
|
||||
#########################################################
|
||||
# #
|
||||
# Script for easier pushing to git #
|
||||
# #
|
||||
#########################################################
|
||||
|
||||
#Bash would work but this is nicer for the user to read
|
||||
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
tmp = subprocess.Popen(["git","branch","--show-current"], cwd = "./", stdout=subprocess.PIPE)
|
||||
targetBranch = tmp.communicate()[0].decode("utf-8").strip("\n")
|
||||
#print (targetBranch)
|
||||
|
||||
if (len(sys.argv)!= 3):
|
||||
print("Use it only with two arguments! python git.py fileToBePushed commitMessage")
|
||||
print("Using " + str(len(sys.argv)) + " arguments")
|
||||
exit()
|
||||
|
||||
toBePushed = sys.argv[1]
|
||||
commitMessage = sys.argv[2]
|
||||
|
||||
class_dict = {
|
||||
"generator": "sources/Core/bu2kstarmumu_generator",
|
||||
"loader": "sources/Core/bu2kstarmumu_loader",
|
||||
"parameters": "sources/Core/bu2kstarmumu_parameters",
|
||||
"pdf": "sources/Core/bu2kstarmumu_pdf",
|
||||
"plotter": "sources/Core/bu2kstarmumu_plotter",
|
||||
"event": "sources/Core/event",
|
||||
"folder": "sources/Core/folder",
|
||||
"fitter": "sources/Core/fitter",
|
||||
"funcs": "sources/Core/funcs",
|
||||
"integrals": "sources/Core/integrals",
|
||||
"options": "sources/Core/options",
|
||||
"toystudy": "sources/Core/toystudy",
|
||||
"design": "sources/Helpers/design",
|
||||
"helpers": "sources/Helpers/helpers",
|
||||
"constants": "sources/Params/constants",
|
||||
"parameters.hh": "sources/Params/parameters",
|
||||
"parameterscan": "sources/Params/parameterscan",
|
||||
"angularcorr": "sources/Run/angularcorr",
|
||||
"backgroundfit": "sources/Run/backgroundfit",
|
||||
"feldman_cousins": "sources/Run/feldman_cousins",
|
||||
"genlvlfit": "sources/Run/genlvlfit",
|
||||
"generatetoys": "sources/Run/generatetoys",
|
||||
"likelihoodscan": "sources/Run/likelihoodscan",
|
||||
"mcfit": "sources/Run/mcfit",
|
||||
"mainfit": "sources/Run/mainfit",
|
||||
"massfit": "sources/Run/massfit",
|
||||
"momfit": "sources/Run/momfit",
|
||||
"multifit": "sources/Run/multifit",
|
||||
"pulls": "sources/Run/pulls",
|
||||
"toysfit": "sources/Run/toysfit",
|
||||
"parse": "sources/parse",
|
||||
"help": "sources/help",
|
||||
"paths": "sources/paths"
|
||||
}
|
||||
|
||||
scripts_dict = {
|
||||
"PlotMCfit": "sources/Scripts/PlotMCfit",
|
||||
"GenLvlvsMC": "sources/Scripts/GenLvlvsMC",
|
||||
"EvaluateToys": "sources/Scripts/EvaluateToys",
|
||||
"ReferencePlots": "sources/Scripts/ReferencePlots",
|
||||
"ScriptHelpers": "sources/Scripts/ScriptHelpers",
|
||||
"RunningScripts": "sources/Scripts/RunningScripts"
|
||||
}
|
||||
|
||||
others_dict ={
|
||||
"main": "bu2kstarmumu.cc",
|
||||
"plotter.hh": "sources/Core/plotter.hh",
|
||||
"values": "sources/Params/values.hh",
|
||||
}
|
||||
|
||||
|
||||
mainPath = "/home/lhcb/kopecna/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter/"
|
||||
if (toBePushed in class_dict):
|
||||
add_cc = subprocess.run(["git","add",class_dict.get(toBePushed)+".cc"], cwd = "./", check = False) #Output into console
|
||||
add_hh = subprocess.run(["git","add",class_dict.get(toBePushed)+".hh"], cwd = "./", check = False) #Output into console
|
||||
elif (toBePushed in others_dict):
|
||||
add = subprocess.run(["git","add",others_dict.get(toBePushed)], cwd = "./", check = False) #Output into console
|
||||
elif (toBePushed in scripts_dict):
|
||||
add_cc = subprocess.run(["git","add",scripts_dict.get(toBePushed)+".cc"], cwd = "./", check = False) #Output into console
|
||||
add_hh = subprocess.run(["git","add",scripts_dict.get(toBePushed)+".hh"], cwd = "./", check = False) #Output into console
|
||||
else:
|
||||
print("Wrong file name! Use any of the following:")
|
||||
print (class_dict.keys())
|
||||
print (others_dict.keys())
|
||||
|
||||
add = subprocess.run(["git","commit","-m",commitMessage], cwd = "./", check = True) #Output into console
|
||||
add = subprocess.run(["git","push","origin",targetBranch], cwd = "./", check = True) #Output into console
|
||||
|
||||
print ("\nDone pushing.\n")
|
||||
|
||||
|
50
Code/FCNCFitter/rerunBasic.sh
Normal file
50
Code/FCNCFitter/rerunBasic.sh
Normal file
@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
#Use as ./rerunBasic.sh RUN
|
||||
|
||||
E_NO_ARGS=65
|
||||
if [ $# -eq 1 ] # Must have one command-line argument (run number)
|
||||
then
|
||||
run=$1
|
||||
echo "Rerruning everything for Run $run"
|
||||
else
|
||||
echo "Please invoke this script with one command-line argument in the following format:"
|
||||
echo "./rerunBasic.sh RUN"
|
||||
exit $E_NO_ARGS
|
||||
fi
|
||||
|
||||
if [ $run = 12 ]
|
||||
then
|
||||
python run.py -convert -all -Run 1
|
||||
python run.py -dontCompile -convert -all -Run 2
|
||||
python run.py -dontCompile -MC -angCorr -Run 1 -scan
|
||||
python run.py -dontCompile -MC -angCorr -Run 2 -scan
|
||||
python run.py -dontCompile -MC -angCorr -Run 1
|
||||
python run.py -dontCompile -MC -angCorr -Run 2
|
||||
python run.py -dontCompile -MC -angRes -Run 1
|
||||
python run.py -dontCompile -MC -angRes -Run 2
|
||||
python run.py -dontCompile -MC -Run 12 -fit -Ref -nBins 1;
|
||||
python run.py -dontCompile -MC -Run 12 -fit -nBins 5;
|
||||
python run.py -dontCompile -Data -Run 12 -fit -Ref -nBins 1 -massDim;
|
||||
python run.py -dontCompile -Data -Run 12 -fit -nBins 5 -massDim;
|
||||
python run.py -dontCompile -Data -Run 12 -fit -Ref -nBins 1 -bkgOnly -upper;
|
||||
python run.py -dontCompile -Data -Run 12 -fit -nBins 5 -onlyBkg -upper;
|
||||
python run.py -dontCompile -Run 12 -v 2 -fit -Ref -nBins 1 -genMC -Ref
|
||||
python run.py -dontCompile -Run 12 -v 2 -fit -nBins 5 -genMC
|
||||
else
|
||||
python run.py -convert -all -Run $run
|
||||
python run.py -dontCompile -MC -angCorr -Run $run -scan
|
||||
python run.py -dontCompile -MC -angCorr -Run $run
|
||||
python run.py -dontCompile -MC -angRes -Run $run
|
||||
python run.py -dontCompile -MC -Run $run -fit -Ref -nBins 1;
|
||||
python run.py -dontCompile -MC -Run $run -fit -nBins 5;
|
||||
python run.py -dontCompile -Data -Run $run -fit -Ref -nBins 1 -massDim;
|
||||
python run.py -dontCompile -Data -Run $run -fit -nBins 5 -massDim;
|
||||
python run.py -dontCompile -Data -Run $run -fit -Ref -nBins 1 -bkgOnly -upper;
|
||||
python run.py -dontCompile -Data -Run $run -fit -nBins 5 -onlyBkg -upper;
|
||||
python run.py -dontCompile -Run $run -v 2 -fit -Ref -nBins 1 -genMC -Ref
|
||||
python run.py -dontCompile -Run $run -v 2 -fit -nBins 5 -genMC
|
||||
fi
|
||||
|
||||
echo "All done"
|
||||
|
70
Code/FCNCFitter/run.py
Normal file
70
Code/FCNCFitter/run.py
Normal file
@ -0,0 +1,70 @@
|
||||
# Renata Kopecna
|
||||
|
||||
#########################################################
|
||||
# #
|
||||
# Set of functions used for running FCNC fitter #
|
||||
# #
|
||||
#########################################################
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
from runUtils import *
|
||||
from runArgs import *
|
||||
|
||||
allYearsDict ={ 2011:1,
|
||||
2012:1,
|
||||
2015:2,
|
||||
2016:2,
|
||||
2017:2,
|
||||
2018:2,
|
||||
}
|
||||
|
||||
if '__main__' == __name__:
|
||||
print ("")
|
||||
|
||||
#Add and parse arguments
|
||||
parser = ShowArgumentsParser(
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
prog=os.path.basename(sys.argv[0]),
|
||||
description=("""Do the comparison for:
|
||||
|
||||
For a full list of arguments, do: 'python {0} -h'
|
||||
""").format(os.path.basename(sys.argv[0]))
|
||||
)
|
||||
addAllArgs(parser)
|
||||
opts = parser.parse_args()
|
||||
dir(opts)
|
||||
|
||||
#check dir is the FCNC dir
|
||||
print ("Starting program in directory: ")
|
||||
os.system('pwd')
|
||||
print ("\n")
|
||||
|
||||
#Open output file; if none specified, print into console
|
||||
if (opts.log!=""): logFile = open(opts.log,'w')
|
||||
else: logFile = open("dummy",'w') #easiest is to create a dummy and then not save anything in it
|
||||
|
||||
|
||||
#if (opts.compile):
|
||||
#Just compile always, because you're a dumb dumb
|
||||
if (not opts.dontCompile):
|
||||
waitForCommand("bash",["cmake.sh"], logFile)
|
||||
print ("\n\nCompiled.")
|
||||
|
||||
cmd = './bu2kstarmumu'
|
||||
|
||||
arg_list = []
|
||||
arg_list.append('-v ' + str(opts.verbosity))
|
||||
if (opts.hilfe):
|
||||
arg_list.append("-h")
|
||||
waitForCommand(cmd,arg_list,logFile)
|
||||
else:
|
||||
argListList= fullArgListPerRun(opts)
|
||||
for arguments in argListList:
|
||||
print("Runinng ./bu2kstarmumu ", arguments, "\n")
|
||||
waitForCommand(cmd,arguments,logFile)
|
||||
|
||||
|
||||
print ("\n\nDone running FCNC.\n")
|
||||
|
||||
|
348
Code/FCNCFitter/runArgs.py
Normal file
348
Code/FCNCFitter/runArgs.py
Normal file
@ -0,0 +1,348 @@
|
||||
# Renata Kopecna
|
||||
|
||||
|
||||
#########################################################
|
||||
# #
|
||||
# Define Parser and add all options #
|
||||
# #
|
||||
#########################################################
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
RunList = [1,2,12]
|
||||
|
||||
class ShowArgumentsParser(argparse.ArgumentParser):
|
||||
def error(self, message):
|
||||
sys.stderr.write('error: %s\n\n' %message)
|
||||
parser.print_usage(sys.stderr)
|
||||
sys.stderr.write('\n'+self.description)
|
||||
sys.exit(2)
|
||||
|
||||
def addAllArgs(parser):
|
||||
#Basic options
|
||||
parser.add_argument("-v", "--verbosity",
|
||||
metavar = '<intVerbosity>',
|
||||
default = 2,
|
||||
type = int,
|
||||
help="Set verbosity level. Default is INFO.\n"+
|
||||
"Available levels are:\n"+
|
||||
"0: Trace\n"+
|
||||
"1: Debug\n"+
|
||||
"2: Info\n"+
|
||||
"3: Warn\n"+
|
||||
"4: Error\n"+
|
||||
"5: Critical\n\n")
|
||||
parser.add_argument("-log", "--log",
|
||||
metavar = '<strLog>',
|
||||
default = "",
|
||||
type = str,
|
||||
help="Set log file. Default is no log, streaming right into console.\n\n")
|
||||
parser.add_argument("-hilfe", "--hilfe",
|
||||
action="store_true",
|
||||
help="Print full help.\n\n")
|
||||
#Compile
|
||||
parser.add_argument("-compile", "--compile",
|
||||
action="store_true",
|
||||
help="Compile the code before runing.\n\n")
|
||||
parser.add_argument("-dontCompile", "--dontCompile",
|
||||
action="store_true",
|
||||
help="Don't compile the code before runing.\n\n")
|
||||
# #Set dataset
|
||||
parser.add_argument('-Run', '--Run',
|
||||
metavar='<Run>',
|
||||
default = 1,
|
||||
type = int,
|
||||
help="Set the Run number. Default is Run 1.\n\n")
|
||||
parser.add_argument('-allRun', '--allRun',
|
||||
action="store_true",
|
||||
default = False,
|
||||
help="Run on Runs 1, 2 and 12.\n\n")
|
||||
parser.add_argument('-year', '--year', #TODO
|
||||
metavar='<year>',
|
||||
default = -1,
|
||||
type = int,
|
||||
help="Run only on one year.\n\n") #TODO
|
||||
parser.add_argument("-PHSP", "--PHSP",
|
||||
action="store_true",
|
||||
default = False,
|
||||
help="Run on PHSP\n\n")
|
||||
parser.add_argument("-Data", "--Data",
|
||||
action="store_true",
|
||||
default = False,
|
||||
help="Run on Data\n\n")
|
||||
parser.add_argument("-Ref", "--Ref",
|
||||
action="store_true",
|
||||
default = False,
|
||||
help="Run on reference channel Jpsi\n\n")
|
||||
parser.add_argument("-MC", "--MC",
|
||||
action="store_true",
|
||||
default = False,
|
||||
help="Run on signal MC\n\n")
|
||||
parser.add_argument("-all", "--all",
|
||||
action="store_true",
|
||||
default = False,
|
||||
help = "Run on data, signal MC, reference MC and PHSP\n\n" )
|
||||
parser.add_argument("-allMC", "--allMC",
|
||||
action="store_true",
|
||||
default = False,
|
||||
help = "Run on signal MC, reference MC and PHSP\n\n" )
|
||||
parser.add_argument("-genMC", "--genMC",
|
||||
action="store_true",
|
||||
default = False,
|
||||
help="Run on generator level MC\n\n")
|
||||
parser.add_argument("-boost", "--boost",
|
||||
action="store_true",
|
||||
default = False,
|
||||
help="Run on boosted sample, turn on also generator level MC option!\n\n")
|
||||
#Set tasks
|
||||
parser.add_argument("-convert", "--convert",
|
||||
action="store_true",
|
||||
help="Convert selection tuples to FCNC tuples.\n\n")
|
||||
parser.add_argument("-angCorr", "--angCorr",
|
||||
action="store_true",
|
||||
help="Obtain angular acceptance correction coefficients from PHSP Monte Carlo events.\n\n")
|
||||
parser.add_argument("-scan", "--scan",
|
||||
action="store_true",
|
||||
help="Scan whatever you are doing :)\n\n")
|
||||
parser.add_argument("-fit", "--fit",
|
||||
action="store_true",
|
||||
help="Run the main fit\n\n")
|
||||
parser.add_argument("-angRes", "--angRes",
|
||||
action="store_true",
|
||||
help="Get angular resolution from signal MC.\n\n")
|
||||
parser.add_argument('-toys', '--toys', #TODO
|
||||
action="store_true",
|
||||
help="Generate toys. Add -evts to generate custom number of events.\n\n")
|
||||
parser.add_argument('-script', '--script',
|
||||
action="store_true",
|
||||
help="Run whatever script you decided.\n\n")
|
||||
parser.add_argument('-job', '--job',
|
||||
metavar='<job>',
|
||||
default = -1,
|
||||
type = int,
|
||||
help="Set the job number\n\n")
|
||||
#Set toy options
|
||||
parser.add_argument('-evts', '--evts',
|
||||
metavar='<evts>',
|
||||
default = -1,
|
||||
type = int,
|
||||
help="Set number of used/generated events\n\n")
|
||||
|
||||
#Set fit options
|
||||
parser.add_argument('-onlyBkg', '--onlyBkg',
|
||||
action="store_true",
|
||||
help="Fit only angular background.\n\n")
|
||||
parser.add_argument('-upper', '--upper',
|
||||
action="store_true",
|
||||
help="Fit only upper-mass side-band.\n\n")
|
||||
parser.add_argument('-lower', '--lower',
|
||||
action="store_true",
|
||||
help="Fit only lower-mass side-band.\n\n")
|
||||
parser.add_argument('-bin', '--bin',
|
||||
metavar='<bin>',
|
||||
default = -1,
|
||||
type = int,
|
||||
help="Which angular bin would you like to fit?\n\n")
|
||||
parser.add_argument('-nBins', '--nBins',
|
||||
metavar='<nBins>',
|
||||
default = -1,
|
||||
type = int,
|
||||
help="Set total number q2 bins.\n\n")
|
||||
parser.add_argument("-MagDown", "--MagDown",
|
||||
action="store_true",
|
||||
default = False,
|
||||
help="Run only on MagDown\n\n")
|
||||
parser.add_argument("-MagUp", "--MagUp",
|
||||
action="store_true",
|
||||
default = False,
|
||||
help="Run only on MagUp\n\n")
|
||||
parser.add_argument('-trueMC', '--trueMC',
|
||||
action="store_true",
|
||||
help="Use MC true information.\n\n")
|
||||
parser.add_argument('-likelyhood', '--likelyhood',
|
||||
action="store_true",
|
||||
help="Likelihood profile scans.\n\n")
|
||||
parser.add_argument('-massDim', '--massDim',
|
||||
action="store_true",
|
||||
help="Fit mass dimension\n\n")
|
||||
parser.add_argument('-MoM', '--MoM',
|
||||
action="store_true",
|
||||
help="Use Method of Moments instead of the fit.\n\n")
|
||||
parser.add_argument('-observeP', '--observeP',
|
||||
action="store_true",
|
||||
help="use P(') angular observables in the fit instead of the S(')\n\n")
|
||||
parser.add_argument('-folding', '--folding',
|
||||
metavar='<folding>',
|
||||
default = -1,
|
||||
type = int,
|
||||
help="Set the folding of angles.\n"
|
||||
+"Five possibilities use range [0-4]\n"
|
||||
+"\t0: phi' = phi + pi for phi < 0\n"
|
||||
+"\t1: phi' = -phi for phi < 0\n"
|
||||
+"\t phi' = pi - phi for ctl < 0\n"
|
||||
+"\t ctl' = -ctl for ctl < 0\n"
|
||||
+"\t2: phi' = -phi for phi < 0\n"
|
||||
+"\t ctl' = -ctl for ctl < 0\n"
|
||||
+"\t3: phi' = pi - phi for phi > pi/2\n"
|
||||
+"\t phi' = -pi - phi for phi < -pi/2\n"
|
||||
+"\t ctl' = -ctl for ctl < 0\n"
|
||||
+"\t4: phi' = pi - phi for phi > pi/2\n"
|
||||
+"\t phi' = -pi - phi for phi < -pi/2\n"
|
||||
+"\t ctk' = -ctk for ctk < 0\n"
|
||||
+"\t ctl' = -ctl for ctl < 0\n"
|
||||
+"Default is -1, meaning no folding.\n\n")
|
||||
parser.add_argument('-loopFolds', '--loopFolds',
|
||||
action="store_true",
|
||||
help="Evaluate all five foldings\n\n")
|
||||
# #Other options
|
||||
|
||||
#parser.add_argument('-FC', '--FC', #TODO
|
||||
# action="store_true",
|
||||
# help="Run Feldman-Cousins: par=<int>/8 and q2bin=<int>%%8") #TODO
|
||||
|
||||
#parser.add_argument('-pullsMC', '--pullsMC', #TODO
|
||||
# action="store_true",
|
||||
# help="Create -pullsMC pulls using specified signal MC events.") #TODO
|
||||
parser.add_argument('-index', '--index', #TODO
|
||||
metavar='<index>',
|
||||
default = -1,
|
||||
type = int,
|
||||
help="Set index, used for various checks.")
|
||||
|
||||
#Systematics
|
||||
#parser.add_argument('-systematics', '--systematics', #TODO "-s <int>"
|
||||
# metavar='<systematics>',
|
||||
# default = -1,
|
||||
# type = int,
|
||||
# help="Run a systematic study number:\n"
|
||||
# +"\t1\t:Bootstrapping of PHSP MC\n"
|
||||
# +"\t2\t:Perform fit with non-symmetric acceptance in ctl\n"
|
||||
# +"\t3\t:Increase Legendre poly order by 2 for PHSP MC\n"
|
||||
# +"\t4\t:Randomly change PHSP MC reweighting wihtin it's uncertainties\n"
|
||||
# +"\t5\t:Check non-homogeneous FS distributions in q2\n"
|
||||
# +"\t6\t:Vary angles (ctk, ctl and phi) within the angular resoluation\n"
|
||||
# +"\t7\t:Generate toy events with double-gaussian profile and fit with CB\n"
|
||||
# +"\t8\t:Systematic study on angular background model, add 10%% contribution of higher order\n"
|
||||
# +"\t9\t:Investigate systematic effects due to trigger selection\n"
|
||||
# +"\t10\t:Reweight PHSP MC according to pion PT disagreement in DD\n"
|
||||
# +"\t11\t:Background systematic for mimicing the B0 -> KS mu mu veto\n")
|
||||
#Test parameter
|
||||
parser.add_argument('-test', '--test', #TODO
|
||||
metavar='<test>',
|
||||
default = -1,
|
||||
type = int,
|
||||
help="Test parameter. When !=-1, verbosity automatically on debug.\n\n") #TODO
|
||||
|
||||
def getDatasetCommands(opts):
|
||||
arg_list = []
|
||||
if (opts.all): return ["-d 0", "-d 1", "-d 2", "-d 3", "-d 4"]
|
||||
if (opts.allMC): return ["-d 1", "-d 2", "-d 3", "-d 4"]
|
||||
|
||||
if (opts.Data): arg_list.append("-d 0")
|
||||
if (opts.genMC):
|
||||
if (opts.PHSP): arg_list.append("-d 4")
|
||||
else: arg_list.append("-d 5")
|
||||
else:
|
||||
if (opts.MC):
|
||||
if (opts.Ref): arg_list.append("-d 2")
|
||||
else: arg_list.append("-d 1")
|
||||
if (opts.PHSP): arg_list.append("-d 3")
|
||||
return arg_list
|
||||
|
||||
def setDataOpts(opts,arg):
|
||||
if (arg == "-d 0"):
|
||||
opts.Data = True
|
||||
opts.MC = False
|
||||
opts.PHSP = False
|
||||
|
||||
elif (arg == "-d 1"):
|
||||
opts.Data = False
|
||||
opts.MC = True
|
||||
opts.Ref = False
|
||||
opts.PHSP = False
|
||||
|
||||
if (arg == "-d 2"):
|
||||
opts.Data = False
|
||||
opts.MC = True
|
||||
opts.Ref = True
|
||||
opts.PHSP = False
|
||||
|
||||
if (arg == "-d 3"):
|
||||
opts.Data = False
|
||||
opts.MC = True
|
||||
opts.PHSP = True
|
||||
|
||||
def getActionCommands(opts):
|
||||
arg_list = []
|
||||
if (opts.test!=-1):
|
||||
arg_list.append("-z " + str(opts.test))
|
||||
opts.verbosity = 1
|
||||
if (opts.angRes): arg_list.append("-a")
|
||||
if (opts.angCorr):
|
||||
arg_list.append("-c")
|
||||
if (opts.scan): arg_list.append("-i 1")
|
||||
|
||||
if (opts.fit):
|
||||
if (opts.onlyBkg):
|
||||
arg_list.append("-f 0")
|
||||
if (opts.upper): arg_list.append("-i 2")
|
||||
if (opts.lower): arg_list.append("-i 1")
|
||||
elif (opts.massDim): arg_list.append("-f 2")
|
||||
elif (opts.MoM): arg_list.append("-f 3")
|
||||
elif (opts.MC or opts.PHSP):
|
||||
arg_list.append("-f 4") #TODO: I'm working on this one
|
||||
if (opts.MagDown): arg_list.append("-i 2")
|
||||
if (opts.MagUp): arg_list.append("-i 1")
|
||||
elif (opts.genMC): arg_list.append("-f 5")
|
||||
else : arg_list.append("-f 1")
|
||||
|
||||
if (opts.toys): arg_list.append("-w")
|
||||
if (opts.convert): arg_list.append("-k")
|
||||
#if (opts.pullsMC): arg_list.append("-m") #or -t when form toys TODO
|
||||
#if (opts.systematics != -1): arg_list.append("-s " + str(opts.systematics)) TODO
|
||||
if (opts.script): arg_list.append("-x")
|
||||
|
||||
if (opts.upper): arg_list.append("") #TODO
|
||||
if (opts.lower): arg_list.append("") #TODO
|
||||
if (opts.trueMC): arg_list.append("") #TODO
|
||||
return arg_list
|
||||
|
||||
|
||||
def getParameterCommands(opts):
|
||||
arg_list = []
|
||||
if (opts.bin!=-1): arg_list.append("-b " + str(opts.bin))
|
||||
if (opts.evts!=-1): arg_list.append("-e " + str(opts.evts))
|
||||
if (opts.folding!=-1): arg_list.append("-g " + str(opts.folding))
|
||||
if (opts.loopFolds): arg_list.append("-g 5")
|
||||
if (opts.likelyhood): arg_list.append("-l")
|
||||
if (opts.observeP): arg_list.append("-p")
|
||||
#if (opts.FC): arg_list.append("-o") TODO
|
||||
if (opts.nBins!=-1): arg_list.append("-u " + str(opts.nBins))
|
||||
if (opts.Ref): arg_list.append("-q")
|
||||
if (opts.index !=-1): arg_list.append("-i " + str(opts.index))
|
||||
if (opts.job!=-1): arg_list.append("-j " + str(opts.job))
|
||||
|
||||
return arg_list
|
||||
|
||||
def fullArgListPerRun(opts):
|
||||
runs = []
|
||||
if (opts.allRun): runs = RunList
|
||||
else: runs = [opts.Run]
|
||||
|
||||
|
||||
argListList = []
|
||||
for dataArg in getDatasetCommands(opts):
|
||||
for r in runs:
|
||||
arg_list = []
|
||||
arg_list.append('-v ' + str(opts.verbosity))
|
||||
setDataOpts(opts,dataArg)
|
||||
if (opts.Run!=-1): arg_list.append("-r " + str(r))
|
||||
if (opts.year!=-1): arg_list.append('-y' + str(opts.year))
|
||||
if (len(arg_list)==0): print ("The script needs at least run or year! Crashing now")
|
||||
arg_list.extend([dataArg])
|
||||
arg_list.extend(getActionCommands(opts))
|
||||
arg_list.extend(getParameterCommands(opts))
|
||||
argListList.append(arg_list)
|
||||
|
||||
return argListList
|
||||
|
29
Code/FCNCFitter/runUtils.py
Normal file
29
Code/FCNCFitter/runUtils.py
Normal file
@ -0,0 +1,29 @@
|
||||
# Renata Kopecna
|
||||
|
||||
import subprocess
|
||||
|
||||
def parse_jobID(opts):
|
||||
job_list = []
|
||||
if (opts.Data): job_list.append(0)
|
||||
if (opts.MC): job_list.append(1)
|
||||
if (opts.RefMC): job_list.append(2)
|
||||
if (opts.PHSP): job_list.append(3)
|
||||
if (opts.genMC):
|
||||
if (opts.boost): job_list.append(5)
|
||||
else: job_list.append(4)
|
||||
return job_list
|
||||
|
||||
|
||||
def waitForCommand(cmd, args, logFile): #args is a list
|
||||
if (type(cmd) is not str):
|
||||
raise TypeError("waitForCommand needs (str,list,str). Got ("+str(type(args))+",list,str) instead.")
|
||||
|
||||
if (type(args) is not list):
|
||||
raise TypeError("waitForCommand needs (str,list,str). Got (str," +type(args)+",str) instead.")
|
||||
|
||||
if (logFile.name=="dummy"):
|
||||
p = subprocess.run([cmd]+args, cwd = "./", check = True) #Output into console
|
||||
else:
|
||||
p = subprocess.run([cmd]+args, stdout=logFile, cwd = "./", check = True) #Output into a logFile
|
||||
|
||||
print ("Return:", p.returncode)
|
572
Code/FCNCFitter/sources/Core/bu2kstarmumu_generator.cc
Normal file
572
Code/FCNCFitter/sources/Core/bu2kstarmumu_generator.cc
Normal file
@ -0,0 +1,572 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <event.hh>
|
||||
#include <funcs.hh>
|
||||
#include <bu2kstarmumu_generator.hh>
|
||||
#include <helpers.hh>
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
//using namespace std;
|
||||
using namespace fcnc;
|
||||
|
||||
//boost::mutex generator_mutex;
|
||||
std::mutex generator_mutex;
|
||||
|
||||
//Function that returns a parameter with given range
|
||||
double genValueFromRange(double min, double max, TRandom3* rnd){
|
||||
return min+rnd->Rndm()*(max-min);
|
||||
}
|
||||
double genValueFromPar(fcnc::parameter *par, TRandom3* rnd){
|
||||
return genValueFromRange(par->get_min(),par->get_max(),rnd);
|
||||
}
|
||||
|
||||
|
||||
std::vector<event> bu2kstarmumu_generator::generate(unsigned int nevents, bu2kstarmumu_parameters* parameters, bu2kstarmumu_pdf* probability){
|
||||
prob = probability;
|
||||
params = parameters;
|
||||
|
||||
//even if folding (non-full-angular) is chosen, use full_angular mode to create events!
|
||||
assert(opts->full_angular == prob->opts->full_angular);
|
||||
assert(opts->always_generate_full_angular == prob->opts->always_generate_full_angular);
|
||||
//always_generate_full_angular is true everywhere anyway
|
||||
|
||||
bool only_generate_full_angular = prob->opts->always_generate_full_angular && !prob->opts->full_angular;
|
||||
spdlog::debug("only_generate_full_angular: " + boolToString(only_generate_full_angular));
|
||||
if(only_generate_full_angular){
|
||||
prob->opts->full_angular = true;
|
||||
opts->full_angular = true;
|
||||
prob->opts->update_angle_ranges();
|
||||
opts->update_angle_ranges();
|
||||
if(opts->use_angular_acc){
|
||||
prob->load_coeffs_eff_phsp_4d();
|
||||
spdlog::debug("Loaded full angular coefficients.");
|
||||
}
|
||||
}
|
||||
|
||||
prob->init(params);
|
||||
|
||||
//account for the bias in f_sig by rescaling the f_sig for production, using efficiency corrected normalization and non-corrected normalization of background and signal PDF
|
||||
//TODO: ask David wth this comment means
|
||||
if((opts->weighted_fit || (opts->use_weighted_bkg && opts->use_angular_acc))){
|
||||
//Get normalizations
|
||||
double bkg_norm = prob->angular_bkg_norm(params, false);
|
||||
double bkg_eff_norm = prob->angular_bkg_norm(params, true);
|
||||
double sig_norm = prob->angular_sig_norm(params, false);
|
||||
double sig_eff_norm = prob->angular_sig_norm(params, true);
|
||||
double f_sig_scale = (bkg_norm / bkg_eff_norm) / (sig_norm / sig_eff_norm);
|
||||
|
||||
spdlog::info("BKG_NORM={0:f}", bkg_norm);
|
||||
spdlog::info("BKG_NORM_EFF={0:f}", bkg_eff_norm);
|
||||
|
||||
//make sure the scale is not too large, because this might lead to unwanted effects
|
||||
if(f_sig_scale > 2.0){
|
||||
spdlog::error("The rescaling of the f_sig in toy generation is larger than 2.0 (value is: {0:f}), which seems very odd. Check your parameters!",f_sig_scale);
|
||||
assert(f_sig_scale < 2.0);
|
||||
}
|
||||
if(f_sig_scale < 0.5){
|
||||
spdlog::error("The rescaling of the f_sig in toy generation is smaller 0.5 (value is: {0:f}), which seems very odd. Check your parameters!",f_sig_scale);
|
||||
assert(f_sig_scale > 0.5);
|
||||
}
|
||||
|
||||
//set effective f_sig:
|
||||
if(params->f_sig() != 0.0 && params->f_sig() != 1.0){
|
||||
effective_f_sig = params->f_sig() * f_sig_scale / (1 + params->f_sig() * (f_sig_scale - 1));
|
||||
}
|
||||
else{
|
||||
effective_f_sig = params->f_sig();
|
||||
}
|
||||
|
||||
//test if resulting 'effective' f_sig is out of the range [0.0, 1.0]
|
||||
if(effective_f_sig > 1.0 || effective_f_sig < 0.0){
|
||||
spdlog::error("Rescaled f_sig in generation is out of the allowed range (0-1). Use either pure background or pure signal toys or a more equal mixture of both!");
|
||||
assert(0);
|
||||
}
|
||||
spdlog::debug("[INFO]\t\tSignal fraction: f_sig={0:0.4f} and eff_f_sig={1:f}", params->f_sig(), effective_f_sig);
|
||||
}
|
||||
else{
|
||||
effective_f_sig = params->f_sig();
|
||||
}
|
||||
|
||||
prob->update_cached_normalization(params);
|
||||
spdlog::info("Generating Toy MC");
|
||||
//Create empty space for the events
|
||||
std::vector< std::vector<event> > generated_events;
|
||||
for (unsigned int i = 0; i < opts->ncores; i++) {
|
||||
generated_events.push_back(std::vector<event>());
|
||||
generated_events.at(i).reserve(nevents/opts->ncores);
|
||||
}
|
||||
|
||||
spdlog::info("Generation started");
|
||||
//Divide in threads if possible
|
||||
std::vector<std::thread*> threads;
|
||||
if (opts->ncores > 1 && nevents > 1000) {
|
||||
for (unsigned int i = 0; i < opts->ncores; i++) {
|
||||
//boost::thread* t = new boost::thread(boost::bind(&bu2kstarmumu_generator::generation_thread, this, i, nevents/opts->ncores, &generated_events.at(i)));
|
||||
std::thread* t = new std::thread(std::bind(&bu2kstarmumu_generator::generation_thread, this, i, nevents/opts->ncores, &generated_events.at(i)));
|
||||
threads.push_back(t);
|
||||
}
|
||||
for (unsigned int i = 0; i < opts->ncores; i++) threads[i]->join();
|
||||
}
|
||||
else generation_thread(0, nevents, &generated_events.at(0));
|
||||
|
||||
//Copy the generated events into the final vector
|
||||
std::vector< event > evtVec;
|
||||
for (unsigned int i = 0; i < opts->ncores; i++){
|
||||
copy(generated_events.at(i).begin(), generated_events.at(i).end(), back_inserter(evtVec));
|
||||
}
|
||||
if (opts->ncores > 1 && nevents > 1000) {
|
||||
for (unsigned int i = 0; i < opts->ncores; i++) delete threads[i];
|
||||
}
|
||||
|
||||
//generate last events on single thread if number of requested event is not multiple of nCPUcores
|
||||
//and add it to the final vector
|
||||
if(evtVec.size() < nevents){
|
||||
std::vector<fcnc::event> last_events;
|
||||
generation_thread(0, nevents - evtVec.size(), &last_events);
|
||||
evtVec.insert(evtVec.end(), last_events.begin(), last_events.end());
|
||||
}
|
||||
|
||||
if(evtVec.size() != nevents){
|
||||
spdlog::critical("Number of requested events not reached: {0:d}/{1:d} ({2:f}%) ",
|
||||
evtVec.size(), nevents, 100. * evtVec.size() / nevents);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
//TODO: ask David what is this supposed to be
|
||||
//opts->use_angular_res = angular_res;
|
||||
spdlog::info("Generation of {0:d} pseudo-events completed", nevents);
|
||||
|
||||
//reset full_angular to false, if it is only needed for the generation of events
|
||||
//Aka when fititng and folding and you need a generator before that, restore the
|
||||
//folding back to being used
|
||||
if(only_generate_full_angular){
|
||||
prob->opts->full_angular = false;
|
||||
opts->full_angular = false;
|
||||
prob->opts->update_angle_ranges();
|
||||
opts->update_angle_ranges();
|
||||
}
|
||||
|
||||
return evtVec;
|
||||
};
|
||||
|
||||
void bu2kstarmumu_generator::generation_thread(unsigned int thread_id, unsigned long nevents, std::vector<event>* eventVec){
|
||||
//nevents is a number of actually generated events
|
||||
|
||||
//TRandom3 has an internal state!
|
||||
//we therefore need one TRandom3 per thread
|
||||
TRandom3* rnd = new TRandom3();
|
||||
if (opts->always_static_seed){//always use the same static seed
|
||||
rnd->SetSeed(71598+thread_id*12); //TODO
|
||||
}
|
||||
else if (opts->static_seed){//this needs to be rerun dependent otherwise every rerun you get the same data!
|
||||
spdlog::info("Thread={0:d}\tJobID={1:d}\tSeed={2:d}", thread_id, opts->get_job_id(), opts->get_job_id()*opts->ncores+thread_id+12345);
|
||||
rnd->SetSeed(opts->get_job_id()*opts->ncores+thread_id+12345);
|
||||
}
|
||||
else rnd->SetSeed(0);//this is correct, see documentation //WHY IS THERE NO LINK AND ONE HAS TO GOOGLE?!
|
||||
|
||||
spdlog::debug("Generator OK");
|
||||
|
||||
double mkpi_min = opts->mkpi_min/1.0e+3;
|
||||
double mkpi_max = opts->mkpi_max/1.0e+3;
|
||||
double asphase = params->asphase();
|
||||
double a = params->a();
|
||||
double r = params->r();
|
||||
double gammakstar = params->gammakstar();
|
||||
double mkstar = params->mkstar();
|
||||
double gammakstarplus = params->gammakstarplus();
|
||||
double mkstarplus = params->mkstarplus();
|
||||
double gammaf800 = params->gammaf800();
|
||||
double mf800 = params->mf800();
|
||||
double f800mag = params->f800mag();
|
||||
double f800phase = params->f800phase();
|
||||
double q2 = params->eff_q2();
|
||||
|
||||
double R = params->R();
|
||||
|
||||
bool swave = opts->swave;
|
||||
|
||||
//integrate over mkpi
|
||||
const double mk = PDGMASS_KST_KAON/1.0e+3;
|
||||
const double mpi = PDGMASS_KST_PION/1.0e+3;
|
||||
const double mb = PDGMASS_B/1.0e+3;
|
||||
const double from = opts->mkpi_full_range_norm ? (mk+mpi) : mkpi_min;
|
||||
const double to = opts->mkpi_full_range_norm ? mb : mkpi_max;
|
||||
double mkpi_swave_2_norm=1.0, mkpi_pwave_2_norm=1.0;
|
||||
double int_mkpi_re_swavepwave=1.0, int_mkpi_im_swavepwave=1.0;
|
||||
//TODO: check whether I can turn off the mkpi generation all together
|
||||
if(opts->generate_mkpi){
|
||||
spdlog::debug("Generating m(Kpi)!");
|
||||
if(opts->simple_mkpi){
|
||||
mkpi_swave_2_norm = fcnc::int_mkpi_simple_kstarzero_amp_squared(from, to, q2, f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus);
|
||||
mkpi_pwave_2_norm = fcnc::int_mkpi_simple_bw_kstar_amp_squared(from, to, q2, gammakstar, mkstar);
|
||||
int_mkpi_re_swavepwave = fcnc::int_mkpi_simple_bw_kstar_amp_bar_kstarzero_amp(from, to, q2, gammakstar, mkstar, asphase, f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus).real();
|
||||
int_mkpi_im_swavepwave = fcnc::int_mkpi_simple_bw_kstar_amp_bar_kstarzero_amp(from, to, q2, gammakstar, mkstar, asphase, f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus).imag();
|
||||
}
|
||||
else if(opts->isobar){
|
||||
mkpi_swave_2_norm = fcnc::int_mkpi_kstarzero_isobar_amp_squared(from, to, q2, f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R);
|
||||
mkpi_pwave_2_norm = fcnc::int_mkpi_bw_kstar_amp_squared(from, to, q2, gammakstar, mkstar, R);
|
||||
int_mkpi_re_swavepwave = fcnc::int_mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(from, to, q2, gammakstar, mkstar, asphase, f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R).real();
|
||||
int_mkpi_im_swavepwave = fcnc::int_mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(from, to, q2, gammakstar, mkstar, asphase, f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R).imag();
|
||||
}
|
||||
else{
|
||||
mkpi_swave_2_norm = fcnc::int_mkpi_kstarzero_lass_amp_squared(from, to, q2, asphase, a, r, gammakstarplus, mkstarplus, R);
|
||||
mkpi_pwave_2_norm = fcnc::int_mkpi_bw_kstar_amp_squared(from, to, q2, gammakstar, mkstar, R);
|
||||
int_mkpi_re_swavepwave = fcnc::int_mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(from, to, q2, gammakstar, mkstar, asphase, a, r, gammakstarplus, mkstarplus, R).real();
|
||||
int_mkpi_im_swavepwave = fcnc::int_mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(from, to, q2, gammakstar, mkstar, asphase, a, r, gammakstarplus, mkstarplus, R).imag();
|
||||
}
|
||||
}
|
||||
else spdlog::debug("Skipping generation of m(Kpi)!");
|
||||
|
||||
//get all P- and S-wave angular observables
|
||||
const double j1s = params->J1s();
|
||||
const double j1c = params->J1c();
|
||||
const double j2s = params->J2s();
|
||||
const double j2c = params->J2c();
|
||||
const double j3 = params->J3();
|
||||
const double j4 = params->J4();
|
||||
const double j5 = params->J5();
|
||||
const double j6s = params->J6s();
|
||||
const double j6c = params->J6c();
|
||||
const double j7 = params->J7();
|
||||
const double j8 = params->J8();
|
||||
const double j9 = params->J9();
|
||||
const double fs = params->FS();
|
||||
const double js1 = params->SS1();
|
||||
const double js2 = params->SS2();
|
||||
const double js3 = params->SS3();
|
||||
const double js4 = params->SS4();
|
||||
const double js5 = params->SS5();
|
||||
|
||||
unsigned int n_gen = 0; //Number of generated events
|
||||
unsigned int n_neg = 0; //Number of events with negative angular probability
|
||||
unsigned int n_rej = 0; //Number of rejected events in the generation
|
||||
unsigned int n_exc = 0; //Number of accepted events
|
||||
|
||||
//main event loop
|
||||
for (unsigned int ev = 0; ev < nevents; ev++){
|
||||
event meas;
|
||||
meas.cp_conjugate = rnd->Rndm() < 0.5;//no overall cp asymmetry, so 50/50 chance of a 1 and 0
|
||||
|
||||
//give a progress report
|
||||
if (ev % 1000 == 0 || ev == nevents - 1){
|
||||
std::lock_guard<std::mutex> lock(generator_mutex);
|
||||
spdlog::debug("\rThread {0:d} generating event no. {1:d} \r", thread_id , ev + 1 );
|
||||
spdlog::default_logger_raw()->flush();
|
||||
}
|
||||
|
||||
//determine if event is signal or background
|
||||
bool is_signal = (rnd->Rndm() < effective_f_sig);
|
||||
if(opts->generate_only_bkg) is_signal = false;
|
||||
if(is_signal) meas.event_type = 0;
|
||||
else meas.event_type = 1;
|
||||
|
||||
//m_res_1 should be the ratio between the two CBs
|
||||
//In case of 2-tailed CB, m_res_1 is always 1
|
||||
if(rnd->Rndm() < params->m_res_1()) meas.sigma_m = params->m_sigma_1();
|
||||
else meas.sigma_m = params->m_sigma_2();
|
||||
|
||||
//generate mass (hit and miss), no real need to speed this up for now
|
||||
bool finished_mass = false; //Means done with generating the mass
|
||||
while(!finished_mass){
|
||||
//get a random mass value
|
||||
meas.m = genValueFromPar(¶ms->m_b, rnd); //get random number between the range of B mass parameter
|
||||
//determine probability from signal PDF
|
||||
if(is_signal){
|
||||
event mmax;
|
||||
mmax.m = params->m_b();
|
||||
//The probability is calculated in bu2kstarmumu_pdf, and it takes into account twotailedCB if opts.twotailedcrystalball is true
|
||||
if(rnd->Rndm() < prob->m_sig_prob(params, meas)/prob->m_sig_prob(params, mmax)){
|
||||
finished_mass = true;
|
||||
}
|
||||
}
|
||||
//or determine background probability
|
||||
else{
|
||||
event mmax;
|
||||
if(opts->fit_lambda){
|
||||
if (params->m_lambda() < 0.0) mmax.m = params->m_b.get_min();
|
||||
else assert(params->m_lambda() < 0.0);
|
||||
}
|
||||
else{
|
||||
if (params->m_tau() > 0.0) mmax.m = params->m_b.get_min();
|
||||
else mmax.m = params->m_b.get_max();
|
||||
}
|
||||
double m_probmax = prob->m_bkg_prob(params, mmax);
|
||||
//systematic 11: remove a gaussian shaped hole in the upper mass sideband:
|
||||
if(opts->systematic == 11){ //TODO
|
||||
double gaussian_width = 30.;
|
||||
double gaussian_mean = 5520.;
|
||||
double gaussian_frac = 0.02;
|
||||
double gaussian_hole = TMath::Exp(-(meas.m - gaussian_mean)*(meas.m - gaussian_mean)/(2.*gaussian_width*gaussian_width))/TMath::Sqrt(2.*TMath::Pi()*gaussian_width*gaussian_width);
|
||||
double exp_norm = 1./params->m_lambda()*(exp(opts->m_max*params->m_lambda()) - exp(opts->m_min*params->m_lambda()));
|
||||
gaussian_hole *= gaussian_frac * exp_norm;
|
||||
|
||||
if (rnd->Rndm()*m_probmax < prob->m_bkg_prob(params, meas) - gaussian_hole) finished_mass = true;
|
||||
}
|
||||
else{
|
||||
if (rnd->Rndm()*m_probmax < prob->m_bkg_prob(params, meas)) finished_mass = true;
|
||||
//If your random shot on the y-axis is smaller than the wanted distribution/comparison function, keep the event!
|
||||
}
|
||||
}
|
||||
}//mass loop end
|
||||
|
||||
//generate angles
|
||||
if(is_signal){//generate signal
|
||||
double max_gen = opts->generate_mkpi ? 10.0 : 2.0;
|
||||
//This is the 'upper limit' or 'comparison funcition', pretty much the top of your generation. It always has to be bigger than dGamma/d(ctl)d(ctk)d(phi)!!!
|
||||
|
||||
bool finished = false;
|
||||
while (!finished){
|
||||
|
||||
n_gen++;
|
||||
double result = 1.0;
|
||||
|
||||
//get q2 value
|
||||
meas.q2 = params->eff_q2();
|
||||
if (opts->weighted_fit){ //TODO eh?
|
||||
assert(opts->q2_min > 0.0);
|
||||
assert(opts->q2_max > opts->q2_min);
|
||||
meas.q2 = genValueFromRange(opts->q2_min, opts->q2_max, rnd);
|
||||
}
|
||||
|
||||
//get angles
|
||||
meas.costhetak = genValueFromRange(opts->ctk_min, opts->ctk_max, rnd);
|
||||
meas.costhetal = genValueFromRange(opts->ctl_min, opts->ctl_max, rnd);
|
||||
meas.phi = genValueFromRange(opts->phi_min, opts->phi_max, rnd);
|
||||
|
||||
double f1=0.0, f2=0.0, f3=0.0, f4 =0.0, f5 =0.0, f6 =0.0,
|
||||
f7=0.0, f8=0.0, f9=0.0, f10=0.0, f11=0.0, f12=0.0;
|
||||
if(opts->full_angular){
|
||||
prob->fj(meas.costhetal, meas.costhetak, meas.phi,
|
||||
f1, f2, f3, f4, f5, f6,
|
||||
f7, f8, f9, f10, f11, f12);
|
||||
}
|
||||
else{
|
||||
prob->folded_fj(meas.costhetal, meas.costhetak, meas.phi,
|
||||
f1, f2, f3, f4, f5, f6,
|
||||
f7, f8, f9, f10, f11, f12);
|
||||
}
|
||||
|
||||
//calculate P-wave probability
|
||||
result = f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
|
||||
+ f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9;
|
||||
|
||||
if(opts->fit_asymmetries && meas.cp_conjugate){
|
||||
result = f1*j1s + f2*j1c + f3*j2s + f4*j2c - f5*j3 - f6*j4
|
||||
- f7*j5 - f8*j6s - f9*j6c - f10*j7 - f11*j8 - f12*j9;
|
||||
}
|
||||
|
||||
//generate m(Kpi)
|
||||
double prob_mkpi_pwave=0.0, prob_mkpi_swave=0.0;
|
||||
std::complex<double> prob_mkpi_swavepwave={0.0, 0.0};
|
||||
if (opts->generate_mkpi){ //TODO: here it is!
|
||||
assert(mkpi_min > 0.0);
|
||||
assert(mkpi_max > mkpi_min);
|
||||
meas.mkpi = genValueFromRange(mkpi_min, mkpi_max, rnd)*1.0e+3;
|
||||
if(opts->simple_mkpi) prob_mkpi_pwave = fcnc::mkpi_simple_bw_kstar_amp_squared(meas.mkpi/1.0e+3, meas.q2, gammakstar, mkstar);
|
||||
else if(opts->isobar) prob_mkpi_pwave = fcnc::mkpi_bw_kstar_amp_squared(meas.mkpi/1.0e+3, meas.q2, gammakstar, mkstar, R);
|
||||
else prob_mkpi_pwave = fcnc::mkpi_bw_kstar_amp_squared(meas.mkpi/1.0e+3, meas.q2, gammakstar, mkstar, R);
|
||||
result *= prob_mkpi_pwave/mkpi_pwave_2_norm;
|
||||
}
|
||||
else{
|
||||
meas.mkpi = PDGMASS_K_STAR_PLUS;
|
||||
}
|
||||
|
||||
//calculate S-wave probability
|
||||
double result_swave = 0.0;
|
||||
if(swave){
|
||||
//P-wave gets factor (1-FS)
|
||||
result *= (1.0-fs);
|
||||
double fs1=0.0, fs2=0.0, fs3=0.0, fs4=0.0, fs5=0.0, fs6=0.0;
|
||||
if(opts->full_angular){
|
||||
prob->swave_fj(meas.costhetal, meas.costhetak, meas.phi,
|
||||
fs1, fs2, fs3, fs4, fs5, fs6);
|
||||
}
|
||||
else{
|
||||
prob->folded_swave_fj(meas.costhetal, meas.costhetak, meas.phi,
|
||||
fs1, fs2, fs3, fs4, fs5, fs6);
|
||||
}
|
||||
|
||||
result_swave = fs*fs1 + js1*fs2 + js2*fs3 + js3*fs4 + js4*fs5 + js5*fs6;
|
||||
if(opts->generate_mkpi){
|
||||
if(opts->simple_mkpi){
|
||||
prob_mkpi_swave = fcnc::mkpi_simple_kstarzero_amp_squared(meas.mkpi/1.0e+3, meas.q2,
|
||||
f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus);
|
||||
prob_mkpi_swavepwave = fcnc::mkpi_simple_bw_kstar_amp_bar_kstarzero_amp(meas.mkpi/1.0e+3, meas.q2,
|
||||
gammakstar, mkstar, asphase,
|
||||
f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus);
|
||||
}
|
||||
else if(opts->isobar){
|
||||
prob_mkpi_swave = fcnc::mkpi_kstarzero_isobar_amp_squared(meas.mkpi/1.0e+3, meas.q2,
|
||||
f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R);
|
||||
prob_mkpi_swavepwave = fcnc::mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(meas.mkpi/1.0e+3, meas.q2,
|
||||
gammakstar, mkstar, asphase,
|
||||
f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R);
|
||||
}
|
||||
else{
|
||||
prob_mkpi_swave = fcnc::mkpi_kstarzero_lass_amp_squared(meas.mkpi/1.0e+3, meas.q2, asphase, a, r, gammakstarplus, mkstarplus, R);
|
||||
prob_mkpi_swavepwave = fcnc::mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(meas.mkpi/1.0e+3, meas.q2, gammakstar, mkstar, asphase, a, r, gammakstarplus, mkstarplus, R);
|
||||
}
|
||||
result_swave = fs*fs1*prob_mkpi_swave/mkpi_swave_2_norm
|
||||
+ (js1*fs2 + js2*fs3 + js3*fs4)*prob_mkpi_swavepwave.real()/int_mkpi_re_swavepwave
|
||||
+ (js4*fs5 + js5*fs6)*prob_mkpi_swavepwave.imag()/int_mkpi_im_swavepwave;
|
||||
}
|
||||
//add S-wave probability to P-wave probability
|
||||
result += result_swave;
|
||||
}
|
||||
|
||||
//safety check on nan or inf
|
||||
if(std::isnan(result) || std::isinf(result)){
|
||||
spdlog::critical("The calculated probability is = {0:f}", result);
|
||||
assert(!std::isnan(result));
|
||||
assert(!std::isinf(result));
|
||||
}
|
||||
|
||||
//safety check to avoid negative probabilities at toy generation
|
||||
if(result < 0.0){
|
||||
n_neg++;
|
||||
continue;
|
||||
}
|
||||
|
||||
//determine angular acceptance
|
||||
if (opts->use_angular_acc || opts->weighted_fit){
|
||||
result *=prob->get_ang_eff(opts, meas, false);
|
||||
}
|
||||
|
||||
if (result > max_gen){
|
||||
double eff = prob->get_ang_eff(opts, meas, false);
|
||||
//Yes, the eff is calculated again, but it doesn't cost any time as it crashes here anyway
|
||||
spdlog::error("Determined probability is too large: {0:e}. With efficiency: {1:f}", result, eff);
|
||||
spdlog::error("swave={0:f}\tpwave={1:f}", result_swave, result/eff - result_swave);
|
||||
spdlog::critical("If you are seing this, increase the max_gen!!!");
|
||||
assert(0);
|
||||
}
|
||||
else if (rnd->Rndm() < result/max_gen){ //If your random shot on the y-axis is smaller than the wanted distribution/comparison function, keep the event!
|
||||
finished = true;
|
||||
n_exc++;
|
||||
}
|
||||
else{
|
||||
n_rej++;
|
||||
}
|
||||
};
|
||||
}
|
||||
else{//generate bkg
|
||||
bool finished = false;
|
||||
double max_gen = 25.;//This is the 'upper limit' or 'comparison funcition', pretty much the top of your generation. It always has to be bigger than dGamma/d(ctl)d(ctk)d(phi)!!!
|
||||
|
||||
while(!finished){
|
||||
|
||||
//generate angles
|
||||
meas.costhetak = genValueFromRange(opts->ctk_min, opts->ctk_max, rnd);
|
||||
meas.costhetal = genValueFromRange(opts->ctl_min, opts->ctl_max, rnd);
|
||||
meas.phi = genValueFromRange(opts->phi_min, opts->phi_max, rnd);
|
||||
|
||||
//generate q2
|
||||
meas.q2 = params->eff_q2();
|
||||
if(opts->weighted_fit){
|
||||
assert(opts->q2_min > 0.0);
|
||||
assert(opts->q2_max > opts->q2_min);
|
||||
meas.q2 = genValueFromRange(opts->q2_min, opts->q2_max, rnd);
|
||||
}
|
||||
|
||||
double result = 1.0;
|
||||
if(!opts->flat_bkg){
|
||||
//use this (3 * 1D)*eff generation instead of 4D(Omega, eff) generation from prob->angular_bkg_prob
|
||||
std::vector<double> ch_ctl = init_ch_ctl(params);
|
||||
std::vector<double> ch_ctk = init_ch_ctk(params);
|
||||
std::vector<double> ch_phi = init_ch_phi(params);
|
||||
|
||||
std::vector<double> poly_ctl(ch_ctl.size(), 0.0);
|
||||
std::vector<double> poly_ctk(ch_ctk.size(), 0.0);
|
||||
std::vector<double> poly_phi(ch_phi.size(), 0.0);
|
||||
|
||||
std::vector<double> temp_ctl(ch_ctl.size(), 0.0);
|
||||
std::vector<double> temp_ctk(ch_ctk.size(), 0.0);
|
||||
std::vector<double> temp_phi(ch_phi.size(), 0.0);
|
||||
|
||||
chebyshev_to_poly(ch_ctl, temp_ctl);
|
||||
chebyshev_to_poly(ch_ctk, temp_ctk);
|
||||
chebyshev_to_poly(ch_phi, temp_phi);
|
||||
|
||||
for (unsigned int i=0; i<temp_ctl.size(); i++) poly_ctl.at(i) = temp_ctl.at(i);
|
||||
for (unsigned int i=0; i<temp_ctk.size(); i++) poly_ctk.at(i) = temp_ctk.at(i);
|
||||
correct_poly(temp_phi, poly_phi, -TMath::Pi(), +TMath::Pi());
|
||||
|
||||
double p_costhetal = 0.0;
|
||||
for(unsigned int i=0; i<ch_ctl.size(); i++) p_costhetal += poly_ctl.at(i)*pow(meas.costhetal,i);
|
||||
double p_costhetak = 0.0;
|
||||
for(unsigned int i=0; i<ch_ctk.size(); i++) p_costhetak += poly_ctk.at(i)*pow(meas.costhetak,i);
|
||||
double p_phi = 0.0;
|
||||
for(unsigned int i=0; i<ch_phi.size(); i++) p_phi += poly_phi.at(i)*pow(meas.phi,i);
|
||||
|
||||
result = p_costhetal*p_costhetak*p_phi;///prob->fnorm_bkg;
|
||||
}
|
||||
|
||||
//efficiency correction in generation:
|
||||
|
||||
if((opts->use_angular_acc && opts->use_weighted_bkg) || opts->weighted_fit){//applies efficiency to bkg for weighted fit
|
||||
result *= prob->get_ang_eff(opts, meas, false);
|
||||
}
|
||||
|
||||
if(result > max_gen){
|
||||
spdlog::error("The probability is too large: {0:f}", result);
|
||||
spdlog::error("It has to be smaller than: {0:f}", max_gen);
|
||||
spdlog::error("The normalization of the PDF is: {0:f}", prob->fnorm_bkg);
|
||||
spdlog::critical("If you are seing this, increase the max_gen!!!");
|
||||
assert(0);
|
||||
}
|
||||
else if(max_gen*rnd->Rndm() < result) finished = true;
|
||||
}//end angular background generation
|
||||
|
||||
finished = false;
|
||||
if(opts->generate_mkpi){
|
||||
double mkpi_min = opts->mkpi_min/1.0e+3;
|
||||
double mkpi_max = opts->mkpi_max/1.0e+3;
|
||||
std::vector<double> ch_mkpi(5, 0.0);
|
||||
ch_mkpi.at(0) = params->cbkgmkpi0();
|
||||
ch_mkpi.at(1) = params->cbkgmkpi1();
|
||||
ch_mkpi.at(2) = params->cbkgmkpi2();
|
||||
ch_mkpi.at(3) = params->cbkgmkpi3();
|
||||
ch_mkpi.at(4) = params->cbkgmkpi4();
|
||||
std::vector<double> poly_mkpi(ch_mkpi.size(), 0.0);
|
||||
chebyshev_to_poly(ch_mkpi, poly_mkpi);
|
||||
std::vector<double> poly_corr_mkpi(ch_mkpi.size(), 0.0);
|
||||
correct_poly(poly_mkpi, poly_corr_mkpi, mkpi_min, mkpi_max);
|
||||
|
||||
while(!finished){
|
||||
double mkpi = mkpi_min+rnd->Rndm()*(mkpi_max-mkpi_min);
|
||||
double probbkg = 0.0;
|
||||
if (opts->mkpi_threshold){
|
||||
probbkg = fcnc::threshold(mkpi, 0.633, params->nthreshold());
|
||||
}
|
||||
else{
|
||||
for(unsigned int i=0; i<ch_mkpi.size(); i++) probbkg += poly_corr_mkpi.at(i)*pow(mkpi,i);
|
||||
}
|
||||
double probmax = 10.0;
|
||||
assert(probbkg < probmax);
|
||||
if(rnd->Rndm()*probmax < probbkg){
|
||||
meas.mkpi = mkpi*1.0e+3;
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
}//end m(Kpi) background generation
|
||||
else{
|
||||
meas.mkpi = PDGMASS_K_STAR_PLUS;
|
||||
}
|
||||
}
|
||||
|
||||
//save angles also in backup/full angular variables:
|
||||
meas.costhetal_fa = meas.costhetal;
|
||||
meas.costhetak_fa = meas.costhetak;
|
||||
meas.phi_fa = meas.phi;
|
||||
meas.year = opts->year;
|
||||
|
||||
eventVec->push_back(meas);
|
||||
|
||||
}//end for all n events that are to be constructed
|
||||
spdlog::debug("Thread #{0:d}: Angular signal events: n_gen={1:d}\tn_neg={2:d}\tn_rej={3:d}\tn_exc={4:d}", thread_id, n_gen, n_neg, n_rej, n_exc);
|
||||
delete rnd;
|
||||
}
|
55
Code/FCNCFitter/sources/Core/bu2kstarmumu_generator.hh
Normal file
55
Code/FCNCFitter/sources/Core/bu2kstarmumu_generator.hh
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @file bu2kstarmumu_generator.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BU2KSTARMUMU_GENERATOR_H
|
||||
#define BU2KSTARMUMU_GENERATOR_H
|
||||
|
||||
#include <vector>
|
||||
#include <bu2kstarmumu_parameters.hh> //Forward declaration is complainign due to dynamic_cast
|
||||
#include <bu2kstarmumu_pdf.hh>
|
||||
#include <generator.hh>
|
||||
|
||||
namespace fcnc {
|
||||
class parameters;
|
||||
class options;
|
||||
class pdf;
|
||||
|
||||
///Class to generate toy data for the decay Bs -> JPsi Phi.
|
||||
class bu2kstarmumu_generator: public generator {
|
||||
public:
|
||||
///constructor
|
||||
bu2kstarmumu_generator(options* o):
|
||||
opts(o) {
|
||||
effective_f_sig = 0.5;
|
||||
};
|
||||
/**
|
||||
* generate Bs -> Phi gamma toy monte carlo and return a vector of the generated events
|
||||
* @param nevents number of events to generate
|
||||
* @param parameters parameter values to use in generation
|
||||
* @param probability pdf to use in the generation. Some helper routines are used from here
|
||||
*/
|
||||
std::vector<event> generate(unsigned int nevents, bu2kstarmumu_parameters* parameters, bu2kstarmumu_pdf* probability);
|
||||
std::vector<event> generate(unsigned int nevents, parameters* params, pdf* probability) {
|
||||
return generate(nevents, dynamic_cast<bu2kstarmumu_parameters*>(params), dynamic_cast<bu2kstarmumu_pdf*>(probability));
|
||||
};
|
||||
private:
|
||||
///pointer to the pdf
|
||||
bu2kstarmumu_pdf* prob;
|
||||
///pointer to the parameters to use in the generation
|
||||
bu2kstarmumu_parameters* params;
|
||||
///pointer to options
|
||||
options* opts;
|
||||
///used internally for threaded generation of the events
|
||||
void generation_thread(unsigned int thread_id, unsigned long nevents, std::vector<event>* eventVec);
|
||||
///background and signal weight correction for f_sig
|
||||
double effective_f_sig;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
659
Code/FCNCFitter/sources/Core/bu2kstarmumu_loader.cc
Executable file
659
Code/FCNCFitter/sources/Core/bu2kstarmumu_loader.cc
Executable file
@ -0,0 +1,659 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <bu2kstarmumu_loader.hh>
|
||||
|
||||
#include <options.hh>
|
||||
#include <event.hh>
|
||||
#include <helpers.hh>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
#include <TChain.h>
|
||||
#include <TFile.h>
|
||||
|
||||
|
||||
using namespace fcnc;
|
||||
|
||||
///calculate decay angles according to theory convention http://arxiv.org/abs/0805.2525
|
||||
void bu2kstarmumu_loader::theory_angles(const TLorentzVector& muplus, const TLorentzVector& muminus, const TLorentzVector& kaon, const TLorentzVector& pion, double& costhetal, double& costhetak, double& phi)
|
||||
{
|
||||
//set up boost vectors
|
||||
TLorentzVector b = muplus + muminus + kaon + pion;
|
||||
TLorentzVector mumu = muplus + muminus;
|
||||
TLorentzVector kpi = kaon + pion;
|
||||
TVector3 mumuboost(-mumu.BoostVector());
|
||||
TVector3 kpiboost(-kpi.BoostVector());
|
||||
TVector3 bboost(-b.BoostVector());
|
||||
|
||||
//determine costhetal
|
||||
TLorentzVector muminusd(muminus);
|
||||
muminusd.Boost(mumuboost);
|
||||
TLorentzVector bd(b);
|
||||
bd.Boost(mumuboost);
|
||||
costhetal = cos(muminusd.Vect().Angle(bd.Vect()));
|
||||
|
||||
//determine costhetak
|
||||
TLorentzVector kaondd(kaon);
|
||||
kaondd.Boost(kpiboost);
|
||||
TLorentzVector bdd(b);
|
||||
bdd.Boost(kpiboost);
|
||||
costhetak = cos(kaondd.Vect().Angle(bdd.Vect()));
|
||||
|
||||
//determine phi
|
||||
TLorentzVector kaonddd(kaon);
|
||||
kaonddd.Boost(bboost);
|
||||
TLorentzVector pionddd(pion);
|
||||
pionddd.Boost(bboost);
|
||||
TLorentzVector muminusddd(muminus);
|
||||
muminusddd.Boost(bboost);
|
||||
TLorentzVector muplusddd(muplus);
|
||||
muplusddd.Boost(bboost);
|
||||
TVector3 normalkpi = kaonddd.Vect().Cross(pionddd.Vect());
|
||||
TVector3 normalmumu = muminusddd.Vect().Cross(muplusddd.Vect());
|
||||
|
||||
phi = normalkpi.Angle(normalmumu);
|
||||
TLorentzVector kpiddd(kpi);
|
||||
kpiddd.Boost(bboost);
|
||||
if (normalkpi.Cross(normalmumu).Dot(kpiddd.Vect()) < 0.0) phi = -phi;
|
||||
|
||||
}
|
||||
|
||||
///calculate decay angles according to lhcb convention http://arxiv.org/abs/1304.6325, bzero is true for B0 and false for B0bar
|
||||
void bu2kstarmumu_loader::lhcb_angles(bool bplus, const TLorentzVector& muplus, const TLorentzVector& muminus, const TLorentzVector& kaon, const TLorentzVector& pion, double& costhetal, double& costhetak, double& phi){
|
||||
|
||||
//set up boost vectors
|
||||
TLorentzVector b = muplus + muminus + kaon + pion;
|
||||
TLorentzVector mumu = muplus + muminus;
|
||||
TLorentzVector kpi = kaon + pion;
|
||||
TVector3 mumuboost(-mumu.BoostVector());
|
||||
TVector3 kpiboost(-kpi.BoostVector());
|
||||
TVector3 bboost(-b.BoostVector());
|
||||
|
||||
//determine costhetal
|
||||
TLorentzVector muminusd(muminus);
|
||||
muminusd.Boost(mumuboost);
|
||||
TLorentzVector muplusd(muplus);
|
||||
muplusd.Boost(mumuboost);
|
||||
TLorentzVector bd(b);
|
||||
bd.Boost(mumuboost);
|
||||
if (bplus) costhetal = cos(muplusd.Vect().Angle(-bd.Vect()));
|
||||
else costhetal = cos(muminusd.Vect().Angle(-bd.Vect()));
|
||||
|
||||
//determine costhetak
|
||||
TLorentzVector kaondd(kaon);
|
||||
kaondd.Boost(kpiboost);
|
||||
TLorentzVector bdd(b);
|
||||
bdd.Boost(kpiboost);
|
||||
costhetak = cos(kaondd.Vect().Angle(-bdd.Vect()));
|
||||
|
||||
//determine phi
|
||||
TLorentzVector kaonddd(kaon);
|
||||
kaonddd.Boost(bboost);
|
||||
TLorentzVector pionddd(pion);
|
||||
pionddd.Boost(bboost);
|
||||
TLorentzVector muminusddd(muminus);
|
||||
muminusddd.Boost(bboost);
|
||||
TLorentzVector muplusddd(muplus);
|
||||
muplusddd.Boost(bboost);
|
||||
TVector3 normalkpi = kaonddd.Vect().Cross(pionddd.Vect());
|
||||
TVector3 normalmumu = muplusddd.Vect().Cross(muminusddd.Vect());
|
||||
|
||||
TLorentzVector kpiddd(kpi);
|
||||
kpiddd.Boost(bboost);
|
||||
|
||||
if (bplus) {
|
||||
phi = normalkpi.Angle(normalmumu);
|
||||
if ((normalmumu.Cross(normalkpi)).Dot(kpiddd.Vect()) < 0.0)
|
||||
phi = -phi;
|
||||
}
|
||||
else
|
||||
{
|
||||
phi = normalkpi.Angle(-normalmumu);
|
||||
if ((normalmumu.Cross(normalkpi)).Dot(kpiddd.Vect()) < 0.0)
|
||||
phi = -phi;
|
||||
}
|
||||
|
||||
spdlog::trace("Calculated angles: \t ctl= {0:0.2f},\t ctk = {1:0.2f}, \t phi = {1:0.2f}", costhetal, costhetak ,phi);
|
||||
return;
|
||||
}
|
||||
|
||||
//calculate angles (Heidelberg2018). Should be 100% identical to LHCb convention
|
||||
//definition as in LHCb-ANA-2013-097 page 23
|
||||
void bu2kstarmumu_loader::hd_angles(bool bplus, const TLorentzVector& muplus, const TLorentzVector& muminus, const TLorentzVector& kaon, const TLorentzVector& pion, double& costhetal_lhs, double& costhetal_rhs, double& costhetak_lhs, double& costhetak_rhs, double& phi){
|
||||
|
||||
//4D and boost vector of B system
|
||||
TLorentzVector B = (muplus + muminus + kaon + pion);
|
||||
TVector3 boost_B = B.BoostVector();
|
||||
|
||||
//ctk
|
||||
TLorentzVector kaon_in_B = kaon;
|
||||
kaon_in_B.Boost(-boost_B);
|
||||
TLorentzVector pion_in_B = pion;
|
||||
pion_in_B.Boost(-boost_B);
|
||||
TLorentzVector kstar_in_B = kaon_in_B + pion_in_B;
|
||||
|
||||
TLorentzVector kaon_in_kstar = kaon_in_B;
|
||||
kaon_in_kstar.Boost(-kstar_in_B.BoostVector());
|
||||
|
||||
costhetak_lhs = kaon_in_kstar.Vect().Unit().Dot(kstar_in_B.Vect().Unit());
|
||||
|
||||
TLorentzVector B_in_kstar = B;
|
||||
B_in_kstar.Boost(-boost_B);
|
||||
B_in_kstar.Boost(-kstar_in_B.BoostVector());
|
||||
|
||||
costhetak_rhs = kaon_in_kstar.Vect().Unit().Dot(-B_in_kstar.Vect().Unit());
|
||||
|
||||
|
||||
//ctl
|
||||
TLorentzVector muplus_in_B = bplus ? muplus : muminus;
|
||||
muplus_in_B.Boost(-boost_B);
|
||||
TLorentzVector muminus_in_B = bplus ? muminus : muplus;
|
||||
muminus_in_B.Boost(-boost_B);
|
||||
TLorentzVector dimuon_in_B = muplus_in_B + muminus_in_B;
|
||||
|
||||
TLorentzVector muon_in_dimuon = muplus_in_B;
|
||||
muon_in_dimuon.Boost(-dimuon_in_B.BoostVector());
|
||||
|
||||
costhetal_lhs = muon_in_dimuon.Vect().Unit().Dot(dimuon_in_B.Vect().Unit());
|
||||
|
||||
TLorentzVector B_in_dimuon = B;
|
||||
B_in_dimuon.Boost(-boost_B);
|
||||
B_in_dimuon.Boost(-dimuon_in_B.BoostVector());
|
||||
|
||||
costhetal_rhs = muon_in_dimuon.Vect().Unit().Dot(-B_in_dimuon.Vect().Unit());
|
||||
|
||||
//phi
|
||||
TVector3 normalkpi = (kaon_in_B.Vect().Unit().Cross(pion_in_B.Vect().Unit())).Unit();
|
||||
TVector3 normalmumu = (muplus_in_B.Vect().Unit().Cross(muminus_in_B.Vect().Unit())).Unit();
|
||||
phi = normalkpi.Angle(normalmumu);
|
||||
if ((bplus ? 1. : -1.)*(normalmumu.Cross(normalkpi)).Dot(kstar_in_B.Vect().Unit()) < 0.0)
|
||||
phi = -phi;
|
||||
}
|
||||
|
||||
///B+ case: no further cuts in the tuple. Read (up to) all events without restrictions
|
||||
std::vector<event> bu2kstarmumu_loader::read_full_tuple(int year, std::string filename, std::string treename, bool isMC, bool mctruth, bool genLevelMC, int nevents) {
|
||||
|
||||
//Set a year for gen lvl MC by hand
|
||||
if(genLevelMC) year = 2017;
|
||||
|
||||
check_year(year);
|
||||
|
||||
//open the root file
|
||||
TFile* root_file = new TFile(filename.c_str(), "READ");
|
||||
assert(root_file->IsOpen());
|
||||
|
||||
//Read the tree
|
||||
TTree* tree = static_cast<TTree*>(root_file->Get(treename.c_str()));
|
||||
if (!tree){
|
||||
//Check if the tree exists, if not, return an empty vector
|
||||
spdlog::warn("Could not get tree {0:s} from file {1:s}", treename, filename);
|
||||
std::vector<fcnc::event> blank_vector;
|
||||
return blank_vector;
|
||||
//assert(0);
|
||||
}
|
||||
|
||||
std::vector<event> events;
|
||||
event meas;
|
||||
|
||||
Double_t mbu = PDGMASS_B;
|
||||
Double_t sigma_mbu = 0.0; //TODO: mbu possibly from the fit?
|
||||
Double_t mkstar = PDGMASS_K_STAR;
|
||||
|
||||
Double_t
|
||||
muplus_px, muplus_py, muplus_pz, muplus_pe,
|
||||
muminus_px, muminus_py, muminus_pz, muminus_pe,
|
||||
muplus_px_TRUE, muplus_py_TRUE, muplus_pz_TRUE, muplus_pe_TRUE,
|
||||
muminus_px_TRUE, muminus_py_TRUE, muminus_pz_TRUE, muminus_pe_TRUE,
|
||||
kaon_px, kaon_py, kaon_pz, kaon_pe,
|
||||
pion_px, pion_py, pion_pz, pion_pe,
|
||||
kaon_pt, pion_pt, muplus_pt, muminus_pt,
|
||||
Ks_pi_plus_px, Ks_pi_plus_py, Ks_pi_plus_pz, Ks_pi_plus_pt, Ks_pi_plus_pe,
|
||||
Ks_pi_minus_px, Ks_pi_minus_py, Ks_pi_minus_pz, Ks_pi_minus_pt, Ks_pi_minus_pe,
|
||||
gamma1_px, gamma1_py, gamma1_pz, gamma1_pt, gamma1_pe,
|
||||
gamma2_px, gamma2_py, gamma2_pz, gamma2_pt, gamma2_pe,
|
||||
totalweight, delta_weight;
|
||||
|
||||
Double_t ctl_TT, ctk_TT, phi_TT;
|
||||
|
||||
Int_t b_id = 521, muplus_id = -13, muminus_id = +13;//, kaon_id, pion_id;
|
||||
Int_t DDLL;
|
||||
|
||||
UInt_t runno = 0;
|
||||
ULong64_t gpstime = 0;
|
||||
Short_t polarity = 0;
|
||||
|
||||
if(!genLevelMC){
|
||||
tree->SetBranchAddress(opts->DTF ? "B_plus_M_DTF" : "B_plus_MM",&mbu);
|
||||
tree->SetBranchAddress(opts->DTF ? "B_plus_MERR_DTF" : "B_plus_MMERR",&sigma_mbu);
|
||||
tree->SetBranchAddress(opts->DTF ? "K_star_plus_M_scaled" : "K_star_plus_MM", &mkstar);
|
||||
|
||||
tree->SetBranchAddress("Polarity", &polarity);
|
||||
tree->SetBranchAddress("runNumber", &runno);
|
||||
|
||||
tree->SetBranchAddress("B_plus_ThetaL", &ctl_TT);
|
||||
tree->SetBranchAddress("B_plus_ThetaK", &ctk_TT);
|
||||
tree->SetBranchAddress("B_plus_Phi", &phi_TT);
|
||||
}
|
||||
|
||||
if (!mctruth && !genLevelMC){
|
||||
tree->SetBranchAddress("GpsTime", &gpstime);
|
||||
|
||||
tree->SetBranchAddress((opts->DTF ? "mu_plus_PX_DTF" : "mu_plus_PX"), &muplus_px);
|
||||
tree->SetBranchAddress((opts->DTF ? "mu_plus_PY_DTF" : "mu_plus_PY"), &muplus_py);
|
||||
tree->SetBranchAddress((opts->DTF ? "mu_plus_PZ_DTF" : "mu_plus_PZ"), &muplus_pz);
|
||||
tree->SetBranchAddress((opts->DTF ? "mu_plus_PE_DTF" : "mu_plus_PE"), &muplus_pe);
|
||||
tree->SetBranchAddress((opts->DTF ? "mu_plus_PT_DTF" : "mu_plus_PT"), &muplus_pt);
|
||||
|
||||
tree->SetBranchAddress((opts->DTF ? "mu_minus_PX_DTF" : "mu_minus_PX"), &muminus_px);
|
||||
tree->SetBranchAddress((opts->DTF ? "mu_minus_PY_DTF" : "mu_minus_PY"), &muminus_py);
|
||||
tree->SetBranchAddress((opts->DTF ? "mu_minus_PZ_DTF" : "mu_minus_PZ"), &muminus_pz);
|
||||
tree->SetBranchAddress((opts->DTF ? "mu_minus_PE_DTF" : "mu_minus_PE"), &muminus_pe);
|
||||
tree->SetBranchAddress((opts->DTF ? "mu_minus_PT_DTF" : "mu_minus_PT"), &muminus_pt);
|
||||
|
||||
if(opts->KS){ //K_S^0 pi^+ channel
|
||||
|
||||
if(opts->DTF){
|
||||
tree->SetBranchAddress("Ks_pi_plus_PX_DTF", &Ks_pi_plus_px);
|
||||
tree->SetBranchAddress("Ks_pi_plus_PY_DTF", &Ks_pi_plus_py);
|
||||
tree->SetBranchAddress("Ks_pi_plus_PZ_DTF", &Ks_pi_plus_pz);
|
||||
tree->SetBranchAddress("Ks_pi_plus_PT_DTF", &Ks_pi_plus_pt);
|
||||
tree->SetBranchAddress("Ks_pi_plus_PE_DTF", &Ks_pi_plus_pe);
|
||||
|
||||
tree->SetBranchAddress("Ks_pi_minus_PX_DTF", &Ks_pi_minus_px);
|
||||
tree->SetBranchAddress("Ks_pi_minus_PY_DTF", &Ks_pi_minus_py);
|
||||
tree->SetBranchAddress("Ks_pi_minus_PZ_DTF", &Ks_pi_minus_pz);
|
||||
tree->SetBranchAddress("Ks_pi_minus_PT_DTF", &Ks_pi_minus_pt);
|
||||
tree->SetBranchAddress("Ks_pi_minus_PE_DTF", &Ks_pi_minus_pe);
|
||||
}
|
||||
else{
|
||||
tree->SetBranchAddress("K_short_PX", &kaon_px);
|
||||
tree->SetBranchAddress("K_short_PY", &kaon_py);
|
||||
tree->SetBranchAddress("K_short_PZ", &kaon_pz);
|
||||
tree->SetBranchAddress("K_short_PE", &kaon_pe);
|
||||
tree->SetBranchAddress("K_short_PT", &kaon_pt);
|
||||
}
|
||||
|
||||
tree->SetBranchAddress((opts->DTF ? "pi_plus_PX_DTF" : "pi_plus_PX"), &pion_px);
|
||||
tree->SetBranchAddress((opts->DTF ? "pi_plus_PY_DTF" : "pi_plus_PY"), &pion_py);
|
||||
tree->SetBranchAddress((opts->DTF ? "pi_plus_PZ_DTF" : "pi_plus_PZ"), &pion_pz);
|
||||
tree->SetBranchAddress((opts->DTF ? "pi_plus_PE_DTF" : "pi_plus_PE"), &pion_pe);
|
||||
tree->SetBranchAddress((opts->DTF ? "pi_plus_PT_DTF" : "pi_plus_PT"), &pion_pt);
|
||||
|
||||
}
|
||||
else{ //K^+pi^0 channel
|
||||
tree->SetBranchAddress((opts->DTF ? "K_plus_PX_DTF" : "K_short_PX"), &kaon_px);
|
||||
tree->SetBranchAddress((opts->DTF ? "K_plus_PY_DTF" : "K_short_PY"), &kaon_py);
|
||||
tree->SetBranchAddress((opts->DTF ? "K_plus_PZ_DTF" : "K_short_PZ"), &kaon_pz);
|
||||
tree->SetBranchAddress((opts->DTF ? "K_plus_PE_DTF" : "K_short_PE"), &kaon_pe);
|
||||
tree->SetBranchAddress((opts->DTF ? "K_plus_PT_DTF" : "K_short_PT"), &kaon_pt);
|
||||
|
||||
if(opts->DTF){
|
||||
tree->SetBranchAddress("gamma1_PX_DTF", &gamma1_px);
|
||||
tree->SetBranchAddress("gamma1_PY_DTF", &gamma1_py);
|
||||
tree->SetBranchAddress("gamma1_PZ_DTF", &gamma1_pz);
|
||||
tree->SetBranchAddress("gamma1_PE_DTF", &gamma1_pe);
|
||||
tree->SetBranchAddress("gamma1_PT_DTF", &gamma1_pt);
|
||||
|
||||
tree->SetBranchAddress("gamma2_PX_DTF", &gamma2_px);
|
||||
tree->SetBranchAddress("gamma2_PY_DTF", &gamma2_py);
|
||||
tree->SetBranchAddress("gamma2_PZ_DTF", &gamma2_pz);
|
||||
tree->SetBranchAddress("gamma2_PE_DTF", &gamma2_pe);
|
||||
tree->SetBranchAddress("gamma2_PT_DTF", &gamma2_pt);
|
||||
}
|
||||
else{
|
||||
tree->SetBranchAddress("pi_zero_resolved_PX", &pion_px);
|
||||
tree->SetBranchAddress("pi_zero_resolved_PY", &pion_py);
|
||||
tree->SetBranchAddress("pi_zero_resolved_PZ", &pion_pz);
|
||||
tree->SetBranchAddress("pi_zero_resolved_PE", &pion_pe);
|
||||
tree->SetBranchAddress("pi_zero_resolved_PT", &pion_pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(genLevelMC){
|
||||
if(opts->KS){
|
||||
tree->SetBranchAddress("KS0_TRUEP_X", &kaon_px);
|
||||
tree->SetBranchAddress("KS0_TRUEP_Y", &kaon_py);
|
||||
tree->SetBranchAddress("KS0_TRUEP_Z", &kaon_pz);
|
||||
tree->SetBranchAddress("KS0_TRUEP_E", &kaon_pe);
|
||||
|
||||
tree->SetBranchAddress("piplus0_TRUEP_X", &pion_px);
|
||||
tree->SetBranchAddress("piplus0_TRUEP_Y", &pion_py);
|
||||
tree->SetBranchAddress("piplus0_TRUEP_Z", &pion_pz);
|
||||
tree->SetBranchAddress("piplus0_TRUEP_E", &pion_pe);
|
||||
|
||||
tree->SetBranchAddress("piplus_TRUEP_X", &Ks_pi_plus_px);
|
||||
tree->SetBranchAddress("piplus_TRUEP_Y", &Ks_pi_plus_py);
|
||||
tree->SetBranchAddress("piplus_TRUEP_Z", &Ks_pi_plus_pz);
|
||||
tree->SetBranchAddress("piplus_TRUEP_E", &Ks_pi_plus_pe);
|
||||
|
||||
tree->SetBranchAddress("piminus_TRUEP_X", &Ks_pi_minus_px);
|
||||
tree->SetBranchAddress("piminus_TRUEP_Y", &Ks_pi_minus_py);
|
||||
tree->SetBranchAddress("piminus_TRUEP_Z", &Ks_pi_minus_pz);
|
||||
tree->SetBranchAddress("piminus_TRUEP_E", &Ks_pi_minus_pe);
|
||||
|
||||
}
|
||||
else{
|
||||
tree->SetBranchAddress("Kplus_TRUEP_X", &kaon_px);
|
||||
tree->SetBranchAddress("Kplus_TRUEP_Y", &kaon_py);
|
||||
tree->SetBranchAddress("Kplus_TRUEP_Z", &kaon_pz);
|
||||
tree->SetBranchAddress("Kplus_TRUEP_E", &kaon_pe);
|
||||
|
||||
tree->SetBranchAddress("pi0_TRUEP_X", &pion_px);
|
||||
tree->SetBranchAddress("pi0_TRUEP_Y", &pion_py);
|
||||
tree->SetBranchAddress("pi0_TRUEP_Z", &pion_pz);
|
||||
tree->SetBranchAddress("pi0_TRUEP_E", &pion_pe);
|
||||
|
||||
tree->SetBranchAddress("muplus_TRUEP_X", &muplus_px_TRUE);
|
||||
tree->SetBranchAddress("muplus_TRUEP_Y", &muplus_py_TRUE);
|
||||
tree->SetBranchAddress("muplus_TRUEP_Z", &muplus_pz_TRUE);
|
||||
tree->SetBranchAddress("muplus_TRUEP_E", &muplus_pe_TRUE);
|
||||
|
||||
tree->SetBranchAddress("muminus_TRUEP_X", &muminus_px_TRUE);
|
||||
tree->SetBranchAddress("muminus_TRUEP_Y", &muminus_py_TRUE);
|
||||
tree->SetBranchAddress("muminus_TRUEP_Z", &muminus_pz_TRUE);
|
||||
tree->SetBranchAddress("muminus_TRUEP_E", &muminus_pe_TRUE);
|
||||
}
|
||||
}
|
||||
else{ //use MC true information
|
||||
if(opts->KS){
|
||||
tree->SetBranchAddress("K_short_TRUEP_X", &kaon_px);
|
||||
tree->SetBranchAddress("K_short_TRUEP_Y", &kaon_py);
|
||||
tree->SetBranchAddress("K_short_TRUEP_Z", &kaon_pz);
|
||||
tree->SetBranchAddress("K_short_TRUEP_E", &kaon_pe);
|
||||
|
||||
tree->SetBranchAddress("pi_plus_TRUEP_X", &pion_px);
|
||||
tree->SetBranchAddress("pi_plus_TRUEP_Y", &pion_py);
|
||||
tree->SetBranchAddress("pi_plus_TRUEP_Z", &pion_pz);
|
||||
tree->SetBranchAddress("pi_plus_TRUEP_E", &pion_pe);
|
||||
}
|
||||
else{
|
||||
tree->SetBranchAddress("K_plus_TRUEP_X", &kaon_px);
|
||||
tree->SetBranchAddress("K_plus_TRUEP_Y", &kaon_py);
|
||||
tree->SetBranchAddress("K_plus_TRUEP_Z", &kaon_pz);
|
||||
tree->SetBranchAddress("K_plus_TRUEP_E", &kaon_pe);
|
||||
|
||||
tree->SetBranchAddress("pi_zero_resolved_TRUEP_X", &pion_px);
|
||||
tree->SetBranchAddress("pi_zero_resolved_TRUEP_Y", &pion_py);
|
||||
tree->SetBranchAddress("pi_zero_resolved_TRUEP_Z", &pion_pz);
|
||||
tree->SetBranchAddress("pi_zero_resolved_TRUEP_E", &pion_pe);
|
||||
}
|
||||
}
|
||||
|
||||
//For any MC, always link the TRUE muon as well:
|
||||
if(isMC || mctruth){
|
||||
tree->SetBranchAddress("mu_plus_TRUEP_X", &muplus_px_TRUE);
|
||||
tree->SetBranchAddress("mu_plus_TRUEP_Y", &muplus_py_TRUE);
|
||||
tree->SetBranchAddress("mu_plus_TRUEP_Z", &muplus_pz_TRUE);
|
||||
tree->SetBranchAddress("mu_plus_TRUEP_E", &muplus_pe_TRUE);
|
||||
|
||||
tree->SetBranchAddress("mu_minus_TRUEP_X", &muminus_px_TRUE);
|
||||
tree->SetBranchAddress("mu_minus_TRUEP_Y", &muminus_py_TRUE);
|
||||
tree->SetBranchAddress("mu_minus_TRUEP_Z", &muminus_pz_TRUE);
|
||||
tree->SetBranchAddress("mu_minus_TRUEP_E", &muminus_pe_TRUE);
|
||||
}
|
||||
|
||||
//particle IDs:
|
||||
if(genLevelMC){
|
||||
tree->SetBranchAddress("Kst_892_plus_MC_MOTHER_ID", &b_id);
|
||||
}
|
||||
else{
|
||||
tree->SetBranchAddress("B_plus_ID", &b_id);
|
||||
tree->SetBranchAddress("mu_minus_ID", &muminus_id);
|
||||
tree->SetBranchAddress("mu_plus_ID", &muplus_id);
|
||||
}
|
||||
|
||||
//for K_S^0 channel, get DD or LL track information
|
||||
if(opts->KS && !genLevelMC)tree->SetBranchAddress("KshortDecayInVeLo", &DDLL);
|
||||
|
||||
//load either sWeights (data) or MC reweights (signal, reference and phase-space MC)
|
||||
if(!genLevelMC){
|
||||
if(isMC){
|
||||
if (opts->KS){
|
||||
tree->SetBranchAddress("weight2D_nLongTracks", &totalweight);
|
||||
tree->SetBranchAddress("delta_weight2D_nLongTracks", &delta_weight);
|
||||
}
|
||||
else{
|
||||
tree->SetBranchAddress("weight2D_nLongTracks_TM_rndGamma", &totalweight);
|
||||
tree->SetBranchAddress("delta_weight2D_nLongTracks_TM_rndGamma", &delta_weight);
|
||||
}
|
||||
}
|
||||
else tree->SetBranchAddress("N_Bplus_sw", &totalweight);
|
||||
}
|
||||
|
||||
//determine number of events to load:
|
||||
unsigned int nentries = tree->GetEntries();
|
||||
if (nevents > 0){
|
||||
unsigned int n = TMath::Abs(nevents);
|
||||
if(n < nentries)nentries = n;
|
||||
}
|
||||
spdlog::info("Reading {0:d} events from file {1:s}", nentries ,filename);
|
||||
|
||||
bool DDtracks = strcmp(opts->DDLL.c_str(), "DD") == 0;
|
||||
|
||||
std::vector<int>vCorruptedEvents;
|
||||
vCorruptedEvents.clear();
|
||||
|
||||
|
||||
//loop over input tree:
|
||||
for(unsigned int j=0; j < nentries; j++){
|
||||
tree->GetEntry(j);
|
||||
if (j % (tree->GetEntries()/10) == 0) std::cout << "\r[" << round(double(j*100)/tree->GetEntries()) << "%]" << std::flush;
|
||||
|
||||
//Is it a B+ or a B-?
|
||||
bool b_plus = b_id > 0;
|
||||
|
||||
//for genLevelMonteCarlo: define muonID accordingly to B_id:
|
||||
if(genLevelMC){
|
||||
muminus_id = b_plus ? +13 : -13;
|
||||
muplus_id = b_plus ? -13 : +13;
|
||||
}
|
||||
|
||||
//skip events in K_S^0 sample that have incorrect tracktype
|
||||
if(opts->KS && !genLevelMC){
|
||||
if( DDtracks && DDLL)continue;
|
||||
if(!DDtracks && !DDLL)continue;
|
||||
}
|
||||
|
||||
if(genLevelMC || mctruth){ //MC TRUE samples and GenLevel samples use the MC true information:
|
||||
muminus_px = muminus_px_TRUE;
|
||||
muminus_py = muminus_py_TRUE;
|
||||
muminus_pz = muminus_pz_TRUE;
|
||||
muminus_pe = muminus_pe_TRUE;
|
||||
muplus_px = muplus_px_TRUE;
|
||||
muplus_py = muplus_py_TRUE;
|
||||
muplus_pz = muplus_pz_TRUE;
|
||||
muplus_pe = muplus_pe_TRUE;
|
||||
}
|
||||
|
||||
//initialize 4D vectors for angel calculations
|
||||
TLorentzVector muplus, muminus, kaon, pion, muplus_TRUE, muminus_TRUE;
|
||||
|
||||
if(muminus_id == muplus_id){
|
||||
spdlog::critical("Cannot have mu+ and mu- to have the same ID: {0:d}", muplus_id);
|
||||
spdlog::critical("Event ID = {0:d}");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (muminus_id == +13){
|
||||
muminus = TLorentzVector(muminus_px, muminus_py, muminus_pz, muminus_pe);
|
||||
muminus_TRUE = TLorentzVector(muminus_px_TRUE, muminus_py_TRUE, muminus_pz_TRUE, muminus_pe_TRUE);
|
||||
}
|
||||
else if(muminus_id == -13){
|
||||
muplus = TLorentzVector(muminus_px, muminus_py, muminus_pz, muminus_pe);
|
||||
muplus_TRUE = TLorentzVector(muminus_px_TRUE, muminus_py_TRUE, muminus_pz_TRUE, muminus_pe_TRUE);
|
||||
}
|
||||
else{
|
||||
spdlog::critical("Found invalid muon ID in mu-: {0:d}", muminus_id);
|
||||
assert(0);
|
||||
}
|
||||
if (muplus_id == -13){
|
||||
muplus = TLorentzVector(muplus_px, muplus_py, muplus_pz, muplus_pe);
|
||||
muplus_TRUE = TLorentzVector(muplus_px_TRUE, muplus_py_TRUE, muplus_pz_TRUE, muplus_pe_TRUE);
|
||||
}
|
||||
else if(muplus_id == +13){
|
||||
muminus = TLorentzVector(muplus_px, muplus_py, muplus_pz, muplus_pe);
|
||||
muminus_TRUE = TLorentzVector(muplus_px_TRUE, muplus_py_TRUE, muplus_pz_TRUE, muplus_pe_TRUE);
|
||||
}
|
||||
else{
|
||||
spdlog::critical("Found invalid muon ID in mu-: {0:d}", muplus_id);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if(opts->DTF && !mctruth && !genLevelMC){
|
||||
//If no true information, re-reconstruct the pion+kaon pair
|
||||
if(opts->KS){
|
||||
pion = TLorentzVector(pion_px, pion_py, pion_pz, pion_pe);
|
||||
kaon = TLorentzVector(Ks_pi_plus_px, Ks_pi_plus_py, Ks_pi_plus_pz, Ks_pi_plus_pe)
|
||||
+ TLorentzVector(Ks_pi_minus_px, Ks_pi_minus_py, Ks_pi_minus_pz, Ks_pi_minus_pe);
|
||||
}
|
||||
else{
|
||||
pion = TLorentzVector(gamma1_px, gamma1_py, gamma1_pz, gamma1_pe)
|
||||
+ TLorentzVector(gamma2_px, gamma2_py, gamma2_pz, gamma2_pe);
|
||||
kaon = TLorentzVector(kaon_px, kaon_py, kaon_pz, kaon_pe);
|
||||
}
|
||||
}
|
||||
else{ //in case of true info, read kaon and pion directly
|
||||
pion = TLorentzVector(pion_px, pion_py, pion_pz, pion_pe);
|
||||
kaon = TLorentzVector(kaon_px, kaon_py, kaon_pz, kaon_pe);
|
||||
}
|
||||
|
||||
|
||||
//In case of genLvl MC recalculate B mass
|
||||
if(genLevelMC) mbu = (kaon+pion+muplus+muminus).M();
|
||||
|
||||
//de-bugging
|
||||
if (opts->KS){
|
||||
spdlog::trace("KS_piplus_PX: {0:f}", Ks_pi_plus_px );
|
||||
spdlog::trace("KS_piplus_PY: {0:f}", Ks_pi_plus_py );
|
||||
spdlog::trace("KS_piplus_PZ: {0:f}", Ks_pi_plus_pz );
|
||||
spdlog::trace("KS_piplus_PE: {0:f}", Ks_pi_plus_pe );
|
||||
spdlog::trace("KS_piminus_PX: {0:f}", Ks_pi_minus_px);
|
||||
spdlog::trace("KS_piminus_PY: {0:f}", Ks_pi_minus_py);
|
||||
spdlog::trace("KS_piminus_PZ: {0:f}", Ks_pi_minus_pz);
|
||||
spdlog::trace("KS_piminus_PE: {0:f}", Ks_pi_minus_pe);
|
||||
}
|
||||
|
||||
//print vectors
|
||||
if(spdlog::default_logger_raw()->level()==spdlog::level::trace){
|
||||
spdlog::debug(b_plus ? "[B+]" : "[B-]");
|
||||
muplus.Print();
|
||||
muminus.Print();
|
||||
pion.Print();
|
||||
kaon.Print();
|
||||
}
|
||||
|
||||
//make sure that the TRUE_P's of muons in MC are not identical
|
||||
if(isMC && opts->reject_identical_muon_TRUEID){
|
||||
if(muplus_TRUE.X() == muminus_TRUE.X() &&
|
||||
muplus_TRUE.Y() == muminus_TRUE.Y() &&
|
||||
muplus_TRUE.Z() == muminus_TRUE.Z() &&
|
||||
muplus_TRUE.T() == muminus_TRUE.T()){
|
||||
vCorruptedEvents.push_back(j);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//make sure that mup != mun
|
||||
if(muplus.X() == muminus.X() &&
|
||||
muplus.Y() == muminus.Y() &&
|
||||
muplus.Z() == muminus.Z() &&
|
||||
muplus.T() == muminus.T()){
|
||||
vCorruptedEvents.push_back(j);
|
||||
continue;
|
||||
}
|
||||
|
||||
//get pseudo_q2 from opening angle of leptons:
|
||||
Double_t pseudo_q2 = muplus.Angle(muminus.Vect());
|
||||
// Double_t pseudo_q2 = std::max(muminus.Pt(), muplus.Pt());
|
||||
|
||||
//calculate angles
|
||||
Double_t ctl_theory, ctk_theory, phi_theory;
|
||||
Double_t ctl_lhcb, ctk_lhcb, phi_lhcb;
|
||||
Double_t ctl_converted, ctk_converted, phi_converted;
|
||||
Double_t ctl_hd_lhs, ctk_hd_lhs, phi_hd;
|
||||
Double_t ctl_hd_rhs, ctk_hd_rhs;
|
||||
|
||||
theory_angles( muplus, muminus, kaon, pion, ctl_theory, ctk_theory, phi_theory);
|
||||
lhcb_angles (b_plus, muplus, muminus, kaon, pion, ctl_lhcb, ctk_lhcb, phi_lhcb);
|
||||
hd_angles (b_plus, muplus, muminus, kaon, pion, ctl_hd_lhs, ctl_hd_rhs, ctk_hd_rhs, ctk_hd_lhs, phi_hd);
|
||||
|
||||
//check and convert theory convention to LHCb convention
|
||||
ctl_converted = b_plus ? ctl_theory : -ctl_theory;
|
||||
ctk_converted = -ctk_theory;
|
||||
if (b_plus) phi_converted = phi_theory > 0 ? TMath::Pi() - phi_theory : -TMath::Pi() - phi_theory;
|
||||
else phi_converted = phi_theory;
|
||||
|
||||
//convert tupletoolP2VV angles to cos()
|
||||
ctl_TT = cos(ctl_TT);
|
||||
ctk_TT = cos(ctk_TT);
|
||||
|
||||
spdlog::trace("Event #{0:d}", j);
|
||||
spdlog::trace("B" + std::string(b_plus ? "+" : "-") + "\t\t: Theory \tLHCb \t\tConverted \tHD(lhs) \tHD(rhs)\tTupleToolP2VV");
|
||||
spdlog::trace("cos(theta_L)\t:{0:0.4f}\t {0:0.4f}\t\t{0:0.4f}\t\t{0:0.4f}\t\t{0:0.4f}\t\t{0:0.4f}\t\t", ctl_theory, ctl_lhcb, ctl_converted, ctl_hd_lhs, ctl_hd_rhs, ctl_TT);
|
||||
spdlog::trace("cos(theta_k)\t:{0:0.4f}\t {0:0.4f}\t\t{0:0.4f}\t\t{0:0.4f}\t\t{0:0.4f}\t\t{0:0.4f}\t\t", ctk_theory, ctk_lhcb , ctk_converted, ctk_hd_lhs, ctk_hd_rhs, ctk_TT);
|
||||
spdlog::trace("phit:{0:0.4f}\t {0:0.4f}\t\t{0:0.4f}\t\t{0:0.4f}\t\t{0:0.4f}\t\t{0:0.4f}\t\t\n", phi_theory, phi_lhcb, phi_converted, phi_hd, phi_TT);
|
||||
|
||||
|
||||
//test all angles to be identical:
|
||||
assert(fabs(ctl_lhcb - ctl_converted) < 1.0e-8);
|
||||
assert(fabs(ctk_lhcb - ctk_converted) < 1.0e-8);
|
||||
assert(fabs(phi_lhcb - phi_converted) < 1.0e-8);
|
||||
|
||||
assert(fabs(ctl_lhcb - ctl_hd_lhs) < 1.0e-8);
|
||||
assert(fabs(ctl_lhcb - ctl_hd_rhs) < 1.0e-8);
|
||||
assert(fabs(ctk_lhcb - ctk_hd_lhs) < 1.0e-8);
|
||||
assert(fabs(ctk_lhcb - ctk_hd_rhs) < 1.0e-8);
|
||||
assert(fabs(phi_lhcb - phi_hd) < 1.0e-8);
|
||||
|
||||
|
||||
meas.year = year;
|
||||
meas.m = mbu;
|
||||
meas.sigma_m = sigma_mbu;
|
||||
meas.costhetal = ctl_lhcb;
|
||||
meas.costhetak = ctk_lhcb;
|
||||
meas.phi = phi_lhcb;
|
||||
meas.costhetal_fa = ctl_lhcb;
|
||||
meas.costhetak_fa = ctk_lhcb;
|
||||
meas.phi_fa = phi_lhcb;
|
||||
meas.q2 = (muplus+muminus).Mag2()/1.0e+6;//in gev2
|
||||
meas.p2 = (kaon+pion).Mag2()/1.0e+6;//in gev2
|
||||
meas.weight = totalweight;
|
||||
meas.delta_weight = delta_weight;
|
||||
meas.mkpi = mkstar;
|
||||
meas.cp_conjugate = b_plus;//this is B+
|
||||
meas.max_mu_pt = TMath::Max(muplus.Pt(), muminus.Pt());
|
||||
meas.kaon_pt = kaon.Pt();
|
||||
meas.pseudo_q2 = pseudo_q2;
|
||||
meas.magnet = polarity;
|
||||
|
||||
|
||||
bool ApplyGenLevelTightCuts = false;
|
||||
if(genLevelMC && ApplyGenLevelTightCuts){
|
||||
if(muplus.Theta() < 0.005 || muplus.Theta() > 0.4)continue;
|
||||
if(muminus.Theta() < 0.005 || muminus.Theta() > 0.4)continue;
|
||||
if(pion.Theta() < 0.005 || pion.Theta() > 0.4)continue;
|
||||
|
||||
TLorentzVector piplus(Ks_pi_plus_px, Ks_pi_plus_py, Ks_pi_plus_pz, Ks_pi_plus_pe);
|
||||
TLorentzVector piminus(Ks_pi_minus_px, Ks_pi_minus_py, Ks_pi_minus_pz, Ks_pi_minus_pe);
|
||||
if(piplus.P() <= 1800)continue;
|
||||
if(piminus.P() <= 1800)continue;
|
||||
if(piplus.Theta() < 0.005 || piplus.Theta() > 0.4)continue;
|
||||
if(piminus.Theta() < 0.005 || piminus.Theta() > 0.4)continue;
|
||||
}
|
||||
|
||||
events.push_back(meas);
|
||||
|
||||
}
|
||||
if(vCorruptedEvents.size() > 0){
|
||||
spdlog::warn("Found {0:d} corrupted events with idendical muons: ",vCorruptedEvents.size());
|
||||
for(UInt_t c = 0; c < vCorruptedEvents.size(); c++) spdlog::warn("Events at: {0:d}",vCorruptedEvents.at(c));
|
||||
}
|
||||
|
||||
root_file->Close();
|
||||
delete root_file;
|
||||
spdlog::info("DONE reading {0:d} events from file " + filename,events.size());
|
||||
return events;
|
||||
|
||||
}
|
||||
|
||||
|
44
Code/FCNCFitter/sources/Core/bu2kstarmumu_loader.hh
Executable file
44
Code/FCNCFitter/sources/Core/bu2kstarmumu_loader.hh
Executable file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @file bu2kstarmumu_loader.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BU2KSTARMUMU_LOADER_H
|
||||
#define BU2KSTARMUMU_LOADER_H
|
||||
|
||||
#include "TLorentzVector.h"
|
||||
|
||||
namespace fcnc {
|
||||
class options;
|
||||
class event;
|
||||
|
||||
///class that implements the ability to load the Bs -> JPsi Phi signal decay from Zoo-ntuple root files.
|
||||
class bu2kstarmumu_loader {
|
||||
public:
|
||||
///constructor
|
||||
bu2kstarmumu_loader(options* o):
|
||||
opts(o) {};
|
||||
///Read events from decaytree tuple
|
||||
std::vector<event> read_decaytree_tuple(std::string filename, std::string treename, bool mctruth=false, int nevents=1000000, int syst_variation=-1);
|
||||
std::vector<event> read_full_tuple(int year, std::string filename, std::string treename, bool isMC = false, bool mctruth=false, bool genLevelMC = false, int nevents=1000000);
|
||||
|
||||
void test_angles(std::string filename, std::string treename, bool mctruth=false, int nevents=1000000);
|
||||
|
||||
///calculate decay angles according to theory convention http://arxiv.org/abs/0805.2525
|
||||
void theory_angles(const TLorentzVector& muplus, const TLorentzVector& muminus, const TLorentzVector& kaon, const TLorentzVector& pion, double& costhetal, double& costhetak, double& phi);
|
||||
|
||||
///calculate decay angles according to lhcb convention http://arxiv.org/abs/1304.6325
|
||||
void lhcb_angles(bool bplus, const TLorentzVector& muplus, const TLorentzVector& muminus, const TLorentzVector& kaon, const TLorentzVector& pion, double& costhetal, double& costhetak, double& phi);
|
||||
|
||||
void hd_angles(bool bplus, const TLorentzVector& muplus, const TLorentzVector& muminus, const TLorentzVector& kaon, const TLorentzVector& pion, double& costhetal_lhs, double& costhetal_rhs, double& costhetak_lhs, double& costhetak_rhs, double& phi);
|
||||
|
||||
private:
|
||||
///pointer to options
|
||||
options* opts;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
953
Code/FCNCFitter/sources/Core/bu2kstarmumu_parameters.cc
Executable file
953
Code/FCNCFitter/sources/Core/bu2kstarmumu_parameters.cc
Executable file
@ -0,0 +1,953 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream> // std::istringstream
|
||||
|
||||
#include <bu2kstarmumu_parameters.hh>
|
||||
#include <fitter.hh>
|
||||
#include <helpers.hh>
|
||||
#include <paths.hh>
|
||||
|
||||
#include <TFile.h>
|
||||
#include <TMath.h>
|
||||
#include <TChain.h>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
//fixConstr constructor
|
||||
fixConstr::fixConstr(bool b_fix,bool b_constr){
|
||||
if (b_fix && b_constr){ //Check if both constrain and fix are set to true
|
||||
//If yes, set constrain to false without modifying the input bools
|
||||
spdlog::warn("Cannot both fix and constrain a parameter.\n The parameter is fixed, setting constrain to false.");
|
||||
spdlog::warn("Check your options.");
|
||||
fix = true;
|
||||
constrain = false;
|
||||
return;
|
||||
}
|
||||
fix = b_fix;
|
||||
constrain = b_constr;
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace fcnc;
|
||||
|
||||
void bu2kstarmumu_parameters::use_default_bkg(){
|
||||
//Set all backgrounds to be flat
|
||||
cbkgctl0.init(1.0, -1.0, 1.0, 0.0);
|
||||
cbkgctl1.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgctl2.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgctl3.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgctl4.init(0.0, -1.0, 1.0, 0.0);
|
||||
|
||||
cbkgctk0.init(1.0, -1.0, 1.0, 0.0);
|
||||
cbkgctk1.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgctk2.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgctk3.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgctk4.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgctk5.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgctk6.init(0.0, -1.0, 1.0, 0.0);
|
||||
|
||||
cbkgphi0.init(1.0, -1.0, 1.0, 0.0);
|
||||
cbkgphi1.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgphi2.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgphi3.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgphi4.init(0.0, -1.0, 1.0, 0.0);
|
||||
|
||||
cbkgmkpi0.init(1.0, -1.0, 1.0, 0.0);
|
||||
cbkgmkpi1.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgmkpi2.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgmkpi3.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgmkpi4.init(0.0, -1.0, 1.0, 0.0);
|
||||
|
||||
cswavemkpi0.init(1.0, -1.0, 1.0, 0.0);
|
||||
cswavemkpi1.init(0.0, -1.0, 1.0, 0.0);
|
||||
cswavemkpi2.init(0.0, -1.0, 1.0, 0.0);
|
||||
cswavemkpi3.init(0.0, -1.0, 1.0, 0.0);
|
||||
cswavemkpi4.init(0.0, -1.0, 1.0, 0.0);
|
||||
|
||||
cbkgp20.init(1.0, -1.0, 1.0, 0.0);
|
||||
cbkgp21.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgp22.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgp23.init(0.0, -1.0, 1.0, 0.0);
|
||||
cbkgp24.init(0.0, -1.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::use_default_observables(){
|
||||
if (opts->fit_pprimes){
|
||||
Fl.init (0.7, 0.0, 2.0*PAR_ANG_RANGE, 0.0);
|
||||
P1.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
P2.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
P3.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
P4.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
P5.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
P6.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
P8.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
}
|
||||
else{
|
||||
Fl.init (0.7, 0.0, 2.0*PAR_ANG_RANGE, 0.0);
|
||||
S1s.init(0.7, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S3.init (0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S4.init (0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S5.init (0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
Afb.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S6s.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S7.init (0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S8.init (0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S9.init (0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
//This function is used in the parameters constructor!
|
||||
void bu2kstarmumu_parameters::use_default(){
|
||||
Fl.init (0.7, 0.0, 2.0*PAR_ANG_RANGE, 0.0);
|
||||
S1s.init(0.7, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S3.init (0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S4.init (0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S5.init (0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
Afb.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S6s.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S7.init (0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S8.init (0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
S9.init (0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
|
||||
P1.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
P2.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
P3.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
P4.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
P5.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
P6.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
P8.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
|
||||
//S-wave parameters
|
||||
FS.init (0.0, 0.0, 2*PAR_ANG_RANGE, 0.0);
|
||||
SS1.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
SS2.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
SS3.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
SS4.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
SS5.init(0.0, -PAR_ANG_RANGE, PAR_ANG_RANGE, 0.0);
|
||||
|
||||
//signal fraction
|
||||
f_sig.init(PAR_N_SIG/(PAR_N_SIG+PAR_N_BKG), 0.0, 1.0, 0.0);
|
||||
n_sig.init(PAR_N_SIG, 0.0, 1.0e+6, 0.0);
|
||||
n_bkg.init(PAR_N_BKG, 0.0, 1.0e+6, 0.0);
|
||||
//mass parameters
|
||||
m_b.init (PDGMASS_B, B_MASS_LOW, B_MASS_HIGH, 0.0);
|
||||
m_res_1.init (DOUBLE_CB ? 1.0 : 0.5, 0.0, 1.0, 0.0);
|
||||
m_sigma_1.init(PAR_SIGMA, PAR_SIGMA_LOW, PAR_SIGMA_HIGH, 0.0);
|
||||
m_sigma_2.init(DOUBLE_CB ? 0.0 : PAR_SIGMA, PAR_SIGMA_LOW, PAR_SIGMA_HIGH, 0.0);
|
||||
//crystal ball
|
||||
m_scale.init(1.0, 0.0, 2.0, 0.0);
|
||||
alpha_1.init(1.0, 0.1, 10.0, 0.0);
|
||||
n_1.init (1.0, 0.1, 10.0, 0.0);
|
||||
alpha_2.init(1.0, 0.1, 10.0, 0.0);
|
||||
n_2.init (1.0, 0.1, 10.0, 0.0);
|
||||
|
||||
fm_tau.init(FIX_FM ? 1.0 : 0.5, 0.0, 1.0, 0.0);
|
||||
m_tau.init(PAR_TAU, PAR_TAU/PAR_TAU_SCALE, PAR_TAU*PAR_TAU_SCALE, 0.0);
|
||||
m_tau_2.init(PAR_TAU, PAR_TAU/PAR_TAU_SCALE, PAR_TAU*PAR_TAU_SCALE, 0.0);
|
||||
m_lambda.init(PAR_LAMBDA, PAR_LAMBDA/PAR_LAMBDA_SCALE, PAR_LAMBDA*PAR_LAMBDA_SCALE, 0.0);
|
||||
m_lambda_2.init(PAR_LAMBDA, PAR_LAMBDA/PAR_LAMBDA_SCALE, PAR_LAMBDA*PAR_LAMBDA_SCALE, 0.0);
|
||||
|
||||
//Welp, this will end up in Jpsi, but whatever :)
|
||||
eff_q2.init(bin_center(Q2_MIN_RANGE,Q2_MAX_RANGE), Q2_MIN_RANGE, Q2_MAX_RANGE, 0.0);
|
||||
|
||||
//TODO: figure out what these are
|
||||
asphase.init(MY_PI, 0.0, 2.0*MY_PI, 0.0);
|
||||
a.init(1.0, 0.0, 10.0, 0.0);
|
||||
r.init(1.0, 0.0, 10.0, 0.0);
|
||||
gammakstar.init(PAR_KSTAR_WIDTH/1.0e3, 0.01, PAR_KSTAR_WIDTH/0.5e3, 0.0); //With of K*
|
||||
mkstar.init(PDGMASS_K_STAR_PLUS/1.0e3, (K_ONE_PLUS-PAR_KSTAR_WIDTH)/1.0e3, (K_ONE_PLUS+PAR_KSTAR_WIDTH)/1.0e3, 0.0);
|
||||
//This is a K1 or K something
|
||||
mkstarplus.init(K_ONE_PLUS/1.0e3, (K_ONE_PLUS-PAR_K1_WIDTH)/1.0e3, (K_ONE_PLUS+PAR_K1_WIDTH)/1.0e3, 0.0);
|
||||
gammakstarplus.init(PAR_K1_WIDTH/1.0e3, 0.01, PAR_K1_WIDTH/0.5e3, 0.0); //Width of K1
|
||||
|
||||
|
||||
nthreshold.init(PAR_NTRESHOLD, 1.0, 10.0, 0.0);
|
||||
R.init(1.6, 0.0, 10.0, 0.0);
|
||||
|
||||
//Some other fancy resonances //TODO ask Eluned
|
||||
mf800.init(0.682, 0.1, 1.0, 0.0);
|
||||
gammaf800.init(0.547, 0.1, 1.0, 0.0);
|
||||
f800mag.init(0.1, 0.0, 1.0, 0.0);
|
||||
f800phase.init(0.5*MY_PI, -2.0*MY_PI, +2.0*MY_PI, 0.0);
|
||||
|
||||
//Set all backgrounds to be flat
|
||||
use_default_bkg();
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::load_param_values(std::string filename){
|
||||
|
||||
std::ifstream file(filename.c_str());;
|
||||
std::string line = "";
|
||||
if (file.is_open()){
|
||||
spdlog::info("Parameter values are being read from file "+filename+".");
|
||||
}
|
||||
else{
|
||||
spdlog::error("Could not load values from file " + filename);;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
UInt_t p_index;
|
||||
std::string p_name;
|
||||
Float_t p_value;
|
||||
Float_t p_error;
|
||||
//loop over lines in file and read values and errors of all parameters
|
||||
while(true){ //Jesus christ, another while(true). Shoot me, please.
|
||||
getline(file, line);
|
||||
spdlog::debug("Line: "+line);;
|
||||
if(file.eof()) break;
|
||||
std::istringstream istr(line);
|
||||
istr >> p_index;
|
||||
istr >> p_name;
|
||||
istr >> p_value;
|
||||
istr >> p_error;
|
||||
|
||||
//sanity check to make sure the parameter index fits to the parameter name:
|
||||
if(p_name != this->get_parameter(p_index)->get_name()){
|
||||
spdlog::critical("Trying to assign values of var=" + p_name + " to parameter=" + this->get_parameter(p_index)->get_name());;
|
||||
assert(p_name == this->get_parameter(p_index)->get_name());
|
||||
}
|
||||
|
||||
//assign value and error from file to parameters
|
||||
this->get_parameter(p_index)->set_values_n_errors(p_value, p_error);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::load_param(std::string filename, std::string parname){
|
||||
|
||||
std::ifstream file(filename.c_str());;
|
||||
std::string line = "";
|
||||
if (!file.is_open()){
|
||||
spdlog::error("\tCould not open file " + filename);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
UInt_t p_index;
|
||||
std::string p_name;
|
||||
Float_t p_value;
|
||||
Float_t p_error;
|
||||
//loop over lines in file and read values and errors of all parameters
|
||||
while(true){ //Dear kids,
|
||||
getline(file, line);
|
||||
spdlog::debug("Line: " + line);
|
||||
if(file.eof()) break; //never ever write code like this. Even at gunpoint. Don't.
|
||||
std::istringstream istr(line);
|
||||
istr >> p_index;
|
||||
istr >> p_name;
|
||||
istr >> p_value;
|
||||
istr >> p_error;
|
||||
|
||||
//continue if param name is identical
|
||||
if(p_name != parname) continue;
|
||||
|
||||
spdlog::debug("Load parameter: " + p_name + "={0:f}", p_value);
|
||||
|
||||
//sanity check to make sure the parameter index fits to the parameter name:
|
||||
assert(p_name == this->get_parameter(p_index)->get_name());
|
||||
|
||||
//assign value and error from file to parameters
|
||||
this->get_parameter(p_index)->set_values_n_errors(p_value, p_error);
|
||||
}
|
||||
file.close();
|
||||
return;
|
||||
}
|
||||
|
||||
double get_param_valueError_from_rootfile(std::string fileName, std::string name, int PDF, int bin, bool getError){
|
||||
//Retuns a value for given parametr from a given rootfile
|
||||
|
||||
//Open file
|
||||
spdlog::info("Opening " + fileName);
|
||||
TFile* file = new TFile(fileName.c_str(), "READ");
|
||||
|
||||
if (!file->GetListOfKeys()->Contains(name.c_str())){
|
||||
spdlog::critical("Wrong tree name " + name + "! Abort.");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
//Get the tree and set the branches to active
|
||||
TTree* tree = (TTree*)file->Get(name.c_str());
|
||||
tree->SetBranchStatus("*",1); //Activate all branches
|
||||
|
||||
//The root file is saved in a way that first bins in first pdf is saved
|
||||
//then the next pdf is saved, bin by bin
|
||||
//Meaning if I want to load event from bin 2 and pdf 1
|
||||
//tree->GetEntry(2)
|
||||
//If I want to load event from bin 2 and pdf 2, one needs to do
|
||||
//tree->GetEntry(totBins+2)
|
||||
//PDFs are named according to the Run! So if only Run 2 is fitted, the returned pdf is 2
|
||||
//This implementation is actually useful for checks
|
||||
//Therefore, starting entry is equal to int bin
|
||||
int entry_position = bin;
|
||||
|
||||
//Read the q2 bins
|
||||
int totBins = DEFAULT_TREE_INT;
|
||||
int pdf_idx = DEFAULT_TREE_INT;
|
||||
int bin_idx = DEFAULT_TREE_INT;
|
||||
double value = DEFAULT_TREE_VAL;
|
||||
double error = DEFAULT_TREE_ERR;
|
||||
int migrad = DEFAULT_TREE_INT;
|
||||
|
||||
tree->SetBranchAddress("totBins", &totBins);
|
||||
tree->SetBranchAddress("pdf", &pdf_idx);
|
||||
tree->SetBranchAddress("bin", &bin_idx);
|
||||
tree->SetBranchAddress("value",&value);
|
||||
tree->SetBranchAddress("migrad",&migrad);
|
||||
tree->SetBranchAddress("error",&error);
|
||||
|
||||
tree->GetEntry(entry_position);
|
||||
|
||||
//Check whether we got the right bin position
|
||||
if (bin_idx != bin){
|
||||
spdlog::critical("Something went very wrong for "+name);
|
||||
spdlog::critical("The read pdf {0:d} from position {1:d} doesn't agree with the wanted bin {2:d}", pdf_idx, entry_position, bin);
|
||||
assert(0);
|
||||
}
|
||||
while (pdf_idx != PDF){
|
||||
entry_position += totBins;
|
||||
if (entry_position >= tree->GetEntries()){
|
||||
spdlog::critical("Required PDF {0:d} for " + name + " not found!",PDF);
|
||||
assert(0);
|
||||
}
|
||||
tree->GetEntry(entry_position);
|
||||
}
|
||||
|
||||
|
||||
//Check if migrad makes sense
|
||||
if (migrad != 0){
|
||||
spdlog::warn("Careful! You are reading a fit that had failed migrad for " + name + "!");
|
||||
printMigradStatus(migrad);
|
||||
}
|
||||
|
||||
|
||||
|
||||
file->Close();
|
||||
spdlog::debug("Loaded " + name + " value is {0:f}", value);
|
||||
|
||||
return getError ? error : value;
|
||||
}
|
||||
|
||||
double get_param_value_from_rootfile(std::string fileName, std::string name, int PDF, int bin){
|
||||
return get_param_valueError_from_rootfile(fileName, name, PDF, bin, false);
|
||||
}
|
||||
double get_param_error_from_rootfile(std::string fileName, std::string name, int PDF, int bin){
|
||||
return get_param_valueError_from_rootfile(fileName, name, PDF, bin, true);
|
||||
}
|
||||
|
||||
int bu2kstarmumu_parameters::get_param_from_rootfile(std::string fileName, std::vector<std::string> names, int PDF, int bin, fixConstr FC){
|
||||
|
||||
//Open file
|
||||
spdlog::info("Opening " + fileName);
|
||||
TFile* file = new TFile(fileName.c_str(), "READ");
|
||||
|
||||
for (auto name: names){
|
||||
if (!file->GetListOfKeys()->Contains(name.c_str())){
|
||||
spdlog::critical("Wrong tree name " + name + "! Abort.");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
//Get the tree and set the branches to active
|
||||
TTree* tree = (TTree*)file->Get(name.c_str());
|
||||
tree->SetBranchStatus("*",1); //Activate all branches
|
||||
|
||||
//The root file is saved in a way that first bins in first pdf is saved
|
||||
//then the next pdf is saved, bin by bin
|
||||
//Meaning if I want to load event from bin 2 and pdf 1
|
||||
//tree->GetEntry(2)
|
||||
//If I want to load event from bin 2 and pdf 2, one needs to do
|
||||
//tree->GetEntry(totBins+2)
|
||||
//PDFs are named according to the Run! So if only Run 2 is fitted, the returned pdf is 2
|
||||
//This implementation is actually useful for checks
|
||||
//Therefore, starting entry is equal to int bin
|
||||
int entry_position = bin;
|
||||
|
||||
//Read the q2 bins
|
||||
int totBins = DEFAULT_TREE_INT;
|
||||
int pdf_idx = DEFAULT_TREE_INT;
|
||||
int bin_idx = DEFAULT_TREE_INT;
|
||||
tree->SetBranchAddress("totBins", &totBins);
|
||||
tree->SetBranchAddress("pdf", &pdf_idx);
|
||||
tree->SetBranchAddress("bin", &bin_idx);
|
||||
|
||||
//Now get all the parameters
|
||||
int migrad = DEFAULT_TREE_INT;
|
||||
int param_index = DEFAULT_TREE_INT;
|
||||
|
||||
double value = DEFAULT_TREE_VAL;
|
||||
double error = DEFAULT_TREE_ERR;
|
||||
double error_up = DEFAULT_TREE_ERR;
|
||||
double error_down = DEFAULT_TREE_ERR;
|
||||
double start_value = DEFAULT_TREE_VAL;
|
||||
double prev_value = DEFAULT_TREE_VAL;
|
||||
double prev_error = DEFAULT_TREE_ERR;
|
||||
|
||||
tree->SetBranchAddress("value",&value);
|
||||
tree->SetBranchAddress("error",&error);
|
||||
tree->SetBranchAddress("error_up",&error_up);
|
||||
tree->SetBranchAddress("error_down",&error_down);
|
||||
|
||||
tree->SetBranchAddress("start_value",&start_value); //Not really used: TODO
|
||||
tree->SetBranchAddress("prev_value",&prev_value); //Not really used: TODO
|
||||
tree->SetBranchAddress("prev_error",&prev_error); //Not really used: TODO
|
||||
|
||||
tree->SetBranchAddress("index",¶m_index);
|
||||
tree->SetBranchAddress("migrad",&migrad);
|
||||
|
||||
tree->GetEntry(entry_position);
|
||||
|
||||
//Check whether the file contains correct numbers of bins
|
||||
//If totBins are 1, let's assume this is fine and we are reading from ReferenceChannel
|
||||
if (unsigned (totBins) != opts->TheQ2binsmin.size() && totBins != 1){
|
||||
spdlog::warn("Wrong number of bins for " + name + "!");
|
||||
spdlog::warn("totBins = {0:d}\tnQ2bins= {1:d}",totBins,opts->TheQ2binsmin.size());
|
||||
}
|
||||
if (bin_idx != bin){
|
||||
spdlog::critical("Something went very wrong for "+name);
|
||||
spdlog::critical("The read pdf {0:d} from position {1:d} doesn't agree with the wanted bin {2:d}", pdf_idx, entry_position, bin);
|
||||
assert(0);
|
||||
}
|
||||
while (pdf_idx != PDF){
|
||||
entry_position += totBins;
|
||||
if (entry_position >= tree->GetEntries()){
|
||||
spdlog::critical("Required PDF {0:d} for " + name + " not found!",PDF);
|
||||
assert(0);
|
||||
}
|
||||
tree->GetEntry(entry_position);
|
||||
}
|
||||
|
||||
//Check if migrad makes sense
|
||||
if (migrad != 0){
|
||||
spdlog::warn("Careful! You are reading a fit that had failed migrad for " + name + "!");
|
||||
printMigradStatus(migrad);
|
||||
}
|
||||
|
||||
//if opts->hesse is non-active, use error for both error_up and error_down
|
||||
if(error_down == DEFAULT_TREE_ERR) error_down = error;
|
||||
if(error_up == DEFAULT_TREE_ERR) error_up = error;
|
||||
|
||||
//Init parameter
|
||||
double stepsize = GetParamStepsize(name); //TODO check
|
||||
if (FC.fix) stepsize = 0.0;
|
||||
else if (stepsize < 0.001) stepsize = 0.01; //Protect zeroes //TODO: possibly add some protection against very very small numbers, but if it works as it is, no need to make it fancier
|
||||
this->get_parameter(param_index)->set_previous_measurement(prev_value);
|
||||
if (FC.constrain){
|
||||
if (error_down==0) error_down = 0.01;
|
||||
if (error_up==0) error_up = 0.01;
|
||||
}
|
||||
std::vector<double> param_range = GetParamRange(name);
|
||||
this->get_parameter(param_index)->init(value, param_range.front(), param_range.back(), stepsize,error_down,error_up,FC.constrain);
|
||||
}
|
||||
|
||||
file->Close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bu2kstarmumu_parameters::fix_param_from_rootfile(std::string fileName,std::vector<std::string> names, int PDF, int bin){
|
||||
return get_param_from_rootfile(fileName, names, PDF, bin, fixConstr(true,false));
|
||||
}
|
||||
|
||||
int bu2kstarmumu_parameters::constrain_param_from_rootfile(std::string fileName,std::vector<std::string> names, int PDF, int bin){
|
||||
return get_param_from_rootfile(fileName, names, PDF, bin, fixConstr(false,true));
|
||||
}
|
||||
|
||||
int bu2kstarmumu_parameters::load_param_from_rootfile(std::string fileName,std::vector<std::string> names, int PDF, int bin){
|
||||
return get_param_from_rootfile(fileName, names, PDF, bin, fixConstr(false, false));
|
||||
}
|
||||
|
||||
//TODO: the following ones are not needed, as the string vector can be used instead....
|
||||
void bu2kstarmumu_parameters::load_only_bckgnd_param_values(std::string filename){
|
||||
this->load_param(filename, "cbkgmkpi0");
|
||||
this->load_param(filename, "cbkgmkpi1");
|
||||
this->load_param(filename, "cbkgmkpi2");
|
||||
this->load_param(filename, "cbkgmkpi3");
|
||||
this->load_param(filename, "cbkgmkpi4");
|
||||
this->load_param(filename, "cbkgctl0");
|
||||
this->load_param(filename, "cbkgctl1");
|
||||
this->load_param(filename, "cbkgctl2");
|
||||
this->load_param(filename, "cbkgctl3");
|
||||
this->load_param(filename, "cbkgctl4");
|
||||
this->load_param(filename, "cbkgctk0");
|
||||
this->load_param(filename, "cbkgctk1");
|
||||
this->load_param(filename, "cbkgctk2");
|
||||
this->load_param(filename, "cbkgctk3");
|
||||
this->load_param(filename, "cbkgctk4");
|
||||
this->load_param(filename, "cbkgctk5");
|
||||
this->load_param(filename, "cbkgctk6");
|
||||
this->load_param(filename, "cbkgphi0");
|
||||
this->load_param(filename, "cbkgphi1");
|
||||
this->load_param(filename, "cbkgphi2");
|
||||
this->load_param(filename, "cbkgphi3");
|
||||
this->load_param(filename, "cbkgphi4");
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::load_only_Bmass_param_values(std::string filename){
|
||||
this->load_param(filename, "sigma_1");
|
||||
this->load_param(filename, "alpha_1");
|
||||
this->load_param(filename, "n_1");
|
||||
this->load_param(filename, "sigma_2");
|
||||
this->load_param(filename, "alpha_2");
|
||||
this->load_param(filename, "n_2");
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::save_param_values(std::string filename){
|
||||
|
||||
std::ostringstream sout;
|
||||
spdlog::info("Parameter values are being saved to file "+ filename);;
|
||||
|
||||
//write all parameters to oss
|
||||
for(UInt_t p = 0; p < this->nparameters(); p++){
|
||||
sout << std::endl;
|
||||
sout << p;
|
||||
sout << "\t" << this->get_parameter(p)->get_name();
|
||||
if (this->get_parameter(p)->get_error()==0) continue; //Print only not-fixed parameters
|
||||
sout << "\t" << this->get_parameter(p)->get_value();
|
||||
sout << "\t" << this->get_parameter(p)->get_error();
|
||||
if (TMath::Abs(this->get_parameter(p)->get_error()/this->get_parameter(p)->get_value()) > 0.5){
|
||||
sout << "\tLARGE ERROR"; //c++s abs returned an int for whatever reason
|
||||
spdlog::warn("Par " + this->get_parameter(p)->get_name() + " has a large error:\t {0:f} +- {1:f}", this->get_parameter(p)->get_value() ,this->get_parameter(p)->get_error() );
|
||||
}
|
||||
else{
|
||||
spdlog::info("\tPar " + this->get_parameter(p)->get_name() + ":\t {0:f} +- {1:f}", this->get_parameter(p)->get_value() ,this->get_parameter(p)->get_error() );
|
||||
}
|
||||
}
|
||||
//save oss to file
|
||||
std::ofstream file(filename.c_str());
|
||||
file << sout.str();
|
||||
file.close();
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::add_parameters(){
|
||||
//physics parameters
|
||||
add_parameter(&Fl);
|
||||
add_parameter(&S1s);
|
||||
add_parameter(&S3);
|
||||
add_parameter(&S4);
|
||||
add_parameter(&S5);
|
||||
add_parameter(&Afb);
|
||||
add_parameter(&S6s);
|
||||
add_parameter(&S7);
|
||||
add_parameter(&S8);
|
||||
add_parameter(&S9);
|
||||
add_parameter(&P1);
|
||||
add_parameter(&P2);
|
||||
add_parameter(&P3);
|
||||
add_parameter(&P4);
|
||||
add_parameter(&P5);
|
||||
add_parameter(&P6);
|
||||
add_parameter(&P8);
|
||||
add_parameter(&FS);
|
||||
add_parameter(&SS1);
|
||||
add_parameter(&SS2);
|
||||
add_parameter(&SS3);
|
||||
add_parameter(&SS4);
|
||||
add_parameter(&SS5);
|
||||
|
||||
//had this at the start
|
||||
//signal fraction
|
||||
add_parameter(&f_sig);
|
||||
add_parameter(&n_sig);
|
||||
add_parameter(&n_bkg);
|
||||
//mass parameters
|
||||
add_parameter(&m_b);
|
||||
add_parameter(&m_res_1);
|
||||
add_parameter(&m_sigma_1);
|
||||
add_parameter(&m_sigma_2);
|
||||
add_parameter(&m_scale);
|
||||
add_parameter(&alpha_1);
|
||||
add_parameter(&alpha_2);
|
||||
add_parameter(&n_1);
|
||||
add_parameter(&n_2);
|
||||
|
||||
add_parameter(&fm_tau);
|
||||
add_parameter(&m_tau);
|
||||
add_parameter(&m_tau_2);
|
||||
add_parameter(&m_lambda);
|
||||
add_parameter(&m_lambda_2);
|
||||
add_parameter(&eff_q2);
|
||||
|
||||
add_parameter(&asphase);
|
||||
add_parameter(&a);
|
||||
add_parameter(&r);
|
||||
add_parameter(&gammakstar);
|
||||
add_parameter(&mkstar);
|
||||
add_parameter(&gammakstarplus);
|
||||
add_parameter(&mkstarplus);
|
||||
|
||||
add_parameter(&mf800);
|
||||
add_parameter(&gammaf800);
|
||||
add_parameter(&f800mag);
|
||||
add_parameter(&f800phase);
|
||||
|
||||
add_parameter(&cbkgctl0);
|
||||
add_parameter(&cbkgctl1);
|
||||
add_parameter(&cbkgctl2);
|
||||
add_parameter(&cbkgctl3);
|
||||
add_parameter(&cbkgctl4);
|
||||
|
||||
add_parameter(&cbkgctk0);
|
||||
add_parameter(&cbkgctk1);
|
||||
add_parameter(&cbkgctk2);
|
||||
add_parameter(&cbkgctk3);
|
||||
add_parameter(&cbkgctk4);
|
||||
add_parameter(&cbkgctk5);
|
||||
add_parameter(&cbkgctk6);
|
||||
|
||||
add_parameter(&cbkgphi0);
|
||||
add_parameter(&cbkgphi1);
|
||||
add_parameter(&cbkgphi2);
|
||||
add_parameter(&cbkgphi3);
|
||||
add_parameter(&cbkgphi4);
|
||||
|
||||
add_parameter(&cbkgmkpi0);
|
||||
add_parameter(&cbkgmkpi1);
|
||||
add_parameter(&cbkgmkpi2);
|
||||
add_parameter(&cbkgmkpi3);
|
||||
add_parameter(&cbkgmkpi4);
|
||||
|
||||
add_parameter(&cswavemkpi0);
|
||||
add_parameter(&cswavemkpi1);
|
||||
add_parameter(&cswavemkpi2);
|
||||
add_parameter(&cswavemkpi3);
|
||||
add_parameter(&cswavemkpi4);
|
||||
|
||||
add_parameter(&cbkgp20);
|
||||
add_parameter(&cbkgp21);
|
||||
add_parameter(&cbkgp22);
|
||||
add_parameter(&cbkgp23);
|
||||
add_parameter(&cbkgp24);
|
||||
|
||||
add_parameter(&nthreshold);
|
||||
add_parameter(&R);
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::init_mass_parameters(int PDF, int nBins, int bin, double defaultStepSize){
|
||||
|
||||
//Initialize the mass fit parameters based on the bin, as pi0 screws everyhting up
|
||||
std::vector<std::vector<double>> sMassPar = init_mass_params_MC(nBins,PDF);
|
||||
//Not the most efficient to always get the full vector with all bins, but oh well
|
||||
if(opts->twotailedcrystalball){
|
||||
m_res_1.init(1.0, 0.0, 1.0, 0.0);
|
||||
m_sigma_1.init(sMassPar[0][bin],15.0, 50.0, defaultStepSize);
|
||||
}
|
||||
else{
|
||||
m_res_1.init(0.5, 0.0, 1.0, defaultStepSize);
|
||||
m_sigma_1.init(sMassPar[0][bin],15.0, 40.0, defaultStepSize);
|
||||
m_sigma_2.init(sMassPar[1][bin],15.0, 40.0, defaultStepSize);
|
||||
}
|
||||
|
||||
alpha_1.init(sMassPar[2][bin], 0.5, 3.0, defaultStepSize);
|
||||
alpha_2.init(sMassPar[3][bin], 0.5, 3.0, defaultStepSize);
|
||||
n_1.init(sMassPar[4][bin], 2.0, 10.0, defaultStepSize);
|
||||
n_2.init(sMassPar[5][bin], 2.0, 10.0, defaultStepSize);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::init_Bmass(std::string fileName, int PDF, double stepSize, fixConstr FC){
|
||||
double massInit = get_param_value_from_rootfile(fileName,"m_b", PDF, 0);
|
||||
//fixing the Bmass outweights constraining it:
|
||||
if (FC.fix) m_b.init(massInit,B_MASS_LOW,B_MASS_HIGH, 0.0);
|
||||
else if (FC.constrain) m_b.init(massInit,B_MASS_LOW,B_MASS_HIGH, stepSize, 1.0, true);
|
||||
else m_b.init(massInit,B_MASS_LOW,B_MASS_HIGH, stepSize);
|
||||
return;
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::init_angular_background_parameters(bool fitReference, double stepsize){
|
||||
//Order of the polynomial is 0-6, each parameter represents x^n
|
||||
//TODO: CHECK THE FOLDINGS
|
||||
|
||||
//fitReference is not used, but in case this needs to be different for signal/reference!
|
||||
//First set everything to be flat so one can only change the parameters that actually vary
|
||||
use_default_bkg();
|
||||
|
||||
std::vector<double> init_values = init_bkg(opts->folding, opts->bkg_order_costhetal,opts->bkg_order_costhetak);
|
||||
for_indexed(auto name: PAR_BKG_STRING(opts->folding, opts->bkg_order_costhetal,opts->bkg_order_costhetak)){
|
||||
std::vector<double> range = GetParamRange(name);
|
||||
this->get_parameter(name)->init(init_values[i],range.front(), range.back(),stepsize);
|
||||
spdlog::trace("Initialized " + this->get_parameter(name)->get_name());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::init_mass_background_parameters(int nBins, int bin, bool useLambda){
|
||||
std::vector<double> f_lambda = init_f_lambda(nBins);
|
||||
if(useLambda){
|
||||
m_lambda.init(f_lambda.at(bin), PAR_LAMBDA*PAR_LAMBDA_SCALE, PAR_LAMBDA/PAR_LAMBDA_SCALE, 1.0e-5);
|
||||
//Turn on/off second exponential possibly
|
||||
m_lambda_2.init(f_lambda.at(bin), PAR_LAMBDA*PAR_LAMBDA_SCALE, PAR_LAMBDA/PAR_LAMBDA_SCALE, FIX_FM ? 0.0 : 1.0e-5);
|
||||
m_tau.init_fixed(0.0);
|
||||
m_tau_2.init_fixed(0.0);
|
||||
}
|
||||
else{
|
||||
//Not really used, so if someone ever needs this, modify yourselves!!!
|
||||
m_tau.init(-1.0/f_lambda.at(bin), 100, 100000, FIX_FM ? 0.0 : 10.0);
|
||||
//Turn on/off second exponential possibly
|
||||
m_tau_2.init(-1.0/f_lambda.at(bin), 100, 100000, FIX_FM ? 0.0 : 10.0);
|
||||
m_lambda.init_fixed(0.0);
|
||||
m_lambda_2.init_fixed(0.0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::init_mkpi_pWave_parameters(bool fitReference, double stepsize){
|
||||
//fitReference is not used, but in case this needs to be different for signal/reference!
|
||||
gammakstar.init(0.065, 0.055, 0.07, stepsize);
|
||||
mkstar.init(PDGMASS_K_STAR_PLUS / 1000., 0.882, 0.902, 0.0); //PDG value
|
||||
R.init(1.6, 0.0, 10.0, 0.00);
|
||||
return;
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::init_mkpi_sWave_parameters(bool fitReference, double stepsize){
|
||||
//fitReference is not used, but in case this needs to be different for signal/reference!
|
||||
gammakstarplus.init(0.236, 0.1, 0.5, stepsize); //PDG value is 0.236
|
||||
mkstarplus.init(1.41,1.2,1.6, 0.00); //PDG value is 1.41
|
||||
asphase.init(TMath::Pi(), 0.0, 2.0*TMath::Pi(), 0.0);
|
||||
a.init(1.95, 0.0, 20.0, 0.0);
|
||||
r.init(1.78, 0.0, 10.0, 0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::init_kpi_background_parameters(bool fitReference, double stepsize){
|
||||
//fitReference is not used, but in case this needs to be different for signal/reference!
|
||||
cbkgmkpi1.init(-0.99, -1.25, 0.25, stepsize);
|
||||
//cbkgmkpi2.init(0.3, -1.0, 1.0, stepsize);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::init_angular_parameters(int nBins, int bin, double stepsize, double scale, bool blind){
|
||||
//Scale sets the range
|
||||
|
||||
//First, make sure everything is at the starting point
|
||||
use_default_observables();
|
||||
|
||||
//Initialize angular parameters from constants
|
||||
//s1s //s3 //s4 //s5 //s6s //s7 //s8 //s9
|
||||
std::vector<std::vector<double>> sParameters;
|
||||
|
||||
if (opts->initSM){
|
||||
spdlog::debug("Loading angular parameters from flavio SM preditions");
|
||||
sParameters = init_angular_params(nBins,false,false);
|
||||
}
|
||||
else{
|
||||
spdlog::debug("Loading angular parameters from MC result file");
|
||||
sParameters = init_angular_params_MC(nBins);
|
||||
}
|
||||
|
||||
double blind_scale = 1.0; //Don't know what it does, but it is set to 1.0 everywhere
|
||||
|
||||
if (!opts->fit_pprimes){
|
||||
|
||||
if(opts->fit_fl) Fl.init(1.0-4.0/3.0*sParameters.at(0).at(bin), 0.0, 2.0*scale, stepsize);
|
||||
else S1s.init(sParameters.at(0).at(bin), -scale, scale, stepsize);
|
||||
|
||||
S3.init(sParameters.at(1).at(bin), -scale, scale, stepsize);
|
||||
S4.init(sParameters.at(2).at(bin), -scale, scale, (opts->full_angular || opts->folding == 1 ? stepsize : 0.0));
|
||||
S5.init(sParameters.at(3).at(bin), -scale, scale, (opts->full_angular || opts->folding == 2 ? stepsize : 0.0));
|
||||
|
||||
if(opts->fit_afb) Afb.init(3.0/4.0*sParameters.at(4).at(bin), -0.75*scale, 0.75*scale, (opts->full_angular || opts->folding == 0 ? stepsize : 0.0));
|
||||
else S6s.init(sParameters.at(4).at(bin), -scale, scale, (opts->full_angular || opts->folding == 0 ? stepsize : 0.0));
|
||||
|
||||
S7.init(sParameters.at(5).at(bin), -scale, scale, (opts->full_angular || opts->folding == 3 ? stepsize : 0.0));
|
||||
S8.init(sParameters.at(6).at(bin), -scale, scale, (opts->full_angular || opts->folding == 4 ? stepsize : 0.0));
|
||||
S9.init(sParameters.at(7).at(bin), -scale, scale, (opts->full_angular || opts->folding == 0 ? stepsize : 0.0));
|
||||
if(blind){
|
||||
Fl.set_blinding(true, blind_scale, true);
|
||||
P1.set_blinding(true, blind_scale, true);
|
||||
P2.set_blinding(true, blind_scale, true);
|
||||
P3.set_blinding(true, blind_scale, true);
|
||||
P4.set_blinding(true, blind_scale, true);
|
||||
P5.set_blinding(true, blind_scale, true);
|
||||
P6.set_blinding(true, blind_scale, true);
|
||||
P8.set_blinding(true, blind_scale, true);
|
||||
}
|
||||
}
|
||||
else{
|
||||
double fl = 1.0-4.0/3.0*sParameters.at(0).at(bin);
|
||||
Fl.init(fl, 0.0, 2.0*scale, stepsize);
|
||||
P1.init(2*sParameters.at(0).at(bin)/(1.-fl) , -scale, scale, stepsize);
|
||||
P2.init(sParameters.at(4).at(bin)/2/(1.-fl) , -scale, scale, (opts->full_angular || opts->folding == 0 ? stepsize : 0.0));
|
||||
P3.init(-sParameters.at(1).at(bin)/(1.-fl) , -scale, scale, (opts->full_angular || opts->folding == 0 ? stepsize : 0.0));
|
||||
P4.init(sParameters.at(2).at(bin)/sqrt(fl*(1.-fl)), -scale, scale, (opts->full_angular || opts->folding == 1 ? stepsize : 0.0));
|
||||
P5.init(sParameters.at(3).at(bin)/sqrt(fl*(1.-fl)), -scale, scale, (opts->full_angular || opts->folding == 2 ? stepsize : 0.0));
|
||||
P6.init(sParameters.at(5).at(bin)/sqrt(fl*(1.-fl)), -scale, scale, (opts->full_angular || opts->folding == 3 ? stepsize : 0.0));
|
||||
P8.init(sParameters.at(6).at(bin)/sqrt(fl*(1.-fl)), -scale, scale, (opts->full_angular || opts->folding == 4 ? stepsize : 0.0));
|
||||
|
||||
if(blind){
|
||||
if(opts->fit_fl) Fl.set_blinding(true, blind_scale, true);
|
||||
else S1s.set_blinding(true, blind_scale, true);
|
||||
S3.set_blinding(true, blind_scale, true);
|
||||
S4.set_blinding(true, blind_scale, true);
|
||||
S5.set_blinding(true, blind_scale, true);
|
||||
if(opts->fit_afb) Afb.set_blinding(true, blind_scale, true);
|
||||
else S6s.set_blinding(true, blind_scale, true);
|
||||
S7.set_blinding(true, blind_scale, true);
|
||||
S8.set_blinding(true, blind_scale, true);
|
||||
S9.set_blinding(true, blind_scale, true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::init_ang_parameters_fromRefDavid(double stepsize, double scale, bool blind){
|
||||
|
||||
std::vector<double> angPars = init_angular_params_RefFromDavid();
|
||||
//Not the most efficient to always get the full vector, but oh well
|
||||
|
||||
if (opts->fit_pprimes){
|
||||
spdlog::critical("init_ang_parameters_fromRefDavid not implemented yet for Pprimes!");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if(opts->fit_fl) Fl.init(1.0-4.0/3.0*angPars.at(0), 0.0, 2.0*scale, stepsize);
|
||||
else S1s.init(angPars.at(0), -scale, scale, stepsize);
|
||||
|
||||
S3.init(angPars.at(1), -scale, scale, stepsize);
|
||||
S4.init(angPars.at(2), -scale, scale, (opts->full_angular || opts->folding == 1 ? stepsize : 0.0));
|
||||
S5.init(angPars.at(3), -scale, scale, (opts->full_angular || opts->folding == 2 ? stepsize : 0.0));
|
||||
|
||||
if(opts->fit_afb) Afb.init(3.0/4.0*angPars.at(4), -0.75*scale, 0.75*scale, (opts->full_angular || opts->folding == 0 ? stepsize : 0.0));
|
||||
else S6s.init(angPars.at(4), -scale, scale, (opts->full_angular || opts->folding == 0 ? stepsize : 0.0));
|
||||
|
||||
S7.init(angPars.at(5), -scale, scale, (opts->full_angular || opts->folding == 3 ? stepsize : 0.0));
|
||||
S8.init(angPars.at(6), -scale, scale, (opts->full_angular || opts->folding == 4 ? stepsize : 0.0));
|
||||
S9.init(angPars.at(7), -scale, scale, (opts->full_angular || opts->folding == 0 ? stepsize : 0.0));
|
||||
|
||||
int blind_scale = 1.0; //No clue what this is good for, but it is 1.0 everywhere, so
|
||||
if(blind){
|
||||
if(opts->fit_fl) Fl.set_blinding(true, blind_scale, true);
|
||||
else S1s.set_blinding(true, blind_scale, true);
|
||||
S3.set_blinding(true, blind_scale, true);
|
||||
S4.set_blinding(true, blind_scale, true);
|
||||
S5.set_blinding(true, blind_scale, true);
|
||||
if(opts->fit_afb) Afb.set_blinding(true, blind_scale, true);
|
||||
else S6s.set_blinding(true, blind_scale, true);
|
||||
S7.set_blinding(true, blind_scale, true);
|
||||
S8.set_blinding(true, blind_scale, true);
|
||||
S9.set_blinding(true, blind_scale, true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void bu2kstarmumu_parameters::init_sWave_parameters(double stepsize){
|
||||
//TODO: very basic for now
|
||||
double scale = 1.0;
|
||||
SS1.init( -0.153, -scale, scale, opts->full_angular || opts->folding != 4 ? stepsize : 0.0);
|
||||
SS2.init( 0.032, -scale, scale, opts->full_angular || opts->folding == 1 ? stepsize : 0.0);
|
||||
SS3.init( -0.001, -scale, scale, opts->full_angular || opts->folding == 2 ? stepsize : 0.0);
|
||||
SS4.init( 0.001, -scale, scale, opts->full_angular || opts->folding > 2 ? stepsize : 0.0);
|
||||
SS5.init( -0.070, -scale, scale, opts->full_angular ? stepsize : 0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
bu2kstarmumu_parameters::bu2kstarmumu_parameters(options* o):
|
||||
opts(o)
|
||||
{
|
||||
use_default();
|
||||
add_parameters();
|
||||
}
|
||||
|
||||
|
||||
double eventsInBin_fraction(int bin, int run, int nBins, bool fromRef){
|
||||
//From the requested total number of events, get the number of events in the given bin for given pdf
|
||||
//Get the number of events from the dataFile and from the fraction of nSig/(nSig+nBkg)
|
||||
|
||||
assert(bin >= 0 && bin < nBins);
|
||||
assert(run == 1 || run == 2 || run == 12);
|
||||
|
||||
TChain * chain = new TChain("Events");
|
||||
spdlog::trace("Run 1 data file ='" + get_theFCNCpath(0,1) + "'");
|
||||
chain->Add(get_theFCNCpath(0,1).c_str());
|
||||
spdlog::trace("Run 2 data file ='" + get_theFCNCpath(0,2) + "'");
|
||||
chain->Add(get_theFCNCpath(0,2).c_str());
|
||||
spdlog::debug("Chain entries: {0:d}", chain->GetEntries());
|
||||
|
||||
//cut on the q2
|
||||
std::vector<double> q2BinsMin = get_TheQ2binsmin(nBins, fromRef); //No need to have specifically 1 for Ref
|
||||
std::vector<double> q2BinsMax = get_TheQ2binsmax(nBins, fromRef); //as if reference, always returns one bin
|
||||
std::string whichYear = "";
|
||||
switch(run){
|
||||
case 1: whichYear = "(year<2013) &&"; break;
|
||||
case 2: whichYear = "(year>2013) &&"; break;
|
||||
case 12: whichYear = "(year<2020) &&"; break;
|
||||
}
|
||||
std::string cutOnQ2 = " ";
|
||||
for (unsigned int b = 0; b < q2BinsMin.size(); b++){
|
||||
cutOnQ2.append( "(" + std::to_string(q2BinsMin[b]) + " < q2 && q2 < "+ std::to_string(q2BinsMax[b]) +") || ");
|
||||
}
|
||||
cutOnQ2.erase(cutOnQ2.length()-3);
|
||||
spdlog::debug("Using cut: '" + cutOnQ2 + "'");
|
||||
int n_all = chain->GetEntries(cutOnQ2.c_str()); //number of events in the rare q2 region
|
||||
if(n_all == -1) spdlog::debug("Getting number of all entries from TChain failed. Using hardcoded numbers.");
|
||||
spdlog::debug("All entries: {0:d}", n_all);
|
||||
|
||||
cutOnQ2 = whichYear + std::to_string(q2BinsMin[bin]) + " < q2 && q2 < "+ std::to_string(q2BinsMax[bin]);
|
||||
spdlog::debug("Using cut: '" + cutOnQ2 + "'");
|
||||
int n_bin = chain->GetEntries(cutOnQ2.c_str()); //number of events in the desired q2 bin
|
||||
if(n_bin == -1)spdlog::debug("Getting number of entries for bin {0:d} from TChain failed. Using hardcoded numbers.", bin);
|
||||
spdlog::debug("Entries in bin: {0:d}", n_bin);
|
||||
|
||||
//Running on Condor does not allow usage of TTreePlayer, which is needed for the GetEntries with selection cut
|
||||
//In that case, -1 is returned. If so, use hardcoded fractions for the 4 or 5 q2 binning scheme.
|
||||
if(n_all == -1 || n_bin == -1){
|
||||
spdlog::warn("Could not determine event fraction in bin={0:d} for run={1:d} from TChain. Use hardcoded numbers.", bin, run);
|
||||
if(nBins == 4 || nBins == 5){
|
||||
std::vector<std::vector<double> > frac = fracs(nBins);
|
||||
if(run == 12)return frac.at(0).at(bin)+frac.at(1).at(bin);
|
||||
else return frac.at(run-1).at(bin);
|
||||
}
|
||||
spdlog::error("No hardcoded numbers available for {0:d} q2 bins.", nBins);
|
||||
return 0.0;
|
||||
}
|
||||
double fraction = double(n_bin)/double(n_all);
|
||||
spdlog::debug("Returning fraction of {0:f}", fraction);
|
||||
chain->Clear();
|
||||
return fraction;
|
||||
}
|
||||
|
||||
void EventNumbers(unsigned int bin, unsigned int pdf, double & fraction, unsigned int & eventnumbers,
|
||||
unsigned int TotalEvents, unsigned int bins, unsigned int pdfs){
|
||||
|
||||
bool use_unblinded_values = false;//TODO
|
||||
|
||||
//return the fraction of nSig/(nSig+nBkg) *** in the requested q2bin ***
|
||||
//return the number of events (nSig+nBkg) *** in this q2bin *** and in this sub-set given a total number of events (all sub-sets and all q2bins)
|
||||
fraction = 0;
|
||||
eventnumbers = 0;
|
||||
|
||||
std::vector<double> f_signal = init_n_signal(bins);
|
||||
std::vector<double> f_bckgnd = init_n_bckgnd(bins);
|
||||
std::vector<double> f_subset = get_f_subset(pdfs);
|
||||
|
||||
assert(f_signal.size() == bins);
|
||||
assert(f_bckgnd.size() == bins);
|
||||
assert(f_subset.size() == pdfs);
|
||||
|
||||
//assign signal fraction
|
||||
fraction = f_signal.at(bin) / (f_signal.at(bin) + f_bckgnd.at(bin));
|
||||
|
||||
//get total event number in this bin and for this sub-set:
|
||||
double f_sig_norm = sum_vector(f_signal) + sum_vector(f_bckgnd);
|
||||
double f_event_norm = sum_vector(f_subset);
|
||||
|
||||
for(auto sig: f_signal) sig /= f_sig_norm;
|
||||
for(auto bkg: f_bckgnd) bkg /= f_sig_norm;
|
||||
for(auto f_sub: f_subset) f_sub /= f_event_norm;
|
||||
|
||||
eventnumbers = (unsigned int) (0.5 + TotalEvents * (f_signal.at(bin) + f_bckgnd.at(bin)) * f_subset.at(pdf));
|
||||
|
||||
if(use_unblinded_values){ //Number of signal and background events for each PDF //TODO: de-hardcode this one
|
||||
fraction = sig_unblinded.at(bin).at(pdf) / (sig_unblinded.at(bin).at(pdf) + bkg_unblinded.at(bin).at(pdf));
|
||||
eventnumbers = (unsigned int) (0.5 + sig_unblinded.at(bin).at(pdf) + bkg_unblinded.at(bin).at(pdf));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
282
Code/FCNCFitter/sources/Core/bu2kstarmumu_parameters.hh
Executable file
282
Code/FCNCFitter/sources/Core/bu2kstarmumu_parameters.hh
Executable file
@ -0,0 +1,282 @@
|
||||
/**
|
||||
* @file bu2kstarmumu_parameters.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BU2KSTARMUMU_PARAMETERS_H
|
||||
#define BU2KSTARMUMU_PARAMETERS_H
|
||||
|
||||
#include <parameters.hh>
|
||||
#include <options.hh>
|
||||
#include <assert.h>
|
||||
|
||||
//Simple struct to see whether fix or constrain a parameter
|
||||
struct fixConstr{
|
||||
bool fix = false;
|
||||
bool constrain = false;
|
||||
//Constructor
|
||||
fixConstr(bool b_fix, bool b_constr);
|
||||
};
|
||||
|
||||
namespace fcnc {
|
||||
|
||||
///class that implements the different parameter sets for Bd -> Kstar mu mu
|
||||
class bu2kstarmumu_parameters: public parameters {
|
||||
private:
|
||||
///adds all parameters to the params vector
|
||||
void add_parameters();
|
||||
options* opts;
|
||||
|
||||
public:
|
||||
///constructor uses toy challenge version 1 data as default
|
||||
bu2kstarmumu_parameters(options* o);
|
||||
|
||||
///use default B+ values
|
||||
/// //THIS IS SOMETHING EVERY ANALYSIS HAS TO CHANGE ON THEIR OWN!
|
||||
void use_default_bkg(); //Just reset bkg, useful in the code down the line
|
||||
void use_default_observables(); //Reset S-wave observables, useful in the code down the line
|
||||
void use_default();
|
||||
|
||||
//simple and quick loading and saving of parameters to/from txt file
|
||||
void load_param_values(std::string filename);
|
||||
void load_param(std::string filename, std::string parname);
|
||||
|
||||
int get_param_from_rootfile(std::string fileName, std::vector<std::string> names, int PDF, int bin, fixConstr FC);
|
||||
|
||||
//Fix parameter to a value from a root file
|
||||
int fix_param_from_rootfile(std::string fileName, std::vector<std::string> names, int PDF, int bin);
|
||||
//Constrain parameter to a value from a root file
|
||||
int constrain_param_from_rootfile(std::string fileName, std::vector<std::string>names, int PDF, int bin);
|
||||
//Initialize parameter from a root file and let if float as it wishes
|
||||
int load_param_from_rootfile(std::string fileName,std::vector<std::string> names, int PDF, int bin);
|
||||
|
||||
//TODO: remove as it is obsolete when done with pulls.cc
|
||||
void load_only_bckgnd_param_values(std::string filename);
|
||||
void load_only_Bmass_param_values(std::string filename);
|
||||
|
||||
//Initialize parameters in the fit
|
||||
void init_mass_parameters(int PDF, int nBins, int bin, double defaultStepSize);
|
||||
void init_angular_background_parameters(bool fitReference, double stepsize);
|
||||
void init_kpi_background_parameters(bool fitReference, double stepsize);
|
||||
void init_mkpi_pWave_parameters(bool fitReference, double stepsize);
|
||||
void init_mkpi_sWave_parameters(bool fitReference, double stepsize);
|
||||
void init_mass_background_parameters(int nBins, int bin, bool useLambda);
|
||||
void init_angular_parameters(int nBins, int bin, double stepsize, double scale, bool blind);
|
||||
void init_Bmass(std::string fileName, int PDF, double stepSize, fixConstr FC);
|
||||
void init_ang_parameters_fromRefDavid(double stepsize, double scale, bool blind);
|
||||
void init_sWave_parameters(double stepsize);
|
||||
|
||||
void save_param_values(std::string filename);
|
||||
|
||||
//Effective q2
|
||||
parameter eff_q2 = parameter("eff_q2", "{q^{2}}_eff");
|
||||
|
||||
//Number of signal/background events
|
||||
parameter n_sig = parameter("n_sig", "N_\\mathrm{sig}");
|
||||
parameter n_bkg = parameter("n_bkg", "N_\\mathrm{bkg}");
|
||||
|
||||
//Fraction of signal events, effectivelly (nsig/(nsig+nbkg)))
|
||||
parameter f_sig = parameter("f_sig", "f_\\mathrm{sig}");
|
||||
|
||||
//The B massneeds the full range of the B-mass fit,
|
||||
//as it decides the range of the data used in the fit
|
||||
parameter m_b = parameter("m_b", "m_{B^{+}}");
|
||||
|
||||
//All mass parameters
|
||||
parameter m_res_1 = parameter("m_res_1", "f_{CB}");
|
||||
parameter m_scale = parameter("m_scale", "s_\\mathrm{m}");
|
||||
parameter m_sigma_1 = parameter("m_sigma_1", "#sigma_{1}^{CB}");
|
||||
parameter m_sigma_2 = parameter("m_sigma_2", "#sigma_{2}^{CB}");
|
||||
parameter alpha_1 = parameter("alpha_1", "#alpha_{1}^{CB}");
|
||||
parameter alpha_2 = parameter("alpha_2", "#alpha_{2}^{CB}");
|
||||
parameter n_1 = parameter("n_1", "n_{1}^{CB}");
|
||||
parameter n_2 = parameter("n_2", "n_{2}^{CB}");
|
||||
|
||||
//These are for exponential background, either exp(-lambda*x) or exp(x/tau) 
|
||||
parameter fm_tau = parameter("fm_tau", "f_{m,#tau}");
|
||||
parameter m_lambda = parameter("m_lambda", "\\lambda_\\mathrm{m}");
|
||||
parameter m_lambda_2 = parameter("m_lambda_2", "\\lambda_\\mathrm{m,2}");
|
||||
parameter m_tau = parameter("m_tau", "#tau_{m,1}");
|
||||
parameter m_tau_2 = parameter("m_tau_2", "#tau_{m,2}");
|
||||
|
||||
//Kstar related parameters /
|
||||
|
||||
parameter mkstar = parameter("mkst","m(K^{*+})");
|
||||
parameter mkstarplus = parameter("mkstz","m(K^{*+}_{x})"); //K1+ resonances
|
||||
parameter mkstp = parameter("mkstp", "m(K^+\\pi^0)"); //TODO
|
||||
|
||||
parameter gammakstar = parameter("gammakstar", "\\Gamma(K^{*+})"); //Width of K*
|
||||
parameter gammakstarplus = parameter("gamkstp", "\\Gamma(K^+\\pi^0)"); //Width of K1
|
||||
//parameter gamkstp = parameter("gamkstp", "\\Gamma(K^+\\pi^0)");
|
||||
|
||||
|
||||
//Afb and FL, S- and P- parameters are in S_pars(int) and P_pars(int)
|
||||
parameter fl = parameter("Fl", "F_{L}");
|
||||
parameter afb = parameter("Afb", "A_{FB}");
|
||||
|
||||
//double exponential bkg
|
||||
parameter Fl = parameter("Fl", "F_{L}");
|
||||
parameter S1s = parameter("S1s", "S_{1s}");
|
||||
parameter S3 = parameter("S3", "S_{3}");
|
||||
parameter S4 = parameter("S4", "S_{4}");
|
||||
parameter S5 = parameter("S5", "S_{5}");
|
||||
parameter Afb = parameter("Afb", "A_{FB}");
|
||||
parameter S6s = parameter("S6s", "S_{6s}");
|
||||
parameter S7 = parameter("S7", "S_{7}");
|
||||
parameter S8 = parameter("S8", "S_{8}");
|
||||
parameter S9 = parameter("S9", "S_{9}");
|
||||
|
||||
//less FF dependent variables P_i
|
||||
parameter P1 = parameter("P1", "P_{1}");//=2*S3/(1-Fl)
|
||||
parameter P2 = parameter("P2", "P_{2}");//=0.5*S6/(1-Fl)
|
||||
parameter P3 = parameter("P3", "P_{3}");//=-S9/(1-Fl)
|
||||
parameter P4 = parameter("P4", "P_{4}^{\\prime}");//=S4/sqrt(Fl Ft)
|
||||
parameter P5 = parameter("P5", "P_{5}^{\\prime}");//=S5/sqrt(Fl Ft)
|
||||
parameter P6 = parameter("P6", "P_{6}^{\\prime}");//=S7/sqrt(Fl Ft)
|
||||
parameter P8 = parameter("P8", "P_{8}^{\\prime}");//=S8/sqrt(Fl Ft)
|
||||
|
||||
//S-wave parameters
|
||||
parameter FS = parameter("FS" ,"F_{S}");
|
||||
parameter SS1 = parameter("SS1","S_{S1}");
|
||||
parameter SS2 = parameter("SS2","S_{S2}");
|
||||
parameter SS3 = parameter("SS3","S_{S3}");
|
||||
parameter SS4 = parameter("SS4","S_{S4}");
|
||||
parameter SS5 = parameter("SS5","S_{S5}");
|
||||
|
||||
//More Kstar related parameters
|
||||
parameter asphase = parameter("asphase", "arg(A_{S})");
|
||||
//Control the K* shape; one is ~p(K*) and one is ~1/p(K*),
|
||||
parameter a = parameter("a", "a");
|
||||
parameter r = parameter("r", "r");
|
||||
|
||||
//Related to kappa(800), or f(800), it changed name apparently
|
||||
//Essentially a wide resonance
|
||||
parameter mf800 = parameter("mf800","m(f_{800})");
|
||||
parameter gammaf800 = parameter("gamf800","\\Gamma(f_{800})");
|
||||
parameter f800mag = parameter("f800mag","|f_{800}|");
|
||||
parameter f800phase = parameter("f800phase","arg(f_{800})");
|
||||
|
||||
//R (also refered to as d in the literature)
|
||||
//is a parameter in the mkpi parameterisation.
|
||||
//It refers to the effective hadronic size
|
||||
//See L861f (page 66) of https://cds.cern.ch/record/2318554/files/LHCb-ANA-2018-022.pdf
|
||||
parameter R = parameter("R", "R");
|
||||
//As a standard this is the radius of a B messon
|
||||
|
||||
//Background parameters
|
||||
//Polynomial of maximal order of four
|
||||
//Each parameter correspons to x^n
|
||||
//Eg cbkgctl1 and cbkgctl3 are non-zero, rest is zero means polynomial
|
||||
// x^1 + x^3
|
||||
|
||||
//ctl
|
||||
parameter cbkgctl0 = parameter("cbkgctl0", "c_{bkg}^{0}(cos#Theta_{L})");
|
||||
parameter cbkgctl1 = parameter("cbkgctl1", "c_{bkg}^{1}(cos#Theta_{L})");
|
||||
parameter cbkgctl2 = parameter("cbkgctl2", "c_{bkg}^{2}(cos#Theta_{L})");
|
||||
parameter cbkgctl3 = parameter("cbkgctl3", "c_{bkg}^{3}(cos#Theta_{L})");
|
||||
parameter cbkgctl4 = parameter("cbkgctl4", "c_{bkg}^{4}(cos#Theta_{L})");
|
||||
//ctk
|
||||
parameter cbkgctk0 = parameter("cbkgctk0", "c_{bkg}^{0}(cos#Theta_{K})");
|
||||
parameter cbkgctk1 = parameter("cbkgctk1", "c_{bkg}^{1}(cos#Theta_{K})");
|
||||
parameter cbkgctk2 = parameter("cbkgctk2", "c_{bkg}^{2}(cos#Theta_{K})");
|
||||
parameter cbkgctk3 = parameter("cbkgctk3", "c_{bkg}^{3}(cos#Theta_{K})");
|
||||
parameter cbkgctk4 = parameter("cbkgctk4", "c_{bkg}^{4}(cos#Theta_{K})");
|
||||
parameter cbkgctk5 = parameter("cbkgctk5", "c_{bkg}^{5}(cos#Theta_{K})");
|
||||
parameter cbkgctk6 = parameter("cbkgctk6", "c_{bkg}^{6}(cos#Theta_{K})");
|
||||
//phi
|
||||
parameter cbkgphi0 = parameter("cbkgphi0", "c_{bkg}^{0}(#phi)");
|
||||
parameter cbkgphi1 = parameter("cbkgphi1", "c_{bkg}^{0}(#phi)");
|
||||
parameter cbkgphi2 = parameter("cbkgphi2", "c_{bkg}^{0}(#phi)");
|
||||
parameter cbkgphi3 = parameter("cbkgphi3", "c_{bkg}^{0}(#phi)");
|
||||
parameter cbkgphi4 = parameter("cbkgphi4", "c_{bkg}^{0}(#phi)");
|
||||
|
||||
//mkpi
|
||||
parameter cbkgmkpi0 = parameter("cbkgmkpi0", "c_{bkg}^{0}(m_{K#pi})");
|
||||
parameter cbkgmkpi1 = parameter("cbkgmkpi1", "c_{bkg}^{1}(m_{K#pi})");
|
||||
parameter cbkgmkpi2 = parameter("cbkgmkpi2", "c_{bkg}^{2}(m_{K#pi})");
|
||||
parameter cbkgmkpi3 = parameter("cbkgmkpi3", "c_{bkg}^{3}(m_{K#pi})");
|
||||
parameter cbkgmkpi4 = parameter("cbkgmkpi4", "c_{bkg}^{4}(m_{K#pi})");
|
||||
|
||||
//Fancy background to mkpi in the p^2 dimension
|
||||
parameter cswavemkpi0 = parameter("cswavemkpi0", "c_{S}^{0}(m_{K#pi})");
|
||||
parameter cswavemkpi1 = parameter("cswavemkpi1", "c_{S}^{1}(m_{K#pi})");
|
||||
parameter cswavemkpi2 = parameter("cswavemkpi2", "c_{S}^{2}(m_{K#pi})");
|
||||
parameter cswavemkpi3 = parameter("cswavemkpi3", "c_{S}^{3}(m_{K#pi})");
|
||||
parameter cswavemkpi4 = parameter("cswavemkpi4", "c_{S}^{4}(m_{K#pi})");
|
||||
|
||||
parameter cbkgp20 = parameter("cbkgp20", "c_{bkg}^{0}(p^{2})");
|
||||
parameter cbkgp21 = parameter("cbkgp21", "c_{bkg}^{1}(p^{2})");
|
||||
parameter cbkgp22 = parameter("cbkgp22", "c_{bkg}^{2}(p^{2})");
|
||||
parameter cbkgp23 = parameter("cbkgp23", "c_{bkg}^{3}(p^{2})");
|
||||
parameter cbkgp24 = parameter("cbkgp24", "c_{bkg}^{4}(p^{2})");
|
||||
|
||||
//Nobody used this ever, probably not even in the PDF
|
||||
parameter nthreshold = parameter("nthreshold", "n_{thr.}");
|
||||
|
||||
double J1s() const {
|
||||
return 3.0/4.0*(1.0-J1c()); // 3/4*(1-F_L)
|
||||
};
|
||||
double J1c() const {
|
||||
if (opts->fit_pprimes) assert(opts->fit_fl);
|
||||
if (opts->fit_fl) return Fl();
|
||||
else return 1.0-4.0/3.0*S1s();
|
||||
};
|
||||
double J2s() const {
|
||||
return J1s()/3.0; //1/4(1-F_L)
|
||||
};
|
||||
double J2c() const {
|
||||
return -J1c(); //-F_L
|
||||
};
|
||||
double J3() const {//P1;//=S3/(1-Fl) correction P1=2S3/(1-FL)
|
||||
if (opts->fit_pprimes) return 0.5*P1()*(1.0-J1c());
|
||||
else return S3();
|
||||
};
|
||||
double J4() const {//P4;//=S4/sqrt(Fl Ft)
|
||||
if (opts->fit_pprimes) return P4()*sqrt(J1c()*(1.0-J1c()));
|
||||
else return S4();
|
||||
};
|
||||
double J5() const {//P5;//=S5/sqrt(Fl Ft)
|
||||
if (opts->fit_pprimes) return P5()*sqrt(J1c()*(1.0-J1c()));
|
||||
else return S5();
|
||||
};
|
||||
double J6s() const {//P2;//=S6/(1-Fl) correction P2=0.5*S6s/(1-FL)
|
||||
if (opts->fit_pprimes) return 2.0*P2()*(1.0-J1c());
|
||||
else if (opts->fit_afb) return 4.0/3.0*Afb();
|
||||
else return S6s();
|
||||
};
|
||||
double J6c() const {
|
||||
return 0.0;
|
||||
};
|
||||
double J7() const {//P6;//=S7/sqrt(Fl Ft)
|
||||
if (opts->fit_pprimes) return P6()*sqrt(J1c()*(1.0-J1c()));
|
||||
else return S7();
|
||||
};
|
||||
double J8() const {//P8;//=S8/sqrt(Fl Ft)
|
||||
if (opts->fit_pprimes) return P8()*sqrt(J1c()*(1.0-J1c()));
|
||||
else return S8();
|
||||
};
|
||||
double J9() const {//P3;//=S9/(1-Fl) correction P3=-S9/(1-FL)
|
||||
if (opts->fit_pprimes) return -P3()*(1.0-J1c());
|
||||
else return S9();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Returns value or error of a parameter from a rootFile
|
||||
double get_param_value_from_rootfile(std::string fileName, std::string names, int PDF, int bin);
|
||||
double get_param_error_from_rootfile(std::string fileName, std::string names, int PDF, int bin);
|
||||
|
||||
//Returns a scaled number of events in given bin from total number of events in data
|
||||
double eventsInBin_fraction(int bin, int run, int nBins, bool fromRef);
|
||||
|
||||
//Returns a scaled number of events in given bin from total number of events
|
||||
//Eg I want to have 1000 events in 4 bins and 2 pdfs, it generates 155 signal + 100 bkg events in bin1, 125+120 in bin2, 180 + 50 in bin3 and 200+70 in bin4 as random example
|
||||
void EventNumbers(unsigned int bin, unsigned int pdf,
|
||||
double & fraction, unsigned int & eventnumbers,unsigned int TotalEvents,
|
||||
unsigned int bins, unsigned int pdfs);
|
||||
|
||||
#endif
|
5380
Code/FCNCFitter/sources/Core/bu2kstarmumu_pdf.cc
Normal file
5380
Code/FCNCFitter/sources/Core/bu2kstarmumu_pdf.cc
Normal file
File diff suppressed because it is too large
Load Diff
275
Code/FCNCFitter/sources/Core/bu2kstarmumu_pdf.hh
Normal file
275
Code/FCNCFitter/sources/Core/bu2kstarmumu_pdf.hh
Normal file
@ -0,0 +1,275 @@
|
||||
/**
|
||||
* @file bu2kstarmumu_pdf.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BU2KSTARMUMU_PDF_H
|
||||
#define BU2KSTARMUMU_PDF_H
|
||||
|
||||
#include <bu2kstarmumu_parameters.hh>
|
||||
#include <pdf.hh>
|
||||
#include <parameters.hh>
|
||||
#include <folder.hh>
|
||||
|
||||
//Create vectors with the values of the polynomials
|
||||
std::vector<double> init_ch_ctl(const fcnc::bu2kstarmumu_parameters* params);
|
||||
std::vector<double> init_ch_ctk(const fcnc::bu2kstarmumu_parameters* params);
|
||||
std::vector<double> init_ch_phi(const fcnc::bu2kstarmumu_parameters* params);
|
||||
|
||||
namespace fcnc {
|
||||
|
||||
struct q2bin {
|
||||
double min;
|
||||
double max;
|
||||
q2bin(double a, double b): min(a), max(b) {};
|
||||
};
|
||||
|
||||
class options;
|
||||
class event;
|
||||
class values;
|
||||
|
||||
static const double mumass = 105.6583668; //TODO: OMFG
|
||||
|
||||
class bu2kstarmumu_pdf;
|
||||
|
||||
///class that implements the pdf ot the signal decay Bs -> JPsi Phi
|
||||
class bu2kstarmumu_pdf: public pdf {
|
||||
///These encapsulation functions used by ROOT/Minuit need access to class internals.
|
||||
friend class bu2kstarmumu_plotter;
|
||||
friend class bu2kstarmumu_generator;
|
||||
private:
|
||||
folder* fldr;
|
||||
public:
|
||||
static bu2kstarmumu_pdf* current_pdf;
|
||||
//double shift_lh;
|
||||
bu2kstarmumu_pdf(options* o, const bu2kstarmumu_parameters* params);
|
||||
virtual ~bu2kstarmumu_pdf();
|
||||
void init(bu2kstarmumu_parameters* params)
|
||||
{
|
||||
};
|
||||
void init(parameters* params);
|
||||
void update_cached_normalization(const bu2kstarmumu_parameters* params);
|
||||
void update_cached_normalization(const parameters* params);
|
||||
void update_cached_integrated_fis(const bu2kstarmumu_parameters* params);
|
||||
void update_cached_integrated_fis(const parameters* params);
|
||||
//void update_cached_normalization(const bu2kstarmumu_parameters* params, std::vector<event>* events);
|
||||
//void update_cached_normalization(const parameters* params, std::vector<event>* events);
|
||||
void update_cached_efficiencies(const bu2kstarmumu_parameters* params, std::vector<event>* events);
|
||||
void update_cached_efficiencies(const parameters* params, std::vector<event>* events);
|
||||
void update_cached_xis(const bu2kstarmumu_parameters* params, std::vector<event>* events);
|
||||
void update_cached_xis(const parameters* params, std::vector<event>* events);
|
||||
public:
|
||||
///normalization
|
||||
double fnorm_sig;
|
||||
//double fnorm_sig_swave;
|
||||
double fnorm_bkg;
|
||||
double fbuffer_f1, fbuffer_f2, fbuffer_f3, fbuffer_f4, fbuffer_f5, fbuffer_f6, fbuffer_f7, fbuffer_f8, fbuffer_f9, fbuffer_f10, fbuffer_f11, fbuffer_f12;
|
||||
double fbuffer_fs1, fbuffer_fs2, fbuffer_fs3, fbuffer_fs4, fbuffer_fs5, fbuffer_fs6;
|
||||
virtual void get_swave_integrated_fj(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const {
|
||||
f1 = fbuffer_fs1;
|
||||
f2 = fbuffer_fs2;
|
||||
f3 = fbuffer_fs3;
|
||||
f4 = fbuffer_fs4;
|
||||
f5 = fbuffer_fs5;
|
||||
f6 = fbuffer_fs6;
|
||||
return;
|
||||
};
|
||||
virtual void get_integrated_fj(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const {
|
||||
f1 = fbuffer_f1;
|
||||
f2 = fbuffer_f2;
|
||||
f3 = fbuffer_f3;
|
||||
f4 = fbuffer_f4;
|
||||
f5 = fbuffer_f5;
|
||||
f6 = fbuffer_f6;
|
||||
f7 = fbuffer_f7;
|
||||
f8 = fbuffer_f8;
|
||||
f9 = fbuffer_f9;
|
||||
f10 = fbuffer_f10;
|
||||
f11 = fbuffer_f11;
|
||||
f12 = fbuffer_f12;
|
||||
return;
|
||||
};
|
||||
/*
|
||||
unsigned int neff_costhetal;
|
||||
unsigned int neff_costhetak;
|
||||
unsigned int neff_phi;
|
||||
|
||||
unsigned int nbkg_costhetal;
|
||||
unsigned int nbkg_costhetak;
|
||||
unsigned int nbkg_phi;
|
||||
*/
|
||||
///coefficients for 4D angular acceptance (Sliding acceptance which is controlled by a parameter eff_q2range in the parameter set)
|
||||
std::vector<double> coeffs_eff_4d;
|
||||
|
||||
///chebyshev coefficients for factorizing bkg modeling
|
||||
//std::vector<double> coeffs_bkg_costhetal;
|
||||
//std::vector<double> coeffs_bkg_costhetak;
|
||||
//std::vector<double> coeffs_bkg_phi;
|
||||
|
||||
//std::vector<event> bkg_events;
|
||||
std::vector<event> eff_events;
|
||||
const bu2kstarmumu_parameters* eff_params;
|
||||
|
||||
//static void bkg_fcn(Int_t &npar, Double_t *grad, Double_t &lh, Double_t *params, Int_t iflag);
|
||||
static void eff_fcn(Int_t &npar, Double_t *grad, Double_t &lh, Double_t *params, Int_t iflag);
|
||||
static void eff_fcn_phsp(Int_t &npar, Double_t *grad, Double_t &lh, Double_t *params, Int_t iflag);
|
||||
static void eff_fcn_phsp_4d(Int_t &npar, Double_t *grad, Double_t &lh, Double_t *params, Int_t iflag);
|
||||
|
||||
//////////////////
|
||||
///Full angular///
|
||||
//////////////////
|
||||
|
||||
//Angular correction polynomials are converted into Sum (c_ijkl * ctk^i * ctl^j * phi^k * q2^l)
|
||||
//S-wave
|
||||
void swave_fj(double ctl, double ctk, double phi,
|
||||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const;
|
||||
void swave_integrated_fj_noacc(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const;
|
||||
void swave_integrated_fj_noacc(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const;
|
||||
void swave_integrated_fj_chebyshev(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double q2) const;
|
||||
void swave_integrated_fj_chebyshev(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double q2) const;
|
||||
|
||||
//P-wave
|
||||
void fj(double ctl, double ctk, double phi,
|
||||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const;
|
||||
void integrated_fj_noacc(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const;
|
||||
void integrated_fj_noacc(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const;
|
||||
void integrated_fj_chebyshev(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12, double q2) const;
|
||||
void integrated_fj_chebyshev(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12, double q2) const;
|
||||
|
||||
/////////////////////
|
||||
///Angular folding///
|
||||
/////////////////////
|
||||
|
||||
//S-wave
|
||||
void folded_swave_fj(double ctl, double ctk, double phi, double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const;
|
||||
void folded_swave_integrated_fj_noacc(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const;
|
||||
void folded_swave_integrated_fj_noacc(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const;
|
||||
void folded_swave_integrated_fj_chebyshev(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double q2) const;
|
||||
void folded_swave_integrated_fj_chebyshev(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double q2) const;
|
||||
|
||||
//P-wave
|
||||
void folded_fj(double ctl, double ctk, double phi, double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const;
|
||||
void folded_integrated_fj_noacc(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const;
|
||||
void folded_integrated_fj_noacc(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const;
|
||||
void folded_integrated_fj_chebyshev(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double& f7, double& f8, double& f9, double& f10, double& f11, double& f12, double q2) const;
|
||||
void folded_integrated_fj_chebyshev(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b,
|
||||
double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double& f7, double& f8, double& f9, double& f10, double& f11, double& f12, double q2) const;
|
||||
|
||||
//background
|
||||
double integral_bkg(const bu2kstarmumu_parameters* params, double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b) const;
|
||||
double integral_bkg_chebyshev(const bu2kstarmumu_parameters* params, double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, double q2) const;
|
||||
|
||||
//moments
|
||||
void get_moments(std::vector<fcnc::event> events, std::vector<double>& moments, std::vector<double>& covariance) const;
|
||||
void save_moments_to_obs(bu2kstarmumu_parameters* params, std::vector<double> obs, std::vector<double> obscov) const;
|
||||
|
||||
//mkpi dependencies
|
||||
double mkpi_pwave_2(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
double mkpi_swave_2(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
double mkpi_re_swavepwave(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
double mkpi_im_swavepwave(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
double mkpi_bkg(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
double mkpi_swave_2_norm;
|
||||
double mkpi_pwave_2_norm;
|
||||
double mkpi_re_swavepwave_norm;
|
||||
double mkpi_im_swavepwave_norm;
|
||||
double mkpi_bkg_norm;
|
||||
|
||||
///determine parametrization for efficiencies in angles and q2, needs reconstructed phsp MC events, needs to change weights so non-const
|
||||
void parametrize_eff_phsp_4d(const std::vector<event>& events, values* globalvalues, int tagNumber, bool assumePhiEven, bool checkSignifcance, bool runMinuit, bool checkFactorization, bool do3Dmoments);
|
||||
|
||||
//Get the efficiency from the angular corrections
|
||||
double get_ang_eff(fcnc::options *opts, double q2, double ctl, double ctk, double phi) const;
|
||||
double get_ang_eff(fcnc::options *opts, fcnc::event evt, bool fa) const; //TBH, no clue why there has to be the const, but it compiles, so I'll take it
|
||||
|
||||
//save and load the 4d coefficients to a file
|
||||
void save_coeffs_eff_phsp_4d();
|
||||
void load_coeffs_eff_phsp_4d();
|
||||
std::vector<double>read_coeffs_eff_phsp_4d();
|
||||
///determine parametrization for efficiencies, needs the reconstructed (MC) events and the set of theory paramters
|
||||
void parametrize_eff(const std::vector<event>& events, const bu2kstarmumu_parameters* theory_params);
|
||||
///parametrize the angular background distribution from the bd mass sidebands
|
||||
//void parametrize_bkg(const std::vector<event>& events);
|
||||
//can do this unbinned in principle ?
|
||||
//yes, do not forget that normalization is not free -> -1 parameter
|
||||
|
||||
///the options used for this pdf e.g. per event resolution or not etc.
|
||||
options* opts;
|
||||
///The signal mass probability (Currently double gaussian). //TODO: check
|
||||
double m_sig_prob(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
double integral_m_sig_prob(const bu2kstarmumu_parameters* params, double ma, double mb) const;
|
||||
///The prompt background mass probability (Currently exponential).
|
||||
double m_bkg_prob(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
double integral_m_bkg_prob(const bu2kstarmumu_parameters* params, double ma, double mb) const;
|
||||
///The signal m(Kpi) mass probability
|
||||
double mkpi_sig_prob(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
///The prompt background in m(Kpi) spectrum probability //TODO: normalization?
|
||||
double mkpi_bkg_prob(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
///The signal angular probability
|
||||
double angular_sig_prob(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
///The prompt background angular probability (flat or Chebyshev)
|
||||
double angular_bkg_prob(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
///Simple background probabilily:
|
||||
double simple_angular_bkg_prob(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
|
||||
///The total probability f_sig*p_sig + (1-f_sig)*p_bkg for event meas.
|
||||
virtual double prob(const parameters* params, const event& meas) const{
|
||||
return prob(static_cast<const bu2kstarmumu_parameters*>(params), meas);//still have the initialization as safety, this is faster
|
||||
};
|
||||
///The total probability f_sig*p_sig + (1-f_sig)*p_bkg for event meas.
|
||||
double prob(const bu2kstarmumu_parameters* params, const event& meas) const;
|
||||
void calculate_sweights(const bu2kstarmumu_parameters* parms, std::vector<event>* ev) const;
|
||||
|
||||
double angular_bkg_norm(const bu2kstarmumu_parameters* params, bool weighted);
|
||||
double angular_sig_norm(const bu2kstarmumu_parameters* params, bool weighted);
|
||||
double angular_swave_norm(const bu2kstarmumu_parameters* params, bool weighted);
|
||||
double angular_pwave_norm(const bu2kstarmumu_parameters* params, bool weighted);
|
||||
double angular_pswave_norm(const bu2kstarmumu_parameters* params, bool weighted);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
struct npolynom{
|
||||
unsigned int ctl;
|
||||
unsigned int ctk;
|
||||
unsigned int phi;
|
||||
unsigned int q2;
|
||||
|
||||
unsigned int getSize(){
|
||||
return q2*ctl*ctk*phi;
|
||||
}
|
||||
|
||||
unsigned int getSize2(){
|
||||
return getSize()*getSize();
|
||||
}
|
||||
|
||||
npolynom(fcnc::options *opts){
|
||||
//Set orders of chebyshev polynomials
|
||||
ctl = opts->eff_order_costhetal;
|
||||
ctk = opts->eff_order_costhetak;
|
||||
phi = opts->eff_order_phi;
|
||||
q2 = opts->eff_order_q2;
|
||||
//spdlog::trace("phi: {0:d}", phi);
|
||||
//spdlog::trace("opts->eff_order_phi: {0:d}", opts->eff_order_phi);
|
||||
}
|
||||
unsigned int get_bin_in4D(int h, int i, int j, int k);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
2625
Code/FCNCFitter/sources/Core/bu2kstarmumu_plotter.cc
Executable file
2625
Code/FCNCFitter/sources/Core/bu2kstarmumu_plotter.cc
Executable file
File diff suppressed because it is too large
Load Diff
66
Code/FCNCFitter/sources/Core/bu2kstarmumu_plotter.hh
Executable file
66
Code/FCNCFitter/sources/Core/bu2kstarmumu_plotter.hh
Executable file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @file bu2kstarmumu_plotter.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BU2KSTARMUMU_PLOTTER_H
|
||||
#define BU2KSTARMUMU_PLOTTER_H
|
||||
|
||||
#include <plotter.hh>
|
||||
#include <bu2kstarmumu_pdf.hh>
|
||||
|
||||
#include <TFile.h>
|
||||
#include <TH1D.h>
|
||||
|
||||
namespace fcnc {
|
||||
|
||||
///class to plots the data and the fitted pdf, also plots the efficiencies
|
||||
class bu2kstarmumu_plotter: public plotter {//was derived from plotter
|
||||
public:
|
||||
///constructor
|
||||
bu2kstarmumu_plotter(options* o);
|
||||
///destructor
|
||||
~bu2kstarmumu_plotter();
|
||||
///plots all projections
|
||||
///
|
||||
int design_pdf(TH1D *pdf, Color_t lineColor, Color_t fillColor, int fillStyle, double eff_pullHeight, bool doPull);
|
||||
|
||||
int plot_data(bu2kstarmumu_pdf* prob, bu2kstarmumu_parameters* params, std::vector<event>* events, std::string prefix, std::string postfix="", bool signalregion=false);
|
||||
|
||||
int plot_data(pdf* prob, parameters* params, std::vector<event>* ev, std::string index) {
|
||||
return plot_data(dynamic_cast<bu2kstarmumu_pdf*>(prob), dynamic_cast<bu2kstarmumu_parameters*>(params), ev, index);
|
||||
};
|
||||
void plot_pdfs(std::vector<bu2kstarmumu_pdf*> * probs, std::vector<bu2kstarmumu_parameters*> * params, std::string postfix, bool signalregion=false);
|
||||
void plot_added_pdfs(std::vector<bu2kstarmumu_pdf*> * probs, std::vector<bu2kstarmumu_parameters*> * params, std::vector<std::vector<event>*> * events, std::string prefix, std::string postfix, bool signalregion=false);
|
||||
void SetPulls(bool drawpulls=true);
|
||||
|
||||
//Plot yields of sig and bkg in one go together with significance and the CMS measurement
|
||||
//Technically this could be in the scritps, but whatever at this point //TODO
|
||||
int plotYieldInQ2(bool fixRange, std::vector<fcnc::parameters*> fitParams[], std::vector<fcnc::pdf*> pdf[], int nPDFs, std::vector<UInt_t>nEvts[], std::string prefix, std::string plotName);
|
||||
private:
|
||||
///pointer to options object
|
||||
options* opts;
|
||||
///draw pull distribuions under plots?
|
||||
bool pulls;
|
||||
///root output file
|
||||
TFile* output;
|
||||
///tex sizes
|
||||
double texsizelarge=0.06, texsizesmall=0.04;
|
||||
///plots the mass projection.
|
||||
void plot_m(bu2kstarmumu_pdf* prob, bu2kstarmumu_parameters* params, std::vector<event>* events, std::string prefix, std::string postfix, bool logarithmic=false, bool printC=false);
|
||||
void plot_mkpi(bu2kstarmumu_pdf* prob, bu2kstarmumu_parameters* params, std::vector<event>* events, std::string prefix, std::string postfix, bool signalregion=false, bool logarithmic=false, bool printC=false);
|
||||
///plots a given angle projection
|
||||
void plot_angle(bu2kstarmumu_pdf* prob, bu2kstarmumu_parameters* params, std::vector<event>* events, std::string prefix, std::string postfix, bool signalregion=false, std::string angle = "ctl", bool printC=false);
|
||||
///plots of pdfs added into one signal histogram!
|
||||
void plot_m_added_pdfs(std::vector<bu2kstarmumu_pdf*> * probs, std::vector<bu2kstarmumu_parameters*> * params, std::vector<std::vector<event>*> * events, std::string prefix, std::string postfix, bool logarithmic=false, bool printC=false);
|
||||
void plot_mkpi_added_pdfs(std::vector<bu2kstarmumu_pdf*> * probs, std::vector<bu2kstarmumu_parameters*> * params, std::vector<std::vector<event>*> * events, std::string prefix, std::string postfix, bool signalregion=false, bool logarithmic=false, bool printC=false);
|
||||
void plot_angle_added_pdfs(std::vector<bu2kstarmumu_pdf*> * probs, std::vector<bu2kstarmumu_parameters*> * params, std::vector<std::vector<event>*> * events, std::string prefix, std::string postfix, bool signalregion=false, std::string angle = "ctl", bool printC=false);
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
287
Code/FCNCFitter/sources/Core/event.cc
Executable file
287
Code/FCNCFitter/sources/Core/event.cc
Executable file
@ -0,0 +1,287 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <event.hh>
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
|
||||
#include "TFile.h"
|
||||
#include "TTree.h"
|
||||
#include "TMath.h"
|
||||
|
||||
#include <helpers.hh>
|
||||
#include <paths.hh>
|
||||
#include <bu2kstarmumu_loader.hh>
|
||||
#include <options.hh>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
void fcnc::print_event(const event& meas)
|
||||
{
|
||||
spdlog::info("Event has" );
|
||||
spdlog::info( " m: {0:f}", meas.m);
|
||||
spdlog::info( " sigma_m: {0:f}", meas.sigma_m);
|
||||
spdlog::info( " weight: {0:f}", meas.weight);
|
||||
spdlog::info( " delta_weight: {0:f}", meas.delta_weight);
|
||||
spdlog::info( " max_mu_pt: {0:f}", meas.max_mu_pt);
|
||||
spdlog::info( " kaon_pt: {0:f}", meas.kaon_pt);
|
||||
spdlog::info( " event_type: {0:d}", meas.event_type);
|
||||
spdlog::info( " Magnet polarity: {0:d}", meas.magnet );
|
||||
spdlog::info( " cos(thetal): {0:f}", meas.costhetal );
|
||||
spdlog::info( " cos(thetak): {0:f}", meas.costhetak );
|
||||
spdlog::info( " phi: {0:f}", meas.phi );
|
||||
|
||||
spdlog::info( " q2: {0:f}", meas.q2 );
|
||||
spdlog::info( " p2: {0:f}", meas.p2 );
|
||||
spdlog::info( " cp conjugate: " +(meas.cp_conjugate) );
|
||||
|
||||
//spdlog::trace( " tagging_decision: {0:f}", meas.tagging_decision );
|
||||
//spdlog::trace( " tagging_dilution: {0:f}", meas.tagging_dilution );
|
||||
//spdlog::trace( " efficiency: {0:f}", meas.efficiency );
|
||||
}
|
||||
|
||||
void fcnc::save_events(std::string filename, const std::vector<fcnc::event>& events){
|
||||
TFile* output = new TFile(filename.c_str(), "RECREATE");
|
||||
output->cd();
|
||||
TTree* tree = new TTree("Events", "Events");
|
||||
//init and link parameters
|
||||
bool cp_conjugate;
|
||||
int year, magnet, event_type;
|
||||
double m, mkpi, sigma_m, costhetal, costhetak, phi, q2, p2, weight, delta_weight, kaon_pt, max_mu_pt, pseudo_q2;
|
||||
tree->Branch("year",&year,"year/I");
|
||||
tree->Branch("m",&m,"m/D");
|
||||
tree->Branch("mkpi",&mkpi,"mkpi/D");
|
||||
tree->Branch("sigma_m",&sigma_m,"sigma_m/D");
|
||||
tree->Branch("costhetal",&costhetal,"costhetal/D");
|
||||
tree->Branch("costhetak",&costhetak,"costhetak/D");
|
||||
tree->Branch("phi",&phi,"phi/D");
|
||||
tree->Branch("magnet", &magnet, "magnet/I");
|
||||
tree->Branch("q2",&q2,"q2/D");
|
||||
tree->Branch("p2",&p2,"p2/D");
|
||||
tree->Branch("cp_conjugate",&cp_conjugate,"cp_conjugate/O");
|
||||
tree->Branch("weight", &weight, "weight/D");
|
||||
tree->Branch("delta_weight", &delta_weight, "delta_weight/D");
|
||||
tree->Branch("kaon_pt", &kaon_pt, "kaon_pt/D");
|
||||
tree->Branch("max_mu_pt", &max_mu_pt, "max_mu_pt/D");
|
||||
tree->Branch("pseudo_q2", &pseudo_q2, "pseudo_q2/D");
|
||||
tree->Branch("event_type", &event_type, "event_type/I"); //TODO
|
||||
spdlog::info( "START to fill events into TTree and save to file!" );
|
||||
|
||||
for (unsigned int i=0; i< events.size(); i++){
|
||||
//get event from vector
|
||||
fcnc::event meas = events.at(i);
|
||||
//copy all values to the linked objects to save in TBranches
|
||||
year = meas.year;
|
||||
m = meas.m;
|
||||
mkpi = meas.mkpi;
|
||||
sigma_m = meas.sigma_m;
|
||||
costhetal = meas.costhetal;
|
||||
costhetak = meas.costhetak;
|
||||
phi = meas.phi;
|
||||
magnet = meas.magnet;
|
||||
q2 = meas.q2;
|
||||
p2 = meas.p2;
|
||||
cp_conjugate = meas.cp_conjugate;
|
||||
weight = meas.weight;
|
||||
delta_weight = meas.delta_weight;
|
||||
kaon_pt = meas.kaon_pt;
|
||||
max_mu_pt = meas.max_mu_pt;
|
||||
pseudo_q2 = meas.pseudo_q2;
|
||||
event_type = meas.event_type;
|
||||
//write to TTree
|
||||
tree->Fill();
|
||||
}
|
||||
Int_t N = tree->GetEntries();
|
||||
tree->Write();
|
||||
output->Write();
|
||||
output->Close();
|
||||
spdlog::info("DONE: Successfully saved {0:d} (out of {1:d}) events to file {2:s}", N, events.size(), filename);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void fcnc::lhcbtotheory(const bool b_plus, const double ctl_lhcb, const double ctk_lhcb, const double phi_lhcb, double& ctl_th, double& ctk_th, double& phi_th)
|
||||
{
|
||||
ctl_th = b_plus ? ctl_lhcb : -ctl_lhcb;
|
||||
ctk_th = -ctk_lhcb;
|
||||
if (b_plus)
|
||||
phi_th = phi_lhcb > 0 ? TMath::Pi() - phi_lhcb : -TMath::Pi() - phi_lhcb;
|
||||
else
|
||||
phi_th = phi_lhcb;
|
||||
}
|
||||
|
||||
void fcnc::theorytolhcb(const bool b_plus, const double ctl_th, const double ctk_th, const double phi_th, double& ctl_lhcb, double& ctk_lhcb, double& phi_lhcb)
|
||||
{
|
||||
ctl_lhcb = b_plus ? ctl_th : -ctl_th;
|
||||
ctk_lhcb = -ctk_th;
|
||||
if (b_plus)
|
||||
phi_lhcb = phi_th > 0 ? TMath::Pi() - phi_th : -TMath::Pi() - phi_th;
|
||||
else
|
||||
phi_lhcb = phi_th;
|
||||
}
|
||||
|
||||
void fcnc::save_eos_events(std::string filename, const std::vector<fcnc::event>& events)
|
||||
{
|
||||
TFile* output = new TFile(filename.c_str(), "RECREATE");
|
||||
output->cd();
|
||||
TTree* tree = new TTree("Events", "Events");
|
||||
fcnc::event meas;
|
||||
tree->Branch("m",&meas.m,"m/D");
|
||||
tree->Branch("mkpi",&meas.mkpi,"mkpi/D");
|
||||
//double costhetal_lhcb, costhetak_lhcb, phi_lhcb;
|
||||
double costhetal_th, costhetak_th, phi_th;
|
||||
|
||||
// tree->Branch("costhetal",&costhetal_lhcb,"costhetal/D");
|
||||
// tree->Branch("costhetak",&costhetak_lhcb,"costhetak/D");
|
||||
// tree->Branch("phi",&phi_lhcb,"phi/D");
|
||||
|
||||
// tree->Branch("costhetal_theory",&meas.costhetal,"costhetal_theory/D");
|
||||
// tree->Branch("costhetak_theory",&meas.costhetak,"costhetak_theory/D");
|
||||
// tree->Branch("phi_theory",&meas.phi,"phi_theory/D");
|
||||
|
||||
tree->Branch("costhetal",&meas.costhetal,"costhetal/D");
|
||||
tree->Branch("costhetak",&meas.costhetak,"costhetak/D");
|
||||
tree->Branch("phi",&meas.phi,"phi/D");
|
||||
|
||||
tree->Branch("costhetal_theory",&costhetal_th,"costhetal_theory/D");
|
||||
tree->Branch("costhetak_theory",&costhetak_th,"costhetak_theory/D");
|
||||
tree->Branch("phi_theory",&phi_th,"phi_theory/D");
|
||||
|
||||
tree->Branch("q2",&meas.q2,"q2/D");
|
||||
tree->Branch("p2",&meas.p2,"p2/D");
|
||||
tree->Branch("cp_conjugate",&meas.cp_conjugate,"cp_conjugate/O");
|
||||
int bid;
|
||||
tree->Branch("bid",&bid,"bid/I");
|
||||
tree->Branch("bkgcat", &meas.event_type, "bkgcat/I");
|
||||
|
||||
for (unsigned int i=0; i< events.size(); i++)
|
||||
{
|
||||
meas = events.at(i);
|
||||
bid = meas.cp_conjugate ? +511 : -511;
|
||||
|
||||
//convert from theory convention to lhcb convention
|
||||
lhcbtotheory(bid > 0, meas.costhetal, meas.costhetak, meas.phi, costhetal_th, costhetak_th, phi_th);
|
||||
tree->Fill();
|
||||
}
|
||||
tree->Write();
|
||||
output->Write();
|
||||
output->Close();
|
||||
delete output;
|
||||
}
|
||||
|
||||
//Removes the resonances from the data sample
|
||||
bool isResonance(double q2){
|
||||
for (auto bin: EXCLUDED_Q2){
|
||||
if (bin[0]<q2 && q2<bin[1]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<fcnc::event> fcnc::filterResonances(std::vector<fcnc::event> events){
|
||||
std::vector<fcnc::event> filtered;
|
||||
for (auto evt: events){
|
||||
if (isResonance(evt.q2)) continue;
|
||||
filtered.push_back(evt);
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
|
||||
std::vector<fcnc::event> fcnc::load_events(std::string filename, std::string treename, int neventsmax)
|
||||
{
|
||||
spdlog::info("Reading " + filename + " into fcnc event vector.");
|
||||
TFile* input = new TFile(filename.c_str(), "READ");
|
||||
TTree* tree = dynamic_cast<TTree*>(input->Get(treename.c_str()));
|
||||
spdlog::debug("Treename: " + std::string(tree->GetName()));
|
||||
fcnc::event meas;
|
||||
|
||||
tree->SetBranchAddress("year", &meas.year);
|
||||
tree->SetBranchAddress("m",&meas.m);
|
||||
tree->SetBranchAddress("mkpi",&meas.mkpi);
|
||||
tree->SetBranchAddress("sigma_m",&meas.sigma_m);
|
||||
|
||||
tree->SetBranchAddress("costhetal",&meas.costhetal);
|
||||
tree->SetBranchAddress("costhetak",&meas.costhetak);
|
||||
tree->SetBranchAddress("phi",&meas.phi);
|
||||
|
||||
tree->SetBranchAddress("q2",&meas.q2);
|
||||
tree->SetBranchAddress("p2",&meas.p2);
|
||||
tree->SetBranchAddress("cp_conjugate",&meas.cp_conjugate);
|
||||
//tree->SetBranchAddress("bkgcat",&meas.event_type); //ONLY USED IN TOYS
|
||||
tree->SetBranchAddress("magnet", &meas.magnet);
|
||||
tree->SetBranchAddress("weight", &meas.weight);
|
||||
tree->SetBranchAddress("delta_weight", &meas.delta_weight);
|
||||
tree->SetBranchAddress("kaon_pt", &meas.kaon_pt);
|
||||
tree->SetBranchAddress("max_mu_pt", &meas.max_mu_pt);
|
||||
|
||||
std::vector<fcnc::event> result;
|
||||
unsigned int nmax = tree->GetEntries();
|
||||
if (neventsmax > 0){
|
||||
unsigned int n = TMath::Abs(neventsmax);
|
||||
if(n < nmax)nmax = n;
|
||||
}
|
||||
for (unsigned int i=0; i< nmax; i++){
|
||||
tree->GetEntry(i);
|
||||
if (!isEvtInAngleRange(&meas)) continue;
|
||||
meas.costhetal_fa = meas.costhetal;
|
||||
meas.costhetak_fa = meas.costhetak;
|
||||
meas.phi_fa = meas.phi;
|
||||
result.push_back(meas);
|
||||
}
|
||||
spdlog::debug("Read events: {0:d}",result.size());
|
||||
input->Close();
|
||||
//delete tree;
|
||||
delete input;
|
||||
return result;
|
||||
};
|
||||
|
||||
std::vector<fcnc::event> merge_two_evtVecs(std::vector<fcnc::event> one, std::vector<fcnc::event> two){
|
||||
std::vector<fcnc::event> merged_vec;
|
||||
merged_vec.insert(merged_vec.end(), one.begin(), one.end());
|
||||
merged_vec.insert(merged_vec.end(), two.begin(), two.end());
|
||||
return merged_vec;
|
||||
}
|
||||
|
||||
//run over the complete tree and create a tree with only the branches needed for FCNC in the correct nomenclature of the FCNCfitter
|
||||
//the data and MC samples are divided into 6 sub-samples: 2 per Run, 3 per sub-decay (K+pi0, KS0pi+(DD) and KS0pi-(LL))
|
||||
int convert_tuples(int job_id, std::string theFCNCpath, fcnc::options opts,std::vector<int> years){
|
||||
|
||||
spdlog::info( "Converting "+get_sample_from_jobID(job_id)+" tuples of Run {0:d} to FCNC format",opts.run);
|
||||
|
||||
reset_spdlog(); // back to default format
|
||||
|
||||
//load the options
|
||||
fcnc::bu2kstarmumu_loader loader(&opts);
|
||||
|
||||
//initialize a vector of this special class of events
|
||||
std::vector<fcnc::event> theEvents;
|
||||
|
||||
if(job_id==4 || job_id ==5) years={2017}; //Only one year available for GenLvl
|
||||
//read the full tuple for each year
|
||||
std::string treePath;
|
||||
for(auto yr: years){
|
||||
//Set the tree name
|
||||
treePath = getSelectedTuplePath(job_id,opts.run,yr);
|
||||
spdlog::debug("Processing " +treePath);
|
||||
//Load the event vector
|
||||
std::vector<fcnc::event> Events = loader.read_full_tuple(yr, treePath, get_inputTree_name(job_id),
|
||||
job_id>0, job_id>0 && opts.useMC, job_id>=4, -1);
|
||||
spdlog::debug("Inserting the vector into theEvents...");
|
||||
//Add
|
||||
theEvents.insert(theEvents.end(), Events.begin(), Events.end());
|
||||
}
|
||||
|
||||
//Some log messages
|
||||
spdlog::debug("Event vector lenght: {0:d}",theEvents.size());
|
||||
if (theEvents.size()==0){
|
||||
spdlog::error("Empty event vector! Abort.");
|
||||
assert(0);
|
||||
}
|
||||
spdlog::info("Completed loading sample: Run {0:d} with years {1:s}", opts.run, convert_vector_to_string(years));
|
||||
|
||||
//save events to standardised output filepath
|
||||
fcnc::save_events(theFCNCpath, theEvents);
|
||||
spdlog::info( "Completed saving sample: Run {0:d}.", opts.run );
|
||||
|
||||
return 0;
|
||||
}
|
134
Code/FCNCFitter/sources/Core/event.hh
Executable file
134
Code/FCNCFitter/sources/Core/event.hh
Executable file
@ -0,0 +1,134 @@
|
||||
/**
|
||||
* @file event.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EVENT_H
|
||||
#define EVENT_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace fcnc { //Forward declaration, fully defined in options.hh
|
||||
class options;
|
||||
}
|
||||
|
||||
namespace fcnc {
|
||||
|
||||
// typedef event_type enum {};
|
||||
///The event class stores the different event quantities needed to extract the physically interesting parametes in the likelihood fit.
|
||||
class event {
|
||||
public:
|
||||
//save the year into each event
|
||||
int year;
|
||||
///the mass used to separate signal and background
|
||||
double m;
|
||||
///the error on the measured mass
|
||||
double sigma_m;
|
||||
//the reconstructed mass of the K*+
|
||||
double mkpi;
|
||||
///set in the toy data generation to distinguish background from signal in the plots
|
||||
int event_type;
|
||||
/// magnet polarity (down = -1 and up = +1)
|
||||
int magnet;
|
||||
///costhetal
|
||||
double costhetal;
|
||||
///costhetak
|
||||
double costhetak;
|
||||
///phi
|
||||
double phi;
|
||||
//full angular angles that are saved even after folding
|
||||
double costhetal_fa;
|
||||
double costhetak_fa;
|
||||
double phi_fa;
|
||||
///weight
|
||||
double weight;
|
||||
double delta_weight;
|
||||
double max_mu_pt;
|
||||
double kaon_pt;
|
||||
///xis
|
||||
//double xis[18];
|
||||
//float xis[18];
|
||||
///q2
|
||||
double q2;
|
||||
///from opening angle of leptons:
|
||||
double pseudo_q2;
|
||||
///p2
|
||||
double p2;
|
||||
///cp_conjugate (B) or not (Bbar)
|
||||
bool cp_conjugate;
|
||||
double sweight;
|
||||
double mjpsipi;
|
||||
event():
|
||||
year(2000),
|
||||
m(0.0),
|
||||
sigma_m(0.0),
|
||||
mkpi(892.0),
|
||||
event_type(0),
|
||||
magnet(0),
|
||||
costhetal(0.0),
|
||||
costhetak(0.0),
|
||||
phi(0.0),
|
||||
costhetal_fa(0.0),
|
||||
costhetak_fa(0.0),
|
||||
phi_fa(0.0),
|
||||
weight(1.0),
|
||||
delta_weight(0.0),
|
||||
max_mu_pt(0.0),
|
||||
kaon_pt(0.0),
|
||||
//norm(1.0),
|
||||
q2(0.0),
|
||||
pseudo_q2(0.0),
|
||||
cp_conjugate(false),
|
||||
sweight(1.0)
|
||||
{
|
||||
// xis[0] = 3.0/2.0;
|
||||
// xis[1] = 3.0/4.0;
|
||||
// xis[2] = -1.0/2.0;
|
||||
// xis[3] = -1.0/4.0;
|
||||
// xis[4] = 0.0;
|
||||
// xis[5] = 0.0;
|
||||
// xis[6] = 0.0;
|
||||
// xis[7] = 0.0;
|
||||
// xis[8] = 0.0;
|
||||
// xis[9] = 0.0;
|
||||
// xis[10] = 0.0;
|
||||
// xis[11] = 0.0;
|
||||
// xis[12] = 1.0;
|
||||
// xis[13] = 0.0;
|
||||
// xis[14] = 0.0;
|
||||
// xis[15] = 0.0;
|
||||
// xis[16] = 0.0;
|
||||
// xis[17] = 0.0;
|
||||
};
|
||||
|
||||
//reset folded angles back to full angular
|
||||
void reset_angles()
|
||||
{
|
||||
costhetal = costhetal_fa;
|
||||
costhetak = costhetak_fa;
|
||||
phi = phi_fa;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
///print the quantities of event meas
|
||||
void print_event(const event& meas);
|
||||
void save_events(std::string filename, const std::vector<event>& events);
|
||||
void save_eos_events(std::string filename, const std::vector<event>& events);
|
||||
std::vector<event> filterResonances(std::vector<event> events);
|
||||
std::vector<event> load_events(std::string filename, std::string treename="Events", int neventsmax = -1);
|
||||
|
||||
///convert between different angular conventions
|
||||
void lhcbtotheory(const bool bzero, const double ctl_lhcb, const double ctk_lhcb, const double phi_lhcb, double& ctl_th, double& ctk_th, double& phi_th);
|
||||
void theorytolhcb(const bool bzero, const double ctl_th, const double ctk_th, const double phi_th, double& ctl_lhcb, double& ctk_lhcb, double& phi_lhcb);
|
||||
};
|
||||
|
||||
|
||||
int convert_tuples(int job_id, std::string theFCNCpath, fcnc::options opts, std::vector<int> years);
|
||||
|
||||
std::vector<fcnc::event> merge_two_evtVecs(std::vector<fcnc::event> one, std::vector<fcnc::event> two);
|
||||
|
||||
#endif
|
1260
Code/FCNCFitter/sources/Core/fitter.cc
Normal file
1260
Code/FCNCFitter/sources/Core/fitter.cc
Normal file
File diff suppressed because it is too large
Load Diff
135
Code/FCNCFitter/sources/Core/fitter.hh
Normal file
135
Code/FCNCFitter/sources/Core/fitter.hh
Normal file
@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @file fitter.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
* @date 2010-10-13
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FITTER_H
|
||||
#define FITTER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
#include <TMinuit.h>
|
||||
|
||||
namespace fcnc {
|
||||
class event;
|
||||
class parameter;
|
||||
class parameters;
|
||||
class pdf;
|
||||
class plotter;
|
||||
class options;
|
||||
class fitter;
|
||||
|
||||
///gives wether a i (absolutely) larger than b
|
||||
template<class T> struct GreaterThan{
|
||||
bool operator()(const T a, const T b) const
|
||||
{ return std::abs(a) > std::abs(b); }
|
||||
};
|
||||
|
||||
///adds up all probability values in an efficient and numerically optimal manner
|
||||
template<typename iterator> typename iterator::value_type add_results(iterator begin, iterator end){
|
||||
typedef typename iterator::value_type T;
|
||||
if (end == begin) return 0.;
|
||||
std::make_heap(begin, end, GreaterThan<T>());
|
||||
|
||||
for (; begin + 1 < end; ) {
|
||||
T x = *begin;
|
||||
std::pop_heap(begin, end--, GreaterThan<T>());
|
||||
do {
|
||||
x += *begin;
|
||||
std::pop_heap(begin, end--, GreaterThan<T>());
|
||||
} while (std::abs(*begin) >= std::abs(x) && begin < end);
|
||||
*end++ = x;
|
||||
std::push_heap(begin, end, GreaterThan<T>());
|
||||
}
|
||||
return *begin;
|
||||
}
|
||||
|
||||
///The fitter class implements an unbinned multithreaded maximum likelihood fit
|
||||
class fitter {
|
||||
public:
|
||||
///global mutex for use of threads
|
||||
//static boost::mutex fitter_mutex;
|
||||
static std::mutex fitter_mutex;
|
||||
///global fitter object for minuit
|
||||
static fitter* minuit_one_fitter;
|
||||
///empirical constant which is subtracted to improve the numerical stability of the fit
|
||||
double empirical_constant;
|
||||
///the minuit 1 minimizer object
|
||||
TMinuit* minuit_one;
|
||||
///pointer to events to fit
|
||||
std::vector< std::vector<event>* > events;
|
||||
///pointer to parameter sets to fit
|
||||
std::vector< parameters* > params;
|
||||
///common parameters in different parameter sets
|
||||
std::vector< std::string > common_params;
|
||||
//plotters
|
||||
std::vector< plotter* > plots;
|
||||
///pointer to the pdf(s)
|
||||
std::vector<pdf*> pdfs;
|
||||
///pointer to the options object
|
||||
options* opts;
|
||||
///if true, this fitter has already been initialized
|
||||
bool initialized;
|
||||
///every thread adds the result of their likelihood calculation to this
|
||||
long double lh_tot;
|
||||
///use square of weights for error correction in weighted fits
|
||||
bool square_weights;
|
||||
public:
|
||||
///minuit one FCN
|
||||
static void minuit_one_fcn(Int_t &npar, Double_t *grad, Double_t &lh, Double_t *params, Int_t iflag);
|
||||
///constructor
|
||||
fitter(options* o);
|
||||
///destructor
|
||||
~fitter();
|
||||
/** fit the parameter set to the events using the pdf
|
||||
* @param probability pointer to pdf to use in the likelihood fit
|
||||
* @param parameters pointer to parameterset to use in the likelihood fit
|
||||
* @param events pointer to a vector of events for which to maximise the likelihood
|
||||
* @param index optional parameter to give the current run of a toystudy **/
|
||||
int fit(std::vector<pdf*> probs, std::vector<parameters*> parms, std::vector< std::vector<event> * > ev, std::string index="");
|
||||
/** fit the parameter set to the events using the pdf
|
||||
* @param vector of probability pointers to pdfs to use in the likelihood fit
|
||||
* @param vector of pointers to parametersets to use in the likelihood fit
|
||||
* @param vector of pointers to vector of events for which to maximise the likelihood
|
||||
* @param index optional parameter to give the current run of a toystudy **/
|
||||
int fit(pdf* probs, parameters* parms, std::vector<event>* ev, std::string index="");
|
||||
//set pdfs, parameters and events to extract likelihoods manually:
|
||||
void init(std::vector<pdf*> probs, std::vector<parameters*> parms, std::vector< std::vector<event> * > ev, std::string index="");
|
||||
void init(pdf* probs, parameters* parms, std::vector<event>* ev, std::string index="");
|
||||
///add a parameter to minuit
|
||||
void define_parameter(int i, const parameter & p);
|
||||
///reset all parameters to the start values
|
||||
void reset_param_values();
|
||||
///calculates log (prod(p_i)) = sum lh(p_i), calls likelihood_thread for every thread
|
||||
double likelihood();
|
||||
///calculates the log pdf for a single thread
|
||||
void likelihood_thread(int thread_id);
|
||||
//set plotter
|
||||
void set_plotters(plotter* plot);
|
||||
///set plotters
|
||||
void set_plotters(std::vector<plotter*> plotters);
|
||||
///define common parameters for all pdfs
|
||||
void set_common_parameters(std::vector<std::string> common_pars);
|
||||
///is the parameter with name one of the common parameters
|
||||
bool is_common(std::string name);
|
||||
///is this the first occurence of the parameter?
|
||||
bool is_first(std::string name, unsigned int idx_i, unsigned int idx_j);
|
||||
///returns the nth minuit index for parameter with name
|
||||
int nth_minuit_index(std::string name, unsigned int n);
|
||||
///returns the first minuit index for parameter with name
|
||||
int first_minuit_index(std::string name);
|
||||
|
||||
///returns wether this is an analysis with blinded parameters
|
||||
bool is_blind();
|
||||
};
|
||||
|
||||
|
||||
}//end namespace
|
||||
|
||||
//Print migrad status with explanation
|
||||
void printMigradStatus(int status);
|
||||
#endif
|
201
Code/FCNCFitter/sources/Core/folder.cc
Normal file
201
Code/FCNCFitter/sources/Core/folder.cc
Normal file
@ -0,0 +1,201 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <folder.hh>
|
||||
#include <TRandom3.h>
|
||||
#include <event.hh>
|
||||
#include <helpers.hh>
|
||||
|
||||
#include <spdlog.h>
|
||||
///fold the set of angles according to the chosen folding scheme
|
||||
void fcnc::folder::fold(event* e){
|
||||
//make sure, that the full angular information was saved before into the correct parameters:
|
||||
assert(e->costhetal == e->costhetal_fa);
|
||||
assert(e->costhetak == e->costhetak_fa);
|
||||
assert(e->phi == e->phi_fa);
|
||||
|
||||
double pi = TMath::Pi();
|
||||
switch(this->scheme){
|
||||
case -1:
|
||||
return;
|
||||
case 0:
|
||||
if(e->phi < 0)e->phi = e->phi + pi;
|
||||
break;
|
||||
case 1:
|
||||
if(e->phi < 0){
|
||||
e->phi = -e->phi;
|
||||
}
|
||||
if(e->costhetal < 0){
|
||||
e->phi = pi - e->phi;
|
||||
e->costhetal = -e->costhetal;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(e->phi < 0) e->phi = -e->phi;
|
||||
|
||||
if(e->costhetal < 0) e->costhetal = -e->costhetal;
|
||||
break;
|
||||
case 3:
|
||||
if(e->phi > pi/2.) e->phi = pi - e->phi;
|
||||
if(e->phi < -pi/2.) e->phi = -pi - e->phi;
|
||||
|
||||
if(e->costhetal < 0) e->costhetal = -e->costhetal;
|
||||
break;
|
||||
case 4:
|
||||
if(e->phi > pi/2.) e->phi = pi - e->phi;
|
||||
if(e->phi < -pi/2.) e->phi = -pi - e->phi;
|
||||
|
||||
if(e->costhetal < 0){
|
||||
e->costhetal = -e->costhetal;
|
||||
e->costhetak = -e->costhetak;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
///inverse fold the set of angles according to the chosen folding scheme
|
||||
void fcnc::folder::invers_fold(const event* e, event *u_phi, event *u_ctl, event *u_full){
|
||||
|
||||
/*
|
||||
phi /^\
|
||||
| :
|
||||
| (2) : (4)
|
||||
| :
|
||||
|---------+--------
|
||||
| :
|
||||
| (1) : (3)
|
||||
|_________________>
|
||||
cos(theta)
|
||||
|
||||
(1): original event (e)
|
||||
(2): unfolded in phi (u_phi)
|
||||
(3): unfolded in ctl (u_ctl)
|
||||
(4): twice unfolded (u_full)
|
||||
|
||||
*/
|
||||
*u_phi = *e; //only inversly folded in dependence of phi
|
||||
*u_ctl = *e; //only inversly folded in dependence of ctl
|
||||
*u_full = *e; //full inversly folded
|
||||
|
||||
double pi = TMath::Pi();
|
||||
switch(this->scheme){
|
||||
case -1:
|
||||
return;
|
||||
case 0:
|
||||
assert(e->phi > 0.0);
|
||||
|
||||
u_phi->phi = u_phi->phi - pi;
|
||||
u_full->phi = u_full->phi - pi;
|
||||
|
||||
break;
|
||||
case 1:
|
||||
assert(e->phi > 0.0);
|
||||
assert(e->costhetal > 0.0);
|
||||
|
||||
u_ctl->phi = pi - u_ctl->phi;
|
||||
u_full->phi = pi - u_full->phi;
|
||||
u_ctl->costhetal = -u_ctl->costhetal;
|
||||
u_full->costhetal = -u_full->costhetal;
|
||||
|
||||
u_phi->phi = -u_phi->phi;
|
||||
u_full->phi = -u_full->phi;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
assert(e->phi > 0.0);
|
||||
assert(e->costhetal > 0.0);
|
||||
|
||||
u_phi->phi = -u_phi->phi;
|
||||
u_full->phi = -u_full->phi;
|
||||
|
||||
u_ctl->costhetal = -u_ctl->costhetal;
|
||||
u_full->costhetal = -u_full->costhetal;
|
||||
|
||||
break;
|
||||
case 3:
|
||||
assert(e->phi < pi/2.);
|
||||
assert(e->phi > -pi/2.);
|
||||
assert(e->costhetal > 0.0);
|
||||
|
||||
if(e->phi > 0.0){
|
||||
u_phi->phi = pi - u_phi->phi;
|
||||
u_full->phi = pi - u_full->phi;
|
||||
}
|
||||
else{
|
||||
u_phi->phi = -pi - u_phi->phi;
|
||||
u_full->phi = -pi - u_full->phi;
|
||||
}
|
||||
|
||||
u_ctl->costhetal = -u_ctl->costhetal;
|
||||
u_full->costhetal = -u_full->costhetal;
|
||||
|
||||
break;
|
||||
case 4:
|
||||
assert(e->phi < pi/2.);
|
||||
assert(e->phi > -pi/2.);
|
||||
assert(e->costhetal > 0.0);
|
||||
|
||||
if(e->phi > 0.0){
|
||||
u_phi->phi = pi - u_phi->phi;
|
||||
u_full->phi = pi - u_full->phi;
|
||||
}
|
||||
else{
|
||||
u_phi->phi = -pi - u_phi->phi;
|
||||
u_full->phi = -pi - u_full->phi;
|
||||
}
|
||||
|
||||
u_ctl->costhetal = -u_ctl->costhetal;
|
||||
u_ctl->costhetak = -u_ctl->costhetak;
|
||||
u_full->costhetal = -u_full->costhetal;
|
||||
u_full->costhetak = -u_full->costhetak;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void fcnc::folder::test_inv_folding(){
|
||||
|
||||
fcnc::event e;
|
||||
e.m = 5286.0;
|
||||
TRandom3 * r = new TRandom3(0);
|
||||
for(int i = 0; i < 10000; i++){
|
||||
|
||||
if(i % 100 == 0 && spdlog_info())std::cout << i / 100. << "%" << std::endl;
|
||||
|
||||
//generate a folded event:
|
||||
e.costhetal = r->Rndm() * 2. - 1.;
|
||||
e.costhetak = r->Rndm() * 2. - 1.;
|
||||
e.phi = (r->Rndm() * 2. - 1.) * TMath::Pi();
|
||||
e.costhetal_fa = e.costhetal;
|
||||
e.costhetak_fa = e.costhetak;
|
||||
e.phi_fa = e.phi;
|
||||
|
||||
this->fold(&e);
|
||||
|
||||
//get 3 events for (partial-)inverse folding:
|
||||
fcnc::event inv_e[3];
|
||||
|
||||
this->invers_fold(&e, &inv_e[0], &inv_e[1], &inv_e[2]);
|
||||
|
||||
for(int j = 0; j < 3; j++){
|
||||
inv_e[j].costhetal_fa = inv_e[j].costhetal;
|
||||
inv_e[j].costhetak_fa = inv_e[j].costhetak;
|
||||
inv_e[j].phi_fa = inv_e[j].phi;
|
||||
this->fold(&inv_e[j]);
|
||||
|
||||
assert(abs(e.phi - inv_e[j].phi ) < 1e-7);
|
||||
assert(abs(e.costhetal - inv_e[j].costhetal) < 1e-7);
|
||||
assert(abs(e.costhetak - inv_e[j].costhetak) < 1e-7);
|
||||
}
|
||||
}
|
||||
spdlog::info("[DONE]\t\tInverse folding #{0:d} works!", this->scheme);
|
||||
}
|
||||
|
||||
int fcnc::folder::get_scheme(){
|
||||
return this->scheme;
|
||||
}
|
||||
|
||||
void fcnc::folder::set_scheme(int s){
|
||||
this->scheme = s;
|
||||
}
|
66
Code/FCNCFitter/sources/Core/folder.hh
Normal file
66
Code/FCNCFitter/sources/Core/folder.hh
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @file folder.hh
|
||||
* @author David Gerick, Renata Kopecna
|
||||
* @date 2018-04-24
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FOLDER_H
|
||||
#define FOLDER_H
|
||||
|
||||
#include <options.hh>
|
||||
#include <assert.h>
|
||||
|
||||
namespace fcnc {
|
||||
class event;
|
||||
|
||||
///An abstract base class to fold angles accordingly
|
||||
class folder {
|
||||
public:
|
||||
int scheme;
|
||||
///constructor
|
||||
folder(options *o):
|
||||
scheme(o->folding)
|
||||
{
|
||||
|
||||
if(!o->full_angular){
|
||||
assert(scheme >= 0);
|
||||
assert(scheme <= 4);
|
||||
}
|
||||
o->update_angle_ranges();
|
||||
};
|
||||
|
||||
///fold the set of angles according to the chosen folding scheme
|
||||
void fold(event* e);
|
||||
|
||||
///inverse fold the set of angles according to the chosen folding scheme
|
||||
void invers_fold(const event* e, event *u_phi, event *u_ctl, event *u_full);
|
||||
|
||||
/*
|
||||
phi /^\
|
||||
| :
|
||||
| (2) : (4)
|
||||
| :
|
||||
|---------+--------
|
||||
| :
|
||||
| (1) : (3)
|
||||
|_________________>
|
||||
cos(theta)
|
||||
|
||||
(1): original event (e)
|
||||
(2): unfolded in phi (u_phi)
|
||||
(3): unfolded in ctl (u_ctl)
|
||||
(4): twice unfolded (u_full)
|
||||
|
||||
*/
|
||||
|
||||
void test_inv_folding();
|
||||
|
||||
int get_scheme();
|
||||
void set_scheme(int s);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
2561
Code/FCNCFitter/sources/Core/funcs.cc
Executable file
2561
Code/FCNCFitter/sources/Core/funcs.cc
Executable file
File diff suppressed because one or more lines are too long
307
Code/FCNCFitter/sources/Core/funcs.hh
Executable file
307
Code/FCNCFitter/sources/Core/funcs.hh
Executable file
@ -0,0 +1,307 @@
|
||||
/**
|
||||
* @file funcs.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FUNCS_H
|
||||
#define FUNCS_H
|
||||
|
||||
#include <complex>
|
||||
|
||||
#include <TRandom3.h>
|
||||
#include <Math/Boost.h>
|
||||
#include <Math/Vector4D.h>
|
||||
#include <Math/Vector3D.h>
|
||||
#include <TMatrixDSym.h>
|
||||
#include <TMatrixD.h>
|
||||
#include <Math/SpecFuncMathCore.h>
|
||||
#include <Math/SpecFuncMathMore.h>
|
||||
|
||||
namespace fcnc { //Forward declaration, fully defined in options.hh
|
||||
class options;
|
||||
class event;
|
||||
}
|
||||
|
||||
namespace fcnc {
|
||||
|
||||
typedef ROOT::Math::PxPyPzEVector LorentzVector;
|
||||
typedef ROOT::Math::Boost LorentzBoost;
|
||||
typedef ROOT::Math::DisplacementVector3D<ROOT::Math::Cartesian3D<double> > Vector3;
|
||||
|
||||
TMatrixDSym get_bsz_invcov();
|
||||
TMatrixDSym get_bsz_cov();
|
||||
TMatrixD get_bsz_mu_invcov();
|
||||
|
||||
double eff_paper(const double& q2, const double& ctl, const double& ctk, const double& phi);
|
||||
|
||||
double get_sliding_error(double xmeas, double xth, double eup, double edown);
|
||||
|
||||
double crystalball(double m, double mean, double sigma, double alpha, double n);
|
||||
double twotailedcrystalball(double m, double mean, double sigma, double alpha1, double alpha2, double n1, double n2);
|
||||
|
||||
//blinding
|
||||
double evaluate_unblind_uniform(double valueSeenByAnalist, const char* blindingString, double scale);
|
||||
double evaluate_unblind_uniform_angle(double valueSeenByAnalist, const char* blindingString, double scale);
|
||||
|
||||
double sqr(double x);
|
||||
//basic trigonometric functions
|
||||
double costheta2(double costheta);
|
||||
double cos2theta(double costheta);
|
||||
double sintheta2(double costheta);
|
||||
double sintheta_abs(double costheta);
|
||||
double sin2theta(double costheta);
|
||||
|
||||
|
||||
double chebyshev(double x, int n);
|
||||
void chebyshev(double x, int n, std::vector<double>& results);
|
||||
void chebyshev_to_poly(const std::vector<double>& chebychev, std::vector<double>& poly);
|
||||
void correct_poly(const std::vector<double>& poly, std::vector<double>& correct, double min, double max);
|
||||
|
||||
double legendre(double x, int n);
|
||||
void legendre(double x, int n, std::vector<double>& results);
|
||||
void orthonormal_legendre(double x, int n, std::vector<double>& results);
|
||||
void legendre_to_poly(const std::vector<double>& legendre, std::vector<double>& poly);
|
||||
|
||||
///calculates the associated legendre polynomial for l,m order
|
||||
double assoc_legendre(unsigned int l, unsigned int m, double x);
|
||||
///calculates the real part of the spherical harmonics for l, m
|
||||
double spherical_harmonic_re(unsigned int l, unsigned int m, double theta, double phi);
|
||||
///calculates the imaginary part of the spherical harmonics for l, m
|
||||
double spherical_harmonic_im(unsigned int l, unsigned int m, double theta, double phi);
|
||||
///function calculates the angles in the transversity base using the momenta of the final state particles
|
||||
void calculate_transversity_angles(const LorentzVector& mu_minus,
|
||||
const LorentzVector& mu_plus,
|
||||
const LorentzVector& k_minus,
|
||||
const LorentzVector& k_plus,
|
||||
double & cos_theta, double & angle_phi, double & cos_psi);
|
||||
///this function calculates the convolution sin(angle) from 0 to pi
|
||||
double convoluted_sin(double angle, double sigma);
|
||||
double convoluted_cos_sin(double angle, double sigma);
|
||||
double convoluted_cos(double angle, double sigma);//not used
|
||||
double convoluted_cos_2(double angle, double sigma);//not used
|
||||
double convoluted_sin_2(double angle, double sigma);//used by s wave
|
||||
double convoluted_2_sin(double angle, double sigma);//used by s wave
|
||||
double convoluted_2_cos(double angle, double sigma);//not used
|
||||
double convoluted_cos_2_sin(double angle, double sigma);
|
||||
double convoluted_2_sin_sin(double angle, double sigma);
|
||||
double convoluted_sin_3(double angle, double sigma);
|
||||
//this integrates the above expressions (vonvolution before has been from 0 to pi
|
||||
double int_convoluted_sin(double angle, double sigma);
|
||||
double int_convoluted_cos_sin(double angle, double sigma);
|
||||
double int_convoluted_cos_2_sin(double angle, double sigma);
|
||||
double int_convoluted_2_sin_sin(double angle, double sigma);
|
||||
double int_convoluted_sin_3(double angle, double sigma);
|
||||
double int_convoluted_sin_2(double angle, double sigma);//used by s wave
|
||||
double int_convoluted_2_sin(double angle, double sigma);//used by s wave
|
||||
//convolutions for phi. this is easier due to the wraparound at +-pi -> convolution from -int to inf
|
||||
double inf_convoluted_sin(double angle, double sigma);
|
||||
double inf_convoluted_cos(double angle, double sigma);
|
||||
double inf_convoluted_cos_2(double angle, double sigma);
|
||||
double inf_convoluted_sin_2(double angle, double sigma);
|
||||
double inf_convoluted_2_sin(double angle, double sigma);
|
||||
//integral of above
|
||||
double int_inf_convoluted_const(double angle, double sigma);
|
||||
double int_inf_convoluted_sin(double angle, double sigma);
|
||||
double int_inf_convoluted_cos(double angle, double sigma);
|
||||
double int_inf_convoluted_cos_2(double angle, double sigma);
|
||||
double int_inf_convoluted_sin_2(double angle, double sigma);
|
||||
double int_inf_convoluted_2_sin(double angle, double sigma);
|
||||
//integrals from -inf to inf over the convolution from 0 to pi with acceptance
|
||||
double int_convoluted_sin_cos_n(int n, double sigma);
|
||||
double int_convoluted_sin_3_cos_n(int n, double sigma);
|
||||
double int_convoluted_cos_2_sin_cos_n(int n, double sigma);
|
||||
double int_convoluted_2_sin_sin_cos_n(int n, double sigma);
|
||||
double int_convoluted_cos_sin_cos_n(int n, double sigma);
|
||||
double int_convoluted_sin_2_cos_n(int n, double sigma);
|
||||
//integrals from 0 to pi over the convolution from -inf to inf with acceptance
|
||||
double int_inf_convoluted_const_x_n(int n, double sigma);
|
||||
double int_inf_convoluted_cos_2_x_n(int n, double sigma);
|
||||
double int_inf_convoluted_sin_2_x_n(int n, double sigma);
|
||||
double int_inf_convoluted_sin_x_n(int n, double sigma);
|
||||
double int_inf_convoluted_2_sin_x_n(int n, double sigma);
|
||||
double int_inf_convoluted_cos_x_n(int n, double sigma);
|
||||
|
||||
|
||||
///function gives the result of exp(-ct/tau)*sin(delta_m*ct) and exp(-ct/tau)*cos(delta_m*ct) convoluted with a gaussian with width sigma
|
||||
void convoluted_exp_sincos(double ct, double sigma, double tau, double deltam, double& one, double& two);
|
||||
///function gives the norm of the expression exp(-ct/tau)*sin(delta_m*ct) and exp(-ct/tau)*cos(delta_m*ct) convoluted with a gaussian with width sigma
|
||||
void norm_convoluted_exp_sincos(double tau, double deltam, double& one, double& two);
|
||||
///function calculates exp(-ct/tau) convoluted with a gaussian with width sigma
|
||||
double convoluted_exp(double ct, double sigma_ct, double S);
|
||||
///function calculates exp(-ct/tau) depending on the parameters normalized or not
|
||||
double expdecay(double t, double tau, bool normalized);
|
||||
///function calculates 1/(sqrt(2*pi)*exp(-(x-mean)^2/(2*sigma^2)))
|
||||
double gauss(double x, double sigma, double mean);
|
||||
///function calculates a normed gaussian between the values min and max used in the mass pdfs
|
||||
double normed_gauss(double x, double sigma, double mean, double min, double max);
|
||||
///integrate gauss from a to b
|
||||
double linear(double x, double min, double max, double slope);
|
||||
///very important helper function, the error function with complex argument. This is probably one of the performance bottlenecks. Probably much faster with a lookup table and interpolation
|
||||
|
||||
double threshold(double x, double thr, double n);
|
||||
double int_threshold(double a, double b, double thr, double n);
|
||||
|
||||
|
||||
//see arxiv 1207.4004
|
||||
/*
|
||||
std::complex<double> bw_kstar_amp(double mkpi_squared, double gammakstar, double mkstar);
|
||||
std::complex<double> bw_kstarzero_amp(double mkpisquared, double gk_re, double gk_im, double gammak, double mk, double gammakstarzero, double mkstarzero);
|
||||
double bw_kstar_amp_squared(double mkpisquared, double gammakstar, double mkstar);
|
||||
std::complex<double> bw_kstar_amp_kstarzero_amp_bar(double mkpisquared, double gammakstar, double mkstar, double gk_re, double gk_im, double gammak, double mk, double gammakstarzero, double mkstarzero);
|
||||
double bw_kstarzero_amp_squared(double mkpisquared, double gk_re, double gk_im, double gammak, double mk, double gammakstarzero, double mkstarzero);
|
||||
*/
|
||||
double daughtermom(double m, double m1, double m2);
|
||||
std::complex<double> mkpi_simple_bw_kstar_amp(double mkpi, double qsquared, double gammakstar, double mkstar);
|
||||
double mkpi_simple_bw_kstar_amp_squared(double mkpi, double qsquared, double gammakstar, double mkstar);
|
||||
double gsl_mkpi_simple_bw_kstar_amp_squared(double x, void* par);
|
||||
double int_mkpi_simple_bw_kstar_amp_squared(const double& mkpia, const double& mkpib, const double& qsquared, const double& gammakstar, const double& mkstar);
|
||||
|
||||
std::complex<double> mkpi_simple_kstarzero_amp(double mkpi, double qsquared, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero);
|
||||
double mkpi_simple_kstarzero_amp_squared(double mkpi, double qsquared, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero);
|
||||
double gsl_mkpi_simple_kstarzero_amp_squared(double x, void* par);
|
||||
double int_mkpi_simple_kstarzero_amp_squared(const double& mkpia, const double& mkpib, const double& qsquared, const double& f800mag, const double& f800phase, const double& gammaf800, const double& mf800, const double& gammakstarzero, const double& mkstarzero);
|
||||
|
||||
std::complex<double> mkpi_simple_bw_kstar_amp_kstarzero_amp_bar(double mkpi, double qsquared,
|
||||
double gammakstar, double mkstar, double asphase,
|
||||
double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero);
|
||||
std::complex<double> mkpi_simple_bw_kstar_amp_bar_kstarzero_amp(double mkpi, double qsquared,
|
||||
double gammakstar, double mkstar, double asphase,
|
||||
double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero);
|
||||
|
||||
std::complex<double> int_mkpi_simple_bw_kstar_amp_kstarzero_amp_bar(const double& mkpia, const double& mkpib, const double& qsquared,
|
||||
const double& gammakstar, const double& mkstar, const double& asphase,
|
||||
const double& f800mag, const double& f800phase, const double& gammaf800, const double& mf800, const double& gammakstarzero, const double& mkstarzero);
|
||||
std::complex<double> int_mkpi_simple_bw_kstar_amp_bar_kstarzero_amp(const double& mkpia, const double& mkpib, const double& qsquared,
|
||||
const double& gammakstar, const double& mkstar, const double& asphase,
|
||||
const double& f800mag, const double& f800phase, const double& gammaf800, const double& mf800, const double& gammakstarzero, const double& mkstarzero);
|
||||
|
||||
double gsl_mkpi_simple_re_bw_kstar_amp_kstarzero_amp_bar(double x, void* par);
|
||||
double gsl_mkpi_simple_im_bw_kstar_amp_kstarzero_amp_bar(double x, void* par);
|
||||
double gsl_mkpi_simple_re_bw_kstar_amp_bar_kstarzero_amp(double x, void* par);
|
||||
double gsl_mkpi_simple_im_bw_kstar_amp_bar_kstarzero_amp(double x, void* par);
|
||||
|
||||
|
||||
std::complex<double> mkpi_bw_kstar_amp(double mkpi, double qsquared, double gammakstar, double mkstar, double R);
|
||||
std::complex<double> mkpi_kstarzero_lass_amp(double mkpi, double qsquared, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R);
|
||||
std::complex<double> mkpi_bw_kstar_amp_kstarzero_lass_amp_bar(double mkpi, double qsquared, double gammakstar, double mkstar, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R);
|
||||
std::complex<double> mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(double mkpi, double qsquared, double gammakstar, double mkstar, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R);
|
||||
double mkpi_bw_kstar_amp_squared(double mkpi, double qsquared, double gammakstar, double mkstar, double R);
|
||||
double mkpi_kstarzero_lass_amp_squared(double mkpi, double qsquared, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R);
|
||||
|
||||
std::complex<double> mkpi_kstarzero_isobar_amp(double mkpi, double qsquared, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R);
|
||||
double mkpi_kstarzero_isobar_amp_squared(double mkpi, double qsquared, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R);
|
||||
std::complex<double> mkpi_bw_kstar_amp_kstarzero_isobar_amp_bar(double mkpi, double qsquared,
|
||||
double gammakstar, double mkstar, double asphase,
|
||||
double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R);
|
||||
std::complex<double> mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(double mkpi, double qsquared,
|
||||
double gammakstar, double mkstar, double asphase,
|
||||
double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R);
|
||||
double gsl_mkpi_kstarzero_isobar_amp_squared(double x, void* par);
|
||||
double gsl_mkpi_re_bw_kstar_amp_kstarzero_isobar_amp_bar(double x, void* par);
|
||||
double gsl_mkpi_im_bw_kstar_amp_kstarzero_isobar_amp_bar(double x, void* par);
|
||||
double gsl_mkpi_re_bw_kstar_amp_bar_kstarzero_isobar_amp(double x, void* par);
|
||||
double gsl_mkpi_im_bw_kstar_amp_bar_kstarzero_isobar_amp(double x, void* par);
|
||||
|
||||
double gsl_mkpi_bw_kstar_amp_squared(double x, void* par);
|
||||
double gsl_mkpi_kstarzero_lass_amp_squared(double x, void* par);
|
||||
double gsl_mkpi_re_bw_kstar_amp_kstarzero_lass_amp_bar(double x, void* par);
|
||||
double gsl_mkpi_im_bw_kstar_amp_kstarzero_lass_amp_bar(double x, void* par);
|
||||
double gsl_mkpi_re_bw_kstar_amp_bar_kstarzero_lass_amp(double x, void* par);
|
||||
double gsl_mkpi_im_bw_kstar_amp_bar_kstarzero_lass_amp(double x, void* par);
|
||||
|
||||
double int_mkpi_bw_kstar_amp_squared(double mkpia, double mkpib, double qsquared, double gammakstar, double mkstar, double R);
|
||||
double int_mkpi_bw_kstar_amp_squared(double qsquared, double gammakstar, double mkstar, double R);
|
||||
double int_mkpi_kstarzero_lass_amp_squared(double mkpia, double mkpib, double qsquared, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R);
|
||||
double int_mkpi_kstarzero_lass_amp_squared(double qsquared, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R);
|
||||
|
||||
std::complex<double> int_mkpi_bw_kstar_amp_kstarzero_lass_amp_bar(double mkpia, double mkpib, double qsquared, double gammakstar, double mkstar, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R);
|
||||
std::complex<double> int_mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(double mkpia, double mkpib, double qsquared, double gammakstar, double mkstar, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R);
|
||||
std::complex<double> int_mkpi_bw_kstar_amp_kstarzero_lass_amp_bar(double qsquared, double gammakstar, double mkstar, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R);
|
||||
std::complex<double> int_mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(double qsquared, double gammakstar, double mkstar, double asphase, double a, double r, double gammakstarzero, double mkstarzero, double R);
|
||||
|
||||
double int_mkpi_kstarzero_isobar_amp_squared(double mkpia, double mkpib, double qsquared, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R);
|
||||
double int_mkpi_kstarzero_isobar_amp_squared(double qsquared, double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R);
|
||||
|
||||
std::complex<double> int_mkpi_bw_kstar_amp_kstarzero_isobar_amp_bar(double mkpia, double mkpib, double qsquared,
|
||||
double gammakstar, double mkstar, double asphase,
|
||||
double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R);
|
||||
std::complex<double> int_mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(double mkpia, double mkpib, double qsquared,
|
||||
double gammakstar, double mkstar, double asphase,
|
||||
double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R);
|
||||
std::complex<double> int_mkpi_bw_kstar_amp_kstarzero_isobar_amp_bar(double qsquared,
|
||||
double gammakstar, double mkstar, double asphase,
|
||||
double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R);
|
||||
std::complex<double> int_mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(double qsquared,
|
||||
double gammakstar, double mkstar, double asphase,
|
||||
double f800mag, double f800phase, double gammaf800, double mf800, double gammakstarzero, double mkstarzero, double R);
|
||||
|
||||
double rndgauss(TRandom3* rnd, double mean, double width, double min, double max);
|
||||
double rndgauss(TRandom3* rnd, double mean, double widthlo, double widthhi, double min, double max);
|
||||
|
||||
void moments_to_observables(TRandom3* rnd,
|
||||
std::vector<double> mom,
|
||||
std::vector<double> momcov,
|
||||
double fsext,
|
||||
double dfsext,
|
||||
std::vector<double>& obs,
|
||||
std::vector<double>& obscov,
|
||||
bool usefsext = true
|
||||
);
|
||||
|
||||
template<class T> struct NumberGreaterThan
|
||||
{
|
||||
bool operator()(const T a, const T b) const
|
||||
{ return std::abs(a) > std::abs(b); }
|
||||
};
|
||||
|
||||
template<typename iterator> typename iterator::value_type add_numbers(iterator begin, iterator end){
|
||||
typedef typename iterator::value_type T;
|
||||
if (end == begin) return 0.;
|
||||
std::make_heap(begin, end, NumberGreaterThan<T>());
|
||||
|
||||
for (; begin + 1 < end; ) {
|
||||
T x = *begin;
|
||||
std::pop_heap(begin, end--, NumberGreaterThan<T>());
|
||||
do {
|
||||
x += *begin;
|
||||
std::pop_heap(begin, end--, NumberGreaterThan<T>());
|
||||
} while (std::abs(*begin) >= std::abs(x) && begin < end);
|
||||
*end++ = x;
|
||||
std::push_heap(begin, end, NumberGreaterThan<T>());
|
||||
}
|
||||
return *begin;
|
||||
};
|
||||
|
||||
std::vector<UInt_t>GetNOutOfM(UInt_t N, UInt_t M, Int_t Seed, bool DoubleCounts, bool PoissonFluctuate);
|
||||
|
||||
template<typename iterator> typename iterator::value_type add_numbers(iterator begin, iterator end);
|
||||
|
||||
int throw_multivariate_normal(const unsigned int ndim, const unsigned int ntoys, const std::vector<double>& xi, const std::vector<double>& cov, std::vector<std::vector<double> >& results);
|
||||
int get_mean_cov(const std::vector<std::vector<double> >& meas, std::vector<double>& mean, std::vector<double>& cov);
|
||||
|
||||
void sis_to_pis(TRandom3* rnd,
|
||||
std::vector<double> sis,
|
||||
std::vector<double> sicorrs,
|
||||
std::vector<double>& pis,
|
||||
std::vector<double>& picorrs);
|
||||
|
||||
|
||||
std::complex<double> cErrF(const std::complex<double>& x);
|
||||
///implementation 2 of the complex error function
|
||||
std::complex<double> cErrF_2(const std::complex<double>& x);
|
||||
std::complex<double> ErrF_2(const std::complex<double>& x);
|
||||
|
||||
///implementation 3 of the complex error function
|
||||
std::complex<double> cErrF_3(const std::complex<double>& x);
|
||||
///the faddeeva function function
|
||||
std::complex<double> Faddeeva_2 (const std::complex<double>& z);
|
||||
///used by cErrF, does the actual calculations
|
||||
std::complex<double> wErrF(const std::complex<double>& arg);
|
||||
///This is another version of the complex error function, used in the newer cdf code
|
||||
std::complex<double> nwwerf(const std::complex<double> z);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
26
Code/FCNCFitter/sources/Core/generator.hh
Normal file
26
Code/FCNCFitter/sources/Core/generator.hh
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @file generator.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GENERATOR_H
|
||||
#define GENERATOR_H
|
||||
|
||||
#include <pdf.hh>
|
||||
#include <parameters.hh>
|
||||
|
||||
namespace fcnc {
|
||||
|
||||
///An abstract base class for toy monte carlo generators
|
||||
class generator {
|
||||
public:
|
||||
///generates nevents toy monte carlo events
|
||||
virtual std::vector<event> generate(unsigned int nevents, parameters* parameters, pdf* probability)=0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
574
Code/FCNCFitter/sources/Core/integrals.cc
Normal file
574
Code/FCNCFitter/sources/Core/integrals.cc
Normal file
@ -0,0 +1,574 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include "integrals.hh"
|
||||
|
||||
#include <Math/Vector4D.h>
|
||||
#include <Math/Boost.h>
|
||||
#include <Math/GSLIntegrator.h>
|
||||
|
||||
#include <spdlog.h>
|
||||
#include <funcs.hh>
|
||||
|
||||
#include <TMath.h>
|
||||
|
||||
double integral_x_to_n(double x, int n){
|
||||
return pow(x,n+1)/(n+1.0);
|
||||
}
|
||||
double integrate_x_to_n(double a, double b, int n){
|
||||
return integral_x_to_n(b,n) - integral_x_to_n(a,n);
|
||||
}
|
||||
|
||||
//this methods are helpful for the phi integration
|
||||
//calculates int x^n * sin(x) dx
|
||||
double integral_x_to_n_times_sin_x(double x, int n){
|
||||
assert(n >= 0);
|
||||
if (n == 0) return -cos(x);
|
||||
else return -pow(x, n)*cos(x) + n*integral_x_to_n_times_cos_x(x, n-1);
|
||||
}
|
||||
double integrate_x_to_n_times_sin_x(double a, double b, int n){
|
||||
return integral_x_to_n_times_sin_x(b, n) - integral_x_to_n_times_sin_x(a, n);
|
||||
}
|
||||
|
||||
//calculates int x^n * cos(x) dx (recursive using per partes)
|
||||
double integral_x_to_n_times_cos_x(double x, int n){
|
||||
assert(n >= 0);
|
||||
if (n == 0) return sin(x);
|
||||
else return pow(x,n)*sin(x) - n*integral_x_to_n_times_sin_x(x, n-1);
|
||||
}
|
||||
double integrate_x_to_n_times_cos_x(double a, double b, int n){
|
||||
return integral_x_to_n_times_cos_x(b, n)-integral_x_to_n_times_cos_x(a, n);
|
||||
}
|
||||
|
||||
//calculates int x^n * sin(2x) dx (recursive using per partes)
|
||||
double integral_x_to_n_times_sin_2x(double x, int n){
|
||||
assert(n >= 0);
|
||||
if (n == 0) return -0.5*cos(2.0*x);
|
||||
else return -pow(x,n)*0.5*cos(2.0*x)
|
||||
+0.5*n*integral_x_to_n_times_cos_2x(x,n-1);
|
||||
}
|
||||
double integrate_x_to_n_times_sin_2x(double a, double b, int n){
|
||||
return integral_x_to_n_times_sin_2x(b, n) - integral_x_to_n_times_sin_2x(a, n);
|
||||
}
|
||||
|
||||
//calculates int x^n * cos(2x) dx (recursive using per partes)
|
||||
double integral_x_to_n_times_cos_2x(double x, int n){
|
||||
assert(n >= 0);
|
||||
if (n == 0) return 0.5*sin(2.0*x);
|
||||
else return +0.5*pow(x,n)*sin(2.0*x)
|
||||
-0.5*n*integral_x_to_n_times_sin_2x(x,n-1);
|
||||
}
|
||||
double integrate_x_to_n_times_cos_2x(double a, double b, int n){
|
||||
return integral_x_to_n_times_cos_2x(b, n) - integral_x_to_n_times_cos_2x(a, n);
|
||||
}
|
||||
|
||||
//calculates int x^n * cos(x)^2 dx
|
||||
double integral_x_to_n_times_cos_x_2(double x, int n){
|
||||
assert(n >= 0);
|
||||
return +1.0/(1.0 + n)*pow(x,n+1)*cos(x)*cos(x)
|
||||
+1.0/(1.0+n)*integral_x_to_n_times_sin_2x(x, n+1);
|
||||
}
|
||||
|
||||
//calculates int x^n * sin(x)^2 dx
|
||||
double integral_x_to_n_times_sin_x_2(double x, int n){
|
||||
assert(n >= 0);
|
||||
return +1.0/(1.0 + n)*pow(x,n+1)*sin(x)*sin(x)
|
||||
-1.0/(1.0+n)*integral_x_to_n_times_sin_2x(x, n+1);
|
||||
}
|
||||
|
||||
//calculates int x^n * asin(x) dx
|
||||
double integral_x_to_n_times_asin_x(double x, int n){
|
||||
assert(n >= 0);
|
||||
if (n == 0){
|
||||
return x*asin(x)+sqrt(1-x*x);
|
||||
}
|
||||
else{
|
||||
// return 1.0/(n+1.0)*pow(x,n)*(x*asin(x)+sqrt(1-x*x))
|
||||
// -n*integral_x_to_n_times_sqrt_1_minus_x2(x, n-1);
|
||||
//factor 1/(n+1) missing???
|
||||
//fix below!
|
||||
return 1.0/(n+1.0)*pow(x,n)*(x*asin(x)+sqrt(1-x*x))
|
||||
-n/(n+1.0)*integral_x_to_n_times_sqrt_1_minus_x2(x, n-1);
|
||||
}
|
||||
}
|
||||
|
||||
//calculates int x^n * sqrt(1-x^2) dx (recursive using per partes)
|
||||
double integral_x_to_n_times_sqrt_1_minus_x2(double x, int n){
|
||||
assert(n >= 0);
|
||||
if (n == 0) return 0.5*asin(x)+0.5*x*sqrt(1-x*x);
|
||||
else return 2.0/(n+2.0)*pow(x, n)*(0.5*asin(x)+0.5*x*sqrt(1-x*x))-n/(n+2.0)*integral_x_to_n_times_asin_x(x, n-1);
|
||||
}
|
||||
|
||||
double integrate_x_to_n_times_sqrt_1_minus_x2(double a, double b, int n){
|
||||
return integral_x_to_n_times_sqrt_1_minus_x2(b, n)-integral_x_to_n_times_sqrt_1_minus_x2(a, n);
|
||||
}
|
||||
|
||||
double integral_chebyshev(double x, int n){
|
||||
assert(n >= 0);
|
||||
if (n == 0) return x;
|
||||
else if (n == 1) return 0.5*x*x;
|
||||
else return 0.5*(fcnc::chebyshev(x, n+1)/(n+1) - fcnc::chebyshev(x, n-1)/(n-1));
|
||||
}
|
||||
|
||||
double integrate_gauss(double sigma, double mean, double min, double max){
|
||||
return 0.5*(TMath::Erf((mean-min)/sqrt(2.0)/sigma) - TMath::Erf((mean-max)/sqrt(2.0)/sigma));
|
||||
}
|
||||
|
||||
double integrate_crystalball(double mean, double sigma, double alpha, double n, double min, double max){
|
||||
|
||||
//implementation taken from RooFit: https://root.cern.ch/doc/master/RooCBShape_8cxx_source.html#l00108
|
||||
|
||||
static const double sqrtPiOver2 = 1.2533141373;
|
||||
static const double sqrt2 = 1.4142135624;
|
||||
|
||||
double result = 0.0;
|
||||
bool useLog = false;
|
||||
|
||||
if( fabs(n-1.0) < 1.0e-05 )
|
||||
useLog = true;
|
||||
|
||||
double sig = fabs((Double_t)sigma);
|
||||
|
||||
//double tmin = (m.min(rangeName)-m0)/sig;
|
||||
//double tmax = (m.max(rangeName)-m0)/sig;
|
||||
double tmin = (min - mean ) / sigma;
|
||||
double tmax = (max - mean ) / sigma;
|
||||
|
||||
if(alpha < 0) {
|
||||
double tmp = tmin;
|
||||
tmin = -tmax;
|
||||
tmax = -tmp;
|
||||
}
|
||||
|
||||
double absAlpha = fabs(alpha);
|
||||
|
||||
if( tmin >= -absAlpha ) {
|
||||
result += sig*sqrtPiOver2*( TMath::Erf(tmax/sqrt2)
|
||||
- TMath::Erf(tmin/sqrt2) );
|
||||
}
|
||||
else if( tmax <= -absAlpha ) {
|
||||
double a = TMath::Power(n/absAlpha,n)*exp(-0.5*absAlpha*absAlpha);
|
||||
double b = n/absAlpha - absAlpha;
|
||||
|
||||
if(useLog) {
|
||||
result += a*sig*( log(b-tmin) - log(b-tmax) );
|
||||
}
|
||||
else {
|
||||
result += a*sig/(1.0-n)*( 1.0/(TMath::Power(b-tmin,n-1.0))
|
||||
- 1.0/(TMath::Power(b-tmax,n-1.0)) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
double a = TMath::Power(n/absAlpha,n)*exp(-0.5*absAlpha*absAlpha);
|
||||
double b = n/absAlpha - absAlpha;
|
||||
|
||||
double term1 = 0.0;
|
||||
if(useLog) {
|
||||
term1 = a*sig*( log(b-tmin) - log(n/absAlpha));
|
||||
}
|
||||
else {
|
||||
term1 = a*sig/(1.0-n)*( 1.0/(TMath::Power(b-tmin,n-1.0))
|
||||
- 1.0/(TMath::Power(n/absAlpha,n-1.0)) );
|
||||
}
|
||||
|
||||
double term2 = sig*sqrtPiOver2*( TMath::Erf(tmax/sqrt2)
|
||||
- TMath::Erf(-absAlpha/sqrt2) );
|
||||
|
||||
result += term1 + term2;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
double integrate_twotailedcrystalball(double mean, double sigma, double alpha1, double alpha2, double n1, double n2, double min, double max){
|
||||
|
||||
double central = 0.0;
|
||||
double left = 0.0;
|
||||
double right = 0.0;
|
||||
double result = 0.0;
|
||||
|
||||
assert(alpha1 > 0.0);
|
||||
assert(alpha2 > 0.0);
|
||||
|
||||
//implementation taken from RooFit: RooDoubleCB.cxx
|
||||
|
||||
static const double rootPiBy2 = sqrt(atan2(0.0,-1.0)/2.0);
|
||||
static const double invRoot2 = 1.0/sqrt(2);
|
||||
|
||||
double invwidth = 1.0/sigma;
|
||||
|
||||
double tmin = (min-mean)*invwidth;
|
||||
double tmax = (max-mean)*invwidth;
|
||||
//spdlog::trace("tmin: {0:f}\t tmax: {0:f} ",tmin, tmax);
|
||||
|
||||
bool isfullrange = (tmin<-1000. && tmax>1000.);
|
||||
|
||||
//compute gaussian (central) contribution
|
||||
double central_low = std::max(min, mean - alpha1*sigma);
|
||||
double central_high = std::min(max, mean + alpha2*sigma);
|
||||
|
||||
double tcentral_low = (central_low-mean)*invwidth;
|
||||
double tcentral_high = (central_high-mean)*invwidth;
|
||||
|
||||
//spdlog::trace("central_low: {0:f}\t central_high: {0:f} ",central_low, central_high);
|
||||
//spdlog::trace("tcentral_low: {0:f}\t tcentral_high: {0:f} ",tcentral_low, tcentral_high);
|
||||
|
||||
if(central_low < central_high){// is the gaussian part in range?
|
||||
central = rootPiBy2*sigma*(TMath::Erf(tcentral_high*invRoot2)-TMath::Erf(tcentral_low*invRoot2));
|
||||
}
|
||||
|
||||
//compute left tail;
|
||||
if(isfullrange && (n1-1.0)>1.e-3) {
|
||||
left = sigma*TMath::Exp(-0.5*alpha1*alpha1)*n1/(alpha1*(n1-1.));
|
||||
spdlog::trace("left: {0:f}", left);
|
||||
}
|
||||
else{
|
||||
double left_low = min;
|
||||
double left_high = std::min(max, mean - alpha1*sigma);
|
||||
double thigh = (left_high-mean)*invwidth;
|
||||
|
||||
if(left_low < left_high){ //is the left tail in range?
|
||||
double n1invalpha1 = n1/(fabs(alpha1));
|
||||
if(fabs(n1-1.0)>1.e-3){
|
||||
double invn1m1 = 1/(n1-1.);
|
||||
double leftpow = TMath::Power(n1invalpha1,-n1*invn1m1);
|
||||
assert(leftpow > 0.0);
|
||||
double left0 = sigma*TMath::Exp(-0.5*alpha1*alpha1)*invn1m1;
|
||||
double left1, left2;
|
||||
|
||||
if(max > (mean-alpha1*sigma))
|
||||
left1 = n1invalpha1;
|
||||
else
|
||||
left1 = TMath::Power( leftpow*(n1invalpha1 - alpha1 - thigh), 1.-n1);
|
||||
|
||||
if(tmin<-1000.)
|
||||
left2 = 0.;
|
||||
else
|
||||
left2 = TMath::Power( leftpow*(n1invalpha1 - alpha1 - tmin ), 1.-n1);
|
||||
|
||||
left = left0*(left1-left2);
|
||||
}
|
||||
else{
|
||||
double A1 = TMath::Power(n1invalpha1,n1)*TMath::Exp(-0.5*alpha1*alpha1);
|
||||
double B1 = n1invalpha1-fabs(alpha1);
|
||||
left = A1*sigma*(TMath::Log(B1-(left_low-mean)*invwidth) - TMath::Log(B1-(left_high-mean)*invwidth) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//compute right tail;
|
||||
if(isfullrange && (n2-1.0)>1.e-3) {
|
||||
right = sigma*TMath::Exp(-0.5*alpha2*alpha2)*n2/(alpha2*(n2-1.));
|
||||
}
|
||||
else{
|
||||
double right_low = std::max(min,mean + alpha2*sigma);
|
||||
double right_high = max;
|
||||
double tlow = (right_low - mean)*invwidth;
|
||||
|
||||
if(right_low < right_high){ //is the right tail in range?
|
||||
double n2invalpha2 = n2/(fabs(alpha2));
|
||||
if(fabs(n2-1.0)>1.e-3) {
|
||||
double invn2m2 = 1.0/(n2-1.);
|
||||
double rightpow = TMath::Power(n2invalpha2,-n2*invn2m2);
|
||||
if (rightpow <= 0.0){
|
||||
spdlog::error("rightpow < 0.0! Returning NaN");
|
||||
spdlog::error("TMath::Power(n2invalpha2,-n2*invn2m2) = {0:.30f}",powl(n2/(fabs(alpha2)),-n2*1.0/(n2-1.)));
|
||||
spdlog::error("n2invalpha2: {0:f}\tn2: {1:f}\tinvn2m2: {2:f}",n2invalpha2,n2,invn2m2);
|
||||
spdlog::error("mean: {0:f}\tsigma: {1:f}\talpha1: {2:f}\talpha2: {3:f}\tn1: {4:f}\tn2: {5:f}\tmin: {6:f}\tmax: {7:f}", mean, sigma, alpha1, alpha2, n1, n2, min, max);
|
||||
return nan("");
|
||||
}
|
||||
double right0 = sigma*TMath::Exp(-0.5*alpha2*alpha2)*invn2m2;
|
||||
double right1, right2;
|
||||
|
||||
if(min<(mean+alpha2*sigma)) right1 = n2invalpha2;
|
||||
else right1 = TMath::Power( rightpow*(n2invalpha2 - alpha2 + tlow), 1.-n2);
|
||||
|
||||
if(tmax>1000.) right2 = 0.;
|
||||
else right2 = TMath::Power( rightpow*(n2invalpha2 - alpha2 + tmax), 1.-n2);
|
||||
|
||||
right = right0*(right1-right2);
|
||||
}
|
||||
else{
|
||||
double A2 = TMath::Power(n2invalpha2,n2)*TMath::Exp(-0.5*alpha2*alpha2);
|
||||
double B2 = n2invalpha2-fabs(alpha2);
|
||||
right = A2*sigma*(TMath::Log(B2+(right_high-mean)*invwidth) - TMath::Log(B2+(right_low-mean)*invwidth) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = left + central + right;
|
||||
|
||||
if(result <= 0.0){
|
||||
spdlog::error("left = {0:e}",left);
|
||||
spdlog::error("central = {0:e}",central);
|
||||
spdlog::error("right = {0:e}", right);
|
||||
spdlog::error("sigma = {0:e}", sigma);
|
||||
spdlog::error("n1 = {0:e}", n1);
|
||||
spdlog::error("n2 = {0:e}", n2);
|
||||
spdlog::error("alpha1 = {0:e}", alpha1);
|
||||
spdlog::error("alpha1 = {0:e}", alpha2);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if(std::isnan(result) || std::isinf(result)){
|
||||
spdlog::critical("Determination of twotailed CB integral failed: {0:f}", result);
|
||||
spdlog::critical("mean: {1:f}\tsigma: {2:f}\talpha1: {3:f}\talpha2: {4:f}\tn1: {5:f}\tn2: {6:f}", mean, sigma, alpha1, alpha2, n1, n2);
|
||||
spdlog::critical("left: {0:f}\tcentral: {1:f}\tright: {2:f}", left, central, right);
|
||||
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double integral_x_to_n_times_exp_minus_x(double x, double tau, int n){
|
||||
assert(n>=0);
|
||||
if (n == 0) return -tau*exp(-x/tau);
|
||||
else return pow(x, n)*(-tau*exp(-x/tau)) + n * tau * integral_x_to_n_times_exp_minus_x(x, tau, n-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------
|
||||
// P wave
|
||||
//-----------------------
|
||||
|
||||
//THESE FUNCTIONS NEED TO BE CHECKED
|
||||
//i correspons to ctl, j to ctk and k to phi
|
||||
|
||||
|
||||
//int[ sin^2(tk) ] for J1s
|
||||
double integral_f1(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin^2 d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return (integral_x_to_n(ctk,n_ctk)-integral_x_to_n(ctk,n_ctk+2))
|
||||
*integral_x_to_n(ctl,n_ctl)
|
||||
*integral_x_to_n(phi,n_phi);
|
||||
}
|
||||
double integrate_f1(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
return (integrate_x_to_n(ctk_a, ctk_b, n_ctk)-integrate_x_to_n(ctk_a,ctk_b,n_ctk+2))
|
||||
*integrate_x_to_n(ctl_a, ctl_b, n_ctl)
|
||||
*integrate_x_to_n(phi_a, phi_b, n_phi);
|
||||
}
|
||||
|
||||
//int[ cos^2(tk) ] for J1c
|
||||
double integral_f2(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate cos^2 thetak d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return integral_x_to_n(ctk,n_ctk+2)
|
||||
*integral_x_to_n(ctl,n_ctl)
|
||||
*integral_x_to_n(phi,n_phi);
|
||||
}
|
||||
double integrate_f2(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
return integrate_x_to_n(ctk_a, ctk_b, n_ctk+2)
|
||||
*integrate_x_to_n(ctl_a, ctl_b, n_ctl)
|
||||
*integrate_x_to_n(phi_a, phi_b, n_phi);
|
||||
}
|
||||
|
||||
//int[ sin^2(tk) * cos(2tl) ] for J2s
|
||||
double integral_f3(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin^2 thetak cos 2thetal d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return (integral_x_to_n(ctk,n_ctk)-integral_x_to_n(ctk,n_ctk+2))
|
||||
*(2*integral_x_to_n(ctl,n_ctl+2)-integral_x_to_n(ctl,n_ctl)) //cos(2x) = 2*cos^2(x)-1
|
||||
*integral_x_to_n(phi,n_phi);
|
||||
}
|
||||
double integrate_f3(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
return (integrate_x_to_n(ctk_a, ctk_b, n_ctk)-integrate_x_to_n(ctk_a, ctk_b, n_ctk+2))
|
||||
*(2*integrate_x_to_n(ctl_a, ctl_b, n_ctl+2)-integrate_x_to_n(ctl_a, ctl_b, n_ctl)) //cos(2x) = 2*cos^2(x)-1
|
||||
*integrate_x_to_n(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
//int[ cos^2(tk) * cos(2tl) ] for J2c
|
||||
double integral_f4(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate cos^2 thetak cos 2thetal d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return integral_x_to_n(ctk,n_ctk+2)
|
||||
*(2*integral_x_to_n(ctl,n_ctl+2)-integral_x_to_n(ctl,n_ctl))
|
||||
*integral_x_to_n(phi,n_phi);
|
||||
}
|
||||
double integrate_f4(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate cos^2 thetak cos 2thetal d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return integrate_x_to_n(ctk_a, ctk_b, n_ctk+2)
|
||||
*(2*integrate_x_to_n(ctl_a, ctl_b, n_ctl+2)-integrate_x_to_n(ctl_a, ctl_b, n_ctl))
|
||||
*integrate_x_to_n(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
//int[ sin^2(tk) * sin^2(tl) * cos(2phi) ] for J3
|
||||
double integral_f5(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin^2 thetak sin^2 thetal cos 2phi d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return (integral_x_to_n(ctk,n_ctk)-integral_x_to_n(ctk,n_ctk+2))
|
||||
*(integral_x_to_n(ctl,n_ctl)-integral_x_to_n(ctl,n_ctl+2))
|
||||
*(integral_x_to_n_times_cos_2x(phi,n_phi));
|
||||
}
|
||||
double integrate_f5(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin^2 thetak sin^2 thetal cos 2phi d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return (integrate_x_to_n(ctk_a, ctk_b, n_ctk)-integrate_x_to_n(ctk_a, ctk_b, n_ctk+2))
|
||||
*(integrate_x_to_n(ctl_a, ctl_b, n_ctl)-integrate_x_to_n(ctl_a, ctl_b, n_ctl+2))
|
||||
*(integrate_x_to_n_times_cos_2x(phi_a,phi_b,n_phi));
|
||||
}
|
||||
|
||||
//int[ sin(2tk) * sin(2tl) * cos(phi) ] for J4
|
||||
double integral_f6(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin 2thetak sin 2thetal cos phi d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return 2*integral_x_to_n_times_sqrt_1_minus_x2(ctk,n_ctk+1)
|
||||
*2*integral_x_to_n_times_sqrt_1_minus_x2(ctl,n_ctl+1)
|
||||
*integral_x_to_n_times_cos_x(phi,n_phi);
|
||||
}
|
||||
double integrate_f6(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin 2thetak sin 2thetal cos phi d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return 2*integrate_x_to_n_times_sqrt_1_minus_x2(ctk_a, ctk_b, n_ctk+1)
|
||||
*2*integrate_x_to_n_times_sqrt_1_minus_x2(ctl_a, ctl_b,n_ctl+1)
|
||||
*integrate_x_to_n_times_cos_x(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
//int [ sin(2tk) * sin(tl) * cos(phi) ] for J5
|
||||
double integral_f7(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin 2thetak sin thetal cos phi d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return 2*integral_x_to_n_times_sqrt_1_minus_x2(ctk,n_ctk+1)
|
||||
*integral_x_to_n_times_sqrt_1_minus_x2(ctl,n_ctl)
|
||||
*integral_x_to_n_times_cos_x(phi,n_phi);
|
||||
}
|
||||
double integrate_f7(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin 2thetak sin thetal cos phi d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return 2*integrate_x_to_n_times_sqrt_1_minus_x2(ctk_a, ctk_b, n_ctk+1)
|
||||
*integrate_x_to_n_times_sqrt_1_minus_x2(ctl_a, ctl_b,n_ctl)
|
||||
*integrate_x_to_n_times_cos_x(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
//int [ sin^2(tk) * cos(tl) ] for J6s
|
||||
double integral_f8(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin^2 thetak cos thetal d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return (integral_x_to_n(ctk,n_ctk)-integral_x_to_n(ctk,n_ctk+2))
|
||||
*integral_x_to_n(ctl,n_ctl+1)
|
||||
*integral_x_to_n(phi,n_phi);
|
||||
}
|
||||
double integrate_f8(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin^2 thetak cos thetal d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return (integrate_x_to_n(ctk_a, ctk_b, n_ctk)-integrate_x_to_n(ctk_a, ctk_b, n_ctk+2))
|
||||
*integrate_x_to_n(ctl_a, ctl_b,n_ctl+1)
|
||||
*integrate_x_to_n(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
//int [ cos^2(tk) * cos(tl) ] for J6c
|
||||
double integral_f9(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin^2 thetak cos thetal d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return integral_x_to_n(ctk,n_ctk+2)
|
||||
*integral_x_to_n(ctl,n_ctl+1)
|
||||
*integral_x_to_n(phi,n_phi);
|
||||
}
|
||||
double integrate_f9(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin^2 thetak cos thetal d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return integrate_x_to_n(ctk_a, ctk_b, n_ctk+2)
|
||||
*integrate_x_to_n(ctl_a, ctl_b,n_ctl+1)
|
||||
*integrate_x_to_n(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
//int [ sin(2tk) * sin(tl) * sin(phi) ] for J7
|
||||
double integral_f10(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin 2thetak sin thetal sin phi d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return 2*integral_x_to_n_times_sqrt_1_minus_x2(ctk,n_ctk+1)
|
||||
*integral_x_to_n_times_sqrt_1_minus_x2(ctl,n_ctl+1)
|
||||
*integral_x_to_n_times_sin_x(phi,n_phi);
|
||||
}
|
||||
double integrate_f10(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin 2thetak sin thetal sin phi d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return 2*integrate_x_to_n_times_sqrt_1_minus_x2(ctk_a, ctk_b, n_ctk+1)
|
||||
*integrate_x_to_n_times_sqrt_1_minus_x2(ctl_a, ctl_b,n_ctl+1)
|
||||
*integrate_x_to_n_times_sin_x(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
//int [ sin(2tk) * sin(2tl) * sin(phi) ] for J8
|
||||
double integral_f11(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin 2thetak sin 2thetal sin phi d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return 2*integral_x_to_n_times_sqrt_1_minus_x2(ctk,n_ctk+1)
|
||||
*2*integral_x_to_n_times_sqrt_1_minus_x2(ctl,n_ctl+1)
|
||||
*integral_x_to_n_times_sin_x(phi,n_phi);
|
||||
}
|
||||
double integrate_f11(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin 2thetak sin 2thetal sin phi d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return 2*integrate_x_to_n_times_sqrt_1_minus_x2(ctk_a, ctk_b,n_ctk+1)
|
||||
*2*integrate_x_to_n_times_sqrt_1_minus_x2(ctl_a, ctl_b,n_ctl+1)
|
||||
*integrate_x_to_n_times_sin_x(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
//int [ sin^2(tk) * sin^2(tl) * sin(2phi) ] for J9
|
||||
double integral_f12(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin^2 thetak sin^2 thetal sin 2phi d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return (integral_x_to_n(ctk,n_ctk)-integral_x_to_n(ctk,n_ctk+2))
|
||||
*(integral_x_to_n(ctl,n_ctl)-integral_x_to_n(ctl,n_ctl+2))
|
||||
*(integral_x_to_n_times_sin_2x(phi,n_phi));
|
||||
}
|
||||
double integrate_f12(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
//Integrate sin^2 thetak sin^2 thetal sin 2phi d costhetak d costhetal d phi times ctk^n1+ctl^n2*phi^n3
|
||||
return (integrate_x_to_n(ctk_a, ctk_b,n_ctk)-integrate_x_to_n(ctk_a, ctk_b,n_ctk+2))
|
||||
*(integrate_x_to_n(ctl_a, ctl_b,n_ctl)-integrate_x_to_n(ctl_a, ctl_b,n_ctl+2))
|
||||
*(integrate_x_to_n_times_sin_2x(phi_a,phi_b,n_phi));
|
||||
}
|
||||
|
||||
//-----------------------
|
||||
// S wave
|
||||
//-----------------------
|
||||
|
||||
double integral_s_f1(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
return (integral_x_to_n(ctl,n_ctl)-integral_x_to_n(ctl,n_ctl+2))
|
||||
*integral_x_to_n(ctk,n_ctk)
|
||||
*integral_x_to_n(phi, n_phi);
|
||||
}
|
||||
double integrate_s_f1(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
return (integrate_x_to_n(ctl_a,ctl_b,n_ctl)-integrate_x_to_n(ctl_a,ctl_b,n_ctl+2))
|
||||
*integrate_x_to_n(ctk_a,ctk_b,n_ctk)
|
||||
*integrate_x_to_n(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
double integral_s_f2(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
return (integral_x_to_n(ctl,n_ctl)-integral_x_to_n(ctl,n_ctl+2))
|
||||
*integral_x_to_n(ctk,n_ctk+1)
|
||||
*integral_x_to_n(phi, n_phi);
|
||||
}
|
||||
double integrate_s_f2(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
return (integrate_x_to_n(ctl_a,ctl_b,n_ctl)-integrate_x_to_n(ctl_a,ctl_b,n_ctl+2))
|
||||
*integrate_x_to_n(ctk_a,ctk_b,n_ctk+1)
|
||||
*integrate_x_to_n(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
double integral_s_f3(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
return 2*integral_x_to_n_times_sqrt_1_minus_x2(ctl,n_ctl+1)
|
||||
*integral_x_to_n_times_sqrt_1_minus_x2(ctk,n_ctk)
|
||||
*integral_x_to_n_times_cos_x(phi, n_phi);
|
||||
}
|
||||
double integrate_s_f3(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
return 2*integrate_x_to_n_times_sqrt_1_minus_x2(ctl_a,ctl_b,n_ctl+1)
|
||||
*integrate_x_to_n_times_sqrt_1_minus_x2(ctk_a,ctk_b,n_ctk)
|
||||
*integrate_x_to_n_times_cos_x(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
double integral_s_f4(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
return integral_x_to_n_times_sqrt_1_minus_x2(ctl,n_ctl)
|
||||
*integral_x_to_n_times_sqrt_1_minus_x2(ctk,n_ctk)
|
||||
*integral_x_to_n_times_cos_x(phi, n_phi);
|
||||
}
|
||||
double integrate_s_f4(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
return integrate_x_to_n_times_sqrt_1_minus_x2(ctl_a,ctl_b,n_ctl)
|
||||
*integrate_x_to_n_times_sqrt_1_minus_x2(ctk_a,ctk_b,n_ctk)
|
||||
*integrate_x_to_n_times_cos_x(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
double integral_s_f5(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
return integral_x_to_n_times_sqrt_1_minus_x2(ctl,n_ctl)
|
||||
*integral_x_to_n_times_sqrt_1_minus_x2(ctk,n_ctk)
|
||||
*integral_x_to_n_times_sin_x(phi, n_phi);
|
||||
}
|
||||
double integrate_s_f5(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
return integrate_x_to_n_times_sqrt_1_minus_x2(ctl_a,ctl_b,n_ctl)
|
||||
*integrate_x_to_n_times_sqrt_1_minus_x2(ctk_a,ctk_b,n_ctk)
|
||||
*integrate_x_to_n_times_sin_x(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
||||
double integral_s_f6(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi){
|
||||
return 2*integral_x_to_n_times_sqrt_1_minus_x2(ctl,n_ctl+1)
|
||||
*integral_x_to_n_times_sqrt_1_minus_x2(ctk,n_ctk)
|
||||
*integral_x_to_n_times_sin_x(phi, n_phi);
|
||||
}
|
||||
double integrate_s_f6(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi){
|
||||
return 2*integrate_x_to_n_times_sqrt_1_minus_x2(ctl_a,ctl_b,n_ctl+1)
|
||||
*integrate_x_to_n_times_sqrt_1_minus_x2(ctk_a,ctk_b,n_ctk)
|
||||
*integrate_x_to_n_times_sin_x(phi_a,phi_b,n_phi);
|
||||
}
|
||||
|
108
Code/FCNCFitter/sources/Core/integrals.hh
Normal file
108
Code/FCNCFitter/sources/Core/integrals.hh
Normal file
@ -0,0 +1,108 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef INTEGRALS_HH
|
||||
#define INTEGRALS_HH
|
||||
|
||||
double integral_x_to_n(double x, int n);
|
||||
double integrate_x_to_n(double a, double b, int n);
|
||||
|
||||
//this methods are helpful for the phi integration
|
||||
//calculates int x^n * sin(x) dx
|
||||
double integral_x_to_n_times_sin_x(double x, int n);
|
||||
double integrate_x_to_n_times_sin_x(double a, double b, int n);
|
||||
|
||||
//calculates int x^n * cos(x) dx
|
||||
double integral_x_to_n_times_cos_x(double x, int n);
|
||||
double integrate_x_to_n_times_cos_x(double a, double b, int n);
|
||||
|
||||
//calculates int x^n * sin(2x) dx
|
||||
double integral_x_to_n_times_sin_2x(double x, int n);
|
||||
double integrate_x_to_n_times_sin_2x(double a, double b, int n);
|
||||
|
||||
//calculates int x^n * cos(2x) dx
|
||||
double integral_x_to_n_times_cos_2x(double x, int n);
|
||||
double integrate_x_to_n_times_cos_2x(double a, double b, int n);
|
||||
|
||||
//calculates int x^n * cos(x)^2 dx
|
||||
double integral_x_to_n_times_cos_x_2(double x, int n);
|
||||
|
||||
//calculates int x^n * sin(x)^2 dx
|
||||
double integral_x_to_n_times_sin_x_2(double x, int n);
|
||||
|
||||
//calculates int x^n * asin(x) dx
|
||||
double integral_x_to_n_times_asin_x(double x, int n);
|
||||
//calculates int x^n * sqrt(1-x^2) dx
|
||||
double integral_x_to_n_times_sqrt_1_minus_x2(double x, int n);
|
||||
|
||||
double integrate_x_to_n_times_sqrt_1_minus_x2(double a, double b, int n);
|
||||
|
||||
double integral_chebyshev(double x, int n);
|
||||
double integrate_gauss(double sigma, double mean, double min, double max);
|
||||
|
||||
double integrate_crystalball(double mean, double sigma, double alpha, double n, double min, double max);
|
||||
|
||||
double integrate_twotailedcrystalball(double mean, double sigma, double alpha1, double alpha2, double n1, double n2, double min, double max);
|
||||
|
||||
double integral_x_to_n_times_exp_minus_x(double x, double tau, int n);
|
||||
//THESE FUNCTIONS NEED TO BE CHECKED
|
||||
//i correspons to ctl, j to ctk and k to phi
|
||||
double integral_f1(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_f1(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_f2(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_f2(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_f3(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_f3(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_f4(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_f4(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_f5(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_f5(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_f6(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_f6(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_f7(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_f7(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_f8(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_f8(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_f9(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_f9(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_f10(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_f10(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_f11(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_f11(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_f12(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_f12(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
|
||||
///////////////////
|
||||
// sWave //
|
||||
///////////////////
|
||||
|
||||
double integral_s_f1(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_s_f1(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_s_f2(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_s_f2(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_s_f3(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_s_f3(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_s_f4(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_s_f4(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_s_f5(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_s_f5(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
double integral_s_f6(double ctl, double ctk, double phi, int n_ctl, int n_ctk, int n_phi);
|
||||
double integrate_s_f6(double ctl_a, double ctl_b, double ctk_a, double ctk_b, double phi_a, double phi_b, int n_ctl, int n_ctk, int n_phi);
|
||||
|
||||
#endif // INTEGRALS_HH
|
224
Code/FCNCFitter/sources/Core/options.cc
Normal file
224
Code/FCNCFitter/sources/Core/options.cc
Normal file
@ -0,0 +1,224 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <options.hh>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <assert.h>
|
||||
|
||||
#include <TStyle.h>
|
||||
#include <TMath.h>
|
||||
#include <spdlog.h>
|
||||
//https://github.com/gabime/spdlog
|
||||
#include <helpers.hh>
|
||||
|
||||
///Try to extract a number from the name (option given on command line)
|
||||
int fcnc::options::get_job_id() {
|
||||
return job_id;
|
||||
};
|
||||
|
||||
//reset the ranges of all three angles back to full_angular configuration
|
||||
void fcnc::options::reset_angle_ranges(){
|
||||
ctl_min = CTK_MIN;
|
||||
ctl_max = CTL_MAX;
|
||||
ctk_min = CTK_MIN;
|
||||
ctk_max = CTK_MAX;
|
||||
phi_min = PHI_MIN;
|
||||
phi_max = PHI_MAX;
|
||||
|
||||
//spdlog::debug( "Reset angles: ctl=[ {0:0.2f} - {1:0.2f}]", ctl_min ,ctl_max);
|
||||
//spdlog::debug( "Reset angles: ctk=[ {0:0.2f} - {1:0.2f}]", ctk_min ,ctk_max);
|
||||
//spdlog::debug( "Reset angles: phi=[ {0:0.2f} - {1:0.2f}]", phi_min ,phi_max);
|
||||
}
|
||||
|
||||
bool fcnc::options::canIFold(){
|
||||
//Check the ranges of the angles, if the ranges are smaller than the full ones, do not perform folding
|
||||
if (folding == -1) return true;
|
||||
if (PHI_MIN != -1.0*TMath::Pi() || PHI_MAX != 1.0*TMath::Pi()) return false;
|
||||
if (folding > 1 && (CTL_MIN != -1.0 || CTL_MAX != 1.0)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void fcnc::options::update_angle_ranges(){
|
||||
reset_angle_ranges();
|
||||
if(full_angular || folding == -1)return;
|
||||
//Check the ranges of the angles, if the ranges are smaller than the full ones, do not perform folding
|
||||
if (!canIFold()){
|
||||
spdlog::warn("Range of the angles is assymetric, cannot perform update of folded angle ranges!");
|
||||
return;
|
||||
}
|
||||
switch(folding){
|
||||
case 0:
|
||||
phi_min = 0.;
|
||||
break;
|
||||
case 1:
|
||||
phi_min = 0.;
|
||||
ctl_min = 0.;
|
||||
break;
|
||||
case 2:
|
||||
phi_min = 0.;
|
||||
ctl_min = 0.;
|
||||
break;
|
||||
case 3:
|
||||
phi_min = -MY_PI/2.;
|
||||
phi_max = +MY_PI/2.;
|
||||
ctl_min = 0.;
|
||||
break;
|
||||
case 4:
|
||||
phi_min = -MY_PI/2.;
|
||||
phi_max = +MY_PI/2.;
|
||||
ctl_min = 0.;
|
||||
ctk_max = std::min(fabs(CTK_MIN), fabs(CTK_MAX)); //Take smaller value from abs(max), abs(min) = M
|
||||
ctk_min = -ctk_max; //And take range (-M,M)
|
||||
break;
|
||||
}
|
||||
|
||||
spdlog::debug( "Update angles: ctl=[{0:0.2f} - {1:0.2f}]", ctl_min ,ctl_max);
|
||||
spdlog::debug( "Update angles: ctk=[{0:0.2f} - {1:0.2f}]", ctk_min ,ctk_max);
|
||||
spdlog::debug( "Update angles: phi=[{0:0.2f} - {1:0.2f}]", phi_min ,phi_max);
|
||||
|
||||
}
|
||||
///This method prints the used options.
|
||||
|
||||
void fcnc::options::print(){
|
||||
spdlog::info( "Options:");
|
||||
spdlog::info( "Number of threads:\t\t {0:d}", ncores);
|
||||
spdlog::info( "Use angular acceptance: " + boolToString(use_angular_acc));
|
||||
spdlog::info( "Fit angular corr. coefficients "+ boolToString(angularacceptance));
|
||||
spdlog::info( "Do projections: "+ boolToString(project));
|
||||
spdlog::info( "Write eps files: "+ boolToString(write_eps));
|
||||
spdlog::info( "Write C files: "+ boolToString(write_C));
|
||||
spdlog::info( "Load only truthmatched: "+ boolToString(only_truthmatched));
|
||||
spdlog::info( "Use only true quantities: "+ boolToString(use_truth));
|
||||
spdlog::info( "Shift likelihood: "+ boolToString(shift_lh));
|
||||
spdlog::info( "Repeat on error: "+ boolToString(repeat_on_fail));
|
||||
spdlog::info( "Use asymmetric Minos errors: "+ boolToString(minos_errors));
|
||||
spdlog::info( "Run Simplex before Migrad: "+ boolToString(simplex_prerun));
|
||||
spdlog::info( "Run Hesse after Migrad: "+ boolToString(hesse_postrun));
|
||||
spdlog::info( "Perform weighted fit: "+ boolToString(weighted_fit));
|
||||
spdlog::info( "Verbosity: "+ spdlog::default_logger_raw()->level());
|
||||
spdlog::info( "Static seed: "+ boolToString(static_seed));
|
||||
spdlog::info( "Always static seed: "+ boolToString(always_static_seed));
|
||||
spdlog::info( "Refit the same data set: "+ boolToString(refitting_nominal));
|
||||
}
|
||||
|
||||
std::vector<std::string> fcnc::options::getAllPlotTypes(){
|
||||
std::vector<std::string> ext;
|
||||
if (write_C) ext.push_back("C");
|
||||
if (write_eps) ext.push_back("eps");
|
||||
if (write_jpg) ext.push_back("jpg");
|
||||
if (write_pdf) ext.push_back("pdf");
|
||||
return ext;
|
||||
}
|
||||
|
||||
|
||||
//Get the number of Q2 bins from the lenght of ThQ2binsmin vector
|
||||
unsigned int fcnc::options::get_nQ2bins(){
|
||||
return TheQ2binsmin.size();
|
||||
}
|
||||
//////////////////////////////
|
||||
// Set systematics options //
|
||||
//////////////////////////////
|
||||
|
||||
void which_systematics( fcnc::options opts, int job_id){
|
||||
|
||||
if(opts.systematic == 1){
|
||||
spdlog::info( "Run systematic study #1: BOOTSTRAPPING of PHSP MC");
|
||||
opts.write_eps = job_id == -1;
|
||||
}
|
||||
if(opts.systematic == 2){
|
||||
spdlog::info( "Run systematic study #2: Forced symmetric acceptance correction in cos(Theta_L)");
|
||||
opts.write_eps = false;
|
||||
}
|
||||
opts.orderincrease = 2;
|
||||
if(opts.systematic == 3){
|
||||
spdlog::info( "Run systematic study #3: Increase of Legendre order of PHSP MC parametrization");
|
||||
opts.eff_order_costhetal += opts.orderincrease;
|
||||
opts.eff_order_costhetak += opts.orderincrease;
|
||||
opts.eff_order_phi += opts.orderincrease;
|
||||
opts.eff_order_q2 += opts.orderincrease;
|
||||
}
|
||||
if(opts.systematic == 4){
|
||||
spdlog::info( "Run systematic study #4: Vary PHSP MC reweights within their uncertainty");
|
||||
opts.write_eps = false;
|
||||
}
|
||||
if(opts.systematic == 5){
|
||||
spdlog::info( "Run systematic study #5: Vary S-wave fraction FS in q2bin within its uncertainty");
|
||||
opts.write_eps = false;
|
||||
}
|
||||
if(opts.systematic == 6){
|
||||
spdlog::info( "Run systematic study #6: Vary angles (ctk, ctl and phi) within the angular resoluation");
|
||||
opts.write_eps = false;
|
||||
}
|
||||
if(opts.systematic == 7){
|
||||
spdlog::info( "Run systematic study #7: Generate toy events with double-gaussian profile and fit with CB");
|
||||
opts.write_eps = false;
|
||||
}
|
||||
if(opts.systematic == 8){
|
||||
spdlog::info( "Run systematic study #8: Systematic study on angular background model");
|
||||
opts.write_eps = false;
|
||||
}
|
||||
if(opts.systematic == 9){
|
||||
spdlog::info( "Run systematic study #9: Investigate systematic effects due to trigger selection");
|
||||
opts.write_eps = false;
|
||||
}
|
||||
if(opts.systematic == 10){
|
||||
spdlog::info( "Run systematic study #10: Reweight the PHSP MC according to discrepancy in Kshort PT distributions for DD tracks");
|
||||
opts.write_eps = false;
|
||||
}
|
||||
if(opts.systematic == 11){
|
||||
spdlog::info( "Run systematic study #11: Remove a gaussian shaped hole in the upper mass sideband of the background to mimic the B0 veto");
|
||||
opts.write_eps = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::string> get_observables_vec (fcnc::options opts){
|
||||
std::vector<std::string> obs;
|
||||
if(opts.fit_fl) obs.push_back("Fl");
|
||||
else obs.push_back("S1s");
|
||||
|
||||
obs.push_back("S3");
|
||||
|
||||
if(opts.full_angular || opts.folding == 1) obs.push_back("S4");
|
||||
if(opts.full_angular || opts.folding == 2) obs.push_back("S5");
|
||||
if(opts.full_angular || opts.folding == 0){
|
||||
if(opts.fit_afb) obs.push_back("Afb");
|
||||
else obs.push_back("S6s");
|
||||
}
|
||||
if(opts.full_angular || opts.folding == 3) obs.push_back("S7");
|
||||
if(opts.full_angular || opts.folding == 4) obs.push_back("S8");
|
||||
if(opts.full_angular || opts.folding == 0) obs.push_back("S9");
|
||||
return obs;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void set_ang_year_options(fcnc::options &opts){
|
||||
//Takes care of setting the year/run options for angular corrections
|
||||
|
||||
//use data from run 1 and run 2 combined
|
||||
opts.angacccorrbothruns = (opts.run == 12);
|
||||
//use 2015+2016 or 2017+2018
|
||||
opts.angacccorrpertwoyears = (opts.run == 21 || opts.run == 22);
|
||||
//If run/two years are used, turn off the per-year correction
|
||||
if (opts.angacccorrbothruns || opts.angacccorrpertwoyears) opts.angacccorrperyear = false;
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_param_folded(int param, fcnc::options *opts){
|
||||
//int param is the number of the parameter according to get_angObser_withTeX_vec()
|
||||
//if the parameter is folded, return true
|
||||
|
||||
if (param==5) return !(opts->full_angular || opts->folding == 1);
|
||||
if (param==6) return !(opts->full_angular || opts->folding == 2);
|
||||
if (param==7) return !(opts->full_angular || opts->folding == 0);
|
||||
if (param==8) return !(opts->full_angular || opts->folding == 0);
|
||||
if (param==9) return !(opts->full_angular || opts->folding == 3);
|
||||
if (param==10) return !(opts->full_angular || opts->folding == 4);
|
||||
if (param==11) return !(opts->full_angular || opts->folding == 0);
|
||||
return false;
|
||||
|
||||
|
||||
}
|
447
Code/FCNCFitter/sources/Core/options.hh
Normal file
447
Code/FCNCFitter/sources/Core/options.hh
Normal file
@ -0,0 +1,447 @@
|
||||
/**
|
||||
* @file options.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
* @date 2009-03-18
|
||||
*
|
||||
* This file contains the options class which is used to store all the settings which are needed
|
||||
* for the fit. The likelihood, fitter, and plotter classes each
|
||||
* hold a pointer to an options object which must be supplied in their constructor.
|
||||
* On initialisation of the fitter class, the chosen options are printed
|
||||
* and should be redirected to a logfile
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPTIONS_H
|
||||
#define OPTIONS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <constants.hh>
|
||||
|
||||
|
||||
|
||||
namespace fcnc {
|
||||
|
||||
///class that stores the options used in the analysis
|
||||
class options {
|
||||
public:
|
||||
///number of cores to use
|
||||
unsigned int ncores;
|
||||
///use angular acceptance in the likelihood
|
||||
bool use_angular_acc;
|
||||
/// fit angular acceptance correction coefficients
|
||||
bool angularacceptance;
|
||||
/// get angular acceptance corrections for every year individually
|
||||
bool angacccorrperyear;
|
||||
/// combine every 2 years (2011+12, 2015+16, 2017+18) for acceptance correction
|
||||
bool angacccorrpertwoyears;
|
||||
/// combine the dataset of both runs for the angular acceptance correction:
|
||||
bool angacccorrbothruns;
|
||||
/// only calculate chi2's from the 1D projections of cos(tl), cos(tk), phi and q2
|
||||
bool only_4_1D_chi2;
|
||||
/// scan the parametrization of angular acceptance corrections coefficients
|
||||
/// by changing the max. order of legendre polynoms
|
||||
bool scan_max_order_angacccorrection;
|
||||
///do plots after every step in a toystudy
|
||||
bool project;
|
||||
///write .eps files
|
||||
bool write_eps;
|
||||
///write .C files (of plots)
|
||||
bool write_C;
|
||||
///write .jpg files (of plots)
|
||||
bool write_jpg;
|
||||
///write .pdf files (of plots)
|
||||
bool write_pdf;
|
||||
///read only out truthmatched bs candidates from file
|
||||
bool only_truthmatched;
|
||||
///use only true quantities for the fit. Not implemented yet
|
||||
bool use_truth;
|
||||
///use numerically optimal summation of likelihoods
|
||||
bool shift_lh;
|
||||
///repeat on fail
|
||||
bool repeat_on_fail;
|
||||
///use minos for error calculation
|
||||
bool minos_errors;
|
||||
///use simplex first
|
||||
bool simplex_prerun;
|
||||
///use Markov chain Monte Carlo
|
||||
bool use_mcmc;
|
||||
///hesse postrun
|
||||
bool hesse_postrun;
|
||||
///use accymptotic hesse, broken at this moment!!!
|
||||
bool asymptotic;
|
||||
///weighted fit
|
||||
bool weighted_fit;
|
||||
///generate background with acceptance correction in the PDF
|
||||
bool use_weighted_bkg;
|
||||
///in the case of a folded and acc corrected fit, use full angular PDF for background
|
||||
bool fit_full_angular_bkg;
|
||||
///use event q2 when determining weight
|
||||
bool use_event_norm;
|
||||
///static seed for toys
|
||||
bool static_seed;
|
||||
///Always use the same seed for toy generation, useful in systematics
|
||||
bool always_static_seed;
|
||||
///extended ml fit
|
||||
bool extended_ml;
|
||||
///refitting of nominal values for systematic studies
|
||||
bool refitting_nominal;
|
||||
///Options to set the mass shape
|
||||
bool crystalball;
|
||||
bool twotailedcrystalball;
|
||||
bool swave;
|
||||
bool simple_mkpi;
|
||||
//THIS TURNS ON FITTING BOTH K*mass and B+ mass
|
||||
//AND it turns off the angle fits
|
||||
bool only_mass2DFit;
|
||||
bool use_p2;
|
||||
//order of fitted polynomials
|
||||
unsigned int eff_order_costhetal;
|
||||
unsigned int eff_order_costhetak;
|
||||
unsigned int eff_order_phi;
|
||||
unsigned int eff_order_q2;
|
||||
int orderincrease;
|
||||
//order of background, currently does nothing, might be useful in the future
|
||||
unsigned int bkg_order_costhetal;
|
||||
unsigned int bkg_order_costhetak;
|
||||
unsigned int bkg_order_phi;
|
||||
|
||||
//minimum and maximum mass
|
||||
bool cutsignalwindow;
|
||||
double m_min; //signal window left edge
|
||||
double m_max; //signal window right edge
|
||||
double m_low; //considered mass spectrum left edge
|
||||
double m_high; //considered mass spectrum right edge
|
||||
double q2_min;//this is only used in weighted generation
|
||||
double q2_max;
|
||||
//Initialize using the SM values?
|
||||
bool initSM;
|
||||
///Options for all plots
|
||||
double ctl_min;
|
||||
double ctl_max;
|
||||
double ctk_min;
|
||||
double ctk_max;
|
||||
double phi_min;
|
||||
double phi_max;
|
||||
unsigned int plots_m_bins;
|
||||
unsigned int plots_mkpi_bins;
|
||||
unsigned int plots_costhetal_bins;
|
||||
unsigned int plots_costhetak_bins;
|
||||
unsigned int plots_phi_bins;
|
||||
std::string plot_label;
|
||||
std::string plot_folder;
|
||||
std::string q2_label;
|
||||
bool plot_chi2;
|
||||
std::string name;
|
||||
double minuit_strategy;
|
||||
bool flat_bkg;
|
||||
bool full_angular; //If false, use folding
|
||||
bool always_generate_full_angular; //I have no idea what it does but it is always true everywhere
|
||||
unsigned int fitsperjob;
|
||||
int job_id;
|
||||
//Fit only mass/angles/kpi mass
|
||||
bool only_Bmass; //For whatever fucking reason, this forces mkpi probability to be 1, so unless you don't fit it, set this to false
|
||||
bool only_angles;
|
||||
bool only_mkpi;
|
||||
bool reset_start;
|
||||
//for a simultaneous fit: TRUE if all param names have individual suffix to distinguish between sets of parameters
|
||||
bool use_individual_param_names;
|
||||
bool fit_asymmetries;
|
||||
bool fit_fl;
|
||||
bool fit_afb;
|
||||
bool fit_pprimes;
|
||||
//fit m(Kpi) mass spectrum?
|
||||
bool fit_mkpi; //4D+1D fit
|
||||
bool fit_lambda;
|
||||
//use the information of the m(Kpi) dimension in the angular_prob
|
||||
bool use_mkpi; //5D fit
|
||||
bool individual_penalties;
|
||||
double mkpi_min;
|
||||
double mkpi_max;
|
||||
bool update_efficiencies;
|
||||
bool squared_hesse;
|
||||
bool mkpi_threshold;
|
||||
bool mkpi_full_range_norm;
|
||||
//Generation
|
||||
bool generate_mkpi;
|
||||
bool generate_only_bkg;
|
||||
bool isobar;
|
||||
bool multiply_eff;
|
||||
bool cache_fis;
|
||||
bool mcweight;
|
||||
bool chisquaredstudy;
|
||||
int systematic;
|
||||
bool useMC;
|
||||
int run;
|
||||
int year;
|
||||
int verbose;
|
||||
std::string DDLL;
|
||||
bool DTF;
|
||||
bool KS;
|
||||
std::vector<double> TheQ2binsmin;
|
||||
std::vector<double> TheQ2binsmax;
|
||||
bool IsFlatQ2;
|
||||
int folding;
|
||||
bool reject_identical_muon_TRUEID;
|
||||
//File used for latex output //TODO
|
||||
std::string latexFileTag;
|
||||
|
||||
///constructor
|
||||
options(std::string argument=""):
|
||||
ncores(1),
|
||||
use_angular_acc(false),
|
||||
angularacceptance(false),
|
||||
angacccorrperyear(false),
|
||||
angacccorrpertwoyears(false),
|
||||
angacccorrbothruns(false),
|
||||
only_4_1D_chi2(false),
|
||||
scan_max_order_angacccorrection(false),
|
||||
project(false),
|
||||
write_eps(false),
|
||||
write_C(false),
|
||||
write_jpg(false),
|
||||
write_pdf(false),
|
||||
shift_lh(false),
|
||||
repeat_on_fail(false),
|
||||
minos_errors(false),
|
||||
simplex_prerun(false),
|
||||
use_mcmc(false),
|
||||
hesse_postrun(true),
|
||||
asymptotic(false),
|
||||
weighted_fit(false),
|
||||
use_weighted_bkg(false),
|
||||
fit_full_angular_bkg(true),
|
||||
use_event_norm(false),
|
||||
static_seed(false),
|
||||
always_static_seed(false),
|
||||
extended_ml(false),
|
||||
refitting_nominal(true),
|
||||
crystalball(!DOUBLE_CB),
|
||||
twotailedcrystalball(DOUBLE_CB),
|
||||
swave(false),
|
||||
simple_mkpi(false),
|
||||
only_mass2DFit(false),
|
||||
use_p2(false),
|
||||
eff_order_costhetal(ORDER_COSTHETAL),
|
||||
eff_order_costhetak(ORDER_COSTHETAK),
|
||||
eff_order_phi(ORDER_PHI),
|
||||
eff_order_q2(ORDER_Q2),
|
||||
orderincrease(0),
|
||||
bkg_order_costhetal(2), //TODO
|
||||
bkg_order_costhetak(4), //TODO
|
||||
bkg_order_phi(0), //TODO
|
||||
|
||||
cutsignalwindow(false),
|
||||
m_min(PDGMASS_B-B_MASS_TIGHT_WINDOW),
|
||||
m_max(PDGMASS_B+B_MASS_TIGHT_WINDOW),
|
||||
m_low(B_MASS_LOW),
|
||||
m_high(B_MASS_HIGH),
|
||||
q2_min(-1.0),
|
||||
q2_max(-1.0),
|
||||
initSM(false),
|
||||
ctl_min(CTL_MIN),
|
||||
ctl_max(CTL_MAX),
|
||||
ctk_min(CTK_MIN),
|
||||
ctk_max(CTK_MAX),
|
||||
phi_min(PHI_MIN),
|
||||
phi_max(PHI_MAX),
|
||||
plots_m_bins(PLOT_NBINS_MB),
|
||||
plots_mkpi_bins(PLOT_NBINS_MKSTAR),
|
||||
plots_costhetal_bins(PLOT_NBINS_ANGLES),
|
||||
plots_costhetak_bins(PLOT_NBINS_ANGLES),
|
||||
plots_phi_bins(PLOT_NBINS_ANGLES),
|
||||
plot_label("LHCb 9.1 fb^{-1}"),
|
||||
plot_folder(""),
|
||||
q2_label("1.1 < q^2 < 19.0"),
|
||||
plot_chi2(false),
|
||||
name(argument),
|
||||
minuit_strategy(2.0),
|
||||
flat_bkg(false),
|
||||
full_angular(false),
|
||||
always_generate_full_angular(true),
|
||||
fitsperjob(10),
|
||||
job_id(-1),
|
||||
only_Bmass(false),
|
||||
only_angles(false),
|
||||
only_mkpi(false),
|
||||
reset_start(true),
|
||||
use_individual_param_names(false),
|
||||
fit_asymmetries(false),
|
||||
fit_fl(false),
|
||||
fit_afb(false),
|
||||
fit_pprimes(false),
|
||||
fit_mkpi(false),
|
||||
fit_lambda(false),
|
||||
use_mkpi(false),
|
||||
individual_penalties(false),
|
||||
mkpi_min(KPI_MASS_MIN),
|
||||
mkpi_max(KPI_MASS_MAX),
|
||||
update_efficiencies(true),
|
||||
squared_hesse(true),
|
||||
mkpi_threshold(false),
|
||||
mkpi_full_range_norm(false),
|
||||
generate_mkpi(false),
|
||||
generate_only_bkg(false),
|
||||
isobar(false),
|
||||
multiply_eff(false),
|
||||
cache_fis(false),
|
||||
mcweight(false), //Not changed anywhere, only in pdf to decide what weights to use and there it is always true, no clue what it is supposed to do
|
||||
chisquaredstudy(false),
|
||||
systematic(-1),
|
||||
useMC(false),
|
||||
run(-1),
|
||||
year(-1),
|
||||
verbose(2), //Set to info
|
||||
DDLL("DD"),
|
||||
DTF(true),
|
||||
KS(true),
|
||||
TheQ2binsmin(std::vector<double>(6, 0.0)),
|
||||
TheQ2binsmax(std::vector<double>(6, 0.0)),
|
||||
IsFlatQ2(true),
|
||||
folding(-1),
|
||||
reject_identical_muon_TRUEID(false),
|
||||
latexFileTag("_basic") //TODO
|
||||
{
|
||||
};
|
||||
|
||||
//assignment operator:
|
||||
options operator=(const options o){
|
||||
//self-assignment guard
|
||||
// if (this == &o) //TODO: requires operator==
|
||||
// return *this;
|
||||
ncores = o.ncores;
|
||||
use_angular_acc = o.use_angular_acc;
|
||||
angularacceptance = o.angularacceptance;
|
||||
angacccorrperyear = o.angacccorrperyear;
|
||||
angacccorrpertwoyears = o.angacccorrpertwoyears;
|
||||
angacccorrbothruns = o.angacccorrbothruns;
|
||||
only_4_1D_chi2 = o.only_4_1D_chi2;
|
||||
scan_max_order_angacccorrection = o.scan_max_order_angacccorrection;
|
||||
project = o.project;
|
||||
write_eps = o.write_eps;
|
||||
write_C = o.write_C;
|
||||
write_jpg = o.write_jpg;
|
||||
write_pdf = o.write_pdf;
|
||||
only_truthmatched = o.only_truthmatched;
|
||||
use_truth = o.use_truth;
|
||||
shift_lh = o.shift_lh;
|
||||
repeat_on_fail = o.repeat_on_fail;
|
||||
minos_errors = o.minos_errors;
|
||||
simplex_prerun = o.simplex_prerun;
|
||||
use_mcmc = o.use_mcmc;
|
||||
asymptotic = o.asymptotic;
|
||||
hesse_postrun = o.hesse_postrun;
|
||||
weighted_fit = o.weighted_fit;
|
||||
use_weighted_bkg = o.use_weighted_bkg;
|
||||
fit_full_angular_bkg = o.fit_full_angular_bkg;
|
||||
use_event_norm = o.use_event_norm;
|
||||
static_seed = o.static_seed;
|
||||
always_static_seed = o.always_static_seed;
|
||||
extended_ml = o.extended_ml;
|
||||
refitting_nominal = o.refitting_nominal;
|
||||
crystalball = o.crystalball;
|
||||
twotailedcrystalball = o.twotailedcrystalball;
|
||||
swave = o.swave;
|
||||
simple_mkpi = o.simple_mkpi;
|
||||
only_mass2DFit = o.only_mass2DFit;
|
||||
use_p2 = o.use_p2;
|
||||
eff_order_costhetal = o.eff_order_costhetal;
|
||||
eff_order_costhetak = o.eff_order_costhetak;
|
||||
eff_order_phi = o.eff_order_phi;
|
||||
eff_order_q2 = o.eff_order_q2;
|
||||
bkg_order_costhetal = o.bkg_order_costhetal;
|
||||
bkg_order_costhetak = o.bkg_order_costhetak;
|
||||
bkg_order_phi = o.bkg_order_phi;
|
||||
orderincrease = o.orderincrease;
|
||||
cutsignalwindow = o.cutsignalwindow;
|
||||
m_min = o.m_min;
|
||||
m_max = o.m_max;
|
||||
m_low = o.m_low;
|
||||
m_high = o.m_high;
|
||||
q2_min = o.q2_min;
|
||||
q2_max = o.q2_max;
|
||||
initSM = o.initSM;
|
||||
ctl_min = o.ctl_min;
|
||||
ctl_max = o.ctl_max;
|
||||
ctk_min = o.ctk_min;
|
||||
ctk_max = o.ctk_max;
|
||||
phi_min = o.phi_min;
|
||||
phi_max = o.phi_max;
|
||||
plots_m_bins = o.plots_m_bins;
|
||||
plots_mkpi_bins = o.plots_mkpi_bins;
|
||||
plots_costhetal_bins = o.plots_costhetal_bins;
|
||||
plots_costhetak_bins = o.plots_costhetak_bins;
|
||||
plots_phi_bins = o.plots_phi_bins;
|
||||
plot_label = o.plot_label;
|
||||
plot_folder = o.plot_folder;
|
||||
q2_label = o.q2_label;
|
||||
plot_chi2 = o.plot_chi2;
|
||||
name = o.name;
|
||||
minuit_strategy = o.minuit_strategy;
|
||||
flat_bkg = o.flat_bkg;
|
||||
full_angular = o.full_angular;
|
||||
always_generate_full_angular = o.always_generate_full_angular;
|
||||
fitsperjob = o.fitsperjob;
|
||||
job_id = o.job_id;
|
||||
only_Bmass = o.only_Bmass;
|
||||
only_angles = o.only_angles;
|
||||
only_mkpi = o.only_mkpi;
|
||||
reset_start = o.reset_start;
|
||||
use_individual_param_names = o.use_individual_param_names;
|
||||
fit_asymmetries = o.fit_asymmetries;
|
||||
fit_fl = o.fit_fl;
|
||||
fit_afb = o.fit_afb;
|
||||
fit_pprimes = o.fit_pprimes;
|
||||
fit_mkpi = o.fit_mkpi;
|
||||
fit_lambda = o.fit_lambda;
|
||||
use_mkpi = o.use_mkpi;
|
||||
individual_penalties = o.individual_penalties;
|
||||
mkpi_min = o.mkpi_min;
|
||||
mkpi_max = o.mkpi_max;
|
||||
update_efficiencies = o.update_efficiencies;
|
||||
squared_hesse = o.squared_hesse;
|
||||
mkpi_threshold = o.mkpi_threshold;
|
||||
mkpi_full_range_norm = o.mkpi_full_range_norm;
|
||||
generate_mkpi = o.generate_mkpi;
|
||||
generate_only_bkg = o.generate_only_bkg;
|
||||
isobar = o.isobar;
|
||||
multiply_eff = o.multiply_eff;
|
||||
cache_fis = o.cache_fis;
|
||||
mcweight = o.mcweight;
|
||||
chisquaredstudy = o.chisquaredstudy;
|
||||
systematic = o.systematic;
|
||||
useMC = o.useMC;
|
||||
run = o.run;
|
||||
year = o.year;
|
||||
verbose = o.verbose;
|
||||
DDLL = o.DDLL;
|
||||
DTF = o.DTF;
|
||||
KS = o.KS;
|
||||
TheQ2binsmin = o.TheQ2binsmin;
|
||||
TheQ2binsmax = o.TheQ2binsmax;
|
||||
IsFlatQ2 = o.IsFlatQ2;
|
||||
folding = o.folding;
|
||||
reject_identical_muon_TRUEID = o.reject_identical_muon_TRUEID;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int get_job_id();
|
||||
//Check if the angle ranges are not interfering with the folding
|
||||
bool canIFold();
|
||||
void reset_angle_ranges();
|
||||
void update_angle_ranges();
|
||||
unsigned int get_nQ2bins();
|
||||
//Reutrns a vector with strings of all types that are required by write_eps, write_C, write_jpg and write_pdf
|
||||
std::vector<std::string> getAllPlotTypes();
|
||||
void print();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::string> get_observables_vec (fcnc::options opts); //TODO: add into fcnc class
|
||||
void set_ang_year_options(fcnc::options &opts);
|
||||
|
||||
//If true, than the parameter is folded and typically set to 0 //TODO: add into fcnc class
|
||||
bool is_param_folded(int param, fcnc::options *opts);
|
||||
#endif
|
52
Code/FCNCFitter/sources/Core/pdf.hh
Normal file
52
Code/FCNCFitter/sources/Core/pdf.hh
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @file pdf.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PDF_H
|
||||
#define PDF_H
|
||||
|
||||
namespace fcnc {
|
||||
class parameters;
|
||||
class event;
|
||||
class options;
|
||||
|
||||
|
||||
///abstract base class that defines the interface for a pdf
|
||||
///your pdf needs to inherit form this and implement all the abstract methods
|
||||
class pdf {
|
||||
public:
|
||||
virtual ~pdf() {};
|
||||
///returns the probability of one event
|
||||
virtual double prob(const parameters* params, const event& meas) const = 0;
|
||||
virtual double chi2(const parameters* params) {return 0.0;};
|
||||
///updates the cached normalization after a parameter change
|
||||
virtual void update_cached_normalization(const parameters* params) = 0;
|
||||
virtual void update_cached_normalization(const parameters* params, std::vector<event>* events) {return;};
|
||||
virtual void update_cached_integrated_fis(const parameters* params) {return;};
|
||||
///updates the cached efficiencies, useable in case of fixed q2 eff or for a weighted fit
|
||||
virtual void update_cached_efficiencies(const parameters* params, std::vector<event>* events) {return;};
|
||||
///updates the cached xis paramters for every event, this allows to use a different q2 dependent norm for every event
|
||||
virtual void update_cached_xis(const parameters* params, std::vector<event>* events) {return;};
|
||||
///performs the necessary initialisations for the pdf
|
||||
virtual void init(parameters* params) = 0;
|
||||
//I am exposing these for now, needed for the S-wave hack
|
||||
virtual void get_swave_integrated_fj(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const {return;};
|
||||
virtual void get_integrated_fj(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const {return;};
|
||||
|
||||
virtual void swave_integrated_fj_noacc(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6) const {return;};
|
||||
//virtual void swave_integrated_fj_chebyshev(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6, double q2) const {return;};
|
||||
virtual void integrated_fj_noacc(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||||
double& f7, double& f8, double& f9, double& f10, double& f11, double& f12) const {return;};
|
||||
//virtual void integrated_fj_chebyshev(double& f1, double& f2, double& f3, double& f4, double& f5, double& f6,
|
||||
// double& f7, double& f8, double& f9, double& f10, double& f11, double& f12, double q2) const {return;};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
32
Code/FCNCFitter/sources/Core/plotter.hh
Normal file
32
Code/FCNCFitter/sources/Core/plotter.hh
Normal file
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* @file plotter.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLOTTER_H
|
||||
#define PLOTTER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace fcnc {
|
||||
class pdf;
|
||||
class event;
|
||||
class parameters;
|
||||
|
||||
///abstract base class that defines the interface for a plotter
|
||||
///your plotter needs to inherit form this and implement all the abstract methods
|
||||
class plotter {
|
||||
public:
|
||||
virtual ~plotter() {};
|
||||
///plots the pdf projections
|
||||
virtual int plot_data(pdf* prob, parameters* params, std::vector<event>* ev, std::string index) = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
355
Code/FCNCFitter/sources/Core/toystudy.cc
Normal file
355
Code/FCNCFitter/sources/Core/toystudy.cc
Normal file
@ -0,0 +1,355 @@
|
||||
/**
|
||||
* @file toystudy.cc
|
||||
* @author Renata Kopecna (cause I find 500 lines functioned defined in a header disgusting)
|
||||
* @date 2021-02-25
|
||||
*
|
||||
*/
|
||||
|
||||
#include <toystudy.hh>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <event.hh>
|
||||
#include <parameters.hh>
|
||||
#include <funcs.hh>
|
||||
#include <pdf.hh>
|
||||
#include <options.hh>
|
||||
#include <fitter.hh>
|
||||
#include <generator.hh>
|
||||
#include <multifit.hh>
|
||||
|
||||
|
||||
void fcnc::toystudy::toy(unsigned int nevents, unsigned int nruns, pdf* prob, parameters* params, generator* gen){
|
||||
std::vector<unsigned int> the_nevents;
|
||||
the_nevents.push_back(nevents);
|
||||
|
||||
std::vector<pdf*> probs;
|
||||
probs.push_back(prob);
|
||||
|
||||
std::vector<parameters*> the_params;
|
||||
the_params.push_back(params);
|
||||
|
||||
std::vector<generator*> gens;
|
||||
gens.push_back(gen);
|
||||
|
||||
toy(the_nevents, nruns, probs, the_params, gens);
|
||||
}
|
||||
|
||||
void fcnc::toystudy::toy(std::vector<unsigned int> nevents, unsigned int nruns, std::vector<pdf*> pdfs, std::vector<parameters*> params, std::vector<generator*> gens){
|
||||
|
||||
//Open texFile
|
||||
std::ofstream myFile;
|
||||
open_Latex_noteFile(latex_toyFile(), myFile);
|
||||
|
||||
spdlog::info("Starting toy study on toy data");
|
||||
//unsigned int run_no = 0;
|
||||
|
||||
spdlog::info("Will run over {0:d} runs with {1:d}", nruns, nevents.at(0));
|
||||
if (spdlog_info()){
|
||||
for (unsigned int i=1; i<nevents.size(); i++) std::cout << "/" << nevents.at(i);
|
||||
}
|
||||
spdlog::info(" events each.");
|
||||
|
||||
//need this for jitter on constraints
|
||||
TRandom3* rnd = new TRandom3();
|
||||
rnd->SetSeed(0);//non-static seed
|
||||
//initialisation for histos and arrrays
|
||||
unsigned int nparams = 0;
|
||||
for (unsigned int i=0; i<params.size(); i++){
|
||||
nparams += params.at(i)->nparameters();
|
||||
}
|
||||
|
||||
std::vector<double> pull_width(nparams, 0.0);
|
||||
std::vector<double> pull_mean(nparams, 0.0);
|
||||
std::vector<double> pull_width_sigma(nparams, 0.0);
|
||||
std::vector<double> pull_mean_sigma(nparams, 0.0);
|
||||
std::vector<double> pull_chisquared(nparams, 0.0);
|
||||
std::vector<double> value_width(nparams, 0.0);
|
||||
std::vector<double> value_mean(nparams, 0.0);
|
||||
std::vector<double> value_width_sigma(nparams, 0.0);
|
||||
std::vector<double> value_mean_sigma(nparams, 0.0);
|
||||
std::vector<double> value_chisquared(nparams, 0.0);
|
||||
std::vector<double> error_width(nparams, 0.0);
|
||||
std::vector<double> error_mean(nparams, 0.0);
|
||||
std::vector<double> error_width_sigma(nparams, 0.0);
|
||||
std::vector<double> error_mean_sigma(nparams, 0.0);
|
||||
std::vector<double> error_chisquared(nparams, 0.0);
|
||||
std::vector<std::vector<double> > errors(nparams, std::vector<double>());
|
||||
std::vector<std::vector<double> > errors_up(nparams, std::vector<double>());
|
||||
std::vector<std::vector<double> > errors_down(nparams, std::vector<double>());
|
||||
std::vector<std::vector<double> > values(nparams, std::vector<double>());
|
||||
std::vector<std::vector<double> > nominal_errors(nparams, std::vector<double>());
|
||||
std::vector<std::vector<double> > nominal_values(nparams, std::vector<double>());
|
||||
std::vector<int> return_values(nruns);
|
||||
std::vector<std::vector<std::vector<double> > > corrs(nparams, std::vector<std::vector<double> >());
|
||||
|
||||
fcnc::fitter fit(opts);
|
||||
for (unsigned int i=0; i<pdfs.size(); i++){
|
||||
pdfs.at(i)->init(params.at(i));
|
||||
}
|
||||
fit.set_common_parameters(common_params);
|
||||
|
||||
for (unsigned int i=0; i < nruns; i++) {
|
||||
spdlog::info("Starting run no. {0:d}", i + 1);
|
||||
//run_no = i;
|
||||
|
||||
std::vector< std::vector<event> > temp_events;
|
||||
for (unsigned int j=0; j<gens.size(); j++){
|
||||
std::vector<event> ev = gens.at(j)->generate(nevents.at(j), params.at(j), pdfs.at(j));
|
||||
temp_events.push_back(ev);
|
||||
}
|
||||
std::vector< std::vector<event>* > events;
|
||||
for (unsigned int j=0; j<gens.size(); j++){
|
||||
events.push_back(&temp_events.at(j));
|
||||
}
|
||||
|
||||
std::string num;
|
||||
std::stringstream out;
|
||||
out << (i+1);
|
||||
num = out.str();
|
||||
int result = 0;
|
||||
|
||||
//in the case of constraints, jitter the mean value
|
||||
for (unsigned int j = 0; j < params.size(); j++){
|
||||
for (unsigned int k = 0; k < params.at(j)->nparameters(); k++){
|
||||
parameter* param = params.at(j)->get_parameter(k);
|
||||
double shift = rnd->Rndm() > 0.5 ? -fabs(rnd->Gaus(0.0, param->get_previous_error_low())) : fabs(rnd->Gaus(0.0, param->get_previous_error_high()));//TODO, actually should probably use PDG method
|
||||
if (param->get_gaussian_constraint()){
|
||||
param->set_previous_measurement(param->get_start_value() + shift);//rnd->Gaus(0.0, sigma));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (opts->eos_bsz_ff){
|
||||
TMatrixD mU = fcnc::get_bsz_mu_invcov();
|
||||
|
||||
std::vector<double> rndvec(21, 0.0);
|
||||
for (unsigned int i=0; i<21; i++){
|
||||
rndvec.at(i) = rnd->Gaus(0.0, 1.0);
|
||||
}
|
||||
std::vector<double> shiftvec(21, 0.0);
|
||||
for (unsigned int i=0; i<21; i++){
|
||||
for (unsigned int j=0; j<21; j++){
|
||||
shiftvec.at(i) += mU(j,i)*rndvec.at(j);//new order, corrected and tested
|
||||
}
|
||||
}
|
||||
for (unsigned int j = 0; j < params.size(); j++){
|
||||
if (params.at(j)->get_parameter("a0_0") != 0){
|
||||
//TODO: jitter according to covariance matrix given
|
||||
//std::vector<double> coeffvec(21, 0.0);// = nominal;//fcnc::legendre_coefficients_nominal;
|
||||
for (unsigned int i=0; i<21; i++){
|
||||
parameter* param = 0;
|
||||
switch (i) {
|
||||
case 0 : param = params.at(j)->get_parameter("a0_0"); break;
|
||||
case 1 : param = params.at(j)->get_parameter("a0_1"); break;
|
||||
case 2 : param = params.at(j)->get_parameter("a0_2"); break;
|
||||
case 3 : param = params.at(j)->get_parameter("a1_0"); break;
|
||||
case 4 : param = params.at(j)->get_parameter("a1_1"); break;
|
||||
case 5 : param = params.at(j)->get_parameter("a1_2"); break;
|
||||
//case 6 : param = params.at(j)->get_parameter(""); break;
|
||||
case 7 : param = params.at(j)->get_parameter("a12_1"); break;
|
||||
case 8 : param = params.at(j)->get_parameter("a12_2"); break;
|
||||
case 9 : param = params.at(j)->get_parameter("v_0"); break;
|
||||
case 10 : param = params.at(j)->get_parameter("v_1"); break;
|
||||
case 11 : param = params.at(j)->get_parameter("v_2"); break;
|
||||
case 12 : param = params.at(j)->get_parameter("t1_0"); break;
|
||||
case 13 : param = params.at(j)->get_parameter("t1_1"); break;
|
||||
case 14 : param = params.at(j)->get_parameter("t1_2"); break;
|
||||
//case 15 : param = params.at(j)->get_parameter(""); break;
|
||||
case 16 : param = params.at(j)->get_parameter("t2_1"); break;
|
||||
case 17 : param = params.at(j)->get_parameter("t2_2"); break;
|
||||
case 18 : param = params.at(j)->get_parameter("t23_0"); break;
|
||||
case 19 : param = params.at(j)->get_parameter("t23_1"); break;
|
||||
case 20 : param = params.at(j)->get_parameter("t23_2"); break;
|
||||
};
|
||||
if (param != 0){
|
||||
param->set_previous_measurement(param->get_start_value() + shiftvec.at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//perform the actual fit
|
||||
result = fit.fit(pdfs, params, events, num);
|
||||
return_values.at(i) = result;
|
||||
|
||||
if (result != 300 && opts->repeat_on_fail) {
|
||||
spdlog::error("Fit failed, repeating run");
|
||||
for (unsigned int j = 0; j < params.size(); j++){
|
||||
params.at(j)->reset_parameters();
|
||||
}
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
//extract the parameters from the fit
|
||||
unsigned int start_param = 0;
|
||||
for (unsigned int j = 0; j < params.size(); j++) {
|
||||
for (unsigned int k = 0; k < params.at(j)->nparameters(); k++){
|
||||
parameter* param = params.at(j)->get_parameter(k);
|
||||
unsigned int idx = start_param+k;
|
||||
values.at(idx).push_back(param->get_value());
|
||||
errors.at(idx).push_back(param->get_error());
|
||||
errors_up.at(idx).push_back(param->get_error_up());
|
||||
errors_down.at(idx).push_back(param->get_error_down());
|
||||
corrs.at(idx).push_back(param->correlations);//for some, this is empty
|
||||
}
|
||||
start_param += params.at(j)->nparameters();
|
||||
}
|
||||
//todo whats this? //I don't know, David. Sincerely, Renata
|
||||
for (unsigned int j = 0; j < nparams; j++){
|
||||
nominal_values.at(j).push_back(0.0);
|
||||
nominal_errors.at(j).push_back(0.0);
|
||||
}
|
||||
|
||||
//Update pull histos every 10 steps or when finished.
|
||||
//if ((i+1 >= 100) && (((i+1)%100 == 0) || (i+1 == nruns)))
|
||||
if (i+1 == nruns) {
|
||||
//This should be done a little differently:
|
||||
//recreate histos every time, use min and max values as axis.
|
||||
start_param = 0;
|
||||
for (unsigned int j = 0; j < params.size(); j++){//this plots the pull histos
|
||||
for (unsigned int k = 0; k < params.at(j)->nparameters(); k++){//this plots the pull histos
|
||||
parameter* par = params.at(j)->get_parameter(k);
|
||||
if (par->get_step_size() != 0.0) {
|
||||
unsigned int idx = start_param+k;
|
||||
update_pull(par, values.at(idx),
|
||||
errors.at(idx),
|
||||
pull_mean[idx], pull_mean_sigma[idx],
|
||||
pull_width[idx], pull_width_sigma[idx],
|
||||
pull_chisquared[idx]);
|
||||
update_value(par, values.at(idx), errors.at(idx),
|
||||
value_mean[idx], value_mean_sigma[idx],
|
||||
value_width[idx], value_width_sigma[idx],
|
||||
value_chisquared[idx]);
|
||||
update_error(par, values.at(idx), errors.at(idx),
|
||||
error_mean[idx], error_mean_sigma[idx],
|
||||
error_width[idx], error_width_sigma[idx],
|
||||
error_chisquared[idx]);
|
||||
}
|
||||
}
|
||||
start_param += params.at(j)->nparameters();
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int j = 0; j < params.size(); j++){
|
||||
params.at(j)->reset_parameters();
|
||||
}
|
||||
|
||||
spdlog::info("Run {0:d} finished", i + 1);
|
||||
}
|
||||
//delete rnd;
|
||||
|
||||
//save result trees to root file
|
||||
//TFile* output;
|
||||
output->cd();
|
||||
int param_index = 0;
|
||||
|
||||
unsigned int start_param = 0;
|
||||
for (unsigned int j = 0; j < params.size(); j++){
|
||||
for (unsigned int k = 0; k < params.at(j)->nparameters(); k++){
|
||||
parameter* param = params.at(j)->get_parameter(k);
|
||||
unsigned int idx = start_param+k;
|
||||
//for (unsigned int j = 0; j < nparams; j++)//this gives nice output
|
||||
if (param->get_step_size() != 0.0) {//todo common parameters, only save once...
|
||||
std::string parname(param->get_name());
|
||||
std::string pardesc(param->get_description());
|
||||
TTree* t = new TTree(parname.c_str(), pardesc.c_str());
|
||||
double value, error, error_up, error_down, start_value, nominal_value, nominal_error;
|
||||
int run, migrad, status_cov;
|
||||
double tmp_corr[corrs.at(idx).at(0).size()];
|
||||
t->Branch("run",&run,"run/I");
|
||||
t->Branch("value",&value,"value/D");
|
||||
t->Branch("error",&error,"error/D");
|
||||
t->Branch("error_up",&error_up,"error_up/D");
|
||||
t->Branch("error_down",&error_down,"error_down/D");
|
||||
t->Branch("start_value",&start_value,"start_value/D");
|
||||
t->Branch("migrad",&migrad,"migrad/I");
|
||||
t->Branch("status_cov",&status_cov,"status_cov/I");
|
||||
t->Branch("nominal_value",&nominal_value,"nominal_value/D");
|
||||
t->Branch("nominal_error",&nominal_error,"nominal_error/D");
|
||||
t->Branch("index",¶m_index, "index/I");
|
||||
std::string corr_string = "correlations";
|
||||
std::stringstream corr_stream;
|
||||
corr_stream << "correlations[" << corrs.at(idx).at(0).size() << "]/D";
|
||||
t->Branch("correlations",&tmp_corr,corr_stream.str().c_str());
|
||||
for (unsigned int i=0; i<nruns; i++){
|
||||
run = i;
|
||||
if (param->is_blind()){
|
||||
value = values.at(idx).at(i) + param->get_blinding_delta();//TODO add delta
|
||||
}
|
||||
else{
|
||||
value = values.at(idx).at(i);//TODO add delta
|
||||
}
|
||||
error = errors.at(idx).at(i);
|
||||
if (param->is_blind()){
|
||||
nominal_value = nominal_values.at(idx).at(i) + param->get_blinding_delta();
|
||||
}
|
||||
else{
|
||||
nominal_value = nominal_values.at(idx).at(i);
|
||||
}
|
||||
nominal_error = nominal_errors.at(idx).at(i);
|
||||
error_up = errors_up.at(idx).at(i);
|
||||
error_down = errors_down.at(idx).at(i);
|
||||
if (param->is_blind()){
|
||||
start_value = param->get_start_value() + param->get_blinding_delta();
|
||||
}
|
||||
else{
|
||||
start_value = param->get_start_value();
|
||||
}
|
||||
migrad = return_values.at(i) % 100;
|
||||
status_cov = return_values.at(i) / 100;
|
||||
//corr = corrs.at(idx).at(i);
|
||||
for (unsigned int l = 0; l < corrs.at(idx).at(i).size(); l++){
|
||||
tmp_corr[l] = corrs.at(idx).at(i).at(l);
|
||||
}
|
||||
t->Fill();
|
||||
}
|
||||
t->Write();
|
||||
delete t;
|
||||
param_index++;
|
||||
}
|
||||
}
|
||||
start_param += params.at(j)->nparameters();
|
||||
}
|
||||
//latex output
|
||||
bool blind = false;
|
||||
for (unsigned int j = 0; j < params.size(); j++){
|
||||
if (!params.at(j)->is_blind()) blind = true;
|
||||
}
|
||||
spdlog::info("Toy Study results");
|
||||
if (!blind){
|
||||
myFile <<"\\begin{tabular}{|cccccccc|}\\hline" << std::endl;
|
||||
myFile <<"\\# & parameter & Mean Value & Mean Width & Mean Error & Error Width & Pull Mean & Pull Width \\\\ \\hline \\hline" << std::endl;
|
||||
start_param = 0;
|
||||
for (unsigned int j = 0; j < params.size(); j++)
|
||||
{
|
||||
for (unsigned int k = 0; k < params.at(j)->nparameters(); k++)
|
||||
{
|
||||
parameter* param = params.at(j)->get_parameter(k);
|
||||
unsigned int idx = start_param+k;
|
||||
if (param->get_step_size() != 0.0){
|
||||
std::string partex = param->get_description();
|
||||
myFile <<std::setw(2) << idx << " & $" << std::setw(22) << partex << "$ & $"
|
||||
<< std::fixed << std::setprecision(4)
|
||||
<< std::setw(7) << value_mean[idx] << " \\pm " << std::setw(7) << value_mean_sigma[idx] << "$ & $"
|
||||
<< std::setw(7) << value_width[idx] << " \\pm " << std::setw(7) << value_width_sigma[idx] << "$ & $"
|
||||
<< std::setw(7) << error_mean[idx] << " \\pm " << std::setw(7) << error_mean_sigma[idx] << "$ & $"
|
||||
<< std::setw(7) << error_width[idx] << " \\pm " << std::setw(7) << error_width_sigma[idx] << "$ & $"
|
||||
<< std::setw(7) << pull_mean[idx] << " \\pm " << std::setw(7) << pull_mean_sigma[idx] << "$ & $"
|
||||
<< std::setw(7) << pull_width[idx] << " \\pm " << std::setw(7) << pull_width_sigma[idx] << "$ \\\\"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
start_param += params.at(j)->nparameters();
|
||||
}
|
||||
myFile <<"\\hline\\end{tabular}" << std::endl;
|
||||
}
|
||||
|
||||
delete rnd;
|
||||
|
||||
//Close Latex file
|
||||
myFile.close();
|
||||
|
||||
}
|
||||
|
||||
|
64
Code/FCNCFitter/sources/Core/toystudy.hh
Normal file
64
Code/FCNCFitter/sources/Core/toystudy.hh
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @file toystudy.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
|
||||
* @date 2010-10-15
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TOYSTUDY_H
|
||||
#define TOYSTUDY_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <multifit.hh>
|
||||
|
||||
namespace fcnc {
|
||||
class options;
|
||||
class pdf;
|
||||
class parameters;
|
||||
class generator;
|
||||
|
||||
///class to perform a toystudy, i.e. a repeated fit using generated toy data
|
||||
//template <class params_type, class pdf_type, class generator_type, class plotter_type, class loader_type>
|
||||
class toystudy: public multifit {
|
||||
private:
|
||||
///common parameters in different parameter sets
|
||||
std::vector< std::string > common_params;
|
||||
public:
|
||||
///constructor
|
||||
toystudy(options* o);
|
||||
/**
|
||||
* perform a toy study on generated toy data
|
||||
* @param nevents the number of events used per fit of the toy data
|
||||
* @param nruns the number of repeats
|
||||
* @param prob pointer to the pdf to use in the likelihood fit
|
||||
* @param params pointer to parameterset to use in the likelihood fit
|
||||
* @param gen pointer to the toy data generator to use
|
||||
**/
|
||||
void toy(unsigned int nevents, unsigned int nruns, pdf* prob, parameters* params, generator* gen);
|
||||
/**
|
||||
* perform a toy study on fully simulated mc data
|
||||
* @param nevents the number of events used per fit of the toy data
|
||||
* @param nruns the number of repeats
|
||||
* @param pdfs pointer to the pdfs to use in the likelihood fit
|
||||
* @param params pointer to parametersets to use in the likelihood fit
|
||||
* @param string filename to load
|
||||
**/
|
||||
void toy(std::vector<unsigned int> nevents, unsigned int nruns, std::vector<pdf*> pdfs, std::vector<parameters*> params, std::vector<generator*> gens);
|
||||
///set common parameters
|
||||
void set_common_parameters(std::vector<std::string> common_pars) {
|
||||
common_params = common_pars;
|
||||
};
|
||||
};
|
||||
|
||||
toystudy::toystudy(options* o):
|
||||
multifit(o)
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
115
Code/FCNCFitter/sources/Helpers/colors.hh
Normal file
115
Code/FCNCFitter/sources/Helpers/colors.hh
Normal file
@ -0,0 +1,115 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include "TColor.h"
|
||||
#include <TStyle.h>
|
||||
|
||||
#ifndef COLORS_HH
|
||||
#define COLORS_HH
|
||||
|
||||
//=========================================
|
||||
//
|
||||
// Colors
|
||||
//
|
||||
//=========================================
|
||||
|
||||
namespace myColorScheme{
|
||||
/* // Taken from https://gist.github.com/gipert/df72b67c1d02bbb41f1dd406b6397811
|
||||
* Handy enum for later color referencing
|
||||
*/
|
||||
enum {
|
||||
// Bright color scheme
|
||||
kTBriBlue = 9000,
|
||||
kTBriCyan = 9001,
|
||||
kTBriGreen = 9002,
|
||||
kTBriYellow = 9003,
|
||||
kTBriRed = 9004,
|
||||
kTBriPurple = 9005,
|
||||
kTBriGrey = 9006,
|
||||
|
||||
// Vibrant color scheme
|
||||
kTVibBlue = 9007,
|
||||
kTVibCyan = 9008,
|
||||
kTVibTeal = 9009,
|
||||
kTVibOrange = 9010,
|
||||
kTVibRed = 9011,
|
||||
kTVibMagenta = 9012,
|
||||
kTVibGrey = 9013,
|
||||
|
||||
// Muted color scheme //10 colors
|
||||
kTMutIndigo = 9014,
|
||||
kTMutCyan = 9015,
|
||||
kTMutTeal = 9016,
|
||||
kTMutGreen = 9017,
|
||||
kTMutOlive = 9018,
|
||||
kTMutSand = 9019,
|
||||
kTMutRose = 9020,
|
||||
kTMutWine = 9021,
|
||||
kTMutPurple = 9022,
|
||||
kTMutPaleGrey = 9023,
|
||||
|
||||
// Light color scheme //9 colors
|
||||
kTLigLightBlue = 9024,
|
||||
kTLigLightCyan = 9025,
|
||||
kTLigMint = 9026,
|
||||
kTLigPear = 9027,
|
||||
kTLigOlive = 9028,
|
||||
kTLigLightYellow = 9029,
|
||||
kTLigOrange = 9030,
|
||||
kTLigPink = 9031,
|
||||
kTLigPaleGrey = 9032,
|
||||
|
||||
// To label "bad" data (see BuRd and PRGn palettes below)
|
||||
kTBadData = 9033
|
||||
|
||||
|
||||
};
|
||||
|
||||
void init() {
|
||||
gStyle->SetColorModelPS(0);
|
||||
|
||||
// Bright color scheme
|
||||
new TColor(kTBriBlue, 68./255, 119./255, 170./255, "tol-bri-blue" );
|
||||
new TColor(kTBriCyan, 102./255, 204./255, 238./255, "tol-bri-cyan" );
|
||||
new TColor(kTBriGreen, 34./255, 136./255, 51./255, "tol-bri-green" );
|
||||
new TColor(kTBriYellow, 204./255, 187./255, 68./255, "tol-bri-yellow" );
|
||||
new TColor(kTBriRed, 238./255, 102./255, 119./255, "tol-bri-red" );
|
||||
new TColor(kTBriPurple, 170./255, 51./255, 119./255, "tol-bri-purple" );
|
||||
new TColor(kTBriGrey, 187./255, 187./255, 187./255, "tol-bri-grey" );
|
||||
|
||||
// Vibrant color scheme
|
||||
new TColor(kTVibBlue, 0./255, 119./255, 187./255, "tol-vib-blue" );
|
||||
new TColor(kTVibCyan, 51./255, 187./255, 238./255, "tol-vib-cyan" );
|
||||
new TColor(kTVibTeal, 0./255, 153./255, 136./255, "tol-vib-teal" );
|
||||
new TColor(kTVibOrange, 238./255, 119./255, 51./255, "tol-vib-orange" );
|
||||
new TColor(kTVibRed, 204./255, 51./255, 17./255, "tol-vib-red" );
|
||||
new TColor(kTVibMagenta, 238./255, 51./255, 119./255, "tol-vib-magenta" );
|
||||
new TColor(kTVibGrey, 187./255, 187./255, 187./255, "tol-vib-grey" );
|
||||
|
||||
// Muted color scheme
|
||||
new TColor(kTMutIndigo, 51./255, 34./255, 136./255, "tol-mut-indigo" );
|
||||
new TColor(kTMutCyan, 136./255, 204./255, 238./255, "tol-mut-cyan" );
|
||||
new TColor(kTMutTeal, 68./255, 170./255, 153./255, "tol-mut-teal" );
|
||||
new TColor(kTMutGreen, 17./255, 119./255, 51./255, "tol-mut-green" );
|
||||
new TColor(kTMutOlive, 153./255, 153./255, 51./255, "tol-mut-olive" );
|
||||
new TColor(kTMutSand, 221./255, 204./255, 119./255, "tol-mut-sand" );
|
||||
new TColor(kTMutRose, 204./255, 102./255, 119./255, "tol-mut-rose" );
|
||||
new TColor(kTMutWine, 136./255, 34./255, 85./255, "tol-mut-wine" );
|
||||
new TColor(kTMutPurple, 170./255, 68./255, 153./255, "tol-mut-purple" );
|
||||
new TColor(kTMutPaleGrey, 221./255, 221./255, 221./255, "tol-mut-palegrey" );
|
||||
|
||||
// Light color scheme
|
||||
new TColor(kTLigLightBlue, 119./255, 170./255, 221./255, "tol-lig-lightblue" );
|
||||
new TColor(kTLigLightCyan, 153./255, 221./255, 255./255, "tol-lig-lightcyan" );
|
||||
new TColor(kTLigMint, 68./255, 187./255, 153./255, "tol-lig-mint" );
|
||||
new TColor(kTLigPear, 187./255, 204./255, 51./255, "tol-lig-pear" );
|
||||
new TColor(kTLigOlive, 170./255, 170./255, 0./255, "tol-lig-olive" );
|
||||
new TColor(kTLigLightYellow, 238./255, 221./255, 136./255, "tol-lig-lightyellow");
|
||||
new TColor(kTLigOrange, 238./255, 136./255, 102./255, "tol-lig-orange" );
|
||||
new TColor(kTLigPink, 255./255, 170./255, 187./255, "tol-lig-pink" );
|
||||
new TColor(kTLigPaleGrey, 221./255, 221./255, 221./255, "tol-lig-palegrey" );
|
||||
|
||||
new TColor(kTBadData, 255./255, 238./255, 153./255, "tol-bad-data" );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // COLORS_HH
|
621
Code/FCNCFitter/sources/Helpers/design.cc
Normal file
621
Code/FCNCFitter/sources/Helpers/design.cc
Normal file
@ -0,0 +1,621 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <design.hh>
|
||||
|
||||
#include <constants.hh>
|
||||
#include <helpers.hh>
|
||||
#include <TROOT.h>
|
||||
#include <TBox.h>
|
||||
#include <TPaveText.h>
|
||||
#include <TF1.h>
|
||||
#include <TLegend.h>
|
||||
#include <TMultiGraph.h>
|
||||
#include <TStyle.h>
|
||||
#include <TFile.h>
|
||||
#include <TGaxis.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
//=========================================
|
||||
//
|
||||
// Latex in plots
|
||||
//
|
||||
//=========================================
|
||||
|
||||
std::string latex_decay(bool DTF){
|
||||
//return "K_{S}^{0}#pi^{+}#mu^{+}#mu^{-}";
|
||||
if (DTF) return "K^{+}#pi^{0}#mu^{+}#mu^{-}";
|
||||
else return "#K^{+}#gamma#gamma#mu^{+}#mu^{-}";
|
||||
}
|
||||
|
||||
std::string latex_Kst_decay(bool DTF){
|
||||
if (DTF) return "K^{+}#pi^{0}";
|
||||
else return "#K^{+}#gamma#gamma";
|
||||
}
|
||||
|
||||
std::string MeVc(){
|
||||
return "MeV";
|
||||
}
|
||||
std::string GeVc(){
|
||||
return "GeV";
|
||||
}
|
||||
std::string GeVc_2(){
|
||||
return "GeV^{2}";
|
||||
}
|
||||
|
||||
std::string latex_pull(){
|
||||
return "(x-x_{0})/#sigma";
|
||||
}
|
||||
|
||||
std::string latex_angle(std::string angle, bool &is_ctl, bool &is_ctk, bool &is_phi){
|
||||
|
||||
if(strcmp(angle.c_str(), "ctk") == 0){
|
||||
is_ctk = true;
|
||||
return "cos(#Theta_{K})";
|
||||
}
|
||||
else if(strcmp(angle.c_str(), "ctl") == 0){
|
||||
is_ctl = true;
|
||||
return "cos(#Theta_{L})";
|
||||
}
|
||||
else if(strcmp(angle.c_str(), "phi") == 0){
|
||||
is_phi = true;
|
||||
return "#phi [rad]";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
//Define the angles as chars, because ROOT
|
||||
//Very not cool, but also very not cool
|
||||
//of ROOT to not accept strings and I cannot be bothered
|
||||
const char *LATEX_Q2_CH() { return LATEX_Q2.c_str(); }
|
||||
const char *LATEX_TL_CH() { return LATEX_TL.c_str(); }
|
||||
const char *LATEX_CTL_CH(){ return LATEX_CTL.c_str();}
|
||||
const char *LATEX_TK_CH() { return LATEX_TK.c_str(); }
|
||||
const char *LATEX_CTK_CH(){ return LATEX_CTK.c_str();}
|
||||
const char *LATEX_PHI_CH(){ return LATEX_PHI.c_str();}
|
||||
|
||||
std::string q2_label(double low_q2, double high_q2){
|
||||
std::ostringstream qqbin; //TODO
|
||||
qqbin << std::fixed << std::setprecision(2) <<low_q2<< " < q^{2} < " << high_q2;
|
||||
return qqbin.str();
|
||||
|
||||
}
|
||||
//=========================================
|
||||
//
|
||||
// General
|
||||
//
|
||||
//=========================================
|
||||
|
||||
void set_gStyle(){
|
||||
gStyle->SetOptStat(0);
|
||||
gStyle->SetOptFit(0);
|
||||
gStyle->SetLabelFont(132, "xyz");
|
||||
gStyle->SetTitleFont(132, "xyz");
|
||||
gStyle->SetLegendFont(132);
|
||||
gStyle->SetStatFont(132);
|
||||
gStyle->SetPaintTextFormat(".1f");
|
||||
}
|
||||
|
||||
//Save canvas with a given name and automatically append the type
|
||||
//Type should be specified without the dot, so eg "eps" instead of ".eps
|
||||
void saveTCanvas(TCanvas *c, std::string name, std::string type){
|
||||
c->Print((name+"."+type).c_str(), type.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
//Save several file types in one go
|
||||
void saveTCanvas(TCanvas *c, std::string name, std::vector<std::string> types){
|
||||
for (auto type: types) saveTCanvas(c,name,type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
TLine *threeSigmaLine(double min, double max, bool plus){
|
||||
int sigma = plus ? +3.0 : -3.0;
|
||||
TLine * line = new TLine(min, sigma, max, sigma);
|
||||
line->SetLineStyle(5);
|
||||
line->SetLineWidth(gStyle->GetLineWidth());
|
||||
return line;
|
||||
}
|
||||
TLine *oneSigmaLine(double min, double max, bool plus){
|
||||
int sigma = plus ? +1.0 : -1.0;
|
||||
TLine * line = new TLine(min, sigma, max, sigma);
|
||||
line->SetLineStyle(7);
|
||||
line->SetLineWidth(gStyle->GetLineWidth());
|
||||
return line;
|
||||
}
|
||||
|
||||
void plotAndSave(TH1D *hist, std::string canvasName, std::string targetPath, std::string plotType){
|
||||
|
||||
TCanvas* cnvs = new TCanvas(canvasName.c_str(), canvasName.c_str(), 1600, 1200);
|
||||
cnvs->cd();
|
||||
hist->Draw();
|
||||
saveTCanvas(cnvs,targetPath, plotType);
|
||||
|
||||
delete cnvs;
|
||||
return;
|
||||
|
||||
}
|
||||
void plotAndSave(TH2D *hist, std::string canvasName, std::string targetPath, std::string plotType){
|
||||
|
||||
TCanvas* cnvs = new TCanvas(canvasName.c_str(), canvasName.c_str(), 1600, 1200);
|
||||
cnvs->cd();
|
||||
hist->Draw("COLZ");
|
||||
saveTCanvas(cnvs,targetPath, plotType);
|
||||
|
||||
delete cnvs;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void plotAndSaveWithLine(TH1D* hist, TF1 *line, std::string canvasName, std::string targetPath, std::string plotType){
|
||||
|
||||
//Create canvas
|
||||
TCanvas* cnvs = new TCanvas(canvasName.c_str(), canvasName.c_str(), 1600, 1200);
|
||||
cnvs->cd();
|
||||
|
||||
//Add legend
|
||||
//TLatex cannot do break lines and I cannot. Even.
|
||||
TPaveText *leg = new TPaveText(0.55,0.65,0.87,0.87);
|
||||
leg->Paint("NDC");
|
||||
leg->SetFillColor(kWhite);
|
||||
leg->SetTextFont(132);
|
||||
//Loop over params and print them
|
||||
for (int n = 0; n < line->GetNpar(); n++){
|
||||
std::ostringstream sParams;
|
||||
sParams << line->GetParName(n) << ": " << std::fixed << std::setprecision(4) << line->GetParameter(n) << "#pm" << line->GetParError(n);
|
||||
leg->AddText(sParams.str().c_str());
|
||||
}
|
||||
|
||||
//Draw
|
||||
hist->Draw("E1");
|
||||
line->Draw("same");
|
||||
leg->Draw("same");
|
||||
|
||||
//Save
|
||||
cnvs->Print((targetPath+"."+plotType).c_str(), plotType.c_str());
|
||||
|
||||
//Delete and return
|
||||
delete leg;
|
||||
delete cnvs;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//Sets TLatex
|
||||
TLatex *getPrettyTex(double TextFontSize, int TextAlign){
|
||||
TLatex *tex = new TLatex();
|
||||
tex->SetNDC(true);
|
||||
tex->SetTextFont(132);
|
||||
tex->SetTextSize(TextFontSize);
|
||||
tex->SetTextAlign(TextAlign);
|
||||
return tex;
|
||||
}
|
||||
|
||||
//Add myThesis tag
|
||||
void addThesistag(double x = 0.6, double y = 0.85, int color = 1, double scaling = 1.0){
|
||||
if (!PLOT_THISTHESIS_TAG) return;
|
||||
TLatex* lhcbtext = getPrettyTex(0.07*scaling, 13);
|
||||
lhcbtext->SetTextColor(color);
|
||||
lhcbtext->DrawLatex(x,y,THISTHESIS_TAG.c_str());
|
||||
return;
|
||||
}
|
||||
//Add lhcb tag
|
||||
void addLHCbtag(double x = 0.6, double y = 0.85, std::string suffix = "", int color = 1, double scaling = 1.0){
|
||||
TLatex* lhcbtext = getPrettyTex(0.07*scaling, 13);
|
||||
lhcbtext->SetTextColor(color);
|
||||
lhcbtext->DrawLatex(x,y,("LHCb "+suffix).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
//=========================================
|
||||
//
|
||||
// Angular correction plots
|
||||
//
|
||||
//=========================================
|
||||
|
||||
//plot eff histograms for angular corrections
|
||||
void plotAngular(TH1D *hist, TH1D *moments, bool write,std::string name,
|
||||
std::string appendix, std::string q2region,
|
||||
TLatex *tex, std::string folderName){
|
||||
TCanvas* c0 = new TCanvas("c0", "c0", 1600, 1200);
|
||||
c0->cd();
|
||||
hist->Scale(hist->GetNbinsX()/hist->Integral());
|
||||
hist->SetMinimum(0.0);
|
||||
hist->Draw();
|
||||
hist->GetYaxis()->SetTitle("Normalized entries (a.u.)");
|
||||
moments->Scale(moments->GetNbinsX()/moments->Integral());
|
||||
addLHCbtag(0.15,0.27,"simulation",1,1.0);
|
||||
addThesistag(0.15,0.20,1,0.9);
|
||||
moments->Draw("samel");
|
||||
|
||||
if (q2region != "") tex->DrawLatex(0.85, 0.15, q2region.c_str());
|
||||
if (write) saveTCanvas(c0,folderName+name+appendix,"eps");
|
||||
delete c0;
|
||||
}
|
||||
|
||||
//Overload the plot without plotting q2 region
|
||||
void plotAngular(TH1D *hist, TH1D *moments, bool write,std::string name, std::string appendix, std::string folderName){
|
||||
TLatex *tex = new TLatex();
|
||||
plotAngular(hist, moments, write, name, appendix, "", tex, folderName);
|
||||
}
|
||||
|
||||
//plot 2D histograms for angular corrections
|
||||
void plotAngular(TH2D *hist, TH2D *moments, bool write, std::string name, std::string appendix, std::string q2region, TLatex *tex, std::string folderName){
|
||||
TCanvas* c0 = new TCanvas("c0", "c0", 1600, 800);
|
||||
c0->Divide(2,1);
|
||||
c0->cd(1);
|
||||
hist->Scale(hist->GetNbinsX()*hist->GetNbinsY()/hist->Integral());
|
||||
hist->SetMinimum(0.0);
|
||||
hist->SetMaximum(1.4);
|
||||
hist->Draw("colz");
|
||||
c0->cd(2);
|
||||
moments->Scale(moments->GetNbinsX()*moments->GetNbinsY()/moments->Integral());
|
||||
moments->SetMinimum(0.0);
|
||||
moments->SetMaximum(1.4);
|
||||
moments->Draw("colz");
|
||||
if (q2region != "") tex->DrawLatex(0.85, 0.15, q2region.c_str());
|
||||
if (write) saveTCanvas(c0,folderName+name+appendix,"eps");
|
||||
delete c0;
|
||||
}
|
||||
|
||||
//Overload the plot without plotting q2 region
|
||||
void plotAngular(TH2D *hist, TH2D *moments, bool write,std::string name, std::string appendix, std::string folderName){
|
||||
TLatex *tex = new TLatex();
|
||||
plotAngular(hist, moments, write, name, appendix, "", tex, folderName);
|
||||
}
|
||||
|
||||
//Plot all the angular corrections in one canvas
|
||||
void plotAngularInOne(TCanvas *c, int whichC, TH1D *moments, TH1D *ub, TH1D *hist, TH1D* ml, bool run_minuit, double q2min, double q2max, double y, bool cross){
|
||||
c->cd(whichC)->SetMargin(0.15,0.05,0.1,0.05);
|
||||
moments->Draw("l");
|
||||
|
||||
TLine* line= new TLine();
|
||||
line->SetLineStyle(kDashed);
|
||||
if (cross){
|
||||
line->SetLineColor(kGray+1);
|
||||
line->DrawLine(q2min, -0.5, q2max, +0.5);
|
||||
line->DrawLine(q2min, +0.5, q2max, -0.5);
|
||||
}
|
||||
else{
|
||||
ub->Draw("same");
|
||||
hist->Draw("same");
|
||||
if (run_minuit) ml->Draw("lsame");
|
||||
line->SetLineColor(kRed);
|
||||
line->DrawLine(q2min, y, q2max, y);
|
||||
}
|
||||
}
|
||||
|
||||
//Label axes for angular correction polynomial scan
|
||||
void labelAngularScan(std::vector<int>scan_low, std::vector<int>scan_range,TH2D *hist){
|
||||
|
||||
//label the x-axis
|
||||
//loop over the range in thetak and thetal and print all possible combination
|
||||
for(int tk = 0; tk < scan_range.at(1); tk++){
|
||||
for(int tl = 0; tl < scan_range.at(2); tl++){
|
||||
hist->GetXaxis()->SetBinLabel(tk * scan_range.at(2) + tl + 1, //+1 because bins start at 1
|
||||
("#bf{"+std::to_string(tk+scan_low.at(1))+"} - "+std::to_string(tl+scan_low.at(2))).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
//label the y-axis
|
||||
for(int qq = 0; qq < scan_range.at(0); qq++){
|
||||
for(int fi =0; fi < scan_range.at(3); fi++){
|
||||
hist->GetYaxis()->SetBinLabel(qq * scan_range.at(3) + fi + 1,
|
||||
("#bf{"+std::to_string(qq+scan_low.at(0))+"} - "+std::to_string(fi+scan_low.at(3))).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
//draw labels on x-axis vertically
|
||||
hist->GetXaxis()->LabelsOption("v");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//=========================================
|
||||
//
|
||||
// Fit results plots
|
||||
//
|
||||
//=========================================
|
||||
int design_pull_basic(TH1D *pull, Float_t textsize, double eff_pullHeight){
|
||||
pull->GetXaxis()->SetNoExponent(); //<-- spoils MaxDigits settings, so don't use it on other axis
|
||||
pull->GetXaxis()->SetNdivisions(gStyle->GetNdivisions("X"));
|
||||
|
||||
pull->GetYaxis()->SetTitleSize(textsize/eff_pullHeight);
|
||||
pull->GetYaxis()->SetLabelSize(textsize/eff_pullHeight);
|
||||
pull->GetYaxis()->SetTitleOffset(gStyle->GetTitleOffset()*eff_pullHeight);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int design_pull(TH1D *pull, Color_t lineColor, Color_t fillColor, double eff_pullHeight, double pullFrameRange){
|
||||
Float_t textsize = gStyle->GetTextSize();
|
||||
pull->GetXaxis()->SetTitleOffset(1.05);
|
||||
design_pull_basic(pull, textsize, eff_pullHeight);
|
||||
|
||||
pull->GetXaxis()->SetTitleSize (textsize/eff_pullHeight);
|
||||
pull->GetXaxis()->SetLabelSize (textsize/eff_pullHeight);
|
||||
pull->GetXaxis()->SetTickLength (pull->GetXaxis()->GetTickLength()/(eff_pullHeight/(1-eff_pullHeight)));
|
||||
|
||||
pull->GetYaxis()->CenterTitle();
|
||||
pull->GetYaxis()->SetNdivisions (3, 9, 0, kTRUE);//gStyle->GetNdivisions("Y"));
|
||||
pull->GetYaxis()->SetRangeUser (-pullFrameRange, pullFrameRange);
|
||||
pull->SetFillColor(fillColor);
|
||||
pull->SetLineColor(lineColor);
|
||||
pull->SetLineWidth(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int design_pull(TGraphErrors *pull, Color_t lineColor, Color_t fillColor, double eff_pullHeight, double pullFrameRange){
|
||||
Float_t textsize = gStyle->GetTextSize();
|
||||
pull->GetXaxis()->SetTitleOffset(1.05);
|
||||
pull->GetXaxis()->SetNoExponent(); //<-- spoils MaxDigits settings, so don't use it on other axis
|
||||
|
||||
pull->GetYaxis()->SetTitleSize(textsize/eff_pullHeight);
|
||||
pull->GetYaxis()->SetLabelSize(textsize/eff_pullHeight);
|
||||
pull->GetYaxis()->SetTitleOffset(gStyle->GetTitleOffset()*eff_pullHeight);
|
||||
|
||||
pull->GetXaxis()->SetTitleSize (textsize/eff_pullHeight);
|
||||
pull->GetXaxis()->SetLabelSize (textsize/eff_pullHeight);
|
||||
pull->GetXaxis()->SetTickLength (pull->GetXaxis()->GetTickLength()/(eff_pullHeight/(1-eff_pullHeight)));
|
||||
|
||||
pull->GetYaxis()->CenterTitle();
|
||||
pull->GetYaxis()->SetRangeUser (-pullFrameRange, pullFrameRange);
|
||||
pull->SetFillColor(fillColor);
|
||||
pull->SetLineColor(lineColor);
|
||||
pull->SetLineWidth(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void drawResonances(TCanvas *c, double min, double max){
|
||||
c->cd();
|
||||
TBox* box = new TBox();
|
||||
box->SetFillColor(21);
|
||||
box->SetLineColor(21);
|
||||
box->SetFillStyle(1001);
|
||||
box->DrawBox(0.98, min, 1.10, max);
|
||||
box->DrawBox(8.0, min, 11.0, max);
|
||||
box->DrawBox(12.5, min, 15.0, max);
|
||||
c->Update(); //Probably not needed, but just ot be sure
|
||||
return;
|
||||
}
|
||||
void drawResonances(TPad *c, double min, double max){
|
||||
c->cd();
|
||||
TBox* box = new TBox();
|
||||
box->SetFillColor(21);
|
||||
box->SetLineColor(21);
|
||||
box->SetFillStyle(1001);
|
||||
box->DrawBox(0.98, min, 1.10, max);
|
||||
box->DrawBox(8.0, min, 11.0, max);
|
||||
box->DrawBox(12.5, min, 15.0, max);
|
||||
c->Update(); //Probably not needed, but just ot be sure
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void designTGraph(TGraphErrors *graph, std::string title, std::string xAxisName, std::string yAxisName, Color_t color, Int_t markerStyle){
|
||||
graph->SetName(title.c_str());
|
||||
graph->SetLineColor(color);
|
||||
//graph->SetLineWidth(0);
|
||||
graph->SetMarkerStyle(markerStyle);
|
||||
graph->SetMarkerColor(color);
|
||||
graph->GetXaxis()->SetTitle(xAxisName.c_str());
|
||||
graph->GetYaxis()->SetTitle(yAxisName.c_str());
|
||||
|
||||
graph->GetXaxis()->SetTitleOffset(1.0);
|
||||
graph->GetYaxis()->SetTitleOffset(1.7);
|
||||
graph->SetTitle("");
|
||||
graph->GetXaxis()->SetLabelSize(0.09);
|
||||
graph->GetYaxis()->SetLabelSize(0.09);
|
||||
graph->GetXaxis()->SetTitleSize(0.07);
|
||||
graph->GetYaxis()->SetTitleSize(0.05);
|
||||
return;
|
||||
}
|
||||
|
||||
void designMultiGraph(TMultiGraph *multGraph, std::string title, std::string xAxisName, std::string yAxisName){
|
||||
|
||||
//One needs to draw the multGraph first!
|
||||
multGraph->SetName(title.c_str());
|
||||
multGraph->GetXaxis()->SetTitle(xAxisName.c_str());
|
||||
multGraph->GetYaxis()->SetTitle(yAxisName.c_str());
|
||||
gStyle->SetOptStat(0);
|
||||
|
||||
multGraph->GetXaxis()->SetTitleOffset(1.0);
|
||||
multGraph->GetYaxis()->SetTitleOffset(1.4);
|
||||
multGraph->SetTitle("");
|
||||
multGraph->GetXaxis()->SetLabelSize(0.05);
|
||||
multGraph->GetYaxis()->SetLabelSize(0.05);
|
||||
multGraph->GetXaxis()->SetTitleSize(0.05);
|
||||
multGraph->GetYaxis()->SetTitleSize(0.055);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int design_YieldInQ2(int Run, TGraphErrors *graphSig, TGraphErrors *graphBkg, TGraphErrors *graphSignificance, TGraphErrors *CMS, bool fixRange, std::string savePath, std::vector<std::string> extensions){
|
||||
|
||||
std::string mainName = "Q2_Run" + std::to_string(Run);
|
||||
double y_scale = 1.5;
|
||||
double y_scale_1 = (Run==1) ? 2.5 : 1.75;
|
||||
|
||||
//Create a TCanvas
|
||||
TCanvas *c = new TCanvas(mainName.c_str(),mainName.c_str(),750, 575);
|
||||
c->SetRightMargin(0.13);
|
||||
c->SetLeftMargin(0.23);
|
||||
c->SetTopMargin(0.075);
|
||||
c->SetBottomMargin(0.12);
|
||||
c->cd();
|
||||
|
||||
designTGraph(graphSig,"Signal","Q2","Yield",kBlack,20);
|
||||
designTGraph(graphBkg,"Background","Q2","Yield",kRed,20);
|
||||
graphSig->SetLineStyle(1);
|
||||
graphSig->SetLineWidth(1);
|
||||
graphSig->SetMarkerSize(0.5);
|
||||
graphBkg->SetLineStyle(1);
|
||||
graphBkg->SetLineWidth(1);
|
||||
graphBkg->SetMarkerSize(0.65);
|
||||
|
||||
designTGraph(graphSignificance,"Significance","Q2","S/(S+B)",kBlue,20);
|
||||
designTGraph(CMS,"Significance_CMS","Q2","S/(S+B)",kGreen+2,20);
|
||||
|
||||
graphSignificance->GetYaxis()->SetRangeUser(0.0,graphSignificance->GetY()[0]*y_scale);
|
||||
graphSignificance->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE);
|
||||
CMS->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE);
|
||||
graphSignificance->SetLineWidth(3);
|
||||
CMS->SetLineWidth(3);
|
||||
|
||||
//Create multigraphs
|
||||
TMultiGraph *mg = new TMultiGraph();
|
||||
mg->Add(graphSig,"AP");
|
||||
mg->Add(graphBkg,"AP");
|
||||
mg->Draw("AP");
|
||||
mg->GetYaxis()->SetRangeUser(0.0,graphBkg->GetY()[1]*y_scale);
|
||||
mg->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE);
|
||||
designMultiGraph(mg,"","q^{2} [GeV^{2}]","Yield");
|
||||
|
||||
TMultiGraph *mg_FoM = new TMultiGraph();
|
||||
mg_FoM->Add(graphSignificance,"AP");
|
||||
mg_FoM->Add(CMS,"AP");
|
||||
mg_FoM->Draw("AP");
|
||||
mg_FoM->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE);
|
||||
designMultiGraph(mg_FoM,"","q^{2} [GeV^{2}]","S/(S+B)");
|
||||
|
||||
|
||||
//Create two pads (to get significance y-axis on the right)
|
||||
TPad *pad1 = new TPad("pad1","",0,0,1,1);
|
||||
TPad *pad2 = new TPad("pad2","",0,0,1,1);
|
||||
|
||||
pad2->SetFillStyle(4000); //will be transparent
|
||||
pad2->SetFrameFillStyle(0);
|
||||
|
||||
pad1->SetRightMargin(0.13);
|
||||
pad1->SetLeftMargin(0.15);
|
||||
pad1->SetTopMargin(0.07);
|
||||
pad1->SetBottomMargin(0.12);
|
||||
|
||||
pad2->SetRightMargin(0.13);
|
||||
pad2->SetLeftMargin(0.15);
|
||||
pad2->SetTopMargin(0.07);
|
||||
pad2->SetBottomMargin(0.12);
|
||||
|
||||
pad1->Draw();
|
||||
pad1->cd();
|
||||
|
||||
//Add legends
|
||||
TLegend *leg = new TLegend(0.15,0.93,0.52,0.82);
|
||||
leg->AddEntry(graphSig, "Signal yield","l");
|
||||
leg->AddEntry(graphBkg, "Background yield","l");
|
||||
|
||||
TLegend *legSignificance = new TLegend(0.52,0.93,0.8,0.82);
|
||||
legSignificance->AddEntry(graphSignificance, "Significance","l");
|
||||
legSignificance->AddEntry(CMS, "CMS","l");
|
||||
|
||||
//Plot it
|
||||
pad1->cd();
|
||||
gStyle->SetGridColor(kGray);
|
||||
pad1->SetGridy();
|
||||
pad1->SetGridx();
|
||||
mg->Draw("SAME");
|
||||
mg->GetYaxis()->SetTitle("Yield");
|
||||
mg->GetYaxis()->SetRangeUser(0.0,graphBkg->GetY()[1]*y_scale);
|
||||
mg->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE);
|
||||
mg->GetXaxis()->SetLabelSize(0);
|
||||
mg->GetYaxis()->SetTickLength(0);
|
||||
leg->Draw("SAME");
|
||||
pad1->Update();
|
||||
c->cd();
|
||||
|
||||
pad2->Draw();
|
||||
pad2->cd();
|
||||
//Get axis on the left side
|
||||
TGaxis *axis = new TGaxis(Q2_MAX_RANGE,0.0,Q2_MAX_RANGE,graphSignificance->GetY()[0]*y_scale_1,0,graphSignificance->GetY()[0]*y_scale_1,510,"+L");
|
||||
axis->SetTitle("S/sqrt(S+B)");
|
||||
axis->SetTextFont(21);
|
||||
mg_FoM->Draw("AP");
|
||||
mg_FoM->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE);
|
||||
mg_FoM->GetYaxis()->SetRangeUser(0.0,graphSignificance->GetY()[0]*y_scale_1);
|
||||
mg_FoM->GetYaxis()->SetLabelSize(0);
|
||||
mg_FoM->GetYaxis()->SetTickLength(0);
|
||||
mg_FoM->GetYaxis()->SetTitle("");
|
||||
axis->Draw("SAME");
|
||||
legSignificance->Draw("SAME");
|
||||
pad2->Update();
|
||||
c->cd();
|
||||
|
||||
//Save it
|
||||
if (!fixRange) savePath = savePath + "_sigma";
|
||||
TFile *file = new TFile ((savePath+".root").c_str(), "RECREATE");
|
||||
file->cd();
|
||||
graphSig->Write();
|
||||
graphBkg->Write();
|
||||
graphSignificance->Write();
|
||||
CMS->Write();
|
||||
c->Write();
|
||||
file->Close();
|
||||
saveTCanvas(c,savePath,extensions);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int design_SignificanceInQ2(int Run, TGraphErrors *graphSignificance, TGraphErrors *CMS, bool fixRange, std::string savePath, std::vector<std::string>extensions){
|
||||
|
||||
std::string mainName = "Q2_Run" + std::to_string(Run);
|
||||
double y_scale = 1.4;
|
||||
|
||||
//Create a TCanvas
|
||||
TCanvas *c = new TCanvas(mainName.c_str(),mainName.c_str(),750, 600);
|
||||
c->SetRightMargin(0.13);
|
||||
c->SetLeftMargin(0.15);
|
||||
c->SetTopMargin(0.07);
|
||||
c->SetBottomMargin(0.12);
|
||||
gStyle->SetGridColor(kGray);
|
||||
c->SetGridy();
|
||||
c->SetGridx();
|
||||
c->SetBottomMargin(0.16);
|
||||
|
||||
|
||||
designTGraph(graphSignificance,"Significance","Q2","S/(S+B)",kBlue,20);
|
||||
designTGraph(CMS,"Significance_CMS","Q2","S/(S+B)",kGreen+2,20);
|
||||
|
||||
graphSignificance->GetYaxis()->SetRangeUser(0.0,graphSignificance->GetY()[0]*y_scale);
|
||||
graphSignificance->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE);
|
||||
CMS->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE);
|
||||
graphSignificance->SetLineWidth(3);
|
||||
CMS->SetLineWidth(3);
|
||||
|
||||
//Create multigraph
|
||||
TMultiGraph *mg_FoM = new TMultiGraph();
|
||||
mg_FoM->Add(graphSignificance,"AP");
|
||||
mg_FoM->Add(CMS,"AP");
|
||||
mg_FoM->Draw("AP");
|
||||
designMultiGraph(mg_FoM,"","q^{2} [GeV^{2}]","S/(S+B)");
|
||||
|
||||
|
||||
//Add legend
|
||||
TLegend *legSignificance = new TLegend(0.35,0.9,0.65,0.75);
|
||||
legSignificance->AddEntry(graphSignificance, "Significance","l");
|
||||
legSignificance->AddEntry(CMS, "CMS","l");
|
||||
|
||||
//Plot it
|
||||
c->cd();
|
||||
mg_FoM->Draw("AP");
|
||||
mg_FoM->GetYaxis()->SetTitle("S/(S+B)");
|
||||
mg_FoM->GetXaxis()->SetRangeUser(Q2_MIN_RANGE,Q2_MAX_RANGE);
|
||||
mg_FoM->GetYaxis()->SetRangeUser(0.0,graphSignificance->GetY()[0]*y_scale);
|
||||
mg_FoM->GetXaxis()->SetTitle("q^{2} [GeV^{2}]");
|
||||
legSignificance->Draw("SAME");
|
||||
c->Update();
|
||||
|
||||
//Save it
|
||||
if (!fixRange) savePath = savePath + "_sigma";
|
||||
TFile *file = new TFile ((savePath+".root").c_str(), "RECREATE");
|
||||
file->cd();
|
||||
graphSignificance->Write();
|
||||
CMS->Write();
|
||||
c->Write();
|
||||
file->Close();
|
||||
saveTCanvas(c,savePath,extensions);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
96
Code/FCNCFitter/sources/Helpers/design.hh
Normal file
96
Code/FCNCFitter/sources/Helpers/design.hh
Normal file
@ -0,0 +1,96 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef DESIGN_HH
|
||||
#define DESIGN_HH
|
||||
|
||||
#include <TH1D.h>
|
||||
#include <TH2D.h>
|
||||
#include <TCanvas.h>
|
||||
#include <TGraphErrors.h>
|
||||
#include <TLine.h>
|
||||
#include <TLatex.h>
|
||||
|
||||
//=========================================
|
||||
//
|
||||
// Latex in plots
|
||||
//
|
||||
//=========================================
|
||||
|
||||
std::string latex_decay(bool DTF);
|
||||
std::string latex_Kst_decay(bool DTF);
|
||||
std::string MeVc();
|
||||
std::string GeVc();
|
||||
std::string GeVc_2();
|
||||
std::string latex_pull();
|
||||
std::string latex_angle(std::string angle, bool &is_ctl, bool &is_ctk, bool &is_phi);
|
||||
const std::string LATEX_Q2 = "q^{2}";
|
||||
const std::string LATEX_TL = "#theta_{L}";
|
||||
const std::string LATEX_CTL = "cos#theta_{L}";
|
||||
const std::string LATEX_TK = "#theta_{K}";
|
||||
const std::string LATEX_CTK = "cos#theta_{K}";
|
||||
const std::string LATEX_PHI = "#phi";
|
||||
const std::string EVENTS_TAG = "Weighted candidates";
|
||||
|
||||
//Define the angles as chars, because ROOT
|
||||
//Very not cool to have a function here, but also very not
|
||||
//cool of ROOT to not accept strings and I cannot be bothered
|
||||
const char *LATEX_Q2_CH();
|
||||
const char *LATEX_TL_CH();
|
||||
const char *LATEX_CTL_CH();
|
||||
const char *LATEX_TK_CH();
|
||||
const char *LATEX_CTK_CH();
|
||||
const char *LATEX_PHI_CH();
|
||||
|
||||
const Color_t pWaveColor = kSpring;
|
||||
const Color_t sWaveColor = kOrange;
|
||||
const Color_t psInterferenceColor = kMagenta-10;
|
||||
|
||||
|
||||
std::string q2_label(double low_q2, double high_q2);
|
||||
|
||||
//=========================================
|
||||
//
|
||||
// General
|
||||
//
|
||||
//=========================================
|
||||
|
||||
void set_gStyle();
|
||||
//Save several file types in one go
|
||||
void saveTCanvas(TCanvas *c, std::string name, std::vector<std::string> types);
|
||||
TLine *threeSigmaLine(double min, double max, bool plus);
|
||||
TLine *oneSigmaLine(double min, double max, bool plus);
|
||||
|
||||
void plotAndSave(TH1D *hist, std::string canvasName, std::string targetPath, std::string plotType);
|
||||
void plotAndSave(TH2D *hist, std::string canvasName, std::string targetPath, std::string plotType);
|
||||
void plotAndSaveWithLine(TH1D* hist, TF1 *line, std::string canvasName, std::string targetPath, std::string plotType);
|
||||
TLatex *getPrettyTex(double TextFontSize, int TextAlign);
|
||||
|
||||
//=========================================
|
||||
//
|
||||
// Angular correction plots
|
||||
//
|
||||
//=========================================
|
||||
void plotAngular(TH1D *hist, TH1D *moments, bool write, std::string name, std::string appendix, std::string q2region, TLatex *tex, std::string folderName);
|
||||
void plotAngular(TH1D *hist, TH1D *moments, bool write, std::string name, std::string appendix, std::string folderName);
|
||||
void plotAngular(TH2D *hist, TH2D *moments, bool write, std::string name, std::string appendix, std::string q2region, TLatex *tex, std::string folderName);
|
||||
void plotAngular(TH2D *hist, TH2D *moments, bool write, std::string name, std::string appendix, std::string folderName);
|
||||
void plotAngularInOne(TCanvas *c, int whichC, TH1D *moments, TH1D *ub, TH1D *hist, TH1D* ml, bool run_minuit, double q2min, double q2max, double y, bool cross);
|
||||
void labelAngularScan(std::vector<int>scan_low, std::vector<int>scan_range,TH2D *hist);
|
||||
|
||||
|
||||
//=========================================
|
||||
//
|
||||
// Fit results plots
|
||||
//
|
||||
//=========================================
|
||||
int design_pull_basic(TH1D *pull, Float_t textsize, double eff_pullHeight);
|
||||
int design_pull(TH1D *pull, Color_t lineColor, Color_t fillColor, double eff_pullHeight, double pullFrameRange);
|
||||
int design_pull(TGraphErrors *pull, Color_t lineColor, Color_t fillColor, double eff_pullHeight, double pullFrameRange);
|
||||
//Draw shaded boxes at q2 regions of resonances
|
||||
void drawResonances(TCanvas *c, double min, double max);
|
||||
void drawResonances(TPad *c, double min, double max);
|
||||
|
||||
int design_YieldInQ2(int Run, TGraphErrors *graphSig, TGraphErrors *graphBkg, TGraphErrors *graphSignificance, TGraphErrors *CMS, bool fixRange, std::string savePath, std::vector<std::string> extensions);
|
||||
int design_SignificanceInQ2(int Run, TGraphErrors *graphSignificance, TGraphErrors *CMS, bool fixRange, std::string savePath, std::vector<std::string> extensions);
|
||||
|
||||
#endif // DESIGN_HH
|
1217
Code/FCNCFitter/sources/Helpers/helpers.cc
Normal file
1217
Code/FCNCFitter/sources/Helpers/helpers.cc
Normal file
File diff suppressed because it is too large
Load Diff
229
Code/FCNCFitter/sources/Helpers/helpers.hh
Normal file
229
Code/FCNCFitter/sources/Helpers/helpers.hh
Normal file
@ -0,0 +1,229 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef HELPERS_HH
|
||||
#define HELPERS_HH
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <TF1.h>
|
||||
#include <TH1D.h>
|
||||
#include <TStopwatch.h>
|
||||
#include <parse.hh>
|
||||
|
||||
//indexed auto looping over vectors
|
||||
#define for_indexed(...) for_indexed_v(i, __VA_ARGS__)
|
||||
#define for_indexed_v(v, ...) for(bool _i_ = true, _break_ = false; _i_;) for(size_t v = 0; _i_; _i_ = false) for(__VA_ARGS__) if(_break_) break; else for(bool _j_ = true; _j_;) for(_break_ = true; _j_; _j_ = false) for(bool _k_ = true; _k_; v++, _k_ = false, _break_ = false)
|
||||
/// usage:
|
||||
/// std::vector<int> v{1, 2, 3};
|
||||
///for_indexed (auto const& item : v) { //the index is always i
|
||||
/// if (i > 0) std::cout << ", ";
|
||||
/// std::cout << i << ": " << item;
|
||||
///}
|
||||
/// for_indexed_v (my_counter, auto const& item : v) //the index is v here
|
||||
|
||||
|
||||
//TODO: work on more forward declarations, it reduces the compiler time as cross-referencing is not recompiled 400 times anymore
|
||||
//TODO: simirarly move your includes into .cpp in order to avoid this
|
||||
|
||||
namespace fcnc { //Forward declaration, fully defined in options.hh
|
||||
class options;
|
||||
class parameters;
|
||||
class bu2kstarmumu_parameters;
|
||||
class event;
|
||||
}
|
||||
|
||||
|
||||
//----------------------//
|
||||
// Print utils //
|
||||
//----------------------//
|
||||
std::string boolToString(bool isTrue);
|
||||
|
||||
//reset the spdlog into my default
|
||||
void reset_spdlog();
|
||||
|
||||
//set spdlog level
|
||||
void set_spdlog_level(int verboseLvl);
|
||||
|
||||
//what lever is the spdlog?
|
||||
bool spdlog_trace();
|
||||
bool spdlog_debug();
|
||||
bool spdlog_info();
|
||||
bool spdlog_warn();
|
||||
bool spdlog_error();
|
||||
|
||||
//Get job_id and turn it in a string
|
||||
std::string get_sample_from_jobID(int job_id);
|
||||
|
||||
//Make pretty outputs with given precision (feault is two)
|
||||
std::string format_double(double value, unsigned int digits=2);
|
||||
std::string format_value(double value, double error, unsigned int digits=2);
|
||||
std::string format_error(double error, unsigned int digits=2);
|
||||
|
||||
//----------------------//
|
||||
// Year utils //
|
||||
//----------------------//
|
||||
|
||||
//Get years according to a run
|
||||
std::vector<int> get_years(int Run, bool MCsig, bool MCref);
|
||||
//Check if year makes sense
|
||||
void check_year(int year);
|
||||
int get_yearFromRun(int year);
|
||||
|
||||
int MC_dataset(bool Reference, bool PHSP);
|
||||
//--------------------------------------//
|
||||
// General helpers //
|
||||
//--------------------------------------//
|
||||
|
||||
//Copy file
|
||||
int copyFile(std::string from, std::string to);
|
||||
//Check if file/folder exists
|
||||
bool existsTest (const std::string& name);
|
||||
//Create new folder
|
||||
void makeFolder (const std::string& name);
|
||||
|
||||
//Convert vector into number-space-number... string
|
||||
std::string convert_vector_to_string(std::vector<int> myVector);
|
||||
std::string convert_vector_to_string(std::vector<double> myVector);
|
||||
std::string convert_vector_to_string(std::vector<std::string> myVector);
|
||||
|
||||
//Merge two vectors
|
||||
std::vector<double> merge_two_vecs(std::vector<double> one, std::vector<double> two);
|
||||
std::vector<int> merge_two_vecs(std::vector<int> one, std::vector<int> two);
|
||||
std::vector<std::string> merge_two_vecs(std::vector<std::string> one, std::vector<std::string> two);
|
||||
|
||||
//Replace a part of a string
|
||||
bool replace(std::string& str, const std::string& from, const std::string& to);
|
||||
|
||||
//Sum a vectors
|
||||
int sum_vector(std::vector<int> vec);
|
||||
double sum_vector(std::vector<double> vec);
|
||||
|
||||
//Return the center of a bin
|
||||
double bin_center(double low, double high);
|
||||
//Return the center of a q2 bin
|
||||
double bin_center_q2(fcnc::options opts, int b);
|
||||
double bin_center_q2(fcnc::options *opts, int b);
|
||||
double bin_center_q2(std::vector<double> q2min, std::vector<double> q2max , int b);
|
||||
|
||||
//Return half of the width (useful for errors)
|
||||
double bin_halfWidth(double low, double high);
|
||||
double bin_halfWidth_q2(fcnc::options opts, int b);
|
||||
double bin_halfWidth_q2(fcnc::options *opts, int b);
|
||||
double bin_halfWidth_q2(std::vector<double> q2min, std::vector<double> q2max, int b);
|
||||
|
||||
//Check if the angles are in the correct range given by options
|
||||
bool isEvtInAngleRange(fcnc::event *evt, fcnc::options *opts);
|
||||
//Check if the angles are in the correct range given by default
|
||||
bool isEvtInAngleRange(fcnc::event *evt);
|
||||
//For now filter out events that are dumb dumb for folding four
|
||||
bool filterFldFour(fcnc::event *evt, fcnc::options *opts);
|
||||
|
||||
//Check if value is in a vector
|
||||
bool isInVec(int key, std::vector<int>vec);
|
||||
bool isInVec(double key, std::vector<double>vec);
|
||||
bool isInVec(std::string key, std::vector<std::string>vec);
|
||||
|
||||
|
||||
//--------------------------------------//
|
||||
// Helpers for converting the tuples //
|
||||
//--------------------------------------//
|
||||
|
||||
//Return's OG tuple name
|
||||
std::string get_inputTree_name(int job_id);
|
||||
|
||||
//--------------------------------------//
|
||||
// Helpers for angular corrections //
|
||||
//--------------------------------------//
|
||||
|
||||
TF1 *fitStraightLine(TH1D* hist, std::string lineName, double lowEdge, double highEdge);
|
||||
|
||||
//--------------------------------------//
|
||||
// Helpers for bu2kstarmumu_pdf //
|
||||
//--------------------------------------//
|
||||
|
||||
//Returns a vector with the {p wave observables, obervable in tex}, useful for histograms in a loop
|
||||
const std::vector<std::vector<std::string>> get_angObser_withTeX_vec();
|
||||
|
||||
|
||||
//Returns a vector with the p wave observables
|
||||
std::vector<std::string> get_angObser_vec();
|
||||
|
||||
//Returns a vector with the p wave observables in tex
|
||||
std::vector<std::string> get_angObserTeX_vec();
|
||||
|
||||
//--------------------------------------//
|
||||
// Helpers for time measuring //
|
||||
//--------------------------------------//
|
||||
|
||||
struct runTime{
|
||||
//Measure the time for the fit:
|
||||
std::vector<Double_t> real_times;
|
||||
std::vector<Double_t> cpu_times;
|
||||
std::vector<Double_t> cpp_times;
|
||||
TStopwatch * sw;// = new TStopwatch();
|
||||
runTime(){
|
||||
sw = new TStopwatch();
|
||||
}
|
||||
void print(unsigned int nBins);
|
||||
void start();
|
||||
void stop(time_t startTime);
|
||||
};
|
||||
|
||||
//--------------------------------------//
|
||||
// Helpers for fit scripts //
|
||||
//--------------------------------------//
|
||||
|
||||
//get a vector of all available angle bkg parameters
|
||||
std::vector<std::string> param_string_bkg();
|
||||
//get a vector of all available angle mkpi parameters
|
||||
std::vector<std::string> param_string_bkg_mkpi();
|
||||
//get a string vector of all effectivelly used parameters
|
||||
std::vector<std::string> param_string(fcnc::options opts, bool MC);
|
||||
//get a string vector of mass parameters
|
||||
std::vector<std::string> params_string_mass(fcnc::options opts);
|
||||
//Reads MC fit files (massFitOnly) and gets the sigma ratio of ref/MC for given bin and pdf
|
||||
double get_sigmaRatio_fromMC(basic_params params, int nBins, int bin, int pdf);
|
||||
|
||||
//---------------------------------------------//
|
||||
// Helpers for printing and saving fit results //
|
||||
//---------------------------------------------//
|
||||
|
||||
void print_all_parameters(unsigned int nBins, fcnc::bu2kstarmumu_parameters *theParams[],
|
||||
int spdlog_level, std::string savePath);
|
||||
void print_all_parameters(unsigned int nBins, std::vector<UInt_t> pdf_idx,
|
||||
std::vector<fcnc::parameters*> theParams[],
|
||||
int spdlog_level);
|
||||
|
||||
void tex_all_parameters(unsigned int nBins, std::vector<UInt_t> pdf_idx,
|
||||
std::vector<fcnc::parameters*> theParams[]);
|
||||
|
||||
void print_fit_results(unsigned int nBins, std::vector<Int_t> fitresults);
|
||||
void print_fit_results(unsigned int nBins, std::vector<UInt_t> pdf_idx, std::vector<Int_t> fitresults[], bool simFit);
|
||||
void print_sig_yields(unsigned int nBins, std::vector<UInt_t> pdf_idx,
|
||||
std::vector<UInt_t> *evts_cntr, std::vector<double> *f_sigs, std::vector<double> *f_sigserr);
|
||||
void print_bkg_yields(unsigned int nBins, std::vector<UInt_t> pdf_idx,
|
||||
std::vector<UInt_t> *evts_cntr, std::vector<double> *f_sigs, std::vector<double> *f_sigserr);
|
||||
void print_bkgOnly_yields(unsigned int nBins, std::vector<UInt_t> pdf_idx,
|
||||
std::vector<fcnc::bu2kstarmumu_parameters*> theParams[],
|
||||
std::vector<double> bkg_int_full_range[], std::vector<UInt_t> *evts_cntr);
|
||||
void print_sig_yields_tex(std::string texFiletag,
|
||||
unsigned int nBins, std::vector<UInt_t> pdf_idx,
|
||||
fcnc::options *theOptions,
|
||||
std::vector<UInt_t> *evts_cntr, std::vector<double> *f_sigs, std::vector<double> *f_sigserr);
|
||||
|
||||
int save_results(std::string results_file, unsigned int nBins, std::vector<UInt_t> pdf_idx, std::vector<int>*fit_results, std::vector<fcnc::parameters*> *theParams, bool simFit, fcnc::options *opts);
|
||||
int save_results(std::string results_file, unsigned int nBins, int n_pdf, std::vector<int> fit_results, fcnc::bu2kstarmumu_parameters **theParams, fcnc::options *opts);
|
||||
//--------------------------------------//
|
||||
// Helpers for writting latex stuff //
|
||||
//--------------------------------------//
|
||||
|
||||
int clear_Latex_noteFile(std::string tag); //Deletes the old file
|
||||
int open_Latex_noteFile(std::string tag, std::ofstream &myfile); //Appends output at the end of the file
|
||||
|
||||
|
||||
//--------------------------------------//
|
||||
// Helpers for reading the parameters //
|
||||
//--------------------------------------//
|
||||
|
||||
std::vector<double> load_param_values_into_vector(std::string paramName, std::string fileName);
|
||||
#endif // HELPERS_HH
|
512
Code/FCNCFitter/sources/Params/constants.cc
Normal file
512
Code/FCNCFitter/sources/Params/constants.cc
Normal file
@ -0,0 +1,512 @@
|
||||
// Renata Kopecna
|
||||
|
||||
#include <constants.hh>
|
||||
#include <spdlog.h>
|
||||
|
||||
//////////////////////////
|
||||
// Q2 bins //
|
||||
//////////////////////////
|
||||
|
||||
//Return a vector with low bin edges in Q2, depending on the number of bins
|
||||
std::vector<double> get_TheQ2binsmin(int nBins, bool Reference){
|
||||
//choose binning scheme:
|
||||
if (Reference) return {8.68};
|
||||
else if (nBins == 1) return {Q2_MIN_RANGE};
|
||||
else if (nBins == 2) return {Q2_MIN_RANGE, 11.0};
|
||||
else if (nBins == 4) return {Q2_MIN_RANGE, 4.0, 11.0, 15.0}; //Default is 4 bins
|
||||
else if (nBins == 5) return {Q2_MIN_RANGE, 4.0, 11.0, 15.0, 1.1}; //Basics 4 + 1.1-6.0 Gev
|
||||
else if (nBins == 8) return {0.1 , 1.1, 2.5, 4.0, 6.0, 11.0, 15.0, 17.0}; //Same binning as B0 and Ks->PiPi
|
||||
else if (nBins == 9) return {0.1 , 1.1, 2.5, 4.0, 6.0, 8.68, 11.0, 15.0, 17.0}; //Same binning as B0 and Ks->PiPi + Jpsi, useful in MC checks
|
||||
else return {};
|
||||
}
|
||||
|
||||
//Return a vector with upper bin edges in Q2, depending on the number of bins
|
||||
std::vector<double> get_TheQ2binsmax(int nBins, bool Reference){
|
||||
//choose binning scheme
|
||||
if (Reference) return {10.09};
|
||||
else if (nBins == 1) return {Q2_MAX_RANGE};
|
||||
else if (nBins == 2) return {1.0, Q2_MAX_RANGE};
|
||||
else if (nBins == 4) return {4.0, 8.0, 12.5, Q2_MAX_RANGE}; //Default is 4 bins
|
||||
else if (nBins == 5) return {4.0, 8.0, 12.5, Q2_MAX_RANGE, 6.0}; //Basic 4 + 1.1-6.0 Gev
|
||||
else if (nBins == 8) return {0.98, 2.5, 4.0, 6.0, 8.0, 12.5, 17.0, 19.0};//Same binning as B0 and Ks->PiPi
|
||||
else if (nBins == 9) return {0.98, 2.5, 4.0, 6.0, 8.0, 10.09, 12.5, 17.0, 19.0};//Same binning as B0 and Ks->PiPi + Jpsi, useful in MC checks
|
||||
else return {};
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// Angle ranges //
|
||||
//////////////////////////
|
||||
|
||||
//Returns pretty much the max-min for different dimensions
|
||||
double CTL_RANGE(){ return CTL_MAX - CTL_MIN; }
|
||||
double CTK_RANGE(){ return CTK_MAX - CTK_MIN; }
|
||||
double PHI_RANGE(){ return PHI_MAX - PHI_MIN; }
|
||||
|
||||
double Q2_RANGE_FULL(){ return Q2_MAX_RANGE - Q2_MIN_RANGE; }
|
||||
//Same, just in angles or in angles+q2
|
||||
double RANGE_3D(){ return CTL_RANGE()*CTK_RANGE()*PHI_RANGE(); }
|
||||
double RANGE_4D(){ return RANGE_3D()*Q2_RANGE_FULL(); }
|
||||
|
||||
//////////////////////////
|
||||
// RESOLUTION //
|
||||
//////////////////////////
|
||||
/// \brief get_resolution
|
||||
/// \return resolution obtained by angular resolution, used for systematic studies
|
||||
///
|
||||
std::vector<std::vector<double>> get_resolution(){
|
||||
std::vector<std::vector<double>> resolution;
|
||||
resolution.push_back({0.0139, 0.0144, 0.0141, 0.0141, 0.0140, 0.0140});//ctk
|
||||
resolution.push_back({0.00481,0.00504,0.00503,0.00503,0.00497,0.00499});//ctl
|
||||
resolution.push_back({0.0256, 0.0253, 0.0260, 0.0260, 0.0258, 0.0248}); //phi
|
||||
return resolution;
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// Main Fit //
|
||||
//////////////////////////
|
||||
|
||||
//This string contains parameters that are varied when fitting bkg
|
||||
//TODO: I hope this doesn't change perf bin, but wurst käse scenario I add bin argument
|
||||
std::vector<std::string> PAR_BKG_STRING_CTL(int folding, int order){
|
||||
std::vector<std::string> str;
|
||||
for (int ord = 1; ord <= order; ord++){
|
||||
if (ord%2==1 && folding>0) continue; //odd values excluded from folding 1,2,3,4
|
||||
str.push_back("cbkgctl"+std::to_string(ord));
|
||||
}
|
||||
return str;
|
||||
}
|
||||
std::vector<std::string> PAR_BKG_STRING_CTK(int folding, int order){
|
||||
std::vector<std::string> str;
|
||||
for (int ord = 1; ord <= order; ord++){
|
||||
if (ord%2==1 && folding == 4) continue; //odd values excluded from folding 4
|
||||
str.push_back("cbkgctk"+std::to_string(ord));
|
||||
}
|
||||
return str;
|
||||
}
|
||||
std::vector<std::string> PAR_BKG_STRING_PHI(){
|
||||
//For now return an empty string as the phi is flat
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> PAR_BKG_STRING(int folding, int nCtl, int nCtk){
|
||||
std::vector<std::string> str;
|
||||
std::vector<std::string> ctl = PAR_BKG_STRING_CTL(folding,nCtl);
|
||||
std::vector<std::string> ctk = PAR_BKG_STRING_CTK(folding,nCtk);
|
||||
std::vector<std::string> phi = PAR_BKG_STRING_PHI();
|
||||
str.insert(str.end(), ctl.begin(), ctl.end());
|
||||
str.insert(str.end(), ctk.begin(), ctk.end());
|
||||
str.insert(str.end(), phi.begin(), phi.end());
|
||||
return str;
|
||||
}
|
||||
|
||||
//Init values of said parameters
|
||||
//CAREFUL!!!! HAS TO BE THE SAME AS PAR_BKG_STRING!!!!
|
||||
std::vector<double> init_bkg_ctl(int folding, int order){
|
||||
std::vector<double> init_val;
|
||||
for (int ord = 1; ord <= order; ord++){
|
||||
if (ord%2==1 && folding>0) continue; //odd values excluded from foldings 1,2,3,4
|
||||
init_val.push_back(0.02); //Even values always push
|
||||
}
|
||||
return init_val;
|
||||
}
|
||||
std::vector<double> init_bkg_ctk(int folding, int order){
|
||||
std::vector<double> init_val;
|
||||
for (int ord = 1; ord <= order; ord++){
|
||||
if (ord%2==1 && folding==4) continue; //odd values excluded from folding 4
|
||||
if (ord%2==1) init_val.push_back(-0.7);
|
||||
else init_val.push_back(-0.5);
|
||||
}
|
||||
return init_val;
|
||||
}
|
||||
std::vector<double> init_bkg_phi(){
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<double> init_bkg(int folding, int nCtl, int nCtk){
|
||||
std::vector<double> init_val;
|
||||
std::vector<double> ctl = init_bkg_ctl(folding,nCtl);
|
||||
std::vector<double> ctk = init_bkg_ctk(folding,nCtk);
|
||||
std::vector<double> phi = init_bkg_phi();
|
||||
init_val.insert(init_val.end(), ctl.begin(), ctl.end());
|
||||
init_val.insert(init_val.end(), ctk.begin(), ctk.end());
|
||||
init_val.insert(init_val.end(), phi.begin(), phi.end());
|
||||
return init_val;
|
||||
}
|
||||
|
||||
std::vector<std::vector<double> > fracs(int nBins){
|
||||
if(nBins == 5 || nBins == 4){
|
||||
return {{0.040286, 0.060429, 0.016244, 0.012995, 0.051982},
|
||||
{0.246914, 0.434048, 0.115010, 0.074074, 0.348928}};
|
||||
}
|
||||
else {
|
||||
spdlog::error("No event number fractions given for binning scheme with {0:d} q2 bins. Exit", nBins);
|
||||
return std::vector<std::vector<double> >(2, std::vector<double>(nBins, 0.));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<double> init_n_signal(int nBins){ //init the number of sig events
|
||||
if(nBins == 5) return {80., 75., 50., 90., 155.};
|
||||
else if(nBins == 4) return {80., 75., 50., 90.};
|
||||
else if(nBins == 2) return {80.+75., 50.+90.};
|
||||
else if(nBins == 1) return {9591.+41809.};
|
||||
else {
|
||||
spdlog::error("No Signal event numbers given for binning scheme with {0:d} q2 bins. Exit", nBins);
|
||||
assert(0);
|
||||
}
|
||||
return {}; //useles, but compiler would complain
|
||||
}
|
||||
std::vector<double> init_n_bckgnd(int nBins){//init the number of bkg events
|
||||
if(nBins == 5) return {80., 160., 40., 20., 240.};
|
||||
else if(nBins == 4) return {80., 160., 40., 20.};
|
||||
else if(nBins == 2) return {206.+279.+358.+358., 158.+93.};
|
||||
else if(nBins == 1) return {716.+4337.};
|
||||
else {
|
||||
spdlog::error("No Background event numbers given for binning scheme with {0:d} q2 bins. Exit", nBins);
|
||||
assert(0);
|
||||
}
|
||||
return {}; //useles, but compiler would complain
|
||||
}
|
||||
std::vector<double> init_f_lambda(int nBins){ //init lambda
|
||||
if(nBins == 5) return {-0.0064, -0.0064, -0.0065, -0.0065, -0.0064};
|
||||
else if(nBins == 4) return {-0.0064, -0.0064, -0.0065, -0.0065};
|
||||
else if(nBins == 2) return {-0.0064, -0.0065};
|
||||
else if(nBins == 1) return {-0.0044};
|
||||
else {
|
||||
spdlog::error("No values for the exponential background description are given for binning scheme with {0:d} q2 bins. Exit", nBins);
|
||||
assert(0);
|
||||
}
|
||||
return {}; //useles, but compiler would complain
|
||||
}
|
||||
|
||||
std::vector<double> get_f_subset(int nPDFs){
|
||||
//obtained from jpsi channel, data, 5D fit, full range
|
||||
if(nPDFs == 4) return {0., 0., 0., 0.}; //TODO!!!
|
||||
else if(nPDFs == 2) return {0.0, 0.0}; //TODO!!!
|
||||
else if(nPDFs == 1) return {1.};
|
||||
else{
|
||||
spdlog::warn("No values for the signal fraction are given for simultaneous fits with {0:d} pdf's. Use default: f_sig = 0.5", nPDFs);
|
||||
return std::vector<double> (nPDFs, 0.5);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>> init_angular_params(int nBins, bool NP, bool isReference){
|
||||
if (nBins==5){
|
||||
if (NP) return {
|
||||
//predictions from flavio for new physics scenario with C9 = -1.0, using min(Q2) = 0.25 and max(Q2) = 18.0
|
||||
{0.30284413148097966,0.27262304293367756,0.4271747118350757,0.4947224191764013,0.22062375348447547},
|
||||
{0.0016779452277498482,-0.03166521898839871,-0.08541706129465602,-0.18930463721455312,-0.011913104816645514},
|
||||
{-0.03554278140794295,-0.2399493206724746,-0.28043043274306023,-0.296509757783654,-0.14577653963645607},
|
||||
{0.1323358147544716,-0.29136093172458405,-0.37328734325703,-0.2736851726358371,-0.08401219272607802},
|
||||
{-0.18973621926844692,0.1460462265211582,0.4666205500210169,0.468761474000308,-0.08526703027846606},
|
||||
{-0.021811112779860177,-0.01286712550773734,-0.002747600804479865,-0.0014945589348205987,-0.01889737958853306},
|
||||
{-0.00881926856860235,-0.003687673879434568,0.0016256878486157777,0.0005018180644191919,-0.005992663137417108},
|
||||
{-0.0006860405719520938,-0.0006097376632470255,0.0006613554952330075,0.00044525884942171284,-0.0006319657235214326}
|
||||
};
|
||||
else return{
|
||||
//SM predictions from flavio, using min(Q2) = 0.25 and max(Q2) = 18.0
|
||||
{+0.248569008046490070, +0.2581971160208132000, +0.42526014659559220000, +0.49420669353506260000, +0.1850102996703149000}, //s1s
|
||||
{+0.000732569649322501, -0.0324523859139632900, -0.08563864422457230000, -0.18934424485647136000, -0.0130310503598977030}, //s3
|
||||
{-0.028317693174889150, -0.2425837027660650600, -0.28116530113868093000, -0.29668531019781386000, -0.1468982883895949300}, //s4
|
||||
{+0.035479698896675250, -0.3745017565795041000, -0.40726931726860705000, -0.30161750053585110000, -0.1915219985323076700}, //s5
|
||||
{-0.122319885918514240, +0.2473816826915200600, +0.52432045165541470000, +0.52106439209368990000, +0.0147578966169414490}, //s6s
|
||||
{-0.019468600975846337, -0.0105435770924197210, -0.00219285191192886900, -0.00119446595061885200, -0.0160492529928752330}, //s7
|
||||
{-0.010192773160727949, -0.0043019891737210840, +0.00104987431866559550, +0.00027244645255727460, -0.0070279543261629670}, //s8
|
||||
{-0.000756965302130655, -0.0006959911482550733, +0.00044741790607562027, +0.00026464193866571387, -0.0007199408885633002} //s9
|
||||
};
|
||||
}
|
||||
else if (nBins==4){
|
||||
if (NP) return {
|
||||
//predictions from flavio for new physics scenario with C9 = -1.0, using min(Q2) = 0.25 and max(Q2) = 18.0
|
||||
{0.30284413148097966,0.27262304293367756,0.4271747118350757,0.4947224191764013},
|
||||
{0.0016779452277498482,-0.03166521898839871,-0.08541706129465602,-0.18930463721455312},
|
||||
{-0.03554278140794295,-0.2399493206724746,-0.28043043274306023,-0.296509757783654},
|
||||
{0.1323358147544716,-0.29136093172458405,-0.37328734325703,-0.2736851726358371},
|
||||
{-0.18973621926844692,0.1460462265211582,0.4666205500210169,0.468761474000308},
|
||||
{-0.021811112779860177,-0.01286712550773734,-0.002747600804479865,-0.0014945589348205987},
|
||||
{-0.00881926856860235,-0.003687673879434568,0.0016256878486157777,0.0005018180644191919},
|
||||
{-0.0006860405719520938,-0.0006097376632470255,0.0006613554952330075,0.00044525884942171284}
|
||||
};
|
||||
else return{
|
||||
//SM predictions from flavio, using min(Q2) = 0.25 and max(Q2) = 18.0
|
||||
{0.24856900804649007,0.2581971160208132,0.4252601465955922,0.4942066935350626}, //s1s
|
||||
{0.000732569649322501,-0.03245238591396329,-0.0856386442245723,-0.18934424485647136}, //s3
|
||||
{-0.02831769317488915,-0.24258370276606506,-0.28116530113868093,-0.29668531019781386}, //s4
|
||||
{0.03547969889667525,-0.3745017565795041,-0.40726931726860705,-0.3016175005358511}, //s5
|
||||
{-0.12231988591851424,0.24738168269152006,0.5243204516554147,0.5210643920936899}, //s6s
|
||||
{-0.019468600975846337,-0.010543577092419721,-0.002192851911928869,-0.001194465950618852}, //s7
|
||||
{-0.010192773160727949,-0.004301989173721084,0.0010498743186655955,0.0002724464525572746}, //s8
|
||||
{-0.000756965302130655,-0.0006959911482550733,0.00044741790607562027,0.00026464193866571387} //s9
|
||||
};
|
||||
}
|
||||
else if (nBins==2){
|
||||
return { //results from signal channel generator level MC fit TODO
|
||||
{0.0,0.0}, //s1s
|
||||
{0.0,0.0}, //s3
|
||||
{0.0,0.0}, //s4
|
||||
{0.0,0.0}, //s5
|
||||
{0.0,0.0}, //s6s
|
||||
{0.0,0.0}, //s7
|
||||
{0.0,0.0}, //s8
|
||||
{0.0,0.0} //s9
|
||||
};
|
||||
}
|
||||
else if (nBins==1){
|
||||
if (isReference) return { //TODO, David's for now
|
||||
{+0.321}, //s1s //FL = 0.572
|
||||
{-0.002}, //s3
|
||||
{-0.246}, //s4
|
||||
{-0.003}, //s5
|
||||
{-0.003}, //s6s
|
||||
{-0.001}, //s7
|
||||
{-0.063}, //s8
|
||||
{-0.084} //s9
|
||||
};
|
||||
else return { //TODO
|
||||
{+0.321}, //s1s//FL = 0.572
|
||||
{-0.002}, //s3
|
||||
{-0.246}, //s4
|
||||
{-0.003}, //s5
|
||||
{-0.003}, //s6s
|
||||
{-0.001}, //s7
|
||||
{-0.063}, //s8
|
||||
{-0.084} //s9
|
||||
};
|
||||
}
|
||||
else {
|
||||
spdlog::error("No SM values given for binning scheme with {0:d} q2 bins. Exit", nBins);
|
||||
assert(0);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>> init_angular_params_MC(int nBins){
|
||||
if (nBins==4){
|
||||
return {
|
||||
{+0.3, +0.25, +0.4, +0.48}, //s1s // 0 //S1s = 3/4(1-FL)
|
||||
{-0.06, -0.01, -0.05, -0.2}, //s3 // 1
|
||||
{-0.02, -0.02, -0.2, -0.3}, //s4 // 2
|
||||
{+0.06, -0.30, -0.4, -0.3}, //s5 // 3
|
||||
{-0.12, +0.2, +0.5, +0.5}, //s6s // 4 //S6 = 4/3 AFB
|
||||
{+0.01, +0.0, +0.0, +0.0}, //s7 // 5
|
||||
{+0.05, +0.05, +0.05, +0.0}, //s8 // 6 big influence on ctl
|
||||
{-0.01, +0.01, +0.01, +0.0} //s9 // 7
|
||||
};
|
||||
}
|
||||
else if (nBins==5){
|
||||
return {
|
||||
{+0.3, +0.25, +0.3, +0.4, +0.2}, //s1s // 0 //S1s = 3/4(1-FL)
|
||||
{-0.06, -0.01, -0.07, -0.05, -0.01}, //s3 // 1
|
||||
{-0.02, -0.20, -0.15, -0.2, -0.13}, //s4 // 2
|
||||
{+0.09, -0.35, -0.4, -0.4, -0.13}, //s5 // 3
|
||||
{-0.12, +0.2, +0.2, +0.5, -0.32}, //s6s // 4 //S6 = 4/3 AFB
|
||||
{+0.01, +0.0, +0.01, +0.0, +0.00}, //s7 // 5
|
||||
{+0.05, +0.05, +0.03, +0.05, +0.03}, //s8 // 6 big influence on ctl
|
||||
{-0.01, +0.01, +0.0, +0.01, -0.01} //s9 // 7
|
||||
};
|
||||
}
|
||||
else if (nBins==8){
|
||||
return {
|
||||
{+0.5, +0.3, +0.1, +0.2, +0.3, +0.4, +0.5, +0.5}, //s1s // 0 //S1s = 3/4(1-FL)
|
||||
{+0.0, +0.0, -0.0, -0.0, -0.1, -0.1, -0.2, -0.2}, //s3 // 1
|
||||
{+0.1, +0.0, -0.2, -0.2, -0.3, -0.3, -0.3, -0.3}, //s4 // 2
|
||||
{+0.2, +0.1, -0.2, -0.3, -0.4, -0.4, -0.3, -0.2}, //s5 // 3
|
||||
{-0.1, -0.2, -0.0, +0.1, +0.3, +0.5, +0.6, +0.5}, //s6s // 4 //S6 = 4/3 AFB
|
||||
{+0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0}, //s7 // 5
|
||||
{+0.0, -0.0, -0.0, -0.0, +0.0, +0.0, +0.0, +0.0}, //s8 // 6 big influence on ctl
|
||||
{-0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0} //s9 // 7
|
||||
};
|
||||
/* David's reuslts
|
||||
s1s = { 0.5120, 0.1800, 0.1370, 0.1930, 0.2750, 0.4170, 0.4840, 0.5030};
|
||||
s1c = { 0.2450, 0.6996, 0.7993, 0.7384, 0.6414, 0.4201, 0.3513, 0.3344};
|
||||
s2s = { 0.1448, 0.0749, 0.0514, 0.0662, 0.0900, 0.1449, 0.1620, 0.1662};
|
||||
s2c = {-0.1953,-0.6639,-0.7774,-0.7254,-0.6334,-0.4171,-0.3497,-0.3332};
|
||||
s3 = { 0.0000, 0.0020,-0.0080,-0.0120,-0.0240,-0.0620,-0.1520,-0.2330};
|
||||
s4 = { 0.0870, 0.0040,-0.1080,-0.1950,-0.2510,-0.2770,-0.2900,-0.3040};
|
||||
s5 = { 0.2440, 0.0950,-0.1590,-0.3050,-0.4140,-0.4210,-0.3400,-0.2490};
|
||||
s6s = {-0.1270,-0.2070,-0.0860, 0.0950, 0.3020, 0.5140, 0.5570, 0.4700};
|
||||
s6c = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000};
|
||||
s7 = {-0.0060,-0.0100,-0.0030, 0.0020, 0.0030,-0.0020,-0.0020, 0.0050};
|
||||
s8 = { 0.0010,-0.0030,-0.0040,-0.0030,-0.0010, 0.0030,-0.0010, 0.0030};
|
||||
s9 = {-0.0020, 0.0000, 0.0020, 0.0040,-0.0020,-0.0010,-0.0010, 0.0010};
|
||||
*/
|
||||
}
|
||||
else if (nBins==9){ //8 bins + Jpsi
|
||||
return {
|
||||
{+0.5, +0.3, +0.1, +0.2, +0.3, +0.3, +0.4, +0.5, +0.5}, //s1s // 0 //S1s = 3/4(1-FL)
|
||||
{+0.0, +0.0, -0.0, -0.0, -0.1, -0.1, -0.1, -0.2, -0.2}, //s3 // 1
|
||||
{+0.1, +0.0, -0.2, -0.2, -0.3, -0.3, -0.3, -0.3, -0.3}, //s4 // 2
|
||||
{+0.2, +0.1, -0.2, -0.3, -0.4, -0.4, -0.4, -0.3, -0.2}, //s5 // 3
|
||||
{-0.1, -0.2, -0.0, +0.1, +0.3, +0.5, +0.5, +0.6, +0.5}, //s6s // 4 //S6 = 4/3 AFB
|
||||
{+0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0}, //s7 // 5
|
||||
{+0.0, -0.0, -0.0, -0.0, +0.0, +0.0, +0.0, +0.0, +0.0}, //s8 // 6
|
||||
{-0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0} //s9 // 7
|
||||
};
|
||||
}
|
||||
else if (nBins==2){
|
||||
return {
|
||||
{0.0,0.0}, //s1s // 0
|
||||
{0.0,0.0}, //s3 // 1
|
||||
{0.0,0.0}, //s4 // 2
|
||||
{0.0,0.0}, //s5 // 3
|
||||
{0.0,0.0}, //s6s // 4
|
||||
{0.0,0.0}, //s7 // 5
|
||||
{0.0,0.0}, //s8 // 6
|
||||
{0.0,0.0} //s9 // 7
|
||||
};
|
||||
}
|
||||
else if (nBins==1){
|
||||
return { //TODO
|
||||
{+0.321}, //s1s // 0
|
||||
{-0.013}, //s3 // 1
|
||||
{-0.250}, //s4 // 2
|
||||
{-0.00}, //s5 // 3
|
||||
{-0.00}, //s6s // 4
|
||||
{-0.00}, //s7 // 5
|
||||
{-0.048}, //s8 // 6
|
||||
{-0.084} //s9 // 7
|
||||
};
|
||||
}
|
||||
else {
|
||||
spdlog::error("No default vectors with values for angular observables obtained from MC defined for binning scheme with {0:d} q2 bins. Exit", nBins);
|
||||
assert(0);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>> init_angular_params_zeros(int nBins){
|
||||
return std::vector<std::vector<double> > (12, std::vector<double> (nBins, 0.0));
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>> init_mass_params_MC(int nBins, int nPDF){
|
||||
if (nBins == 9){ //Used only in sanity checks, so put zeros for now
|
||||
return {
|
||||
{+33.0, +33.0, +29.0, +29.0, +27.0, +27.0, +25.0, +22.8, +22.8}, //sigma 1 //0
|
||||
{+0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0}, //sigma 1 //0
|
||||
{+1.33, +1.33, +1.40, +1.40, +1.37, +1.26, +1.18, +1.85, +1.85}, //sigma 1 //0
|
||||
{+0.91, +0.91, +0.99, +0.99, +0.99, +1.01,+1.01, +1.34, +1.34}, //alpha 2 //3
|
||||
{+2.36,+2.36,+2.35,+2.35,+2.28,+2.28,+4.28,+3.1, +3.1}, //n 1 //4
|
||||
{+3.39,+3.39,+3.23,+3.23,+3.63,+3.63,+5.46,+3.5, +3.5} //n 2 // 5
|
||||
};
|
||||
}
|
||||
else if (nBins == 8){ //Used only in sanity checks, so put zeros for now //TODO: add
|
||||
return {
|
||||
{+0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0}, //sigma 1 //0
|
||||
{+0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0}, //sigma 1 //0
|
||||
{+0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0}, //sigma 1 //0
|
||||
{+0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0}, //alpha 2 //3
|
||||
{-0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0}, //n 1 //4
|
||||
{+0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0, +0.0} //n 2 // 5
|
||||
};
|
||||
}
|
||||
else if (nBins == 5){//TODO update values of bin 5 to actual results from MC fit. for now, taking average values of first two bins
|
||||
if (nPDF ==0) return { //Run 1
|
||||
{+30.0, +31.0, +24.5, +25.2, +30.5}, //sigma 1 //0
|
||||
{+25.0, +25.0, +25.0, +25.0, +25.0}, //sigma 2 //1
|
||||
{+1.40, +1.3967, +1.37, +1.8541,+1.39835},//alpha 1 //2
|
||||
{+0.94, +0.9847, +1.0039,+1.3360,+0.96235},//alpha 2 //3
|
||||
{+3.98, +2.35, +1.85, +3.1, +3.165}, //n 1 //4
|
||||
{+4.39, +3.23, +3.63, +3.50, +3.81} //n 2 //5
|
||||
};
|
||||
if (nPDF==1) return { //Run 2
|
||||
{+35.8, +31.0, +24.5, +22.0, +33.4}, //sigma 1 //0
|
||||
{+25.0, +25.0, +25.0, +25.0, +25.0}, //sigma 2 //1
|
||||
{+1.41, +1.2853, +1.4168,+1.8406,+1.34765},//alpha 1 //2
|
||||
{+1.13, +1.0736, +1.0649,+0.9954,+1.1018}, //alpha 2 //3
|
||||
{+3.36, +2.35, +2.28, +3.1 ,+2.855}, //n 1 //4
|
||||
{+4.39, +3.23, +3.63, +3.50 ,+3.81} //n 2 //5
|
||||
};
|
||||
}
|
||||
else if (nBins == 4){
|
||||
if (nPDF ==0) return { //Run 1
|
||||
{+30.0, +31.0, +24.5, +25.2}, //sigma 1 //0
|
||||
{+25.0, +25.0, +25.0, +25.0}, //sigma 2 //1
|
||||
{+1.40, +1.3967, +1.37, +1.8541},//alpha 1 //2
|
||||
{+0.94, +0.9847, +1.0039,+1.3360},//alpha 2 //3
|
||||
{+3.98, +2.35, +1.85, +3.1}, //n 1 //4
|
||||
{+4.39, +3.23, +3.63, +3.50} //n 2 //5
|
||||
};
|
||||
if (nPDF==1) return { //Run 2
|
||||
{+35.8, +31.0, +24.5, +22.0}, //sigma 1 //0
|
||||
{+25.0, +25.0, +25.0, +25.0}, //sigma 2 //1
|
||||
{+1.41, +1.2853, +1.4168,+1.8406},//alpha 1 //2
|
||||
{+1.13, +1.0736, +1.0649,+0.9954},//alpha 2 //3
|
||||
{+3.36, +2.35, +2.28, +3.1}, //n 1 //4
|
||||
{+4.39, +3.23, +3.63, +3.50} //n 2 //5
|
||||
};
|
||||
}
|
||||
else if (nBins==1){
|
||||
if (nPDF==0) return{ //Run 1
|
||||
{+31.0}, //sigma 1 //0
|
||||
{+31.0}, //sigma 2 //1
|
||||
{+1.40},//alpha 1 //2
|
||||
{+0.939},//alpha 2 //3
|
||||
{+4.03}, //n 1 //4
|
||||
{+5.9} //n 2 //5
|
||||
};
|
||||
if (nPDF==1) return{ //Run 2
|
||||
{+31.0}, //sigma 1 //0
|
||||
{+31.0}, //sigma 2 //1
|
||||
{+1.442},//alpha 1 //2
|
||||
{+1.013},//alpha 2 //3
|
||||
{+3.74}, //n 1 //4
|
||||
{+3.90} //n 2 //5
|
||||
};
|
||||
}
|
||||
else {
|
||||
spdlog::error("No mass param vectors defined for binning scheme with {0:d} q2 bins. Exit", nBins);
|
||||
assert(0);
|
||||
return {};
|
||||
}
|
||||
return {}; //Not needed but compiler complains
|
||||
}
|
||||
|
||||
//Jpsi results from B+->K*(Kspi+)mumu
|
||||
std::vector<double> init_angular_params_RefFromDavid(){
|
||||
return {
|
||||
+0.321, //s1s // 0
|
||||
-0.002, //s3 // 1
|
||||
-0.246, //s4 // 2
|
||||
-0.003, //s5 // 3
|
||||
-0.003, //s6s // 4
|
||||
-0.001, //s7 // 5
|
||||
-0.063, //s8 // 6
|
||||
-0.084 //s9 // 7
|
||||
};
|
||||
}
|
||||
|
||||
//obtain parameter ranges and stepsize for (most) parameters
|
||||
double GetParamStepsize(std::string name){
|
||||
double stepsize = 0.1;
|
||||
//TODO improving the stepsizes can be done later!
|
||||
spdlog::debug("Stepsize of '"+name+"': {0:f}", stepsize);
|
||||
return stepsize;
|
||||
}
|
||||
|
||||
std::vector<double> GetParamRange(std::string name){
|
||||
std::vector<double> range = {-1., +1.};
|
||||
if(name.find("m_b") != std::string::npos) return range = {B_MASS_LOW, B_MASS_HIGH};
|
||||
else if(name.find("f_sig") != std::string::npos) return range = {0.0 , 1.0};
|
||||
else if(name.find("m_sigma") != std::string::npos) return range = {PAR_SIGMA_LOW, PAR_SIGMA_HIGH};
|
||||
else if(name.find("alpha_") != std::string::npos) return range = {0.5 , 5.0};
|
||||
else if(name.find("_lambda") != std::string::npos) return range = {PAR_LAMBDA*PAR_LAMBDA_SCALE,
|
||||
PAR_LAMBDA/PAR_LAMBDA_SCALE};
|
||||
else if(name.find("_tau") != std::string::npos) return range = {0.0 , 1.0};
|
||||
else if(name.find("_scale") != std::string::npos) return range = {0.0 , 2.0};
|
||||
else if(name.find("gamkstp") != std::string::npos) return range = {0.1 , 0.8}; //Width of K1, the naming convention is stupid
|
||||
else if(name.find("mkstp") != std::string::npos) return range = {1.2 , 1.6};
|
||||
else if(name.find("gammakstar") != std::string::npos) return range = {0.01, 1.0}; //Width of K*
|
||||
else if(name.find("mkst") != std::string::npos) return range = {K_ONE_PLUS-PAR_KSTAR_WIDTH/1.0e3,
|
||||
K_ONE_PLUS+PAR_KSTAR_WIDTH/1.0e3};
|
||||
else if(name.find("nthreshold") != std::string::npos) return range = {0.1 , 10.0};
|
||||
else if(name.find("cbkg") != std::string::npos) return range = {-2.25, +1.5};
|
||||
else if(name.find("FS") != std::string::npos) return range = {0.0 , 1.0};
|
||||
else if(name == "n_1" || name == "n_2") return range = {1.0 , 8.0};
|
||||
else if(name.at(0) == 'S'){
|
||||
if (name.at(1)=='S') return range = {-PAR_ANG_RANGE, PAR_ANG_RANGE}; //S wave
|
||||
else return range = {-PAR_ANG_RANGE, PAR_ANG_RANGE}; //P wave
|
||||
}
|
||||
else spdlog::warn("Using default range for '"+name+"': [{0:f} - {1:f}]", range.front(), range.back());
|
||||
return range;
|
||||
}
|
||||
|
300
Code/FCNCFitter/sources/Params/constants.hh
Normal file
300
Code/FCNCFitter/sources/Params/constants.hh
Normal file
@ -0,0 +1,300 @@
|
||||
// Renata Kopecna
|
||||
|
||||
#ifndef CONSTANTS_HH
|
||||
#define CONSTANTS_HH
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <TMath.h>
|
||||
|
||||
//general constnats
|
||||
const double MY_PI = TMath::Pi();
|
||||
const double C_PWAVE = 9.0/32.0/MY_PI;
|
||||
const double C_SWAVE = 3.0/16.0/MY_PI;
|
||||
|
||||
const double ONE_SIGMA = 0.683;
|
||||
const double TWO_SIGMAS = 0.9773;
|
||||
const double THREE_SIGMAS = 0.9987;
|
||||
|
||||
const int DEFAULT_TREE_INT = -1; //Used when initializing doubles in trees
|
||||
const double DEFAULT_TREE_VAL = -100.0; //Used when initializing doubles in trees
|
||||
const double DEFAULT_TREE_ERR = 0.0; //Used when initializing error of doubles in trees
|
||||
|
||||
//Set binning scheme
|
||||
const double Q2_MIN_RANGE = 0.25; //Not necesarilly connected to get_TheQ2binsmin, used only when the full q2 range is used, eg for plotting
|
||||
const double Q2_MAX_RANGE = 18.0;
|
||||
const double Q2_MAX_RANGE_B0 = 19.0;
|
||||
//Not necesarilly connected to get_TheQ2binsmax, used only when the full q2 range is used, eg for plotting
|
||||
std::vector<double> get_TheQ2binsmin(int nBins, bool Reference);
|
||||
std::vector<double> get_TheQ2binsmax(int nBins, bool Reference);
|
||||
|
||||
//List excluded Q2 regions
|
||||
const std::vector<std::vector<double>> EXCLUDED_Q2 ={
|
||||
{0.98,1.1}, //meaning events with q^2 in 0.98-1.1 will not be considered
|
||||
{8.0,11.0},
|
||||
{12.5,15}
|
||||
};
|
||||
|
||||
const int NBINS_DEFAULT = 4; //used as a default number of q2 bins
|
||||
|
||||
//Set resolution
|
||||
std::vector<std::vector<double>> get_resolution();
|
||||
|
||||
//Set limits of the angles
|
||||
const double CTL_MIN = -1.0;
|
||||
const double CTL_MAX = +1.0;
|
||||
const double CTK_MIN = -1.0;
|
||||
const double CTK_MAX = +0.8;
|
||||
const double PHI_MIN = -TMath::Pi();
|
||||
const double PHI_MAX = +TMath::Pi();
|
||||
|
||||
//Set the maximum number of folding ID, useful for loops
|
||||
const double MAX_FOLDING = 5;
|
||||
|
||||
//Ranges of the angles, always max-min
|
||||
double CTL_RANGE();
|
||||
double CTK_RANGE();
|
||||
double PHI_RANGE();
|
||||
double Q2_RANGE_FULL();
|
||||
double RANGE_3D(); //ctl*ctk*phi range
|
||||
double RANGE_4D(); //ctl*ctk*phi*q2 range
|
||||
|
||||
|
||||
const int nANGLES = 3;
|
||||
const std::vector<std::string> ANGLES = {"ctl", "ctk", "phi"};
|
||||
//This *could* be in design.hh, but then it has to be sourced everywhere and this is just easier
|
||||
const std::vector<std::string> latex_angles = {"cos(#Theta_{L})", "cos(#Theta_{K})", "#phi"};
|
||||
const std::vector<std::string> latex_2angles = {"\\ctl", "\\ctk", "$\\phi$"};
|
||||
|
||||
//////////////////////////////////
|
||||
// Fitter options //
|
||||
//////////////////////////////////
|
||||
|
||||
//Set number of used cores
|
||||
const int NCORES = 8;
|
||||
|
||||
const double MIG_MAX_CALLS = 100000000.0;
|
||||
const double MIG_TOLERANCE = 0.1; //TODO
|
||||
// The default tolerance in TMinuit is 0.1
|
||||
// The minimization will stop when the estimated vertical distance to the minimum (EDM) is less than 0.001*[tolerance]*UP(see SET ERR)
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Basic paths //
|
||||
//////////////////////////////////
|
||||
|
||||
//Set decay string and main path
|
||||
const std::string DECAY_NAME = "KplusPi0Resolved";//"KshortPiplus"
|
||||
const std::string CONFIG_PHSP_WEIGHT = "config/phspweightq2.root";
|
||||
|
||||
//////////////////////////////////
|
||||
// plotting //
|
||||
//////////////////////////////////
|
||||
const bool PLOT_THISTHESIS_TAG = true;
|
||||
const std::string THISTHESIS_TAG = "this thesis";
|
||||
const int PLOT_NBINS_MB = 100;
|
||||
const int PLOT_NBINS_MKSTAR = 50;
|
||||
const int PLOT_NBINS_ANGLES = 20;
|
||||
//When plotting, the pdf is plotted as a very fine TH1D,
|
||||
//PLOT_NBINS_RATIO says how many times more bins is there in the pdf compared to the data bins
|
||||
const int PLOT_NBINS_RATIO = 20;
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// PDG masses //
|
||||
//////////////////////////////////
|
||||
|
||||
const Double_t PDGMASS_B_PLUS = 5279.29;
|
||||
const Double_t PDGMASS_B_ZERO = 5279.61;
|
||||
const Double_t PDGMASS_J_PSI = 3096.90;
|
||||
const Double_t PDGMASS_PSI_2S = 3686.10;
|
||||
const Double_t PDGMASS_K_STAR_PLUS = 891.66;
|
||||
const Double_t K_ONE_PLUS = 1272.0;
|
||||
const Double_t PDGMASS_K_PLUS = 493.68;
|
||||
const Double_t PDGMASS_K_SHORT = 497.61;
|
||||
const Double_t PDGMASS_PI_PLUS = 139.57;
|
||||
const Double_t PDGMASS_PI_ZERO = 134.98;
|
||||
const Double_t PDGMASS_MU = 105.66;
|
||||
const Double_t PDGMASS_GAMMA = 0.0;
|
||||
|
||||
//Decay specific PDG masses
|
||||
const Double_t PDGMASS_K_STAR = PDGMASS_K_STAR_PLUS;
|
||||
const Double_t PDGMASS_KST_KAON = PDGMASS_K_PLUS;
|
||||
const Double_t PDGMASS_KST_PION = PDGMASS_PI_ZERO;
|
||||
const Double_t PDGMASS_B = PDGMASS_B_PLUS;
|
||||
|
||||
//Set mass range and window of the B mass
|
||||
const double B_MASS_LOW = 5150.0;
|
||||
const double B_MASS_HIGH = 5800.0;
|
||||
//CAREFUL when initializing the m_b parameter:
|
||||
//the min and max set also the fit range, so it should be always
|
||||
//set to B_MASS_LOW and B_MASS_HIGH
|
||||
|
||||
//The tight window is used for plotting the very signal only region
|
||||
const double B_MASS_TIGHT_WINDOW = 100; //David had 50
|
||||
|
||||
//Set the cuts from where we have only background
|
||||
const double B_MASS_HIGH_BKG = PDGMASS_B_PLUS + 100;
|
||||
const double B_MASS_LOW_BKG = PDGMASS_B_PLUS - 100;
|
||||
const double B_MASS_HIGH_BKG_REF = PDGMASS_B_PLUS + 350;
|
||||
const double B_MASS_LOW_BKG_REF = 5150;
|
||||
|
||||
const double KPI_MASS_MIN = PDGMASS_K_STAR-100.;
|
||||
const double KPI_MASS_MAX = PDGMASS_K_STAR+100.;
|
||||
|
||||
//////////////////////////////////
|
||||
// PARTICLE IDs //
|
||||
//////////////////////////////////
|
||||
const int ID_B_PLUS = +521;
|
||||
const int ID_B_ZERO = +511;
|
||||
|
||||
const int ID_K_STAR_PLUS = +323;
|
||||
const int ID_K_STAR_ZERO = +313;
|
||||
|
||||
const int ID_K_PLUS = +321;
|
||||
const int ID_K_SHORT = +310;
|
||||
|
||||
const int ID_PI_PLUS = +211;
|
||||
const int ID_PI_ZERO = +111;
|
||||
const int ID_GAMMA = +22;
|
||||
|
||||
const int ID_MU_PLUS = -13;
|
||||
const int ID_MU_MINUS = +13;
|
||||
const int ID_J_PSI = +443;
|
||||
const int ID_RHO_ZERO = +113;
|
||||
|
||||
const int ID_K_ONE_PLUS = +10323; // K1(1270)+
|
||||
const int ID_K_ONE_PLUS_1400 = +20323; // K1(1400)+
|
||||
const int ID_K_ONE_PLUS_1410 = +100323; // K1(1410)+
|
||||
const int ID_K_ONE_ZERO = 10313; // K0(1270)+
|
||||
const int ID_ELECTRON = -11;
|
||||
|
||||
//////////////////////////////////
|
||||
// Angular correction //
|
||||
//////////////////////////////////
|
||||
|
||||
//Modify this after being done with scannig the corrections
|
||||
const bool IS_PHI_EVEN = true;
|
||||
const int ORDER_COSTHETAL = 3;
|
||||
const int ORDER_COSTHETAK = 6;
|
||||
const int ORDER_PHI = 1;
|
||||
const int ORDER_Q2 = 7;
|
||||
|
||||
//////////////////////////
|
||||
// Reweighting //
|
||||
//////////////////////////
|
||||
|
||||
//Descides at what 1/weight you reject events
|
||||
//Large weights result in large errorbars and can be a source of fluctuations
|
||||
const double EFF_CUTOFF = 0.01;
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Idk why, but here are pies //
|
||||
//////////////////////////////////
|
||||
const double M_4_PI = 1.2732395447351626861510701069801; // 4/Pi
|
||||
const double M_SQRTPI = 1.7724538509055160272981674833411; // sqrt(Pi)
|
||||
const double M_SQRT2PI = 2.5066282746310005024157652848111; // sqrt(2Pi)
|
||||
const double M_SQRT_PI_2= 1.2533141373155002512078826424055; // sqrt(Pi/2)
|
||||
const double M_SQRT_2_PI= 0.79788456080286535587989211986876; // sqrt(2/Pi)
|
||||
const double M_1_SQRTPI = 0.56418958354775628694807945156077; // 1/sqrt(Pi)
|
||||
const double m_2_SQRTPI = 1.1283791670955125738961589031216; // 2/sqrt(Pi)
|
||||
//M_2_SQRTPI is defined in math.h, see https://stackoverflow.com/questions/52796736/why-does-c-define-m-2-sqrtpi-constant-in-math-h
|
||||
const double M_SQRT_2PI = 0.39894228040143267793994605993438; // 1/sqrt(2Pi)
|
||||
const double M_SQRT_2 = 0.70710678118654752440084436210485; // sqrt(1/2)
|
||||
const double M_2PI = 6.2831853071795864769252867665590; // 2Pi
|
||||
const double M_4PI = 12.5663706143591729538505735331180; //4Pi
|
||||
|
||||
|
||||
|
||||
//////////////////////////
|
||||
// Fit parameters //
|
||||
//////////////////////////
|
||||
|
||||
//Set default values for most parameters
|
||||
//These values can be set individually, but it is good to have some default starting points
|
||||
|
||||
//Check the definitions in bu2kstarmumu_parameters!
|
||||
|
||||
const double PAR_ANG_RANGE = 1.0; //Default range for all angular observables
|
||||
const double PAR_SIGMA = 30.0; //[MeV]
|
||||
const double PAR_SIGMA_LOW = 25.0; //[MeV]
|
||||
const double PAR_SIGMA_HIGH = 50.0; //[MeV]
|
||||
const double PAR_TAU = 100.0;
|
||||
const double PAR_TAU_SCALE = 100.0; //Tau range is then par_tau/scale to par_tau*scale
|
||||
const double PAR_LAMBDA = -0.0001;
|
||||
const double PAR_LAMBDA_SCALE = 100.0; //Lambda range is then par_lambda*scale to par_lambda/scale
|
||||
const double PAR_NTRESHOLD = 1.5;
|
||||
const double PAR_KSTAR_WIDTH = 50.0; //[MeV]
|
||||
const double PAR_K1_WIDTH = 270.0; //[MeV]
|
||||
const double PAR_N_SIG = 150.0;
|
||||
const double PAR_N_BKG = 500.0; //f_sig is init as PAR_N_SIG/(PAR_N_SIG+PAR_N_BKG)
|
||||
|
||||
//If you want to have only 1 exponential in bkg, set to false
|
||||
const double FIX_FM = true;
|
||||
const double DOUBLE_CB = true; //Just always use double CB, it is not like anyone is going to switch this halfway through the code
|
||||
|
||||
//This string contains parameters that are varied when fitting bkg
|
||||
//TODO: optimize at some point
|
||||
std::vector<std::string> PAR_BKG_STRING(int folding, int nCtl, int nCtk);
|
||||
//Init values of said parameters
|
||||
//CAREFUL!!!! HAS TO BE THE SAME AS PAR_BKG_STRING!!!!
|
||||
std::vector<double> init_bkg(int folding, int nCtl, int nCtk);
|
||||
|
||||
//////////////////////////////////
|
||||
// Main Fit Parameters //
|
||||
//////////////////////////////////
|
||||
|
||||
//Number of angular terms: 12 for P wave, 6 for S wave
|
||||
const int NTERMS_P = 12;
|
||||
const int NTERMS_S = 6;
|
||||
const int NTERMS = NTERMS_S + NTERMS_P; //If no s Wave ever, one can also set it to 12 and save some memory
|
||||
|
||||
//Fraction of events in each subset
|
||||
std::vector<std::vector<double> > fracs(int nBins);
|
||||
|
||||
//Init default parameters
|
||||
std::vector<double> init_n_signal(int nBins);
|
||||
std::vector<double> init_n_bckgnd(int nBins);
|
||||
std::vector<double> init_f_lambda(int nBins);
|
||||
std::vector<double> get_f_subset(int nPDFs);
|
||||
|
||||
//Used in EventNumbers
|
||||
const std::vector<std::vector<double> > sig_unblinded = { //Set only for 8 bins and 4 pdfs //TODO
|
||||
{5.86168, 13.9418, 54.4478, 27.3012},
|
||||
{2.36522, 1.09800, 31.7908, 13.7227},
|
||||
{8.99630, 6.53635, 14.4187, 12.2178},
|
||||
{14.0240, 8.82742, 62.4731, 23.5189},
|
||||
{5.11878, 7.85420, 59.2977, 32.3194},
|
||||
{17.7802, 12.8009, 39.0769, 40.8969},
|
||||
{19.8873, 12.7440, 81.8400, 29.7622},
|
||||
{3.73514, 7.56100, 32.8754, 31.5777}
|
||||
};
|
||||
|
||||
const std::vector<std::vector<double> > bkg_unblinded = { //Set only for 8 bins and 4 pdfs //TODO
|
||||
{18.6849, 10.7306, 130.508, 26.1523},
|
||||
{28.8699, 11.4018, 152.795, 26.1676},
|
||||
{36.0865, 7.24722, 196.480, 35.0536},
|
||||
{39.2519, 22.7192, 163.944, 61.0158},
|
||||
{65.1688, 19.2037, 165.299, 48.0148},
|
||||
{19.5884, 16.5293, 88.6190, 46.0676},
|
||||
{17.2658, 14.1666, 42.6978, 34.5553},
|
||||
{17.6887, 20.2719, 41.7393, 26.3643}
|
||||
};
|
||||
|
||||
std::vector<std::vector<double>> init_angular_params(int nBins, bool NP, bool isReference);
|
||||
|
||||
std::vector<std::vector<double>> init_angular_params_MC(int nBins);
|
||||
std::vector<std::vector<double>> init_angular_params_zeros(int nBins);
|
||||
|
||||
std::vector<std::vector<double>> init_mass_params_MC(int nBins, int nPDF);
|
||||
|
||||
//Jpsi results from B+->K*(Kspi+)mumu
|
||||
std::vector<double> init_angular_params_RefFromDavid();
|
||||
|
||||
//obtain parameter ranges and stepsize for (most) parameters
|
||||
double GetParamStepsize(std::string);
|
||||
std::vector<double> GetParamRange(std::string);
|
||||
|
||||
#endif // CONSTANTS_HH
|
230
Code/FCNCFitter/sources/Params/parameters.cc
Normal file
230
Code/FCNCFitter/sources/Params/parameters.cc
Normal file
@ -0,0 +1,230 @@
|
||||
#include <parameters.hh>
|
||||
#include <constants.hh>
|
||||
#include <helpers.hh>
|
||||
#include <funcs.hh>
|
||||
#include <fstream>
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
#include <paths.hh>
|
||||
#include <spdlog.h>
|
||||
/**
|
||||
* @file parameters.cc
|
||||
* @author Renata Kopecna
|
||||
* @date 2021-03-02
|
||||
*
|
||||
*/
|
||||
|
||||
void fcnc::parameter::set_values_n_errors(double v, double e){
|
||||
value = v;
|
||||
start_value = v;
|
||||
previous_measurement = v;
|
||||
|
||||
error = e;
|
||||
error_down = e;
|
||||
error_up = e;
|
||||
previous_error_low = e;
|
||||
previous_error_high = e;
|
||||
//step_size = e; //not correct
|
||||
}
|
||||
void fcnc::parameter::reset_correlations(){
|
||||
correlations.clear();
|
||||
}
|
||||
void fcnc::parameter::set_correlation(double corr, unsigned int idx){
|
||||
while(correlations.size() <= idx) correlations.push_back(0.0);
|
||||
correlations.at(idx) = corr;
|
||||
}
|
||||
void fcnc::parameter::set_correlations(std::vector<double> corrs, unsigned int first, unsigned int last, double scalefactor){
|
||||
reset_correlations();
|
||||
assert(first < last);
|
||||
assert(last < corrs.size());
|
||||
for(unsigned int idx = first; idx <= last; idx++){
|
||||
correlations.push_back(scalefactor * corrs.at(idx));
|
||||
}
|
||||
}
|
||||
|
||||
///set blinding string
|
||||
void fcnc::parameter::set_blinding_string(std::string s) {
|
||||
blinding_string = s;
|
||||
}
|
||||
void fcnc::parameter::set_blinding(bool b, double b_scale, bool is_angle, std::string b_string) {
|
||||
blind = b;
|
||||
blinding_scale = b_scale;
|
||||
blinding_string = b_string;
|
||||
//this is new, apparently the shi(f)t needs to be subtracted, who knew?
|
||||
/* removed by David 18/07/18, as the functions are commented out in funcs.cc anyhow...
|
||||
if (is_angle)
|
||||
blinding_delta = -evaluate_unblind_uniform(0.0, blinding_string.c_str(), blinding_scale);
|
||||
else
|
||||
blinding_delta = -evaluate_unblind_uniform_angle(0.0, blinding_string.c_str(), blinding_scale);
|
||||
*/
|
||||
//new blinding: just add
|
||||
TRandom3 * rn = new TRandom3(0);
|
||||
blinding_delta = rn->Gaus(0., 1.);
|
||||
delete rn;
|
||||
}
|
||||
|
||||
std::string fcnc::parameter::get_root_name() const {
|
||||
std::string rootstring = get_description();
|
||||
size_t j;
|
||||
while ((j = rootstring.find("\\mathrm ")) != std::string::npos) rootstring.replace(j,8,"");
|
||||
while ((j = rootstring.find("\\")) != std::string::npos) rootstring.replace(j,1,"#");
|
||||
return rootstring;
|
||||
}
|
||||
|
||||
|
||||
///The parameters class stores a collection of parameters used in the analysis. Every analysis should implement its own set e.g. bs2jpsiphi_parameters
|
||||
void fcnc::parameters::add_parameter(parameter* param) {
|
||||
param->set_index(params.size());
|
||||
param->set_parent(this);
|
||||
params.push_back(param);
|
||||
}
|
||||
|
||||
bool fcnc::parameters::is_blind() const {
|
||||
for (unsigned int i = 0; i<params.size(); i++){
|
||||
if (params.at(i)->is_blind()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int fcnc::parameters::nparameters() const{
|
||||
return params.size();
|
||||
}
|
||||
|
||||
///Methos returns a pointer to parameter with index i
|
||||
fcnc::parameter* fcnc::parameters::get_parameter(unsigned int i) const{
|
||||
return params.at(i);
|
||||
}
|
||||
|
||||
///returns parameter with specific name
|
||||
fcnc::parameter* fcnc::parameters::get_parameter(std::string name) const{
|
||||
parameter* res=0;
|
||||
for (unsigned int i =0; i<nparameters();i++)
|
||||
if (get_parameter(i)->get_name() == name){
|
||||
res = get_parameter(i);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
///Resets all parameters to their start values
|
||||
void fcnc::parameters::reset_parameters(){
|
||||
for (unsigned int i = 0; i < nparameters(); i++) params.at(i)->reset_start();
|
||||
}
|
||||
|
||||
///Method that prints the parameter set, the current values, errors and the deviation from the start value in sigma
|
||||
void fcnc::parameters::print_parameters(bool latex_output) const{
|
||||
|
||||
std::ofstream myFile;
|
||||
open_Latex_noteFile(latex_params(), myFile);
|
||||
if (!latex_output){
|
||||
if (spdlog_trace()){
|
||||
std::cout << std::endl << "Parameters" << std::endl;
|
||||
spdlog::info("Blinded Parameters: ");
|
||||
for (unsigned int j = 0; j < nparameters(); j++){
|
||||
if (params[j]->is_blind()) std::cout << params[j]->get_name() << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
spdlog::info("The {0:d} Parameters: ", nparameters());
|
||||
for (unsigned int j = 0; j < nparameters(); j++) {
|
||||
std::string parname(params[j]->get_name());//the_minimizer->fCpnam[j]);
|
||||
std::cout.setf(std::ios::left);
|
||||
double nsigma = 0.0;
|
||||
if (params[j]->get_error() > 0.0){
|
||||
nsigma = (params[j]->get_value() - params[j]->get_start_value())/params[j]->get_error();
|
||||
}
|
||||
double value = params[j]->get_value();
|
||||
// if (params[j]->is_blind())
|
||||
// value += params[j]->blinding_delta;//todo
|
||||
double error = params[j]->get_error();
|
||||
double error_up = params[j]->get_error_up();
|
||||
double error_down = params[j]->get_error_down();
|
||||
if (params[j]->is_blind()){
|
||||
value += params[j]->blinding_delta * (error_up + error_down) / 2.;
|
||||
}
|
||||
if (error_up == error_down){
|
||||
std::cout << std::setw(12) << parname
|
||||
//<< std::setw(12) << (params[j]->is_blind() ? "(*)" : format_value(value, error))
|
||||
<< std::setw(12) << (format_value(value, error))
|
||||
<< std::setw(12) << "+-"
|
||||
<< std::setw(12) << format_error(error)
|
||||
<< std::setw(12) << (params[j]->is_blind() ? " (*)": "")
|
||||
<< " " << (params[j]->is_blind() ? "(*)" : format_double(nsigma)) << " sigma" << std::endl;
|
||||
}
|
||||
else {
|
||||
std::cout << std::setw(12) << parname
|
||||
//<< std::setw(12) << (params[j]->is_blind() ? "(*)" : format_value(value, error))
|
||||
<< std::setw(12) << (format_value(value, error))
|
||||
<< std::setw(12) << " " << format_error(error_down)
|
||||
<< std::setw(12) << " " << format_error(error_up)
|
||||
<< std::setw(12) << (params[j]->is_blind() ? "(*)": "")
|
||||
<< " " << (params[j]->is_blind() ? "(*)" : format_double(nsigma)) << " sigma" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (params[0]->get_error_up() == params[0]->get_error_down()){
|
||||
myFile << "\\begin{tabular}{|c|c|c|} \\hline" << std::endl;
|
||||
myFile << "parameter & result & $\\sigma$ from nominal \\\\ \\hline \\hline" << std::endl;
|
||||
}
|
||||
else{
|
||||
myFile << "\\begin{tabular}{|c|c|c|c|c|} \\hline" << std::endl;
|
||||
myFile << "parameter & result & $\\sigma_\\text{down}$ & $\\sigma_\\text{up}$ & $\\sigma$ from nominal \\\\ \\hline \\hline" << std::endl;
|
||||
}
|
||||
for (unsigned int j = 0; j < nparameters(); j++){
|
||||
std::string pardesc(params[j]->get_description());//the_minimizer->fCpnam[j]);
|
||||
std::string partex("");
|
||||
for (std::string::iterator it = pardesc.begin(); it != pardesc.end(); it++){ //Replace the ROOT tex by actual latex //TODO: maybe do this properly
|
||||
if (*it != '#') partex += *it;
|
||||
else partex += "\\";
|
||||
}
|
||||
double value = params[j]->get_value();
|
||||
if (params[j]->is_blind()) value += params[j]->blinding_delta;//todo
|
||||
double error = params[j]->get_error();
|
||||
if (error == 0.0) continue; //Do not print fixed params into latex
|
||||
double error_up = params[j]->get_error_up();
|
||||
double error_down = params[j]->get_error_down();
|
||||
double nsigma = 0.0;
|
||||
if (error > 0.0) nsigma = (value - params[j]->get_start_value())/error;
|
||||
std::cout.setf(std::ios::left);
|
||||
|
||||
if (error_up == error_down){
|
||||
myFile << "$" << std::setw(20) << partex << "$ & $"
|
||||
//<< std::setw(12) << (params[j]->is_blind() ? "(*)" : format_value(value, error))
|
||||
<< std::setw(12) << ((params[j]->get_step_size() == 0.0 && params[j]->is_blind()) ? "" : format_value(value, error))
|
||||
<< "\\pm " << std::setw(12) << format_error(error) << (params[j]->is_blind() ? "(*)": "") << "$ & "
|
||||
<< (params[j]->is_blind() ? "(*)" : format_double(nsigma)) << "\\\\" << std::endl;
|
||||
}
|
||||
else{
|
||||
myFile << "$" << std::setw(20) << partex << "$ & $"
|
||||
<< std::setw(12)
|
||||
//<< (params[j]->is_blind() ? "(*)" : format_value(value, error))
|
||||
<< (format_value(value, error))
|
||||
<< "\\pm "
|
||||
<< std::setw(12) << format_error(error) << (params[j]->is_blind() ? "(*)": "") << "$ & "
|
||||
<< std::setw(12) << format_error(error_down)<< " & "
|
||||
<< std::setw(12) << "+" << format_error(error_up) << " & "
|
||||
<< (params[j]->is_blind() ? "(*)" : format_double(nsigma)) << "\\\\" << std::endl;
|
||||
}
|
||||
}
|
||||
myFile << "\\hline" << std::endl;
|
||||
myFile << "\\end{tabular}" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
///fix all parameters
|
||||
void fcnc::parameters::fix_parameters() {
|
||||
for (unsigned int i = 0; i < params.size(); i++) params.at(i)->set_step_size(0.0);
|
||||
}
|
||||
///set all parameters to current values! Careful with this, please.
|
||||
void fcnc::parameters::take_current_as_start() {
|
||||
for (unsigned int i = 0; i < params.size(); i++) {
|
||||
parameter* p = params.at(i);
|
||||
p->set_start_value(p->get_value());
|
||||
}
|
||||
}
|
||||
|
||||
|
245
Code/FCNCFitter/sources/Params/parameters.hh
Executable file
245
Code/FCNCFitter/sources/Params/parameters.hh
Executable file
@ -0,0 +1,245 @@
|
||||
/**
|
||||
* @file parameters.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
#ifndef PARAMETERS_H
|
||||
#define PARAMETERS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace fcnc {
|
||||
|
||||
class parameters;
|
||||
|
||||
/// The parameter class stores the different attributes of a parameter used in the analysis, e.g. the name, start value and the parameter range.
|
||||
class parameter {
|
||||
friend class parameters;
|
||||
friend class feldman_cousins;
|
||||
private:
|
||||
///blind this parameter
|
||||
bool blind;
|
||||
///blinding string
|
||||
std::string blinding_string;
|
||||
///blinding delta, never look at this
|
||||
double blinding_delta;
|
||||
///blinding range
|
||||
double blinding_scale;
|
||||
///This name is supplied as the parameter name to minuit. Please give every parameter a different name.
|
||||
std::string name;
|
||||
///The parameter description is used by the plotter for plot captions and axis titles.
|
||||
std::string description;
|
||||
///The start value of the parameter. After every step in the toy study, the parameter is reset to this value.
|
||||
double start_value;
|
||||
///The current value of the parameter
|
||||
double value;
|
||||
///The minimum possible value for the parameter
|
||||
double min;
|
||||
///The maximum possible value for the parameter
|
||||
double max;
|
||||
///The initial step size used by minuit
|
||||
double step_size;
|
||||
///The error of the fitted result
|
||||
double error;
|
||||
///asymmetric errors if a minos error analysis has been performed
|
||||
double error_up;
|
||||
///asymmetric errors if a minos error analysis has been performed
|
||||
double error_down;
|
||||
///the index of this parameter in the params array of the parameter set
|
||||
int index;
|
||||
///should the parameter float without limits?
|
||||
bool unlimited;
|
||||
///this has been the error of a previous measurement
|
||||
double previous_error_low;
|
||||
double previous_error_high;
|
||||
///previous measurement, this can be different from the start value, e.g. when running a toy study
|
||||
double previous_measurement;
|
||||
///do we want to vary the parameter so that it is compatible with an earlier measurement
|
||||
bool gaussian_constraint;
|
||||
bool do_minos;
|
||||
///pointer to parent parameterset this parameter was added to!
|
||||
parameters* parent;
|
||||
public:
|
||||
///
|
||||
void set_parent(parameters* p) {parent = p;};
|
||||
//correlations
|
||||
std::vector<double> correlations;
|
||||
///public set routines
|
||||
void set_name(std::string n) {name = n;};
|
||||
void set_min(double m) {min = m;};
|
||||
void set_max(double m) {max = m;};
|
||||
void set_step_size(double s) {step_size = s;};
|
||||
void set_value(double v) {value = v;};
|
||||
void set_start_value(double v) {start_value = v;};
|
||||
//void set_true_value(double v) {true_value = v;};
|
||||
void set_description(std::string d) {description = d;};
|
||||
void set_error(double e) {error = e;};
|
||||
void set_error_down(double e) {error_down = e;};
|
||||
void set_error_up(double e) {error_up = e;};
|
||||
void set_unlimited(bool u) {unlimited = u;};
|
||||
void set_index(int idx) {index = idx;};
|
||||
void set_previous_measurement(double m) {previous_measurement = m;};
|
||||
void set_previous_error_low(double e) {previous_error_low = e;};
|
||||
void set_previous_error_high(double e) {previous_error_high = e;};
|
||||
void set_values_n_errors(double v, double e);
|
||||
void reset_correlations();
|
||||
void set_correlation(double corr, unsigned int idx);
|
||||
void set_correlations(std::vector<double> corrs, unsigned int first, unsigned int last, double scalefactor = 1.0);
|
||||
|
||||
///set blinding string
|
||||
void set_blinding_string(std::string s);
|
||||
void set_minos(bool minos) { do_minos = minos; };
|
||||
bool get_minos() { return do_minos; };
|
||||
void set_blinding(bool b, double b_scale, bool is_angle=false, std::string b_string="DefaultBlinder");
|
||||
|
||||
///set all values which make sense on initialisation
|
||||
void init(double v, double min, double max, double stepsize)
|
||||
{
|
||||
set_value(v);
|
||||
start_value = v;
|
||||
set_min(min);
|
||||
set_max(max);
|
||||
set_step_size(stepsize);
|
||||
set_error(0.0);
|
||||
set_error_up(0.0);
|
||||
set_error_down(0.0);
|
||||
set_unlimited(false);
|
||||
set_minos(false);
|
||||
gaussian_constraint = false;
|
||||
previous_measurement = v;
|
||||
correlations.clear();
|
||||
};
|
||||
|
||||
void init_fixed(double v){
|
||||
init(v, v-0.01, v+0.01, 0.0);
|
||||
//This eaquals to the previous init with limits of v-0.01, v+0.01
|
||||
//Not sure if there is a < or <= further in the code, so let's play it safe
|
||||
}
|
||||
void init(double v, double min, double max, double stepsize, double previous_measurement_error, bool constrain)
|
||||
{
|
||||
init(v, min, max, stepsize);
|
||||
previous_error_low = previous_measurement_error;
|
||||
previous_error_high = previous_measurement_error;
|
||||
gaussian_constraint = constrain;
|
||||
}
|
||||
void init(double v, double min, double max, double stepsize, double previous_measurement_error_low, double previous_measurement_error_high, bool constrain)
|
||||
{
|
||||
init(v, min, max, stepsize);
|
||||
previous_error_low = previous_measurement_error_low;
|
||||
previous_error_high = previous_measurement_error_high;
|
||||
gaussian_constraint = constrain;
|
||||
}
|
||||
void init_unlimited( double v, double min, double max, double stepsize, bool nolimits)
|
||||
{
|
||||
init(v, min, max, stepsize);
|
||||
unlimited = nolimits;
|
||||
};
|
||||
|
||||
///public get routines
|
||||
std::string get_name() const {return name;};
|
||||
const char* get_mn_name() const {return get_name().c_str();};
|
||||
double get_min() const {return min;};
|
||||
double get_max() const {return max;};
|
||||
double get_blinding_delta() const {return blinding_delta;};
|
||||
double get_step_size() const {return step_size;};
|
||||
double get_value() const {return value;};
|
||||
double get_start_value() const {return start_value;};
|
||||
//double get_true_value() const {return true_value;};
|
||||
double get_previous_error() const {return 0.5*(previous_error_low+previous_error_high);};
|
||||
double get_previous_error_low() const {return previous_error_low;};
|
||||
double get_previous_error_high() const {return previous_error_high;};
|
||||
double get_previous_measurement() const {return previous_measurement;};
|
||||
std::string get_description() const {return description;};
|
||||
bool get_unlimited() const {return unlimited;};
|
||||
bool get_gaussian_constraint() const {return gaussian_constraint;};
|
||||
|
||||
std::string get_root_name() const;
|
||||
///public set routines
|
||||
void set_constant() {step_size = 0.0;};
|
||||
double operator() () const {return value;};
|
||||
double get_error() const {return error;};
|
||||
double get_error_up() const {return error_up;};
|
||||
double get_error_down() const {return error_down;};
|
||||
int get_index() const {return index;};
|
||||
void reset_start() {value = start_value; error = 0.0;};
|
||||
///default constructor
|
||||
parameter(std::string n, std::string d):
|
||||
blind(false),
|
||||
blinding_string("DefaultBlinder"),
|
||||
blinding_delta(0.0),
|
||||
name(n),
|
||||
description(d),
|
||||
start_value(0.0),
|
||||
value(0.0),
|
||||
min(-1.0),
|
||||
max(+1.0),
|
||||
step_size(0.001),
|
||||
error(0.0),
|
||||
error_up(0.0),
|
||||
error_down(0.0),
|
||||
index(-1),
|
||||
unlimited(false),
|
||||
previous_error_low(0.0),
|
||||
previous_error_high(0.0),
|
||||
previous_measurement(0.0),
|
||||
gaussian_constraint(false)
|
||||
{};
|
||||
///normal constructor
|
||||
parameter(std::string n, std::string d, double v,
|
||||
double minimum, double maximum, double stepsize = 0.0, bool nolimits=false):
|
||||
blind(false),
|
||||
blinding_string("DefaultBlinder"),
|
||||
blinding_delta(0.0),
|
||||
name(n),
|
||||
description(d),
|
||||
start_value(v),
|
||||
// true_value(v),
|
||||
value(v),
|
||||
min(minimum),
|
||||
max(maximum),
|
||||
step_size(stepsize),
|
||||
error(0.0),
|
||||
error_up(0.0),
|
||||
error_down(0.0),
|
||||
index(-1),
|
||||
unlimited(nolimits),
|
||||
gaussian_constraint(false)
|
||||
{};
|
||||
bool is_blind() {
|
||||
return blind;
|
||||
};
|
||||
};
|
||||
|
||||
///The parameters class stores a collection of parameters used in the analysis. Every analysis should implement its own set e.g. bs2jpsiphi_parameters
|
||||
class parameters
|
||||
{
|
||||
private:
|
||||
///this vector holds the different parameters
|
||||
std::vector<parameter*> params;
|
||||
protected:
|
||||
///Add a certain parameter to the params vector.
|
||||
void add_parameter(parameter* param);
|
||||
public:
|
||||
bool is_blind() const;
|
||||
virtual ~parameters() {};
|
||||
///Method gives back he number of parameters
|
||||
unsigned int nparameters() const;
|
||||
///Methos returns a pointer to parameter with index i
|
||||
parameter* get_parameter(unsigned int i) const;
|
||||
///returns parameter with specific name
|
||||
parameter* get_parameter(std::string name) const;
|
||||
///Resets all parameters to their start values
|
||||
void reset_parameters();
|
||||
///Method that prints the parameter set, the current values, errors and the deviation from the start value in sigma
|
||||
void print_parameters(bool latex_output=true) const;
|
||||
///fix all parameters
|
||||
void fix_parameters();
|
||||
///set all parameters to current values! Careful with this, please.
|
||||
void take_current_as_start();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
458
Code/FCNCFitter/sources/Params/parameterscan.cc
Normal file
458
Code/FCNCFitter/sources/Params/parameterscan.cc
Normal file
@ -0,0 +1,458 @@
|
||||
#include <parameterscan.hh>
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <paths.hh>
|
||||
#include <options.hh>
|
||||
#include <funcs.hh>
|
||||
#include <generator.hh>
|
||||
#include <parameters.hh>
|
||||
#include <event.hh>
|
||||
#include <funcs.hh>
|
||||
#include <pdf.hh>
|
||||
#include <fitter.hh>
|
||||
#include <helpers.hh>
|
||||
|
||||
#include <TFile.h>
|
||||
#include <TTree.h>
|
||||
#include <TCanvas.h>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
/**
|
||||
* @file parameterscan.cc
|
||||
* @author Renata Kopecna
|
||||
* @date 2021-03-02
|
||||
*
|
||||
*/
|
||||
|
||||
fcnc::parameterscan::parameterscan(options* o):
|
||||
multifit(o)
|
||||
{
|
||||
};
|
||||
|
||||
void fcnc::parameterscan::scan(std::string param_name, double min, double max, unsigned int nsteps, unsigned int nevents, unsigned int reruns, pdf* prob, parameters* params, generator* gen, bool only_float_in_generation){
|
||||
std::vector<unsigned int > events;
|
||||
events.push_back(nevents);
|
||||
|
||||
std::vector<pdf* > probs;
|
||||
probs.push_back(prob);
|
||||
|
||||
std::vector<parameters* > the_params;
|
||||
the_params.push_back(params);
|
||||
|
||||
std::vector<generator* > gens;
|
||||
gens.push_back(gen);
|
||||
|
||||
scan(param_name, min, max, nsteps, events, reruns, probs, the_params, gens, only_float_in_generation);
|
||||
}
|
||||
|
||||
//void parameterscan::scan(std::string param_name, double min, double max, unsigned int nsteps, unsigned int nevents, unsigned int reruns, pdf_type* prob, params_type* params, generator_type* gen, bool only_float_in_generation) //fixed in fit on fixed value
|
||||
void fcnc::parameterscan::scan(std::string param_name, double min, double max, unsigned int nsteps, std::vector<unsigned int> nevents, unsigned int reruns, std::vector<pdf*> pdfs, std::vector<parameters*> params, std::vector<generator*> gens, bool only_float_in_generation){
|
||||
parameter* param_varied = 0;
|
||||
for (unsigned int i=0; i<params.size(); i++){
|
||||
if (params.at(i)->get_parameter(param_name)) {
|
||||
param_varied = params.at(i)->get_parameter(param_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//open TeX file
|
||||
std::ofstream myFile;
|
||||
open_Latex_noteFile(latex_paramScan(), myFile);
|
||||
|
||||
//parameter* param_varied = params->get_parameter(param_name);
|
||||
|
||||
double fit_start_value = param_varied->get_start_value();
|
||||
if (only_float_in_generation) spdlog::info( "The fit start value will be fixed at: {0:f}",fit_start_value);
|
||||
|
||||
int param_index = param_varied->get_index();
|
||||
if (param_varied != 0){
|
||||
std::string param_description = param_varied->get_description();
|
||||
std::string param_root = param_varied->get_root_name();
|
||||
spdlog::info( "Doing parameter scan of parameter {0:d}: {1:s}", param_index, param_name);
|
||||
spdlog::info( "Varying parameter from {0:f} to {1:f}", min, max);
|
||||
|
||||
unsigned int nparams = 0;
|
||||
for (unsigned int i=0; i<params.size(); i++){
|
||||
nparams += params.at(i)->nparameters();
|
||||
}
|
||||
//params->nparameters();
|
||||
|
||||
TH1D* error_hists[nparams];
|
||||
TH1D* value_hists[nparams];
|
||||
double mean_values[nparams][nsteps+1];
|
||||
double sigma_mean_values[nparams][nsteps+1];
|
||||
double mean_errors[nparams][nsteps+1];
|
||||
double sigma_mean_errors[nparams][nsteps+1];
|
||||
|
||||
double min_hist = min - 0.5*(max-min)/nsteps;
|
||||
double max_hist = max + 0.5*(max-min)/nsteps;
|
||||
//create histograms
|
||||
unsigned int start_param = 0;
|
||||
for (unsigned int i=0; i<params.size(); i++){
|
||||
for (unsigned int j = 0; j < nparams; j++){
|
||||
unsigned int idx = start_param+j;
|
||||
parameter* param = params.at(i)->get_parameter(j);
|
||||
error_hists[idx] = new TH1D(("error_" + param->get_name()).c_str(),
|
||||
("#sigma" + param->get_root_name() + ";" + param_root).c_str(),
|
||||
nsteps+1, min_hist, max_hist);
|
||||
error_hists[idx]->SetMarkerStyle(8);
|
||||
error_hists[idx]->SetMarkerColor(4);
|
||||
value_hists[idx] = new TH1D(("value_" + param->get_name()).c_str(),
|
||||
(param->get_root_name() + ";" + param_root).c_str(),
|
||||
nsteps+1, min_hist, max_hist);
|
||||
value_hists[idx]->SetMarkerStyle(8);
|
||||
value_hists[idx]->SetMarkerColor(4);
|
||||
}
|
||||
start_param += params.at(i)->nparameters();
|
||||
}
|
||||
//do precalculations
|
||||
for (unsigned int i=0; i<params.size(); i++){
|
||||
pdfs.at(i)->init(params.at(i));
|
||||
}
|
||||
//create output trees
|
||||
//current values to fill into the tree
|
||||
double value, error, error_up, error_down, start_value, param_value, nominal_error, nominal_value;
|
||||
int step, run, migrad, status_cov;
|
||||
std::vector<TTree*> trees;//one tree for every varied parameter
|
||||
//start_param = 0;
|
||||
for (unsigned int i=0; i<params.size(); i++){
|
||||
for (unsigned int j = 0; j < nparams; j++){
|
||||
//unsigned int idx = start_param+j;
|
||||
parameter* param = params.at(i)->get_parameter(j);
|
||||
if (param->get_step_size() != 0.0){
|
||||
std::string parname(param->get_name());
|
||||
std::string pardesc(param->get_description());// + " results");
|
||||
TTree* t = new TTree(parname.c_str(), pardesc.c_str());
|
||||
t->Branch("step",&step,"step/I");
|
||||
t->Branch("run",&run,"run/I");
|
||||
t->Branch("param_value",¶m_value,"param_value/D");
|
||||
t->Branch("value",&value,"value/D");
|
||||
t->Branch("error",&error,"error/D");
|
||||
t->Branch("nominal_value",&nominal_value,"nominal_value/D");
|
||||
t->Branch("nominal_error",&nominal_error,"nominal_error/D");
|
||||
t->Branch("error_up",&error_up,"error_up/D");
|
||||
t->Branch("error_down",&error_down,"error_down/D");
|
||||
t->Branch("start_value",&start_value,"start_value/D");
|
||||
t->Branch("migrad",&migrad,"migrad/I");
|
||||
t->Branch("status_cov",&status_cov,"status_cov/I");
|
||||
trees.push_back(t);
|
||||
}
|
||||
}
|
||||
//start_param += params.at(i)->nparameters();
|
||||
}
|
||||
|
||||
//enter main loop
|
||||
for (unsigned int i = 0; i <= nsteps; i++){
|
||||
//reset all results
|
||||
std::vector<std::vector<double> > values(nparams, std::vector<double>(reruns, 0.0));
|
||||
std::vector<std::vector<double> > errors(nparams, std::vector<double>(reruns, 0.0));
|
||||
std::vector<std::vector<double> > errors_up(nparams, std::vector<double>(reruns, 0.0));
|
||||
std::vector<std::vector<double> > errors_down(nparams, std::vector<double>(reruns, 0.0));
|
||||
std::vector<std::vector<double> > nominal_values(nparams, std::vector<double>(reruns, 0.0));
|
||||
std::vector<std::vector<double> > nominal_errors(nparams, std::vector<double>(reruns, 0.0));
|
||||
std::vector<int> return_values(reruns);
|
||||
|
||||
//only_float_in_generation means that you use a varied parameter
|
||||
//for generation but in the fit use the start_value
|
||||
//this can be used for systematic studies
|
||||
//we would also need to do a nominal fit
|
||||
//then we can see the actual difference
|
||||
|
||||
//choose new value for the scan parameter
|
||||
param_value = double(i)*(max - min)/(nsteps) + min;
|
||||
if (!only_float_in_generation){ //float in generation and fit
|
||||
param_varied->set_value(param_value);
|
||||
param_varied->set_start_value(param_value);
|
||||
}
|
||||
// param_varied->init(param_name, param_description,
|
||||
// param_value,
|
||||
// param_varied->get_min(), param_varied->get_max(),
|
||||
// param_varied->get_step_size());
|
||||
|
||||
//this is the scanned parameter so usually we change it before generation and fit
|
||||
//this is the point: we need to do a couple reruns
|
||||
fitter fit(opts);
|
||||
fit.set_common_parameters(common_params);
|
||||
|
||||
for (unsigned int k = 0; k < reruns; k++){
|
||||
spdlog::info( "Parameter "+param_name+" {0:f}", param_value);
|
||||
spdlog::info( "Run no. {0:d}", k);
|
||||
std::string num;
|
||||
std::stringstream out;
|
||||
out << opts->name << "_" << (i+1) << "_" << (k+1); //TOOD: move to paths
|
||||
num = out.str();
|
||||
|
||||
if (only_float_in_generation){//this generates with updated parameter values
|
||||
param_varied->set_value(param_value);
|
||||
param_varied->set_start_value(param_value);
|
||||
}
|
||||
// param_varied->init(param_name, param_description,
|
||||
// param_value,
|
||||
// param_varied->get_min(), param_varied->get_max(),
|
||||
// param_varied->get_step_size());
|
||||
|
||||
for (unsigned int j=0; j<params.size(); j++){
|
||||
params.at(j)->reset_parameters();//this line was missing before? did we generate with fitted params?
|
||||
}
|
||||
|
||||
std::vector< std::vector <event> > temp_events;
|
||||
for (unsigned int j=0; j<gens.size(); j++){
|
||||
std::vector<event> ev = gens.at(j)->generate(nevents.at(j), params.at(j), pdfs.at(j));
|
||||
temp_events.push_back(ev);
|
||||
}
|
||||
std::vector< std::vector <event> * > events;
|
||||
for (unsigned int j=0; j<gens.size(); j++){
|
||||
events.push_back(&temp_events.at(j));
|
||||
}
|
||||
|
||||
if (only_float_in_generation){//this tries to fit with original parameter values
|
||||
param_varied->set_value(fit_start_value);
|
||||
param_varied->set_start_value(fit_start_value);
|
||||
}
|
||||
// param_varied->init(param_name, param_description,
|
||||
// fit_start_value, //use start value here!
|
||||
// param_varied->get_min(), param_varied->get_max(),
|
||||
// param_varied->get_step_size());
|
||||
|
||||
|
||||
for (unsigned int j=0; j<params.size(); j++){
|
||||
params.at(j)->reset_parameters();
|
||||
}
|
||||
int result = 0;
|
||||
result = fit.fit(pdfs, params, events, num);
|
||||
|
||||
return_values.at(k) = result;
|
||||
if (result != 0 && opts->repeat_on_fail){
|
||||
spdlog::warn( "Fit failed, repeating run");
|
||||
k--;
|
||||
continue;
|
||||
}
|
||||
unsigned int start_param = 0;
|
||||
for (unsigned int j = 0; j < params.size(); j++){
|
||||
for (unsigned int l = 0; l < params.at(j)->nparameters(); l++){
|
||||
unsigned int idx = start_param+l;
|
||||
parameter* param = params.at(j)->get_parameter(l);
|
||||
values.at(idx).at(k) = param->get_value();
|
||||
errors.at(idx).at(k) = param->get_error();
|
||||
errors_up.at(idx).at(k) = param->get_error_up();
|
||||
errors_down.at(idx).at(k) = param->get_error_down();
|
||||
}
|
||||
start_param += params.at(j)->nparameters();
|
||||
}
|
||||
//now we want to do a nominal fit (if the respective options are set)
|
||||
if (opts->refitting_nominal && only_float_in_generation){//now we do a nominal fit
|
||||
spdlog::info( "Nominal fit");
|
||||
|
||||
param_varied->set_value(param_value);
|
||||
param_varied->set_start_value(param_value);
|
||||
// param_varied->init(param_name, param_description,
|
||||
// param_value,
|
||||
// param_varied->get_min(), param_varied->get_max(),
|
||||
// param_varied->get_step_size());
|
||||
|
||||
for (unsigned int j = 0; j < params.size(); j++){
|
||||
params.at(j)->reset_parameters();
|
||||
}
|
||||
//and lets fit
|
||||
fit.fit(pdfs, params, events, num);
|
||||
|
||||
//extract the parameters from the fit
|
||||
start_param = 0;
|
||||
for (unsigned int j = 0; j < params.size(); j++){
|
||||
for (unsigned int l = 0; l < params.at(j)->nparameters(); l++){
|
||||
unsigned int idx = start_param+l;
|
||||
parameter* param = params.at(j)->get_parameter(l);
|
||||
nominal_values.at(idx).at(k) = (param->get_value());
|
||||
nominal_errors.at(idx).at(k) = (param->get_error());
|
||||
}
|
||||
start_param += params.at(j)->nparameters();
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (unsigned int j = 0; j < nparams; j++){
|
||||
nominal_values.at(j).at(k) = (0.0);
|
||||
nominal_errors.at(j).at(k) = (0.0);
|
||||
}
|
||||
}
|
||||
|
||||
}//end reruns
|
||||
|
||||
//determine means/widths of the distributions via gauss-fits
|
||||
unsigned int start_param = 0;
|
||||
for (unsigned int j = 0; j < params.size(); j++){
|
||||
for (unsigned int k = 0; k < params.at(j)->nparameters(); k++){
|
||||
unsigned int idx = start_param + k;
|
||||
parameter* param = params.at(j)->get_parameter(k);
|
||||
if (param->get_step_size() != 0.0){
|
||||
std::string step;
|
||||
std::stringstream out;
|
||||
out << (i+1);
|
||||
step = out.str();
|
||||
|
||||
double dummy1, dummy2, dummy3, dummy4, dummy5;
|
||||
double mean_value, mean_error, sigma_mean_value, sigma_mean_error;
|
||||
update_pull(param, values.at(idx), errors.at(idx),
|
||||
dummy1, dummy2, dummy3, dummy4, dummy5, step);
|
||||
update_value(param, values.at(idx), errors.at(idx),
|
||||
mean_value, sigma_mean_value, dummy3, dummy4, dummy5, step);
|
||||
update_error(param, values.at(idx), errors.at(idx),
|
||||
mean_error, sigma_mean_error, dummy3, dummy4, dummy5, step);
|
||||
|
||||
value_hists[idx]->SetBinContent(i+1,mean_value);
|
||||
value_hists[idx]->SetBinError(i+1,sigma_mean_value);
|
||||
error_hists[idx]->SetBinContent(i+1,mean_error);
|
||||
error_hists[idx]->SetBinError(i+1,sigma_mean_error);
|
||||
|
||||
mean_values[idx][i] = mean_value;//for the output tables
|
||||
sigma_mean_values[idx][i] = sigma_mean_value;//for the output tables
|
||||
mean_errors[idx][i] = mean_error;
|
||||
sigma_mean_errors[idx][i] = sigma_mean_error;
|
||||
}
|
||||
}
|
||||
start_param += params.at(j)->nparameters();
|
||||
}
|
||||
|
||||
//save tree results
|
||||
int param_idx = 0;
|
||||
output->cd();
|
||||
start_param = 0;
|
||||
for (unsigned int j = 0; j < params.size(); j++){//this gives nice output
|
||||
for (unsigned int l = 0; l < params.at(j)->nparameters(); l++){
|
||||
unsigned int idx = start_param+l;
|
||||
parameter* param = params.at(j)->get_parameter(l);
|
||||
if (param->get_step_size() != 0.0){
|
||||
TTree* t = trees.at(param_idx);
|
||||
for (unsigned int k=0; k<reruns; k++){
|
||||
step = i;
|
||||
run = k;
|
||||
//param_value is already set;
|
||||
value = values.at(idx).at(k);
|
||||
error = errors.at(idx).at(k);
|
||||
nominal_value = nominal_values.at(idx).at(k);
|
||||
nominal_error = nominal_errors.at(idx).at(k);
|
||||
error_up = errors_up.at(idx).at(k);
|
||||
error_down = errors_down.at(idx).at(k);
|
||||
start_value = param->get_start_value();
|
||||
migrad = return_values.at(k) % 100;
|
||||
status_cov = return_values.at(k) / 100;
|
||||
t->Fill();
|
||||
}
|
||||
param_idx++;
|
||||
}
|
||||
}
|
||||
start_param += params.at(j)->nparameters();
|
||||
}
|
||||
}
|
||||
//save output trees
|
||||
for (unsigned int j = 0; j < trees.size(); j++){
|
||||
trees.at(j)->Write();
|
||||
}
|
||||
|
||||
//summary output
|
||||
myFile << "Parameter scan results: values\\\\" << std::endl;
|
||||
myFile << "\\begin{tabular}{|c|";
|
||||
for (unsigned int i=0; i<=nsteps; i++){
|
||||
myFile << "c";
|
||||
}
|
||||
myFile << "|}\\hline" << std::endl;
|
||||
myFile << "$" << param_varied->get_description() << "$";
|
||||
for (unsigned int i=0; i<=nsteps; i++){
|
||||
double param_value = double(i)*(max - min)/(nsteps) + min;
|
||||
myFile << " & " << std::setprecision(2) << param_value;
|
||||
}
|
||||
myFile << "\\\\ \\hline" << std::endl;
|
||||
|
||||
start_param = 0;
|
||||
for (unsigned int i=0; i < params.size(); i++){
|
||||
for (unsigned int j=0; j < params.at(i)->nparameters(); j++){
|
||||
unsigned int idx = start_param+j;
|
||||
if (params.at(i)->get_parameter(j)->get_step_size() != 0.0){
|
||||
myFile << "$" << params.at(i)->get_parameter(j)->get_description() << "$";
|
||||
for (unsigned int k=0; k <= nsteps; k++){
|
||||
myFile << " & $" << std::setprecision(2)
|
||||
<< mean_values[idx][k] << " \\pm "
|
||||
//<< mean_errors[i][j]
|
||||
<< sigma_mean_values[idx][k]
|
||||
<< "$";
|
||||
}
|
||||
myFile << "\\\\" << std::endl;
|
||||
}
|
||||
}
|
||||
start_param += params.at(i)->nparameters();
|
||||
}
|
||||
myFile << "\\hline \\end{tabular}" << std::endl;
|
||||
|
||||
myFile << "Parameter scan results: errors\\\\" << std::endl;
|
||||
myFile << "\\begin{tabular}{|c|";
|
||||
for (unsigned int i=0; i<=nsteps; i++){
|
||||
myFile << "c";
|
||||
}
|
||||
myFile << "|}\\hline" << std::endl;
|
||||
myFile << "$" << param_varied->get_description() << "$";
|
||||
for (unsigned int i=0; i<=nsteps; i++){
|
||||
double param_value = double(i)*(max - min)/(nsteps) + min;
|
||||
myFile << " & " << std::setprecision(2) << param_value;
|
||||
}
|
||||
myFile << "\\\\ \\hline" << std::endl;
|
||||
|
||||
start_param = 0;
|
||||
for (unsigned int i=0; i < params.size(); i++){
|
||||
for (unsigned int j=0; j < params.at(i)->nparameters(); j++){
|
||||
unsigned int idx = start_param+j;
|
||||
if (params.at(i)->get_parameter(j)->get_step_size() != 0.0){
|
||||
myFile << "$" << params.at(i)->get_parameter(j)->get_description() << "$";
|
||||
for (unsigned int k=0; k <= nsteps; k++){
|
||||
myFile << " & $" << std::setprecision(2)
|
||||
<< mean_errors[idx][k] << " \\pm "
|
||||
<< sigma_mean_errors[idx][k] << "$";
|
||||
}
|
||||
myFile << "\\\\" << std::endl;
|
||||
}
|
||||
}
|
||||
start_param += params.at(i)->nparameters();
|
||||
}
|
||||
myFile << "\\hline \\end{tabular}" << std::endl;
|
||||
|
||||
start_param = 0;
|
||||
for (unsigned int i=0; i < params.size(); i++){
|
||||
for (unsigned int j=0; j < params.at(i)->nparameters(); j++){
|
||||
unsigned int idx = start_param+j;
|
||||
//print result histos
|
||||
if (params.at(i)->get_parameter(j)->get_step_size() != 0.0){
|
||||
output->cd();
|
||||
parameter* param = params.at(i)->get_parameter(j);
|
||||
|
||||
std::string error_name = "parameter scan sigma(" + param->get_name() + ")";
|
||||
TCanvas *c1 = new TCanvas(error_name.c_str(), error_name.c_str(), 1600, 1200);
|
||||
c1->cd();
|
||||
error_hists[idx]->Draw("e");
|
||||
if (opts->write_eps) c1->Print(get_param_scan_path(param->get_name(),true).c_str(), "eps");
|
||||
c1->Write();
|
||||
delete error_hists[idx];
|
||||
delete c1;
|
||||
|
||||
std::string value_name = "Parameter scan "+param->get_name();
|
||||
TCanvas *c2 = new TCanvas(value_name.c_str(), value_name.c_str(), 1600, 1200);
|
||||
c2->cd();
|
||||
value_hists[idx]->Draw("e");
|
||||
if (opts->write_eps) c2->Print(get_param_scan_path(param->get_name(),false).c_str(), "eps");
|
||||
c2->Write();
|
||||
delete value_hists[idx];
|
||||
delete c2;
|
||||
|
||||
//TODO add pulls
|
||||
}
|
||||
}
|
||||
start_param += params.at(i)->nparameters();
|
||||
}
|
||||
}
|
||||
else{
|
||||
spdlog::error("Parameter "+param_name+" not found.");
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
70
Code/FCNCFitter/sources/Params/parameterscan.hh
Normal file
70
Code/FCNCFitter/sources/Params/parameterscan.hh
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @file parameterscan.hh
|
||||
* @author Christoph Langenbruch, Renata Kopecna
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PARAMETERSCAN_H
|
||||
#define PARAMETERSCAN_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <multifit.hh>
|
||||
|
||||
//TODO: move to /Run/!
|
||||
|
||||
namespace fcnc {
|
||||
class options;
|
||||
class generator;
|
||||
class parameters;
|
||||
class pdf;
|
||||
|
||||
///class to perform repeated fits while changing a parameter value, e.g. background fraction
|
||||
class parameterscan: public multifit {
|
||||
private:
|
||||
///common parameters in different parameter sets
|
||||
std::vector< std::string > common_params;
|
||||
public:
|
||||
///constructor
|
||||
parameterscan(options* o);
|
||||
/**
|
||||
* perform a parameter scan
|
||||
* @param param_name the name of the parameter which will be varied in the scan
|
||||
* @param min the start value for the varied parameter
|
||||
* @param max the stop value for the varied parameter
|
||||
* @param nsteps the number of steps in which to vary the parameter
|
||||
* @param nevents the number of events used per fit of the toy data
|
||||
* @param reruns the number of repeats for a single value of the parameter
|
||||
* @param prob pointer to the pdf to use in the likelihood fit
|
||||
* @param params pointer to parameterset to use in the likelihood fit
|
||||
* @param gen pointer to the toy data generator to use
|
||||
* @param only_float_in_generation only varies the parameter in the generation,
|
||||
* but fixes it in the fit. This way one can do systematic studies.
|
||||
**/
|
||||
void scan(std::string param_name, double min, double max, unsigned int nsteps, unsigned int nevents, unsigned int reruns, pdf* prob, parameters* params, generator* gen, bool only_float_in_generation=false);
|
||||
/**
|
||||
* perform a parameter scan
|
||||
* @param param_name the name of the parameter which will be varied in the scan
|
||||
* @param min the start value for the varied parameter
|
||||
* @param max the stop value for the varied parameter
|
||||
* @param nsteps the number of steps in which to vary the parameter
|
||||
* @param nevents the number of events used per fit of the toy data
|
||||
* @param reruns the number of repeats for a single value of the parameter
|
||||
* @param prob pointer to the pdf to use in the likelihood fit
|
||||
* @param params pointer to parameterset to use in the likelihood fit
|
||||
* @param gen pointer to the toy data generator to use
|
||||
* @param only_float_in_generation only varies the parameter in the generation,
|
||||
* but fixes it in the fit. This way one can do systematic studies.
|
||||
**/
|
||||
void scan(std::string param_name, double min, double max, unsigned int nsteps, std::vector<unsigned int> nevents, unsigned int reruns, std::vector<pdf*> pdfs, std::vector<parameters*> params, std::vector<generator*> gens, bool only_float_in_generation=false);
|
||||
///set common parameters
|
||||
void set_common_parameters(std::vector<std::string> common_pars) {
|
||||
common_params = common_pars;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
58
Code/FCNCFitter/sources/Params/values.hh
Normal file
58
Code/FCNCFitter/sources/Params/values.hh
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @file values.hh
|
||||
* @author David Gerick
|
||||
* @date 2018-04-03
|
||||
*
|
||||
* This file contains the values that may be shared between functions!
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef VALUES_H
|
||||
#define VALUES_H
|
||||
|
||||
namespace fcnc {
|
||||
|
||||
///class that stores the options used in the analysis
|
||||
class values {
|
||||
public:
|
||||
|
||||
///resulting chi2 of angular acceptance correction parametrization
|
||||
double angacccorr_chi2;
|
||||
///number of degrees of freedom in chi2 test of angular acceptance correction
|
||||
int angacccorr_ndof;
|
||||
|
||||
///chi2 calculated from 4 * 1D projections in angular acceptance corrections
|
||||
double chi2_4_1D;
|
||||
double chi2_4_1D_ctk;
|
||||
double chi2_4_1D_ctl;
|
||||
double chi2_4_1D_phi;
|
||||
double chi2_4_1D_q2;
|
||||
///number of degrees of freedom in 4 * 1D projections
|
||||
int ndof_4_1D;
|
||||
int ndof_4_1D_ctk;
|
||||
int ndof_4_1D_ctl;
|
||||
int ndof_4_1D_phi;
|
||||
int ndof_4_1D_q2;
|
||||
|
||||
//constructor:
|
||||
values():
|
||||
angacccorr_chi2(1.0),
|
||||
angacccorr_ndof(1),
|
||||
chi2_4_1D(1.0),
|
||||
chi2_4_1D_ctk(1.0),
|
||||
chi2_4_1D_ctl(1.0),
|
||||
chi2_4_1D_phi(1.0),
|
||||
chi2_4_1D_q2(1.0),
|
||||
ndof_4_1D(1),
|
||||
ndof_4_1D_ctk(1),
|
||||
ndof_4_1D_ctl(1),
|
||||
ndof_4_1D_phi(1),
|
||||
ndof_4_1D_q2(1)
|
||||
{
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
908
Code/FCNCFitter/sources/Run/angularcorr.cc
Normal file
908
Code/FCNCFitter/sources/Run/angularcorr.cc
Normal file
@ -0,0 +1,908 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <angularcorr.hh>
|
||||
#include <sstream> // std::istringstream
|
||||
|
||||
#include <options.hh>
|
||||
#include <event.hh>
|
||||
#include <values.hh>
|
||||
#include <helpers.hh>
|
||||
#include <paths.hh>
|
||||
#include <design.hh>
|
||||
|
||||
#include <bu2kstarmumu_loader.hh>
|
||||
#include <bu2kstarmumu_parameters.hh>
|
||||
#include <bu2kstarmumu_pdf.hh>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
#include <TFitResult.h>
|
||||
#include <TH2D.h>
|
||||
#include <TROOT.h>
|
||||
#include <TChain.h>
|
||||
#include <TFile.h>
|
||||
#include <TRandom3.h>
|
||||
#include <TMatrixD.h>
|
||||
#include <TStyle.h>
|
||||
|
||||
|
||||
//-------------------------------
|
||||
// scan angular acceptance max. order of legendre
|
||||
//-------------------------------
|
||||
|
||||
|
||||
void logYears(std::vector<int>years, std::vector< std::vector<fcnc::event> > eves, int loadedSize){
|
||||
|
||||
for(UInt_t y = 0; y < years.size(); y++){
|
||||
spdlog::info("Events in run {0:d} : {1:d}", years.at(y) , eves.at(y).size());
|
||||
}
|
||||
spdlog::info( "------------------------");
|
||||
spdlog::info("Events in total: {0:d}", loadedSize);
|
||||
return;
|
||||
}
|
||||
|
||||
void logYears(int run, int evtsSize, int loadedSize){
|
||||
spdlog::info("Events in run {0:d} : {1:d}", run, evtsSize);
|
||||
spdlog::info("------------------------");
|
||||
spdlog::info("Events in total : {0:d}", loadedSize);
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// scan angular acceptance
|
||||
//-------------------------------
|
||||
|
||||
std::vector<int> get_scan_low(bool quickTest, bool only_1D_chi2){
|
||||
//q2, thetak, thetal, phi
|
||||
if (quickTest) return {6,5,5,2};//use small range for quick tests on format or algorithms:
|
||||
if (only_1D_chi2) return {2,2,2,2};//use huge range for quick tests of 1D chi2:
|
||||
return {6,5,2,1};
|
||||
}
|
||||
|
||||
std::vector<int> get_scan_high(bool quickTest, bool only_1D_chi2){
|
||||
//q2, thetak, thetal, phi
|
||||
if (quickTest) return {6,10,5,2};//use small range for quick tests on format or algorithms:
|
||||
if (only_1D_chi2) return {9,9,9,9};//use huge range for quick tests of 1D chi2:
|
||||
return {8,7,4,3};
|
||||
}
|
||||
|
||||
std::vector<int> get_scan_range(std::vector<int> scan_low, std::vector<int> scan_high){
|
||||
std::vector<int> scan_range;
|
||||
for_indexed(auto item: scan_low){
|
||||
//If high >= low, raise an exception
|
||||
assert(scan_high.at(i) >= item);
|
||||
scan_range.push_back(scan_high.at(i) -item + 1);
|
||||
}
|
||||
return scan_range;
|
||||
}
|
||||
|
||||
int sanityCheck(std::vector<fcnc::event>events, fcnc::options opts, bool PHSP, int bin, bool norm){
|
||||
//events: input events
|
||||
//opts: general options
|
||||
//PHSP: using PHSP or sigMC?
|
||||
//bin: # of bin in q2, when all, set to -1
|
||||
//norm: Normalize the plots?
|
||||
|
||||
//Create parameter set
|
||||
fcnc::bu2kstarmumu_parameters * leParameters = new fcnc::bu2kstarmumu_parameters(&opts);
|
||||
//create PDF
|
||||
fcnc::bu2kstarmumu_pdf * lePDF = new fcnc::bu2kstarmumu_pdf(&opts, leParameters);
|
||||
std::vector<fcnc::event> *leEvents= new std::vector<fcnc::event>;
|
||||
|
||||
opts.weighted_fit = true; //Jesus efin christ
|
||||
int nAngleBins = 20;
|
||||
|
||||
for(auto meas: events){
|
||||
leEvents->push_back(meas);
|
||||
}
|
||||
leParameters->use_default();
|
||||
leParameters->take_current_as_start();
|
||||
|
||||
lePDF->load_coeffs_eff_phsp_4d();
|
||||
opts.multiply_eff = true;
|
||||
opts.weighted_fit = true;
|
||||
lePDF->update_cached_efficiencies(leParameters, leEvents);
|
||||
lePDF->update_cached_normalization(leParameters);
|
||||
|
||||
//check the distributions of weighted events
|
||||
TH1D * ctl = new TH1D ("h_ctl", "h_ctl", nAngleBins, CTL_MIN, CTL_MAX);
|
||||
TH1D * ctk = new TH1D ("h_ctk", "h_ctk", nAngleBins, CTK_MIN, CTK_MAX);
|
||||
TH1D * phi = new TH1D ("h_phi", "h_phi", nAngleBins, PHI_MIN, PHI_MAX);
|
||||
TH1D * q2 = new TH1D ("h_q2" , "h_q2" , nAngleBins, Q2_MIN_RANGE, Q2_MAX_RANGE);
|
||||
TH2D * ctkq2 = new TH2D ("h_ctkq2" , "h_ctkq2", nAngleBins, CTK_MIN, CTK_MAX, nAngleBins, Q2_MIN_RANGE, Q2_MAX_RANGE);
|
||||
TH2D * ctlq2 = new TH2D ("h_ctlq2" , "h_ctlq2", nAngleBins, CTL_MIN, CTL_MAX, nAngleBins, Q2_MIN_RANGE, Q2_MAX_RANGE);
|
||||
TH2D * phiq2 = new TH2D ("h_phiq2" , "h_phiq2", nAngleBins, PHI_MIN, PHI_MAX, nAngleBins, Q2_MIN_RANGE, Q2_MAX_RANGE);
|
||||
TH1D * ctl_noW = new TH1D ("ctl_noW", "ctl_noW", nAngleBins, CTL_MIN, CTL_MAX);
|
||||
TH1D * ctk_noW = new TH1D ("ctk_noW", "ctk_noW", nAngleBins, CTK_MIN, CTK_MAX);
|
||||
TH1D * phi_noW = new TH1D ("phi_noW", "phi_noW", nAngleBins, PHI_MIN, PHI_MAX);
|
||||
TH1D * q2_noW = new TH1D ("q2_noW" , "q2_noW" , nAngleBins, Q2_MIN_RANGE, Q2_MAX_RANGE);
|
||||
TH1D* hweight = new TH1D("hweight", ";w;", 100, 0.0, 1.0/EFF_CUTOFF);
|
||||
|
||||
|
||||
for(auto &meas: *leEvents){
|
||||
if(meas.weight < 0.0){
|
||||
spdlog::warn("negative weight event:\tm={0:f} \t\tctl={1:f} \tctk={2:f}\tphi={3:f} \tweight={4:f}", meas.m, meas.costhetal, meas.costhetak, meas.phi, meas.weight);
|
||||
}
|
||||
ctl->Fill(meas.costhetal, meas.weight);
|
||||
ctk->Fill(meas.costhetak, meas.weight);
|
||||
phi->Fill(meas.phi, meas.weight);
|
||||
q2 ->Fill(meas.q2, meas.weight);
|
||||
ctkq2->Fill(meas.costhetak, meas.q2, meas.weight);
|
||||
ctlq2->Fill(meas.costhetal, meas.q2, meas.weight);
|
||||
phiq2->Fill(meas.phi, meas.q2, meas.weight);
|
||||
|
||||
ctl_noW->Fill(meas.costhetal);
|
||||
ctk_noW->Fill(meas.costhetak);
|
||||
phi_noW->Fill(meas.phi);
|
||||
q2_noW ->Fill(meas.q2);
|
||||
if (meas.weight > 30){
|
||||
spdlog::warn("Event with very high weight {0:f} found!", meas.weight);
|
||||
print_event(meas);
|
||||
}
|
||||
|
||||
hweight->Fill(meas.weight);
|
||||
|
||||
}
|
||||
//phi->GetYaxis()->SetRangeUser(5000,7000);
|
||||
|
||||
|
||||
int tagNumber =1*opts.eff_order_q2+
|
||||
100*opts.eff_order_costhetak+
|
||||
10000* opts.eff_order_costhetal+
|
||||
1000000*opts.eff_order_phi ;
|
||||
|
||||
|
||||
//Normalize to one
|
||||
|
||||
if (norm){
|
||||
ctl->Scale(nAngleBins/ctl->Integral());
|
||||
ctk->Scale(nAngleBins/ctk->Integral());
|
||||
phi->Scale(nAngleBins/phi->Integral());
|
||||
q2->Scale(nAngleBins/q2->Integral());
|
||||
ctkq2->Scale(nAngleBins*nAngleBins/ctkq2->Integral());
|
||||
ctlq2->Scale(nAngleBins*nAngleBins/ctlq2->Integral());
|
||||
phiq2->Scale(nAngleBins*nAngleBins/phiq2->Integral());
|
||||
}
|
||||
|
||||
std::string subfolder = get_angCorrPath(false);
|
||||
std::string tag = (PHSP ? "" : "MC_") + (bin==-1 ? "" : "_bin"+std::to_string(bin)) + tag_Run(opts.run) +"_" + std::to_string(tagNumber);
|
||||
if (PHSP){
|
||||
//Get the fitted lines
|
||||
TF1 *fitLine_ctl = fitStraightLine(ctl, "fitLine_ctl", CTL_MIN, CTL_MAX);
|
||||
TF1 *fitLine_ctk = fitStraightLine(ctk, "fitLine_ctk", CTK_MIN, CTK_MAX);
|
||||
TF1 *fitLine_phi = fitStraightLine(phi, "fitLine_phi", PHI_MIN, PHI_MAX);
|
||||
TF1 *fitLine_q2 = fitStraightLine(q2, "fitLine_q2", Q2_MIN_RANGE, Q2_MAX_RANGE);
|
||||
//and plot them
|
||||
plotAndSaveWithLine(ctl,fitLine_ctl,"c_ctl",subfolder+"debug_ctl_"+tag,"eps");
|
||||
plotAndSaveWithLine(ctk,fitLine_ctk,"c_ctk",subfolder+"debug_ctk_"+tag,"eps");
|
||||
plotAndSaveWithLine(phi,fitLine_phi,"c_phi",subfolder+"debug_phi_"+tag,"eps");
|
||||
plotAndSaveWithLine(q2, fitLine_q2, "c_q2" ,subfolder+"debug_q2_"+tag, "eps");
|
||||
}
|
||||
else{
|
||||
plotAndSave(ctl,"c_ctl",subfolder+"debug_ctl_"+tag,"eps");
|
||||
plotAndSave(ctk,"c_ctk",subfolder+"debug_ctk_"+tag,"eps");
|
||||
plotAndSave(phi,"c_phi",subfolder+"debug_phi_"+tag,"eps");
|
||||
plotAndSave(q2, "c_q2" ,subfolder+"debug_q2_"+tag, "eps");
|
||||
}
|
||||
plotAndSave(ctkq2, "c_ctkq2" ,subfolder+"debug_ctkq2_"+tag, "eps");
|
||||
plotAndSave(ctlq2, "c_ctlq2" ,subfolder+"debug_ctlq2_"+tag, "eps");
|
||||
plotAndSave(phiq2, "c_phiq2" ,subfolder+"debug_phiq2_"+tag, "eps");
|
||||
plotAndSave(hweight, "c_weight" ,subfolder+"debug_weights_"+tag, "eps");
|
||||
|
||||
std::string outputPath = subfolder + "debug_angles"+ tag + ".root";
|
||||
TFile *output = new TFile(outputPath.c_str(),"RECREATE");
|
||||
output->cd();
|
||||
ctl->Write("",TObject::kWriteDelete);
|
||||
ctk->Write("",TObject::kWriteDelete);
|
||||
phi->Write("",TObject::kWriteDelete);
|
||||
q2->Write("",TObject::kWriteDelete);
|
||||
ctkq2->Write("",TObject::kWriteDelete);
|
||||
ctlq2->Write("",TObject::kWriteDelete);
|
||||
phiq2->Write("",TObject::kWriteDelete);
|
||||
hweight->Write("",TObject::kWriteDelete);
|
||||
output->Close();
|
||||
|
||||
|
||||
if (norm){ //save only when the option of normalization is on
|
||||
plotAndSave(ctl_noW,"c_ctl_noW",subfolder+"debug_ctl_noW_"+tag,"eps");
|
||||
plotAndSave(ctk_noW,"c_ctk_noW",subfolder+"debug_ctk_noW_"+tag,"eps");
|
||||
plotAndSave(phi_noW,"c_phi_noW",subfolder+"debug_phi_noW_"+tag,"eps");
|
||||
plotAndSave(q2_noW, "c_q2_noW" ,subfolder+"debug_q2_noW_"+tag, "eps");
|
||||
}
|
||||
|
||||
delete ctl;
|
||||
delete ctk;
|
||||
delete phi;
|
||||
delete q2;
|
||||
delete ctlq2;
|
||||
delete ctkq2;
|
||||
delete phiq2;
|
||||
delete ctl_noW;
|
||||
delete ctk_noW;
|
||||
delete phi_noW;
|
||||
delete q2_noW;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sanityCheck_MC(fcnc::options opts){
|
||||
|
||||
spdlog::info("Checking MC distribution after correction");
|
||||
|
||||
//load MC
|
||||
std::vector<fcnc::event> events;
|
||||
|
||||
if (opts.run == 1){
|
||||
events = fcnc::load_events(get_theFCNCpath(1,1), "Events", -1);
|
||||
}
|
||||
else if (opts.run == 2){
|
||||
events = fcnc::load_events(get_theFCNCpath(1,2), "Events", -1);
|
||||
}
|
||||
else {
|
||||
std::vector<fcnc::event> events1 = fcnc::load_events(get_theFCNCpath(1,1), "Events", -1);
|
||||
std::vector<fcnc::event> events2 = fcnc::load_events(get_theFCNCpath(1,2), "Events", -1);
|
||||
events = {merge_two_evtVecs(events1,events2)};
|
||||
}
|
||||
for (unsigned int b = 0; b < opts.get_nQ2bins(); b++){
|
||||
std::vector<fcnc::event> filtered_events;
|
||||
for (auto &evt: events){
|
||||
|
||||
if (evt.costhetal > opts.ctl_max) continue;
|
||||
if (evt.costhetal < opts.ctl_min) continue;
|
||||
if (evt.costhetak > opts.ctk_max) continue;
|
||||
if (evt.costhetak < opts.ctk_min) continue;
|
||||
if (evt.phi > opts.phi_max) continue;
|
||||
if (evt.phi < opts.phi_min) continue;
|
||||
if (evt.q2 > opts.TheQ2binsmax[b]) continue;
|
||||
if (evt.q2 < opts.TheQ2binsmin[b]) continue;
|
||||
filtered_events.push_back(evt);
|
||||
}
|
||||
sanityCheck(filtered_events, opts, false, b, false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
std::vector< std::vector<fcnc::event> > select_event(fcnc::options opts,std::vector<int> years){
|
||||
//Load and check size of events in both runs
|
||||
|
||||
std::vector<fcnc::event>events[2] = {
|
||||
fcnc::load_events(get_theFCNCpath(3,1), "Events", -1),
|
||||
fcnc::load_events(get_theFCNCpath(3,2), "Events", -1)
|
||||
};
|
||||
assert(events[0].size());
|
||||
assert(events[1].size());
|
||||
spdlog::debug("Load angular corrections per two years?\t{0:b}",opts.angacccorrpertwoyears);
|
||||
spdlog::debug("Load angular corrections for both runs?\t{0:b}",opts.angacccorrbothruns);
|
||||
|
||||
std::vector<fcnc::event> loaded_events;
|
||||
if (opts.angacccorrbothruns) loaded_events = merge_two_evtVecs(events[0], events[1]);
|
||||
else if (opts.angacccorrpertwoyears) loaded_events = events[1];
|
||||
else loaded_events = events[opts.run-1];
|
||||
|
||||
std::vector< std::vector<fcnc::event> > eves;
|
||||
|
||||
if (opts.angacccorrperyear || opts.angacccorrpertwoyears){
|
||||
spdlog::debug("Seperate sample into {0:d} sub-samples. One per year!",years.size());
|
||||
//create indidividual vectors for every year
|
||||
std::vector<fcnc::event>eve_year(years.size());
|
||||
//fill events into the correct vector
|
||||
for(auto ev: loaded_events){
|
||||
for(uint y = 0; y < years.size(); y++){
|
||||
if(ev.year == years.at(y)) eves.at(y).push_back(ev);
|
||||
}
|
||||
}
|
||||
|
||||
//print the corresponding numbers in every vector:
|
||||
logYears(years, eves, loaded_events.size());
|
||||
}
|
||||
else eves.push_back(loaded_events);
|
||||
|
||||
//If the correction is done by two years only, merge the two vectors into one
|
||||
if (opts.angacccorrpertwoyears){
|
||||
eves = {merge_two_evtVecs(eves.at(0),eves.at(1))};
|
||||
spdlog::debug("Size of the final vector is {0:d}",eves.size());
|
||||
spdlog::debug("Size of the final vector at(0) is {0:d}",eves.at(0).size());
|
||||
}
|
||||
|
||||
return eves;
|
||||
|
||||
}
|
||||
|
||||
int get_flat_Q2_weights(){
|
||||
|
||||
spdlog::info("Start preparing weights for flat-flat PHSP.");
|
||||
std::string PHSPpath = getSelectedTuplePath(4,2017,2);
|
||||
|
||||
TFile *output = new TFile(CONFIG_PHSP_WEIGHT.c_str(),"RECREATE");
|
||||
output->cd();
|
||||
spdlog::debug("Created " + std::string(output->GetPath()));
|
||||
TH1D *flatq2weights = new TH1D("flatq2weights","flatq2weights",100,Q2_MIN_RANGE,Q2_MAX_RANGE);
|
||||
TH1D *originalQ2 = new TH1D("originalQ2","originalQ2",100,Q2_MIN_RANGE,Q2_MAX_RANGE);
|
||||
|
||||
|
||||
spdlog::debug("Reading tree DecayTree from " + PHSPpath);
|
||||
TChain *tree = new TChain("DecayTree");
|
||||
tree->Add(PHSPpath.c_str());
|
||||
spdlog::debug("Events in tree DecayTree:\t{0:d}", tree->GetEntries());
|
||||
|
||||
double Q2;
|
||||
tree->SetBranchStatus("Q2",1);
|
||||
tree->SetBranchAddress("Q2",&Q2);
|
||||
|
||||
for (int e = 0; e<tree->GetEntries(); e++){
|
||||
//spdlog::trace("Q2 for event {0:d}:\t{1:f}",e,Q2);
|
||||
tree->GetEntry(e);
|
||||
originalQ2->Fill(Q2/1e6); //Fill q2 in GeV instead of MeV
|
||||
}
|
||||
|
||||
|
||||
for (int b =1; b <= originalQ2->GetNbinsX(); b++){
|
||||
flatq2weights->SetBinContent(b,1.0/originalQ2->GetBinContent(b)); //Create the weights
|
||||
}
|
||||
flatq2weights->Scale(flatq2weights->GetNbinsX()/ flatq2weights->Integral()); //Normalize the weights
|
||||
output->cd();
|
||||
originalQ2->Write("",TObject::kWriteDelete);
|
||||
flatq2weights->Write("",TObject::kWriteDelete);
|
||||
output->Close();
|
||||
spdlog::info("Done preparing weights for flat-flat PHSP.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scan_max_order_angular_ccorrection(fcnc::options opts,
|
||||
bool assumePhiEven,
|
||||
bool quickTest, bool test_4times1D,
|
||||
bool checkSignificance, bool runMinuit,
|
||||
bool checkFactorization, bool do3Dmoments){
|
||||
get_flat_Q2_weights();
|
||||
//only use chi2 from 1D projections
|
||||
opts.only_4_1D_chi2 = test_4times1D;
|
||||
//prevent any plot printing for the scan
|
||||
opts.write_eps = quickTest || test_4times1D;
|
||||
//Set year/run options
|
||||
set_ang_year_options(opts);
|
||||
|
||||
//define the range to scan through the parameters:
|
||||
//format: {q2, theta_K, theta_L, phi}
|
||||
std::vector<int> scan_low = get_scan_low(quickTest, opts.only_4_1D_chi2);
|
||||
std::vector<int> scan_high = get_scan_high(quickTest, opts.only_4_1D_chi2);
|
||||
std::vector<int> scan_range = get_scan_range(scan_low, scan_high);
|
||||
|
||||
spdlog::debug("Scan range:" + convert_vector_to_string(scan_range));
|
||||
|
||||
//construct results in 2D histogram:
|
||||
const UInt_t nBinsX = scan_range.at(1)*scan_range.at(2); // cos(theta_K) and cos(theta_L)
|
||||
const UInt_t nBinsY = scan_range.at(0)*scan_range.at(3); // q^2 and phi
|
||||
|
||||
//load phase-space MC events
|
||||
std::vector<int> years = get_years(opts.run,false, false);
|
||||
std::vector< std::vector<fcnc::event> > eves = select_event(opts, years);
|
||||
|
||||
//object for exporting values from the parametrization process:
|
||||
fcnc::values valu;
|
||||
spdlog::debug("Eves vector size: {0:d}", eves.size());
|
||||
|
||||
for_indexed(auto evts: eves){
|
||||
|
||||
if(opts.angacccorrperyear ){
|
||||
opts.year = years.at(i);
|
||||
spdlog::debug("[YEAR]\t\t{0:d}", opts.year);
|
||||
}
|
||||
else opts.year = -1;
|
||||
|
||||
std::string sample_suffix;
|
||||
if (opts.angacccorrbothruns) sample_suffix = "Run1and2";
|
||||
else if(opts.angacccorrperyear)sample_suffix = std::to_string(opts.year);
|
||||
else sample_suffix = "Run"+std::to_string(opts.run);
|
||||
|
||||
TH2D * chi2histo = new TH2D(("ScanLegendreOrders_Chi2result_"+sample_suffix).c_str(),
|
||||
("#chi^{2} scan of max. order of polynoms ("+sample_suffix+");#bf{#theta_{K}} - #theta_{L};#bf{q^{2}} - #phi").c_str(),
|
||||
nBinsX, -0.5, nBinsX - 0.5,
|
||||
nBinsY, -0.5, nBinsY - 0.5);
|
||||
|
||||
TH2D * pvaluehisto = new TH2D(("ScanLegendreOrders_Pvalueresult_"+sample_suffix).c_str(),
|
||||
("p-value scan of max. order of polynoms ("+sample_suffix+");#bf{#theta_{K}} - #theta_{L};#bf{q^{2}} - #phi").c_str(),
|
||||
nBinsX, -0.5, nBinsX - 0.5,
|
||||
nBinsY, -0.5, nBinsY - 0.5);
|
||||
|
||||
|
||||
//label the axese
|
||||
labelAngularScan(scan_low, scan_range, chi2histo);
|
||||
labelAngularScan(scan_low, scan_range, pvaluehisto);
|
||||
|
||||
/*
|
||||
//individual histograms for each 1D projection:
|
||||
TH2D * dist_4_1D[4];
|
||||
std::string svar[4] = {"ctk", "ctl", "phi", "q2"};
|
||||
|
||||
if(opts.only_4_1D_chi2){
|
||||
//was only needed to proof that all four 1D projections are indipendent.
|
||||
//keep the code for possible re-checks:
|
||||
for(int h = 0; h < 4; h++){
|
||||
dist_4_1D[h] = new TH2D(("ScanLegendreOrders_Chi2result_"+svar[h]+"_"+sample_suffix).c_str(),
|
||||
(svar[h]+": #chi^{2} scan of max. order of polynoms ("+sample_suffix+");#bf{#theta_{K}} - #theta_{L};#bf{q^{2}} - #phi").c_str(),
|
||||
nBinsX, -0.5, nBinsX - 0.5,
|
||||
nBinsY, -0.5, nBinsY - 0.5);
|
||||
//label the x-axis
|
||||
labelAngularScan(scan_low, scan_range, dist_4_1D[h]);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//determine max scan range:
|
||||
int range_low = *min_element(std::begin(scan_low),std::end(scan_low));
|
||||
//for_indexed(auto item: scan_low) if(scan_low[c] < range_low)range_low = scan_low[c];
|
||||
int range_high = *max_element(std::begin(scan_high),std::end(scan_high));
|
||||
|
||||
//get the histogram for all four varialbes:
|
||||
TH2D * chi2_4_1D = new TH2D(("Scan_Chi2result_"+sample_suffix).c_str(),
|
||||
("#chi^{2} scan of max. order of polynoms ("+sample_suffix+");max. order;variable").c_str(),
|
||||
range_high - range_low + 1, range_low - 0.5, range_high + 0.5,
|
||||
4, -0.5, 3.5);
|
||||
//label the x-axis
|
||||
for(int b = range_low; b <= range_high; b++){
|
||||
chi2_4_1D->GetXaxis()->SetBinLabel(b - range_low + 1, (std::to_string(b)).c_str());
|
||||
}
|
||||
//label the y-axis
|
||||
chi2_4_1D->GetYaxis()->SetBinLabel(1, LATEX_Q2_CH());
|
||||
chi2_4_1D->GetYaxis()->SetBinLabel(2, LATEX_TK_CH());
|
||||
chi2_4_1D->GetYaxis()->SetBinLabel(3, LATEX_TL_CH());
|
||||
chi2_4_1D->GetYaxis()->SetBinLabel(4, LATEX_PHI_CH());
|
||||
|
||||
if(opts.only_4_1D_chi2){ //Screams in python
|
||||
for(int i = 0; i < 4; i++){
|
||||
for(int j = scan_low.at(i); j <= scan_high.at(i); j++){
|
||||
|
||||
//set to max order to current scan value and all others to min value
|
||||
if(i == 0)opts.eff_order_q2 = j;
|
||||
else opts.eff_order_q2 = scan_low.at(0);
|
||||
if(i == 1)opts.eff_order_costhetak = j;
|
||||
else opts.eff_order_costhetak = scan_low.at(1);
|
||||
if(i == 2)opts.eff_order_costhetal = j;
|
||||
else opts.eff_order_costhetal = scan_low.at(2);
|
||||
if(i == 3)opts.eff_order_phi = j;
|
||||
else opts.eff_order_phi = scan_low.at(3);
|
||||
|
||||
spdlog::debug("[SCAN]\t\tq2 {0:d} \tcos(t_K) {1:d} \tcos(t_L) {2:d} \tphi {3:d}", opts.eff_order_q2, opts.eff_order_costhetak, opts.eff_order_costhetal , opts.eff_order_phi);
|
||||
|
||||
//All Unbiased parameters!
|
||||
fcnc::bu2kstarmumu_parameters params(&opts);
|
||||
//pdf
|
||||
fcnc::bu2kstarmumu_pdf prob(&opts, ¶ms);
|
||||
|
||||
//prob.parametrize_eff_phsp(selected);
|
||||
int tagNumber = i*10+j;
|
||||
spdlog::debug("Tag number:\t{0:d}", tagNumber);
|
||||
prob.parametrize_eff_phsp_4d(evts, &valu,tagNumber, assumePhiEven, checkSignificance, runMinuit, checkFactorization, do3Dmoments);
|
||||
//Tag for all possible combinations when testing
|
||||
|
||||
//save the one chi2 value:
|
||||
double chi2 = 0.;
|
||||
if(i == 0) chi2 = valu.chi2_4_1D_q2;
|
||||
else if(i == 1)chi2 = valu.chi2_4_1D_ctk;
|
||||
else if(i == 2)chi2 = valu.chi2_4_1D_ctl;
|
||||
else chi2 = valu.chi2_4_1D_phi;
|
||||
int ndof = 1;
|
||||
if(i == 0) ndof = valu.ndof_4_1D_q2;
|
||||
else if(i == 1)ndof = valu.ndof_4_1D_ctl;
|
||||
else if(i == 2)ndof = valu.ndof_4_1D_ctl;
|
||||
else ndof = valu.ndof_4_1D_phi;
|
||||
if(chi2 / ndof < 2.) chi2_4_1D->SetBinContent(j - range_low + 1, i + 1, chi2 / ndof);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(int qq = 0; qq < scan_range.at(0); qq++){
|
||||
for(int tk = 0; tk < scan_range.at(1); tk++){
|
||||
for(int tl = 0; tl < scan_range.at(2); tl++){
|
||||
for(int fi = 0; fi < scan_range.at(3); fi++){
|
||||
|
||||
//change max order of polynoms according to the scan:
|
||||
opts.eff_order_q2 = qq+scan_low.at(0);
|
||||
opts.eff_order_costhetak = tk+scan_low.at(1);
|
||||
opts.eff_order_costhetal = tl+scan_low.at(2);
|
||||
opts.eff_order_phi = fi+scan_low.at(3);
|
||||
|
||||
int tagNumber = 1*opts.eff_order_q2+
|
||||
10*opts.eff_order_costhetak+
|
||||
100* opts.eff_order_costhetal+
|
||||
1000*opts.eff_order_phi ;
|
||||
//This works fine assuming all the orders are <10!
|
||||
|
||||
spdlog::info("[SCAN]\t\tq2 {0:d} \tcos(t_K) {1:d} \tcos(t_L) {2:d} \tphi {3:d}", opts.eff_order_q2, opts.eff_order_costhetak, opts.eff_order_costhetal , opts.eff_order_phi);
|
||||
spdlog::debug("Tag number:\t{0:d}", tagNumber);
|
||||
|
||||
//All Unbiased parameters!
|
||||
fcnc::bu2kstarmumu_parameters params(&opts);
|
||||
//pdf
|
||||
fcnc::bu2kstarmumu_pdf prob(&opts, ¶ms);
|
||||
|
||||
//prob.parametrize_eff_phsp(selected);
|
||||
prob.parametrize_eff_phsp_4d(evts, &valu, tagNumber, assumePhiEven, checkSignificance, runMinuit, checkFactorization, do3Dmoments);
|
||||
|
||||
double chi2 = valu.angacccorr_chi2;
|
||||
int ndof = valu.angacccorr_ndof;
|
||||
|
||||
chi2histo->SetBinContent(tk * scan_range.at(2) + tl + 1,
|
||||
qq * scan_range.at(3) + fi + 1, chi2 / ndof);
|
||||
|
||||
pvaluehisto->SetBinContent(tk * scan_range.at(2) + tl + 1,
|
||||
qq * scan_range.at(3) + fi + 1,
|
||||
TMath::Prob(chi2, ndof));
|
||||
//P(chi2,ndof) represents the probability that the observed Chi-squared
|
||||
//for a correct model should be less than the value chi2.
|
||||
//The returned probability corresponds to 1-P(chi2,ndof),
|
||||
//which denotes the probability that an observed Chi-squared exceeds
|
||||
//the value chi2 by chance, even for a correct model.
|
||||
}
|
||||
}
|
||||
}
|
||||
}//loop over max. orders
|
||||
}
|
||||
|
||||
//save the histogram with chi2/ndof output
|
||||
TCanvas * cChi2Ndof = new TCanvas(("cChi2Ndof_"+sample_suffix).c_str(), ("cChi2Ndof_"+sample_suffix).c_str());
|
||||
TCanvas * cPvalue = new TCanvas(("cPvalue_"+sample_suffix).c_str(), ("cPvalue_"+sample_suffix).c_str());
|
||||
|
||||
gStyle->SetPaintTextFormat("1.3f");
|
||||
std::string plotName = "plots/angular/test/ScanChi2MaxOrderPolynom" + sample_suffix+std::string(quickTest ? "_quickTest" : "");
|
||||
if(opts.only_4_1D_chi2){
|
||||
replace(plotName,"Polynom","Polynom_4_1D_");
|
||||
cChi2Ndof->cd();
|
||||
cChi2Ndof->SetLogz(false);
|
||||
chi2_4_1D->GetZaxis()->SetRangeUser(-1.0,2.5);
|
||||
chi2_4_1D->Draw("TEXTCOLZ");
|
||||
cChi2Ndof->SaveAs((plotName+".eps").c_str(), "eps");
|
||||
}
|
||||
else{
|
||||
cChi2Ndof->cd();
|
||||
chi2histo->GetZaxis()->SetRangeUser(0.98, 1.05);
|
||||
chi2histo->Draw("TEXTCOLZ");
|
||||
cChi2Ndof->SaveAs((plotName + ".eps").c_str(), "eps");
|
||||
cChi2Ndof->SetLogz();
|
||||
cChi2Ndof->SaveAs((plotName+"_log.eps").c_str(), "eps");
|
||||
|
||||
replace(plotName,"Chi2Max","PvalueMax");
|
||||
cPvalue->cd();
|
||||
//pvaluehisto->GetZaxis()->SetRangeUser(1e-8, 2.5e-2);
|
||||
pvaluehisto->Draw("TEXTCOLZ");
|
||||
|
||||
cPvalue->SaveAs((plotName+".eps").c_str(), "eps");
|
||||
cPvalue->SetLogz();
|
||||
cPvalue->SaveAs((plotName+"_log.eps").c_str(), "eps");
|
||||
|
||||
|
||||
replace(plotName,"PvalueMax","Max");
|
||||
TFile * f = new TFile((plotName+".root").c_str(), "UPDATE");
|
||||
f->cd();
|
||||
chi2histo ->Write("", TObject::kWriteDelete);
|
||||
pvaluehisto->Write("", TObject::kWriteDelete);
|
||||
f->Close();
|
||||
}
|
||||
|
||||
delete cChi2Ndof;
|
||||
delete cPvalue;
|
||||
|
||||
delete chi2histo;
|
||||
delete pvaluehisto;
|
||||
|
||||
}
|
||||
|
||||
//end program after scan
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------
|
||||
// fit angular acceptance
|
||||
//-------------------------------
|
||||
int get_angular_acceptance(fcnc::options opts, bool testSaving){
|
||||
|
||||
//Mostly useless here, but in case it is needed quickly get the correction to PHSP from genLvl MC
|
||||
//Needed to correct for flat q2
|
||||
get_flat_Q2_weights();
|
||||
|
||||
spdlog::info("[START] Determination of angular acceptance corrections");
|
||||
//Set year/run options
|
||||
set_ang_year_options(opts);
|
||||
|
||||
//load phase-space MC
|
||||
std::vector<int> years = get_years(opts.run,false, false);
|
||||
std::vector< std::vector<fcnc::event> > eves = select_event(opts, years);
|
||||
|
||||
//object for exporting values from the parametrization process:
|
||||
fcnc::values valu;
|
||||
|
||||
for(UInt_t y = 0; y < (opts.angacccorrperyear ? years.size() : 1); y++){
|
||||
|
||||
opts.year = opts.angacccorrperyear ? years.at(y) : -1;
|
||||
if(opts.angacccorrperyear) spdlog::debug("[YEAR]\t\t{0:d}",years.at(y));
|
||||
|
||||
//All Unbiased parameters!
|
||||
fcnc::bu2kstarmumu_parameters params(&opts);
|
||||
//pdf
|
||||
fcnc::bu2kstarmumu_pdf prob(&opts, ¶ms);
|
||||
|
||||
//prob.parametrize_eff_phsp(selected);
|
||||
prob.parametrize_eff_phsp_4d(eves.at(y), &valu, 0, IS_PHI_EVEN, false, false, false, false);
|
||||
|
||||
//save the coefficients to .dat file
|
||||
prob.save_coeffs_eff_phsp_4d();
|
||||
|
||||
|
||||
//Plot the corrected distributions
|
||||
sanityCheck(eves.at(y), opts, true, -1, true);
|
||||
|
||||
//test succesfull saving by loading and checking the coefficients:
|
||||
if(testSaving){
|
||||
//load the coefficients from file:
|
||||
std::vector<double>testCoeffs;
|
||||
testCoeffs = prob.read_coeffs_eff_phsp_4d();
|
||||
//check if the correct number of coeffs is saved and reloaded
|
||||
assert(testCoeffs.size() == prob.coeffs_eff_4d.size());
|
||||
|
||||
//test if all coeffs are identical
|
||||
for(UInt_t c = 0; c < prob.coeffs_eff_4d.size(); c++){
|
||||
if(TMath::Abs(testCoeffs.at(c) - prob.coeffs_eff_4d.at(c)) > 1.0e-14){
|
||||
spdlog::warn(" Coeff #{0:d} unequal.",c+1);
|
||||
spdlog::warn(" Saved: {0:f}", prob.coeffs_eff_4d.at(c));
|
||||
spdlog::warn(" Loaded: {0:f}", testCoeffs.at(c));
|
||||
spdlog::warn(" Difference: {0:f}", testCoeffs.at(c) - prob.coeffs_eff_4d.at(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
npolynom npol(&opts);
|
||||
assert(prob.coeffs_eff_4d.size() == npol.getSize());
|
||||
|
||||
//this can be varying parameter, or can be fixed for example to the middle of the bin
|
||||
//double q2 = params->eff_q2();
|
||||
TRandom3* rnd = new TRandom3(432759);
|
||||
std::vector<fcnc::event> negativeeff;
|
||||
const bool testdata = false;
|
||||
const bool testtoy = false;
|
||||
unsigned int ntest = 100000;
|
||||
if (testdata){
|
||||
std::vector<fcnc::event> dataevents = fcnc::filterResonances(fcnc::load_events( get_theFCNCpath(0, opts.run), "Events", ntest));
|
||||
ntest = 0;//dataevents.size();
|
||||
for (unsigned int l=0; l<dataevents.size(); l++){
|
||||
fcnc::event meas = dataevents.at(l);
|
||||
if ( (meas.q2 < Q2_MIN_RANGE)
|
||||
|| (meas.q2 > Q2_MAX_RANGE)
|
||||
|| (meas.m < opts.m_low || meas.m > opts.m_high) )
|
||||
continue;
|
||||
|
||||
continue;
|
||||
ntest++;
|
||||
|
||||
double eff = 0.0;
|
||||
unsigned int bin = 0;
|
||||
double costhetal = meas.costhetal;
|
||||
double costhetak = meas.costhetak;
|
||||
double phi = meas.phi;
|
||||
double q2 = meas.q2;
|
||||
for (unsigned int h = 0; h < npol.q2; h++){
|
||||
for (unsigned int i = 0; i < npol.ctl; i++){
|
||||
for (unsigned int j = 0; j < npol.ctk; j++){
|
||||
for (unsigned int k = 0; k < npol.phi; k++){
|
||||
bin = npol.get_bin_in4D(h,i,j,k);
|
||||
eff += prob.coeffs_eff_4d.at(bin)*pow(q2, h)*pow(costhetal, i)*pow(costhetak, j)*pow(phi, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (eff < 0.0){
|
||||
meas.weight = eff;
|
||||
negativeeff.push_back(meas);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (testtoy){
|
||||
for (unsigned int l=0; l<ntest; l++){
|
||||
if (l % (ntest/100) == 0) spdlog::debug("{0:d}%", l/(ntest/100));
|
||||
double eff = 0.0;
|
||||
unsigned int bin = 0;
|
||||
double costhetal = CTL_MIN + rnd->Rndm()*CTL_RANGE();
|
||||
double costhetak = CTK_MIN + rnd->Rndm()*CTK_RANGE();
|
||||
double phi = PHI_MIN + rnd->Rndm()*PHI_RANGE();
|
||||
double q2 = Q2_MIN_RANGE + rnd->Rndm()*Q2_RANGE_FULL();
|
||||
for (unsigned int h = 0; h < npol.q2; h++){
|
||||
for (unsigned int i = 0; i < npol.ctl; i++){
|
||||
for (unsigned int j = 0; j < npol.ctk; j++){
|
||||
for (unsigned int k = 0; k < npol.phi; k++){
|
||||
bin = npol.get_bin_in4D(h,i,j,k);
|
||||
eff += prob.coeffs_eff_4d.at(bin)*pow(q2, h)*pow(costhetal, i)*pow(costhetak, j)*pow(phi, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (eff < 0.0){
|
||||
fcnc::event meas;
|
||||
meas.costhetal = costhetal;
|
||||
meas.costhetak = costhetak;
|
||||
meas.phi = phi;
|
||||
meas.q2 = q2;
|
||||
meas.weight = eff;
|
||||
negativeeff.push_back(meas);
|
||||
}
|
||||
else if (eff > 3.0) spdlog::debug("LARGE {0:f} {1:f} {2:f} {3:f} {4:f}", costhetal, costhetak, phi, q2, eff);
|
||||
}
|
||||
}
|
||||
if(testtoy || testdata){
|
||||
spdlog::info( "looping over {0:d} events"+ std::string(testtoy ? " (TOYS)" : " (DATA)"),ntest);
|
||||
for (unsigned int i=0; i<negativeeff.size();i++){
|
||||
const fcnc::event& meas = negativeeff.at(i);
|
||||
spdlog::debug( "{0:f} {1:f} {2:f} {3:f} {4:f} {5:f}", meas.costhetal, meas.costhetak, meas.phi, meas.q2, meas.m, meas.weight);
|
||||
}
|
||||
spdlog::debug( "negative fraction {0:f}", double(negativeeff.size())/ntest);
|
||||
}
|
||||
|
||||
if(opts.only_4_1D_chi2){
|
||||
spdlog::debug( "Results from >>>> " + std::string(opts.year == -1 ? (opts.angacccorrbothruns ? "Run1+2" : "Run"+std::to_string(opts.run)) : std::to_string(opts.year)) + " <<<< data set:");
|
||||
spdlog::debug( "Reduced chi2 of 4*1D projections:\t {0:f} ({1:f}/{2:f})",
|
||||
valu.chi2_4_1D/ valu.ndof_4_1D, valu.chi2_4_1D,valu.ndof_4_1D);
|
||||
spdlog::debug( "Reduced chi2 of 4*1D projections: ctk \t {0:f} ({1:f}/{2:f})",
|
||||
valu.chi2_4_1D_ctk/valu.ndof_4_1D_ctk, valu.chi2_4_1D_ctk, valu.ndof_4_1D_ctk);
|
||||
spdlog::debug( "Reduced chi2 of 4*1D projections: ctl\t {0:f} ({1:f}/{2:f})",
|
||||
valu.chi2_4_1D_ctl/valu.ndof_4_1D_ctl, valu.chi2_4_1D_ctl, valu.ndof_4_1D_ctl);
|
||||
spdlog::debug( "Reduced chi2 of 4*1D projections: phi\t {0:f} ({1:f}/{2:f})",
|
||||
valu.chi2_4_1D_phi/valu.ndof_4_1D_phi, valu.chi2_4_1D_phi, valu.ndof_4_1D_phi);
|
||||
spdlog::debug( "Reduced chi2 of 4*1D projections: q2\t {0:f} ({1:f}/{2:f})",
|
||||
valu.chi2_4_1D_q2/valu.ndof_4_1D_q2, valu.chi2_4_1D_q2, valu.ndof_4_1D_q2 );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------
|
||||
// fit angular resolution
|
||||
//-------------------------------
|
||||
int get_angular_resolution(fcnc::options opts, std::vector<int> years){
|
||||
//Don't forget to set the full ctk range when doing this!
|
||||
|
||||
//create resolution histograms for all three angles (x - x_true)
|
||||
const unsigned int leBins = 50;
|
||||
const double leRange = 0.12;
|
||||
|
||||
|
||||
spdlog::info("Determine angular resolutions from signal MC true information!");
|
||||
gROOT->SetBatch(kTRUE);
|
||||
gROOT->SetStyle("Plain");
|
||||
set_gStyle();
|
||||
|
||||
assert(years.size());
|
||||
opts.reject_identical_muon_TRUEID = true;
|
||||
fcnc::bu2kstarmumu_loader loader(&opts);
|
||||
|
||||
double resolution[3][years.size()];
|
||||
|
||||
for_indexed(auto yr: years){
|
||||
spdlog::info("Evaluate year {0:d}", yr);
|
||||
//load tuples:
|
||||
std::vector<fcnc::event> MCevents = loader.read_full_tuple(yr,
|
||||
getSelectedTuplePath(1, get_yearFromRun(yr),
|
||||
yr),
|
||||
get_inputTree_name(1),
|
||||
true, false, false, -1);
|
||||
|
||||
std::vector<fcnc::event> MCtrue = loader.read_full_tuple(yr,
|
||||
getSelectedTuplePath(1, get_yearFromRun(yr),
|
||||
yr),
|
||||
get_inputTree_name(1),
|
||||
true, true, false, -1);
|
||||
|
||||
assert(MCevents.size() == MCtrue.size());
|
||||
|
||||
//create resolution histograms for all three angles (x - x_true)
|
||||
|
||||
TCanvas * cReso = nullptr;
|
||||
std::string sangle[3] = {"ctk", "ctl", "phi"};
|
||||
std::string latexangle[3] = {LATEX_CTK,LATEX_CTL,LATEX_PHI};
|
||||
|
||||
TH1D * h[3];
|
||||
for(unsigned int i = 0; i < 3; i++){
|
||||
h[i] = new TH1D(("h"+sangle[i]+"_"+std::to_string(yr)).c_str(),
|
||||
(";"+latexangle[i]+" - "+latexangle[i]+"_{true};Events").c_str(),
|
||||
leBins, -leRange, +leRange);
|
||||
}
|
||||
|
||||
//fill histograms:
|
||||
for(unsigned int e = 0; e < MCevents.size(); e++){
|
||||
fcnc::event measMC = MCevents.at(e);
|
||||
fcnc::event measTRUE = MCtrue.at(e);
|
||||
|
||||
h[0]->Fill(measMC.costhetak - measTRUE.costhetak);
|
||||
h[1]->Fill(measMC.costhetal - measTRUE.costhetal);
|
||||
h[2]->Fill(measMC.phi - measTRUE.phi);
|
||||
}
|
||||
|
||||
spdlog::info("Entries in histograms: {0:f}", h[0]->Integral());
|
||||
|
||||
TF1 * fGauss = new TF1("theGaussian", "[0]*([2]*exp(-0.5*((x-[1])/[3])**2)+(1.-[2])*exp(-0.5*((x-[1])/[4])**2))", -leRange, +leRange);
|
||||
|
||||
fGauss->SetLineStyle(kDashed);
|
||||
fGauss->SetLineColor(kMagenta - 3);
|
||||
|
||||
//Set init parameters differently for each variable
|
||||
double initSigma[3] = {0.0125, 0.005, 0.025};
|
||||
double sigmaLowRange[3] = {0.008, 0.001, 0.01};
|
||||
double sigmaHighRange[3] = {0.020, 0.01, 0.04};
|
||||
for(int j = 0; j < 3; j++){
|
||||
fGauss->SetParameter(0, MCevents.size());
|
||||
fGauss->SetParameter(1, 0.);
|
||||
fGauss->SetParameter(2, 0.5);
|
||||
fGauss->SetParLimits(2, 0.0, 1.0);
|
||||
//Set the init resolution extra for ctl, as it is very narrow compared to phi and ctk
|
||||
|
||||
fGauss->SetParameter(3, initSigma[j]);
|
||||
fGauss->SetParLimits(3, sigmaLowRange[j], sigmaHighRange[j]);
|
||||
fGauss->SetParameter(4, initSigma[j]);
|
||||
fGauss->SetParLimits(4, sigmaLowRange[j], sigmaHighRange[j]);
|
||||
TFitResultPtr fr;
|
||||
do{
|
||||
h[j]->GetListOfFunctions()->Clear();
|
||||
fr = h[j]->Fit(fGauss, "MS+Q");
|
||||
spdlog::info("Fit status = {0:d}", fr->Status());
|
||||
} while (!fr->IsValid());
|
||||
TMatrixD covmat = fr->GetCovarianceMatrix();
|
||||
if (spdlog::default_logger_raw()->level()==spdlog::level::trace) covmat.Print();
|
||||
|
||||
double rel_frac = fGauss->GetParameter(2);
|
||||
double drel_frac = fGauss->GetParError(2);
|
||||
double sigma1 = fGauss->GetParameter(3);
|
||||
double dsigma1 = fGauss->GetParError(3);
|
||||
double sigma2 = fGauss->GetParameter(4);
|
||||
double dsigma2 = fGauss->GetParError(4);
|
||||
|
||||
double eff_sigma = sqrt(rel_frac*sigma1*sigma1 + (1.-rel_frac)*sigma2*sigma2);
|
||||
double deff_sigma = 1./(2.*eff_sigma) * sqrt(
|
||||
TMath::Power(2*rel_frac*sigma1*dsigma1, 2)
|
||||
+ TMath::Power(2*(1.-rel_frac)*sigma2*dsigma2, 2)
|
||||
+ TMath::Power((sigma1*sigma1-sigma2*sigma2)*drel_frac, 2)
|
||||
+ 2 * 2*rel_frac*sigma1 * 2*(1.-rel_frac)*sigma2 * covmat[3][4]
|
||||
+ 2 * 2*rel_frac*sigma1 * (sigma1*sigma1-sigma2*sigma2) * covmat[3][2]
|
||||
+ 2 * 2*(1.-rel_frac)*sigma2 * (sigma1*sigma1-sigma2*sigma2) * covmat[4][2]);
|
||||
|
||||
cReso = new TCanvas((sangle[j]+"_reso_"+std::to_string(yr)).c_str(),
|
||||
(sangle[j]+"_reso_"+std::to_string(yr)).c_str(), 1600, 1200);
|
||||
TLatex * leg = getPrettyTex(0.06, 13);
|
||||
|
||||
std::ostringstream sRMS;
|
||||
sRMS << std::fixed << std::setprecision(4) << "#sigma = " << eff_sigma << " #pm " << deff_sigma;
|
||||
resolution[j][i] = eff_sigma;
|
||||
|
||||
cReso->SetMargin(0.125,0.05,0.115,0.05);
|
||||
cReso->cd();
|
||||
h[j]->GetYaxis()->SetTitleOffset(1.15);
|
||||
h[j]->GetYaxis()->SetTitleSize(0.05);
|
||||
h[j]->GetYaxis()->SetLabelSize(0.05);
|
||||
h[j]->GetXaxis()->SetTitleSize(0.05);
|
||||
h[j]->GetXaxis()->SetLabelSize(0.05);
|
||||
h[j]->Draw("E1");
|
||||
leg->DrawLatex(0.15,0.84, sRMS.str().c_str());
|
||||
leg->DrawLatex(0.7,0.88, "LHCb MC");
|
||||
leg->DrawLatex(0.7,0.82, std::to_string(yr).c_str());
|
||||
|
||||
cReso->Print(get_angResoPlot_path(sangle[j],yr,"eps").c_str(), "eps");
|
||||
cReso->SaveAs(get_angResoPlot_path(sangle[j],yr,"root").c_str());
|
||||
|
||||
delete h[j];
|
||||
}
|
||||
}
|
||||
|
||||
//print out resolutions:
|
||||
spdlog::info("resolution: {");
|
||||
for(int i = 0; i < 3; i++){
|
||||
std::cout << "{";
|
||||
for(UInt_t y = 0; y < years.size(); y++){
|
||||
std::cout << std::fixed << std::setprecision(6) << resolution[i][y];
|
||||
if(y < years.size() - 1)
|
||||
std::cout << ", ";
|
||||
}
|
||||
std::cout << "}" << std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
21
Code/FCNCFitter/sources/Run/angularcorr.hh
Normal file
21
Code/FCNCFitter/sources/Run/angularcorr.hh
Normal file
@ -0,0 +1,21 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef ANGULARCORR_HH
|
||||
#define ANGULARCORR_HH
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace fcnc { //Forward declarations
|
||||
class event;
|
||||
class options;
|
||||
}
|
||||
|
||||
int scan_max_order_angular_ccorrection(fcnc::options opts, bool assumePhiEven, bool quickTest, bool test_4times1D, bool checkSignificance, bool runMinuit, bool checkFactorization, bool do3Dmoments);
|
||||
|
||||
int sanityCheck_MC(fcnc::options opts);
|
||||
int sanityCheck(std::vector<fcnc::event>events, fcnc::options opts, bool PHSP, int bin, bool norm);
|
||||
int get_angular_acceptance(fcnc::options opts, bool testSaving);
|
||||
|
||||
int get_angular_resolution(fcnc::options opts, std::vector<int> years);
|
||||
|
||||
#endif // ANGULARCORR_HH
|
421
Code/FCNCFitter/sources/Run/backgroundfit.cc
Normal file
421
Code/FCNCFitter/sources/Run/backgroundfit.cc
Normal file
@ -0,0 +1,421 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <backgroundfit.hh>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream> // std::istringstream
|
||||
|
||||
#include <bu2kstarmumu_parameters.hh>
|
||||
#include <bu2kstarmumu_plotter.hh>
|
||||
#include <bu2kstarmumu_pdf.hh>
|
||||
#include <folder.hh>
|
||||
#include <fitter.hh>
|
||||
#include <paths.hh>
|
||||
#include <design.hh>
|
||||
#include <helpers.hh>
|
||||
#include <event.hh>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
#include <TStyle.h>
|
||||
#include <TH2D.h>
|
||||
#include <TLatex.h>
|
||||
#include <TCanvas.h>
|
||||
#include <TROOT.h>
|
||||
|
||||
//Do the actuall background fit
|
||||
int backgroundfit(fcnc::options opts,
|
||||
bool fitReference, bool LowMassFit, bool HighMassFit, bool fitKpi,
|
||||
bool Use2DAngularBins, basic_params params){
|
||||
//params now only used to tag nBins in the names
|
||||
|
||||
//Technically, this should be simFit between Run 1 and 2, but since we need it only for the toys atm, no need for it
|
||||
|
||||
gROOT->SetBatch(kTRUE);
|
||||
gROOT->SetStyle("Plain");
|
||||
set_gStyle();
|
||||
|
||||
//Open texFile
|
||||
std::ofstream myFile;
|
||||
open_Latex_noteFile(latex_bkgFit(), myFile);
|
||||
|
||||
spdlog::info("[FIT]\t\tFit only angular and m(Kpi) background");
|
||||
|
||||
|
||||
//Used to check whether the background is "correlated" between each other
|
||||
//TODO: not needed atm, maybe fix later
|
||||
/* 1D angular bins
|
||||
1: ctl < -0.5
|
||||
2: -0.5 < ctl < 0.0
|
||||
3: 0.0 < ctl < 0.5
|
||||
4: 0.5 < ctl
|
||||
5: ctk < -0.5
|
||||
6: -0.5 < ctk < 0.0
|
||||
7: 0.0 < ctk < 0.5
|
||||
8: 0.5 < ctk
|
||||
*/
|
||||
/* 2D angular bins
|
||||
1: ctl < 0.0 && ctk < 0.0
|
||||
2: ctl < 0.0 && ctk > 0.0
|
||||
3: ctl > 0.0 && ctk < 0.0
|
||||
4: ctl > 0.0 && ctk > 0.0
|
||||
*/
|
||||
|
||||
double HighBpeakCut = fitReference ? B_MASS_HIGH_BKG_REF : B_MASS_HIGH_BKG;
|
||||
double LowBpeakCut = fitReference ? B_MASS_LOW_BKG_REF : B_MASS_LOW_BKG;
|
||||
|
||||
assert(!(HighMassFit && LowMassFit));
|
||||
|
||||
opts.fit_full_angular_bkg = true;
|
||||
|
||||
opts.only_angles = !(HighMassFit || LowMassFit); //Fit mass only if one sideband is selected
|
||||
opts.only_Bmass = false;
|
||||
opts.only_mkpi = false;
|
||||
|
||||
opts.swave = false;
|
||||
|
||||
opts.bkg_order_costhetak = 5;
|
||||
opts.shift_lh = false; //keep it, it was there before
|
||||
opts.weighted_fit = true;
|
||||
opts.squared_hesse = true;
|
||||
opts.minos_errors = false;
|
||||
opts.asymptotic = false;
|
||||
|
||||
opts.flat_bkg = false;
|
||||
|
||||
opts.fit_mkpi = false; //set to true only later
|
||||
opts.use_mkpi = false;
|
||||
opts.simple_mkpi = false; //S-wave model
|
||||
opts.isobar = false; //S-wave model
|
||||
|
||||
//Plotting options
|
||||
opts.plot_chi2 = false;
|
||||
opts.plots_m_bins = 20;
|
||||
opts.plots_mkpi_bins = 20;
|
||||
|
||||
//load events from data tuple
|
||||
std::vector<std::vector<fcnc::event>>events;
|
||||
std::vector<int> run_idx;
|
||||
|
||||
if (opts.run == 1 || opts.run == 12){
|
||||
std::vector<fcnc::event> tmp = fcnc::load_events(get_theFCNCpath(0,1), "Events", -1);
|
||||
if (!fitReference) events.push_back(fcnc::filterResonances(tmp));
|
||||
else events.push_back(tmp);
|
||||
run_idx.push_back(1);
|
||||
}
|
||||
if (opts.run == 2 || opts.run == 12){
|
||||
std::vector<fcnc::event> tmp = fcnc::load_events(get_theFCNCpath(0,2), "Events", -1);
|
||||
if (!fitReference) events.push_back(fcnc::filterResonances(tmp));
|
||||
else events.push_back(tmp);
|
||||
run_idx.push_back(2);
|
||||
}
|
||||
|
||||
std::vector<int> fitresults;
|
||||
|
||||
//determine number of bins:
|
||||
const UInt_t nBins = opts.TheQ2binsmin.size();
|
||||
|
||||
//current fitter, plotter, parameteres and pdfs:
|
||||
fcnc::fitter f(&opts);
|
||||
fcnc::folder fldr(&opts);
|
||||
fcnc::bu2kstarmumu_plotter thePlotter(&opts);
|
||||
|
||||
fcnc::bu2kstarmumu_parameters * theParams[nBins];
|
||||
fcnc::bu2kstarmumu_pdf * theProb[nBins];
|
||||
std::vector<fcnc::event> * theEvents[nBins];
|
||||
|
||||
|
||||
for(UInt_t b = 0; b < nBins; b++){
|
||||
|
||||
theParams[b] = new fcnc::bu2kstarmumu_parameters(&opts);
|
||||
theProb[b] = new fcnc::bu2kstarmumu_pdf(&opts, theParams[b]);
|
||||
theEvents[b] = new std::vector<fcnc::event>();
|
||||
|
||||
//Init parameters
|
||||
theParams[b]->f_sig.init_fixed(0.0);
|
||||
theParams[b]->m_b.init(PDGMASS_B, HighMassFit ? HighBpeakCut : B_MASS_LOW, LowMassFit ? LowBpeakCut : B_MASS_HIGH, 0.0);
|
||||
//The rest of the mass parameters can be left to default values
|
||||
//They are defined in bu2kstamumu_parameters
|
||||
|
||||
//Init the bkg shape
|
||||
theParams[b]->init_angular_background_parameters(fitReference,0.1);
|
||||
|
||||
//Init the mass bkg shape
|
||||
theParams[b]->init_mass_background_parameters(nBins,b,true);
|
||||
//theParams[b]->cbkgctk3.init_fixed(-2.5);
|
||||
|
||||
//Select events
|
||||
for_indexed(auto evts: events){
|
||||
//update weights according to sub-set for all events
|
||||
opts.run = run_idx.at(i);
|
||||
opts.update_efficiencies = true;
|
||||
|
||||
theProb[b]->load_coeffs_eff_phsp_4d();
|
||||
theProb[b]->update_cached_normalization(theParams[b]);
|
||||
theProb[b]->update_cached_efficiencies(theParams[b], &evts);
|
||||
opts.update_angle_ranges(); //Update angles to get rid of events that cannot be folded
|
||||
//select events
|
||||
spdlog::debug("Loop over {0:d} events and select the suitable ones", evts.size());
|
||||
for(auto meas: evts){
|
||||
|
||||
if(meas.q2 < opts.TheQ2binsmin.at(b) || meas.q2 > opts.TheQ2binsmax.at(b)) continue;
|
||||
if(meas.m < opts.m_low || meas.m > opts.m_high) continue;
|
||||
|
||||
if(LowMassFit && meas.m > LowBpeakCut) continue;
|
||||
else if(HighMassFit && meas.m < HighBpeakCut) continue;
|
||||
else if(meas.m > LowBpeakCut && meas.m < HighBpeakCut) continue;
|
||||
|
||||
if(meas.mkpi < opts.mkpi_min || meas.mkpi > opts.mkpi_max) continue;
|
||||
|
||||
if(params.bin > 1){
|
||||
bool keep_event = true;
|
||||
if(Use2DAngularBins){
|
||||
switch(params.bin){
|
||||
case 2:
|
||||
if(meas.costhetal > 0.0 || meas.costhetak > 0.0) keep_event = false;
|
||||
break;
|
||||
case 3:
|
||||
if(meas.costhetal > 0.0 || meas.costhetak < 0.0) keep_event = false;
|
||||
break;
|
||||
case 4:
|
||||
if(meas.costhetal < 0.0 || meas.costhetak > 0.0) keep_event = false;
|
||||
break;
|
||||
case 5:
|
||||
if(meas.costhetal < 0.0 || meas.costhetak < 0.0) keep_event = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else{ //1D angular bins
|
||||
switch(params.bin){
|
||||
case 2:
|
||||
if(meas.costhetal > -0.5) keep_event = false;
|
||||
break;
|
||||
case 3:
|
||||
if(meas.costhetal < -0.5 || meas.costhetal > 0.0) keep_event = false;;
|
||||
break;
|
||||
case 4:
|
||||
if(meas.costhetal < 0.0 || meas.costhetal > 0.5) keep_event = false;;
|
||||
break;
|
||||
case 5:
|
||||
if(meas.costhetal > 0.5) keep_event = false;;
|
||||
break;
|
||||
case 6:
|
||||
if(meas.costhetak > -0.5) keep_event = false;;
|
||||
break;
|
||||
case 7:
|
||||
if(meas.costhetak < -0.5 || meas.costhetak > 0.0) keep_event = false;;
|
||||
break;
|
||||
case 8:
|
||||
if(meas.costhetak < 0.0 || meas.costhetak > 0.5) keep_event = false;;
|
||||
break;
|
||||
case 9:
|
||||
if(meas.costhetak > 0.5) keep_event = false;;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!keep_event) continue;
|
||||
}
|
||||
|
||||
if(!filterFldFour(&meas, &opts)) continue;
|
||||
fldr.fold(&meas);
|
||||
|
||||
//only one combined event vector
|
||||
theEvents[b]->push_back(meas);
|
||||
}
|
||||
spdlog::debug("Selected {0:d} events.", theEvents[b]->size());
|
||||
}
|
||||
spdlog::info("[BIN {0:d}]\tDone!",b);
|
||||
}//end loop over bins
|
||||
|
||||
//do not update cached efficiencies anyomre, to keep individual ones for four sub-sets
|
||||
opts.update_efficiencies = false;
|
||||
|
||||
//create 2D correlation plots for all angles (3) and all bins (8): 3! * 8 = 24
|
||||
const unsigned int nANGLES = 3;
|
||||
|
||||
double hmin[nANGLES] = {CTL_MIN, CTK_MIN, PHI_MIN};
|
||||
double hmax[nANGLES] = {CTL_MAX, CTK_MAX, PHI_MAX};
|
||||
double corrfactor[nBins][nANGLES][nANGLES];
|
||||
const int nCorrBins = 10;
|
||||
for(UInt_t b = 0; b < nBins; b++){
|
||||
spdlog::info("[START]\tStart the background 2D correlation plotting for bin #{0:d}", b);
|
||||
for(UInt_t a = 0; a < nANGLES - 1; a++){
|
||||
for(UInt_t aa = a + 1; aa < nANGLES; aa++){
|
||||
std::string mainName = "bckgnd_correl_"+ANGLES[a]+"_"+ANGLES[aa]+"_q2bin"+std::to_string(b);
|
||||
TCanvas * cAngCorr = new TCanvas(("c"+mainName).c_str(),
|
||||
("c"+mainName).c_str(), 1400, 1200);
|
||||
cAngCorr->cd()->SetMargin(0.1,0.125,0.125,0.125);
|
||||
cAngCorr->cd();
|
||||
TH2D * h = new TH2D((mainName).c_str(),
|
||||
(mainName+";"+latex_angles[a]+";"+latex_angles[aa]).c_str(),
|
||||
nCorrBins, hmin[a], hmax[a], nCorrBins, hmin[aa], hmax[aa]);
|
||||
|
||||
for(UInt_t e = 0; e < theEvents[b]->size(); e++){
|
||||
fcnc::event meas = theEvents[b]->at(e);
|
||||
double x=0.0, y=0.0;
|
||||
switch(a){ //TODO: make a function in helpers
|
||||
case 0:
|
||||
x = meas.costhetal;
|
||||
break;
|
||||
case 1:
|
||||
x = meas.costhetak;
|
||||
break;
|
||||
}
|
||||
switch(aa){
|
||||
case 1:
|
||||
y = meas.costhetak;
|
||||
break;
|
||||
case 2:
|
||||
y = meas.phi;
|
||||
break;
|
||||
}
|
||||
h->Fill(x, y);
|
||||
}
|
||||
h->GetZaxis()->SetRangeUser(0, fitReference ? 25 : 5);
|
||||
h->GetZaxis()->SetTitle("Number of entries");
|
||||
|
||||
h->GetXaxis()->SetTitleSize(0.05);
|
||||
h->GetXaxis()->SetLabelSize(0.05);
|
||||
h->GetXaxis()->SetTitleOffset(0.95);
|
||||
|
||||
h->GetYaxis()->SetTitleSize(0.05);
|
||||
h->GetYaxis()->SetLabelSize(0.05);
|
||||
h->GetYaxis()->SetTitleOffset(0.75);
|
||||
|
||||
h->GetZaxis()->SetTitleSize(0.05);
|
||||
h->GetZaxis()->SetLabelSize(0.05);
|
||||
h->GetZaxis()->SetTitleOffset(0.75);
|
||||
|
||||
h->SetTitle("");
|
||||
h->Draw("COLZ");
|
||||
|
||||
corrfactor[b][a][aa] = h->GetCorrelationFactor();
|
||||
|
||||
TLatex * leg = getPrettyTex(0.06,13);
|
||||
leg->SetTextColor(kBlack);
|
||||
std::ostringstream sCorrout; //TODO: move the path
|
||||
sCorrout << std::fixed << std::setprecision(2) << "corr(" << latex_angles[a] << ", " << latex_angles[aa] <<") = " << corrfactor[b][a][aa]*100. << "\%";
|
||||
leg->DrawLatex(0.22,0.98, sCorrout.str().c_str());
|
||||
leg->SetTextSize(0.04);
|
||||
leg->DrawLatex(0.25,0.92, ("Events: "+std::to_string((int) h->GetEntries())).c_str());
|
||||
cAngCorr->Print(get_bkgCorrPlot_path(ANGLES[a],ANGLES[aa],b,nBins,fitReference, LowMassFit, HighMassFit, fitKpi, params).c_str(), "eps");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Save the correlations s
|
||||
myFile << "\\begin{tabular}{r|ccc}\\hline" << std::endl;
|
||||
myFile << std::fixed << std::setprecision(2) << "[" << opts.TheQ2binsmin.at(b) << ", " << opts.TheQ2binsmax.at(b) << "]";
|
||||
for(UInt_t a = 0; a < nANGLES; a++) myFile << "\t&" << latex_2angles[a];
|
||||
myFile << "\\\\" << std::endl;
|
||||
myFile << "\\hline\\hline" << std::endl;
|
||||
for(UInt_t a = 0; a < nANGLES; a++){
|
||||
myFile << latex_2angles[a];
|
||||
for(UInt_t aa = 0; aa < nANGLES; aa++){
|
||||
myFile << "\t&";
|
||||
if(aa > a) myFile << std::setprecision(3) << std::fixed << corrfactor[b][a][aa];
|
||||
else if(aa == a) myFile << "1.00";
|
||||
else if(aa < a) myFile << " ";
|
||||
}
|
||||
myFile << "\\\\" << std::endl;
|
||||
}
|
||||
myFile << "\\hline" << std::endl;
|
||||
myFile << "\\end{tabular}"<< std::endl;
|
||||
myFile << std::endl;
|
||||
|
||||
}
|
||||
|
||||
//FIT ANGULAR BACKGROUND + B mass
|
||||
opts.update_angle_ranges(); //Just in case
|
||||
//fit all bins:
|
||||
for(UInt_t b = 0; b < nBins; b++){
|
||||
|
||||
spdlog::info("[START]\tStart the fit for bin #{0:d}", b);
|
||||
|
||||
//fit the events:
|
||||
int fitresult = f.fit(theProb[b], theParams[b], theEvents[b]);
|
||||
fitresults.push_back(fitresult);
|
||||
|
||||
spdlog::info("[BIN{0:d}]:\tFitresult: {1:d}", b, fitresult);
|
||||
|
||||
//plot pdf with the data points:
|
||||
opts.plot_label = "LHCb data";
|
||||
opts.q2_label = q2_label(opts.TheQ2binsmin.at(b), opts.TheQ2binsmax.at(b));
|
||||
|
||||
if(opts.write_eps){
|
||||
std::string label = get_bkg_tag(b,nBins,fitReference, LowMassFit, HighMassFit, false, params);
|
||||
spdlog::info("[PLOT]\t" + label);
|
||||
thePlotter.plot_data(theProb[b], theParams[b], theEvents[b], get_bkgFitPlot_path(), label, false);
|
||||
}
|
||||
//print all parameters
|
||||
std::string fitResultTxt = get_bkgFitResult_path()+ "fitresult_" + get_bkg_tag(b,nBins,fitReference, LowMassFit, HighMassFit, false, params);
|
||||
spdlog::debug("Saving into "+fitResultTxt);
|
||||
print_all_parameters(nBins, theParams, 2, fitResultTxt);
|
||||
}
|
||||
|
||||
//print all fitresults
|
||||
print_fit_results(nBins, fitresults);
|
||||
|
||||
//Save results to root file
|
||||
std::string results_file = final_result_name_bkg(nBins, fitReference, LowMassFit, HighMassFit, false, params);
|
||||
save_results(results_file, nBins, params.Run, fitresults, theParams, &opts);
|
||||
|
||||
//FIT M(KPI) BACKGROUND
|
||||
if (!fitKpi){ //first check if you really want to fit M(KPI) :)
|
||||
//Close Latex file
|
||||
myFile.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Reset the options
|
||||
opts.only_angles = false;
|
||||
opts.only_mkpi = true;
|
||||
opts.fit_mkpi = true;
|
||||
|
||||
|
||||
//fit all bins:
|
||||
spdlog::info("[BKGFIT]\tFit the Kpi mass");
|
||||
for(UInt_t b = 0; b < nBins; b++){
|
||||
|
||||
theParams[b]->use_default_bkg();
|
||||
//null the lambda(s) and taus
|
||||
theParams[b]->m_lambda.init_fixed(0.0);
|
||||
theParams[b]->m_lambda_2.init_fixed(0.0);
|
||||
theParams[b]->m_tau.init_fixed(0.0);
|
||||
theParams[b]->m_tau_2.init_fixed(0.0);
|
||||
//Init the floating parameters
|
||||
theParams[b]->init_kpi_background_parameters(fitReference,0.01);
|
||||
|
||||
spdlog::info("[START]\tStart the fit for bin #{0:d}", b);
|
||||
|
||||
//fit the events:
|
||||
fitresults.push_back(f.fit(theProb[b], theParams[b], theEvents[b]));
|
||||
spdlog::info("[BIN{0:d} ]:\tFitresult: {1:d}",b, fitresults.at(b));
|
||||
|
||||
//plot pdf with the data points:
|
||||
opts.q2_label = q2_label(opts.TheQ2binsmin.at(b), opts.TheQ2binsmax.at(b));
|
||||
|
||||
if(opts.write_eps){
|
||||
std::string label = get_bkg_tag(b,nBins,fitReference, LowMassFit, HighMassFit, false, params);
|
||||
spdlog::info("[PLOT]\t" + label);
|
||||
thePlotter.plot_data(theProb[b], theParams[b], theEvents[b], get_bkgFitPlot_path(), label, false);
|
||||
}
|
||||
//Print all parameters, but don't save
|
||||
print_all_parameters(nBins, theParams, 2, "");
|
||||
|
||||
//print all parameters to txt file
|
||||
std::string fitResultTxt = get_bkgFitResult_path()+ "fitresult_" + get_bkg_tag(b,nBins,fitReference, LowMassFit, HighMassFit, true, params);
|
||||
spdlog::debug("Saving into "+fitResultTxt);
|
||||
print_all_parameters(nBins, theParams, 2, fitResultTxt);
|
||||
}
|
||||
spdlog::info("[BKGFIT]\tDone with Kpi fit.");
|
||||
//Save results to root file
|
||||
results_file = final_result_name_bkg(nBins, fitReference, LowMassFit, HighMassFit, true, params);
|
||||
save_results(results_file, nBins, params.Run, fitresults, theParams, &opts);
|
||||
|
||||
//Close Latex file
|
||||
myFile.close();
|
||||
|
||||
spdlog::info("[BKGFIT]\tFinished.");
|
||||
return 0;
|
||||
}
|
13
Code/FCNCFitter/sources/Run/backgroundfit.hh
Normal file
13
Code/FCNCFitter/sources/Run/backgroundfit.hh
Normal file
@ -0,0 +1,13 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef BACKGROUNDFIT_HH
|
||||
#define BACKGROUNDFIT_HH
|
||||
|
||||
#include <options.hh>
|
||||
#include <parse.hh>
|
||||
|
||||
int backgroundfit(fcnc::options opts,
|
||||
bool fitReference, bool LowMassFit, bool HighMassFit,bool fitKpi,
|
||||
bool Use2DAngularBins, basic_params params);
|
||||
|
||||
#endif // BACKGROUNDFIT_HH
|
629
Code/FCNCFitter/sources/Run/feldman_cousins.cc
Normal file
629
Code/FCNCFitter/sources/Run/feldman_cousins.cc
Normal file
@ -0,0 +1,629 @@
|
||||
/**
|
||||
* @file feldman_cousins.hh
|
||||
* @author Christoph Langenbruch, David Gerick, Renata Kopecna
|
||||
* @date 2021-01-12
|
||||
*
|
||||
*/
|
||||
|
||||
#include <feldman_cousins.hh>
|
||||
|
||||
//TODO: removed what all is unused
|
||||
#include <iostream>
|
||||
#include <complex>
|
||||
#include <assert.h>
|
||||
|
||||
#include <event.hh>
|
||||
#include <parameters.hh>
|
||||
#include <funcs.hh>
|
||||
#include <pdf.hh>
|
||||
#include <plotter.hh>
|
||||
#include <options.hh>
|
||||
#include <bu2kstarmumu_generator.hh>
|
||||
#include <fitter.hh>
|
||||
#include "folder.hh"
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
#include <TMinuit.h>
|
||||
#include <TFile.h>
|
||||
#include <TTree.h>
|
||||
#include <TRandom3.h>
|
||||
#include <TMatrix.h>
|
||||
#include <TH1D.h>
|
||||
#include <TCanvas.h>
|
||||
#include <TROOT.h>
|
||||
#include <TStyle.h>
|
||||
#include <TVector.h>
|
||||
#include <TMatrixD.h>
|
||||
#include <TMatrixDSym.h>
|
||||
#include <TMatrixTSym.h>
|
||||
#include <TMatrixT.h>
|
||||
#include <TDecompChol.h>
|
||||
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
bool fcnc::feldman_cousins::fc_1d(std::string parname, unsigned int nsteps, double parmin, double parmax, unsigned int ntoys, unsigned int pdfidx,
|
||||
std::vector<pdf*> probs, std::vector<parameters*> params, generator* gen, fitter* f,
|
||||
std::vector<std::vector<event> *> events, unsigned int bin, int from, int to){
|
||||
std::ostringstream sout;
|
||||
bool TwoBins = false;
|
||||
if(opts->TheQ2binsmin.size() == 8) TwoBins = false;
|
||||
else if(opts->TheQ2binsmin.size() == 2) TwoBins = true;
|
||||
else assert(opts->TheQ2binsmin.size() == 2 || opts->TheQ2binsmin.size() == 8);
|
||||
|
||||
sout << "FCresult" << (TwoBins ? "_2BINS_" : "") << bin << "_" << parname << "_" << from << "_" << to << ".root";
|
||||
struct stat buffer;
|
||||
if(stat (sout.str().c_str(), &buffer) == 0){
|
||||
spdlog::warn("[SKIP]\t\tFC job already run as root-file '" + sout.str() + "' exists, continue to next job!");
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
spdlog::info("Feldman-Cousins study for parameter="+ parname + " in q2bin={0:d}", bin);
|
||||
}
|
||||
// if(!opts->full_angular)
|
||||
// opts->always_generate_full_angular = false;
|
||||
bool cache_minos = opts->minos_errors;
|
||||
bool cache_hesse = opts->hesse_postrun;
|
||||
bool cache_sq_hesse = opts->squared_hesse;
|
||||
bool cache_shift = opts->shift_lh;
|
||||
//int cache_print = spdlog::default_logger_raw()->level();
|
||||
|
||||
const unsigned int nPDF = probs.size();
|
||||
assert(params.size() == nPDF);
|
||||
assert(events.size() == nPDF);
|
||||
assert(pdfidx < nPDF);
|
||||
|
||||
//temp save parameter set
|
||||
unsigned int nparameters = params.at(pdfidx)->nparameters();
|
||||
std::vector<std::vector<double> > smvalues (nPDF, std::vector<double> (nparameters, 0.0));
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
for (unsigned int k=0; k<nparameters; k++){
|
||||
smvalues.at(n).at(k) = params.at(n)->get_parameter(k)->get_value();
|
||||
}
|
||||
}
|
||||
|
||||
parameter* par = params.at(pdfidx)->get_parameter(parname);
|
||||
if (par != 0){
|
||||
opts->minos_errors = false;
|
||||
opts->squared_hesse = false;
|
||||
opts->hesse_postrun = false;
|
||||
opts->simplex_prerun = false;
|
||||
opts->shift_lh = false;
|
||||
|
||||
opts->minuit_strategy = 2.0;
|
||||
//fitter f(opts);
|
||||
int statusdatafloated = f->fit(probs, params, events);
|
||||
double lhdatafloated = f->likelihood();
|
||||
double valuedatafloated = par->get_value();
|
||||
spdlog::info("Data fit finished with -2logLh = {0:f}",lhdatafloated );
|
||||
std::vector<std::vector<double> > floatingvalues(nPDF, std::vector<double> (nparameters, 0.0));
|
||||
std::vector<std::vector<double> > prev_error_low(nPDF, std::vector<double> (nparameters, 0.0));
|
||||
std::vector<std::vector<double> > prev_error_high(nPDF, std::vector<double> (nparameters, 0.0));
|
||||
std::vector<std::vector<double> > prev_meas(nPDF, std::vector<double> (nparameters, 0.0));
|
||||
std::vector<std::vector<bool> > isConstraint(nPDF, std::vector<bool> (nparameters, false));
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
for (unsigned int k=0; k<nparameters; k++){
|
||||
floatingvalues.at(n).at(k) = params.at(n)->get_parameter(k)->get_value();
|
||||
prev_error_low.at(n).at(k) = params.at(n)->get_parameter(k)->get_previous_error_low();
|
||||
prev_error_high.at(n).at(k) = params.at(n)->get_parameter(k)->get_previous_error_high();
|
||||
prev_meas.at(n).at(k) = params.at(n)->get_parameter(k)->get_previous_measurement();
|
||||
isConstraint.at(n).at(k) = params.at(n)->get_parameter(k)->get_gaussian_constraint();
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
for (unsigned int k=0; k<nparameters; k++){
|
||||
if(isConstraint.at(n).at(k)){
|
||||
spdlog::info("[PDF{0:d}][PAR{1:d}]\tpar={2:s}: prev_measurement={3:f} prev_low={4:f}prev_high={5:f}",
|
||||
n, k, params.at(n)->get_parameter(k)->get_name(),
|
||||
prev_meas.at(n).at(k),prev_error_low.at(n).at(k) ,prev_error_high.at(n).at(k));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//opts->minuit_strategy = 1.0;//this should be 2 for the fixed data fit I think
|
||||
if (from < 0) from = 0;
|
||||
if (to > int(nsteps) || to < 0) to = nsteps;
|
||||
std::vector<double> lhdatafixed(to-from, 0.0);
|
||||
std::vector<int> statusdatafixed(to-from, 0);
|
||||
std::vector<std::vector<double> > lhtoysfixed;
|
||||
std::vector<std::vector<double> > lhtoysfloated;
|
||||
|
||||
std::vector<std::vector<int> > statustoysfixed;
|
||||
std::vector<std::vector<int> > statustoysfloated;
|
||||
|
||||
std::vector<std::vector< double> > params_dfloated (nPDF, std::vector< double> (nparameters, 0.0));
|
||||
std::vector<std::vector<std::vector<double>>>params_dfixed(nPDF,std::vector<std::vector<double>>
|
||||
(to-from, std::vector<double>(nparameters, 0.0)));
|
||||
std::vector<std::vector<std::vector< std::vector< double> > > > params_tfixed (nPDF,
|
||||
std::vector<std::vector< std::vector< double> > > (to - from,
|
||||
std::vector< std::vector< double> > (ntoys,
|
||||
std::vector< double> (nparameters, 0.0))));
|
||||
std::vector<std::vector<std::vector< std::vector< double> > > > params_tfloated (nPDF,
|
||||
std::vector<std::vector< std::vector< double> > > (to - from,
|
||||
std::vector< std::vector< double> > (ntoys,
|
||||
std::vector< double> (nparameters, 0.0))));
|
||||
|
||||
//buffer floated data values
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
for (unsigned int k=0; k<nparameters; k++){
|
||||
params_dfloated.at(n).at(k) = params.at(n)->get_parameter(k)->get_value();
|
||||
}
|
||||
}
|
||||
|
||||
std::string pardesc = par->get_description();
|
||||
for (int j=from; j<to; j++){//loop over steps
|
||||
double parcur = parmin+(j+0.5)*(parmax-parmin)/nsteps;
|
||||
spdlog::info("[STEP]\tEvaluating step {0:d}out of {1:d} steps!",j-from+1, to-from);
|
||||
spdlog::info("[INFO]\tStudying point "+parname+"={0:f}",parcur);
|
||||
|
||||
//init parameters from floating fit values
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
for(unsigned int k=0; k<nparameters; k++){
|
||||
if(isConstraint.at(n).at(k)){
|
||||
params.at(n)->get_parameter(k)->init(floatingvalues.at(n).at(k), params.at(n)->get_parameter(k)->get_min(), params.at(n)->get_parameter(k)->get_max(),
|
||||
params.at(n)->get_parameter(k)->get_step_size(), prev_error_low.at(n).at(k), prev_error_high.at(n).at(k));
|
||||
params.at(n)->get_parameter(k)->set_previous_measurement(prev_meas.at(n).at(k));
|
||||
}
|
||||
else{
|
||||
params.at(n)->get_parameter(k)->init(floatingvalues.at(n).at(k), params.at(n)->get_parameter(k)->get_min(), params.at(n)->get_parameter(k)->get_max(),
|
||||
params.at(n)->get_parameter(k)->get_step_size());
|
||||
}
|
||||
}
|
||||
params.at(n)->reset_parameters();
|
||||
}
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
params.at(n)->get_parameter(parname)->init(parcur, parmin, parmax, 0.0);
|
||||
}
|
||||
opts->minuit_strategy = 2.0;//more precise for fixed data fit (used for lh)
|
||||
opts->hesse_postrun = false;
|
||||
opts->simplex_prerun = false;
|
||||
spdlog::info("Start fit with fixed parameter");
|
||||
statusdatafixed.at(j-from) = f->fit(probs, params, events);
|
||||
lhdatafixed.at(j-from) = f->likelihood();
|
||||
spdlog::info("[DONE]\tFinished fit with fixed parameter");
|
||||
opts->minuit_strategy = 1.0;//less precise for toys -> speed more important
|
||||
|
||||
opts->hesse_postrun = false;
|
||||
opts->simplex_prerun = false;
|
||||
|
||||
std::vector<std::vector<double> > fitvalues (nPDF, std::vector<double> (nparameters, 0.0));
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
//parameters from fixed point
|
||||
for (unsigned int k=0; k<nparameters; k++){
|
||||
fitvalues.at(n).at(k) = params.at(n)->get_parameter(k)->get_value();
|
||||
}
|
||||
//buffer fixed data values
|
||||
for (unsigned int k=0; k<nparameters; k++){
|
||||
params_dfixed.at(n).at(j-from).at(k) = params.at(n)->get_parameter(k)->get_value();
|
||||
}
|
||||
}
|
||||
|
||||
//make all toys with these params!
|
||||
std::vector<std::vector<std::vector<event> > >toys(ntoys, std::vector<std::vector<event> > ());
|
||||
spdlog::info("Start generating toys");
|
||||
for (unsigned int k = 0; k < ntoys; k++){
|
||||
spdlog::debug("[TOYS]\tGenerating toy sample {0:d}/{1:d}",k+1,ntoys );
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
std::vector<event> toy = gen->generate(events.at(n)->size(), params.at(n), probs.at(n));
|
||||
if(!opts->full_angular){
|
||||
fcnc::folder fldr(opts);
|
||||
for(UInt_t e = 0; e < toy.size(); e++){
|
||||
fldr.fold(&toy.at(e));
|
||||
if(toy.at(e).m < 1000.){
|
||||
spdlog::warn("[CORRUPT]\tEvent={0:d} pdf={0:f} toy={0:f}",e, n, k );
|
||||
spdlog::warn("[CORRUPT]\tctl={0:f} ctk={0:f} phi={0:f} q2={0:f}",
|
||||
toy.at(e).costhetal, toy.at(e).costhetak, toy.at(e).phi, toy.at(e).q2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
toys.at(k).push_back(toy);
|
||||
}
|
||||
}
|
||||
spdlog::info("[DONE]\tGenerating toys");
|
||||
|
||||
//init parameters from fixed point
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
for(unsigned int k=0; k<nparameters; k++){
|
||||
if(isConstraint.at(n).at(k)){
|
||||
params.at(n)->get_parameter(k)->init(fitvalues.at(n).at(k), params.at(n)->get_parameter(k)->get_min(), params.at(n)->get_parameter(k)->get_max(),
|
||||
params.at(n)->get_parameter(k)->get_step_size(), prev_error_low.at(n).at(k), prev_error_high.at(n).at(k));
|
||||
params.at(n)->get_parameter(k)->set_previous_measurement(prev_meas.at(n).at(k));
|
||||
}
|
||||
else{
|
||||
params.at(n)->get_parameter(k)->init(fitvalues.at(n).at(k), params.at(n)->get_parameter(k)->get_min(), params.at(n)->get_parameter(k)->get_max(),
|
||||
params.at(n)->get_parameter(k)->get_step_size());
|
||||
}
|
||||
}
|
||||
}
|
||||
//fit toys repeatedly
|
||||
std::vector<double> toysfixed;
|
||||
std::vector<double> toysfloated;
|
||||
std::vector<int> statusfixed;
|
||||
std::vector<int> statusfloated;
|
||||
spdlog::info("Start fitting all toys");
|
||||
for (unsigned int k=0; k<ntoys; k++){
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
params.at(n)->reset_parameters();//these are not the fitted/generated parameters->fix, they should float however, so should be ok?
|
||||
}
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
params.at(n)->get_parameter(parname)->init(parcur, parmin, parmax, 0.0);
|
||||
}
|
||||
|
||||
//save pointers to toy events into vector:
|
||||
std::vector<std::vector<event> * > leToys;
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
leToys.push_back(&toys.at(k).at(n));
|
||||
}
|
||||
|
||||
//fit with fixed parameter
|
||||
spdlog::info("[TOYS]\tFitting fixed toy sample {0:d}/{1:d} at step {2:d}/{3:d}",
|
||||
k+1, ntoys, j-from+1, to-from );
|
||||
int resultfixed = f->fit(probs, params, leToys);
|
||||
toysfixed.push_back(f->likelihood());
|
||||
statusfixed.push_back(resultfixed);
|
||||
|
||||
//buffer fixed toy values
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
for (unsigned int l=0; l<nparameters; l++){
|
||||
params_tfixed.at(n).at(j-from).at(k).at(l) = params.at(n)->get_parameter(l)->get_value();
|
||||
}
|
||||
params.at(n)->reset_parameters();
|
||||
|
||||
}
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
params.at(n)->get_parameter(parname)->init(parcur, parmin, parmax, 0.01);
|
||||
}
|
||||
|
||||
//fit with floated parameter
|
||||
spdlog::info("[TOYS]\tFitting freed toy sample0:d}/{1:d} at step {2:d}/{3:d}",
|
||||
k+1, ntoys, j-from+1, to-from );
|
||||
int resultfloated = f->fit(probs, params, leToys);
|
||||
toysfloated.push_back(f->likelihood());
|
||||
statusfloated.push_back(resultfloated);
|
||||
|
||||
//buffer fixed toy values
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
for (unsigned int l=0; l<nparameters; l++){
|
||||
params_tfloated.at(n).at(j-from).at(k).at(l) = params.at(n)->get_parameter(l)->get_value();
|
||||
}
|
||||
}
|
||||
}
|
||||
lhtoysfixed.push_back(toysfixed);
|
||||
lhtoysfloated.push_back(toysfloated);
|
||||
statustoysfixed.push_back(statusfixed);
|
||||
statustoysfloated.push_back(statusfloated);
|
||||
}// end loop over steps
|
||||
spdlog::info("[DONE]\tFitting all toys");
|
||||
spdlog::debug("tLoop over all {0:d} steps completed. Writing results to file!",nsteps );
|
||||
|
||||
//save to root file
|
||||
TFile* fout = new TFile(sout.str().c_str(), "RECREATE");
|
||||
fout->cd();
|
||||
TTree* t = new TTree(parname.c_str(), pardesc.c_str());
|
||||
int pdf=0, step=0, statustfixed=0, statustfloated=0, toy=0, statusdfixed=0, statusdfloated=0;
|
||||
double value=0.0, lhdfloated=lhdatafloated, lhdfixed=0.0, lhtfixed=0.0, lhtfloated=0.0;
|
||||
t->Branch("bin",&bin,"bin/I");
|
||||
t->Branch("pdf",&pdf,"pdf/I");
|
||||
t->Branch("step",&step,"step/I");
|
||||
t->Branch("value",&value,"value/D");
|
||||
t->Branch("toy",&toy,"toy/I");
|
||||
t->Branch("statusdatafixed",&statusdfixed,"statusdatafixed/I");
|
||||
t->Branch("statusdatafloated",&statusdfloated,"statusdatafloated/I");
|
||||
t->Branch("statustoyfixed",&statustfixed,"statustoyfixed/I");
|
||||
t->Branch("statustoyfloated",&statustfloated,"statustoyfloated/I");
|
||||
t->Branch("lhdatafloated",&lhdfloated,"lhdatafloated/D");
|
||||
t->Branch("valuedatafloated",&valuedatafloated,"valuedatafloated/D");
|
||||
t->Branch("lhdatafixed",&lhdfixed,"lhdatafixed/D");
|
||||
t->Branch("lhtoyfixed",&lhtfixed,"lhtoyfixed/D");
|
||||
t->Branch("lhtoyfloated",&lhtfloated,"lhtoyfloated/D");
|
||||
//also save the fitted values
|
||||
std::vector<double> tfloated(nparameters, 0.0), tfixed(nparameters, 0.0), dfloated(nparameters, 0.0), dfixed(nparameters, 0.0);
|
||||
for (unsigned int k = 0; k < nparameters; k++){
|
||||
fcnc::parameter* param = params.at(pdfidx)->get_parameter(k);
|
||||
if (param->get_step_size() != 0.0){
|
||||
std::string parname(param->get_name());
|
||||
std::string pardesc(param->get_description());
|
||||
//TTree* t = new TTree(parname.c_str(), pardesc.c_str());
|
||||
t->Branch((std::string("datafixed_")+parname).c_str(),&dfixed.at(k),(std::string("datafixed_")+parname+std::string("/D")).c_str());
|
||||
t->Branch((std::string("datafloated_")+parname).c_str(),&dfloated.at(k),(std::string("datafloated_")+parname+std::string("/D")).c_str());
|
||||
t->Branch((std::string("toyfixed_")+parname).c_str(),&tfixed.at(k),(std::string("toyfixed_")+parname+std::string("/D")).c_str());
|
||||
t->Branch((std::string("toyfloated_")+parname).c_str(),&tfloated.at(k),(std::string("toyfloated_")+parname+std::string("/D")).c_str());
|
||||
}
|
||||
}
|
||||
for(unsigned int n = 0; n < nPDF; n++){
|
||||
pdf = n; //TODO: what is this supposed to do?
|
||||
for (int j=from; j<to; j++){
|
||||
step = j;
|
||||
for (unsigned int k=0; k<ntoys; k++){
|
||||
toy = k;
|
||||
value = parmin+(j+0.5)*(parmax-parmin)/nsteps;
|
||||
statustfixed = statustoysfixed.at(j-from).at(k);
|
||||
statustfloated = statustoysfloated.at(j-from).at(k);
|
||||
statusdfloated = statusdatafloated;
|
||||
statusdfixed = statusdatafixed.at(j-from);
|
||||
lhtfixed = lhtoysfixed.at(j-from).at(k);
|
||||
lhtfloated = lhtoysfloated.at(j-from).at(k);
|
||||
lhdfixed = lhdatafixed.at(j-from);
|
||||
//lhdfloated = lhdatafloated; //always the same
|
||||
for (unsigned int l = 0; l < nparameters; l++){
|
||||
tfloated.at(l) = params_tfloated.at(n).at(j-from).at(k).at(l);
|
||||
tfixed.at(l) = params_tfixed.at(n).at(j-from).at(k).at(l);
|
||||
dfloated.at(l) = params_dfloated.at(n).at(l);
|
||||
dfixed.at(l) = params_dfixed.at(n).at(j-from).at(l);
|
||||
}
|
||||
t->Fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
t->Write();
|
||||
fout->Write();
|
||||
fout->Close();
|
||||
delete fout;
|
||||
/*
|
||||
//analyse results
|
||||
std::string suffix = "";
|
||||
TH1D* cl = new TH1D((std::string("cl")+parname+suffix).c_str(), (std::string(";")+pardesc+std::string(";Confidence level")).c_str(), nsteps, parmin, parmax);
|
||||
TH1D* lh = new TH1D((std::string("lh")+parname+suffix).c_str(), (std::string(";")+pardesc+std::string(";Confidence level")).c_str(), nsteps, parmin, parmax);
|
||||
for (unsigned int j=0; j<nsteps; j++)
|
||||
{
|
||||
unsigned int nlarger = 0;
|
||||
for (unsigned int k=0; k<ntoys; k++)
|
||||
{
|
||||
double dtoy = lhtoysfixed.at(j).at(k)-lhtoysfloated.at(j).at(k);
|
||||
double ddata = lhdatafixed.at(j)-lhdatafloated;
|
||||
if (dtoy > ddata)
|
||||
nlarger++;
|
||||
}
|
||||
lh->SetBinContent(j+1, TMath::Erf(sqrt(lhdatafixed.at(j)-lhdatafloated)/sqrt(2.0)));
|
||||
cl->SetBinContent(j+1, 1.0-double(nlarger)/ntoys);
|
||||
}
|
||||
double low = parmin;
|
||||
const double thecl = 0.683;
|
||||
if (cl->GetBinContent(1) > thecl)//???
|
||||
{
|
||||
for (int i=0; i<nsteps; i++)
|
||||
if (cl->GetBinContent(i+1) > thecl && cl->GetBinContent(i+2) < thecl)
|
||||
{
|
||||
low = cl->GetBinCenter(i+1) + (thecl-cl->GetBinContent(i+1))*(cl->GetBinCenter(i+2)-cl->GetBinCenter(i+1))/(cl->GetBinContent(i+2)-cl->GetBinContent(i+1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
double high = parmax;
|
||||
if (cl->GetBinContent(nsteps) > thecl)
|
||||
{
|
||||
for (int i=nsteps-1; i>=0; i--)
|
||||
if (cl->GetBinContent(i+1) < thecl && cl->GetBinContent(i+2) > thecl)
|
||||
{
|
||||
high = cl->GetBinCenter(i+1) + (thecl-cl->GetBinContent(i+1))*(cl->GetBinCenter(i+2)-cl->GetBinCenter(i+1))/(cl->GetBinContent(i+2)-cl->GetBinContent(i+1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
TCanvas* c1 = new TCanvas("c1", "c1", 1600, 1200);
|
||||
TLine* l = new TLine();
|
||||
c1->cd();
|
||||
cl->SetMinimum(0.0);
|
||||
cl->SetMaximum(1.1);
|
||||
cl->Draw();
|
||||
lh->SetLineColor(4);
|
||||
lh->Draw("lsame");
|
||||
l->SetLineColor(2);
|
||||
l->DrawLine(low, 0.0, low, 1.1);
|
||||
l->DrawLine(high, 0.0, high, 1.1);
|
||||
c1->Print((std::string("plots/cl")+parname+suffix+std::string(".eps")).c_str(),"eps");
|
||||
//delete cl;
|
||||
delete l;
|
||||
delete c1;
|
||||
delete cl;
|
||||
*/
|
||||
}
|
||||
else{
|
||||
spdlog::critical("Could not find parameter "+parname);
|
||||
assert(0);
|
||||
}
|
||||
spdlog::info("Finished Feldman-Cousins study for parameter "+ parname);
|
||||
opts->hesse_postrun = cache_hesse;
|
||||
opts->squared_hesse = cache_sq_hesse;
|
||||
opts->minos_errors = cache_minos;
|
||||
opts->shift_lh = cache_shift;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fcnc::feldman_cousins::fc_1d(std::string parname, unsigned int nsteps, double parmin, double parmax, unsigned int ntoys,
|
||||
pdf* prob, parameters* params, generator* gen, fitter* f,
|
||||
std::vector<event> * events, unsigned int bin, int from, int to){
|
||||
std::vector<pdf *> the_probs;
|
||||
the_probs.push_back(prob);
|
||||
|
||||
std::vector<parameters *> the_params;
|
||||
the_params.push_back(params);
|
||||
|
||||
std::vector<std::vector<event>* > the_events;
|
||||
the_events.push_back(events);
|
||||
|
||||
return fc_1d(parname, nsteps, parmin, parmax, ntoys, 0,
|
||||
the_probs, the_params, gen, f,
|
||||
the_events, bin, from, to);
|
||||
}
|
||||
|
||||
bool fcnc::feldman_cousins::fc_2d(std::string parxname, unsigned int nstepsx, double parxmin, double parxmax,
|
||||
std::string paryname, unsigned int nstepsy, double parymin, double parymax,
|
||||
unsigned int ntoys, unsigned int pdfidx, //this parameter just changes output file
|
||||
std::vector<pdf*> probs, std::vector<parameters*> params, generator* gen, fitter* f,
|
||||
std::vector<std::vector<event> *> events, unsigned int bin, int from, int to){
|
||||
spdlog::info("Feldman-Cousins study for parameters" + parxname +", " +paryname );
|
||||
/*
|
||||
bool cache_minos = opts->minos_errors;
|
||||
bool cache_hesse = opts->hesse_postrun;
|
||||
bool cache_shift = opts->shift_lh;
|
||||
int cache_print = opts->print_level;
|
||||
|
||||
const unsigned int nPDF = probs.size();
|
||||
assert(params.size() == nPDF);
|
||||
assert(events.size() == nPDF);
|
||||
assert(pdfidx < nPDF);
|
||||
|
||||
parameter* parx = params.at(pdfidx)->get_parameter(parxname);
|
||||
parameter* pary = params.at(pdfidx)->get_parameter(paryname);
|
||||
if (parx != 0 && pary != 0)
|
||||
{
|
||||
opts->minos_errors = false;
|
||||
opts->hesse_postrun = false;
|
||||
opts->shift_lh = false;
|
||||
|
||||
//fitter f(opts);
|
||||
f->fit(probs, params, events);
|
||||
double lhdatafloated = f.likelihood();
|
||||
double valuexdatafloated = parx->get_value();
|
||||
double valueydatafloated = pary->get_value();
|
||||
spdlog::info("Data fit finished with -2logLh = {0:f}",lhdatafloated );
|
||||
|
||||
opts->print_level = -1;
|
||||
//std::cout << from << " {0:f}",to << " {0:f}",from - to << std::endl;
|
||||
if (from < 0)
|
||||
from = 0;
|
||||
if (to > int(nstepsx*nstepsy) || to < 0)
|
||||
to = nstepsx*nstepsy;
|
||||
std::vector<double> lhdatafixed(to-from, 0.0);
|
||||
std::vector<std::vector<double> > lhtoysfixed;
|
||||
std::vector<std::vector<double> > lhtoysfloated;
|
||||
|
||||
std::vector<std::vector<int> > statustoysfixed;
|
||||
std::vector<std::vector<int> > statustoysfloated;
|
||||
|
||||
std::string parxdesc = parx->get_description();
|
||||
std::string parydesc = pary->get_description();
|
||||
for (int j=from; j<to; j++)
|
||||
{
|
||||
//xidx = j%nstepsx
|
||||
//yidx = j/nstepsx
|
||||
double parxcur = parxmin+((j%nstepsx)+0.5)*(parxmax-parxmin)/nstepsx;
|
||||
double parycur = parymin+((j/nstepsx)+0.5)*(parymax-parymin)/nstepsy;
|
||||
|
||||
spdlog::info("Studying point" +parxname +"="+ parxcur + paryname + "=" +parycur );
|
||||
params.reset_parameters();
|
||||
|
||||
parx->init(parxname, parxdesc, parxcur, parxmin, parxmax, 0.0);
|
||||
pary->init(paryname, parydesc, parycur, parymin, parymax, 0.0);
|
||||
f->fit(probs, params, events);
|
||||
lhdatafixed.at(j-from) = f->likelihood();
|
||||
|
||||
//make all toys with these params!
|
||||
std::vector<std::vector<event> > toys;
|
||||
for (unsigned int k=0; k<ntoys; k++)
|
||||
{
|
||||
std::vector<event> toy = gen->generate(events.size(), params, prob);
|
||||
toys.push_back(toy);
|
||||
}
|
||||
//fit toys repeatedly
|
||||
std::vector<double> toysfixed;
|
||||
std::vector<double> toysfloated;
|
||||
std::vector<int> statusfixed;
|
||||
std::vector<int> statusfloated;
|
||||
for (unsigned int k=0; k<ntoys; k++)
|
||||
{
|
||||
params.reset_parameters();//these are not the fitted/generated parameters->fix, they should float however, so should be ok?
|
||||
parx->init(parxname, parxdesc, parxcur, parxmin, parxmax, 0.0);
|
||||
pary->init(paryname, parydesc, parycur, parymin, parymax, 0.0);
|
||||
int resultfixed = f->fit(probs, params, &toys.at(k));
|
||||
toysfixed.push_back(f->likelihood());
|
||||
statusfixed.push_back(resultfixed);
|
||||
|
||||
params.reset_parameters();
|
||||
parx->init(parxname, parxdesc, parxcur, parxmin, parxmax, 0.01);
|
||||
pary->init(paryname, parydesc, parycur, parymin, parymax, 0.01);
|
||||
int resultfloated = f->fit(probs, params, &toys.at(k));
|
||||
toysfloated.push_back(f->likelihood());
|
||||
statusfloated.push_back(resultfloated);
|
||||
}
|
||||
lhtoysfixed.push_back(toysfixed);
|
||||
lhtoysfloated.push_back(toysfloated);
|
||||
statustoysfixed.push_back(statusfixed);
|
||||
statustoysfloated.push_back(statusfloated);
|
||||
}
|
||||
//std::cout <<"after loop" );
|
||||
|
||||
//save to root file
|
||||
std::ostringstream sout;
|
||||
sout << "FCresult_" << bin << "_" << parxname << "_" << paryname << "_" << from << "_" << to << ".root";
|
||||
TFile* fout = new TFile(sout.str().c_str(), "RECREATE");
|
||||
fout->cd();
|
||||
TTree* t = new TTree((parxname+std::string("_")+paryname).c_str(), (std::string(";")+parxdesc+std::string(";")+parydesc).c_str());
|
||||
int step=0, stepx=0, stepy=0, statustfixed=0, statustfloated=0, toy=0;
|
||||
double valuex=0.0, valuey, lhdfloated=lhdatafloated, lhdfixed=0.0, lhtfixed=0.0, lhtfloated=0.0;
|
||||
t->Branch("bin",&bin,"bin/I");
|
||||
t->Branch("step",&step,"step/I");
|
||||
t->Branch("stepx",&stepx,"stepx/I");
|
||||
t->Branch("stepy",&stepy,"stepy/I");
|
||||
t->Branch("valuex",&valuex,"valuex/D");
|
||||
t->Branch("valuey",&valuey,"valuey/D");
|
||||
t->Branch("valuexdatafloated",&valuexdatafloated,"valuexdatafloated/D");
|
||||
t->Branch("valueydatafloated",&valueydatafloated,"valueydatafloated/D");
|
||||
t->Branch("toy",&toy,"toy/I");
|
||||
t->Branch("statustoyfixed",&statustfixed,"statustoyfixed/I");
|
||||
t->Branch("statustoyfloated",&statustfloated,"statustoyfloated/I");
|
||||
t->Branch("lhdatafloated",&lhdfloated,"lhdatafloated/D");
|
||||
t->Branch("lhdatafixed",&lhdfixed,"lhdatafixed/D");
|
||||
t->Branch("lhtoyfixed",&lhtfixed,"lhtoyfixed/D");
|
||||
t->Branch("lhtoyfloated",&lhtfloated,"lhtoyfloated/D");
|
||||
for (int j=from; j<to; j++)
|
||||
{
|
||||
for (unsigned int k=0; k<ntoys; k++)
|
||||
{
|
||||
step = j;
|
||||
stepx = j%nstepsx;
|
||||
stepy = j/nstepsx;
|
||||
toy = k;
|
||||
valuex = parxmin+((j%nstepsx)+0.5)*(parxmax-parxmin)/nstepsx;
|
||||
valuey = parymin+((j/nstepsx)+0.5)*(parymax-parymin)/nstepsy;
|
||||
statustfixed = statustoysfixed.at(j-from).at(k);
|
||||
statustfloated = statustoysfloated.at(j-from).at(k);
|
||||
lhtfixed = lhtoysfixed.at(j-from).at(k);
|
||||
lhtfloated = lhtoysfloated.at(j-from).at(k);
|
||||
lhdfixed = lhdatafixed.at(j-from);
|
||||
lhdfloated = lhdatafloated;
|
||||
t->Fill();
|
||||
}
|
||||
}
|
||||
t->Write();
|
||||
fout->Write();
|
||||
fout->Close();
|
||||
delete fout;
|
||||
}
|
||||
else{
|
||||
if (parx == 0) spdlog::error("Could not find parameter" +parxname );
|
||||
if (pary == 0) spdlog::error("Could not find parameter" +paryname );
|
||||
assert(0);
|
||||
}
|
||||
spdlog::info("Finished Feldman-Cousins study for parameters "+parxname + "," +paryname );
|
||||
opts->hesse_postrun = cache_hesse;
|
||||
opts->minos_errors = cache_minos;
|
||||
opts->shift_lh = cache_shift;
|
||||
opts->print_level = cache_print;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fcnc::feldman_cousins::fc_2d(std::string parxname, unsigned int nstepsx, double parxmin, double parxmax,
|
||||
std::string paryname, unsigned int nstepsy, double parymin, double parymax,
|
||||
unsigned int ntoys, //this parameter just changes output file
|
||||
pdf* prob, parameters* params, generator* gen, fitter* f,
|
||||
std::vector<event> * events, unsigned int bin, int from, int to){
|
||||
std::vector<pdf *> the_probs;
|
||||
the_probs.push_back(prob);
|
||||
|
||||
std::vector<parameters *> the_params;
|
||||
the_params.push_back(params);
|
||||
|
||||
std::vector<std::vector<event>* > the_events;
|
||||
the_events.push_back(events);
|
||||
|
||||
return fc_2d(parxname, nstepsx, parxmin, parxmax,
|
||||
paryname, nstepsy, parymin, parymax,
|
||||
ntoys, 0,
|
||||
the_probs, the_params, gen, f,
|
||||
the_events, bin, from, to);
|
||||
}
|
||||
|
66
Code/FCNCFitter/sources/Run/feldman_cousins.hh
Normal file
66
Code/FCNCFitter/sources/Run/feldman_cousins.hh
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @file feldman_cousins.hh
|
||||
* @author Christoph Langenbruch, David Gerick
|
||||
* @date 2020-06-30
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FELDMAN_COUSINS_H
|
||||
#define FELDMAN_COUSINS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
namespace fcnc {
|
||||
//Forward declarations
|
||||
class event;
|
||||
class fitter;
|
||||
class pdf;
|
||||
class generator;
|
||||
class parameters;
|
||||
class options;
|
||||
|
||||
class feldman_cousins;
|
||||
|
||||
class feldman_cousins {
|
||||
private:
|
||||
options* opts;
|
||||
int from, to;
|
||||
public:
|
||||
///constructor
|
||||
feldman_cousins(options* o):
|
||||
opts(o),
|
||||
from(-1),
|
||||
to(-1)
|
||||
{
|
||||
};
|
||||
///destructor
|
||||
~feldman_cousins(){};
|
||||
|
||||
///one-dimensional feldman cousins
|
||||
bool fc_1d(std::string parname, unsigned int nsteps, double parmin, double parmax,
|
||||
unsigned int ntoys, unsigned int pdfidx, //this parameter just changes output file
|
||||
std::vector<pdf*> probs, std::vector<parameters*> params, generator* gen, fitter* f,
|
||||
std::vector<std::vector<event> *> events, unsigned int bin=0, int from=-1, int to=-1);
|
||||
|
||||
bool fc_1d(std::string parname, unsigned int nsteps, double parmin, double parmax,
|
||||
unsigned int ntoys, //this parameter just changes output file
|
||||
pdf* prob, parameters* params, generator* gen, fitter* f,
|
||||
std::vector<event> * events, unsigned int bin=0, int from=-1, int to=-1);
|
||||
///two-dimensional feldman cousins
|
||||
bool fc_2d(std::string parxname, unsigned int nstepsx, double parxmin, double parxmax,
|
||||
std::string paryname, unsigned int nstepsy, double parymin, double parymax,
|
||||
unsigned int ntoys, unsigned int pdfidx, //this parameter just changes output file
|
||||
std::vector<pdf*> probs, std::vector<parameters*> params, generator* gen, fitter* f,
|
||||
std::vector<std::vector<event> *> events, unsigned int bin=0, int from=-1, int to=-1);
|
||||
|
||||
bool fc_2d(std::string parxname, unsigned int nstepsx, double parxmin, double parxmax,
|
||||
std::string paryname, unsigned int nstepsy, double parymin, double parymax,
|
||||
unsigned int ntoys, //this parameter just changes output file
|
||||
pdf* prob, parameters* params, generator* gen, fitter* f,
|
||||
std::vector<event> * events, unsigned int bin=0, int from=-1, int to=-1);
|
||||
};
|
||||
|
||||
|
||||
}//end namespace
|
||||
|
||||
#endif
|
290
Code/FCNCFitter/sources/Run/generatetoys.cc
Normal file
290
Code/FCNCFitter/sources/Run/generatetoys.cc
Normal file
@ -0,0 +1,290 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include "generatetoys.hh"
|
||||
#include <bu2kstarmumu_parameters.hh>
|
||||
#include <helpers.hh>
|
||||
#include <event.hh>
|
||||
#include <paths.hh>
|
||||
#include <folder.hh>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
//Options to generate toys:
|
||||
//Runs: 1, 2 or 1+2
|
||||
//Signal only / Bkg only / Both
|
||||
//Rare / Jpsi
|
||||
//Bins
|
||||
//Mass only / Angles only
|
||||
//S or P
|
||||
|
||||
//Values taken from: MCsig, MCref, Bkg (top/bottom/both), Reference
|
||||
//Can be also just mass/angle fit
|
||||
|
||||
//TODO: move this somewhere else
|
||||
bool LowMassFit = false;
|
||||
bool HighMassFit = true;
|
||||
|
||||
|
||||
int initialize_parameters_from_MCfit(fcnc::bu2kstarmumu_parameters *parameters, bool fromRef, int PDF, int bin, std::vector<std::string> names, basic_params params, fixConstr fixConstrain){
|
||||
bool SimFit = true;
|
||||
bool onlyAngs = false;
|
||||
int nBins = fromRef ? 1 : params.nBins; //When looping over bins, this protects from trying to read from refMC
|
||||
std::string fileName_MC = final_result_name_MC(params, nBins, fromRef, false, SimFit, onlyAngs, fromRef);
|
||||
parameters->get_param_from_rootfile(fileName_MC, names, PDF, fromRef ? 0 : bin, fixConstrain); //TODO: use the struct fixConstr also in the parameters
|
||||
return 0;
|
||||
}
|
||||
|
||||
int initialize_parameters_from_BkgFit(fcnc::bu2kstarmumu_parameters *parameters, bool fromRef, bool LowMassFit, bool HighMassFit, bool fitKpi, int PDF, int bin, std::vector<std::string> names, basic_params params,fixConstr fixConstrain){
|
||||
int nBins = fromRef ? 1 : params.nBins;
|
||||
std::string fileName_topBkg = final_result_name_bkg(nBins, fromRef, LowMassFit, HighMassFit, fitKpi, params);
|
||||
parameters->get_param_from_rootfile(fileName_topBkg, names, PDF,fromRef ? 0 : bin, fixConstrain);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int initialize_parameters_from_MassFit(fcnc::bu2kstarmumu_parameters *parameters, bool fromRef, int PDF, int bin, std::vector<std::string> names, basic_params params, fixConstr fixConstrain){
|
||||
int nBins = fromRef ? 1 : params.nBins; //When looping over bins, this protects from trying to read from refMC
|
||||
bool splitRuns = true; //Get it per run or not
|
||||
int b = fromRef ? 0 : bin;
|
||||
//If not, use the PDF number form the parameter Run
|
||||
std::string fileName_dataMass = final_result_name_mass(fromRef, nBins, params.Run, params, params.Run);
|
||||
parameters->get_param_from_rootfile(fileName_dataMass, names, splitRuns ? PDF : params.Run, b, fixConstrain);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int initialize_B_mass(fcnc::bu2kstarmumu_parameters *parameters, bool fromRef, int PDF, int bin, basic_params params){
|
||||
int nBins = fromRef ? 1 : params.nBins; //When looping over bins, this protects from trying to read from refMC
|
||||
bool splitRuns = true; //Get it per run or not
|
||||
int b = fromRef ? 0 : bin;
|
||||
//Not part of the other functions as the range needs to be full
|
||||
std::string fileName_dataMass = final_result_name_mass(fromRef, nBins, params.Run, params, params.Run);
|
||||
parameters->m_b.init(get_param_value_from_rootfile(fileName_dataMass,"m_b", splitRuns ? PDF : params.Run,b),B_MASS_LOW,B_MASS_HIGH,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//Take the default values, set in constants.hh and bu2kstarmumu_parameters.cc
|
||||
int initialize_default_parameters(fcnc::bu2kstarmumu_parameters *parameters){
|
||||
parameters->use_default();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Generates toys identical to the given parameters
|
||||
std::vector<fcnc::event> generateToys(basic_params params, int bin, int PDF,
|
||||
fcnc::bu2kstarmumu_parameters *toyParameters,
|
||||
fcnc::options opts){
|
||||
/* These options should not be modified inside here
|
||||
// Set options //
|
||||
//The options will be taken from the fitter itself
|
||||
opts.only_angles = false;
|
||||
opts.only_Bmass = false;
|
||||
|
||||
opts.weighted_fit = true;
|
||||
opts.use_weighted_bkg = false;
|
||||
opts.always_generate_full_angular = true;
|
||||
|
||||
opts.swave = false;
|
||||
opts.shift_lh = false;
|
||||
opts.individual_penalties = false;
|
||||
|
||||
//Stat. uncertainty determination tool:
|
||||
opts.squared_hesse = true;
|
||||
opts.minos_errors = false;
|
||||
|
||||
opts.generate_mkpi = true;
|
||||
opts.simple_mkpi = false;
|
||||
opts.isobar = false;
|
||||
opts.mkpi_full_range_norm = false;
|
||||
|
||||
opts.flat_bkg = false;
|
||||
*/
|
||||
//Init the q2 options, to be sure
|
||||
opts.q2_min = opts.TheQ2binsmin[bin];
|
||||
opts.q2_max = opts.TheQ2binsmax[bin];
|
||||
|
||||
opts.update_angle_ranges(); //Set angles in options back to defaults
|
||||
//opts.update_efficiencies = true; //This ensures the acceptance weights to be taken into account. //TODO
|
||||
if (opts.run == 1) opts.year = 2012; //Cause why not :)
|
||||
else opts.year = 2017;
|
||||
|
||||
//Create parameter set
|
||||
fcnc::bu2kstarmumu_pdf prob(&opts, toyParameters);
|
||||
fcnc::bu2kstarmumu_generator gen(&opts);
|
||||
|
||||
prob.load_coeffs_eff_phsp_4d();
|
||||
prob.update_cached_normalization(toyParameters);
|
||||
//And finally generate the events
|
||||
//How much events relative to the requedred total number of events?
|
||||
double frac = eventsInBin_fraction(bin,opts.run,params.nBins,params.reference);
|
||||
int N = std::lround(params.nEvents*frac);
|
||||
spdlog::info("Generate {0:d} toy events", N);
|
||||
|
||||
std::vector<fcnc::event> genToys = gen.generate(N, toyParameters, &prob);
|
||||
|
||||
//Update cached efficiencies of the angular acceptance correction weights
|
||||
prob.update_cached_efficiencies(toyParameters, &genToys);
|
||||
|
||||
//for folded analysis, fold the angular values of all generated events before returning
|
||||
if(!opts.full_angular){
|
||||
spdlog::debug("Folding the generated {0:d} events according to fold #{1:d}", genToys.size(), opts.folding);
|
||||
fcnc::folder theFolder(&opts);
|
||||
for(UInt_t e = 0; e < genToys.size(); e++){
|
||||
fcnc::event * evt = &genToys.at(e);
|
||||
theFolder.fold(evt);
|
||||
spdlog::trace("Folded event: ctk={0:f}\t ctl={1:f}\t phi={2:f}\t m={3:f} \tmkpi={4:f}", evt->costhetak, evt->costhetal, evt->phi, evt->m, evt->mkpi);
|
||||
}
|
||||
}
|
||||
return genToys;
|
||||
}
|
||||
|
||||
std::vector<fcnc::event> generateIndividualToys(basic_params params, int bin, int PDF,
|
||||
fcnc::bu2kstarmumu_parameters *toyParameters,
|
||||
fcnc::options opts, bool genOnlySig, bool genOnlyBkg){
|
||||
|
||||
if (genOnlySig && genOnlyBkg){
|
||||
spdlog::error("Cannot generate only bkg and only sig in one go!");
|
||||
spdlog::error("Check your options.");
|
||||
return {{}};
|
||||
}
|
||||
|
||||
bool genReference = params.reference;
|
||||
|
||||
// Set options //
|
||||
//The options will be taken from the fitter itself
|
||||
opts.only_angles = false;
|
||||
opts.only_Bmass = false;
|
||||
|
||||
opts.weighted_fit = true;
|
||||
opts.use_weighted_bkg = false;
|
||||
opts.always_generate_full_angular = true;
|
||||
|
||||
opts.swave = false;
|
||||
opts.shift_lh = false;
|
||||
opts.individual_penalties = false;
|
||||
|
||||
//Stat. uncertainty determination tool:
|
||||
opts.squared_hesse = true;
|
||||
opts.minos_errors = false;
|
||||
|
||||
opts.generate_mkpi = true;
|
||||
opts.generate_only_bkg = genOnlyBkg;
|
||||
opts.simple_mkpi = false;
|
||||
opts.isobar = false;
|
||||
opts.mkpi_full_range_norm = false;
|
||||
|
||||
opts.flat_bkg = false;
|
||||
|
||||
//Init the q2 options, to be sure
|
||||
opts.q2_min = opts.TheQ2binsmin[bin];
|
||||
opts.q2_max = opts.TheQ2binsmax[bin];
|
||||
|
||||
opts.run = PDF; //Set proper run to options
|
||||
opts.update_angle_ranges(); //Set angles in options back to defaults
|
||||
opts.update_efficiencies = true; //This ensures the acceptance weights to be taken into account.
|
||||
if (opts.run == 1) opts.year = 2012; //Cause why not :)
|
||||
else opts.year = 2017;
|
||||
|
||||
//Create parameter set
|
||||
fcnc::bu2kstarmumu_pdf prob(&opts, toyParameters);
|
||||
fcnc::bu2kstarmumu_generator gen(&opts);
|
||||
|
||||
prob.load_coeffs_eff_phsp_4d();
|
||||
prob.update_cached_normalization(toyParameters);
|
||||
|
||||
// Initialize everything //
|
||||
//Note that hte code will crash if the file is not there, so test before submititng pls
|
||||
|
||||
//Set the f_sig
|
||||
if (genOnlySig) toyParameters->f_sig.init_fixed(1.0);
|
||||
else if (genOnlyBkg) toyParameters->f_sig.init_fixed(0.0);
|
||||
else{ //Or both, in that case load the f_sig from mass only fit
|
||||
initialize_parameters_from_MassFit(toyParameters,genReference,PDF,bin,{"f_sig"},params,fixConstr(false,false));
|
||||
}
|
||||
|
||||
//Init angular parameters from MC
|
||||
if (genReference) toyParameters->init_ang_parameters_fromRefDavid(bin,1.0,0.01);
|
||||
else initialize_parameters_from_MCfit(toyParameters,false,PDF,bin,param_string(opts, true),params,fixConstr(false,false));
|
||||
|
||||
//Init the ratio of sigmas in signal MC/reference MC
|
||||
//As everything is fixed everywhere and not contrained in mass, this is fine, but this should be done properly //TODO
|
||||
initialize_parameters_from_MCfit(toyParameters,genReference,PDF,bin,params_string_mass(opts),params,fixConstr(true,false));
|
||||
|
||||
if (!genReference) toyParameters->m_scale.init_fixed(get_sigmaRatio_fromMC(params,params.nBins,bin, PDF));
|
||||
else toyParameters->m_scale.init_fixed(1.0);
|
||||
|
||||
|
||||
//Init the bkg parameters from the BKG fit file
|
||||
//First init the background for angles
|
||||
initialize_parameters_from_BkgFit(toyParameters, true, LowMassFit, HighMassFit, false, 12, bin,param_string_bkg(),params,fixConstr(false,false));
|
||||
//Then init the background for m_Kpi
|
||||
initialize_parameters_from_BkgFit(toyParameters, true, LowMassFit, HighMassFit, true, 12, bin,param_string_bkg_mkpi(),params,fixConstr(false,false));
|
||||
|
||||
//Init the mass background from mass fit to reference for now
|
||||
std::vector<std::string> fixFromMassFit; //TODO: set as a proper vector depending on using 2 lambdas or anything
|
||||
if (opts.fit_lambda) fixFromMassFit.push_back("m_lambda");
|
||||
else fixFromMassFit.push_back("m_tau");
|
||||
initialize_parameters_from_MassFit(toyParameters,true,PDF,bin,fixFromMassFit,params,fixConstr(false,false));
|
||||
|
||||
//Initialize the q2 by hand, as it is the easiest
|
||||
toyParameters->eff_q2.init(bin_center_q2(opts,bin), opts.q2_min, opts.q2_max, 0.0);
|
||||
|
||||
//Set the Bmass separatelly as it's range is important
|
||||
initialize_B_mass(toyParameters,true,PDF,bin,params);
|
||||
|
||||
//Control print of the parameters
|
||||
toyParameters->print_parameters(false);
|
||||
|
||||
//Update the normalisation with the new parameter settings
|
||||
prob.update_cached_normalization(toyParameters);
|
||||
|
||||
//And finally generate the events
|
||||
//How much events relative to the requedred total number of events?
|
||||
double frac = eventsInBin_fraction(bin,opts.run,params.nBins,params.reference);
|
||||
int N = std::lround(params.nEvents*frac);
|
||||
spdlog::info("Generate {0:d} toy events", N);
|
||||
std::vector<fcnc::event> genToys = gen.generate(N, toyParameters, &prob);
|
||||
|
||||
//for folded analysis, fold the angular values of all generated events before returning
|
||||
if(!opts.full_angular){
|
||||
spdlog::debug("Folding the generated {0:d} events according to fold #{1:d}", genToys.size(), opts.folding);
|
||||
fcnc::folder theFolder(&opts);
|
||||
for(auto evt: genToys){
|
||||
theFolder.fold(&evt);
|
||||
spdlog::trace("Folded event: ctk={0:f}, ctl={1:f}, phi={2:f}", evt.costhetak, evt.costhetal, evt.phi);
|
||||
}
|
||||
}
|
||||
return genToys;
|
||||
}
|
||||
|
||||
int saveToys(basic_params params, fcnc::options opts, bool genOnlySig, bool genOnlyBkg){
|
||||
|
||||
std::vector<UInt_t> pdf_idx;
|
||||
if (params.Run == 1 || params.Run == 12) pdf_idx.push_back(1);
|
||||
if (params.Run == 2 || params.Run == 12) pdf_idx.push_back(2);
|
||||
|
||||
|
||||
const int nBins = params.nBins;
|
||||
|
||||
std::vector<fcnc::parameters*> toyParams [nBins];
|
||||
std::vector<int>tmpRes[nBins]; //instead of fit results
|
||||
|
||||
//Now just for saving do this
|
||||
for (auto idx: pdf_idx){
|
||||
std::vector<fcnc::event> events;
|
||||
for (int bin = 0; bin < params.nBins; bin++){
|
||||
fcnc::bu2kstarmumu_parameters * tmpParams = new fcnc::bu2kstarmumu_parameters (&opts);
|
||||
std::vector<fcnc::event> tmp = generateIndividualToys(params, bin, idx, tmpParams, opts,genOnlySig, genOnlyBkg);
|
||||
events.insert(events.end(),tmp.begin(),tmp.end());
|
||||
toyParams[bin].push_back(tmpParams);
|
||||
tmpRes[bin].push_back(0);
|
||||
}
|
||||
std::string saveFile = get_finalToys_file(params.reference, nBins, true, params, idx);
|
||||
fcnc::save_events(saveFile,events);
|
||||
}
|
||||
std::string paramFile = init_params_name_toys(-1,params.reference, nBins, true, params, params.Run, false, false, genOnlySig, genOnlyBkg, false, false); //TODO: fix the naming, as you actually do take stuff from upper-mass sideband
|
||||
|
||||
save_results(paramFile,nBins,pdf_idx,tmpRes,toyParams,true,&opts);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
18
Code/FCNCFitter/sources/Run/generatetoys.hh
Normal file
18
Code/FCNCFitter/sources/Run/generatetoys.hh
Normal file
@ -0,0 +1,18 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef GENERATETOYS_H
|
||||
#define GENERATETOYS_H
|
||||
|
||||
#include <bu2kstarmumu_generator.hh>
|
||||
#include <constants.hh>
|
||||
#include <parse.hh>
|
||||
|
||||
int initialize_parameters_from_MCfit(fcnc::bu2kstarmumu_parameters *parameters, bool fromRef, int PDF, int bin, std::vector<std::string> names, basic_params params, fixConstr fixConstrain);
|
||||
int initialize_parameters_from_BkgFit(fcnc::bu2kstarmumu_parameters *parameters, bool fromRef, bool LowMassFit, bool HighMassFit, bool fitKpi, int PDF, int bin, std::vector<std::string> names, basic_params params, fixConstr fixConstrain);
|
||||
int initialize_parameters_from_MassFit(fcnc::bu2kstarmumu_parameters *parameters, bool fromRef, int PDF, int bin, std::vector<std::string> names, basic_params params, fixConstr fixConstrain);
|
||||
int initialize_B_mass(fcnc::bu2kstarmumu_parameters *parameters, bool fromRef, int PDF, int bin, basic_params params);
|
||||
|
||||
std::vector<fcnc::event> generateToys(basic_params params, int bin, int PDF, fcnc::bu2kstarmumu_parameters *toyParameters, fcnc::options opts);
|
||||
std::vector<fcnc::event> generateIndividualToys(basic_params params, int bin, int PDF, fcnc::bu2kstarmumu_parameters *toyParameters, fcnc::options opts, bool genOnlySig, bool genOnlyBkg);
|
||||
int saveToys(basic_params params, fcnc::options opts, bool genOnlySig, bool genOnlyBkg);
|
||||
#endif // GENERATETOYS_H
|
270
Code/FCNCFitter/sources/Run/genlvlfit.cc
Normal file
270
Code/FCNCFitter/sources/Run/genlvlfit.cc
Normal file
@ -0,0 +1,270 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <genlvlfit.hh>
|
||||
#include <bu2kstarmumu_pdf.hh>
|
||||
#include <fitter.hh>
|
||||
#include <folder.hh>
|
||||
#include <bu2kstarmumu_plotter.hh>
|
||||
#include <paths.hh>
|
||||
#include <event.hh>
|
||||
#include <helpers.hh>
|
||||
#include <design.hh>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
int genlvlfit(fcnc::options opts, bool fitPHSP, basic_params params){
|
||||
|
||||
//Gen Lvl always 2017
|
||||
params.Run = 2;
|
||||
params.year = 2017;
|
||||
|
||||
|
||||
//yes, it is repetition of mcfit, but it is easier this way
|
||||
|
||||
//--------------------------------
|
||||
// Set constants
|
||||
//--------------------------------
|
||||
if(fitPHSP) spdlog::info("[MCFIT]\tFit PHSP genLvl."); //reference channel only
|
||||
else spdlog::info("[MCFIT]\tFit signal genLvl MC.");//signal MC only
|
||||
|
||||
const bool Blind = false; //False as it is MC, HAS TO BE TRUE FOR DATA
|
||||
const bool UseBinnedFit = true; //Use bins in q2, if false, nBins is forced to be one
|
||||
const bool fixBMass = true; //Fix B mass to PDG value
|
||||
const bool plotPulls = true; //Do you wanna pull plots with or without pulls?
|
||||
|
||||
//Scales for the fit parameters (meaning fit-ranges)
|
||||
double PprimeRangeScale = 10.0;
|
||||
double angleRange = +1.0;
|
||||
if (params.usePprime) angleRange *= PprimeRangeScale;
|
||||
double angleStepSize = 0.05;
|
||||
|
||||
if (!UseBinnedFit){
|
||||
spdlog::info("Running an unbinned fit");
|
||||
opts.TheQ2binsmin = get_TheQ2binsmin(1,false);
|
||||
opts.TheQ2binsmax = get_TheQ2binsmax(1,false);
|
||||
}
|
||||
const unsigned int nBins = opts.get_nQ2bins(); //unsigned because vector.size is unsigned
|
||||
spdlog::debug("Using {0:d} q2 bins.", nBins);
|
||||
|
||||
//--------------------------------
|
||||
// Set all options
|
||||
//--------------------------------
|
||||
opts.use_mkpi = false;
|
||||
opts.fit_mkpi = false;
|
||||
opts.crystalball = false;
|
||||
opts.swave = false;
|
||||
opts.weighted_fit = false; //Needed to plot the weights properly
|
||||
opts.use_event_norm = false; //Used for convoluting the acceptance into pdf
|
||||
|
||||
opts.only_angles = true; //Do not fit the mass, just angles
|
||||
opts.only_Bmass = false; //Do not fit the angles, just mass
|
||||
opts.extended_ml = false;
|
||||
opts.flat_bkg = false;
|
||||
|
||||
|
||||
//TODO: possibly add polarity
|
||||
//--------------------------------
|
||||
// Load data
|
||||
//--------------------------------
|
||||
spdlog::info("[MCFIT]\tLoading data...");
|
||||
int dataset = 5; //TODO: have a function for this
|
||||
if (fitPHSP) dataset = 4;
|
||||
std::vector<fcnc::event> events= fcnc::load_events(get_theFCNCpath(dataset,2), "Events", -1);
|
||||
|
||||
UInt_t N_tot = events.size();
|
||||
if (N_tot==0){
|
||||
spdlog::error("Empty event vector!");
|
||||
return 404;
|
||||
}
|
||||
else spdlog::debug("Total number of used events:\t{0:d}", N_tot);
|
||||
|
||||
//the rest can happily be arrays as nBins and nPDFs are well defined and it is 1D
|
||||
std::vector<Int_t> fitresults;
|
||||
|
||||
//Initialize all needed things for the fit
|
||||
//current fitter, plotter, parameteres and pdfs:
|
||||
fcnc::fitter f(&opts);
|
||||
fcnc::folder fldr(&opts);
|
||||
fcnc::bu2kstarmumu_plotter * thePlotter;
|
||||
std::vector<fcnc::parameters*> theParams [nBins];
|
||||
std::vector<fcnc::pdf*> theProbs [nBins];
|
||||
std::vector<std::vector<fcnc::event>*> selection[nBins];
|
||||
|
||||
//--------------------------------
|
||||
// Read events
|
||||
//--------------------------------
|
||||
|
||||
opts.run = params.Run; //Set proper run to options //TODO: check if really needed
|
||||
spdlog::debug("Run {0:d}", opts.run);
|
||||
opts.name = get_genLvlFit_label(fitPHSP, nBins, -1, params, opts.only_angles, opts.only_Bmass);
|
||||
opts.update_angle_ranges(); //Set angles in options back to defaults
|
||||
opts.update_efficiencies = false;
|
||||
|
||||
//Set the label to MC
|
||||
opts.plot_label = "LHCb genLvl MC";
|
||||
|
||||
//Loop over bins
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
opts.q2_min = opts.TheQ2binsmin.front();
|
||||
opts.q2_max = opts.TheQ2binsmax.back();
|
||||
|
||||
//Create parameter set
|
||||
fcnc::bu2kstarmumu_parameters * leParameters = new fcnc::bu2kstarmumu_parameters(&opts);
|
||||
//create PDF
|
||||
fcnc::bu2kstarmumu_pdf * lePDF = new fcnc::bu2kstarmumu_pdf(&opts, leParameters);
|
||||
|
||||
//Initialize basic parameters
|
||||
//define center of q2bin as effective q2
|
||||
leParameters->eff_q2.init_fixed( bin_center_q2(opts,b));
|
||||
leParameters->f_sig.init_fixed(1.0);
|
||||
|
||||
if (!opts.only_angles){ //If not fitting the angles, do not init the mass parameters
|
||||
leParameters->init_mass_parameters(0,nBins,b,0.01);
|
||||
leParameters->m_b.init(PDGMASS_B_PLUS, B_MASS_LOW, B_MASS_HIGH, fixBMass ? 0.0: 1.0);
|
||||
leParameters->m_scale.init(1.0, 0.0, 2.0, 0.0);
|
||||
}
|
||||
|
||||
|
||||
//Angular observables
|
||||
leParameters->init_angular_parameters(nBins,b,angleStepSize, angleRange, false);
|
||||
|
||||
//make sure all configured values are also the start_value:
|
||||
leParameters->take_current_as_start();
|
||||
|
||||
theParams[b].push_back(leParameters);
|
||||
theProbs [b].push_back(lePDF);
|
||||
spdlog::info("Saved PDF and parameters!");
|
||||
|
||||
//create vector with events according to the requested fits/pulls
|
||||
std::vector<fcnc::event> *leEvents= new std::vector<fcnc::event>;
|
||||
|
||||
//Loop over events
|
||||
spdlog::debug("Loop over events");
|
||||
for(auto meas: events){ //WARN when more PDFs per run, this will fail!!!
|
||||
//crosscheck between mag up and mag down:
|
||||
if(params.polarity==1 && meas.magnet > 0) continue;
|
||||
if(params.polarity==-1 && meas.magnet < 0) continue;
|
||||
if(meas.q2 < opts.TheQ2binsmin.at(b) || meas.q2 > opts.TheQ2binsmax.at(b)) continue;
|
||||
if(meas.mkpi < opts.mkpi_min || meas.mkpi > opts.mkpi_max) continue;
|
||||
if(!opts.full_angular) fldr.fold(&meas);
|
||||
|
||||
leEvents->push_back(meas);
|
||||
}
|
||||
|
||||
//Update efficiencies ONCE
|
||||
lePDF->update_cached_normalization(leParameters);
|
||||
lePDF->update_cached_efficiencies(leParameters, leEvents);
|
||||
|
||||
spdlog::info("Finished selecting the events: {0:d}",leEvents->size());
|
||||
|
||||
//save event vector in vector
|
||||
selection[b].push_back(leEvents);
|
||||
if ((selection[b]).at(0)->size() > 0){
|
||||
spdlog::info("[BIN{0:d}]\tDone!", b);
|
||||
}
|
||||
else{
|
||||
spdlog::critical("No events found for q2-bin={0:d}. Exit!",b);
|
||||
assert(0);
|
||||
}
|
||||
} //End loop over bins
|
||||
|
||||
//Allocate the plotter
|
||||
thePlotter = new fcnc::bu2kstarmumu_plotter(&opts);
|
||||
|
||||
|
||||
//--------------------------------
|
||||
// FIT
|
||||
//--------------------------------
|
||||
spdlog::info("[MCFIT]\tMC fit started.");
|
||||
|
||||
//Measure the time for the fit:
|
||||
runTime timer = runTime();
|
||||
|
||||
//Save the fit results
|
||||
std::vector<int> fit_results[nBins];
|
||||
std::vector<double> f_sigs[nBins];
|
||||
std::vector<double> f_sigserr[nBins];
|
||||
std::vector<UInt_t> evts_cntr[nBins];
|
||||
std::vector<fcnc::parameters*> vecParams;
|
||||
|
||||
//fit all bins:
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
|
||||
//Start the clock
|
||||
timer.start();
|
||||
time_t startTime = time(0);
|
||||
|
||||
spdlog::info("[START]\tStart the fit for bin #{0:d}", b);
|
||||
|
||||
//Int for fit status
|
||||
int fitresult = 0;
|
||||
|
||||
//Delete the texFile
|
||||
std::string tag = get_genLvlFit_label(fitPHSP, nBins, b, params,
|
||||
opts.only_angles, opts.only_Bmass);
|
||||
clear_Latex_noteFile(latex_fitterFile(tag));
|
||||
|
||||
spdlog::info("Running the fitter...");
|
||||
fitresult = f.fit(theProbs[b].at(0), theParams[b].at(0), selection[b].at(0),tag);
|
||||
fit_results[b].push_back(fitresult);
|
||||
|
||||
|
||||
//Stop the clock
|
||||
timer.stop(startTime);
|
||||
|
||||
//Print the fit results
|
||||
spdlog::info("[BIN{0:d}]:\tFitresult: {1:d}", b, fitresult);
|
||||
|
||||
//save signal fraction and event number for each bin and each pdf:
|
||||
f_sigs[b].push_back( ((fcnc::bu2kstarmumu_parameters *) theParams[b].at(0))->f_sig.get_value());
|
||||
f_sigserr[b].push_back( ((fcnc::bu2kstarmumu_parameters *) theParams[b].at(0))->f_sig.get_error());
|
||||
evts_cntr[b].push_back((selection[b]).at(0)->size());
|
||||
opts.q2_label = q2_label(opts.TheQ2binsmin.at(b), opts.TheQ2binsmax.at(b));
|
||||
if (!plotPulls) tag = tag+"_noPulls";
|
||||
|
||||
|
||||
std::vector<fcnc::bu2kstarmumu_pdf*> * prober = (std::vector<fcnc::bu2kstarmumu_pdf*> *) & theProbs[b];
|
||||
std::vector<fcnc::bu2kstarmumu_parameters*> * paramser = (std::vector<fcnc::bu2kstarmumu_parameters*> *) & theParams[b];
|
||||
thePlotter->SetPulls(plotPulls);
|
||||
|
||||
thePlotter->plot_added_pdfs(prober, paramser, &selection[b],
|
||||
get_genLvlFitPlot_path(fitPHSP),tag, false);
|
||||
|
||||
} //end bin loop
|
||||
|
||||
|
||||
//--------------------------------
|
||||
// Print & Save
|
||||
//--------------------------------
|
||||
|
||||
//Print running time
|
||||
timer.print(nBins);
|
||||
|
||||
//Print all fit results
|
||||
print_all_parameters(nBins, {0}, theParams, spdlog::level::debug);
|
||||
|
||||
//Save the fit results
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
std::vector<fcnc::bu2kstarmumu_parameters*> * paramser = (std::vector<fcnc::bu2kstarmumu_parameters*> *) & theParams[b];
|
||||
paramser->at(0)->save_param_values(finalResult_genLvlMCfit_txt(fitPHSP, nBins, b, params, opts.only_angles, opts.only_Bmass));
|
||||
}
|
||||
|
||||
//Print signal yield in the terminal and to a tex file
|
||||
if (!Blind) print_sig_yields(nBins, {0}, evts_cntr, f_sigs, f_sigserr);
|
||||
|
||||
print_sig_yields_tex(get_genLvlFit_label(fitPHSP, nBins, -1, params,
|
||||
opts.only_angles, opts.only_Bmass),
|
||||
nBins, {0}, &opts, evts_cntr, f_sigs, f_sigserr);
|
||||
|
||||
|
||||
//Save results to root file
|
||||
|
||||
std::string results_file = final_result_name_genLvlMC(params, nBins, fitPHSP, opts.only_angles, opts.only_Bmass);
|
||||
save_results(results_file, nBins, {0}, fit_results, theParams, false, &opts);
|
||||
|
||||
spdlog::info("[MCFIT]\tMC fit finished.");
|
||||
return 0;
|
||||
|
||||
}
|
10
Code/FCNCFitter/sources/Run/genlvlfit.hh
Normal file
10
Code/FCNCFitter/sources/Run/genlvlfit.hh
Normal file
@ -0,0 +1,10 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef GENLVLFIT_HH
|
||||
#define GENLVLFIT_HH
|
||||
|
||||
#include <parse.hh>
|
||||
#include <options.hh>
|
||||
|
||||
int genlvlfit(fcnc::options opts, bool fitPHSP, basic_params params);
|
||||
#endif // GENLVLFIT_HH
|
268
Code/FCNCFitter/sources/Run/likelihoodscan.cc
Normal file
268
Code/FCNCFitter/sources/Run/likelihoodscan.cc
Normal file
@ -0,0 +1,268 @@
|
||||
/**
|
||||
* @file likelihoodscan.hh
|
||||
* @author Christoph Langenbruch Renata Kopecna
|
||||
* @date 2020-01-12
|
||||
*
|
||||
*/
|
||||
|
||||
//TODO: remove unused stuff
|
||||
#include <likelihoodscan.hh>
|
||||
#include <iostream>
|
||||
#include <TMinuit.h>
|
||||
#include <TTree.h>
|
||||
#include <TRandom3.h>
|
||||
#include <complex>
|
||||
#include <assert.h>
|
||||
#include <event.hh>
|
||||
#include <parameters.hh>
|
||||
#include <funcs.hh>
|
||||
#include <pdf.hh>
|
||||
#include <plotter.hh>
|
||||
#include <options.hh>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <TMatrix.h>
|
||||
#include <TH1D.h>
|
||||
#include <TCanvas.h>
|
||||
#include <TROOT.h>
|
||||
#include <TStyle.h>
|
||||
#include <TVector.h>
|
||||
#include <TMatrixD.h>
|
||||
#include <TMatrixDSym.h>
|
||||
#include <TMatrixTSym.h>
|
||||
#include <TMatrixT.h>
|
||||
#include <TFile.h>
|
||||
#include <TDecompChol.h>
|
||||
|
||||
#include <fitter.hh>
|
||||
#include <spdlog.h>
|
||||
|
||||
|
||||
bool fcnc::likelihoodscan::scan_1d(std::string parname, unsigned int nsteps, double parmin, double parmax,
|
||||
std::vector<pdf*> probs, std::vector<parameters*> params,
|
||||
std::vector<std::vector<event> *> events, std::vector<std::string> common_par,
|
||||
unsigned int bin, int from, int to){
|
||||
spdlog::info("Likelihood scan study for parameter "+parname);
|
||||
bool cache_minos = opts->minos_errors;
|
||||
bool cache_hesse = opts->hesse_postrun;
|
||||
bool cache_hesse2 = opts->squared_hesse;
|
||||
bool cache_shift = opts->shift_lh;
|
||||
//int cache_print = spdlog::default_logger_raw()->level();
|
||||
|
||||
parameter* par = params.at(0)->get_parameter(parname);
|
||||
double cache_value = par->get_start_value();
|
||||
double cache_step_size = par->get_start_value();
|
||||
if (par != 0){
|
||||
opts->minos_errors = false;
|
||||
opts->hesse_postrun = false;
|
||||
opts->squared_hesse = false;
|
||||
opts->shift_lh = false;
|
||||
|
||||
fitter f(opts);
|
||||
if(common_par.size() > 0) f.set_common_parameters(common_par);
|
||||
|
||||
f.fit(probs, params, events);
|
||||
double lhdatafloated = f.likelihood();
|
||||
spdlog::info("Data fit finished with -2logLh = {0:f}", lhdatafloated);
|
||||
|
||||
if (from < 0) from = 0;
|
||||
if (to > int(nsteps) || to < 0) to = int(nsteps);
|
||||
|
||||
std::vector<double> lhdatafixed(to-from, 0.0);
|
||||
std::vector<double> statusdatafixed(to-from, 0.0);
|
||||
|
||||
std::string pardesc = par->get_description();
|
||||
for (int j=from; j<to; j++){
|
||||
double parcur = parmin+(j+0.5)*(parmax-parmin)/nsteps;
|
||||
spdlog::info("Studying point " + parname + "={0:f}", parcur);
|
||||
for(unsigned int p=0; p<params.size(); p++){
|
||||
params.at(p)->reset_parameters();
|
||||
params.at(p)->get_parameter(parname)->init(parcur, parmin, parmax, 0.0);
|
||||
}
|
||||
statusdatafixed.at(j-from) = f.fit(probs, params, events);
|
||||
lhdatafixed.at(j-from) = f.likelihood();
|
||||
}
|
||||
//reactivate parameter for consecutive llh scans:
|
||||
for(unsigned int p=0; p<params.size(); p++){
|
||||
params.at(p)->get_parameter(parname)->init(cache_value, parmin, parmax, cache_step_size);
|
||||
}
|
||||
|
||||
//save to root file
|
||||
std::ostringstream sout;
|
||||
sout << "llhscan_results_" << (opts->full_angular ? "full_angular" : "folding"+std::to_string(opts->folding)) << "_bin" << bin << ".root"; //TODO names
|
||||
|
||||
TFile* fout = new TFile(sout.str().c_str(), "UPDATE");
|
||||
fout->cd();
|
||||
TTree* t = new TTree(parname.c_str(), pardesc.c_str());
|
||||
int step=0, statusdfixed=0;
|
||||
double value=0.0, lhdfloated=lhdatafloated, lhdfixed=0.0;
|
||||
t->Branch("bin",&bin,"bin/I");
|
||||
t->Branch("step",&step,"step/I");
|
||||
t->Branch("value",&value,"value/D");
|
||||
t->Branch("statusdatafixed",&statusdfixed,"statusdatafixed/I");
|
||||
t->Branch("lhdatafloated",&lhdfloated,"lhdatafloated/D");
|
||||
t->Branch("lhdatafixed",&lhdfixed,"lhdatafixed/D");
|
||||
for (int j=from; j<to; j++){
|
||||
step = j;
|
||||
value = parmin+(j+0.5)*(parmax-parmin)/nsteps;
|
||||
statusdfixed = statusdatafixed.at(j-from);
|
||||
lhdfixed = lhdatafixed.at(j-from);
|
||||
lhdfloated = lhdatafloated;
|
||||
t->Fill();
|
||||
}
|
||||
t->Write("",TObject::kWriteDelete);
|
||||
fout->Write();
|
||||
fout->Close();
|
||||
delete fout;
|
||||
}
|
||||
else{
|
||||
spdlog::critical("Could not find parameter "+parname);
|
||||
assert(0);
|
||||
}
|
||||
spdlog::info("Finished likelihood scan for parameter "+parname);
|
||||
opts->hesse_postrun = cache_hesse;
|
||||
opts->squared_hesse = cache_hesse2;
|
||||
opts->minos_errors = cache_minos;
|
||||
opts->shift_lh = cache_shift;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fcnc::likelihoodscan::scan_1d(std::string parname, unsigned int nsteps,
|
||||
double parmin, double parmax,
|
||||
pdf* prob, parameters* params,
|
||||
std::vector<event> * events,
|
||||
unsigned int bin, int from, int to){
|
||||
std::vector<pdf *> the_probs;
|
||||
the_probs.push_back(prob);
|
||||
|
||||
std::vector<parameters *> the_params;
|
||||
the_params.push_back(params);
|
||||
|
||||
std::vector<std::vector<event>* > the_events;
|
||||
the_events.push_back(events);
|
||||
|
||||
std::vector<std::string> common_par;
|
||||
common_par.clear();
|
||||
|
||||
return scan_1d(parname, nsteps, parmin, parmax, the_probs, the_params, the_events, common_par, bin, from, to);
|
||||
}
|
||||
|
||||
|
||||
bool fcnc::likelihoodscan::scan_2d(std::string parxname, unsigned int nstepsx, double parxmin, double parxmax,
|
||||
std::string paryname, unsigned int nstepsy, double parymin, double parymax,
|
||||
std::vector<pdf*> probs, std::vector<parameters*> params,
|
||||
std::vector<std::vector<event> *> events, std::vector<std::string> common_par,
|
||||
unsigned int bin, int from, int to){
|
||||
spdlog::info("Likelihood scan study for parameters "+parxname+", "+paryname);
|
||||
bool cache_minos = opts->minos_errors;
|
||||
bool cache_hesse = opts->hesse_postrun;
|
||||
bool cache_hesse2 = opts->squared_hesse;
|
||||
bool cache_shift = opts->shift_lh;
|
||||
//int cache_print = spdlog::default_logger_raw()->level();
|
||||
|
||||
parameter* parx = params.at(0)->get_parameter(parxname);
|
||||
parameter* pary = params.at(0)->get_parameter(paryname);
|
||||
if (parx != 0 && pary != 0){
|
||||
opts->minos_errors = false;
|
||||
opts->hesse_postrun = false;
|
||||
opts->squared_hesse = false;
|
||||
opts->shift_lh = false;
|
||||
|
||||
fitter f(opts);
|
||||
if(common_par.size() > 0) f.set_common_parameters(common_par);
|
||||
|
||||
f.fit(probs, params, events);
|
||||
double lhdatafloated = f.likelihood();
|
||||
spdlog::info("Data fit finished with -2logLh = {0:f}", lhdatafloated);
|
||||
|
||||
if (from < 0) from = 0;
|
||||
if (to > int(nstepsx*nstepsy) || to < 0) to = nstepsx*nstepsy;
|
||||
|
||||
std::vector<double> lhdatafixed(to-from, 0.0);
|
||||
std::vector<int > statusdatafixed(to-from, 0.0);
|
||||
|
||||
std::string parxdesc = parx->get_description();
|
||||
std::string parydesc = pary->get_description();
|
||||
for (int j=from; j<to; j++){
|
||||
double parxcur = parxmin+((j%nstepsx)+0.5)*(parxmax-parxmin)/nstepsx;
|
||||
double parycur = parymin+((j/nstepsx)+0.5)*(parymax-parymin)/nstepsy;
|
||||
|
||||
spdlog::info("Studying point {0:s}={1:f}, {2:s}={3:f} idx={4:d}", parxname, parxcur, paryname,parycur, j);
|
||||
for(unsigned int p = 0; p < params.size(); p++){
|
||||
params.at(p)->reset_parameters();
|
||||
params.at(p)->get_parameter(parxname)->init(parxcur, parxmin, parxmax, 0.0);
|
||||
params.at(p)->get_parameter(paryname)->init(parycur, parymin, parymax, 0.0);
|
||||
}
|
||||
|
||||
statusdatafixed.at(j-from) = f.fit(probs, params, events);
|
||||
lhdatafixed.at(j-from) = f.likelihood();
|
||||
}
|
||||
|
||||
//save to root file
|
||||
std::ostringstream sout;
|
||||
sout << "llh2Dscan_results_" << (opts->full_angular ? "full_angular" : "folding"+std::to_string(opts->folding)) << "_bin" << bin << ".root"; //TODO: name
|
||||
TFile* fout = new TFile(sout.str().c_str(), "RECREATE");
|
||||
fout->cd();
|
||||
TTree* t = new TTree((parxname+std::string("_")+paryname).c_str(), (std::string(";")+parxdesc+std::string(";")+parydesc).c_str());
|
||||
int step=0, stepx=0, stepy=0, statusdfixed=0;
|
||||
double valuex=0.0, valuey, lhdfloated=lhdatafloated, lhdfixed=0.0;
|
||||
t->Branch("bin",&bin,"bin/I");
|
||||
t->Branch("step",&step,"step/I");
|
||||
t->Branch("stepx",&stepx,"stepx/I");
|
||||
t->Branch("stepy",&stepy,"stepy/I");
|
||||
t->Branch("valuex",&valuex,"valuex/D");
|
||||
t->Branch("valuey",&valuey,"valuey/D");
|
||||
t->Branch("statusdatafixed",&statusdfixed,"statusdatafixed/I");
|
||||
t->Branch("lhdatafloated",&lhdfloated,"lhdatafloated/D");
|
||||
t->Branch("lhdatafixed",&lhdfixed,"lhdatafixed/D");
|
||||
for (int j=from; j<to; j++){
|
||||
step = j;
|
||||
stepx = j%nstepsx;
|
||||
stepy = j/nstepsx;
|
||||
valuex = parxmin+((j%nstepsx)+0.5)*(parxmax-parxmin)/nstepsx;
|
||||
valuey = parymin+((j/nstepsx)+0.5)*(parymax-parymin)/nstepsy;
|
||||
lhdfixed = lhdatafixed.at(j-from);
|
||||
statusdfixed = statusdatafixed.at(j-from);
|
||||
lhdfloated = lhdatafloated;
|
||||
t->Fill();
|
||||
}
|
||||
t->Write();
|
||||
fout->Write();
|
||||
fout->Close();
|
||||
delete fout;
|
||||
}
|
||||
else{
|
||||
if (parx == 0) spdlog::info("Could not find parameter "+parxname);
|
||||
if (pary == 0) spdlog::info("Could not find parameter "+paryname);
|
||||
assert(0);
|
||||
}
|
||||
spdlog::info("Finished likelihood scan for parameters "+parxname+", "+paryname);
|
||||
opts->hesse_postrun = cache_hesse;
|
||||
opts->squared_hesse = cache_hesse2;
|
||||
opts->minos_errors = cache_minos;
|
||||
opts->shift_lh = cache_shift;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fcnc::likelihoodscan::scan_2d(std::string parxname, unsigned int nstepsx, double parxmin, double parxmax,
|
||||
std::string paryname, unsigned int nstepsy, double parymin, double parymax,
|
||||
pdf* prob, parameters* params,
|
||||
std::vector<event> * events, unsigned int bin, int from, int to){
|
||||
|
||||
std::vector<pdf *> the_probs;
|
||||
the_probs.push_back(prob);
|
||||
|
||||
std::vector<parameters *> the_params;
|
||||
the_params.push_back(params);
|
||||
|
||||
std::vector<std::vector<event>* > the_events;
|
||||
the_events.push_back(events);
|
||||
|
||||
std::vector<std::string> common_par;
|
||||
common_par.clear();
|
||||
|
||||
return scan_2d(parxname, nstepsx, parxmin, parxmax,
|
||||
paryname, nstepsy, parymin, parymax,
|
||||
the_probs, the_params, the_events, common_par, bin, from, to);
|
||||
}
|
||||
|
60
Code/FCNCFitter/sources/Run/likelihoodscan.hh
Normal file
60
Code/FCNCFitter/sources/Run/likelihoodscan.hh
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file likelihoodscan.hh
|
||||
* @author Christoph Langenbruch Renata Kopecna
|
||||
* @date 2020-01-12
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIKELIHOODSCAN_H
|
||||
#define LIKELIHOODSCAN_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace fcnc {
|
||||
//Forward decalrations
|
||||
class parameters;
|
||||
class pdf;
|
||||
class event;
|
||||
class options;
|
||||
|
||||
class likelihoodscan;
|
||||
|
||||
class likelihoodscan {
|
||||
private:
|
||||
options* opts;
|
||||
int from, to;
|
||||
public:
|
||||
///constructor
|
||||
likelihoodscan(options* o):
|
||||
opts(o),
|
||||
from(-1),
|
||||
to(-1)
|
||||
{};
|
||||
///destructor
|
||||
~likelihoodscan(){};
|
||||
|
||||
///one-dimensional likelihoodscan
|
||||
bool scan_1d(std::string parname, unsigned int nsteps, double parmin, double parmax,
|
||||
std::vector<pdf*> probs, std::vector<parameters*> params,
|
||||
std::vector<std::vector<event> *> events, std::vector<std::string> common_par,
|
||||
unsigned int bin=0, int from=-1, int to=-1);
|
||||
bool scan_1d(std::string parname, unsigned int nsteps, double parmin, double parmax,
|
||||
pdf* prob, parameters* params, std::vector<event> * events,
|
||||
unsigned int bin=0, int from=-1, int to=-1);
|
||||
|
||||
///two-dimensional likelihood scan
|
||||
bool scan_2d(std::string parxname, unsigned int nstepsx, double parxmin, double parxmax,
|
||||
std::string paryname, unsigned int nstepsy, double parymin, double parymax,
|
||||
std::vector<pdf*> probs, std::vector<parameters*> params,
|
||||
std::vector<std::vector<event> *> events, std::vector<std::string> common_par,
|
||||
unsigned int bin=0, int from=-1, int to=-1);
|
||||
bool scan_2d(std::string parxname, unsigned int nstepsx, double parxmin, double parxmax,
|
||||
std::string paryname, unsigned int nstepsy, double parymin, double parymax,
|
||||
pdf* prob, parameters* params, std::vector<event> * events,
|
||||
unsigned int bin=0, int from=-1, int to=-1);
|
||||
};
|
||||
|
||||
}//end namespace
|
||||
|
||||
#endif
|
521
Code/FCNCFitter/sources/Run/mainfit.cc
Normal file
521
Code/FCNCFitter/sources/Run/mainfit.cc
Normal file
@ -0,0 +1,521 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <mainfit.hh>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream> // std::istringstream
|
||||
|
||||
#include <event.hh>
|
||||
#include <fitter.hh>
|
||||
#include <folder.hh>
|
||||
#include <paths.hh>
|
||||
#include <funcs.hh>
|
||||
#include <design.hh>
|
||||
#include <helpers.hh>
|
||||
#include <constants.hh>
|
||||
|
||||
#include <bu2kstarmumu_generator.hh>
|
||||
#include <bu2kstarmumu_plotter.hh>
|
||||
#include <bu2kstarmumu_parameters.hh>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
#include <TStyle.h>
|
||||
|
||||
int mainfit(fcnc::options opts, basic_params params, bool fitReference, bool fitToy, bool likelihoodScan, bool FeldmanCousin){
|
||||
|
||||
//TODO
|
||||
bool fitData = !fitToy;
|
||||
//TODO: add a test where I cna try this on a toy file
|
||||
|
||||
if(fitData) spdlog::info("[FIT]\tFit signal data"); //signal data << FINAL FIT!!
|
||||
if(fitReference)spdlog::info("[FIT]\tFit reference channel: J/psi K*+"); //reference channel only
|
||||
|
||||
//--------------------------------
|
||||
// Set all the options
|
||||
//--------------------------------
|
||||
|
||||
//TODO: declare maybe in the header or elsewhere
|
||||
const bool UseBinnedFit = !fitReference;
|
||||
const bool SimultaneousFit = true;
|
||||
const bool FixAngularBckgnd = false; //Fix the background to the shape of the upper mass sideband
|
||||
const bool constrainBmass = false;
|
||||
const bool FixedSwave = !fitReference; //TODO
|
||||
const bool ConstrainedSwave = false; //TODO
|
||||
const bool ConstrainedFS = false; //TODO
|
||||
|
||||
const bool LoadFSfrom2Dfit = !fitReference && !(opts.systematic > -1);
|
||||
//const bool JpsiWithRareStats = false; //Try to fit the Jpsi fit with only a subsample of events //TODO
|
||||
const double fractionOfStats = 1.0; //Use only a fraction of statistics, eg for half set this to 0.5
|
||||
|
||||
//TODO: set the fraction of stats accordingly if JpsiWithRareStats; will make my life easier
|
||||
|
||||
const bool NP = false; //TODO
|
||||
const bool Blind = fitData && !fitReference;
|
||||
|
||||
const bool plotPulls = true; //Do you wanna pull plots with or without pulls?
|
||||
bool plotSignalRegion = fitReference; //Plot only the region around B mass, makes nicer plots
|
||||
|
||||
const unsigned int nBins = UseBinnedFit ? opts.get_nQ2bins() : 1;
|
||||
|
||||
if (fitToy && params.polarity!= 0){
|
||||
spdlog::warn("Your polarity is not set to both ofr whatever reason when fitting a toy!");
|
||||
spdlog::warn("Setting the polarity to 0!");
|
||||
params.polarity = 0;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
if((int)ConstrainedSwave + (int) ConstrainedFS + (int) LoadFSfrom2Dfit > 1){
|
||||
//If at least two of those, then crash
|
||||
spdlog::error("Use only one option to constrain FS:");
|
||||
spdlog::error("Constrained sWave" + boolToString(ConstrainedSwave));
|
||||
spdlog::error("Constrained FS" + boolToString(ConstrainedFS));
|
||||
spdlog::error("Load FS from 2D fit" + boolToString(LoadFSfrom2Dfit));
|
||||
assert(0);
|
||||
}
|
||||
|
||||
opts.fit_full_angular_bkg = true; //fold also the bkg?
|
||||
opts.individual_penalties = false;
|
||||
|
||||
//If blinded, don't plot anything
|
||||
opts.write_eps = !Blind;
|
||||
opts.write_pdf = false;
|
||||
opts.write_C = false;
|
||||
|
||||
//Fit both angles and mass
|
||||
opts.only_angles = false;
|
||||
opts.only_Bmass = false;
|
||||
|
||||
//Fit swave?
|
||||
opts.swave = true;
|
||||
|
||||
//Use weights
|
||||
opts.weighted_fit = true;
|
||||
|
||||
//What framework?
|
||||
opts.shift_lh = false;
|
||||
opts.hesse_postrun = true;
|
||||
opts.squared_hesse = true;//params.folding>-1;
|
||||
opts.minos_errors = false;// params.folding==-1;
|
||||
|
||||
//Flat background?
|
||||
opts.flat_bkg = false;
|
||||
//What order of bkg
|
||||
opts.bkg_order_costhetak = 5;
|
||||
|
||||
opts.fit_mkpi = true; //Use fit to Kpi mass?
|
||||
opts.use_mkpi = false; //Do the 5D fit? //TODO: probably doesn't work now
|
||||
opts.simple_mkpi = false;
|
||||
opts.isobar = false;
|
||||
opts.asymptotic = false; //Use the improved hesse calculation?
|
||||
|
||||
//Check that sWave is on when fitting Kpi mass
|
||||
assert(!(opts.fit_mkpi && !opts.swave));
|
||||
assert(!(opts.use_mkpi && !opts.swave));
|
||||
|
||||
//Use angular acceptance corrections
|
||||
opts.update_efficiencies = true;
|
||||
|
||||
//generate nametag for root file to save results:
|
||||
std::string results_file = final_result_name(fitReference, false, params,
|
||||
SimultaneousFit, nBins, params.Run,
|
||||
fitToy, fractionOfStats,
|
||||
NP, -1); //FitOnlyRun is not reflected in opts here TODO
|
||||
|
||||
|
||||
//Set the available PDFs: this depends on the selected Run for now, so if only one is selected, run over one pdf, if both, use two
|
||||
std::vector<UInt_t> pdf_idx;
|
||||
if (params.Run == 1 || params.Run == 12) pdf_idx.push_back(1);
|
||||
if (params.Run == 2 || params.Run == 12) pdf_idx.push_back(2);
|
||||
|
||||
//--------------------------------
|
||||
// Load data
|
||||
//--------------------------------
|
||||
spdlog::info("[FIT]\tLoading data...");
|
||||
std::vector<std::vector<fcnc::event>>events;
|
||||
|
||||
if(fitToy){
|
||||
events.push_back(fcnc::load_events(get_finalToys_file(fitReference,nBins, SimultaneousFit, params,1),"Events", -1)); //Run1
|
||||
events.push_back(fcnc::load_events(get_finalToys_file(fitReference,nBins, SimultaneousFit, params,2),"Events", -1)); //Run2
|
||||
}
|
||||
else{
|
||||
std::vector<fcnc::event> tmp = fcnc::load_events(get_theFCNCpath(0,1), "Events", -1); //Run1
|
||||
if (!fitReference) events.push_back(fcnc::filterResonances(tmp));
|
||||
else events.push_back(tmp);
|
||||
tmp = fcnc::load_events(get_theFCNCpath(0,2), "Events", -1); //Run2
|
||||
if (!fitReference) events.push_back(fcnc::filterResonances(tmp));
|
||||
else events.push_back(tmp);
|
||||
}
|
||||
|
||||
//check that the number of pdfs is the same as number of event vectors
|
||||
if (pdf_idx.size() != events.size()){
|
||||
spdlog::error("Something went very wrong when loading the events and setting the pdfs.");
|
||||
spdlog::error("The number of PDFs != number of event vectors: {0:d} vs {1:d}",pdf_idx.size(), events.size());
|
||||
return 5;
|
||||
}
|
||||
|
||||
//we are good to go, now; how many individual pdfs are used?
|
||||
const UInt_t nPDFs = pdf_idx.size();
|
||||
|
||||
//Control print of the loaded events
|
||||
UInt_t N_tot = 0;
|
||||
for (UInt_t n = 0; n < nPDFs; n++){
|
||||
spdlog::debug("Event vector {0:d}:\t"+(Blind?"Larger 1 ":std::to_string(events.at(n).size())),n);
|
||||
if (events.at(n).size()==0){
|
||||
spdlog::error("Empty event vector!");
|
||||
return 404;
|
||||
}
|
||||
N_tot += events.at(n).size();
|
||||
}
|
||||
spdlog::info("Total number of used events:\t{0:d}", N_tot);
|
||||
|
||||
//Set fit ranges //TODO: just move it to init angle parameters
|
||||
double angleRange = 1.0;
|
||||
double PprimeRangeScale = 10.0;
|
||||
if (params.usePprime) angleRange *= PprimeRangeScale;
|
||||
double angleStepSize = 0.1;
|
||||
|
||||
//get signal fractions and event numbers
|
||||
//TODO: fix this when you know whether we need the eventNumbers here specifically
|
||||
double sig_frac[nBins];
|
||||
|
||||
unsigned int event_numbers[nBins][nPDFs];
|
||||
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
for(unsigned int n = 0; n < nPDFs; n++){
|
||||
//get event numbers and signal fraction from global function, given the total number of events
|
||||
//TODO: check what to do with JpsiWithRareStats
|
||||
EventNumbers(b, n, sig_frac[b], event_numbers[b][n], N_tot, nBins, nPDFs);
|
||||
event_numbers[b][n] *= fractionOfStats;
|
||||
}
|
||||
}
|
||||
|
||||
//Control print
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
for(unsigned int n = 0; n < nPDFs; n++){
|
||||
spdlog::debug("q2bin={0:d}\tPDF={1:d}\tf_sig={2:f}\tN={3:d}", b, n, sig_frac[b], event_numbers[b][n]);
|
||||
}
|
||||
}
|
||||
|
||||
//create the fitter, plotter, parameteres and pdfs
|
||||
fcnc::fitter f(&opts);
|
||||
fcnc::folder fldr(&opts);
|
||||
fcnc::options theOptions[nPDFs];
|
||||
fcnc::bu2kstarmumu_plotter * thePlotter[nPDFs];
|
||||
std::vector<fcnc::parameters*> theParams [nBins];
|
||||
std::vector<fcnc::pdf*> theProbs [nBins];
|
||||
std::vector< std::vector<fcnc::event>* > selection[nBins];
|
||||
|
||||
//these parameters are common:
|
||||
std::vector<std::string> common_params = param_string(opts, false); //set MC to true to avoid background there
|
||||
spdlog::info("Shared parameters: " + convert_vector_to_string(common_params));
|
||||
//set common parameters:
|
||||
if(SimultaneousFit) f.set_common_parameters(common_params);
|
||||
|
||||
//Get the name of files needed for constraining
|
||||
std::string signalMCFile = final_result_name_MC(params, nBins, false, false, SimultaneousFit, false, false);
|
||||
std::string refrenceMCFile = final_result_name_MC(params, 1, true, false, SimultaneousFit, false, true);
|
||||
bool takeAngBkgFromRef = true;
|
||||
std::string upperMassBkgFile = final_result_name_bkg(takeAngBkgFromRef ? 1 : nBins, takeAngBkgFromRef, false, true, false, params);
|
||||
std::string upperMassKpiBkgFile = final_result_name_bkg(takeAngBkgFromRef ? 1 : nBins, takeAngBkgFromRef, false, true, true, params);
|
||||
std::string RefMassFile = final_result_name_mass(true,1,true,params,params.Run);
|
||||
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
spdlog::debug("PDF {0:d}", n);
|
||||
UInt_t idx = pdf_idx.at(n);
|
||||
opts.update_angle_ranges(); //Set angles in options back to defaults
|
||||
opts.update_efficiencies = true; //This ensures the acceptance weights to be taken into account.
|
||||
//Set the label
|
||||
if (fitToy) opts.plot_label = "Toy sample";
|
||||
else opts.plot_label = "LHCb data";
|
||||
opts.name = std::to_string(idx+1) + "_"+ get_eps_label(fitReference,false,false,fitToy, nBins, -1,-SimultaneousFit,params); //TODO: FIX THIS!!!
|
||||
|
||||
//Set the options and init the plotter
|
||||
theOptions[n] = opts;
|
||||
theOptions[n].run = pdf_idx.at(n); //Set proper run to options
|
||||
thePlotter[n] = new fcnc::bu2kstarmumu_plotter(&theOptions[n]);
|
||||
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
theOptions[n].q2_min = theOptions[n].TheQ2binsmin.at(b) ;
|
||||
theOptions[n].q2_max = theOptions[n].TheQ2binsmax.at(b);
|
||||
|
||||
//create parameter sets
|
||||
fcnc::bu2kstarmumu_parameters * leParameters = new fcnc::bu2kstarmumu_parameters(&theOptions[n]);
|
||||
|
||||
//create PDFs
|
||||
fcnc::bu2kstarmumu_pdf * lePDF = new fcnc::bu2kstarmumu_pdf(&theOptions[n], leParameters);
|
||||
|
||||
//define center of q2bin as effective q2 by hand
|
||||
leParameters->eff_q2.init_fixed(bin_center_q2(theOptions[n],b));
|
||||
|
||||
//Init mass
|
||||
std::string fileName_dataMass = final_result_name_mass(true, 1, true, params, params.Run);
|
||||
leParameters->init_Bmass(fileName_dataMass,pdf_idx.at(n),0.5,fixConstr(false,constrainBmass));
|
||||
|
||||
|
||||
//initiate the sig/bkg fraction for mass fit
|
||||
leParameters->f_sig.init(fitReference ? 0.8 : 0.3, 0.0, 1.0, 0.05);
|
||||
|
||||
//Init mass parameters
|
||||
leParameters->init_mass_parameters(n,nBins,b,0.01);
|
||||
leParameters->fix_param_from_rootfile(fitReference ? refrenceMCFile : signalMCFile,
|
||||
{"alpha_1","alpha_2","n_1","n_2"}, idx, b);
|
||||
//Fix the mass mean to the one from reference channel
|
||||
if (!fitReference) leParameters->init_Bmass(RefMassFile, pdf_idx.at(n), 0.0, fixConstr(true,false));
|
||||
|
||||
//Init the ratio of sigmas in signal MC/reference MC
|
||||
if (!fitReference) leParameters->m_scale.init_fixed(get_sigmaRatio_fromMC(params,nBins,b,pdf_idx.at(n)));
|
||||
else leParameters->m_scale.init_fixed(1.0);
|
||||
|
||||
//Init mass background
|
||||
leParameters->init_mass_background_parameters(nBins,b,opts.fit_lambda);
|
||||
|
||||
//(de)activate S-wave
|
||||
double swaveStepSize = opts.swave && !FixedSwave ? 0.1 : 0.0;
|
||||
|
||||
//Init the Kstar mass fit
|
||||
if(opts.fit_mkpi || opts.use_mkpi){
|
||||
//p-wave
|
||||
leParameters->init_mkpi_pWave_parameters(fitReference,0.0);
|
||||
leParameters->init_kpi_background_parameters(fitReference,0.05);
|
||||
//s-wave
|
||||
if (opts.swave) leParameters->init_mkpi_sWave_parameters(fitReference, 0.0);
|
||||
}
|
||||
|
||||
//Init the sWave
|
||||
if (opts.swave){
|
||||
leParameters->init_sWave_parameters(swaveStepSize);
|
||||
leParameters->get_param_from_rootfile(RefMassFile, {"FS"}, idx, b,fixConstr(!fitReference,ConstrainedFS));
|
||||
}
|
||||
|
||||
//Add angular parameters
|
||||
leParameters->init_angular_parameters(nBins,b,angleStepSize,angleRange, Blind);
|
||||
|
||||
//Add background to angular observables
|
||||
|
||||
if(!theOptions[n].flat_bkg){ //If bkg not flat, init based on upper mass sideband fit
|
||||
leParameters->get_param_from_rootfile(upperMassBkgFile,
|
||||
PAR_BKG_STRING(opts.folding,opts.bkg_order_costhetal,opts.bkg_order_costhetak),
|
||||
params.Run,b,fixConstr(FixAngularBckgnd,false));
|
||||
if (params.folding ==4){
|
||||
leParameters->cbkgctk2.init(-1.75,-3.0,1.5,0.05);
|
||||
leParameters->cbkgctk4.init(-1.75,-3.0,1.5,0.05);
|
||||
}
|
||||
}
|
||||
|
||||
//make sure all configured values are also the start_value:
|
||||
leParameters->take_current_as_start();
|
||||
|
||||
//Add the parameters and the pdf into the vectors
|
||||
theParams[b].push_back(leParameters);
|
||||
theProbs [b].push_back(lePDF);
|
||||
|
||||
spdlog::info("[PDF{0:d}]\tSaved PDF and parameters!", n);
|
||||
|
||||
//Load the events
|
||||
std::vector<fcnc::event> * leEvents = new std::vector<fcnc::event>;
|
||||
|
||||
//choose events from the event vector and sort corresponding to q2bin or non-resonant:
|
||||
//If use all events, just keep the numbers as they are
|
||||
UInt_t NNN = events[n].size()*fractionOfStats; // UInt_t NNN = fractionOfStats == 1 ? events[n].size() : 0.5 + event_numbers[b][n];
|
||||
|
||||
//This randomly pre-selected list of events is used, if not all events are wanted (eg if JpsiWithRareStats)
|
||||
std::vector<UInt_t> event_idxs(NNN);
|
||||
|
||||
if(fractionOfStats != 1.0){
|
||||
event_idxs = fcnc::GetNOutOfM(NNN, events[n].size(), 0, false, false);
|
||||
}
|
||||
else{
|
||||
std::iota (std::begin(event_idxs), std::end(event_idxs), 0); //This just puts 0,1,2,3,... into a vector
|
||||
}
|
||||
spdlog::info("Running fitter with a total number of events of: {0:d}", event_idxs.size());
|
||||
|
||||
for_indexed(auto e: event_idxs){
|
||||
//if (i%2!=0) continue;
|
||||
fcnc::event meas = events[n].at(e);
|
||||
//Cut on B mass
|
||||
if(meas.m < B_MASS_LOW || meas.m > B_MASS_HIGH) continue;
|
||||
//Select either magUp or magDown
|
||||
if(params.polarity==1 && meas.magnet > 0) continue;
|
||||
if(params.polarity==-1 && meas.magnet < 0) continue;
|
||||
|
||||
//Select only events in the given bin
|
||||
if(meas.q2 < theOptions[n].TheQ2binsmin.at(b) || meas.q2 > theOptions[n].TheQ2binsmax.at(b)) continue;
|
||||
|
||||
//Cut on Kpi mass
|
||||
if(meas.mkpi < opts.mkpi_min || meas.mkpi > opts.mkpi_max) continue;
|
||||
|
||||
//Fold if needed
|
||||
if(!filterFldFour(&meas, &theOptions[n])) continue; //remove ctk events
|
||||
if(!opts.full_angular) fldr.fold(&meas);
|
||||
|
||||
leEvents->push_back(meas);
|
||||
}
|
||||
|
||||
//Load the acceptance correction
|
||||
lePDF->load_coeffs_eff_phsp_4d();
|
||||
lePDF->update_cached_normalization(leParameters);
|
||||
lePDF->update_cached_efficiencies(leParameters, leEvents);
|
||||
|
||||
spdlog::info("[PDF{0:d}]\tFinished selecting the events: {1:d}",n, leEvents->size());
|
||||
|
||||
//save event vector in vector
|
||||
selection[b].push_back(leEvents);
|
||||
|
||||
if(selection[b].back()->size() > 0){
|
||||
spdlog::info("[PDF{0:d}]\t[BIN{1:d}]\tDone!", n, b);
|
||||
}
|
||||
else{
|
||||
spdlog::critical("No events found for PDF={0:d} and q2-bin={1:d}. Exit!",n,b);
|
||||
assert(0);
|
||||
}
|
||||
} //end loop over bins
|
||||
theOptions[n].update_efficiencies = false; //Prevent multiple weights
|
||||
} //end loop over PDFs
|
||||
|
||||
//Measure the time for the fit:
|
||||
runTime timer = runTime();
|
||||
|
||||
//Save the fit results
|
||||
std::vector<int>fit_results[nBins];
|
||||
std::vector<double>f_sigs[nBins];
|
||||
std::vector<double>f_sigserr[nBins];
|
||||
std::vector<UInt_t>evts_cntr[nBins];
|
||||
|
||||
//--------------------------------
|
||||
// FIT
|
||||
//--------------------------------
|
||||
spdlog::info("[FIT]\tFit started.");
|
||||
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
|
||||
//Start the clock
|
||||
timer.start();
|
||||
time_t startTime = time(0);
|
||||
|
||||
spdlog::info("[START]\tStart the fit for bin #{0:d}", b);
|
||||
|
||||
//fit the events:
|
||||
const bool do_fit = !FeldmanCousin; //TODO: ask David wtf
|
||||
int fitresult = 0;
|
||||
if(do_fit){
|
||||
if(!SimultaneousFit){
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
UInt_t idx = pdf_idx.at(n);
|
||||
spdlog::info("[FIT{0:d}]\tRunning the fitter...", idx);
|
||||
fitresult = f.fit(theProbs[b].at(n), theParams[b].at(n), selection[b].at(n));
|
||||
fit_results[b].push_back(fitresult);
|
||||
}
|
||||
}
|
||||
else{
|
||||
spdlog::info("[FIT]\tFitting the following events simultaenously:");
|
||||
for(UInt_t s = 0; s < selection[b].size(); s++) spdlog::info("PDF #{0:d}: {1:d}", pdf_idx.at(s), selection[b].at(s)->size());
|
||||
fitresult = f.fit(theProbs[b], theParams[b], selection[b]);
|
||||
fit_results[b].push_back(fitresult);
|
||||
spdlog::info("Q2BIN={0:d}\tLLH={1:f}", b, f.likelihood());
|
||||
|
||||
//run likelihood profile scan //TODO: fix and implement
|
||||
if(likelihoodScan) return 5;
|
||||
|
||||
//run feldman cousins //TODO: fix and implement
|
||||
if(FeldmanCousin) return 5;
|
||||
}
|
||||
}
|
||||
else{ //in case of not fit, just update the pdfs....?
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
theProbs[b].at(n)->update_cached_efficiencies(theParams[b].at(n), selection[b].at(n));
|
||||
fit_results[b].push_back(fitresult);
|
||||
}
|
||||
}
|
||||
|
||||
//Stop the clock
|
||||
timer.stop(startTime);
|
||||
|
||||
|
||||
//save signal fraction and event number for each bin and each pdf:
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
f_sigs[b] .push_back(((fcnc::bu2kstarmumu_parameters *) theParams[b].at(n))->f_sig.get_value());
|
||||
f_sigserr[b].push_back(((fcnc::bu2kstarmumu_parameters *) theParams[b].at(n))->f_sig.get_error());
|
||||
evts_cntr[b].push_back(selection[b].at(n)->size());
|
||||
}
|
||||
|
||||
//plot each set of pdfs with the data points:
|
||||
bool do_plot = !(likelihoodScan || FeldmanCousin);
|
||||
if (do_plot){
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
std::string eps_label = get_eps_label(fitReference,false, false, fitToy,
|
||||
params.nBins, b,
|
||||
params.polarity,
|
||||
SimultaneousFit, theOptions[n]);
|
||||
|
||||
theOptions[n].q2_label = q2_label(opts.TheQ2binsmin.at(b), opts.TheQ2binsmax.at(b));
|
||||
|
||||
spdlog::info("[PLOT]\t"+eps_label);
|
||||
thePlotter[n]->SetPulls(plotPulls);
|
||||
if (plotSignalRegion) thePlotter[n]->plot_data((fcnc::bu2kstarmumu_pdf*)theProbs[b].at(n), (fcnc::bu2kstarmumu_parameters*)theParams[b].at(n), selection[b].at(n), get_MainFitPlot_path(), eps_label, plotSignalRegion);
|
||||
thePlotter[n]->plot_data((fcnc::bu2kstarmumu_pdf*)theProbs[b].at(n), (fcnc::bu2kstarmumu_parameters*)theParams[b].at(n), selection[b].at(n), get_MainFitPlot_path(), eps_label+"_incBkg", false);
|
||||
}
|
||||
|
||||
//plot both PDFs together
|
||||
std::vector<fcnc::bu2kstarmumu_pdf*> * prober = (std::vector<fcnc::bu2kstarmumu_pdf*> *) & theProbs[b];
|
||||
|
||||
std::string eps_label = get_eps_label(fitReference,false, false, fitToy,
|
||||
params.nBins, b,
|
||||
params.polarity,
|
||||
SimultaneousFit, opts);
|
||||
std::vector<fcnc::bu2kstarmumu_parameters*> * paramser = (std::vector<fcnc::bu2kstarmumu_parameters*> *) & theParams[b];
|
||||
thePlotter[0]->SetPulls(plotPulls);
|
||||
if (plotSignalRegion) thePlotter[0]->plot_added_pdfs(prober, paramser, & selection[b], get_MainFitPlot_path(), eps_label, plotSignalRegion); //TODO add prefix to the plots
|
||||
thePlotter[0]->plot_added_pdfs(prober, paramser, & selection[b], get_MainFitPlot_path(), eps_label+"_incBkg", false);
|
||||
|
||||
|
||||
}//end do_plot
|
||||
}//end loop over bins for fitter
|
||||
|
||||
if(likelihoodScan || FeldmanCousin) return 5; //Not implemented yet
|
||||
|
||||
//--------------------------------
|
||||
// Print & Save
|
||||
//--------------------------------
|
||||
|
||||
//Print running time
|
||||
timer.print(nBins);
|
||||
|
||||
|
||||
if (!Blind) print_all_parameters(nBins, pdf_idx, theParams, spdlog::level::debug);
|
||||
|
||||
//Save the fit results into a txt file in case
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
//Print all fit results
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
spdlog::info("[BIN{0:d}]:\tFitresult: {1:d}", b, fit_results[n].at(b));
|
||||
}
|
||||
std::string txtFile = get_MainFitResult_path() + "fitresult_"
|
||||
+ get_eps_label(fitReference,false, false, fitToy,
|
||||
params.nBins, b,
|
||||
params.polarity,
|
||||
SimultaneousFit, theOptions[n])+ ".txt";
|
||||
((fcnc::bu2kstarmumu_parameters *) theParams[b].at(n))->save_param_values(txtFile);
|
||||
}
|
||||
}
|
||||
|
||||
//Print signal yield in the terminal and to a tex file
|
||||
if (!Blind){
|
||||
print_sig_yields(nBins, pdf_idx, evts_cntr, f_sigs, f_sigserr);
|
||||
print_bkg_yields(nBins, pdf_idx, evts_cntr, f_sigs, f_sigserr);
|
||||
}
|
||||
print_sig_yields_tex(get_eps_label(fitReference,false, false, fitToy,
|
||||
params.nBins, -1,
|
||||
params.polarity,
|
||||
SimultaneousFit, opts),
|
||||
nBins, pdf_idx, &opts, evts_cntr, f_sigs, f_sigserr);
|
||||
|
||||
|
||||
//saving results to root file TODO
|
||||
save_results(results_file,nBins,pdf_idx,fit_results,theParams,SimultaneousFit,&opts);
|
||||
spdlog::info("Finished fit.");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
44
Code/FCNCFitter/sources/Run/mainfit.hh
Normal file
44
Code/FCNCFitter/sources/Run/mainfit.hh
Normal file
@ -0,0 +1,44 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef MAINFIT_HH
|
||||
#define MAINFIT_HH
|
||||
|
||||
#include <options.hh>
|
||||
#include <parse.hh>
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
// FL SCALING OF LARGE BINS TO SMALL BINS //
|
||||
////////////////////////////////////////////
|
||||
|
||||
// TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
|
||||
//Idea is to scale FS accordingly to FL distributions
|
||||
//FS is obtained in three bins: [1.0-8.0], [11.0-12.5] and [15.0-19.0] in 2D mass fits
|
||||
//the following scales for FL are obtained from flav.io and are the ratio of int(FL)_largebin / int(FL)_smallbin
|
||||
//in principle, only the scaling in q2 below the ccbar peaks is significant
|
||||
|
||||
///including the first q2bin: //TODO: get from my MC
|
||||
const std::vector<double> FL_scale = {0.4836193455050577, 1.2251014138607774, 1.274499551405837, 1.1368614009399862};
|
||||
|
||||
const std::vector<double> FL_scale_toys = { //TODO Get from my MC!
|
||||
0.5, //scaled from average of bin 1-4
|
||||
1.0 + 0.07 / (61.*4) * (61.+ 62.+ 96.+ 125.),
|
||||
1.0 + 0.12 / (62.*4) * (61.+ 62.+ 96.+ 125.),
|
||||
1.0 - 0.02 / (96.*4) * (61.+ 62.+ 96.+ 125.),
|
||||
1.0 - 0.17 / (125.*4) * (61.+ 62.+ 96.+ 125.),
|
||||
1.0,//evaluated by itself
|
||||
1.0 + 0.04 / (129. * 2) * (129. + 69.),
|
||||
1.0 - 0.04 / (69. * 2) * (129. + 69.),
|
||||
};
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Other constants //
|
||||
////////////////////////////////////////////
|
||||
const int TotalEvents = 0;
|
||||
|
||||
////////////////////////////////////////////
|
||||
/// \brief mainfit
|
||||
int mainfit(fcnc::options opts, basic_params params, bool fitReference, bool fitToy, bool likelihoodScan, bool FeldmanCousin);
|
||||
|
||||
#endif // MAINFIT_HH
|
414
Code/FCNCFitter/sources/Run/massfit.cc
Normal file
414
Code/FCNCFitter/sources/Run/massfit.cc
Normal file
@ -0,0 +1,414 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <massfit.hh>
|
||||
|
||||
#include <event.hh>
|
||||
#include <fitter.hh>
|
||||
#include <bu2kstarmumu_plotter.hh>
|
||||
#include <paths.hh>
|
||||
#include <design.hh>
|
||||
#include <helpers.hh>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
#include <TROOT.h>
|
||||
#include <TStyle.h>
|
||||
|
||||
//Fitter part that fits only the mass of DATA
|
||||
|
||||
bool checkForCommonValues(std::vector<std::string> vec_one,std::vector<std::string> vec_two){
|
||||
for (auto key: vec_one){
|
||||
if (std::find(vec_two.begin(), vec_two.end(), key)!= vec_two.end()){
|
||||
spdlog::warn("Parameter " + key + " is shared between two vectors!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int massfit(fcnc::options opts, bool fitReference, bool splitRuns, basic_params pars){
|
||||
//splitRuns = true means one gets a simFit of Run 1 and Run 2
|
||||
//splitRuns = false means Run 1 and Run 2 are fit together
|
||||
|
||||
const bool fitKstarMass = true;
|
||||
|
||||
bool Blind = false;//!fitReference; //If signal channel, blind to be sure
|
||||
const unsigned int nBins = opts.get_nQ2bins(); //unsigned because vector.size is unsigned
|
||||
|
||||
bool constrainMassFromMC = false; //Use mass fit of MC to constrain mass parameters?
|
||||
bool constrainMassFromRefMC = true;//Use mass fit of *RefMC* to constrain mass parameters?
|
||||
bool constrainMassFromData = !fitReference; //Use the mass fit of data Reference to constrain the parameters?
|
||||
|
||||
bool fixBMass = !fitReference; //Fix the B mass to PDG?
|
||||
|
||||
//Set the parameters that should be constrained
|
||||
std::vector<std::string> toBeConstrainedMC = {};
|
||||
std::vector<std::string> toBeFixedMC = {};
|
||||
|
||||
std::vector<std::string> toBeConstrainedRefMC = {};
|
||||
std::vector<std::string> toBeFixedRefMC = {"alpha_1","alpha_2","n_1","n_2"};
|
||||
|
||||
std::vector<std::string> toBeConstrainedRefData = {};
|
||||
std::vector<std::string> toBeFixedRefData = {"m_b","m_sigma_1"};
|
||||
|
||||
|
||||
//Sanity check one doesn't constrain one thing to two different values
|
||||
if (constrainMassFromMC && constrainMassFromRefMC){
|
||||
if (checkForCommonValues(toBeConstrainedMC, toBeConstrainedRefMC)){
|
||||
spdlog::warn("Fix your options, aborting now!");
|
||||
return 2;
|
||||
}
|
||||
if (checkForCommonValues(toBeFixedMC, toBeFixedRefMC)){
|
||||
spdlog::warn("Fix your options, aborting now!");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
if (constrainMassFromMC && constrainMassFromData){
|
||||
if (checkForCommonValues(toBeConstrainedMC, toBeConstrainedRefData)){
|
||||
spdlog::warn("Fix your options, aborting now!");
|
||||
return 2;
|
||||
}
|
||||
if (checkForCommonValues(toBeFixedMC, toBeFixedRefData)){
|
||||
spdlog::warn("Fix your options, aborting now!");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
if (constrainMassFromRefMC && constrainMassFromData){
|
||||
if (checkForCommonValues(toBeConstrainedRefMC, toBeConstrainedRefData) ){
|
||||
spdlog::warn("Fix your options, aborting now!");
|
||||
return 2;
|
||||
}
|
||||
if (checkForCommonValues(toBeFixedRefMC, toBeFixedRefData)){
|
||||
spdlog::warn("Fix your options, aborting now!");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (constrainMassFromMC && checkForCommonValues(toBeConstrainedMC, toBeFixedMC)){
|
||||
spdlog::warn("The parameter will be fixed!");
|
||||
}
|
||||
if (constrainMassFromRefMC && checkForCommonValues(toBeConstrainedRefMC, toBeFixedRefMC)){
|
||||
spdlog::warn("The parameter will be fixed!");
|
||||
}
|
||||
if (constrainMassFromData && checkForCommonValues(toBeConstrainedRefData, toBeFixedRefData)){
|
||||
spdlog::warn("The parameter will be fixed!");
|
||||
}
|
||||
|
||||
gROOT->SetBatch(kTRUE);
|
||||
gROOT->SetStyle("Plain");
|
||||
set_gStyle();
|
||||
|
||||
//Open texFile
|
||||
std::ofstream myFile;
|
||||
open_Latex_noteFile(latex_massFit(), myFile);
|
||||
|
||||
spdlog::info("[FIT]\t\tFitting only mass...");
|
||||
|
||||
// --- Set the options --- //
|
||||
opts.only_Bmass = !fitKstarMass;
|
||||
opts.only_mass2DFit = fitKstarMass;
|
||||
|
||||
opts.swave = fitKstarMass;
|
||||
opts.shift_lh = false; //keep it, it was there before
|
||||
opts.weighted_fit = fitKstarMass; // weights for the MASS DATA fit
|
||||
|
||||
opts.plot_chi2 = true;
|
||||
opts.fit_mkpi = fitKstarMass;
|
||||
opts.use_mkpi = false;
|
||||
opts.plot_folder = get_MassFitPlot_path(); //Set the plot path
|
||||
opts.minos_errors = true; //TODO!
|
||||
opts.squared_hesse = false;
|
||||
opts.asymptotic = false;
|
||||
|
||||
if (!fitReference) opts.plots_m_bins = 30; //Plot less bins for signal channel as the stats are sad there
|
||||
if (!fitReference) opts.plots_mkpi_bins = 20; //Plot less bins for signal channel as the stats are sad there
|
||||
|
||||
// --- Load events from data tuple --- //
|
||||
std::vector<std::vector<fcnc::event>>events;
|
||||
std::vector<UInt_t> pdf_idx;
|
||||
|
||||
if (opts.run == 1 || opts.run == 12){
|
||||
std::vector<fcnc::event> tmp = fcnc::load_events(get_theFCNCpath(0,1), "Events", -1);
|
||||
if (!fitReference) events.push_back(fcnc::filterResonances(tmp));
|
||||
else events.push_back(tmp);
|
||||
pdf_idx.push_back(1);
|
||||
}
|
||||
if (opts.run == 2 || opts.run == 12){
|
||||
std::vector<fcnc::event> tmp = fcnc::load_events(get_theFCNCpath(0,2), "Events", -1);
|
||||
if (!fitReference) events.push_back(fcnc::filterResonances(tmp));
|
||||
else events.push_back(tmp);
|
||||
pdf_idx.push_back(2);
|
||||
}
|
||||
//No need to keep the datasets separated, as there is no need for the weights
|
||||
if (!splitRuns && opts.run == 12){
|
||||
pdf_idx.clear();
|
||||
pdf_idx.push_back(12);
|
||||
//Add the vector from Run 2 into Run 1 vector
|
||||
events[0].insert(events[0].end(), events[1].begin(), events[1].end());
|
||||
//Delete the Run 2 vector
|
||||
events.pop_back();
|
||||
}
|
||||
|
||||
//check that the number of pdfs is the same as number of event vectors
|
||||
if (pdf_idx.size() != events.size()){
|
||||
spdlog::error("Something went very wrong when loading the events and setting the pdfs.");
|
||||
spdlog::error("The number of PDFs!= number of event vectors: {0:d} vs {1:d}",pdf_idx.size(), events.size());
|
||||
return 5;
|
||||
}
|
||||
//we are good to go, now; how many individual pdfs are used?
|
||||
const UInt_t nPDFs = pdf_idx.size();
|
||||
|
||||
//Check the number of events
|
||||
UInt_t N_tot = 0;
|
||||
for (UInt_t n = 0; n < nPDFs; n++){
|
||||
spdlog::debug("Event vector {0:d}:\t"+(Blind ? "Larger 1 ":std::to_string(events.at(n).size())), n);
|
||||
if (events.at(n).size()==0){
|
||||
spdlog::error("Empty event vector!");
|
||||
return 404;
|
||||
}
|
||||
N_tot += events.at(n).size();
|
||||
}
|
||||
spdlog::info("Total number of used events:\t{0:d}", N_tot);
|
||||
|
||||
//Get the path to the file where to get the values/constraints from
|
||||
//Always use simFit from MCand mass only, it is easier
|
||||
std::string ParamInitFileMC = final_result_name_MC(pars, nBins, fitReference, false, true, false, false);
|
||||
std::string ParamInitFileRefMC = final_result_name_MC(pars, 1, true, false, true, false, true);
|
||||
std::string ParamInitFileRefData = final_result_name_mass(true, 1, splitRuns, pars, pars.Run);
|
||||
|
||||
//current fitter, plotter, parameter and pdf:
|
||||
fcnc::fitter f(&opts);
|
||||
fcnc::options theOptions[nPDFs];
|
||||
fcnc::bu2kstarmumu_plotter * thePlotter[nPDFs];
|
||||
std::vector<fcnc::parameters*> theParams [nBins];
|
||||
std::vector<fcnc::pdf*> theProbs [nBins];
|
||||
std::vector< std::vector<fcnc::event>*> selection[nBins];
|
||||
|
||||
//Set FS as a common parameter if fitting the sWeight
|
||||
if(fitKstarMass) f.set_common_parameters({"FS"});
|
||||
|
||||
//Loop over PDFs and initialize parameters
|
||||
for(unsigned n = 0; n < nPDFs; n++){
|
||||
opts.run = pdf_idx.at(n); //Set proper run to options
|
||||
opts.name = get_MassFit_label(fitReference, -1, nBins, splitRuns, pars, pdf_idx.at(n));
|
||||
spdlog::debug("Initializing run {0:d}", opts.run);
|
||||
opts.update_efficiencies = true; //This ensures the acceptance weights to be taken into account.
|
||||
//loop over number of bins
|
||||
for(UInt_t b = 0; b < nBins; b++){
|
||||
//Create parameter set
|
||||
fcnc::bu2kstarmumu_parameters * leParameters = new fcnc::bu2kstarmumu_parameters(&opts);
|
||||
//create PDF
|
||||
fcnc::bu2kstarmumu_pdf * lePDF = new fcnc::bu2kstarmumu_pdf(&opts, leParameters);
|
||||
|
||||
//Init the sig/bkg fraction
|
||||
leParameters->f_sig.init(fitReference ? 0.8 : 0.3, 0.1, 1.0, 0.1);
|
||||
|
||||
//Init PDG mass, keep the range this large!
|
||||
leParameters->m_b.init(PDGMASS_B, B_MASS_LOW, B_MASS_HIGH, fixBMass ? 0.0 : 0.1);
|
||||
|
||||
//Init mass parameters to defaults
|
||||
leParameters->init_mass_parameters(n,nBins,b,0.01);
|
||||
|
||||
//Overwrite the defaults with constraints/fixes from MC/Ref, if needed
|
||||
if (constrainMassFromMC){
|
||||
leParameters->constrain_param_from_rootfile(ParamInitFileMC, toBeConstrainedMC, splitRuns ? pdf_idx.at(n) : 2, b);
|
||||
leParameters->fix_param_from_rootfile(ParamInitFileMC, toBeFixedMC, splitRuns ? pdf_idx.at(n) : 2, b);
|
||||
}
|
||||
if (constrainMassFromRefMC){ //Fix to refrence channel, so always read 0th bin
|
||||
leParameters->constrain_param_from_rootfile(ParamInitFileRefMC, toBeConstrainedRefMC, splitRuns ? pdf_idx.at(n) : 2, 0);
|
||||
leParameters->fix_param_from_rootfile(ParamInitFileRefMC, toBeFixedRefMC, splitRuns ? pdf_idx.at(n) : 2, 0);
|
||||
}
|
||||
if (constrainMassFromData){ //Fix to refrence channel, so always read 0th bin
|
||||
leParameters->constrain_param_from_rootfile(ParamInitFileRefData, toBeConstrainedRefData, splitRuns ? pdf_idx.at(n) : 2, 0);
|
||||
leParameters->fix_param_from_rootfile(ParamInitFileRefData, toBeFixedRefData, splitRuns ? pdf_idx.at(n) : 2, 0);
|
||||
}
|
||||
|
||||
//Make sure the B mass range is correct
|
||||
leParameters->m_b.set_min(B_MASS_LOW);
|
||||
leParameters->m_b.set_max(B_MASS_HIGH);
|
||||
|
||||
|
||||
//Init the ratio of sigmas in signal MC/reference MC
|
||||
if (!fitReference) leParameters->m_sigma_1.init_fixed(leParameters->m_sigma_1.get_value()*get_sigmaRatio_fromMC(pars,nBins,b,pdf_idx.at(n)));
|
||||
//I don't trust the m_scale
|
||||
|
||||
|
||||
//Init background
|
||||
leParameters->init_mass_background_parameters(nBins, b, opts.fit_lambda);
|
||||
|
||||
//define center of q2bin as effective q2:
|
||||
leParameters->eff_q2.init_fixed(bin_center_q2(opts,b));
|
||||
|
||||
//Init the Kstar mass fit
|
||||
if(opts.fit_mkpi || opts.use_mkpi){
|
||||
//p-wave;
|
||||
leParameters->init_mkpi_pWave_parameters(fitReference,0.001);
|
||||
leParameters->init_kpi_background_parameters(fitReference,0.05);
|
||||
|
||||
//s-wave
|
||||
leParameters->FS.init(0.055, 0.00, 0.5, 0.001); //David got 0.055
|
||||
leParameters->init_mkpi_sWave_parameters(fitReference, 0.0); //Fix it, otherwise it doesn't converge
|
||||
}
|
||||
|
||||
//Control print of the parameters
|
||||
//leParameters->print_parameters(false);
|
||||
|
||||
//Save the parameters and PDF per bin
|
||||
leParameters->take_current_as_start();
|
||||
theParams[b].push_back(leParameters);
|
||||
theProbs [b].push_back(lePDF);
|
||||
spdlog::info("[PDF{0:d}]\tSaved PDF and parameters!", pdf_idx.at(n));
|
||||
|
||||
//create vector with events according to the requested fits/pulls
|
||||
std::vector<fcnc::event> *leEvents= new std::vector<fcnc::event>;
|
||||
//Loop over events
|
||||
spdlog::debug("Loop over events");
|
||||
|
||||
for (auto meas: events.at(n)){
|
||||
if(meas.m < opts.m_low || meas.m > opts.m_high) continue;
|
||||
if(pars.polarity==1 && meas.magnet > 0) continue;
|
||||
if(pars.polarity==-1 && meas.magnet < 0) continue;
|
||||
if(meas.q2 < opts.TheQ2binsmin.at(b) || meas.q2 > opts.TheQ2binsmax.at(b)) continue;
|
||||
leEvents->push_back(meas);
|
||||
}
|
||||
//Update efficiencies (aka take into account angular parametrization weights) ONCE
|
||||
lePDF->load_coeffs_eff_phsp_4d();
|
||||
lePDF->update_cached_normalization(leParameters);
|
||||
lePDF->update_cached_efficiencies(leParameters, leEvents);
|
||||
|
||||
spdlog::info("[PDF{0:d}]\tFinished selecting the events: {1:d}",n, leEvents->size());
|
||||
|
||||
//save event vector in vector
|
||||
selection[b].push_back(leEvents);
|
||||
if(selection[b].back()->size() > 0){
|
||||
spdlog::info("[PDF{0:d}]\t[BIN{1:d}]\tDone!", n, b);
|
||||
}
|
||||
else{
|
||||
spdlog::critical("No events found for PDF={0:d} and q2 bin={1:d}. Exit!",n,b);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
} //End loop over bins
|
||||
opts.update_efficiencies = false; //Prevent the weights to be applied several more times in fitter::fit
|
||||
|
||||
theOptions[n] = opts;
|
||||
//Allocate the plotter... sigh #ItIsn'tThe90sAnymore
|
||||
thePlotter[n] = new fcnc::bu2kstarmumu_plotter(&theOptions[n]);
|
||||
}//end loop over PDFs
|
||||
|
||||
//--------------------------------
|
||||
// FIT
|
||||
//--------------------------------
|
||||
spdlog::info("[MASSFIT]\tMass fit started.");
|
||||
|
||||
//Measure the time for the fit:
|
||||
runTime timer = runTime();
|
||||
|
||||
//Save the fit results
|
||||
std::vector<int>fit_results[nBins];
|
||||
std::vector<double>f_sigs[nBins];
|
||||
std::vector<double>f_sigserr[nBins];
|
||||
std::vector<double> bkg_int_full_range[nBins]; //Not really used
|
||||
std::vector<UInt_t>evts_cntr[nBins];
|
||||
|
||||
//fit per bins:
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
|
||||
//Start the clock
|
||||
timer.start();
|
||||
time_t startTime = time(0);
|
||||
spdlog::info("[START]\tStart the fit for bin #{0:d}", b);
|
||||
|
||||
std::string tag = get_MassFit_label(fitReference, b,nBins, splitRuns, pars, 0);
|
||||
clear_Latex_noteFile(latex_fitterFile(tag));
|
||||
spdlog::info("[FIT]\tRunning the fitter...");
|
||||
fit_results[b].push_back(f.fit(theProbs[b], theParams[b], selection[b], tag));
|
||||
spdlog::info("Q2BIN={0:d}\tLLH={1:f}", b, f.likelihood());
|
||||
|
||||
//Stop the clock
|
||||
timer.stop(startTime);
|
||||
|
||||
//save signal fraction and event number for each bin and each pdf:
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
f_sigs[b] .push_back(((fcnc::bu2kstarmumu_parameters *) theParams[b].at(n))->f_sig.get_value());
|
||||
f_sigserr[b].push_back(((fcnc::bu2kstarmumu_parameters *) theParams[b].at(n))->f_sig.get_error());
|
||||
evts_cntr[b].push_back(selection[b].at(n)->size());
|
||||
//integrate the background pdf over the range [opts.m_min; opts.m_max] to estimate the background contribution in each q2bin:
|
||||
bkg_int_full_range[b].push_back(((fcnc::bu2kstarmumu_pdf*)theProbs[b].at(n))->integral_m_bkg_prob((fcnc::bu2kstarmumu_parameters*)theParams[b].at(n),B_MASS_LOW, B_MASS_HIGH));
|
||||
}
|
||||
|
||||
|
||||
//Plot everything
|
||||
bool sigRegion = true; //Plot only in the signal region
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
tag = get_MassFit_label(fitReference, b,nBins, splitRuns, pars, pdf_idx.at(n));
|
||||
theOptions[n].plot_label = "LHCb data";
|
||||
theOptions[n].q2_label =q2_label(opts.TheQ2binsmin.at(b), opts.TheQ2binsmax.at(b));
|
||||
|
||||
if (nPDFs>1){ //If only one PDF, just plot the "added pdfs"
|
||||
spdlog::info("[PLOT]\t"+theOptions[n].plot_label);
|
||||
thePlotter[n]->plot_data((fcnc::bu2kstarmumu_pdf*)theProbs[b].at(n),
|
||||
(fcnc::bu2kstarmumu_parameters*)theParams[b].at(n),
|
||||
selection[b].at(n), get_MassFitPlot_path(),tag, sigRegion);
|
||||
}
|
||||
}
|
||||
//Plot joint result
|
||||
std::vector<fcnc::bu2kstarmumu_pdf*> * prober = (std::vector<fcnc::bu2kstarmumu_pdf*> *) & theProbs[b];
|
||||
std::vector<fcnc::bu2kstarmumu_parameters*> * paramser = (std::vector<fcnc::bu2kstarmumu_parameters*> *) & theParams[b];
|
||||
|
||||
tag = get_MassFit_label(fitReference, b,nBins, splitRuns, pars, pars.Run);
|
||||
thePlotter[0]->plot_added_pdfs(prober, paramser, &selection[b],
|
||||
get_MassFitPlot_path(), tag, sigRegion);
|
||||
}//end bin loop
|
||||
|
||||
//Plot the significances and yields in the fancy plot
|
||||
//TODO: unhardcode the runs
|
||||
if (!fitReference && nBins>1){
|
||||
std::string tag = get_MassFit_label(fitReference, -1,nBins, splitRuns, pars, 12);
|
||||
spdlog::info("Saving yield plots into " + tag);
|
||||
thePlotter[0]->plotYieldInQ2(true, theParams, theProbs, nPDFs, evts_cntr, get_MassFitPlot_path(), tag);
|
||||
thePlotter[1]->plotYieldInQ2(false, theParams, theProbs, nPDFs, evts_cntr, get_MassFitPlot_path(), tag);
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
// Print & Save
|
||||
//--------------------------------
|
||||
|
||||
//Print running time
|
||||
timer.print(nBins);
|
||||
|
||||
//Print all fit results
|
||||
print_all_parameters(nBins, pdf_idx, theParams, spdlog::level::debug);
|
||||
|
||||
//Save the fit results
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
for(UInt_t i = 0; i < pdf_idx.size(); i++){
|
||||
std::vector<fcnc::bu2kstarmumu_parameters*> * paramser = (std::vector<fcnc::bu2kstarmumu_parameters*> *) & theParams[b];
|
||||
std::string results_file = get_MassFitResult_path()+ "fitresult_"
|
||||
+get_MassFit_label(fitReference, b, nBins, splitRuns, pars, pars.Run)+ ".txt";
|
||||
paramser->at(i)->save_param_values(results_file);
|
||||
}
|
||||
}
|
||||
|
||||
//Print signal yield in the terminal and to a tex file
|
||||
if (!Blind){
|
||||
print_sig_yields(nBins, pdf_idx, evts_cntr, f_sigs, f_sigserr);
|
||||
print_bkg_yields(nBins, pdf_idx, evts_cntr, f_sigs, f_sigserr);
|
||||
}
|
||||
print_sig_yields_tex(get_MassFit_label(fitReference, -1,nBins,
|
||||
splitRuns, pars, pars.Run),
|
||||
nBins, pdf_idx, &opts, evts_cntr, f_sigs, f_sigserr);
|
||||
|
||||
|
||||
//Save results to root file
|
||||
std::string results_file = final_result_name_mass(fitReference, nBins, splitRuns, pars, pars.Run);
|
||||
save_results(results_file, nBins, pdf_idx, fit_results, theParams, true, &opts);
|
||||
|
||||
//Close Latex file
|
||||
myFile.close();
|
||||
|
||||
spdlog::info("[MASSFIT]\tMass fit finished.");
|
||||
return 0;
|
||||
}
|
11
Code/FCNCFitter/sources/Run/massfit.hh
Normal file
11
Code/FCNCFitter/sources/Run/massfit.hh
Normal file
@ -0,0 +1,11 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef MASSFIT_H
|
||||
#define MASSFIT_H
|
||||
|
||||
#include <options.hh>
|
||||
#include <parse.hh>
|
||||
|
||||
int massfit(fcnc::options opts, bool fitReference, bool splitRuns, basic_params pars);
|
||||
|
||||
#endif // MASSFIT_H
|
388
Code/FCNCFitter/sources/Run/mcfit.cc
Normal file
388
Code/FCNCFitter/sources/Run/mcfit.cc
Normal file
@ -0,0 +1,388 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include "mcfit.hh"
|
||||
|
||||
#include <event.hh>
|
||||
#include <fitter.hh>
|
||||
#include <bu2kstarmumu_plotter.hh>
|
||||
#include <folder.hh>
|
||||
#include <paths.hh>
|
||||
#include <design.hh>
|
||||
#include <helpers.hh>
|
||||
#include <spdlog.h>
|
||||
|
||||
int mcfit_4D(fcnc::options opts, bool fitReference, bool fitPHSP, basic_params params){
|
||||
|
||||
//--------------------------------
|
||||
// Sanity checks
|
||||
//--------------------------------
|
||||
|
||||
if (params.Run != 1 && params.Run != 2 && params.Run != 12){
|
||||
spdlog::error("Wrong run selected! Please use either 1, 2 or 12 for fititng the MC!");
|
||||
return 1;
|
||||
}
|
||||
//--------------------------------
|
||||
// Set constants
|
||||
//--------------------------------
|
||||
if(fitReference) spdlog::info("[MCFIT]\tFit reference channel: J/psi K*+"); //reference channel only
|
||||
else spdlog::info("[MCFIT]\tFit signal MC");//signal MC only
|
||||
|
||||
const bool Blind = false; //False as it is MC, HAS TO BE TRUE FOR DATA
|
||||
const bool UseBinnedFit = true; //Use bins in q2, if false, nBins is forced to be one
|
||||
const bool SimultaneousFit = true; //Simultanously fit all PDFs
|
||||
const bool fixBMass = false; //Fix B mass to PDG value
|
||||
const bool plotPulls = true; //Do you wanna pull plots with or without pulls?
|
||||
|
||||
int prescale = 1; //The fraction of events to be kept
|
||||
//Eg if prescale = 3, only a third of events will be kept
|
||||
//This is not EXACTLY a third though, but a third from all the possible events,
|
||||
//as this is taken from the loaded events, not from the selected events
|
||||
//In an extreme case when eg prescale is 2, only MagDown is to be fitted and every second event
|
||||
//is MagDown, all events would be still kept.
|
||||
//To use all the events, set it to 1
|
||||
|
||||
//Scales for the fit parameters (meaning fit-ranges)
|
||||
double PprimeRangeScale = 10.0;
|
||||
double angleRange = +1.0;
|
||||
if (params.usePprime) angleRange *= PprimeRangeScale;
|
||||
double angleStepSize = 0.01;
|
||||
|
||||
if (!UseBinnedFit){
|
||||
spdlog::info("Running an unbinned fit");
|
||||
opts.TheQ2binsmin = get_TheQ2binsmin(1,fitReference);
|
||||
opts.TheQ2binsmax = get_TheQ2binsmax(1,fitReference);
|
||||
}
|
||||
const unsigned int nBins = opts.get_nQ2bins(); //unsigned because vector.size is unsigned
|
||||
spdlog::debug("Using {0:d} q2 bins.", nBins);
|
||||
|
||||
//--------------------------------
|
||||
// Set all options
|
||||
//--------------------------------
|
||||
opts.use_mkpi = false; //5D fit
|
||||
opts.fit_mkpi = false; //4D+1 fit
|
||||
|
||||
opts.full_angular = (params.folding ==-1);
|
||||
opts.folding = params.folding;
|
||||
//TODO: this needs to be fixed, it is written like for idiots
|
||||
if(opts.fit_mkpi || opts.use_mkpi){
|
||||
opts.only_Bmass = false;
|
||||
opts.only_mass2DFit = fitReference;
|
||||
}
|
||||
bool dontFitAngles = fitReference;
|
||||
|
||||
opts.swave = false;
|
||||
opts.multiply_eff = true; //MC weights need to be taken into account
|
||||
opts.weighted_fit = true; //Needed to plot the weights properly
|
||||
opts.use_event_norm = false; //Used for convoluting the acceptance into pdf
|
||||
|
||||
//Set the plot folder
|
||||
opts.plot_folder = get_MCfitPlot_path(fitReference, fitPHSP);
|
||||
|
||||
//Set the available PDFs: this depends on the selected Run for now, so if only one is selected, run over one pdf, if both, use two
|
||||
std::vector<UInt_t> pdf_idx;
|
||||
if (params.Run == 1 || params.Run == 12) pdf_idx.push_back(1);
|
||||
if (params.Run == 2 || params.Run == 12) pdf_idx.push_back(2);
|
||||
|
||||
//--------------------------------
|
||||
// Load data
|
||||
//--------------------------------
|
||||
spdlog::info("[MCFIT]\tLoading data...");
|
||||
std::vector<std::vector<fcnc::event>>events;
|
||||
|
||||
if (opts.run == 1 || opts.run == 12){
|
||||
events.push_back(fcnc::load_events(get_theFCNCpath(MC_dataset(fitReference,fitPHSP),1), "Events", -1));
|
||||
}
|
||||
if (opts.run == 2 || opts.run == 12){
|
||||
events.push_back(fcnc::load_events(get_theFCNCpath(MC_dataset(fitReference,fitPHSP),2), "Events", -1));
|
||||
}
|
||||
|
||||
|
||||
//check that the number of pdfs is the same as number of event vectors
|
||||
if (pdf_idx.size() != events.size()){
|
||||
spdlog::error("Something went very wrong when loading the events and setting the pdfs.");
|
||||
spdlog::error("The number of PDFs!= number of event vectors: {0:d} vs {1:d}",pdf_idx.size(), events.size());
|
||||
return 5;
|
||||
}
|
||||
//we are good to go, now; how many individual pdfs are used?
|
||||
const UInt_t nPDFs = pdf_idx.size();
|
||||
|
||||
UInt_t N_tot = 0;
|
||||
for (UInt_t n = 0; n < nPDFs; n++){
|
||||
spdlog::debug("Event vector {0:d}:\t"+(Blind?"Larger 1 ":std::to_string(events.at(n).size())),n);
|
||||
if (events.at(n).size()==0){
|
||||
spdlog::error("Empty event vector!");
|
||||
return 404;
|
||||
}
|
||||
N_tot += events.at(n).size();
|
||||
}
|
||||
spdlog::info("Total number of used events:\t{0:d}", N_tot);
|
||||
|
||||
//Initialize all needed things for the fit
|
||||
//current fitter, plotter, parameteres and pdfs:
|
||||
fcnc::fitter f(&opts);
|
||||
fcnc::folder fldr(&opts);
|
||||
fcnc::options theOptions[nPDFs];
|
||||
fcnc::bu2kstarmumu_plotter * thePlotter[nPDFs];
|
||||
std::vector<fcnc::parameters*> theParams [nBins];
|
||||
std::vector<fcnc::pdf*> theProbs [nBins];
|
||||
std::vector< std::vector<fcnc::event>*> selection[nBins];
|
||||
|
||||
//Initialize common parameters //Includes sWave if opts.swave is on
|
||||
std::vector<std::string> common_params = param_string(opts, true);
|
||||
if(SimultaneousFit) f.set_common_parameters(common_params);
|
||||
spdlog::info("Shared parameters: " + convert_vector_to_string(common_params));
|
||||
|
||||
//--------------------------------
|
||||
// Read events
|
||||
//--------------------------------
|
||||
|
||||
//Loop over PDFs and initialize parameters
|
||||
for(unsigned n = 0; n < nPDFs; n++){
|
||||
opts.run = pdf_idx.at(n); //Set proper run to options
|
||||
spdlog::debug("Run {0:d}", opts.run);
|
||||
opts.name = get_MCfit_label(fitReference, fitPHSP, nBins, -1, SimultaneousFit, params, opts.run, opts.only_angles, dontFitAngles);
|
||||
opts.update_angle_ranges(); //Set angles in options back to defaults
|
||||
opts.update_efficiencies = true; //This ensures the acceptance weights to be taken into account.
|
||||
//It needs to be set properly as the MC needs to take into account the MC-data weights and hence the weight multiplication is on. However, the weights are recalculated later on (see fitter::fit and fitter::init), so they need to be turned off after loading the efficiencies.
|
||||
|
||||
//Set the label to MC
|
||||
opts.plot_label = "LHCb MC";
|
||||
|
||||
//Loop over bins now
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
opts.q2_min = opts.TheQ2binsmin.front();
|
||||
opts.q2_max = opts.TheQ2binsmax.back();
|
||||
|
||||
//Create parameter set
|
||||
fcnc::bu2kstarmumu_parameters * leParameters = new fcnc::bu2kstarmumu_parameters(&opts);
|
||||
//create PDF
|
||||
fcnc::bu2kstarmumu_pdf * lePDF = new fcnc::bu2kstarmumu_pdf(&opts, leParameters);
|
||||
|
||||
//Initialize basic parameters
|
||||
//define center of q2bin as effective q2
|
||||
leParameters->eff_q2.init_fixed( bin_center_q2(opts,b));
|
||||
leParameters->f_sig.init_fixed(1.0);
|
||||
|
||||
if (!opts.only_angles){ //If not fitting the angles ONLY, init the mass parameters
|
||||
leParameters->init_mass_parameters(n,nBins,b,0.01);
|
||||
leParameters->m_b.init(PDGMASS_B_PLUS, B_MASS_LOW, B_MASS_HIGH, fixBMass ? 0.0: 1.0);
|
||||
if (!fitReference && !fitPHSP){
|
||||
std::string file = final_result_name_MC(params, 1, true, false, true, false, true);
|
||||
leParameters->fix_param_from_rootfile(file, {"alpha_1","alpha_2","n_1","n_2"}, pdf_idx.at(n), 0);
|
||||
}
|
||||
leParameters->m_scale.init_fixed(1.0); //Scale of sigma between the signal/ref MC, used in the data mass fit
|
||||
}
|
||||
|
||||
if (!dontFitAngles){
|
||||
leParameters->init_angular_parameters(nBins,b,angleStepSize,angleRange, Blind);
|
||||
}
|
||||
|
||||
|
||||
//TODO: DELETE: only for testing the folding
|
||||
//double FLinit[4] = {0.662,0.689,0.444,0.357};
|
||||
//if (params.folding == 4) leParameters->Fl.init_fixed(FLinit[b]);//,0.0,1.0,0.05);
|
||||
//if (params.folding == 4) leParameters->S8.init_fixed(0.0);
|
||||
if (!fitReference && !fitPHSP){
|
||||
std::string file = final_result_name_MC(params, 1, true, false, true, false, true);
|
||||
leParameters->fix_param_from_rootfile(file, {"alpha_1","alpha_2","n_1","n_2"}, pdf_idx.at(n), 0);
|
||||
}
|
||||
//Kpi mass p-wave
|
||||
if(opts.fit_mkpi || opts.use_mkpi){
|
||||
leParameters->init_mkpi_pWave_parameters(fitReference,0.001);
|
||||
}
|
||||
//make sure all configured values are also the start_value:
|
||||
leParameters->take_current_as_start();
|
||||
|
||||
theParams[b].push_back(leParameters);
|
||||
theProbs [b].push_back(lePDF);
|
||||
spdlog::info("[PDF{0:d}]\tSaved PDF and parameters!", pdf_idx.at(n) );
|
||||
|
||||
//create vector with events according to the requested fits/pulls
|
||||
std::vector<fcnc::event> *leEvents= new std::vector<fcnc::event>;
|
||||
|
||||
//Loop over events
|
||||
spdlog::debug("Loop over events");
|
||||
for_indexed(auto meas: events.at(n)){
|
||||
theOptions[n].update_angle_ranges(); //Update angle ranges based on the folding
|
||||
//Reject events in the case prescale is used
|
||||
if (prescale>1 && i%prescale!=0) continue;
|
||||
//Select either magUp or magDown
|
||||
if(params.polarity==1 && meas.magnet > 0) continue;
|
||||
if(params.polarity==-1 && meas.magnet < 0) continue;
|
||||
if(meas.q2 < opts.TheQ2binsmin.at(b) || meas.q2 > opts.TheQ2binsmax.at(b)) continue;
|
||||
if(meas.mkpi < opts.mkpi_min || meas.mkpi > opts.mkpi_max) continue;
|
||||
if(meas.m < B_MASS_LOW || meas.m > B_MASS_HIGH) continue;
|
||||
if(!filterFldFour(&meas, &theOptions[n])) continue; //remove ctk events
|
||||
if(!opts.full_angular) fldr.fold(&meas);
|
||||
leEvents->push_back(meas);
|
||||
}
|
||||
|
||||
//Update efficiencies (aka take into account angular parametrization weights) ONCE
|
||||
lePDF->load_coeffs_eff_phsp_4d();
|
||||
lePDF->update_cached_normalization(leParameters);
|
||||
lePDF->update_cached_efficiencies(leParameters, leEvents);
|
||||
opts.update_angle_ranges();
|
||||
spdlog::info("[PDF{0:d}]\tFinished selecting the events: {1:d}",n, leEvents->size());
|
||||
//save event vector in vector
|
||||
selection[b].push_back(leEvents);
|
||||
if(selection[b].back()->size() > 0){
|
||||
spdlog::info("[PDF{0:d}]\t[BIN{1:d}]\tDone!", n, b);
|
||||
}
|
||||
else{
|
||||
spdlog::critical("No events found for PDF={0:d} and q2 bin={1:d}. Exit!",n,b);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
} //End loop over bins
|
||||
opts.update_efficiencies = false; //Prevent the weights to be applied several more times in fitter::fit
|
||||
|
||||
theOptions[n] = opts;
|
||||
//Allocate the plotter... sigh
|
||||
thePlotter[n] = new fcnc::bu2kstarmumu_plotter(&theOptions[n]);
|
||||
|
||||
}//end loop over PDFs
|
||||
|
||||
//--------------------------------
|
||||
// FIT
|
||||
//--------------------------------
|
||||
spdlog::info("[MCFIT]\tMC fit started.");
|
||||
|
||||
//Measure the time for the fit:
|
||||
runTime timer = runTime();
|
||||
|
||||
//Save the fit results
|
||||
std::vector<int>fit_results[nBins];
|
||||
std::vector<double>f_sigs[nBins];
|
||||
std::vector<double>f_sigserr[nBins];
|
||||
std::vector<UInt_t>evts_cntr[nBins];
|
||||
|
||||
//fit all bins:
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
|
||||
//Start the clock
|
||||
timer.start();
|
||||
time_t startTime = time(0);
|
||||
|
||||
spdlog::info("[START]\tStart the fit for bin #{0:d}", b);
|
||||
|
||||
//Int for fit status
|
||||
int fitresult = 0;
|
||||
|
||||
if(!SimultaneousFit){
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
|
||||
//Delete the texFile
|
||||
std::string tag = get_MCfit_label(fitReference, fitPHSP,
|
||||
nBins, b,
|
||||
SimultaneousFit, params, theOptions[n].run,
|
||||
opts.only_angles, dontFitAngles);
|
||||
|
||||
clear_Latex_noteFile(latex_fitterFile(tag));
|
||||
|
||||
spdlog::info("[FIT{0:d}]\tRunning the fitter...", n);
|
||||
fitresult = f.fit(theProbs[b].at(n), theParams[b].at(n), selection[b].at(n),tag);
|
||||
fit_results[b].push_back(fitresult);
|
||||
}
|
||||
}
|
||||
else{
|
||||
spdlog::info("[FIT]\tFitting simultaenously....");
|
||||
//Delete the texFile
|
||||
std::string tag = get_MCfit_label(fitReference, fitPHSP,
|
||||
nBins, b,
|
||||
SimultaneousFit, params, opts.run,
|
||||
opts.only_angles, dontFitAngles);
|
||||
clear_Latex_noteFile(latex_fitterFile(tag));
|
||||
for(UInt_t s = 0; s < selection[b].size(); s++)spdlog::info("PDF #{0:d}: {1:d}", pdf_idx.at(s), selection[b].at(s)->size());
|
||||
fitresult = f.fit(theProbs[b], theParams[b], selection[b],tag);
|
||||
fit_results[b].push_back(fitresult);
|
||||
spdlog::info("Q2BIN={0:d}\tLLH={1:f}", b, f.likelihood());
|
||||
if(params.likelyhood){
|
||||
spdlog::error("TODO.");
|
||||
return 5;
|
||||
}
|
||||
if(params.FeldCous){
|
||||
spdlog::error("TODO.");
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
//Stop the clock
|
||||
timer.stop(startTime);
|
||||
|
||||
//Print the fit results
|
||||
spdlog::info("[BIN{0:d}]:\tFitresult: {1:d}", b, fitresult);
|
||||
|
||||
//save signal fraction and event number for each bin and each pdf:
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
f_sigs[b] .push_back(((fcnc::bu2kstarmumu_parameters *) theParams[b].at(n))->f_sig.get_value());
|
||||
f_sigserr[b].push_back(((fcnc::bu2kstarmumu_parameters *) theParams[b].at(n))->f_sig.get_error());
|
||||
evts_cntr[b].push_back(selection[b].at(n)->size());
|
||||
}
|
||||
|
||||
//Plot everything
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
std::string eps_label = get_MCfit_label(fitReference, fitPHSP,
|
||||
nBins, b,
|
||||
SimultaneousFit, params, theOptions[n].run,
|
||||
opts.only_angles, dontFitAngles);
|
||||
theOptions[n].q2_label = q2_label(theOptions[n].TheQ2binsmin.at(b), theOptions[n].TheQ2binsmax.at(b));
|
||||
spdlog::info("[PLOT]\t"+eps_label);
|
||||
thePlotter[n]->SetPulls(plotPulls);
|
||||
thePlotter[n]->plot_data((fcnc::bu2kstarmumu_pdf*)theProbs[b].at(n),
|
||||
(fcnc::bu2kstarmumu_parameters*)theParams[b].at(n),
|
||||
selection[b].at(n),
|
||||
get_MCfitPlot_path(fitReference, fitPHSP), eps_label, false);
|
||||
}
|
||||
|
||||
std::string eps_label = get_MCfit_label(fitReference, fitPHSP,
|
||||
nBins, b,
|
||||
SimultaneousFit, params, params.Run,
|
||||
opts.only_angles, dontFitAngles);
|
||||
if (!plotPulls) eps_label = eps_label+"_noPulls";
|
||||
|
||||
std::vector<fcnc::bu2kstarmumu_pdf*> * prober = (std::vector<fcnc::bu2kstarmumu_pdf*> *) & theProbs[b];
|
||||
std::vector<fcnc::bu2kstarmumu_parameters*> * paramser = (std::vector<fcnc::bu2kstarmumu_parameters*> *) & theParams[b];
|
||||
thePlotter[0]->SetPulls(plotPulls);
|
||||
thePlotter[0]->plot_added_pdfs(prober, paramser, &selection[b],
|
||||
get_MCfitPlot_path(fitReference, fitPHSP),eps_label, false);
|
||||
|
||||
} //end bin loop
|
||||
|
||||
|
||||
//--------------------------------
|
||||
// Print & Save
|
||||
//--------------------------------
|
||||
|
||||
//Print running time
|
||||
timer.print(nBins);
|
||||
|
||||
//Print all fit results
|
||||
print_all_parameters(nBins, pdf_idx, theParams, spdlog::level::debug);
|
||||
|
||||
|
||||
//Save the fit results
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
for(UInt_t i = 0; i < pdf_idx.size(); i++){
|
||||
std::vector<fcnc::bu2kstarmumu_parameters*> * paramser = (std::vector<fcnc::bu2kstarmumu_parameters*> *) & theParams[b];
|
||||
paramser->at(i)->save_param_values(finalResult_MCfit_txt(i,fitReference,fitPHSP, nBins, b, SimultaneousFit, params, params.Run, opts.only_angles, dontFitAngles));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Print signal yield in the terminal and to a tex file
|
||||
if (!Blind) print_sig_yields(nBins, pdf_idx, evts_cntr, f_sigs, f_sigserr);
|
||||
|
||||
print_sig_yields_tex(get_MCfit_label(fitReference, fitPHSP,
|
||||
nBins, -1,
|
||||
SimultaneousFit, params, params.Run,
|
||||
opts.only_angles, dontFitAngles),
|
||||
nBins, pdf_idx, theOptions, evts_cntr, f_sigs, f_sigserr);
|
||||
|
||||
//Save results to root file
|
||||
std::string results_file = final_result_name_MC(params, nBins, fitReference, fitPHSP, SimultaneousFit, opts.only_angles, dontFitAngles);
|
||||
save_results(results_file, nBins, pdf_idx, fit_results, theParams, SimultaneousFit, &opts);
|
||||
|
||||
spdlog::info("[MCFIT]\tMC fit finished.");
|
||||
return 0;
|
||||
|
||||
}
|
11
Code/FCNCFitter/sources/Run/mcfit.hh
Normal file
11
Code/FCNCFitter/sources/Run/mcfit.hh
Normal file
@ -0,0 +1,11 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef MCFIT_HH
|
||||
#define MCFIT_HH
|
||||
|
||||
#include <options.hh>
|
||||
#include <parse.hh>
|
||||
|
||||
int mcfit_4D(fcnc::options opts, bool fitReference, bool fitPHSP, basic_params params);
|
||||
|
||||
#endif // MCFIT_HH
|
1324
Code/FCNCFitter/sources/Run/momfit.cc
Normal file
1324
Code/FCNCFitter/sources/Run/momfit.cc
Normal file
File diff suppressed because it is too large
Load Diff
15
Code/FCNCFitter/sources/Run/momfit.hh
Normal file
15
Code/FCNCFitter/sources/Run/momfit.hh
Normal file
@ -0,0 +1,15 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef MOMFIT_HH
|
||||
#define MOMFIT_HH
|
||||
|
||||
#include <options.hh>
|
||||
//////////////////////////
|
||||
// INIT VALUES FOR FITS //
|
||||
//////////////////////////
|
||||
|
||||
int momfit(fcnc::options opts,
|
||||
bool fitReference, bool fitSignalMC, bool fitData, bool blind,
|
||||
bool Fit1bin, bool Fit2bins, bool FitAllbins);
|
||||
|
||||
#endif // MOMFIT_HH
|
230
Code/FCNCFitter/sources/Run/multifit.cc
Normal file
230
Code/FCNCFitter/sources/Run/multifit.cc
Normal file
@ -0,0 +1,230 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <TCanvas.h>
|
||||
#include <TPaveText.h>
|
||||
#include <TTree.h>
|
||||
#include <TBranch.h>
|
||||
#include <TF1.h>
|
||||
#include <TH1D.h>
|
||||
#include <TStyle.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <event.hh>
|
||||
#include <parameters.hh>
|
||||
#include <funcs.hh>
|
||||
#include <pdf.hh>
|
||||
#include <options.hh>
|
||||
|
||||
#include <multifit.hh>
|
||||
|
||||
using namespace std;
|
||||
using namespace fcnc;
|
||||
|
||||
multifit::multifit(options* o):
|
||||
opts(o)
|
||||
{
|
||||
output = new TFile(("result" + opts->name + ".root").c_str(), "RECREATE");
|
||||
};
|
||||
|
||||
multifit::~multifit(){
|
||||
output->Write();
|
||||
output->Close();
|
||||
delete output;
|
||||
};
|
||||
|
||||
void multifit::fit_gaussian(vector<double>& values, double& gauss_mean, double& sigma_gauss_mean, double& gauss_width, double& sigma_gauss_width, double& chi_squared) const
|
||||
{
|
||||
|
||||
double max = *max_element(std::begin(values), std::end(values));
|
||||
double min = *min_element(std::begin(values), std::end(values));
|
||||
|
||||
double mean=0.0;
|
||||
double rms=0.0;
|
||||
TTree* t = new TTree("tree", "pull values");
|
||||
double value;
|
||||
TBranch *branch = t->Branch("value",&value,"value/D");
|
||||
for (unsigned int i = 0; i < values.size(); i++) {
|
||||
value = values.at(i);
|
||||
branch->Fill();
|
||||
t->Fill();
|
||||
mean += value/values.size();
|
||||
}
|
||||
for (unsigned int i = 0; i < values.size(); i++){
|
||||
value = values.at(i);
|
||||
rms += (value - mean)*(value - mean)/values.size();
|
||||
}
|
||||
rms = sqrt(rms);
|
||||
TF1* f1 = new TF1("f1", "gaus(0)/sqrt(2.0*3.1415926536)/abs([2])", min-5.0, max+5.0);
|
||||
f1->SetParameters(1.0,mean,rms);
|
||||
//f1->SetParLimits(0, 1.0, 1.0);
|
||||
f1->FixParameter(0, 1.0);
|
||||
t->UnbinnedFit("f1", "value");
|
||||
gauss_mean = f1->GetParameter(1);
|
||||
sigma_gauss_mean = f1->GetParError(1);
|
||||
gauss_width = f1->GetParameter(2);
|
||||
sigma_gauss_width = f1->GetParError(2);
|
||||
delete f1;
|
||||
delete t;
|
||||
};
|
||||
|
||||
void multifit::update_pull(parameter* p, vector<double>& values, vector<double>& errors, double& gauss_mean, double& sigma_gauss_mean, double& gauss_width, double& sigma_gauss_width, double& chi_squared, string appendix) const
|
||||
{
|
||||
unsigned int runs=values.size();
|
||||
string parname(p->get_name());
|
||||
string descr(p->get_description());
|
||||
gStyle->SetOptStat(0);
|
||||
gStyle->SetOptFit(0);
|
||||
//finally the pull histo
|
||||
TH1D* pull_histo = new TH1D((parname + "_pull_").c_str(),
|
||||
(descr + " pull distribution;" + "(" + descr
|
||||
+ "^{fitted}-" + descr
|
||||
+ "^{generated})/#sigma").c_str(),
|
||||
50, -5.0, 5.0);//sensible for pulls
|
||||
//fill histos
|
||||
//this is done every time because the time is negligible
|
||||
double start_value = p->get_start_value();
|
||||
vector<double> pull_values;
|
||||
for (unsigned int k=0; k<runs; k++){
|
||||
if (errors.at(k) != 0.0){
|
||||
double pull = (values.at(k)-start_value)/errors.at(k);
|
||||
pull_histo->Fill(pull);
|
||||
pull_values.push_back(pull);
|
||||
}
|
||||
}
|
||||
fit_gaussian(pull_values, gauss_mean, sigma_gauss_mean, gauss_width, sigma_gauss_width, chi_squared);
|
||||
|
||||
TCanvas *pull_canvas = new TCanvas((parname + "_pull_" + appendix).c_str(), "Bs Likelihood Analysis: Pull distribution",1600,1200);
|
||||
pull_canvas->cd();
|
||||
pull_histo->Draw();
|
||||
TF1 *g = new TF1("g","[0]*exp(-(x-[1])*(x-[1])/2.0/[2]/[2])",-5.0,5.0);
|
||||
|
||||
//for normalization: multiply with dx*histint = width/Nbins*histint
|
||||
g->SetParameters(1.0/sqrt(2.0*TMath::Pi())/gauss_width*10.0/50.0*pull_histo->Integral(), gauss_mean, gauss_width);
|
||||
g->Draw("same");
|
||||
TPaveText* text = new TPaveText(0.6,0.7,0.88,0.88,"NDC");
|
||||
text->SetFillColor(0);
|
||||
std::ostringstream stream_mean;
|
||||
stream_mean << "Mean: " << fixed << setprecision(3) << gauss_mean << "#pm" << sigma_gauss_mean;
|
||||
std::ostringstream stream_width;
|
||||
stream_width << "Width: " << fixed << setprecision(3) << gauss_width << "#pm" << sigma_gauss_width;
|
||||
text->AddText(stream_mean.str().c_str());
|
||||
text->AddText(stream_width.str().c_str());
|
||||
text->Draw("same");
|
||||
|
||||
string afilename; //TODO: move to paths
|
||||
if (appendix != "") afilename = "plots/pull_" + parname + "_" + appendix + ".eps";
|
||||
else afilename = "plots/pull_" + parname + ".eps";
|
||||
if (opts->write_eps)pull_canvas->Print(afilename.c_str(), "eps");
|
||||
output->cd();
|
||||
pull_canvas->Write();
|
||||
delete text;
|
||||
delete g;
|
||||
delete pull_histo;
|
||||
delete pull_canvas;
|
||||
}
|
||||
|
||||
void multifit::update_value(parameter * p, vector<double>& values, vector<double>& errors, double& gauss_mean, double& sigma_gauss_mean, double& gauss_width, double& sigma_gauss_width, double& chi_squared, string appendix) const
|
||||
{
|
||||
unsigned int runs=values.size();
|
||||
string parname(p->get_name());
|
||||
string descr(p->get_description());
|
||||
//first find min and max values
|
||||
double max = *max_element(std::begin(values), std::end(values));
|
||||
double min = *min_element(std::begin(values), std::end(values));
|
||||
double width = max-min;
|
||||
double hist_min = min - 0.5*width;
|
||||
double hist_max = max + 0.5*width;
|
||||
gStyle->SetOptStat(0);
|
||||
gStyle->SetOptFit(0);
|
||||
TH1D* value_histo = new TH1D((parname+"_values").c_str(),
|
||||
(descr + ";" + descr).c_str(),
|
||||
50, hist_min, hist_max);
|
||||
for (unsigned int k=0; k<runs; k++) {
|
||||
value_histo->Fill(values.at(k));
|
||||
}
|
||||
|
||||
fit_gaussian(values, gauss_mean, sigma_gauss_mean, gauss_width, sigma_gauss_width, chi_squared);
|
||||
TCanvas *value_canvas = new TCanvas((parname + "_value_" + appendix).c_str(), "Bs Likelihood Analysis: Value distribution",1600,1200);
|
||||
value_canvas->cd();
|
||||
value_histo->Draw();
|
||||
TF1 *g = new TF1("g","[0]*exp(-(x-[1])*(x-[1])/2.0/[2]/[2])",-5.0,5.0);
|
||||
g->SetParameters(1.0/sqrt(2.0*TMath::Pi())/gauss_width*(hist_max-hist_min)/50.0*value_histo->Integral(), gauss_mean, gauss_width);
|
||||
g->Draw("same");
|
||||
|
||||
TPaveText* text = new TPaveText(0.6,0.7,0.88,0.88,"NDC");
|
||||
text->SetFillColor(0);
|
||||
std::ostringstream stream_mean;
|
||||
stream_mean << "Mean: " << fixed << setprecision(3) << gauss_mean << "#pm" << sigma_gauss_mean;
|
||||
std::ostringstream stream_width;
|
||||
stream_width << "Width: " << fixed << setprecision(3) << gauss_width << "#pm" << sigma_gauss_width;
|
||||
text->AddText(stream_mean.str().c_str());
|
||||
text->AddText(stream_width.str().c_str());
|
||||
text->Draw("same");
|
||||
|
||||
//TODO: move
|
||||
string afilename;
|
||||
if (appendix != "") afilename = "plots/value_" + parname + "_" + appendix + ".eps";
|
||||
else afilename = "plots/value_" + parname + ".eps";
|
||||
if (opts->write_eps) value_canvas->Print(afilename.c_str(), "eps");
|
||||
output->cd();
|
||||
value_canvas->Write();
|
||||
delete text;
|
||||
delete value_histo;
|
||||
delete value_canvas;
|
||||
delete g;
|
||||
}
|
||||
|
||||
void multifit::update_error(parameter* p, vector<double>& values, vector<double>& errors, double& gauss_mean, double& sigma_gauss_mean, double& gauss_width, double& sigma_gauss_width, double& chi_squared, string appendix) const
|
||||
{
|
||||
unsigned int runs=values.size();
|
||||
string parname(p->get_name());
|
||||
string descr(p->get_description());
|
||||
//then find min and max errors
|
||||
double max = *max_element(std::begin(errors), std::end(errors));
|
||||
double min = *min_element(std::begin(errors), std::end(errors));
|
||||
|
||||
double width = max - min;
|
||||
double hist_min = min - 0.5*width;
|
||||
double hist_max = max + 0.5*width;
|
||||
gStyle->SetOptStat(0);
|
||||
gStyle->SetOptFit(0);
|
||||
TH1D* error_histo = new TH1D((parname+"_errors").c_str(),
|
||||
("#sigma(" + descr + ");#sigma(" + descr + ")").c_str(),
|
||||
100, hist_min, hist_max);
|
||||
for (unsigned int k=0; k<runs; k++){
|
||||
error_histo->Fill(errors.at(k));
|
||||
}
|
||||
fit_gaussian(errors, gauss_mean, sigma_gauss_mean, gauss_width, sigma_gauss_width, chi_squared);
|
||||
TCanvas *error_canvas = new TCanvas((parname + "_error_" + appendix).c_str(), "Bs Likelihood Analysis: Error distribution",1600,1200);
|
||||
|
||||
error_canvas->cd();
|
||||
error_histo->Draw();
|
||||
TF1 *g = new TF1("g","[0]*exp(-(x-[1])*(x-[1])/2.0/[2]/[2])",-5.0,5.0);
|
||||
g->SetParameters(1.0/sqrt(2.0*TMath::Pi())/gauss_width*(hist_max-hist_min)/100.0*error_histo->Integral(), gauss_mean, gauss_width);
|
||||
g->Draw("same");
|
||||
TPaveText* text = new TPaveText(0.6,0.7,0.88,0.88,"NDC");
|
||||
text->SetFillColor(0);
|
||||
std::ostringstream stream_mean;
|
||||
stream_mean << "Mean: " << fixed << setprecision(3) << gauss_mean << "#pm" << sigma_gauss_mean;
|
||||
std::ostringstream stream_width;
|
||||
stream_width << "Width: " << fixed << setprecision(3) << gauss_width << "#pm" << sigma_gauss_width;
|
||||
text->AddText(stream_mean.str().c_str());
|
||||
text->AddText(stream_width.str().c_str());
|
||||
text->Draw("same");
|
||||
|
||||
//TODO: move
|
||||
string afilename;
|
||||
|
||||
if (appendix != "") afilename = "plots/error_" + parname + "_" + appendix + ".eps";
|
||||
else afilename = "plots/error_" + parname + ".eps";
|
||||
|
||||
if (opts->write_eps) error_canvas->Print(afilename.c_str(), "eps");
|
||||
|
||||
output->cd();
|
||||
error_canvas->Write();
|
||||
delete text;
|
||||
delete error_histo;
|
||||
delete error_canvas;
|
||||
delete g;
|
||||
}
|
44
Code/FCNCFitter/sources/Run/multifit.hh
Normal file
44
Code/FCNCFitter/sources/Run/multifit.hh
Normal file
@ -0,0 +1,44 @@
|
||||
//Renata Kopecna
|
||||
/**
|
||||
* @file multifit.hh
|
||||
* @author Christoph Langenbruch
|
||||
* @date 2009-03-18
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MULTIFIT_H
|
||||
#define MULTIFIT_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <funcs.hh>
|
||||
#include <TFile.h>
|
||||
|
||||
namespace fcnc {
|
||||
//Forward declaration
|
||||
class parameter;
|
||||
|
||||
|
||||
///base class for analysis classes which do multiple fits, e.g. toystudy
|
||||
class multifit {
|
||||
protected:
|
||||
///set of options
|
||||
options* opts;
|
||||
///constructor
|
||||
multifit(options* o);
|
||||
///destructor
|
||||
virtual ~multifit();
|
||||
///unbinned likelihood fit of gaussian
|
||||
void fit_gaussian(std::vector<double>& values, double& gauss_mean, double& sigma_gauss_mean, double& gauss_width, double& sigma_gauss_width, double& chi_squared) const;
|
||||
///fits a gaussian to the pull values
|
||||
void update_pull(parameter* p, std::vector<double>& values, std::vector<double>& errors, double& gauss_mean, double& sigma_gauss_mean, double& gauss_width, double& sigma_gauss_width, double& chi_squared, std::string appendix="") const;
|
||||
///fits a gaussian to the values
|
||||
void update_value(parameter* p, std::vector<double>& values, std::vector<double>& errors, double& gauss_mean, double& sigma_gauss_mean, double& gauss_width, double& sigma_gauss_width, double& chi_squared, std::string appendix="") const;
|
||||
///fits a gaussian to the errors
|
||||
void update_error(parameter* p, std::vector<double>& values, std::vector<double>& errors, double& gauss_mean, double& sigma_gauss_mean, double& gauss_width, double& sigma_gauss_width, double& chi_squared, std::string appendix="") const;
|
||||
TFile* output;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
628
Code/FCNCFitter/sources/Run/pulls.cc
Normal file
628
Code/FCNCFitter/sources/Run/pulls.cc
Normal file
@ -0,0 +1,628 @@
|
||||
//Renata Kopecna
|
||||
|
||||
|
||||
#include <pulls.hh>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "folder.hh"
|
||||
#include <fitter.hh>
|
||||
#include <bu2kstarmumu_plotter.hh>
|
||||
#include <bu2kstarmumu_generator.hh>
|
||||
#include <bu2kstarmumu_pdf.hh>
|
||||
#include <bu2kstarmumu_parameters.hh>
|
||||
#include <paths.hh>
|
||||
#include <helpers.hh>
|
||||
#include <event.hh>
|
||||
|
||||
#include <TTree.h>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
//////////////////////////
|
||||
// INIT VALUES FOR FITS //
|
||||
//////////////////////////
|
||||
|
||||
//Do they change anywhere or can I set them in a header?
|
||||
//TODO replace by the parameters->init
|
||||
double f_m_B[4] = {5282.32, 5282.08, 5278.57, 5279.48};
|
||||
double f_lambda1[4] = {-0.00386, -0.00610, -0.00362, -0.00578};
|
||||
double f_lambda2[4] = {-0.03320, -0.00120, -0.04600, -0.00100};
|
||||
double f_alpha_1[4] = { 1.7910, 1.8000, 1.6510, 1.5400};
|
||||
double f_alpha_2[4] = { 2.3200, 2.4300, 2.0100, 2.2500};
|
||||
double f_n_1[4] = { 1.4400, 1.4900, 1.6800, 1.6100};
|
||||
double f_n_2[4] = { 2.8900, 3.7000, 3.8700, 3.7000};
|
||||
double f_sigma_1[4] = {14.8300, 15.4800, 14.8400, 14.4};
|
||||
double f_sigma_2[4] = {14.0700, 13.1000, 15.6200, 13.3};
|
||||
double f_f_CB[4] = { 0.6360, 0.3600, 0.3040, 0.6200};
|
||||
double f_m_scale[4] = { 1.1814, 1.0648, 1.1547, 1.1168};
|
||||
|
||||
|
||||
//TODO posibly to be deleted so ignoring for now!
|
||||
void do_pulls(fcnc::options opts, bool doToyPulls, bool doMCPulls, int job_id, double SwaveFraction, UInt_t nPulls, Double_t nToyEvents, UInt_t nMCEvents ,std::string angularsuffix, bool Fit1bin, bool Fit2bins, bool FitAllbins ){ //TODO: change to int and return some errors possibly
|
||||
//TODO: figure out jobs_to_do and job_id, but there is no manipulation with it, so so far so good
|
||||
//Why is it not opts.job_id?
|
||||
if(doToyPulls)std::cout << "[INFO]\t\tGetting pull distributions and test fits from Toy Events!" << std::endl;
|
||||
|
||||
//disable eps output if job_id is larger than -1. This is needed for HD cluster jobs:
|
||||
if(job_id > -1)opts.write_eps = false;
|
||||
|
||||
//have extra option for the usage of binning:
|
||||
const bool UseBinnedFit = false;
|
||||
|
||||
opts.fit_fl = false;
|
||||
opts.fit_afb = false;
|
||||
opts.only_angles = false;
|
||||
opts.only_Bmass = false;
|
||||
if(opts.only_Bmass) opts.only_angles = false;
|
||||
|
||||
opts.use_angular_acc = true;
|
||||
opts.use_weighted_bkg = true;
|
||||
opts.fit_full_angular_bkg = true;
|
||||
opts.always_generate_full_angular = true;
|
||||
opts.weighted_fit = true;
|
||||
|
||||
opts.swave = true;
|
||||
opts.shift_lh = false;
|
||||
|
||||
opts.squared_hesse = true;
|
||||
opts.minos_errors = false;
|
||||
|
||||
opts.generate_mkpi = true;
|
||||
opts.fit_mkpi = false;
|
||||
opts.use_mkpi = true;
|
||||
opts.flat_bkg = false;
|
||||
|
||||
//change the label of the produced plots:
|
||||
opts.plot_label = "LHCb toys";
|
||||
|
||||
//SM
|
||||
std::vector<double> s1s, s1c, s2s, s2c, s3, s4, s5, s6s, s6c, s7, s8, s9;
|
||||
std::vector<double> f_signal, f_bckgnd, f_bckcoeff;
|
||||
double f_sig_norm = 0.0;
|
||||
std::vector<UInt_t> events_per_bin;
|
||||
|
||||
//determine number of bins:
|
||||
const UInt_t nBins = UseBinnedFit ? opts.TheQ2binsmin.size() : 1;
|
||||
if(!UseBinnedFit){
|
||||
opts.TheQ2binsmin = {8.68};
|
||||
opts.TheQ2binsmax = {10.09};
|
||||
}
|
||||
|
||||
//create TTree to save pull values
|
||||
double treeValue, treeStart, treeError, treeErrorUp, treeErrorDown;
|
||||
UInt_t treeBin, treeFitNumber, treeFitResult, treeIndex;
|
||||
|
||||
TTree * T = nullptr;
|
||||
if(doToyPulls || doMCPulls){
|
||||
T = new TTree("PullTree", "PullTree");
|
||||
T->Branch("v", &treeValue, "v/D");
|
||||
T->Branch("i", &treeIndex, "i/i");
|
||||
T->Branch("s", &treeStart, "s/D");
|
||||
T->Branch("e", &treeError, "e/D");
|
||||
T->Branch("eu", &treeErrorUp, "eu/D");
|
||||
T->Branch("ed", &treeErrorDown, "ed/D");
|
||||
T->Branch("b", &treeBin , "b/i");
|
||||
T->Branch("f", &treeFitNumber, "f/i");
|
||||
T->Branch("r", &treeFitResult, "r/i");
|
||||
T->Branch("fs", &SwaveFraction, "fs/D");
|
||||
}
|
||||
|
||||
//TODO: fix the name of the genLvl root file
|
||||
basic_params params_genLvl = basic_params();
|
||||
params_genLvl.Run = 2;
|
||||
params_genLvl.year = 2017;
|
||||
params_genLvl.nBins = nBins;
|
||||
std::string genPath = final_result_name_genLvlMC(params_genLvl, nBins, false, true, false);
|
||||
|
||||
s1s = load_param_values_into_vector("S1s",genPath);
|
||||
s3 = load_param_values_into_vector("S3", genPath);
|
||||
s4 = load_param_values_into_vector("S4", genPath);
|
||||
s5 = load_param_values_into_vector("S5", genPath);
|
||||
s6s = load_param_values_into_vector("S6s",genPath);
|
||||
s7 = load_param_values_into_vector("S7", genPath);
|
||||
s8 = load_param_values_into_vector("S8", genPath);
|
||||
s9 = load_param_values_into_vector("S9", genPath);
|
||||
|
||||
if(UseBinnedFit){
|
||||
if(nBins == 8){
|
||||
f_signal = {101., 61., 62., 96., 125., 124., 129., 69.};
|
||||
f_bckgnd = {131., 206., 279., 358., 358., 247., 158., 93.};
|
||||
f_bckcoeff = {-0.0052, -0.0084, -0.0088, -0.0031, -0.0028, -0.0158, -0.0079, -0.0058}; //for notation: exp(lambda * x)
|
||||
|
||||
//results from Signal channel generator level MC fits:
|
||||
s1c = { 0.2450, 0.6996, 0.7993, 0.7384, 0.6414, 0.4201, 0.3513, 0.3344};
|
||||
s2s = { 0.1448, 0.0749, 0.0514, 0.0662, 0.0900, 0.1449, 0.1620, 0.1662};
|
||||
s2c = {-0.1953,-0.6639,-0.7774,-0.7254,-0.6334,-0.4171,-0.3497,-0.3332};
|
||||
s3 = { 0.0000, 0.0020,-0.0080,-0.0120,-0.0240,-0.0620,-0.1520,-0.2330};
|
||||
s4 = { 0.0870, 0.0040,-0.1080,-0.1950,-0.2510,-0.2770,-0.2900,-0.3040};
|
||||
s5 = { 0.2440, 0.0950,-0.1590,-0.3050,-0.4140,-0.4210,-0.3400,-0.2490};
|
||||
s6s = {-0.1270,-0.2070,-0.0860, 0.0950, 0.3020, 0.5140, 0.5570, 0.4700};
|
||||
s6c = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000};
|
||||
s7 = {-0.0060,-0.0100,-0.0030, 0.0020, 0.0030,-0.0020,-0.0020, 0.0050};
|
||||
s8 = { 0.0010,-0.0030,-0.0040,-0.0030,-0.0010, 0.0030,-0.0010, 0.0030};
|
||||
s9 = {-0.0020, 0.0000, 0.0020, 0.0040,-0.0020,-0.0010,-0.0010, 0.0010};
|
||||
|
||||
}
|
||||
else if(nBins == 4){
|
||||
spdlog::error("YOU NEED TO UPDATE THESE FIRTS!");
|
||||
assert(0);
|
||||
f_signal = {101., 61., 62., 96.};
|
||||
f_bckgnd = {131., 206., 279., 358.};
|
||||
f_bckcoeff = {-0.0052, -0.0084, -0.0088, -0.0031}; //for notation: exp(lambda * x)
|
||||
|
||||
//results from Signal channel generator level MC fits:
|
||||
s1s = { 0.5120, 0.1800, 0.1370, 0.1930};
|
||||
s1c = { 0.2450, 0.6996, 0.7993, 0.7384};
|
||||
s2s = { 0.1448, 0.0749, 0.0514, 0.0662};
|
||||
s2c = {-0.1953,-0.6639,-0.7774,-0.7254};
|
||||
s3 = { 0.0000, 0.0020,-0.0080,-0.0120};
|
||||
s4 = { 0.0870, 0.0040,-0.1080,-0.1950};
|
||||
s5 = { 0.2440, 0.0950,-0.1590,-0.3050};
|
||||
s6s = {-0.1270,-0.2070,-0.0860, 0.0950};
|
||||
s6c = { 0.0000, 0.0000, 0.0000, 0.0000};
|
||||
s7 = {-0.0060,-0.0100,-0.0030, 0.0020};
|
||||
s8 = { 0.0010,-0.0030,-0.0040,-0.0030};
|
||||
s9 = {-0.0020, 0.0000, 0.0020, 0.0040};
|
||||
}
|
||||
else if(nBins == 2){
|
||||
f_signal = { 61.+ 62.+ 96.+125., 129.+69.};
|
||||
f_bckgnd = {206.+279.+358.+358., 158.+93.};
|
||||
f_bckcoeff = {-0.0064, -0.0065};
|
||||
|
||||
s1s = { 0.1959, 0.4917};
|
||||
s1c = { 0.7441, 0.3447};
|
||||
s2s = { 0.0646, 0.1636};
|
||||
s2c = {-0.7217, -0.3432};
|
||||
s3 = {-0.0042, -0.1747};
|
||||
s4 = { 0.1033, 0.2929};
|
||||
s5 = {-0.1458, -0.3157};
|
||||
s6s = { 0.0652, -0.5338};
|
||||
s6c = { 0.0000, 0.0000};
|
||||
s7 = { 0.0340, -0.0000};
|
||||
s8 = {-0.0115, -0.0002};
|
||||
s9 = { 0.0003, 0.0003};
|
||||
}
|
||||
else {
|
||||
spdlog::error("No SM values given for binning scheme with {0:d} q2 bins. Exit", nBins);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
else{
|
||||
f_signal = {0.5};
|
||||
f_bckgnd = {0.5};
|
||||
f_bckcoeff = {-2.835e-3}; //for notation: exp(lambda * x)
|
||||
s1s = { 0.2372};
|
||||
s1c = { 0.6863};
|
||||
s2s = { 0.0};
|
||||
s2c = {-0.6760};
|
||||
s3 = {-0.0107};
|
||||
s4 = { 0.2163};
|
||||
s5 = {-0.3806};
|
||||
s6s = {-0.1957};
|
||||
s6c = { 0.0};
|
||||
s7 = { 0.0290};
|
||||
s8 = {-0.0113};
|
||||
s9 = { 0.0003};
|
||||
}
|
||||
|
||||
assert(f_signal.size() == f_bckgnd.size());
|
||||
f_sig_norm = std::accumulate(f_signal.begin(), f_signal.end(), 0.0)
|
||||
+ std::accumulate(f_bckgnd.begin(), f_bckgnd.end(), 0.0);
|
||||
|
||||
for(UInt_t i = 0; i < f_signal.size(); i++){
|
||||
f_signal.at(i) /= f_sig_norm;
|
||||
f_bckgnd.at(i) /= f_sig_norm;
|
||||
}
|
||||
|
||||
fcnc::folder fldr(&opts);
|
||||
fcnc::fitter f(&opts);
|
||||
fcnc::bu2kstarmumu_plotter thePlotter(&opts);
|
||||
|
||||
std::vector< std::vector<fcnc::bu2kstarmumu_parameters*> >theParameters;
|
||||
std::vector< std::vector<fcnc::bu2kstarmumu_pdf*> > thePDFs;
|
||||
for(UInt_t c = 0; c < nBins; c++){
|
||||
//add vector of params to matrix:
|
||||
std::vector<fcnc::bu2kstarmumu_parameters*> params_per_bin;
|
||||
params_per_bin.clear();
|
||||
theParameters.push_back(params_per_bin);
|
||||
|
||||
//add vector of pdfs to matrix:
|
||||
std::vector<fcnc::bu2kstarmumu_pdf*> pdf_per_bin;
|
||||
pdf_per_bin.clear();
|
||||
thePDFs.push_back(pdf_per_bin);
|
||||
}
|
||||
assert(theParameters.size() == nBins);
|
||||
assert(thePDFs.size() == nBins);
|
||||
|
||||
//pointers to current parameter, pdf and generator:
|
||||
fcnc::bu2kstarmumu_parameters * params[nBins];
|
||||
fcnc::bu2kstarmumu_pdf * prob[nBins];
|
||||
fcnc::bu2kstarmumu_generator * gen = nullptr;
|
||||
|
||||
std::vector<int> fitresults;
|
||||
std::vector<fcnc::event>selection;
|
||||
|
||||
//number of fits is either determined by the larger number of pulls or fits requested
|
||||
UInt_t nFits = nPulls;
|
||||
|
||||
//vectors to save values for pull plots:
|
||||
std::vector<int>var_indexs;
|
||||
std::vector< std::vector< std::vector<double> > >pull_values;
|
||||
std::vector< std::vector< std::vector<double> > >pull_errors;
|
||||
std::vector< std::vector<double> >pull_starts;
|
||||
|
||||
|
||||
//initialize parameters, events and fitter for every FitTest:
|
||||
for(UInt_t n = 0; n < nFits; n++){
|
||||
|
||||
//if binning is used, loop over the number of q2 bins, else only run loop once!
|
||||
for(UInt_t b = 0; b < nBins; b++){
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "****************************************" << std::endl;
|
||||
std::cout << "[FIT]\t\tStarting fit >> " << n << " <<" << std::endl;
|
||||
std::cout << "[FIT]\t\tIn bin >> " << b << " <<" << std::endl;
|
||||
std::cout << "****************************************" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
opts.swave = true;
|
||||
|
||||
opts.q2_min = UseBinnedFit ? opts.TheQ2binsmin.at(b) : opts.TheQ2binsmin.front();
|
||||
opts.q2_max = UseBinnedFit ? opts.TheQ2binsmax.at(b) : opts.TheQ2binsmax.back();
|
||||
|
||||
if(n == 0){
|
||||
//initiate parameters for mass fit
|
||||
params[b] = new fcnc::bu2kstarmumu_parameters(&opts);
|
||||
params[b]->f_sig.init(f_signal.at(b)/(f_signal.at(b)+f_bckgnd.at(b)), 0.0, 1.0, 0.01);
|
||||
if(params[b]->f_sig.get_value() == 0.0)
|
||||
params[b]->m_b.init(PDGMASS_B, B_MASS_LOW, B_MASS_HIGH, 0.0);
|
||||
else
|
||||
params[b]->m_b.init(PDGMASS_B, B_MASS_LOW, B_MASS_HIGH, 0.01);
|
||||
if(opts.twotailedcrystalball)
|
||||
params[b]->m_res_1.init(1.0, 0.0, 1.0, 0.0);
|
||||
else
|
||||
params[b]->m_res_1.init(0.391, 0.0, 1.0, 0.0);// 0.01);
|
||||
params[b]->fm_tau.init(1.0, 0.0, 1.0, 0.0);
|
||||
if(opts.fit_lambda){
|
||||
if(params[b]->f_sig.get_value() == 1.0)
|
||||
params[b]->m_lambda.init(f_bckcoeff.at(b), -1.0e-1, -1.0e-6, 0);
|
||||
else
|
||||
params[b]->m_lambda.init(f_bckcoeff.at(b), -1.0e-1, -1.0e-6, 1.0e-5);
|
||||
params[b]->m_lambda_2.init(-1.664e-3, -1.0e-1, -1.0e-6, 0.0);
|
||||
params[b]->m_tau.init( 1./2.835e-3, 100.0, 1.0e+4, 0.0);
|
||||
params[b]->m_tau_2.init(1./1.664e-3, 0.0, 1.0e+4, 0.0);
|
||||
}
|
||||
else{
|
||||
params[b]->m_lambda.init(-1.0e-3, -1.0e-1, -1.0e-6, 0.0);
|
||||
params[b]->m_lambda_2.init(-1.5e-3, -1.0e-1, -1.0e-6, 0.0);
|
||||
params[b]->m_tau.init(-1./f_bckcoeff.at(b), 100.0, 1.0e+4, 1.0);
|
||||
params[b]->m_tau_2.init(6.01e+2, 0.0, 1.0e+4, 0.0);
|
||||
}
|
||||
if(opts.twotailedcrystalball)
|
||||
params[b]->m_sigma_1.init(f_sigma_1[n], 5.0, 200.0, 0.0);//, 0.1);
|
||||
else{
|
||||
params[b]->m_sigma_1.init(f_sigma_1[n], 5.0, 200.0, 0.0);//, 0.1);
|
||||
params[b]->m_sigma_2.init(f_sigma_2[n], 5.0, 200.0, 0.0);//, 0.1);
|
||||
}
|
||||
params[b]->alpha_1.init(f_alpha_1[n], 0.1, 10.0, 0.0);//, 0.15);
|
||||
params[b]->alpha_2.init(f_alpha_2[n], 0.1, 10.0, 0.0);//, 0.20);
|
||||
params[b]->n_1.init(f_n_1[n], 0.1, 15.0, 0.0);//, 2.0);
|
||||
params[b]->n_2.init(f_n_2[n], 0.1, 10.0, 0.0);//, 0.16);
|
||||
params[b]->m_scale.init(f_m_scale[n], 0.0, 2.0, 0.0);
|
||||
|
||||
params[b]->load_only_Bmass_param_values("fitresult_SignalFit_MC_SimultaneousFit_2Dfit_bin"+std::to_string(b)+"_pdf"+std::to_string(n)+".txt");
|
||||
|
||||
//S-wave
|
||||
double sWaveStepSize = 0.01;
|
||||
params[b]->FS.init(SwaveFraction, 0.0, 1.0, sWaveStepSize);
|
||||
|
||||
//B0 fit results
|
||||
params[b]->SS1.init(-0.231, -1.0, 1.0, (opts.full_angular || opts.folding != 4 ? sWaveStepSize : 0.0));
|
||||
params[b]->SS2.init( 0.023, -1.0, 1.0, (opts.full_angular || opts.folding == 1 ? sWaveStepSize : 0.0));
|
||||
params[b]->SS3.init( 0.003, -1.0, 1.0, (opts.full_angular || opts.folding == 2 ? sWaveStepSize : 0.0));
|
||||
params[b]->SS4.init( 0.001, -1.0, 1.0, (opts.full_angular || opts.folding > 2 ? sWaveStepSize : 0.0));
|
||||
params[b]->SS5.init(-0.068, -1.0, 1.0, (opts.full_angular ? sWaveStepSize : 0.0));
|
||||
|
||||
if(opts.fit_mkpi || opts.use_mkpi){
|
||||
params[b]->gammakstar.init(0.0503, 0.01, 0.8, 0.001); //PDG value
|
||||
params[b]->mkstar.init(PDGMASS_K_STAR_PLUS / 1000., 0.7, 1.2, 0.001); //PDG value
|
||||
params[b]->gammakstarplus.init(0.236, 0.1, 1.0, 0.0); //PDG value
|
||||
params[b]->mkstarplus.init(1.41, 1.2, 1.6, 0.0); //PDG value
|
||||
params[b]->asphase.init(TMath::Pi(), 0.0, 2.0*TMath::Pi(), 0.0);
|
||||
params[b]->a.init(1.95, 0.001, 20.0, 0.0);
|
||||
params[b]->r.init(1.78, 0.001, 10.0, 0.0);
|
||||
//background parameter
|
||||
if(params[b]->f_sig() != 1.0){
|
||||
params[b]->cbkgmkpi0.init(1.0, -1.0, 1.0, 0.0);
|
||||
params[b]->cbkgmkpi1.init(0.0, -1.0, 1.0, 0.01);
|
||||
params[b]->cbkgmkpi2.init(0.0, -1.0, 1.0, 0.0);
|
||||
params[b]->cbkgmkpi3.init(0.0, -1.0, 1.0, 0.0);
|
||||
params[b]->cbkgmkpi4.init(0.0, -1.0, 1.0, 0.0);
|
||||
opts.mkpi_threshold = false;
|
||||
params[b]->nthreshold.init(1.5, 0.0, 15.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
//define center of q2bin as effective q2:
|
||||
params[b]->eff_q2.init((UseBinnedFit ? 0.5*(opts.TheQ2binsmin.at(b)+opts.TheQ2binsmax.at(b)) : 6.0), opts.TheQ2binsmin.front(), opts.TheQ2binsmax.back(), 0.0);
|
||||
|
||||
//if only mass fit: do not active angles in fit, i.e. set stepsize to 0.0
|
||||
double angleStepSize = opts.only_Bmass ? 0.0 : 0.001;
|
||||
if(params[b]->f_sig.get_value() == 0.0)
|
||||
angleStepSize = 0.0;
|
||||
if(opts.fit_fl)
|
||||
//params[b]->Fl.init(3.0/4.0*(s1c[b]-s2c[b]/3.0), 0.0, 1.0, angleStepSize);
|
||||
params[b]->Fl.init(1.0-4.0/3.0*s1s[b], 0.0, 1.0, angleStepSize);
|
||||
else
|
||||
params[b]->S1s.init(s1s[b], -1.0, 1.0, angleStepSize);
|
||||
params[b]->S3.init(s3[b], -1.0, 1.0, angleStepSize/10.);
|
||||
params[b]->S4.init(s4[b], -1.0, 1.0, (opts.full_angular || opts.folding == 1 ? angleStepSize : 0.0));
|
||||
params[b]->S5.init(s5[b], -1.0, 1.0, (opts.full_angular || opts.folding == 2 ? angleStepSize : 0.0));
|
||||
if(opts.fit_afb)
|
||||
params[b]->Afb.init(3.0/4.0*s6s[b], -0.75, 0.75, (opts.full_angular || opts.folding == 0 ? angleStepSize: 0.0));
|
||||
else
|
||||
params[b]->S6s.init(s6s[b], -1.0, 1.0, (opts.full_angular || opts.folding == 0 ? angleStepSize : 0.0));
|
||||
params[b]->S7.init(s7[b], -1.0, 1.0, (opts.full_angular || opts.folding == 3 ? angleStepSize/10. : 0.0));
|
||||
params[b]->S8.init(s8[b], -1.0, 1.0, (opts.full_angular || opts.folding == 4 ? angleStepSize/10. : 0.0));
|
||||
params[b]->S9.init(s9[b], -1.0, 1.0, (opts.full_angular || opts.folding == 0 ? angleStepSize/100. : 0.0));
|
||||
|
||||
if(!opts.flat_bkg){
|
||||
//ctl
|
||||
params[b]->cbkgctl0.init(1.0, -1.0, 1.0, 0.0);
|
||||
params[b]->cbkgctl2.init(0.0, -1.0, 1.0, 0.01);
|
||||
params[b]->cbkgctl4.init(0.0, -1.0, 1.0, 0.0);
|
||||
if(opts.full_angular || opts.folding == 0){
|
||||
params[b]->cbkgctl1.init(0.0, -1.0, 1.0, 0.01);
|
||||
params[b]->cbkgctl3.init(0.0, -1.0, 1.0, 0.0);
|
||||
}
|
||||
else{
|
||||
params[b]->cbkgctl1.init(0.0, -1.0, 1.0, 0.0);
|
||||
params[b]->cbkgctl3.init(0.0, -1.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
//ctk
|
||||
params[b]->cbkgctk0.init(1.0, -1.0, 1.0, 0.0);
|
||||
params[b]->cbkgctk2.init(0.05, -1.0, 1.0, 0.01);
|
||||
params[b]->cbkgctk4.init(0.0, -1.0, 1.0, 0.0);
|
||||
if(opts.full_angular || opts.folding != 4){
|
||||
params[b]->cbkgctk1.init(0.1, -1.0, 1.0, 0.01);
|
||||
params[b]->cbkgctk3.init(0.0, -1.0, 1.0, 0.0);
|
||||
}
|
||||
else{
|
||||
params[b]->cbkgctk1.init(0.0, -1.0, 1.0, 0.0);
|
||||
params[b]->cbkgctk3.init(0.0, -1.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
//phi
|
||||
params[b]->cbkgphi0.init(1.0, -1.0, 1.0, 0.0);
|
||||
params[b]->cbkgphi2.init(0.0, -1.0, 1.0, 0.0);
|
||||
params[b]->cbkgphi4.init(0.0, -1.0, 1.0, 0.0);
|
||||
if(opts.full_angular || opts.folding == 0 || opts.folding == 3 || opts.folding == 4){
|
||||
params[b]->cbkgphi1.init(0.0, -1.0, 1.0, 0.0);
|
||||
params[b]->cbkgphi3.init(0.0, -1.0, 1.0, 0.0);
|
||||
}
|
||||
else{
|
||||
params[b]->cbkgphi1.init(0.0, -1.0, 1.0, 0.0);
|
||||
params[b]->cbkgphi3.init(0.0, -1.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
params[b]->load_only_bckgnd_param_values(("fitresult_OnlyBckgnd_bin"+std::to_string(b)+".txt").c_str());
|
||||
|
||||
}
|
||||
}
|
||||
else{
|
||||
//S-wave
|
||||
double sWaveStepSize = 0.01;
|
||||
params[b]->FS.init(SwaveFraction, 0.0, 1.0, sWaveStepSize);
|
||||
/*
|
||||
//JPSI Fit results
|
||||
params[b]->SS1.init( 0.549, -1.0, 1.0, (opts.full_angular || opts.folding != 4 ? sWaveStepSize : 0.0));
|
||||
params[b]->SS2.init(-0.128, -1.0, 1.0, (opts.full_angular || opts.folding == 1 ? sWaveStepSize : 0.0));
|
||||
params[b]->SS3.init( 0.003, -1.0, 1.0, (opts.full_angular || opts.folding == 2 ? sWaveStepSize : 0.0));
|
||||
params[b]->SS4.init(-0.006, -1.0, 1.0, (opts.full_angular || opts.folding > 2 ? sWaveStepSize : 0.0));
|
||||
params[b]->SS5.init(-0.149, -1.0, 1.0, (opts.full_angular ? sWaveStepSize : 0.0));
|
||||
*/
|
||||
|
||||
//B0 fit results
|
||||
params[b]->SS1.init(-0.231, -1.0, 1.0, (opts.full_angular || opts.folding != 4 ? sWaveStepSize : 0.0));
|
||||
params[b]->SS2.init( 0.023, -1.0, 1.0, (opts.full_angular || opts.folding == 1 ? sWaveStepSize : 0.0));
|
||||
params[b]->SS3.init( 0.003, -1.0, 1.0, (opts.full_angular || opts.folding == 2 ? sWaveStepSize : 0.0));
|
||||
params[b]->SS4.init( 0.001, -1.0, 1.0, (opts.full_angular || opts.folding > 2 ? sWaveStepSize : 0.0));
|
||||
params[b]->SS5.init(-0.068, -1.0, 1.0, (opts.full_angular ? sWaveStepSize : 0.0));
|
||||
params[b]->reset_parameters();
|
||||
|
||||
}
|
||||
|
||||
//create vectors to save parameter values for pull plots:
|
||||
if(n == 0){
|
||||
if(doToyPulls || doMCPulls){
|
||||
UInt_t pp = 0;
|
||||
for(UInt_t p = 0; p < params[b]->nparameters(); p++){
|
||||
if(params[b]->get_parameter(p)->get_step_size() != 0.0){
|
||||
if(b == 0){
|
||||
std::vector< std::vector<double> >pulls_per_parameter;
|
||||
pull_values.push_back(pulls_per_parameter);
|
||||
|
||||
std::vector< std::vector<double> >errors_per_parameter;
|
||||
pull_errors.push_back(errors_per_parameter);
|
||||
|
||||
std::vector<double>starts_per_parameter;
|
||||
pull_starts.push_back(starts_per_parameter);
|
||||
|
||||
var_indexs.push_back(p);
|
||||
}
|
||||
//check that vectors have same size and that no alloc error occurs:
|
||||
assert(pp < pull_values.size());
|
||||
assert(var_indexs.size() == pull_values.size());
|
||||
assert(pp < pull_errors.size());
|
||||
assert(var_indexs.size() == pull_errors.size());
|
||||
assert(pp < pull_starts.size());
|
||||
assert(var_indexs.size() == pull_starts.size());
|
||||
|
||||
//save vectors for values and start values to matrices
|
||||
std::vector<double>pulls_per_param_per_bin;
|
||||
pull_values.at(pp).push_back(pulls_per_param_per_bin);
|
||||
std::vector<double>errors_per_param_per_bin;
|
||||
pull_errors.at(pp).push_back(errors_per_param_per_bin);
|
||||
pull_starts.at(pp).push_back(params[b]->get_parameter(p)->get_start_value());
|
||||
|
||||
//increase parameter index:
|
||||
pp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//pdf
|
||||
prob[b] = new fcnc::bu2kstarmumu_pdf(&opts, params[b]);
|
||||
if(opts.use_angular_acc || opts.weighted_fit){
|
||||
prob[b]->load_coeffs_eff_phsp_4d();
|
||||
}
|
||||
prob[b]->update_cached_normalization(params[b]);
|
||||
|
||||
//create vector with events according to the requested fits/pulls
|
||||
selection.clear();
|
||||
|
||||
Double_t nEvents = 0.;
|
||||
|
||||
if(UseBinnedFit){
|
||||
nEvents *= f_signal.at(b)+f_bckgnd.at(b);
|
||||
}
|
||||
else
|
||||
nEvents = nToyEvents;
|
||||
|
||||
std::cout << "Generate " << nEvents << " events!" << std::endl;
|
||||
gen = new fcnc::bu2kstarmumu_generator(&opts);
|
||||
selection = gen->generate(nEvents, params[b], prob[b]);
|
||||
//delete gen;
|
||||
if(!opts.full_angular && opts.always_generate_full_angular){
|
||||
for(UInt_t ee = 0; ee < selection.size(); ee++){
|
||||
fldr.fold(&selection.at(ee));
|
||||
}
|
||||
}
|
||||
|
||||
//check if all angles are almost 0.0
|
||||
if(false){
|
||||
for(UInt_t i = 0; i < selection.size(); i++)
|
||||
if((fabs(selection.at(i).costhetak) < 0.001) && (fabs(selection.at(i).costhetal) < 0.001) && (fabs(selection.at(i).phi) < 0.001))
|
||||
std::cout << "[WARNING]\tEvent" << i << "\tctk: " << selection.at(i).costhetak << "\tctl: " << selection.at(i).costhetal << "\tphi: " << selection.at(i).phi << std::endl;
|
||||
}
|
||||
|
||||
if(n == 0)events_per_bin.push_back(selection.size());
|
||||
|
||||
//deactive the S-wave for the fit!
|
||||
/*
|
||||
opts.swave = false;
|
||||
params[b]->FS.init(0.0, 0.0, 1.0, 0.0);
|
||||
params[b]->SS1.init( 0.0, -1.0, 1.0, 0.0);
|
||||
params[b]->SS2.init( 0.0, -1.0, 1.0, 0.0);
|
||||
params[b]->SS3.init( 0.0, -1.0, 1.0, 0.0);
|
||||
params[b]->SS4.init( 0.0, -1.0, 1.0, 0.0);
|
||||
params[b]->SS5.init( 0.0, -1.0, 1.0, 0.0);
|
||||
*/
|
||||
//set values to jpsi results for the fit!
|
||||
params[b]->FS.init(0.0, 0.0, 1.0, 0.0);
|
||||
params[b]->SS1.init( 0.549, -1.0, 1.0, 0.0);
|
||||
params[b]->SS2.init(-0.128, -1.0, 1.0, 0.0);
|
||||
params[b]->SS3.init( 0.003, -1.0, 1.0, 0.0);
|
||||
params[b]->SS4.init(-0.006, -1.0, 1.0, 0.0);
|
||||
params[b]->SS5.init(-0.149, -1.0, 1.0, 0.0);
|
||||
|
||||
//make sure that the correct coefficients are chosen for the fit:
|
||||
if(!opts.full_angular && (opts.use_angular_acc || opts.weighted_fit) && opts.always_generate_full_angular){
|
||||
prob[b]->load_coeffs_eff_phsp_4d();
|
||||
prob[b]->update_cached_normalization(params[b]);
|
||||
}
|
||||
|
||||
//fit the events:
|
||||
bool do_fit = true;
|
||||
int fitresult = 0;
|
||||
if(do_fit){
|
||||
fitresult = f.fit(prob[b], params[b], &selection);
|
||||
}
|
||||
else{ //don't fit, just update the efficiencies
|
||||
fitresult = 300;
|
||||
if(opts.use_angular_acc || opts.weighted_fit){
|
||||
prob[b]->update_cached_efficiencies(params[b], &selection);
|
||||
}
|
||||
}
|
||||
|
||||
fitresults.push_back(fitresult);
|
||||
//nametag per bin!
|
||||
std::string plotname;
|
||||
plotname = "ToyGen_"+std::to_string(nToyEvents)+"ToyEvents_FS_"+std::to_string(SwaveFraction)+"_";
|
||||
|
||||
plotname.append(angularsuffix);
|
||||
if(UseBinnedFit){
|
||||
plotname.append("_bin"+std::to_string(b));
|
||||
if(Fit1bin)
|
||||
plotname.append("_1BIN");
|
||||
if(Fit2bins)
|
||||
plotname.append("_2BINS");
|
||||
if(FitAllbins)
|
||||
plotname.append("_9BINS");
|
||||
}
|
||||
|
||||
//plot the current pdf with event data:
|
||||
if(n == 0 && opts.write_eps){
|
||||
std::cout << "PLOT: " << selection.size() << " events" << std::endl;
|
||||
thePlotter.plot_data(prob[b], params[b], &selection, get_PullPlot_path(), plotname+"_Fit"+std::to_string(n), true);
|
||||
|
||||
//add pdfs for all binning:
|
||||
thePDFs.at(b).push_back(prob[b]);
|
||||
theParameters.at(b).push_back(params[b]);
|
||||
|
||||
}
|
||||
|
||||
//save param values to pull_values vector:
|
||||
if(doToyPulls){
|
||||
for(UInt_t p = 0; p < var_indexs.size(); p++){
|
||||
int index = var_indexs.at(p);
|
||||
|
||||
double val = params[b]->get_parameter(index)->get_value();
|
||||
double err = params[b]->get_parameter(index)->get_error();
|
||||
|
||||
pull_values.at(p).at(b).push_back(val);
|
||||
pull_errors.at(p).at(b).push_back(err);
|
||||
|
||||
//save values to tree:
|
||||
treeValue = params[b]->get_parameter(index)->get_value();
|
||||
treeStart = params[b]->get_parameter(index)->get_start_value();
|
||||
treeError = params[b]->get_parameter(index)->get_error();
|
||||
treeErrorUp = params[b]->get_parameter(index)->get_error_up();
|
||||
treeErrorDown = params[b]->get_parameter(index)->get_error_down();
|
||||
|
||||
treeIndex = index;
|
||||
treeBin = b;
|
||||
treeFitNumber = n;
|
||||
treeFitResult = fitresult;
|
||||
|
||||
//treeVarName = params[b]->get_parameter(index)->get_name();
|
||||
//treeVarDesc = params[b]->get_parameter(index)->get_description();
|
||||
|
||||
T->Fill();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//save TTree to .root file:
|
||||
if(doToyPulls){
|
||||
TFile * F = new TFile(("PullResults_"
|
||||
+std::to_string(job_id == -10 ? nMCEvents : nToyEvents)
|
||||
+(job_id == -10 ? "_MC_" : "_Toys_")
|
||||
+std::to_string(nPulls)+"_Fits_"
|
||||
+angularsuffix
|
||||
+"_F_S_"+std::to_string(SwaveFraction)
|
||||
+(job_id >= 0 ? "_job"+std::to_string(job_id) : "")
|
||||
+".root").c_str(), "RECREATE");
|
||||
F->cd();
|
||||
T->Write();
|
||||
F->Close();
|
||||
delete T;
|
||||
}
|
||||
}
|
11
Code/FCNCFitter/sources/Run/pulls.hh
Normal file
11
Code/FCNCFitter/sources/Run/pulls.hh
Normal file
@ -0,0 +1,11 @@
|
||||
//Renata Kopecna
|
||||
|
||||
|
||||
#ifndef PULLS_HH
|
||||
#define PULLS_HH
|
||||
|
||||
#include <options.hh>
|
||||
|
||||
void do_pulls(fcnc::options opts, bool doToyPulls, bool doMCPulls, int job_id , double SwaveFraction, UInt_t nPulls, Double_t nToyEvents, UInt_t nMCEvents, std::string angularsuffix, bool Fit1bin, bool Fit2bins, bool FitAllbins);
|
||||
|
||||
#endif // PULLS_HH
|
487
Code/FCNCFitter/sources/Run/toysfit.cc
Normal file
487
Code/FCNCFitter/sources/Run/toysfit.cc
Normal file
@ -0,0 +1,487 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <toysfit.hh>
|
||||
#include <constants.hh>
|
||||
#include <fitter.hh>
|
||||
#include <bu2kstarmumu_pdf.hh>
|
||||
#include <bu2kstarmumu_plotter.hh>
|
||||
#include <folder.hh>
|
||||
#include "generatetoys.hh"
|
||||
#include <design.hh>
|
||||
#include <helpers.hh>
|
||||
#include <paths.hh>
|
||||
#include <event.hh>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
//Fit the toys and save results somewhere
|
||||
int toysfit(fcnc::options opts, unsigned int nBins, bool fitReference, basic_params params, bool onlySig, bool onlyBkg){
|
||||
|
||||
opts.job_id = params.jobID; //Just to be sure
|
||||
spdlog::info("[TOYSFIT]\t Starting fit with jobID {0:d}", opts.job_id);
|
||||
|
||||
//actually fit the toy events
|
||||
const bool do_fit = true;
|
||||
if(!do_fit) spdlog::warn("Fitting of the toy sample is disabled. Set hardcoded 'do_fit' to true in toysfit.cc");
|
||||
//It is useful to save the generated toys in order to debug
|
||||
const bool SaveTheToys = params.index==-1;
|
||||
const bool SaveProjections = params.index==-1;
|
||||
opts.plot_folder = get_ToysFitPlot_path(params);
|
||||
const bool save_init = (params.index==-1 || params.jobID ==0);
|
||||
if(!save_init)spdlog::warn("Saving the initialised parameters for the toy generation is disabled. Set hardcoded 'save_init' to true in toysfit.cc");
|
||||
|
||||
const bool bkgFromHighMass = true;
|
||||
const bool bkgFromLowMass = false;
|
||||
|
||||
const bool SimultaneousFit = true;
|
||||
|
||||
//Fit ranges for angles
|
||||
double angleStepSize = 0.01;
|
||||
double PprimeRangeScale = 10.0;
|
||||
double angleRange = 1.0;
|
||||
if (params.usePprime) angleRange *= PprimeRangeScale;
|
||||
|
||||
double swaveStepSize = 0.1;
|
||||
|
||||
//Set what parameters to fix
|
||||
fixConstr Bmass_FC(!fitReference || onlyBkg,false); //Fix/constrain B mass
|
||||
fixConstr f_sig_FC(false,false); //Fix/constrain f_sig?
|
||||
fixConstr ang_params_FC(false,false); //Fix/constrain angular parameters?
|
||||
fixConstr mass_params_FC(true,false); //Fix/constrain mass parameters?
|
||||
fixConstr bkg_ang_FC(false,false); //Fix/constrain angular background?
|
||||
fixConstr bkg_Kpi_FC(false,false); //Fix/constrain Kst mass background?
|
||||
fixConstr bkg_mass_FC(false, false); //Fix/constrain mass background?
|
||||
//This boolean decides whether to fit the bkg with order of five or of two //TODO: Should be less hardcody
|
||||
bool setCtkToTwo = !fitReference;
|
||||
opts.bkg_order_costhetak = 5;
|
||||
if(params.folding == 4 && !fitReference){
|
||||
setCtkToTwo = false;
|
||||
opts.bkg_order_costhetak = 4;
|
||||
}
|
||||
opts.flat_bkg = false;
|
||||
opts.fit_full_angular_bkg = true; //Do you want to fold also the bkg?
|
||||
|
||||
//Init angular parameters according to SM (true) or previous measurements (false)?
|
||||
opts.initSM = true;
|
||||
|
||||
//Weighted fit
|
||||
opts.weighted_fit = true;
|
||||
|
||||
//Set s-wave parameters to fix
|
||||
fixConstr gammakstar_FC(true,false); //Fix/constrain gammakstar
|
||||
fixConstr gammakstarplus_FC(true,false); //Fix/constrain gammakstar
|
||||
fixConstr sWave_FC(onlyBkg || !fitReference ,false); //Fix/constrain sWave parameters?
|
||||
fixConstr FS_FC(onlyBkg || !fitReference,false);
|
||||
//FS is fixed no matter what
|
||||
//Fix to something else afterwards
|
||||
bool changeFS = false;
|
||||
|
||||
//Do or do not fit s-wave
|
||||
opts.swave = !onlyBkg;//TODO
|
||||
//Fit kpi or not
|
||||
opts.fit_mkpi = opts.swave || onlyBkg;
|
||||
|
||||
//Quick sanity checks
|
||||
if (onlyBkg && onlySig){
|
||||
spdlog::error("Cannot have onlyBkg && onlySig! Returning.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (bkgFromHighMass && bkgFromLowMass){
|
||||
spdlog::error("Cannot have background taken only from upper and only from lower mass sideband at the same time! Returning.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Save plots?
|
||||
opts.write_eps = SaveProjections;
|
||||
opts.write_pdf = false;
|
||||
//Plot less bins for signal channel as the stats are sad there
|
||||
if (!fitReference) opts.plots_m_bins = 30;
|
||||
//Plot less bins for signal channel as the stats are sad there
|
||||
if (!fitReference) opts.plots_mkpi_bins = 20;
|
||||
|
||||
//Fit both mass and angles, use lambda for bkg fit
|
||||
opts.only_angles = false;
|
||||
opts.only_Bmass = false;
|
||||
opts.only_mkpi = false;
|
||||
|
||||
//Use weights and squared hesse
|
||||
opts.shift_lh = false;
|
||||
opts.use_angular_acc = false;
|
||||
opts.hesse_postrun = true;
|
||||
opts.squared_hesse = true;//!(params.index == -1);// fitReference;
|
||||
opts.minos_errors = false;//(params.index == -1); //!fitReference;
|
||||
opts.multiply_eff = false; //Toy generated events have saved acceptance weights!
|
||||
|
||||
//Fit angular BKG
|
||||
opts.individual_penalties = false; //forces individual probabilities for sig and bkg to be positive
|
||||
|
||||
//How would you like to fit mkpi?
|
||||
opts.use_mkpi = false;
|
||||
opts.simple_mkpi = false;
|
||||
opts.isobar = false;
|
||||
opts.generate_mkpi = opts.fit_mkpi || opts.use_mkpi;
|
||||
|
||||
//Get names for the init parameters file and the fitted parameters file
|
||||
const std::string results_file = final_result_name_toys(params.jobID,fitReference, nBins, SimultaneousFit, params, opts.run, opts.only_angles, opts.only_Bmass, onlySig, onlyBkg, bkgFromLowMass, bkgFromHighMass);
|
||||
std::string params_file = init_params_name_toys(params.jobID,fitReference, nBins, SimultaneousFit, params, opts.run, opts.only_angles, opts.only_Bmass, onlySig, onlyBkg, bkgFromLowMass, bkgFromHighMass);
|
||||
|
||||
if (existsTest(results_file) && params.index != -1){
|
||||
spdlog::warn("[SKIP]\t\tJob already run as root-file '"+results_file+"' exists, continue to next job!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Set the available PDFs: this depends on the selected Run for now, so if only one is selected, run over one pdf, if both, use two
|
||||
std::vector<UInt_t> pdf_idx;
|
||||
if (params.Run == 1 || params.Run == 12) pdf_idx.push_back(1);
|
||||
if (params.Run == 2 || params.Run == 12) pdf_idx.push_back(2);
|
||||
|
||||
//we are good to go, now; how many individual pdfs are used?
|
||||
const UInt_t nPDFs = pdf_idx.size();
|
||||
|
||||
//current fitter, plotter, parameteres and pdfs:
|
||||
fcnc::fitter f(&opts);
|
||||
fcnc::options theOptions[nPDFs];
|
||||
fcnc::bu2kstarmumu_plotter * thePlotter[nPDFs];
|
||||
std::vector<fcnc::parameters*> theParams [nBins];
|
||||
std::vector<fcnc::pdf*> theProbs [nBins];
|
||||
std::vector< std::vector<fcnc::event>* > selection[nBins];
|
||||
|
||||
//Initialize common parameters
|
||||
std::vector<std::string> common_params = param_string(opts, false); //All the angular observables are shared
|
||||
if(SimultaneousFit) f.set_common_parameters(common_params);
|
||||
//--------------------------------
|
||||
// Read events
|
||||
//--------------------------------
|
||||
|
||||
//Init vector for the events to be saved, in case required
|
||||
std::vector<fcnc::event> eventsToSave;
|
||||
|
||||
//Loop over PDFs and initialize parameters
|
||||
for(unsigned n = 0; n < nPDFs; n++){
|
||||
unsigned int idx = pdf_idx.at(n);
|
||||
opts.run = idx; //Set proper run to options
|
||||
spdlog::debug("Run {0:d}", opts.run);
|
||||
opts.name = get_ToysFit_label(params.jobID, fitReference, -1, nBins, SimultaneousFit, params, opts.run, opts.only_angles, opts.only_Bmass, onlySig, onlyBkg, bkgFromLowMass, bkgFromHighMass);
|
||||
|
||||
opts.update_angle_ranges(); //Set angles in options back to defaults
|
||||
opts.update_efficiencies = true; //This ensures the acceptance weights to be taken into account
|
||||
opts.plot_label = "Toys";
|
||||
|
||||
//Get options separate for all PDFs
|
||||
theOptions[n] = opts;
|
||||
|
||||
for(UInt_t b = 0; b < nBins; b++){
|
||||
opts.q2_min = theOptions[n].TheQ2binsmin.front();
|
||||
opts.q2_max = theOptions[n].TheQ2binsmax.back();
|
||||
|
||||
//-----------------------------------------
|
||||
// Initialize 1D parameters
|
||||
//-----------------------------------------
|
||||
|
||||
//create parameter sets:
|
||||
fcnc::bu2kstarmumu_parameters * leParameters = new fcnc::bu2kstarmumu_parameters(&theOptions[n]);
|
||||
|
||||
//create PDFs
|
||||
fcnc::bu2kstarmumu_pdf * lePDF = new fcnc::bu2kstarmumu_pdf(&theOptions[n], leParameters);
|
||||
|
||||
//cache the folding and set to -1 for loading mass parameters from non-folded fits to jpsi, MC, etc.
|
||||
int cached_folding = params.folding;
|
||||
params.folding = -1;
|
||||
|
||||
//Inititalize q2 by hand
|
||||
leParameters->eff_q2.init_fixed( bin_center_q2(theOptions[n],b));
|
||||
|
||||
//Init the fraction betweeen sig and bkg
|
||||
if (onlySig) leParameters->f_sig.init_fixed(1.0);
|
||||
else if (onlyBkg) leParameters->f_sig.init_fixed(0.0);
|
||||
else{ //Or both, in that case load the f_sig from mass only fit
|
||||
initialize_parameters_from_MassFit(leParameters,fitReference,idx,b,{"f_sig"},params,f_sig_FC);
|
||||
}
|
||||
|
||||
//**********************************//
|
||||
// //
|
||||
// Bmass //
|
||||
// //
|
||||
//**********************************//
|
||||
|
||||
//Set the Bmass separatelly as it's range is important
|
||||
std::string fileName_dataMass = final_result_name_mass(true, 1, true, params, params.Run);
|
||||
leParameters->init_Bmass(fileName_dataMass,idx,0.5,Bmass_FC);
|
||||
|
||||
|
||||
//Init B mass fit from Jpsi MC
|
||||
if (!onlyBkg){
|
||||
initialize_parameters_from_MCfit(leParameters,true,idx,b, {"alpha_1","alpha_2","n_1","n_2"},params, mass_params_FC);
|
||||
|
||||
//Init the ratio of sigmas in signal MC/reference MC
|
||||
initialize_parameters_from_MassFit(leParameters,true,idx,b,{"m_sigma_1"},params,fixConstr(!fitReference,false));
|
||||
if (!fitReference){
|
||||
leParameters->m_scale.init_fixed(get_sigmaRatio_fromMC(params,nBins,b,pdf_idx.at(n)));
|
||||
}
|
||||
else{
|
||||
leParameters->m_scale.init_fixed(1.0);
|
||||
}
|
||||
}
|
||||
|
||||
//Init the mass background from mass fit to reference for now
|
||||
//TODO: set as a proper vector depending on using 2 lambdas or anything
|
||||
if (!onlySig) initialize_parameters_from_MassFit(leParameters,fitReference,idx,b,{"m_lambda"},params,bkg_mass_FC);
|
||||
|
||||
//**********************************//
|
||||
// //
|
||||
// Angles //
|
||||
// //
|
||||
//**********************************//
|
||||
|
||||
//Init angular parameters from MC
|
||||
if (!onlyBkg){
|
||||
if (opts.initSM){
|
||||
leParameters->init_angular_parameters(nBins,b,ang_params_FC.fix ? 0.0 : angleStepSize,1.0,false); //TODO: make it better
|
||||
}
|
||||
else{
|
||||
if (fitReference) leParameters->init_ang_parameters_fromRefDavid(b,1.0,0.01);
|
||||
else initialize_parameters_from_MCfit(leParameters,false,idx,b,param_string(opts, true),params, ang_params_FC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Init the bkg parameters from the BKG fit file
|
||||
if (!onlySig){
|
||||
if (opts.flat_bkg) leParameters->use_default_bkg();
|
||||
else{
|
||||
//First init the background for angles for all orders
|
||||
initialize_parameters_from_BkgFit(leParameters, true,
|
||||
bkgFromLowMass, bkgFromHighMass,false, 12,b,
|
||||
PAR_BKG_STRING(-1,opts.bkg_order_costhetal,opts.bkg_order_costhetak),
|
||||
params,fixConstr(true,false));
|
||||
//Now let float only the ones actually used by the folding
|
||||
initialize_parameters_from_BkgFit(leParameters, true,
|
||||
bkgFromLowMass, bkgFromHighMass,false, 12,b,
|
||||
PAR_BKG_STRING(cached_folding,opts.bkg_order_costhetal,opts.bkg_order_costhetak),
|
||||
params,bkg_ang_FC);
|
||||
if (opts.bkg_order_costhetak>=3 && cached_folding!=4){
|
||||
leParameters->cbkgctk3.init(-2.25,-3.25,1.5,0.05);
|
||||
}
|
||||
//Then init the background for m_Kpi
|
||||
if (opts.generate_mkpi){
|
||||
initialize_parameters_from_BkgFit(leParameters, true,
|
||||
bkgFromLowMass, bkgFromHighMass,
|
||||
true, 12,
|
||||
b,param_string_bkg_mkpi(),params,bkg_Kpi_FC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//**********************************//
|
||||
// //
|
||||
// S wave and Kstar //
|
||||
// //
|
||||
//**********************************//
|
||||
|
||||
//Init the Kstar mass fit
|
||||
if(opts.generate_mkpi){
|
||||
//p-wave
|
||||
leParameters->init_mkpi_pWave_parameters(fitReference,gammakstar_FC.fix ? 0.0:0.01);
|
||||
//s-wave
|
||||
if (opts.swave) leParameters->init_mkpi_sWave_parameters(fitReference,gammakstarplus_FC.fix ? 0.0:0.001);
|
||||
}
|
||||
if (opts.swave){
|
||||
leParameters->init_sWave_parameters(sWave_FC.fix ? 0.0 : swaveStepSize);
|
||||
std::string RefMassFile = final_result_name_mass(true,1,true,params,params.Run);
|
||||
if (!fitReference) leParameters->FS.init(0.25,-0.25,1.0,FS_FC.fix ? 0.0 : 0.1);
|
||||
else leParameters->get_param_from_rootfile(RefMassFile, {"FS"}, idx, 0,FS_FC);
|
||||
if (changeFS) leParameters->FS.set_constant();
|
||||
}
|
||||
|
||||
//set folding back to configured value using the cached value from above:
|
||||
params.folding = cached_folding;
|
||||
|
||||
spdlog::info("[PDF{0:d}]\tSaved PDF and parameters!", n);
|
||||
|
||||
//Save the events now
|
||||
std::vector<fcnc::event> * leEvents = new std::vector<fcnc::event>;
|
||||
if(theOptions[n].job_id >= 0){
|
||||
//Seed is opts->get_job_id()*opts->ncores+thread_id+12345 if opts->static_seed, else take from the internal clock backwards
|
||||
std::vector<fcnc::event> evts = generateToys(params, b, pdf_idx.at(n),
|
||||
leParameters,theOptions[n]);
|
||||
//copy generated events to pointer vector object
|
||||
leEvents->clear();
|
||||
//count the number of dismissed events:
|
||||
unsigned int dismissed = 0;
|
||||
for(auto evt: evts){
|
||||
theOptions[n].update_angle_ranges(); //Update angle ranges based on the folding
|
||||
//filter events, that are outside the defined angular range:
|
||||
if(!filterFldFour(&evt, &theOptions[n])){ //I don't think this should be here at all
|
||||
dismissed++;
|
||||
continue;
|
||||
}
|
||||
leEvents->push_back(evt);
|
||||
}
|
||||
spdlog::info("{0:d} generated events are outside the angular range and are dismissed from the sample", dismissed);
|
||||
assert(leEvents->size()+dismissed == evts.size());
|
||||
}
|
||||
else{ //Just load all events TODO
|
||||
std::vector<fcnc::event> evts = fcnc::load_events("/home/lhcb/kopecna/B2KstarMuMu/code/ewp-Bplus2Kstmumu-AngAna/FCNCfitter/Toys/Toy_toyfit__JpsiFit_1BIN_Run12_SimultaneousFit_6.root","Events", -1); //copy generated events to pointer vector object
|
||||
leEvents->clear();
|
||||
for(auto evt: evts)leEvents->push_back(evt);
|
||||
assert(leEvents->size() == evts.size());
|
||||
}
|
||||
|
||||
spdlog::info("[PDF{0:d}]\tFinished generating the events: {1:d}", n, leEvents->size());
|
||||
if (!onlySig && setCtkToTwo){
|
||||
theOptions[n].bkg_order_costhetak = 2;
|
||||
leParameters->use_default_bkg();
|
||||
leParameters->init_angular_background_parameters(fitReference,0.01);
|
||||
}
|
||||
if (changeFS){
|
||||
leParameters->FS.init_fixed(0.0);
|
||||
leParameters->SS1.init_fixed(0.0);
|
||||
leParameters->SS2.init_fixed(0.0);
|
||||
leParameters->SS3.init_fixed(0.0);
|
||||
leParameters->SS4.init_fixed(0.0);
|
||||
leParameters->SS5.init_fixed(0.0);
|
||||
}
|
||||
|
||||
leParameters->take_current_as_start();
|
||||
lePDF->load_coeffs_eff_phsp_4d();
|
||||
lePDF->update_cached_normalization(leParameters);
|
||||
theParams [b].push_back(leParameters);
|
||||
theProbs [b].push_back(lePDF);
|
||||
lePDF->update_cached_efficiencies(leParameters, leEvents);
|
||||
|
||||
if (SaveTheToys){
|
||||
//save all events into one vector, except for the fifth (extra wide bin) in the 5BIN scheme. this would be double counting events
|
||||
if(!(nBins == 5 && b == 4))eventsToSave.insert(eventsToSave.end(),leEvents->begin(),leEvents->end());
|
||||
}
|
||||
|
||||
//save event vector in vector
|
||||
selection[b].push_back(leEvents);
|
||||
} //end loop over bins
|
||||
theOptions[n].update_efficiencies = false;//Prevent the weights to be applied several more times in fitter::fit
|
||||
} //end loop over PDFs
|
||||
|
||||
//validate correct saving to of all events:
|
||||
for(unsigned n = 0; n < nPDFs; n++){
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
if(selection[b].at(n)->size() > 0){
|
||||
spdlog::info("[PDF{0:d}]\t[BIN{1:d}]\tDone!", n, b);
|
||||
}
|
||||
else{
|
||||
spdlog::critical("No events found for PDF={0:d} and q2-bin={1:d} Exit!", n, b);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
spdlog::info("Finished configurating all parameters, defining all pdfs and generating all toy event samples:");
|
||||
|
||||
//If required to save the generated events, save them
|
||||
if (SaveTheToys){
|
||||
std::string eventsFile = get_finalToys_file(fitReference,nBins,SimultaneousFit,params,params.Run);
|
||||
replace(eventsFile,".root","_"+std::to_string(params.jobID)+".root"); //Add the number of the job to the file name
|
||||
fcnc::save_events(eventsFile,eventsToSave);
|
||||
}
|
||||
//Save the initial toy values in a root file
|
||||
|
||||
std::vector<int>tmp[nBins]; //Create a vector array with zeros, so you can save init values before the fit
|
||||
for(unsigned int b = 0; b < nBins; b++)tmp[b] = std::vector<int>(nPDFs, 0);
|
||||
if(save_init) save_results(params_file,nBins,pdf_idx,tmp,theParams,SimultaneousFit,&opts);
|
||||
|
||||
//Save the fit results
|
||||
std::vector<int>fit_results[nBins];
|
||||
|
||||
//fit all bins:
|
||||
for(unsigned int b = 0; b < nBins; b++){
|
||||
spdlog::info("");
|
||||
spdlog::warn("[START]\tStart fit BIN{0:d}", b);
|
||||
|
||||
//Int for fit status
|
||||
int fitresult = 0;
|
||||
|
||||
if(!SimultaneousFit){
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
|
||||
//Delete the texFile
|
||||
std::string tag = get_ToysFit_label(params.jobID, fitReference, b, nBins,
|
||||
false, params, opts.run,
|
||||
opts.only_angles, opts.only_Bmass,
|
||||
onlySig, onlyBkg,
|
||||
bkgFromLowMass, bkgFromHighMass);
|
||||
|
||||
spdlog::info("[FIT{0:d}]\tRunning the fitter...", n);
|
||||
if(do_fit)fitresult = f.fit(theProbs[b].at(n), theParams[b].at(n), selection[b].at(n),tag);
|
||||
fit_results[b].push_back(fitresult);
|
||||
}
|
||||
}
|
||||
else{
|
||||
spdlog::info("[FIT]\tFitting simultaenously....");
|
||||
std::string tag = "";
|
||||
for(UInt_t n = 0; n < nPDFs; n++)for(UInt_t e = 0; e < selection[b].at(n)->size(); e++)spdlog::trace("Event for fitting: pdf={0:d}\t bin={1:d}\t evt={2:d}\t ctk={3:f}\t ctl={4:f}\t phi={5:f}\t m={6:f}\t mkpi={7:f}", n, b, e, selection[b].at(n)->at(e).costhetak, selection[b].at(n)->at(e).costhetal, selection[b].at(n)->at(e).phi, selection[b].at(n)->at(e).m, selection[b].at(n)->at(e).mkpi);
|
||||
|
||||
if(do_fit)fitresult = f.fit(theProbs[b], theParams[b], selection[b], tag);
|
||||
fit_results[b].push_back(fitresult);
|
||||
spdlog::info("Q2BIN={0:d}: LLH={1:f}", b, f.likelihood());
|
||||
}
|
||||
|
||||
//Print the fit results
|
||||
spdlog::info("[BIN{0:d}]: Fitresult: {1:d}", b, fitresult);
|
||||
spdlog::info("");
|
||||
}
|
||||
|
||||
//Plot stuff if wanted
|
||||
if (SaveProjections){
|
||||
//If needed, also save the projections for the toys
|
||||
//plot each set of pdfs with the data points:
|
||||
bool plotPulls = true;
|
||||
for(UInt_t b = 0; b < nBins; b++){
|
||||
for(UInt_t n = 0; n < nPDFs; n++){
|
||||
thePlotter[n] = new fcnc::bu2kstarmumu_plotter(&theOptions[n]);
|
||||
|
||||
//plot pdf and events:
|
||||
std::string eps_label = get_ToysFit_label(params.jobID, fitReference, b, nBins,
|
||||
SimultaneousFit, params, pdf_idx.at(n),
|
||||
opts.only_angles, opts.only_Bmass,
|
||||
onlySig, onlyBkg,
|
||||
bkgFromLowMass, bkgFromHighMass);
|
||||
|
||||
theOptions[n].plot_label = "Toys";
|
||||
|
||||
if (!fitReference) theOptions[n].plots_m_bins = 30;
|
||||
if (!fitReference) theOptions[n].plots_mkpi_bins = 20;
|
||||
theOptions[n].q2_label = q2_label(opts.TheQ2binsmin.at(b), opts.TheQ2binsmax.at(b));
|
||||
|
||||
spdlog::info("[PLOT]\t"+eps_label);
|
||||
thePlotter[n]->SetPulls(plotPulls);
|
||||
thePlotter[n]->plot_data((fcnc::bu2kstarmumu_pdf*)theProbs[b].at(n), (fcnc::bu2kstarmumu_parameters*)theParams[b].at(n), selection[b].at(n), get_ToysFitPlot_path(params), eps_label, true);
|
||||
thePlotter[n]->plot_data((fcnc::bu2kstarmumu_pdf*)theProbs[b].at(n), (fcnc::bu2kstarmumu_parameters*)theParams[b].at(n), selection[b].at(n), get_ToysFitPlot_path(params), eps_label+"_incBkg", false);
|
||||
|
||||
}
|
||||
|
||||
std::vector<fcnc::bu2kstarmumu_pdf*> * prober = (std::vector<fcnc::bu2kstarmumu_pdf*> *) & theProbs[b];
|
||||
|
||||
std::string eps_label = get_ToysFit_label(params.jobID, fitReference, b, nBins,
|
||||
SimultaneousFit, params, params.Run,
|
||||
opts.only_angles, opts.only_Bmass,
|
||||
onlySig, onlyBkg,
|
||||
bkgFromLowMass, bkgFromHighMass);
|
||||
std::vector<fcnc::bu2kstarmumu_parameters*> * paramser = (std::vector<fcnc::bu2kstarmumu_parameters*> *) & theParams[b];
|
||||
thePlotter[0]->SetPulls(plotPulls);
|
||||
thePlotter[0]->plot_added_pdfs(prober, paramser, & selection[b], get_ToysFitPlot_path(params), eps_label, true);
|
||||
thePlotter[0]->plot_added_pdfs(prober, paramser, & selection[b], get_ToysFitPlot_path(params), eps_label+"_incBkg", false);
|
||||
}//end loop over bins
|
||||
}
|
||||
|
||||
spdlog::info("[TOYFIT] Fit status results:");
|
||||
if(SimultaneousFit){
|
||||
for(UInt_t b = 0; b < nBins; b++)spdlog::info("[BIN{0:d}]: {1:d}", b, fit_results[b].at(0));
|
||||
}
|
||||
else{
|
||||
for(UInt_t b = 0; b < nBins; b++)for(UInt_t n = 0; n < nPDFs; n++)spdlog::info("[BIN{0:d}][PDF{1:d}]: {2:d}", b, n, fit_results[b].at(n));
|
||||
}
|
||||
if (params.index == -1) print_all_parameters(nBins, pdf_idx, theParams, spdlog::level::info);
|
||||
//saving results to root file
|
||||
save_results(results_file,nBins,pdf_idx,fit_results,theParams,SimultaneousFit,&opts);
|
||||
|
||||
spdlog::info("[TOYFIT] Finished.");
|
||||
return 0;
|
||||
}
|
11
Code/FCNCFitter/sources/Run/toysfit.hh
Normal file
11
Code/FCNCFitter/sources/Run/toysfit.hh
Normal file
@ -0,0 +1,11 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef TOYS_HH
|
||||
#define TOYS_HH
|
||||
|
||||
#include <options.hh>
|
||||
#include <parse.hh>
|
||||
|
||||
int toysfit(fcnc::options opts, unsigned int nBins, bool fitReference, basic_params params, bool onlySig, bool onlyBkg);
|
||||
|
||||
#endif // TOYS_HH
|
759
Code/FCNCFitter/sources/Scripts/EvaluateToys.cc
Normal file
759
Code/FCNCFitter/sources/Scripts/EvaluateToys.cc
Normal file
@ -0,0 +1,759 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <TChain.h>
|
||||
#include <TH1D.h>
|
||||
#include <TF1.h>
|
||||
#include <TCanvas.h>
|
||||
#include <TFile.h>
|
||||
#include <TMath.h>
|
||||
#include <TColor.h>
|
||||
#include <TLegend.h>
|
||||
#include <TStyle.h>
|
||||
#include <TLatex.h>
|
||||
#include <TROOT.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <RooDataSet.h>
|
||||
#include <RooGaussian.h>
|
||||
#include <RooFitResult.h>
|
||||
#include <RooPlot.h>
|
||||
#include <RooRealVar.h>
|
||||
#include "EvaluateToys.hh"
|
||||
#include <design.hh>
|
||||
#include <helpers.hh>
|
||||
#include "ScriptHelpers.hh"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
//This code is as broken as it gets, the string for latex names and var names should be in a struct so when one has to skip stuff one can also skip the name and value actually
|
||||
//This way it is error prone and god knows whether it even saves everything properly
|
||||
//And it should've been connected directly with the csv file... like... no wonder some stuff took that long before
|
||||
|
||||
const bool UnbinnedFit = true;
|
||||
const bool UseCellColor = true;
|
||||
Int_t Idx = 0;
|
||||
|
||||
const UInt_t nPDFs = 2;
|
||||
|
||||
struct pullInfo{
|
||||
double sigma;
|
||||
double sigmaErr;
|
||||
double mean;
|
||||
double meanErr;
|
||||
double failRate;
|
||||
pullInfo(){
|
||||
sigma = DEFAULT_TREE_VAL;
|
||||
sigmaErr = DEFAULT_TREE_ERR;
|
||||
mean = DEFAULT_TREE_VAL;
|
||||
meanErr = DEFAULT_TREE_ERR;
|
||||
failRate = DEFAULT_TREE_VAL;
|
||||
}
|
||||
pullInfo(double sig, double sigErr, double mu, double muErr, double rate){
|
||||
sigma = sig;
|
||||
sigmaErr = sigErr;
|
||||
mean = mu;
|
||||
meanErr = muErr;
|
||||
failRate = rate;
|
||||
}
|
||||
};
|
||||
|
||||
struct q2Bins{
|
||||
unsigned int nBins;
|
||||
std::vector<double> q2min;
|
||||
std::vector<double> q2max;
|
||||
|
||||
q2Bins(basic_params params){
|
||||
nBins = params.nBins;
|
||||
q2min = get_TheQ2binsmin(nBins, params.reference);
|
||||
q2max = get_TheQ2binsmax(nBins, params.reference);
|
||||
}
|
||||
};
|
||||
|
||||
const std::vector<std::vector<double>> bkg_340 = {{47.0,57.0},{0.0,15.0},{-10.0,0.0},{-25.0,-10.0},{-5.0,5.0},{-5.0,3.0},{-48.0,-38.0}};
|
||||
|
||||
//draw legend to the pull plots
|
||||
void drawLegend(TLatex * leg, double q2min, double q2max, pullInfo info,
|
||||
int tot_fits, int oor_fits, int failed_fits){
|
||||
std::ostringstream bindescription;
|
||||
//draw q2 bin
|
||||
bindescription << std::setprecision(2) << std::fixed << "( " << q2min << " < q^{2} < " << q2max << " )";
|
||||
spdlog::trace(bindescription.str());
|
||||
leg->DrawLatex(0.21,0.88, bindescription.str().c_str());
|
||||
//draw mean value
|
||||
std::ostringstream sMean;
|
||||
sMean << std::fixed << std::setprecision(4) << std::fixed << info.mean << " #pm " << info.meanErr;
|
||||
spdlog::trace(sMean.str());
|
||||
leg->DrawLatex(0.13,0.80, "#bf{mean:}");
|
||||
leg->DrawLatex(0.13,0.77, sMean.str().c_str());
|
||||
//draw sigma value
|
||||
std::ostringstream sRMS;
|
||||
sRMS << std::fixed << std::setprecision(4) << std::fixed << info.sigma << " #pm " << info.sigmaErr;
|
||||
spdlog::trace(sRMS.str());
|
||||
leg->DrawLatex(0.13,0.73, "#bf{sigma:}");
|
||||
leg->DrawLatex(0.13,0.69, sRMS.str().c_str());
|
||||
//draw percentage of results in histo range
|
||||
//
|
||||
//std::ostringstream sInRange;
|
||||
//sInRange << std::fixed << std::setprecision(1) << std::fixed << 100. * (tot_fits - oor_fits - failed_fits) / (tot_fits - failed_fits) << "% in range";
|
||||
//spdlog::trace(sInRange.str());
|
||||
//leg->DrawLatex(0.13,0.64, sInRange.str().c_str());
|
||||
//draw failRate
|
||||
std::ostringstream sfailRate;
|
||||
if(!UnbinnedFit){
|
||||
sfailRate << std::fixed << std::setprecision(1) << std::fixed << info.failRate << "% failed";
|
||||
spdlog::trace(sfailRate.str());
|
||||
leg->DrawLatex(0.13,0.59, sfailRate.str().c_str());
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//function to load toy fit results of one angular observables and create pull (or residual) plots for each q2 bin.
|
||||
//In this function the histogram is fitted using a single Gaussian bell shape. Either a standard binned fit or a RooFit unbinned fit
|
||||
//weirdShape is there for the cases the fitter generates stuff with different parameters than it fits, eg different polynomial bkg description
|
||||
std::vector<pullInfo> eval_toys(std::string filename, std::string treename, basic_params params,
|
||||
bool doPulls, double pullRange_low, double pullRange_high, int whichPDf){
|
||||
|
||||
const q2Bins bins(params);
|
||||
|
||||
//configure TPad style format and suppress pop-up windows from TCanvas:
|
||||
gROOT->SetBatch(kTRUE);
|
||||
gROOT->SetStyle("Plain");
|
||||
TPad foo;
|
||||
set_gStyle();
|
||||
gStyle->SetOptTitle(0);
|
||||
gStyle->SetTitleFont(132, "t");
|
||||
gStyle->SetTextFont(132);
|
||||
gStyle->SetEndErrorSize(10.0);
|
||||
gErrorIgnoreLevel = kWarning;
|
||||
RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR);
|
||||
|
||||
|
||||
//start loading the values from the toy fit results root files:
|
||||
std::vector<unsigned int> tot_fits(bins.nBins, 0); //counter for total fits
|
||||
std::vector<unsigned int> oor_fits(bins.nBins, 0); //counter for fit results outside the histogram range (oor=out of range)
|
||||
std::vector<unsigned int> failed_fits(bins.nBins, 0); //counter for fits with non-300 fit result
|
||||
|
||||
std::vector<double> max_value(bins.nBins, -10.);
|
||||
std::vector<double> min_value(bins.nBins, +10.);
|
||||
|
||||
std::vector<double>all_Values[bins.nBins];
|
||||
|
||||
//load chain with all results of bootstrapping
|
||||
TChain * ch = new TChain(treename.c_str());
|
||||
Int_t nFiles = 0;
|
||||
|
||||
//when wildcard [0-9] is used, add all files and the digits of the counter until no files are found
|
||||
//[0-9] stands for any digit, i.e. the combination 'file_[0-9][0-9][0-9][0-9].root' would add all files from 'file_0000.root' to 'file_9999.root'
|
||||
if(filename.find("[0-9]") != std::string::npos){
|
||||
Int_t addedFiles = 1;
|
||||
while(addedFiles > 0){
|
||||
addedFiles = ch->Add(filename.c_str());
|
||||
//add another wildcard to the filename in order to search for files with job IDs in the next order of magnitude
|
||||
filename.replace(filename.find("[0-9]"), 5, "[0-9][0-9]");
|
||||
//Can someone explain to me why the fuck shoudl this be needed?
|
||||
//add the number of found files to the total number of files
|
||||
nFiles += addedFiles;
|
||||
}
|
||||
}
|
||||
else{ //if no wildcard '[0-9]' or the general wildcard '*' is used, simply add all files:
|
||||
nFiles = ch->Add(filename.c_str());
|
||||
}
|
||||
|
||||
//check that at least one file with at least one entry is found:
|
||||
if(nFiles == 0){
|
||||
spdlog::error("No files found for name='"+filename+"'.");
|
||||
return {};
|
||||
}
|
||||
UInt_t nEntries = ch->GetEntries();
|
||||
if(nEntries == 0){
|
||||
spdlog::error("No entries found in files for tree='"+treename+"'.");
|
||||
return {};
|
||||
}
|
||||
//make sure that the number of entries is equivalent to the number of files times the number of q2 bins times the number of simultaneous PDFs
|
||||
if(TMath::Abs((int)(nEntries/(nPDFs*bins.nBins))) != TMath::Abs(nFiles)){
|
||||
spdlog::error("Number of entries found in files for tree='"+treename+"' does not match the number of files.");
|
||||
return {};
|
||||
}
|
||||
spdlog::info("[LOAD]\t\tReading {0:d} events from {1:d} files for variable='{2:s}'.", nEntries, nFiles, treename);
|
||||
|
||||
//link variables to branches
|
||||
double startvalue= DEFAULT_TREE_VAL; //TODO: check the start_value of the parameter is not changed anywhere, as it isn't a const it is very likely it is changed
|
||||
double value = DEFAULT_TREE_VAL;
|
||||
double error = DEFAULT_TREE_ERR;
|
||||
double errorup = DEFAULT_TREE_ERR;
|
||||
double errordown = DEFAULT_TREE_ERR;
|
||||
|
||||
int migrad = DEFAULT_TREE_INT;
|
||||
int cov = DEFAULT_TREE_INT;
|
||||
int bin = DEFAULT_TREE_INT;
|
||||
int pdf = DEFAULT_TREE_INT;
|
||||
|
||||
ch->SetBranchStatus("*",1); //TODO optimize
|
||||
ch->SetBranchAddress("value", &value);
|
||||
ch->SetBranchAddress("start_value", &startvalue);
|
||||
ch->SetBranchAddress("error", &error);
|
||||
ch->SetBranchAddress("error_up", &errorup);
|
||||
ch->SetBranchAddress("error_down", &errordown);
|
||||
ch->SetBranchAddress("migrad", &migrad);
|
||||
ch->SetBranchAddress("status_cov", &cov);
|
||||
ch->SetBranchAddress("bin", &bin);
|
||||
ch->SetBranchAddress("pdf", &pdf);
|
||||
|
||||
//create a new simple tree that used the calculated pull or residual value, in case that unbinned fit is selected
|
||||
//this tree is used as input to the RooFitter
|
||||
TTree * unbinnedTree = nullptr;
|
||||
double x; //this variable is used for either the pull or residual value (depending on arg 'doPulls')
|
||||
if(UnbinnedFit){
|
||||
unbinnedTree = new TTree("tmp_tree", "tmp_tree");
|
||||
unbinnedTree->Branch("value", &x);
|
||||
unbinnedTree->Branch("bin", &bin);
|
||||
}
|
||||
//or else create histograms for the binned fit:
|
||||
TH1D * h_pull[bins.nBins];
|
||||
TH1D * h_values[bins.nBins];
|
||||
|
||||
|
||||
double binwidth = doPulls ? 0.5 : 0.05;//0.05;
|
||||
double xrange = doPulls ? 2.0*pullRange_high : 1.0;//2.0;
|
||||
if(!UnbinnedFit){
|
||||
for(UInt_t b = 0; b < bins.nBins; b++){ //FUCK PEOPLE WHO DON'T DO BRACKETS
|
||||
h_pull[b] = new TH1D((treename+"_bin"+std::to_string(b)).c_str(),
|
||||
(treename+" in q^{2} bin #"+std::to_string(b)+(doPulls ? ";(x-x_{nomi.})/#sigma" : ";(x-x_{nomi.})")+";entries").c_str(),
|
||||
2*xrange/binwidth, -xrange, +xrange);
|
||||
}
|
||||
}
|
||||
spdlog::debug("Finished initializing the histograms");
|
||||
|
||||
//load results from files:
|
||||
for(UInt_t e = 0; e < nEntries; e++){
|
||||
//since all PDFs are saved in the TTree, only use 8(5) q2bins out of 32(10) for the KS0(pi0) channel
|
||||
//Eeee... e?
|
||||
//if(e%(bins.nBins*nPDFs) > (bins.nBins-1)) continue;
|
||||
|
||||
ch->GetEntry(e);
|
||||
|
||||
if(pdf != whichPDf) continue;
|
||||
spdlog::trace("Parameter value at entry {0:d}: {1:f}", e, value);
|
||||
all_Values[bin].push_back(value);
|
||||
tot_fits.at(bin)++;
|
||||
|
||||
//require convered migrad
|
||||
if(migrad != 0){
|
||||
failed_fits.at(bin)++;
|
||||
continue;
|
||||
}
|
||||
//require fitresult = 300 or 100 (or 200)
|
||||
if(!(cov == 1 || cov == 3 || cov == 2)){
|
||||
failed_fits.at(bin)++;
|
||||
continue;
|
||||
}
|
||||
|
||||
//derive residual and pull
|
||||
double diff = value - startvalue;
|
||||
if(error == 0. || isnan(error)){
|
||||
spdlog::error("[{0:s}][BIN{1:d}]{2:d}\tError equal to zero!", treename, bin, e);
|
||||
return {};
|
||||
}
|
||||
double pull = diff/error;
|
||||
spdlog::trace("[{0:s}][BIN{1:d}]{2:d}\tdiff={3:f}\tpull={4:f}\terr={5:f}", treename, bin, e, diff, pull, error);
|
||||
|
||||
if(UnbinnedFit){
|
||||
//assign pull or residual to 'x' and save in TTree
|
||||
x = doPulls ? pull : diff; //x, pull and diff is never used? //TODO
|
||||
unbinnedTree->Fill();
|
||||
}
|
||||
else{//Binned fit
|
||||
if(TMath::Abs(diff) <= xrange){
|
||||
if(doPulls){
|
||||
//fill pull to histogram:
|
||||
h_pull[bin]->Fill(pull);
|
||||
//determine range of pull values
|
||||
max_value.at(bin) = std::max(max_value.at(bin),pull);
|
||||
min_value.at(bin) = std::min(min_value.at(bin),pull);
|
||||
}
|
||||
else{
|
||||
h_pull[bin]->Fill(diff);
|
||||
//determine range of diff values
|
||||
max_value.at(bin) = std::max(max_value.at(bin),diff);
|
||||
min_value.at(bin) = std::min(min_value.at(bin),diff);
|
||||
}
|
||||
}
|
||||
else{
|
||||
oor_fits.at(bin)++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
spdlog::debug("Filled all histograms/TTrees with values of variable="+treename+".");
|
||||
spdlog::debug("Tree size="+treename+".");
|
||||
|
||||
//vectors to store the measured mean and widths of the pull(residual) distributions
|
||||
std::vector<pullInfo> allInfo;
|
||||
|
||||
//init some nullptr RooFit objects, to make the compiler happy. (These two are needed later in the plotting of the histograms)
|
||||
RooGaussian * roogaus[bins.nBins];
|
||||
RooDataSet * roodata[bins.nBins];
|
||||
RooRealVar * roovalue[bins.nBins];
|
||||
|
||||
for(UInt_t b = 0; b < bins.nBins; b++){ //loop over q2bins to fit all distributions
|
||||
if(UnbinnedFit){
|
||||
//initialise RooFit objects for the unbinned fit:
|
||||
RooRealVar * roomean, * roosigma, * roobin;
|
||||
roovalue[b] = new RooRealVar("value", "value", pullRange_low, pullRange_high, "");
|
||||
roomean = new RooRealVar("mean", "mean", bin_center(pullRange_low,pullRange_high), pullRange_low, pullRange_high);
|
||||
roosigma = new RooRealVar("sigma", "sigma", doPulls ? 0.85: 0.1, 0., 2.);
|
||||
roobin = new RooRealVar("bin", "q2 bin", -1., 10.0, "");
|
||||
RooArgSet rooarg = RooArgSet(*roovalue[b]);
|
||||
rooarg.add(*roobin);
|
||||
roogaus[b] = new RooGaussian("RooGaus", "RooGaus", *roovalue[b], *roomean, *roosigma);
|
||||
//RooFitResult * result = new RooFitResult("FitResult","FitResult");
|
||||
|
||||
spdlog::debug("Start fitting q2 bin {0:d} for par={1:s}.", b, treename);
|
||||
roodata[b] = new RooDataSet("RooDataSet", "RooDataSet", unbinnedTree, rooarg,
|
||||
("abs(bin-"+std::to_string(b)+") < 0.1").c_str());
|
||||
spdlog::debug("Fit {0:d} events", roodata[b]->numEntries());
|
||||
if(roodata[b]->numEntries() == 0){
|
||||
spdlog::critical("Empty fit not possible for var={0:s} in q2bin={1:d}", treename, b);
|
||||
assert(0);
|
||||
}
|
||||
int fitstatus = roogaus[b]->fitTo(*roodata[b], RooFit::Save(kTRUE),RooFit::PrintLevel(spdlog_trace()?1 : -1))->status();
|
||||
spdlog::debug("[{0:s}][BIN{1:d}]\tFitstatus={2:d}", treename, b, fitstatus);
|
||||
allInfo.push_back(pullInfo(roosigma->getVal(),roosigma->getError(),
|
||||
roomean->getVal(),roomean->getError(),fitstatus));
|
||||
}//end unbinned fit
|
||||
else{//binned fit
|
||||
double entries = h_pull[b]->Integral();
|
||||
bool dofit = entries > 10.0 && h_pull[b]->GetRMS(1) > 0.001;
|
||||
spdlog::debug("var={0:s}\t q2bin={1:d}\t DOFIT={2:s}", treename, b, (dofit ? "TRUE" : "FALSE"));
|
||||
|
||||
if(entries < 0.0){
|
||||
spdlog::warn("Negative entries for: q2bin={0:d}\t par={1:s}\t entries={2:d}", b, treename, entries);
|
||||
}
|
||||
|
||||
int fitstatus = 0.0;
|
||||
if(tot_fits.at(b) > 0) fitstatus = (100.0 * failed_fits.at(b) / tot_fits.at(b));
|
||||
|
||||
if(dofit){
|
||||
double minfit = -xrange;
|
||||
double maxfit = +xrange;
|
||||
TF1 * fGauss = new TF1("theGaussian", "gaus(0)", minfit, maxfit);
|
||||
fGauss->SetParameter(0, entries);
|
||||
fGauss->SetParameter(1, h_pull[b]->GetXaxis()->GetBinCenter(h_pull[b]->GetMaximumBin()));
|
||||
if(!doPulls){
|
||||
double mean_range = (treename.find("P") != std::string::npos || treename == "Fl") ? 0.05 : 0.01;
|
||||
fGauss->SetParLimits(1, h_pull[b]->GetXaxis()->GetBinCenter(h_pull[b]->GetMaximumBin()) - mean_range, h_pull[b]->GetXaxis()->GetBinCenter(h_pull[b]->GetMaximumBin()) + mean_range);
|
||||
}
|
||||
fGauss->SetParameter(2, h_pull[b]->GetRMS(1));
|
||||
fGauss->SetParLimits(2, 0.0, doPulls ? 1.5 : 0.1);
|
||||
fGauss->SetLineStyle(kDashed);
|
||||
fGauss->SetLineColor(kMagenta - 3);
|
||||
h_pull[b]->Fit(fGauss, "RQM+");
|
||||
//save values in a vector
|
||||
allInfo.push_back(pullInfo(fGauss->GetParameter(2),fGauss->GetParError(2),
|
||||
fGauss->GetParameter(1),fGauss->GetParError(1),fitstatus));
|
||||
}
|
||||
else{//only use RMS and MEAN obtained by TH1F
|
||||
allInfo.push_back(pullInfo(h_pull[b]->GetRMS(1),h_pull[b]->GetRMSError(1),
|
||||
h_pull[b]->GetMean(1),h_pull[b]->GetMeanError(1),fitstatus));
|
||||
}
|
||||
}//end of binned fit
|
||||
}//end of loops of q2 bins
|
||||
|
||||
|
||||
//save histogram with pulls (or residuals) and the value distributions to file
|
||||
TCanvas* c1 = new TCanvas("c1", "c1", 1600, 1200);
|
||||
c1->cd()->SetMargin(0.1,0.05,0.1,0.05);
|
||||
for(UInt_t b = 0; b < bins.nBins; b++){ //loop over bins.nBins
|
||||
spdlog::debug("Plotting bin {0:b}.",b);
|
||||
|
||||
c1->cd();
|
||||
if(UnbinnedFit){
|
||||
RooPlot * rooframe = roovalue[b]->frame();
|
||||
roodata[b]->plotOn(rooframe);
|
||||
roogaus[b]->plotOn(rooframe);
|
||||
rooframe->Draw();
|
||||
}
|
||||
else{
|
||||
h_pull[b]->Draw();
|
||||
}
|
||||
|
||||
//initiliaze and format a legend:
|
||||
TLatex * leg = getPrettyTex(0.07,13);
|
||||
leg->SetTextColor(kBlack);
|
||||
|
||||
//draw variable name
|
||||
leg->DrawLatex(0.13,0.89, treename.c_str());
|
||||
leg->SetTextSize(0.04);
|
||||
drawLegend(leg,bins.q2min.at(b) ,bins.q2max.at(b),
|
||||
allInfo[b],tot_fits[b],oor_fits[b],failed_fits[b]);
|
||||
c1->Print((get_ToyPullPlot_tag(b,treename,params,false,doPulls) +".eps").c_str(), "eps");
|
||||
if(!UnbinnedFit) delete h_pull[b];
|
||||
|
||||
double max = *max_element(all_Values[b].begin(), all_Values[b].end());
|
||||
double min = *min_element(all_Values[b].begin(), all_Values[b].end());
|
||||
|
||||
h_values[b] = new TH1D(treename.c_str(),
|
||||
(treename+" in q^{2} bin #"+std::to_string(b)+";"+treename+";Entries").c_str(),
|
||||
nFiles/5, min, max);
|
||||
for (auto val: all_Values[b]){
|
||||
h_values[b]->Fill(val);
|
||||
}
|
||||
|
||||
|
||||
//save histogram with values to file
|
||||
plotAndSave(h_values[b],treename,get_ToyPullPlot_tag(b,treename,params,true, false),"eps");
|
||||
|
||||
|
||||
}//end loop over q2 bins
|
||||
|
||||
delete c1;
|
||||
return allInfo;
|
||||
}
|
||||
|
||||
//print the results of the toy studies to latex tables:
|
||||
int print_latex_tables(bool Pprimes, bool doPulls, std::vector< std::string> LaTeXnames, std::vector< std::vector<pullInfo> > lePullInfo, const q2Bins bins, int jobID){
|
||||
if(lePullInfo.size() == 0){
|
||||
spdlog::error("No results found for widths of pull/residual distributrionn");
|
||||
return 1;
|
||||
}
|
||||
|
||||
//generate color palette:
|
||||
TPad foo;
|
||||
TColor::InitializeColors();
|
||||
Double_t stops[9] = { 0.0000, 0.1250, 0.2500, 0.3750, 0.5000, 0.6250, 0.7500, 0.8750, 1.0000};
|
||||
Double_t red[9] = { 55./255., 55./255., 55./255., 55./255., 55./255., 105./255., 155./255., 205./255., 255./255.};
|
||||
Double_t green[9] = { 55./255., 105./255., 155./255., 205./255., 255./255., 205./255., 155./255., 105./255., 55./255.};
|
||||
Double_t blue[9] = { 255./255., 205./255., 155./255., 105./255., 55./255., 55./255., 55./255., 55./255., 55./255.};
|
||||
Idx = TColor::CreateGradientColorTable(9, stops, red, green, blue, 255);
|
||||
|
||||
//in what range should the colors be defined:
|
||||
double colorrange[] = {doPulls ? 0.2 : (Pprimes ? 0.2 : 0.05),
|
||||
doPulls ? 0.2 : (Pprimes ? 0.2 : 0.05),
|
||||
UnbinnedFit ? 2. : 20.};
|
||||
std::vector<std::string> tabnames = {"width", "mean"};//, (UnbinnedFit ? "fitstatus" : "failRate")};
|
||||
|
||||
clear_Latex_noteFile(latex_toyFile()+"_"+std::to_string(jobID)+std::string(doPulls?"":"_res")); //First make sure you don't append stuff
|
||||
std::ofstream myFile; //TODO: fix the latex name file
|
||||
open_Latex_noteFile(latex_toyFile()+"_"+std::to_string(jobID)+std::string(doPulls?"":"_res"), myFile); //open latex file
|
||||
|
||||
for(unsigned int i = 0; i < tabnames.size(); i++){
|
||||
myFile << "\\begin{frame} \\footnotesize \\centering" << std::endl;
|
||||
myFile << "\\begin{tabular}{|l|";
|
||||
for(unsigned int b = 0; b < bins.nBins; b++) myFile << "p{2.2cm}";
|
||||
myFile << "|}\\hline" << std::endl;
|
||||
myFile << "\\textbf{" << tabnames[i] << "}";
|
||||
//for(unsigned int b = 0; b < bins.nBins; b++)myFile << "\t& " << b;
|
||||
for(unsigned int b = 0; b < bins.nBins; b++)myFile << std::setprecision(2) << std::fixed << "\t&[" << bins.q2min.at(b) << "--" << bins.q2max.at(b) << "]";
|
||||
myFile << "\\\\" << std::endl;
|
||||
myFile << "\\hline\\hline" << std::endl;
|
||||
//TABLE CONTENT:
|
||||
for(unsigned int v = 0; v < lePullInfo.size(); v++){
|
||||
if (lePullInfo.at(v).size()==0) continue;
|
||||
myFile << "$" << LaTeXnames.at(v) << "$ ";
|
||||
for(unsigned int b = 0; b < bins.nBins; b++){
|
||||
//get correct value for mean,sigma,failRate at q2bin and variable
|
||||
double levalue = 0.0;
|
||||
double leerror = 0.0;
|
||||
if(i == 0){
|
||||
levalue = lePullInfo.at(v)[b].sigma;
|
||||
leerror = lePullInfo.at(v)[b].sigmaErr;
|
||||
}
|
||||
else if(i == 1){
|
||||
levalue = lePullInfo.at(v)[b].mean;
|
||||
leerror = lePullInfo.at(v)[b].meanErr;
|
||||
}
|
||||
else{
|
||||
levalue = lePullInfo.at(v)[b].failRate; //TODO
|
||||
}
|
||||
myFile << "\t&";
|
||||
//generate cell background color accordingly to the value:
|
||||
if(UseCellColor){
|
||||
//TColor * colour = gROOT->GetColor(Idx + TMath::Min(254, (int) ((TMath::Abs((doPulls && i == 0 ? levalue - 1. : levalue))/2./colorrange[i]+0.5)*255.)));
|
||||
int coloridx = ((doPulls && i == 0 ? levalue - 1.0 : levalue)/colorrange[i])*127;
|
||||
if(coloridx < -127)coloridx = -127;
|
||||
if(coloridx > 127)coloridx = 127;
|
||||
TColor * colour = gROOT->GetColor(Idx + 127 + coloridx);
|
||||
if(colour==nullptr)spdlog::error("Color with idx={0:d} not found", Idx + 127 + coloridx);
|
||||
else{
|
||||
std::string leColour(colour->AsHexString());
|
||||
std::transform(leColour.begin(), leColour.end(),leColour.begin(), ::toupper);
|
||||
myFile << "\\cellcolor[HTML]{" << leColour.substr(1,6) << "} ";
|
||||
}
|
||||
}
|
||||
//draw cell content
|
||||
myFile << "$";
|
||||
if(levalue>=0.0)myFile << "\\phantom{-}";//align columns by adding an invisible minus sign
|
||||
myFile << std::setprecision(3) << std::fixed << levalue << " \\pm " << leerror << "$";
|
||||
}
|
||||
myFile << "\\\\" << std::endl;
|
||||
}
|
||||
//END OF TABLE CONTENT
|
||||
myFile << "\\hline" << std::endl;
|
||||
myFile << "\\end{tabular}" << std::endl << std::endl;
|
||||
myFile << "\\end{frame}" << std::endl;
|
||||
}
|
||||
myFile.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void save2rootFile( basic_params params, std::vector< std::string> treeNames, std::vector< std::string> LaTeXnames, std::vector< std::vector<pullInfo> > lePullInfo, const q2Bins bins){
|
||||
TFile * file = new TFile((get_ToyPullPlot_folder(params)+"pullResults.root").c_str(), "RECREATE");
|
||||
spdlog::debug("Opening "+std::string(file->GetPath()));
|
||||
file->cd();
|
||||
for(UInt_t t = 0; t < treeNames.size(); t++){
|
||||
if (lePullInfo[t].size()==0) continue;
|
||||
TTree * tree = new TTree(treeNames[t].c_str(), LaTeXnames[t].c_str());
|
||||
spdlog::debug("Saving tree "+ treeNames[t]);
|
||||
double mean = DEFAULT_TREE_VAL;
|
||||
double width = DEFAULT_TREE_ERR;
|
||||
tree->Branch("mean", &mean, "mean/D");
|
||||
tree->Branch("width", &width, "width/D");
|
||||
for(UInt_t b = 0; b < bins.nBins; b++){
|
||||
mean = lePullInfo[t][b].mean;
|
||||
width = lePullInfo[t][b].sigma;
|
||||
spdlog::debug("mean:\t{0:f}",mean);
|
||||
spdlog::debug("width:\t{0:f}",width);
|
||||
tree->Fill();
|
||||
}
|
||||
tree->Write();
|
||||
delete tree;
|
||||
}
|
||||
file->Close();
|
||||
delete file;
|
||||
}
|
||||
|
||||
const std::vector<std::string>colorPallete =
|
||||
{"0d3c7b","2b6d97","499eb3","67cfcf","85ffeb","7ce9c8","72d2a5","69b282",
|
||||
"5FA55F",
|
||||
"84BC70", "A8D281","CCE892","F0FEA2","DABF7A","C47F51","AE4029","970000"};
|
||||
|
||||
/*
|
||||
const std::vector<std::string>colorPallete =
|
||||
{"93006A","751778","562D86","374494","185AA2","2A6D92","3C8081","4E9370",
|
||||
"5FA55F",
|
||||
"84BC70", "A8D281","CCE892","F0FEA2","DABF7A","C47F51","AE4029","970000"};
|
||||
*/
|
||||
/*
|
||||
const std::vector<std::string>colorPallete =
|
||||
{"0d3c7b","0e5d85","0e7d8e","0f9d97","0fbda0","0cae7b","089f56","049031",
|
||||
"00800B",
|
||||
"3B9714", "76ae1d","b1c526","EBDB2e","d9a523","c76e17","B5370c","A30000"};
|
||||
*/
|
||||
|
||||
const std::vector<double> colStops = {-1.000,-0.8750,-0.7500,-0.6250,-0.5000,-0.3750,-0.2500,-0.1250,
|
||||
0.0000,
|
||||
0.1250, 0.2500, 0.3750, 0.5000, 0.6250, 0.7500, 0.8750, 1.0000};
|
||||
|
||||
std::string getCol(double val){
|
||||
int len = colStops.size();
|
||||
for (int i = 0; i < len; i++){
|
||||
if (colStops[i+1]>val) return colorPallete[i];
|
||||
}
|
||||
return colorPallete[len-1];
|
||||
}
|
||||
|
||||
int save2texFileNew(std::vector< std::string> LaTeXnames, std::vector< std::vector<pullInfo> > lePullInfo, const q2Bins bins, int jobID){
|
||||
if(lePullInfo.size() == 0){
|
||||
spdlog::error("No results found for widths of pull/residual distributrionn");
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<std::string> tabnames = {"width", "mean"};//, (UnbinnedFit ? "fitstatus" : "failRate")};
|
||||
|
||||
clear_Latex_noteFile(latex_toyFile()+"_"+std::to_string(jobID)); //First make sure you don't append stuff
|
||||
std::ofstream myFile; //TODO: fix the latex name file
|
||||
open_Latex_noteFile(latex_toyFile()+"_"+std::to_string(jobID), myFile); //open latex file
|
||||
|
||||
for(unsigned int i = 0; i < tabnames.size(); i++){
|
||||
myFile << "\\begin{frame} \\footnotesize \\centering" << std::endl;
|
||||
myFile << "\\begin{tabular}{|l|";
|
||||
for(unsigned int b = 0; b < bins.nBins; b++) myFile << "p{2.2cm}";
|
||||
myFile << "|}\\hline" << std::endl;
|
||||
myFile << "\\textbf{" << tabnames[i] << "}";
|
||||
//for(unsigned int b = 0; b < bins.nBins; b++)myFile << "\t& " << b;
|
||||
for(unsigned int b = 0; b < bins.nBins; b++)myFile << std::setprecision(2) << std::fixed << "\t&[" << bins.q2min.at(b) << "--" << bins.q2max.at(b) << "]";
|
||||
myFile << "\\\\" << std::endl;
|
||||
myFile << "\\hline\\hline" << std::endl;
|
||||
//TABLE CONTENT:
|
||||
for(unsigned int v = 0; v < lePullInfo.size(); v++){
|
||||
if (lePullInfo.at(v).size()==0) continue;
|
||||
myFile << "$" << LaTeXnames.at(v) << "$ ";
|
||||
for(unsigned int b = 0; b < bins.nBins; b++){
|
||||
//get correct value for mean,sigma,failRate at q2bin and variable
|
||||
double levalue = 0.0;
|
||||
double leerror = 0.0;
|
||||
if(i == 0){
|
||||
levalue = lePullInfo.at(v)[b].sigma;
|
||||
leerror = lePullInfo.at(v)[b].sigmaErr;
|
||||
}
|
||||
else if(i == 1){
|
||||
levalue = lePullInfo.at(v)[b].mean;
|
||||
leerror = lePullInfo.at(v)[b].meanErr;
|
||||
}
|
||||
else{
|
||||
levalue = lePullInfo.at(v)[b].failRate; //TODO
|
||||
}
|
||||
myFile << "\t&";
|
||||
//generate cell background color accordingly to the value:
|
||||
if(UseCellColor){
|
||||
if (i==0) myFile << "\\cellcolor[HTML]{" << getCol(levalue-1.0) << "} ";
|
||||
else myFile << "\\cellcolor[HTML]{" << getCol(levalue) << "} ";
|
||||
}
|
||||
//draw cell content
|
||||
myFile << "$";
|
||||
if(levalue>=0.0)myFile << "\\phantom{-}";//align columns by adding an invisible minus sign
|
||||
myFile << std::setprecision(3) << std::fixed << levalue << " \\pm " << leerror << "$";
|
||||
}
|
||||
myFile << "\\\\" << std::endl;
|
||||
}
|
||||
//END OF TABLE CONTENT
|
||||
myFile << "\\hline" << std::endl;
|
||||
myFile << "\\end{tabular}" << std::endl << std::endl;
|
||||
myFile << "\\end{frame}" << std::endl;
|
||||
}
|
||||
myFile.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//MAIN FUNCTION to run over all observables and q2bin.
|
||||
//the function calls the loading and fitting function 'eval_toys()'
|
||||
//then runs the print and save functions
|
||||
int EvaluateToyStudy(const std::vector<std::string> obs, const std::vector<std::string> obs_latex, basic_params params, bool UseFolds, bool doPulls, bool Pprimes, bool onlySig, bool onlyBkg){
|
||||
|
||||
//define names of observables and which foldings are taken for which observable
|
||||
std::vector<UInt_t> folding_idx;
|
||||
|
||||
if(Pprimes) folding_idx = {3, 3, 0, 0, 1, 2, 3, 4};
|
||||
else folding_idx = {3, 3, 1, 2, 0, 3, 4, 0};
|
||||
|
||||
std::vector<int> weirdRangeJobs = {340, 343, 344, 349, 350, 353, 354, 355, 362, 379, 382, 497,558, 559, 560, 561, 562, 563}; //jobIDs with off pull ranges
|
||||
double lowRange = -5.0;
|
||||
double highRange = 5.0;
|
||||
|
||||
std::vector<int> ctkRange = {497, 558, 559, 560, 561, 562, 563, 566, 567, 568, 569, 570, 571, 620, 621, 622, 623, 624, 625, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648};
|
||||
|
||||
|
||||
//configure the path and tags of the toy study result files
|
||||
std::string PPtag = Pprimes ? "_Pprimes" : "";
|
||||
std::string suffix = ""; //TODO
|
||||
makeFolder(get_ToyPullPlot_folder(params));
|
||||
const q2Bins bins(params);
|
||||
|
||||
//using this status for error propagation
|
||||
std::vector< std::vector<pullInfo>> leInfo = {};
|
||||
|
||||
for(UInt_t p = 0; p < obs.size(); p++){
|
||||
lowRange = -5.0; //Reset the ranges again in case
|
||||
highRange = 5.0;
|
||||
if(params.reference && ( isInVec(obs.at(p),ANG_OBS) || isInVec(obs.at(p),SWAVE))){
|
||||
lowRange = -1.0; //Reset the ranges again in case
|
||||
highRange = 1.0;
|
||||
}
|
||||
if(params.reference && params.folding>-1 && ( isInVec(obs.at(p),ANG_OBS) || isInVec(obs.at(p),SWAVE))){
|
||||
lowRange = -0.5; //Reset the ranges again in case
|
||||
highRange = 0.5;
|
||||
}
|
||||
if(params.reference && params.folding==4 && ( isInVec(obs.at(p),ANG_OBS) || isInVec(obs.at(p),SWAVE))){
|
||||
lowRange = -5.0; //TODO
|
||||
highRange = 5.0;
|
||||
}
|
||||
if(params.reference && params.folding>-1 && obs.at(p)=="FS"){
|
||||
lowRange = -0.25; //Reset the ranges again in case
|
||||
highRange = 0.25;
|
||||
}
|
||||
if(UseFolds)params.folding = folding_idx.at(p);
|
||||
|
||||
//get a filename accordingly to the basic_params settings, then replace the number 1111 by the wildcard
|
||||
//and then replace the folder ToysFit by the subfolder created by condor
|
||||
std::string files = final_result_name_toys(1111, params.reference, params.nBins, true, params, params.Run, false, false, onlySig, onlyBkg, false, true);
|
||||
replace(files, "1111", "*"); //integer replaced by a string *
|
||||
replace(files, "ToysFit/", "ToysFit/"+std::to_string(params.jobID)+"/");
|
||||
spdlog::info("Read pdfs from file='"+files+"'");
|
||||
|
||||
//Set the range for weird pulls in ctk
|
||||
if (isInVec(params.jobID, weirdRangeJobs) && p>7 && p<15){ //This is a dirty hack
|
||||
lowRange = -50.0;
|
||||
highRange = +50.0;
|
||||
}
|
||||
if ((params.jobID==503 || (params.jobID>=509 && params.jobID<=512)) && (p==11 || p ==12)){ //This is a dirty hack
|
||||
lowRange = -50.0;
|
||||
highRange = +50.0;
|
||||
|
||||
}
|
||||
|
||||
if ((params.jobID==551 && (p==1))){ //This is a dirty hack
|
||||
leInfo.push_back({});
|
||||
continue;
|
||||
}
|
||||
if ((params.jobID==551 && (p==3))){
|
||||
lowRange = -10.0;
|
||||
highRange = 0.0;
|
||||
}
|
||||
|
||||
if (params.jobID==566 && (p==9)){ //This is a dirty hack
|
||||
leInfo.push_back({});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (params.jobID==567 && (p==9)){ //This is a dirty hack
|
||||
leInfo.push_back({});
|
||||
continue;
|
||||
}
|
||||
if (isInVec(params.jobID,ctkRange) && (p==8|| p==9)){
|
||||
lowRange = -5.0;
|
||||
highRange = 15.0;
|
||||
}
|
||||
if (isInVec(params.jobID,ctkRange) && params.jobID>619 && (obs.at(p)=="cbkgctk1")){
|
||||
leInfo.push_back({});
|
||||
continue; //TODO WTF
|
||||
lowRange = 10.0;
|
||||
highRange = 30.0;
|
||||
}
|
||||
if (isInVec(params.jobID,ctkRange) && params.jobID>619 && (obs.at(p)=="cbkgctk2")){
|
||||
leInfo.push_back({});
|
||||
continue;//TODO WTF
|
||||
lowRange = 20.0;
|
||||
highRange = 45.0;
|
||||
}
|
||||
if (params.jobID==571 && (p==9)){ //This is a dirty hack
|
||||
leInfo.push_back({});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (params.jobID>619 && (obs.at(p)=="cbkgctl2")){ //This is a dirty hack
|
||||
leInfo.push_back({});
|
||||
continue;//TODO, actually anythig below zero possible depending on the bin
|
||||
lowRange = -15.0;
|
||||
highRange = -5.0;
|
||||
}
|
||||
//if (params.jobID==637 && (obs.at(p)=="SS5")){ //This is a dirty hack
|
||||
// continue;
|
||||
//}
|
||||
if (params.jobID==630 && (p==9)){ //This is a dirty hack
|
||||
leInfo.push_back({});
|
||||
continue;
|
||||
}
|
||||
if (params.jobID==650 && (p==9)){
|
||||
leInfo.push_back({});
|
||||
continue;
|
||||
}
|
||||
//evalute the files for this observable and check the status
|
||||
leInfo.push_back(eval_toys(files, obs.at(p), params, doPulls, lowRange, highRange, 1));
|
||||
}
|
||||
|
||||
if (doPulls){
|
||||
//print results to latex table into 'cout' and save to a root file
|
||||
if (params.reference) save2rootFile(params,obs, obs_latex,leInfo, bins); //This could be done for each value
|
||||
return save2texFileNew(obs_latex,leInfo,bins,params.jobID);
|
||||
}
|
||||
else return print_latex_tables(params.usePprime,false,obs_latex,leInfo, bins, params.jobID);
|
||||
}
|
||||
|
||||
|
22
Code/FCNCFitter/sources/Scripts/EvaluateToys.hh
Normal file
22
Code/FCNCFitter/sources/Scripts/EvaluateToys.hh
Normal file
@ -0,0 +1,22 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef EVALUATETOYS_H
|
||||
#define EVALUATETOYS_H
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include <parse.hh>
|
||||
#include <paths.hh>
|
||||
#include <spdlog.h>
|
||||
#include <RooAbsReal.h>
|
||||
#include <RooDataSet.h>
|
||||
#include <RooGaussian.h>
|
||||
#include <RooFitResult.h>
|
||||
#include <RooGaussian.h>
|
||||
#include <RooPlot.h>
|
||||
#include <RooRealVar.h>
|
||||
|
||||
int EvaluateToyStudy(const std::vector<std::string> obs, const std::vector<std::string> obs_latex, basic_params pars, bool UseFolds, bool doPulls, bool Pprimes, bool onlySig, bool onlyBkg);
|
||||
|
||||
#endif // EVALUATETOYS_H
|
431
Code/FCNCFitter/sources/Scripts/GenLvlvsMC.cc
Normal file
431
Code/FCNCFitter/sources/Scripts/GenLvlvsMC.cc
Normal file
@ -0,0 +1,431 @@
|
||||
//Renata Kopecna
|
||||
|
||||
|
||||
#include "GenLvlvsMC.hh"
|
||||
#include <TH1D.h>
|
||||
#include <TFile.h>
|
||||
#include <TLegend.h>
|
||||
#include <string>
|
||||
#include <TGraphAsymmErrors.h>
|
||||
#include <TGraphErrors.h>
|
||||
#include <TGraph.h>
|
||||
#include <design.hh>
|
||||
#include <paths.hh>
|
||||
#include <parse.hh>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <helpers.hh>
|
||||
#include "ScriptHelpers.hh"
|
||||
|
||||
std::string plotPath(std::string observable, std::string tag){
|
||||
return PLOTS_PATH+"MCfit/"+ "GenLvl_vs_MC_" + observable + tag +".eps";
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>> DavidsGenLvl = {
|
||||
{ 0.5120, 0.1800, 0.1370, 0.1930, 0.2750, 0.4170, 0.4840, 0.5030}, //S1s
|
||||
{ 0.2450, 0.6996, 0.7993, 0.7384, 0.6414, 0.4201, 0.3513, 0.3344}, //S1c
|
||||
{ 0.1448, 0.0749, 0.0514, 0.0662, 0.0900, 0.1449, 0.1620, 0.1662}, //S2s
|
||||
{-0.1953,-0.6639,-0.7774,-0.7254,-0.6334,-0.4171,-0.3497,-0.3332}, //S2c
|
||||
{ 0.0000, 0.0020,-0.0080,-0.0120,-0.0240,-0.0620,-0.1520,-0.2330}, //S3
|
||||
{ 0.0870, 0.0040,-0.1080,-0.1950,-0.2510,-0.2770,-0.2900,-0.3040}, //S4
|
||||
{ 0.2440, 0.0950,-0.1590,-0.3050,-0.4140,-0.4210,-0.3400,-0.2490}, //S5
|
||||
{-0.1270,-0.2070,-0.0860, 0.0950, 0.3020, 0.5140, 0.5570, 0.4700}, //S6s
|
||||
{ 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000}, //S6c
|
||||
{-0.0060,-0.0100,-0.0030, 0.0020, 0.0030,-0.0020,-0.0020, 0.0050}, //S7
|
||||
{ 0.0010,-0.0030,-0.0040,-0.0030,-0.0010, 0.0030,-0.0010, 0.0030}, //S8
|
||||
{-0.0020, 0.0000, 0.0020, 0.0040,-0.0020,-0.0010,-0.0010, 0.0010} //S9
|
||||
}; //I would kill for a dictionary in C++ now
|
||||
|
||||
double getDavidsValue(std::string observable, int bin){ //Not the most efficienc implementation, but oh well, hard to live without numpy
|
||||
if (observable == "Fl") return (1-4.0/3.0*DavidsGenLvl[0][bin]);
|
||||
if (observable == "S1s") return DavidsGenLvl[0][bin];
|
||||
if (observable == "S1c") return DavidsGenLvl[1][bin];
|
||||
if (observable == "S2s") return DavidsGenLvl[2][bin];
|
||||
if (observable == "S2c") return DavidsGenLvl[3][bin];
|
||||
if (observable == "S3") return DavidsGenLvl[4][bin];
|
||||
if (observable == "S4") return DavidsGenLvl[5][bin];
|
||||
if (observable == "S5") return DavidsGenLvl[6][bin];
|
||||
if (observable == "S6s") return DavidsGenLvl[7][bin];
|
||||
if (observable == "Afb") return 3.0/4.0*DavidsGenLvl[7][bin];
|
||||
if (observable == "S6c") return DavidsGenLvl[8][bin];
|
||||
if (observable == "S7") return DavidsGenLvl[9][bin];
|
||||
if (observable == "S8") return DavidsGenLvl[10][bin];
|
||||
if (observable == "S9") return DavidsGenLvl[11][bin];
|
||||
|
||||
spdlog::critical("I don't know observable "+observable);
|
||||
spdlog::critical("Throwing an error now.");
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TGraphAsymmErrors* DavidsGenLvlGraph(std::string observable){
|
||||
int nBins = DavidsGenLvl[0].size(); //In case the vector above changes, this should be secure
|
||||
std::vector<double> q2min = get_TheQ2binsmin(nBins,false);
|
||||
std::vector<double> q2max = get_TheQ2binsmax(nBins,false);
|
||||
|
||||
//Initilialize the TGraph
|
||||
//Initialize it on purpose with 0 points; in case something goes wrong with nBins, this makes sure there are no segfaults
|
||||
TGraphAsymmErrors* graph = new TGraphAsymmErrors(0);
|
||||
|
||||
//Loop over bins to fill TGraph from DavidsGenLvl
|
||||
for (int b = 0; b < nBins; b++){
|
||||
graph->SetPoint(graph->GetN(),bin_center_q2(q2min,q2max,b), getDavidsValue(observable,b));
|
||||
graph->SetPointError(graph->GetN()-1,bin_halfWidth_q2(q2min,q2max,b), bin_halfWidth_q2(q2min,q2max,b), 0, 0);
|
||||
}
|
||||
return graph;
|
||||
|
||||
}
|
||||
|
||||
int compareGenLvlMC(std::vector<TGraphAsymmErrors*> graphs,
|
||||
std::vector<std::string> legends,
|
||||
std::vector<int> color,
|
||||
std::vector<int> markerStyle,
|
||||
std::string observable, std::string plotPath,
|
||||
std::vector<int> plotDiff){ //What two plots should be considered for plotting the "pulls"? Marked with 1 and 2, plotting 1-2
|
||||
|
||||
int idx_1 = find(plotDiff.begin(), plotDiff.end(), 1)-plotDiff.begin();
|
||||
int idx_2 = find(plotDiff.begin(), plotDiff.end(), 2)-plotDiff.begin();
|
||||
bool plotD = (idx_1 != int(graphs.size()) && idx_2 != int(graphs.size()));
|
||||
spdlog::debug("plot diff? " + boolToString(plotD));
|
||||
spdlog::debug("Idx_1: {0:d}\tIdx_2: {1:d}", idx_1, idx_2);
|
||||
|
||||
//Create a canvas
|
||||
TCanvas *c_compare = new TCanvas("c_compare", "c_compare", 1600, 1200);
|
||||
|
||||
const double pullHeight = 0.27;
|
||||
const double pullFrameRange = 3.5;
|
||||
TPad *pad1 = new TPad("pad1", "plot",0.0,pullHeight,1.0,1.0,0);
|
||||
TPad *pad2 = new TPad("pad2", "pull",0.0,0.0,1.0,pullHeight,0);
|
||||
if(plotD){
|
||||
pad1->Draw();
|
||||
pad2->Draw();
|
||||
pad1->SetBorderSize (0);
|
||||
pad1->SetMargin(0.125,0.05,1e-6,1.25/(1.0 - pullHeight));
|
||||
pad1->SetTickx();
|
||||
pad1->SetTicky();
|
||||
pad1->cd();
|
||||
}
|
||||
else{
|
||||
c_compare->cd();
|
||||
c_compare->SetMargin(0.125,0.05,0.1,0.1);
|
||||
c_compare->SetTickx();
|
||||
c_compare->SetTicky();
|
||||
}
|
||||
|
||||
|
||||
//Create an empty hist for the axes
|
||||
TH1D* haxes = emptyHist(observable);
|
||||
haxes->Draw("AXIS");
|
||||
|
||||
//Draw boxes for resonances
|
||||
drawResonances(plotD ? pad1 : c_compare, obsv_range(observable)[0], obsv_range(observable)[1]);
|
||||
|
||||
haxes->SetFillStyle(0);
|
||||
haxes->Draw("AXIS SAME");
|
||||
|
||||
TLegend* leg = new TLegend(0.62,0.70,0.94,0.94);
|
||||
leg->SetBorderSize(0);
|
||||
leg->SetTextFont(132);
|
||||
leg->SetFillColor(0);
|
||||
|
||||
for_indexed(auto g: graphs){
|
||||
designTGraph(g, markerStyle[i], color[i]);
|
||||
if (legends[i]!="") leg->AddEntry(g, legends[i].c_str());
|
||||
g->Draw("P");
|
||||
}
|
||||
leg->Draw("SAME");
|
||||
|
||||
TH1D *diff = nullptr;
|
||||
if (plotD){ //If there are no tags 1 and 2, don't do anything
|
||||
pad2->Clear();
|
||||
pad2->SetMargin(0.125,0.05,0.1/ pullHeight, 1e-6);
|
||||
pad2->SetTickx();
|
||||
pad2->cd();
|
||||
|
||||
std::string y_title = "Diff [#sigma]";//legends[idx_1] + "-" + legends[idx_2];
|
||||
diff = hist_graphDiff(graphs[idx_1],graphs[idx_2],pullFrameRange, y_title);
|
||||
|
||||
double max = haxes->GetBinLowEdge(haxes->GetNbinsX()+1);
|
||||
double min = haxes->GetBinLowEdge(1);
|
||||
//I hate that I have to workaround ranges of an efin histogram
|
||||
|
||||
TLine *sigmaUp_3 = threeSigmaLine(min,max, true);
|
||||
TLine *sigmaLow_3 = threeSigmaLine(min,max, false);
|
||||
TLine *sigmaUp_1 = oneSigmaLine(min,max, true);
|
||||
TLine *sigmaLow_1 = oneSigmaLine(min,max, false);
|
||||
design_pull(diff, 9011, 9011, pullHeight+0.1, pullFrameRange);
|
||||
diff->GetYaxis()->SetNdivisions(110);
|
||||
diff->Draw("");
|
||||
|
||||
sigmaUp_3->Draw("same");
|
||||
sigmaLow_3->Draw("same");
|
||||
sigmaUp_1->Draw("same");
|
||||
sigmaLow_1->Draw("same");
|
||||
}
|
||||
|
||||
spdlog::info("Saving into "+ plotPath);
|
||||
c_compare->Print(plotPath.c_str(), "eps");
|
||||
if (spdlog_debug()){ //When debugging save also the root file
|
||||
replace(plotPath,".eps",".root");
|
||||
c_compare->Print(plotPath.c_str(), "root");
|
||||
}
|
||||
|
||||
delete c_compare;
|
||||
delete haxes;
|
||||
delete diff;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int plotComparison_Toy_GenVsMC(std::string observable, bool isRef){
|
||||
bool onlySig = false;
|
||||
bool onlyBkg = false;
|
||||
bool onlyAngles = false;
|
||||
bool onlyMass = false;
|
||||
bool bkgFromLowMass = false;
|
||||
bool bkgFromHighMass = true;
|
||||
|
||||
basic_params params_MC = basic_params();
|
||||
params_MC.Run = 12;
|
||||
params_MC.nBins = isRef ? 1 : 4;
|
||||
params_MC.reference = isRef;
|
||||
|
||||
basic_params params_Toys = basic_params();
|
||||
params_Toys.Run = 12;
|
||||
params_Toys.nBins = isRef ? 1 : 4;
|
||||
params_Toys.reference = isRef;
|
||||
|
||||
std::vector<std::string> legends;
|
||||
std::vector<int> color;
|
||||
std::vector<int> markerStyle;
|
||||
std::vector<TGraphAsymmErrors*> graphs;
|
||||
std::vector<int> difference; //makes a plot with difference of grpahs with a tag of 1-2
|
||||
//I shoudl write a class for this, but too much effort
|
||||
|
||||
|
||||
//Add init parameters
|
||||
std::string path = final_result_name_MC(params_MC, params_Toys.nBins, isRef, false, true, false, false);
|
||||
graphs.push_back(get_TGraphFromFile(path,observable,isRef));
|
||||
legends.push_back("MC"); //Don't plot legend as it is same as sigMC
|
||||
color.push_back(9012);
|
||||
markerStyle.push_back(27);
|
||||
difference.push_back(1);
|
||||
|
||||
//Fill the toy init parameters
|
||||
path = init_params_name_toys(1,isRef,params_Toys.nBins, true, params_Toys, params_Toys.Run, onlyAngles, onlyMass, onlySig, onlyBkg, bkgFromLowMass, bkgFromHighMass);
|
||||
graphs.push_back(get_TGraphFromFile(path,observable,isRef));
|
||||
legends.push_back("Toy");
|
||||
color.push_back(9007);
|
||||
markerStyle.push_back(34);
|
||||
difference.push_back(2);
|
||||
|
||||
std::string plotPath = PLOTS_PATH+"Toys/"+ "MC_vs_Init_" + observable +".eps";
|
||||
return compareGenLvlMC(graphs,legends,color,markerStyle,observable, plotPath, difference);
|
||||
|
||||
}
|
||||
|
||||
//This one compares the data-like fit to the init toy values
|
||||
int plotComparison_Toy_InitVsAcutalFit(std::string observable, bool isRef){
|
||||
|
||||
bool onlySig = false;
|
||||
bool onlyBkg = false;
|
||||
bool onlyAngles = false;
|
||||
bool onlyMass = false;
|
||||
bool bkgFromLowMass = false;
|
||||
bool bkgFromHighMass = false;
|
||||
|
||||
double fractionOfStats = 1.0;
|
||||
|
||||
basic_params params_Init= basic_params();
|
||||
params_Init.Run = 12;
|
||||
params_Init.nBins = isRef ? 1 : 4;
|
||||
params_Init.reference = isRef;
|
||||
params_Init.jobID = -1;
|
||||
|
||||
basic_params params_Fit= basic_params();
|
||||
params_Fit.Run = 12;
|
||||
params_Fit.nBins = isRef ? 1 : 4;
|
||||
params_Fit.reference = isRef;
|
||||
|
||||
std::vector<std::string> legends;
|
||||
std::vector<int> color;
|
||||
std::vector<int> markerStyle;
|
||||
std::vector<TGraphAsymmErrors*> graphs;
|
||||
std::vector<int> difference; //makes a plot with difference of grpahs with a tag of 1-2
|
||||
//I shoudl write a class for this, but too much effort
|
||||
|
||||
//Add init parameters
|
||||
std::string paramFile = init_params_name_toys(-1,params_Init.reference, params_Init.nBins, true, params_Init, params_Init.Run, onlyAngles, onlyMass, onlySig, onlyBkg, bkgFromLowMass, bkgFromHighMass);
|
||||
graphs.push_back(get_TGraphFromFile(paramFile,observable,isRef));
|
||||
legends.push_back("Init"); //Don't plot legend as it is same as sigMC
|
||||
color.push_back(9012);
|
||||
markerStyle.push_back(27);
|
||||
difference.push_back(1);
|
||||
|
||||
//Add fitted parameters
|
||||
std::string fitFile = final_result_name(isRef, false, params_Fit,
|
||||
true, params_Fit.nBins, params_Fit.Run,
|
||||
true, fractionOfStats,
|
||||
false, -1);
|
||||
|
||||
graphs.push_back(get_TGraphFromFile(fitFile,observable,isRef));
|
||||
legends.push_back("Fit");
|
||||
color.push_back(9007);
|
||||
markerStyle.push_back(34);
|
||||
difference.push_back(2);
|
||||
|
||||
std::string plotPath = PLOTS_PATH+"Toys/"+ "FinalToy_Init_vs_Fit_" + observable + std::string(isRef ? "_Ref" : "" )+".eps";
|
||||
return compareGenLvlMC(graphs,legends,color,markerStyle,observable, plotPath, difference);
|
||||
}
|
||||
|
||||
|
||||
int plotComparison_Toy_GenVsFit(std::string observable, bool isRef){
|
||||
|
||||
bool onlySig = false;
|
||||
bool onlyBkg = false;
|
||||
bool onlyAngles = false;
|
||||
bool onlyMass = false;
|
||||
bool bkgFromLowMass = false;
|
||||
bool bkgFromHighMass = true;
|
||||
|
||||
basic_params params_Init= basic_params();
|
||||
params_Init.Run = 12;
|
||||
params_Init.nBins = isRef ? 1 : 4;
|
||||
params_Init.reference = isRef;
|
||||
|
||||
basic_params params_Fit= basic_params();
|
||||
params_Fit.Run = 12;
|
||||
params_Fit.nBins = isRef ? 1 : 4;
|
||||
params_Fit.reference = isRef;
|
||||
|
||||
std::vector<std::string> legends;
|
||||
std::vector<int> color;
|
||||
std::vector<int> markerStyle;
|
||||
std::vector<TGraphAsymmErrors*> graphs;
|
||||
std::vector<int> difference; //makes a plot with difference of grpahs with a tag of 1-2
|
||||
//I shoudl write a class for this, but too much effort
|
||||
|
||||
//Add init parameters
|
||||
std::string path = init_params_name_toys(1,isRef,params_Init.nBins, true, params_Init, params_Init.Run, onlyAngles, onlyMass, onlySig, onlyBkg, bkgFromLowMass, bkgFromHighMass);
|
||||
graphs.push_back(get_TGraphFromFile(path,observable,isRef));
|
||||
legends.push_back("Init"); //Don't plot legend as it is same as sigMC
|
||||
color.push_back(9012);
|
||||
markerStyle.push_back(27);
|
||||
difference.push_back(1);
|
||||
|
||||
//Add fitted parameters
|
||||
path = final_result_name_toys(1,isRef,params_Fit.nBins, true, params_Fit, params_Fit.Run, onlyAngles, onlyMass, onlySig, onlyBkg, bkgFromLowMass, bkgFromHighMass);
|
||||
graphs.push_back(get_TGraphFromFile(path,observable,isRef));
|
||||
legends.push_back("Fit");
|
||||
color.push_back(9007);
|
||||
markerStyle.push_back(34);
|
||||
difference.push_back(2);
|
||||
|
||||
std::string plotPath = PLOTS_PATH+"Toys/"+ "Init_vs_Fit_" + observable + std::string(isRef ? "_Ref" : "" )+".eps";
|
||||
return compareGenLvlMC(graphs,legends,color,markerStyle,observable, plotPath, difference);
|
||||
}
|
||||
|
||||
int plotComparisonMCFolding(std::string observable){
|
||||
basic_params params_MC= basic_params();
|
||||
params_MC.Run = 12;
|
||||
params_MC.nBins = 4;
|
||||
params_MC.reference = false;
|
||||
|
||||
std::vector<std::string> legends;
|
||||
std::vector<int> color;
|
||||
std::vector<int> markerStyle;
|
||||
std::vector<TGraphAsymmErrors*> graphs;
|
||||
std::vector<int> difference; //makes a plot with difference of grpahs with a tag of 1-2
|
||||
|
||||
for (int f = -1; f <5; f++){
|
||||
params_MC.folding = f;
|
||||
if (f == -1) difference.push_back(1);
|
||||
if (plotObsv(f,observable)){
|
||||
graphs.push_back(get_TGraphFromFile(final_result_name_MC(params_MC,params_MC.nBins, false, false, true, false, false),observable,false));
|
||||
legends.push_back("Fld " + std::to_string(f));
|
||||
color.push_back(9009+f);
|
||||
markerStyle.push_back(25+f);
|
||||
difference.push_back(2);
|
||||
}
|
||||
}
|
||||
|
||||
std::string tag = "";
|
||||
std::string plotPath = PLOTS_PATH+"MCfit/"+ "Folding_" + observable + tag +".eps";
|
||||
|
||||
assert(!compareGenLvlMC(graphs,legends,color,markerStyle,observable, plotPath, difference));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int plotComparison(std::string observable){
|
||||
|
||||
basic_params params_genLvl = basic_params();
|
||||
params_genLvl.Run = 2;
|
||||
params_genLvl.year = 2017;
|
||||
params_genLvl.nBins = 8;
|
||||
|
||||
bool PHSP = false;
|
||||
|
||||
std::vector<std::string> legends;
|
||||
std::vector<int> color;
|
||||
std::vector<int> markerStyle;
|
||||
std::vector<TGraphAsymmErrors*> graphs;
|
||||
std::vector<int> difference; //makes a plot with difference of grpahs with a tag of 1-2
|
||||
//I shoudl write a class for this, but too much effort
|
||||
|
||||
//First make a comparison between my and David's genLvl
|
||||
//---------------------------------------------------//
|
||||
//Add genLvl
|
||||
graphs.push_back(get_TGraphFromFile(final_result_name_genLvlMC(params_genLvl, 8, PHSP, true, false),observable,false));
|
||||
legends.push_back("GenLvl MC"); //Don't plot legend as it is same as sigMC
|
||||
color.push_back(9012);
|
||||
markerStyle.push_back(27);
|
||||
difference.push_back(1);
|
||||
|
||||
//Fill David's results first
|
||||
graphs.push_back(DavidsGenLvlGraph(observable));
|
||||
legends.push_back("David's GenLvl results");
|
||||
color.push_back(9007);
|
||||
markerStyle.push_back(34);
|
||||
difference.push_back(2);
|
||||
|
||||
std::string tag = "_MyVsDavids";
|
||||
std::string plotPath = PLOTS_PATH+"MCfit/"+ "GenLvl_vs_MC_" + observable + tag +".eps";
|
||||
|
||||
assert(!compareGenLvlMC(graphs,legends,color,markerStyle,observable, plotPath, difference));
|
||||
|
||||
//Delete David's graphs
|
||||
graphs.clear();
|
||||
legends.clear();
|
||||
color.clear();
|
||||
markerStyle.clear();
|
||||
difference.clear();
|
||||
//---------------------------------------------------//
|
||||
//Compare my fit of genLvl mc and processed MC
|
||||
//---------------------------------------------------//
|
||||
//Add MC as it should be done
|
||||
|
||||
basic_params params_MC= basic_params();
|
||||
params_MC.Run = 12;
|
||||
params_MC.nBins = 4;
|
||||
params_MC.reference = false;
|
||||
|
||||
graphs.push_back(get_TGraphFromFile(final_result_name_MC(params_MC, 4, false, PHSP, true, false, false),observable,false));
|
||||
legends.push_back("LHCb simulation");
|
||||
color.push_back(9016);
|
||||
markerStyle.push_back(24);
|
||||
difference.push_back(1);
|
||||
|
||||
//Add genLvl MC
|
||||
params_genLvl.nBins = 4;
|
||||
graphs.push_back(get_TGraphFromFile(final_result_name_genLvlMC(params_genLvl, 4, PHSP, true, false),observable,false));
|
||||
legends.push_back("Generator level");
|
||||
color.push_back(9010);
|
||||
markerStyle.push_back(25);
|
||||
difference.push_back(2);
|
||||
|
||||
plotPath = PLOTS_PATH+"MCfit/"+ "GenLvl_vs_MC_" + observable + ".eps";
|
||||
return compareGenLvlMC(graphs,legends,color,markerStyle,observable, plotPath, difference);
|
||||
//---------------------------------------------------//
|
||||
|
||||
}
|
22
Code/FCNCFitter/sources/Scripts/GenLvlvsMC.hh
Normal file
22
Code/FCNCFitter/sources/Scripts/GenLvlvsMC.hh
Normal file
@ -0,0 +1,22 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef GENLVLVSMC_H
|
||||
#define GENLVLVSMC_H
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include <parse.hh>
|
||||
#include <paths.hh>
|
||||
#include <spdlog.h>
|
||||
|
||||
//Used to plot the fit results of GenLvl MC vs processed MC
|
||||
//Plots both signal and Jpsi, hence nBins is hardcoded to 5 and it reads both the fit of
|
||||
//4 bins in MC + 1 bin in RefMC
|
||||
|
||||
int plotComparison(std::string observable);
|
||||
int plotComparison_Toy_GenVsFit(std::string observable, bool isRef);
|
||||
int plotComparison_Toy_GenVsMC(std::string observable, bool isRef);
|
||||
int plotComparison_Toy_InitVsAcutalFit(std::string observable, bool isRef);
|
||||
int plotComparisonMCFolding(std::string observable);
|
||||
#endif // GENLVLVSMC_H
|
138
Code/FCNCFitter/sources/Scripts/GetMeanError.cc
Normal file
138
Code/FCNCFitter/sources/Scripts/GetMeanError.cc
Normal file
@ -0,0 +1,138 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#include <TFile.h>
|
||||
#include <TCanvas.h>
|
||||
#include <TChain.h>
|
||||
#include <TF1.h>
|
||||
#include <TH1D.h>
|
||||
|
||||
#include "GetMeanError.hh"
|
||||
#include <design.hh>
|
||||
#include <helpers.hh>
|
||||
#include "ScriptHelpers.hh"
|
||||
|
||||
|
||||
std::vector<double> getSM(std::string observable){
|
||||
|
||||
if (observable == "Fl") return {+0.248569008046490070, +0.2581971160208132000, +0.42526014659559220000, +0.49420669353506260000, +0.1850102996703149000}; //s1s
|
||||
else if (observable == "S3") return {+0.000732569649322501, -0.0324523859139632900, -0.08563864422457230000, -0.18934424485647136000, -0.0130310503598977030}; //s3
|
||||
else if (observable == "S4") return {-0.028317693174889150, -0.2425837027660650600, -0.28116530113868093000, -0.29668531019781386000, -0.1468982883895949300}; //s4
|
||||
else if (observable == "S5") return {+0.035479698896675250, -0.3745017565795041000, -0.40726931726860705000, -0.30161750053585110000, -0.1915219985323076700}; //s5
|
||||
else if (observable == "Afb")return {-0.122319885918514240, +0.2473816826915200600, +0.52432045165541470000, +0.52106439209368990000, +0.0147578966169414490}; //s6s
|
||||
else if (observable == "S7") return {-0.019468600975846337, -0.0105435770924197210, -0.00219285191192886900, -0.00119446595061885200, -0.0160492529928752330}; //s7
|
||||
else if (observable == "S8") return {-0.010192773160727949, -0.0043019891737210840, +0.00104987431866559550, +0.00027244645255727460, -0.0070279543261629670}; //s8
|
||||
else if (observable == "S9") return {-0.000756965302130655, -0.0006959911482550733, +0.00044741790607562027, +0.00026464193866571387, -0.0007199408885633002}; //s9
|
||||
else{
|
||||
spdlog::warn("Wrong observable, returning an empty vector");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<double> fixSM(std::string observable){
|
||||
std::vector<double> tmp = {};
|
||||
for (auto val : getSM(observable)){
|
||||
if (observable == "Fl") tmp.push_back(round((1-4.0*val/3.0)*100.0)/100.0);
|
||||
else if (observable=="Afb") tmp.push_back(round((3.0*val/4.0)*100.0)/100.0);
|
||||
else tmp.push_back(round(val*100.0)/100.0);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int loadAllFiles(std::string observable, basic_params params){
|
||||
//load chain with all results of bootstrapping
|
||||
TChain * ch = new TChain(observable.c_str());
|
||||
|
||||
std::string files = final_result_name_toys(1111, params.reference, params.nBins, true, params, params.Run, false, false, false, false, false, true);
|
||||
replace(files, "1111", "*"); //integer replaced by a string *
|
||||
replace(files, "ToysFit/", "ToysFit/"+std::to_string(params.jobID)+"/");
|
||||
|
||||
spdlog::debug("Loading files: " + files);
|
||||
|
||||
ch->Add(files.c_str());
|
||||
int nEntries = ch->GetEntries();
|
||||
spdlog::debug("Loaded {0:d} entries", nEntries);
|
||||
if (nEntries == 0){
|
||||
spdlog::error("No files found!");
|
||||
return 404;
|
||||
}
|
||||
|
||||
//link variables to branches
|
||||
|
||||
double value = DEFAULT_TREE_VAL;
|
||||
double error = DEFAULT_TREE_ERR;
|
||||
double errorup = DEFAULT_TREE_ERR;
|
||||
double errordown = DEFAULT_TREE_ERR;
|
||||
|
||||
int migrad = DEFAULT_TREE_INT;
|
||||
int cov = DEFAULT_TREE_INT;
|
||||
int bin = DEFAULT_TREE_INT;
|
||||
int pdf = DEFAULT_TREE_INT;
|
||||
|
||||
ch->SetBranchStatus("*",1); //TODO optimize
|
||||
ch->SetBranchAddress("value", &value);
|
||||
ch->SetBranchAddress("error", &error);
|
||||
ch->SetBranchAddress("error_up", &errorup);
|
||||
ch->SetBranchAddress("error_down", &errordown);
|
||||
ch->SetBranchAddress("migrad", &migrad);
|
||||
ch->SetBranchAddress("status_cov", &cov);
|
||||
ch->SetBranchAddress("bin", &bin);
|
||||
ch->SetBranchAddress("pdf", &pdf);
|
||||
|
||||
const int nBins = params.nBins;
|
||||
std::vector<double> errors[nBins]; //Don't fill a histogram just yet, just put the values in a vector first
|
||||
|
||||
//Loop over the entries and fill the vector
|
||||
for (int iter = 0; iter < nEntries; iter++){
|
||||
ch->GetEntry(iter);
|
||||
//require converged migrad
|
||||
if (migrad!=0) continue;
|
||||
//require fitresult = 300 or 100 (or 200)
|
||||
if(!(cov == 1 || cov == 3 || cov == 2)) continue;
|
||||
if (pdf == 1) continue; //Just take one pdf, as the values are shared
|
||||
spdlog::trace("Parameter value at entry {0:d}: {1:f}", iter, value);
|
||||
spdlog::trace("Parameter error at entry {0:d}: {1:f}", iter, error);
|
||||
errors[bin].push_back(error);
|
||||
}
|
||||
|
||||
//Debug print in case
|
||||
for (int b = 0; b < nBins; b++){
|
||||
spdlog::debug("Got {0:d} entries for bin {1:d}", errors[b].size(),b);
|
||||
}
|
||||
|
||||
//Now init a histogram for each bin and fill it
|
||||
std::vector<double> means;
|
||||
for (int b = 0; b < nBins; b++){
|
||||
//Get the max and the min of the errors
|
||||
double max = *max_element(errors[b].begin(), errors[b].end());
|
||||
double min = *min_element(errors[b].begin(), errors[b].end());
|
||||
if (min == max) continue; //If errors are all the same, it was fixed, so don't plot
|
||||
//Easier than checking folding
|
||||
if (max>1.0) max = 0.5;
|
||||
if (min<0.01) min = 0.01;
|
||||
//Create the TH1D for the errors
|
||||
TH1D *h_errors = new TH1D(observable.c_str(),
|
||||
(observable+" in q^{2} bin #"+std::to_string(b)
|
||||
+";"+observable+";Entries").c_str(),
|
||||
errors[b].size()/10, min, max);
|
||||
//Fill the TH1D from the read vector
|
||||
for (auto err: errors[b]) h_errors->Fill(err);
|
||||
//Fit the distribution with a gaussia
|
||||
TF1 *fit_func = new TF1("fit_func","gaus",min,max);
|
||||
fit_func->SetParameters(h_errors->GetMaximum(), h_errors->GetMean(), h_errors->GetRMS() );
|
||||
h_errors->Fit("fit_func",spdlog_debug() ? "R" : "RQ");
|
||||
//Plot and save it
|
||||
plotAndSave(h_errors,observable,"./"+observable+"_"+std::to_string(params.jobID)+"_"+std::to_string(b),"eps");
|
||||
//Save the mean to a vector so you can print it later
|
||||
means.push_back(fit_func->GetParameter("Mean") );
|
||||
h_errors->Clear();
|
||||
}
|
||||
if (means.size()>0){
|
||||
std::vector<double>valSM = fixSM(observable);
|
||||
std::cout << "$" << observable << "$\t";
|
||||
for_indexed (auto val: means) std::cout << " & $" << valSM[i] << " \\pm " << val << "$";
|
||||
std::cout << "\\\\" << std::endl;
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
12
Code/FCNCFitter/sources/Scripts/GetMeanError.hh
Normal file
12
Code/FCNCFitter/sources/Scripts/GetMeanError.hh
Normal file
@ -0,0 +1,12 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef GETMEANERROR_HH
|
||||
#define GETMEANERROR_HH
|
||||
|
||||
#endif // GETMEANERROR_HH
|
||||
|
||||
#include <parse.hh>
|
||||
#include <paths.hh>
|
||||
#include <spdlog.h>
|
||||
|
||||
int loadAllFiles(std::string observable, basic_params params);
|
294
Code/FCNCFitter/sources/Scripts/ReferencePlots.cc
Normal file
294
Code/FCNCFitter/sources/Scripts/ReferencePlots.cc
Normal file
@ -0,0 +1,294 @@
|
||||
//Renata Kopecna
|
||||
|
||||
|
||||
#include "ReferencePlots.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "ScriptHelpers.hh"
|
||||
#include <bu2kstarmumu_parameters.hh>
|
||||
#include <paths.hh>
|
||||
#include <helpers.hh>
|
||||
|
||||
#include <TColor.h>
|
||||
#include <TH2D.h>
|
||||
#include <TCanvas.h>
|
||||
#include <TROOT.h>
|
||||
#include <TFile.h>
|
||||
#include <TTree.h>
|
||||
|
||||
#include <spdlog.h>
|
||||
|
||||
const int oneSigma_RGB[3] = {34,136,51};
|
||||
const int twoSigma_RGB[3] = {170,170,0};
|
||||
const int threeSigma_RGB[3] = {238,22,136};
|
||||
const int moreSigma_RGB[3] = {204,51,17};
|
||||
|
||||
//TODO: make it into a texfile instead of a cout!
|
||||
|
||||
const std::vector<valErr> Davids = {
|
||||
valErr(+0.572,0.005),//valErr(+0.321,0.004),
|
||||
valErr(-0.002,0.007),
|
||||
valErr(-0.246,0.008),
|
||||
valErr(-0.003,0.008),
|
||||
valErr(-0.002,0.005),//valErr(-0.003,0.006),
|
||||
valErr(-0.001,0.008),
|
||||
valErr(-0.063,0.008),
|
||||
valErr(-0.084,0.007)
|
||||
};
|
||||
const std::vector<valErr> Belles = {
|
||||
valErr(+0.604,0.015),//valErr(+0.297,0.011),
|
||||
valErr(-0.018,0.017),
|
||||
valErr(-0.255,0.010),
|
||||
valErr(0.0,0.0),
|
||||
valErr(0.0,0.0),
|
||||
valErr(0.0,0.0),
|
||||
valErr(-0.037,0.018),
|
||||
valErr(-0.041,0.016)
|
||||
};
|
||||
const std::vector<valErr> BaBars = {
|
||||
valErr(+0.556,0.009),//valErr(+0.333,0.007),
|
||||
valErr(+0.011,0.011),
|
||||
valErr(-0.237,0.007),
|
||||
valErr(0.0,0.0),
|
||||
valErr(0.0,0.0),
|
||||
valErr(0.0,0.0),
|
||||
valErr(-0.058,0.015),
|
||||
valErr(-0.095,0.014)
|
||||
};
|
||||
const std::vector<valErr> B0s = {
|
||||
valErr(+0.572,0.008),//valErr(+0.321,0.006),
|
||||
valErr(-0.013,0.010),
|
||||
valErr(-0.250,0.006),
|
||||
valErr(0.0,0.0),
|
||||
valErr(0.0,0.0),
|
||||
valErr(0.0,0.0),
|
||||
valErr(-0.048,0.007),
|
||||
valErr(-0.084,0.006)
|
||||
};
|
||||
|
||||
std::vector<double>getSigma(std::vector<valErr> vec_a, std::vector<valErr> vec_b){
|
||||
if (vec_a.size() != vec_b.size()){
|
||||
spdlog::error("Two valErr vectors have different lenghts! Abort.");
|
||||
assert(0);
|
||||
}
|
||||
std::vector<double>sigs;
|
||||
for_indexed(auto a: vec_a){
|
||||
sigs.push_back(sigmaAway(a,vec_b[i]));
|
||||
}
|
||||
return sigs;
|
||||
}
|
||||
|
||||
std::vector<const int*>getSigmaColor(std::vector<double>vec_sigma){
|
||||
std::vector<const int*> tmp;
|
||||
for(auto sigma: vec_sigma){
|
||||
if (fabs(sigma) < 1.0) tmp.push_back(oneSigma_RGB);
|
||||
else if (fabs(sigma) < 2.0) tmp.push_back(twoSigma_RGB);
|
||||
else if (fabs(sigma) < 3.0) tmp.push_back(threeSigma_RGB);
|
||||
else tmp.push_back(moreSigma_RGB);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
std::string getSigmaColor_str(double sigma){
|
||||
if (fabs(sigma) < 1.0) return "\\cellcolor{oneSigma}";
|
||||
else if (fabs(sigma) < 2.0) return "\\cellcolor{twoSigmas}";
|
||||
else if (fabs(sigma) < 3.0) return"\\cellcolor{threeSigmas}";
|
||||
else return "\\cellcolor{moreSigmas}";
|
||||
}
|
||||
|
||||
std::vector<std::string>getSigmaColor_strVec(std::vector<double>vec_sigma){
|
||||
std::vector<std::string> tmp;
|
||||
for(auto sigma: vec_sigma) tmp.push_back(getSigmaColor_str(sigma));
|
||||
return tmp;
|
||||
}
|
||||
double getCorrectedError(std::string name, double err, int jobID){ //For now, no bins, cause it is used anyhow only for reference //TODO
|
||||
|
||||
basic_params tmpParams; //This is dumb, but no time
|
||||
tmpParams.jobID = jobID;
|
||||
|
||||
std::string fileName = get_ToyPullPlot_folder(tmpParams)+"pullResults.root";
|
||||
spdlog::info("Opening " + fileName);
|
||||
TFile* file = new TFile(fileName.c_str(), "READ");
|
||||
|
||||
if (!file->GetListOfKeys()->Contains(name.c_str())){
|
||||
spdlog::critical("Wrong tree name " + name + "! Abort.");
|
||||
assert(0);
|
||||
}
|
||||
//Get the tree and set the branches to active
|
||||
TTree* tree = (TTree*)file->Get(name.c_str());
|
||||
tree->SetBranchStatus("*",1); //Activate all branches
|
||||
double width = DEFAULT_TREE_ERR;
|
||||
double mean = DEFAULT_TREE_VAL;
|
||||
|
||||
tree->SetBranchAddress("width", &width);
|
||||
tree->SetBranchAddress("mean", &mean);
|
||||
|
||||
tree->GetEntry(0);
|
||||
file->Close();
|
||||
|
||||
//get_param_valueError_from_rootfile()
|
||||
|
||||
return err*width;
|
||||
}
|
||||
|
||||
int plotComparisonFull(){
|
||||
spdlog::debug("Starting with printing the values for RefChan measurement in a nice table.");
|
||||
double fractionOfStats = 1.0;
|
||||
|
||||
basic_params params_Fit= basic_params();
|
||||
params_Fit.Run = 12;
|
||||
params_Fit.nBins = 1;
|
||||
params_Fit.reference =true;
|
||||
std::string fitFile = final_result_name(true, false, params_Fit,
|
||||
true, 1, params_Fit.Run,
|
||||
false, fractionOfStats,
|
||||
false, -1);
|
||||
|
||||
std::vector<valErr> myValues;
|
||||
spdlog::debug("Filling my values into a vector");
|
||||
for (auto obs: ANG_OBS){
|
||||
//The easiest rounding in c++
|
||||
double err = get_param_error_from_rootfile(fitFile, obs, 1,0);
|
||||
//The easiest rounding in c++
|
||||
err = round(getCorrectedError(obs,err,649)*1000.0)/1000.0; //TODO
|
||||
double val = round(get_param_value_from_rootfile(fitFile, obs, 1,0)*1000.0)/1000.0;
|
||||
myValues.push_back(valErr(val,err));
|
||||
}
|
||||
std::vector<std::string>col_Davids = getSigmaColor_strVec(getSigma(myValues,Davids));
|
||||
std::vector<std::string>col_Belles = getSigmaColor_strVec(getSigma(myValues,Belles));
|
||||
std::vector<std::string>col_BaBars = getSigmaColor_strVec(getSigma(myValues,BaBars));
|
||||
std::vector<std::string>col_B0s = getSigmaColor_strVec( getSigma(myValues,B0s));
|
||||
|
||||
std::cout << "\\begin{table}[]" << std::endl;
|
||||
std::cout << "\\begin{tabular}{llllll}" << std::endl;
|
||||
std::cout << " & this fit & \\lhcb \\Bu & Belle (\\Bu) & BaBar (\\Bu + \\Bd) & \\lhcb \\Bd \\\\\\hline" << std::endl;
|
||||
for_indexed(auto myVal: myValues){
|
||||
std::cout << std::setprecision(3) << "$" << ANG_OBS_TLaTeX[i] << "$";
|
||||
std::cout << " & " << myVal.val << "$\\pm$" <<myVal.err;
|
||||
std::cout << " & " << col_Davids[i] << " " << Davids[i].val << "$\\pm$" <<Davids[i].err;
|
||||
std::cout << " & " << col_Belles[i] << " " << Belles[i].val << "$\\pm$" <<Belles[i].err;
|
||||
std::cout << " & " << col_BaBars[i] << " " << BaBars[i].val << "$\\pm$" <<BaBars[i].err;
|
||||
std::cout << " & " << col_B0s[i] << " " << B0s[i].val << "$\\pm$" <<B0s[i].err;
|
||||
std::cout << "\\\\" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << " \\end{tabular}" << std::endl;
|
||||
std::cout << " \\end{table}" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int foldingTable(){
|
||||
spdlog::debug("Starting with printing the values for different foldings RefChan measurement in a nice table.");
|
||||
double fractionOfStats = 1.0;
|
||||
|
||||
basic_params params_Fit= basic_params();
|
||||
params_Fit.Run = 12;
|
||||
params_Fit.nBins = 1;
|
||||
params_Fit.reference =true;
|
||||
|
||||
std::cout << "\\begin{table}[]" << std::endl;
|
||||
std::cout << "\\begin{tabular}{l|"; //First cell is for the obs name
|
||||
for (int f = -1; f<MAX_FOLDING; f++) std::cout << "l";
|
||||
std::cout << "}" << std::endl;
|
||||
std::cout << std::setprecision(1) << " & No folding" ;
|
||||
for (int f = 0; f<MAX_FOLDING; f++) std::cout << " & Folding " << f;
|
||||
std::cout <<"\\\\\\hline" << std::endl;
|
||||
|
||||
for_indexed (auto obs: ANG_OBS){ //TODO: if it would be for me, this would be a struct of name and latexname
|
||||
std::cout << std::setprecision(3) << "$" << ANG_OBS_TLaTeX[i] << "$";
|
||||
params_Fit.folding = -1; //Needed extra as it has to be saved to myVec to get the sigmas away
|
||||
std::string fitFile = final_result_name(true, false, params_Fit,
|
||||
true, 1, params_Fit.Run,
|
||||
false, fractionOfStats,
|
||||
false, -1);
|
||||
//The easiest rounding in c++
|
||||
double err = get_param_error_from_rootfile(fitFile, obs, 1,0);
|
||||
//The easiest rounding in c++
|
||||
err = round(getCorrectedError(obs,err,649)*1000.0)/1000.0; //TODO
|
||||
|
||||
double val = round(get_param_value_from_rootfile(fitFile, obs, 1,0)*1000.0)/1000.0;
|
||||
valErr full(err,val);
|
||||
std::cout << " & " << val << "$\\pm$" << err;
|
||||
|
||||
for (int f = 0; f<MAX_FOLDING; f++){
|
||||
if (plotObsv(f,obs)){
|
||||
params_Fit.folding = f;
|
||||
int jobID = 626+params_Fit.folding;
|
||||
if (params_Fit.folding==4) jobID = 650;
|
||||
|
||||
std::string fitFile = final_result_name(true, false, params_Fit,
|
||||
true, 1, params_Fit.Run,
|
||||
false, fractionOfStats,
|
||||
false, -1);
|
||||
|
||||
//The easiest rounding in c++
|
||||
double err = get_param_error_from_rootfile(fitFile, obs, 1,0);
|
||||
//The easiest rounding in c++
|
||||
err = round(getCorrectedError(obs,err,jobID)*1000.0)/1000.0;
|
||||
double val = round(get_param_value_from_rootfile(fitFile, obs, 1,0)*1000.0)/1000.0;
|
||||
|
||||
std::cout << " & " << getSigmaColor_str(sigmaAway(full,valErr(err,val))) << val << "$\\pm$" << err;
|
||||
}
|
||||
else std::cout << " & ";
|
||||
}
|
||||
std::cout << "\\\\" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << " \\end{tabular}" << std::endl;
|
||||
std::cout << " \\end{table}" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int plotComparisonSigmas(){
|
||||
spdlog::debug("Starting with printing the values for RefChan measurement in a nice table.");
|
||||
double fractionOfStats = 1.0;
|
||||
|
||||
basic_params params_Fit= basic_params();
|
||||
params_Fit.Run = 12;
|
||||
params_Fit.nBins = 1;
|
||||
params_Fit.reference =true;
|
||||
std::string fitFile = final_result_name(true, false, params_Fit,
|
||||
true, 1, params_Fit.Run,
|
||||
false, fractionOfStats,
|
||||
false, -1);
|
||||
|
||||
std::vector<valErr> myValues;
|
||||
spdlog::debug("Filling my values into a vector");
|
||||
for (auto obs: ANG_OBS){
|
||||
double err = get_param_error_from_rootfile(fitFile, obs, 1,0);
|
||||
//The easiest rounding in c++
|
||||
err = round(getCorrectedError(obs,err,649)*1000.0)/1000.0; //TODO
|
||||
double val = round(get_param_value_from_rootfile(fitFile, obs, 1,0)*1000.0)/1000.0;
|
||||
myValues.push_back(valErr(val,err));
|
||||
}
|
||||
std::vector<double>sig_Davids = getSigma(myValues,Davids);
|
||||
std::vector<double>sig_Belles = getSigma(myValues,Belles);
|
||||
std::vector<double>sig_BaBars = getSigma(myValues,BaBars);
|
||||
std::vector<double>sig_B0s = getSigma(myValues,B0s);
|
||||
|
||||
std::cout << "\\begin{table}[]" << std::endl;
|
||||
std::cout << "\\begin{tabular}{l|llll}" << std::endl;
|
||||
std::cout << " & \\lhcb \\Bu & Belle (\\Bu) & BaBar (\\Bu + \\Bd) & \\lhcb \\Bd \\\\\\hline" << std::endl;
|
||||
//for_indexed(auto myVal: myValues){ //TODO remove: yields warning in compilation due to unused 'myVals'
|
||||
for(UInt_t i = 0; i < sig_Davids.size(); i++){
|
||||
std::cout << std::setprecision(2) << "$" << ANG_OBS_TLaTeX[i] << "$";
|
||||
std::cout << " & " << sig_Davids[i];
|
||||
std::cout << " & " << sig_Belles[i];
|
||||
std::cout << " & " << sig_BaBars[i];
|
||||
std::cout << " & " << sig_B0s[i];
|
||||
std::cout << "\\\\" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << " \\end{tabular}" << std::endl;
|
||||
std::cout << " \\end{table}" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
10
Code/FCNCFitter/sources/Scripts/ReferencePlots.hh
Normal file
10
Code/FCNCFitter/sources/Scripts/ReferencePlots.hh
Normal file
@ -0,0 +1,10 @@
|
||||
//Renata Kopecna
|
||||
|
||||
#ifndef REFERENCEPLOTS_HH
|
||||
#define REFERENCEPLOTS_HH
|
||||
|
||||
int plotComparisonFull();
|
||||
int foldingTable();
|
||||
int plotComparisonSigmas();
|
||||
|
||||
#endif // REFERENCEPLOTS_HH
|
73
Code/FCNCFitter/sources/Scripts/RunningScripts.cc
Normal file
73
Code/FCNCFitter/sources/Scripts/RunningScripts.cc
Normal file
@ -0,0 +1,73 @@
|
||||
//Renata Kopecna
|
||||
|
||||
|
||||
#include "RunningScripts.hh"
|
||||
#include <string.h>
|
||||
#include <helpers.hh>
|
||||
|
||||
#include "ScriptHelpers.hh"
|
||||
|
||||
int runWhatever(basic_params pars, basic_actions acts){
|
||||
int status = 0;
|
||||
|
||||
|
||||
for (auto obs: ANG_OBS){
|
||||
plotComparison(obs);
|
||||
plotComparisonMCFolding(obs);
|
||||
}
|
||||
|
||||
|
||||
// plotComparisonFull();
|
||||
// plotComparisonSigmas();
|
||||
// foldingTable();
|
||||
//return loadAllFiles("S3",pars);
|
||||
//return loadAllFiles("Fl",pars);
|
||||
|
||||
//for(auto obs: ANG_OBS) loadAllFiles(obs,pars);
|
||||
return 0;
|
||||
|
||||
|
||||
|
||||
bool toyEval = true;
|
||||
bool loopFolds = pars.folding == 5;
|
||||
bool onlySig = isInVec(pars.jobID,{531, 532, 533, 534, 535, 536, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595});
|
||||
bool onlyBkg = isInVec(pars.jobID,{546, 547, 548, 549, 550, 551});
|
||||
bool sWave = isInVec(pars.jobID,{496, 497, 498, 531, 532, 533, 534, 535, 536, 558, 559, 560, 561, 562, 563, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650});
|
||||
bool bMass = isInVec(pars.jobID,{496, 497, 498, 572, 573, 574, 575, 576, 577, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 626, 627, 628, 629, 649, 650});
|
||||
if(toyEval){
|
||||
//bool doPulls = true;
|
||||
std::vector<std::string> variables = {};
|
||||
std::vector<std::string> names = {};
|
||||
if(!onlyBkg){
|
||||
variables = merge_two_vecs(variables,ANG_OBS);
|
||||
names = merge_two_vecs(names,ANG_OBS_TLaTeX);
|
||||
}
|
||||
if(false){
|
||||
variables = merge_two_vecs(variables,P_OBS);
|
||||
names = merge_two_vecs(names,P_OBS_TLaTeX);
|
||||
}
|
||||
if(false){
|
||||
variables = merge_two_vecs(variables,MASS_OBS);
|
||||
names = merge_two_vecs(names,MASS_OBS_TLaTeX);
|
||||
}
|
||||
if(!onlySig){
|
||||
variables = merge_two_vecs(variables,BKG_OBS);
|
||||
names = merge_two_vecs(names,BKG_OBS_TLaTeX);
|
||||
}
|
||||
if (sWave){
|
||||
variables = merge_two_vecs(variables,SWAVE);
|
||||
names = merge_two_vecs(names,SWAVE_TLaTeX);
|
||||
}
|
||||
if (bMass || pars.reference){
|
||||
variables = merge_two_vecs(variables,{"m_b"});
|
||||
names = merge_two_vecs(names,{"m_{B^{+}}"});
|
||||
}
|
||||
if (pars.reference){
|
||||
variables = merge_two_vecs(variables,{"m_sigma_1"});
|
||||
names = merge_two_vecs(names,{"\\sigma_{1}"});
|
||||
}
|
||||
return EvaluateToyStudy(variables, names, pars, loopFolds, true, false, onlySig, onlyBkg) + EvaluateToyStudy(variables, names, pars, loopFolds, false, false, onlySig, onlyBkg);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user