Pushing FCNC fitter. Removed tmp files accidentaly pushed

This commit is contained in:
Renata Kopecna 2022-02-10 17:00:28 +01:00
parent e49c224d67
commit 6b17868719
250 changed files with 36026 additions and 23 deletions

View 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)

View 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
)

View 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

View 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

View 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

View 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

View 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
)

View 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)

View File

View 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

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

View 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))

View 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

View 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 "$@"

View 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

View 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

Binary file not shown.

0
Code/FCNCFitter/dummy Normal file
View File

View 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
View 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
View 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")

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

View 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)

View 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(&params->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;
}

View 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

View 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;
}

View 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

View 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",&param_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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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;
}

View 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

File diff suppressed because one or more lines are too long

View 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

View 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

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

View 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

View 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;
}

View 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

View 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

View 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

View 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",&param_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();
}

View 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

View 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

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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;
}

View 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

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

View 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

View 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",&param_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);
}
}

View 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

View 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

View 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, &params);
//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, &params);
//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, &params);
//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;
}

View 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

View 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;
}

View 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

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

View 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

View 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;
}

View 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

View 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;
}

View 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

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

View 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

View 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;
}

View 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

View 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;
}

View 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

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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;
}

View 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

View 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;
}
}

View 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

View 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;
}

View 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

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

View 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

View 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);
//---------------------------------------------------//
}

View 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

View 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;
}

View 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);

View 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;
}

View File

@ -0,0 +1,10 @@
//Renata Kopecna
#ifndef REFERENCEPLOTS_HH
#define REFERENCEPLOTS_HH
int plotComparisonFull();
int foldingTable();
int plotComparisonSigmas();
#endif // REFERENCEPLOTS_HH

View 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