From 8dbd706238895c86a48c49f7bdd13ecb8c98caf9 Mon Sep 17 00:00:00 2001 From: juacrumar Date: Thu, 30 Jan 2025 20:36:17 +0100 Subject: [PATCH 01/19] first commit, move temporary files to a separate folder --- .gitignore | 5 ++- README | 10 +++--- fixpar_nnpdf.py | 13 +++++++- {outputs => outputs_old}/buffer/test.dat | 0 {outputs => outputs_old}/evgrids/TODO.dat | 0 {outputs => outputs_old}/evgrids/post_fit.sh | 0 .../test/nnfit/replica_1/test.exportgrid | 0 {outputs => outputs_old}/grids/test/test.info | 0 .../grids/test/test_0000.dat | 0 {outputs => outputs_old}/pars/test.dat | 0 {outputs => outputs_old}/plots/test.dat | 0 {outputs => outputs_old}/res/test.dat | 0 src/__pycache__/chebyshevs.cpython-38.pyc | Bin 4049 -> 0 bytes src/__pycache__/chebyshevs.cpython-39.pyc | Bin 4045 -> 0 bytes src/__pycache__/chi2s.cpython-38.pyc | Bin 24901 -> 0 bytes src/__pycache__/chi2s.cpython-39.pyc | Bin 29849 -> 0 bytes src/__pycache__/data_theory.cpython-38.pyc | Bin 3747 -> 0 bytes src/__pycache__/data_theory.cpython-39.pyc | Bin 10111 -> 0 bytes src/__pycache__/error_calc.cpython-38.pyc | Bin 15845 -> 0 bytes src/__pycache__/error_calc.cpython-39.pyc | Bin 17100 -> 0 bytes src/__pycache__/global_pars.cpython-38.pyc | Bin 7624 -> 0 bytes src/__pycache__/global_pars.cpython-39.pyc | Bin 16259 -> 0 bytes src/__pycache__/inputs.cpython-38.pyc | Bin 2439 -> 0 bytes src/__pycache__/inputs.cpython-39.pyc | Bin 4752 -> 0 bytes src/__pycache__/levmar.cpython-38.pyc | Bin 8313 -> 0 bytes src/__pycache__/levmar.cpython-39.pyc | Bin 8313 -> 0 bytes src/__pycache__/lhapdf_funs.cpython-38.pyc | Bin 3843 -> 0 bytes src/__pycache__/lhapdf_funs.cpython-39.pyc | Bin 4199 -> 0 bytes src/__pycache__/minpars.cpython-39.pyc | Bin 10702 -> 0 bytes src/__pycache__/msht_theory.cpython-39.pyc | Bin 15983 -> 0 bytes src/__pycache__/outputs.cpython-38.pyc | Bin 9090 -> 0 bytes src/__pycache__/outputs.cpython-39.pyc | Bin 9942 -> 0 bytes src/__pycache__/pdfs.cpython-38.pyc | Bin 13301 -> 0 bytes src/__pycache__/pdfs.cpython-39.pyc | Bin 19720 -> 0 bytes src/chi2s.py | 14 ++++----- src/global_pars.py | 2 ++ src/inputs.py | 16 ++++++++-- src/lhapdf_funs.py | 29 ++++++------------ 38 files changed, 52 insertions(+), 37 deletions(-) rename {outputs => outputs_old}/buffer/test.dat (100%) rename {outputs => outputs_old}/evgrids/TODO.dat (100%) rename {outputs => outputs_old}/evgrids/post_fit.sh (100%) rename {outputs => outputs_old}/evgrids/test/nnfit/replica_1/test.exportgrid (100%) rename {outputs => outputs_old}/grids/test/test.info (100%) rename {outputs => outputs_old}/grids/test/test_0000.dat (100%) rename {outputs => outputs_old}/pars/test.dat (100%) rename {outputs => outputs_old}/plots/test.dat (100%) rename {outputs => outputs_old}/res/test.dat (100%) delete mode 100644 src/__pycache__/chebyshevs.cpython-38.pyc delete mode 100644 src/__pycache__/chebyshevs.cpython-39.pyc delete mode 100644 src/__pycache__/chi2s.cpython-38.pyc delete mode 100644 src/__pycache__/chi2s.cpython-39.pyc delete mode 100644 src/__pycache__/data_theory.cpython-38.pyc delete mode 100644 src/__pycache__/data_theory.cpython-39.pyc delete mode 100644 src/__pycache__/error_calc.cpython-38.pyc delete mode 100644 src/__pycache__/error_calc.cpython-39.pyc delete mode 100644 src/__pycache__/global_pars.cpython-38.pyc delete mode 100644 src/__pycache__/global_pars.cpython-39.pyc delete mode 100644 src/__pycache__/inputs.cpython-38.pyc delete mode 100644 src/__pycache__/inputs.cpython-39.pyc delete mode 100644 src/__pycache__/levmar.cpython-38.pyc delete mode 100644 src/__pycache__/levmar.cpython-39.pyc delete mode 100644 src/__pycache__/lhapdf_funs.cpython-38.pyc delete mode 100644 src/__pycache__/lhapdf_funs.cpython-39.pyc delete mode 100644 src/__pycache__/minpars.cpython-39.pyc delete mode 100644 src/__pycache__/msht_theory.cpython-39.pyc delete mode 100644 src/__pycache__/outputs.cpython-38.pyc delete mode 100644 src/__pycache__/outputs.cpython-39.pyc delete mode 100644 src/__pycache__/pdfs.cpython-38.pyc delete mode 100644 src/__pycache__/pdfs.cpython-39.pyc diff --git a/.gitignore b/.gitignore index 7f150f4..8762454 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ # To ignore *.*~ **/*.*~ -git_push.sh \ No newline at end of file +git_push.sh +__pycache__ +outputs/ +tmp_lhapdf diff --git a/README b/README index e8ea136..d779d3a 100644 --- a/README +++ b/README @@ -1,10 +1,10 @@ Readme (under construction) for fixpar_nnpdf code -Requires NNPDF code from https://docs.nnpdf.science via conda installation. Tested for: +Requires NNPDF code from https://docs.nnpdf.science either from source or conda -conda install nnpdf python=3.9 - -(I think python version may be needed for lhapdf to run though need to double check that) +``` + conda install nnpdf -c https://packages.nnpdf.science/conda -c conda-forge +``` To run simply execute: @@ -18,4 +18,4 @@ The outputs are in the outputs/ folder: /buffer : outputs from running code /cov : covariance matrix (used for error calculation) /evscans: outputs if eigenvector scan is done -/pars : the PDF parameters \ No newline at end of file +/pars : the PDF parameters diff --git a/fixpar_nnpdf.py b/fixpar_nnpdf.py index 628fc46..47e64bc 100644 --- a/fixpar_nnpdf.py +++ b/fixpar_nnpdf.py @@ -32,6 +32,13 @@ from validphys.loader import _get_nnpdf_profile from validphys.lhaindex import get_lha_datapath +lhapdf.setVerbosity(0) + +# Fake LHAPDF folder +TEMP_LHAPDF = pathlib.Path("tmp_lhapdf") +TEMP_LHAPDF.mkdir(exist_ok=True) +lhapdf.pathsAppend(TEMP_LHAPDF.as_posix()) + sys.path.append("src/") from global_pars import * @@ -248,7 +255,8 @@ fit_pars.dataset_40=fit_pars.dataset_40_nlo fit_pars.imaxdat=len(fit_pars.dataset_40) -pdf_pars.lhapdfdir=get_lha_datapath()+'/' +pdf_pars.lhapdfdir = get_lha_datapath() + "/" +pdf_pars.tmp_lhapdfdir = TEMP_LHAPDF profile=_get_nnpdf_profile(None) fit_pars.datapath=pathlib.Path(profile["data_path"]) # fit_pars.theories_path=pathlib.Path(profile["theories_path"]) @@ -610,3 +618,6 @@ resout(pospeni,pospenf,chi2t0i,chi2expi,chi2t0f,chi2expf,chi2_pars.ndat) t1=time.process_time() print('time= ',t1-tzero) + + +# TODO Remove TEMP_LHAPDF at the end diff --git a/outputs/buffer/test.dat b/outputs_old/buffer/test.dat similarity index 100% rename from outputs/buffer/test.dat rename to outputs_old/buffer/test.dat diff --git a/outputs/evgrids/TODO.dat b/outputs_old/evgrids/TODO.dat similarity index 100% rename from outputs/evgrids/TODO.dat rename to outputs_old/evgrids/TODO.dat diff --git a/outputs/evgrids/post_fit.sh b/outputs_old/evgrids/post_fit.sh similarity index 100% rename from outputs/evgrids/post_fit.sh rename to outputs_old/evgrids/post_fit.sh diff --git a/outputs/evgrids/test/nnfit/replica_1/test.exportgrid b/outputs_old/evgrids/test/nnfit/replica_1/test.exportgrid similarity index 100% rename from outputs/evgrids/test/nnfit/replica_1/test.exportgrid rename to outputs_old/evgrids/test/nnfit/replica_1/test.exportgrid diff --git a/outputs/grids/test/test.info b/outputs_old/grids/test/test.info similarity index 100% rename from outputs/grids/test/test.info rename to outputs_old/grids/test/test.info diff --git a/outputs/grids/test/test_0000.dat b/outputs_old/grids/test/test_0000.dat similarity index 100% rename from outputs/grids/test/test_0000.dat rename to outputs_old/grids/test/test_0000.dat diff --git a/outputs/pars/test.dat b/outputs_old/pars/test.dat similarity index 100% rename from outputs/pars/test.dat rename to outputs_old/pars/test.dat diff --git a/outputs/plots/test.dat b/outputs_old/plots/test.dat similarity index 100% rename from outputs/plots/test.dat rename to outputs_old/plots/test.dat diff --git a/outputs/res/test.dat b/outputs_old/res/test.dat similarity index 100% rename from outputs/res/test.dat rename to outputs_old/res/test.dat diff --git a/src/__pycache__/chebyshevs.cpython-38.pyc b/src/__pycache__/chebyshevs.cpython-38.pyc deleted file mode 100644 index 420576da21b394bf2520bfbddfa15ae25603a24d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4049 zcmcgv&uN(qDjQH9D%jVh3kg<6m(LJh{xBxxPT%x+pD zxe^sr>ao4`zyWSW>Y;zno+@#uxb;}|)bGvCdhJjzM2)(Z=k1%>o%!B3-^{$dRVWM# zT>jFl`t2bhUa`}CDL5Yf{x2voLZh(5G)8-1b2Ls9uz4!dUf2Rn(iH3nm1rOADD9_d*fE-+1F(DO zARU4or&&4-J3&Y2C~T3A(Q(+lq&^en6R&|*lw~MSRZwPDs_X03n!}a$a$yJX{}_M& zIf}L<`IXQY1JOowQ{sulos8~^;#;Tfa7$ZGA!cr!MqTqkAfKzYwDsYU!X zwtS(A!qi7S;K{bgfwPj}mbiC9{S#@Pbb$ii3wYd$m@<_Wz{K^r_gccd=BfFED}?y- zN;#uByihe;q3b`?L6~W6d{ft4vfz%KM@FXnn02Ivbn8OQFZ`{NGD+o6WUH zbHQqTLvPK`HLA^(xd&^(vL95NRBdcD>&tPQuWQSjEm{uhelS;Ct>54BSLZ&}b^f>(fv>!ujL~2_-afk^w)Pp?uMNx`FcPchc;n|ztue_9| zcb!8gCX}ey12=T8ZJp!je4b^YW|f|V?GI!Tt?584ILv$uZYl=n#^A<0T|`HkWu^CW z(FfZ+qp{c)lrF*RkL@~I--693lhu-7ql_VQAgSw+IT-7x6yddup7acG>&?bQ|8*rb zl=Cx5C|8wcuYV}_b}bYdG~s2F@H*2mRMGn}j+u%T+~8X53C;8LG%9VNXFWXuFEz-8 zBY48j*IlI#!RsGnfY#laFFS{W-9b{;1U{71b>?+Ap4Vg1yxQQGqTsD}GYUS6`2e6= z8eA`xfeR-S23krVPG#VS-DBWirkREe1H;`6P|nolle&%^3KhK%c)I0K>5&6Pj97k} zksPeI>gid$Y&p6SuZe6rSr^aX9V?foN*{;UUoOwkx=V8T4`fln5IB+$*pby}EUVK! zvbxnRtH%$!NqqcW4~gIRkl6M#Z~KY?{pM6Y2rdO-Z>X6QAz404O}4}*Ya&^jok-+a=9KMo=+(}7c+C!xSNa2Z zZw$dngc)KMH_?$BA8CO}vN$j3C{tC;Hdc;K(6nrzHvb7aw1dwm%?tF6!8_R?>$7)o zQpxZ=X-UK^zW@|`_@z>Cp3icN0y)VXy#6T8qIDYzWR{$1#>r8jVy~kjP{M~_*)fNd z$t+TNS@<+TbXsX1vp*tUgWC{o3VN=)_L>Wu@og^(S~~$H2)=pmzx~ zQ_)A!mp+BUMsPijV1^^$4fGwUzeIS}M&K!Z9$xj5s;NxnOE6db|CHd4|>gMfdBvi diff --git a/src/__pycache__/chebyshevs.cpython-39.pyc b/src/__pycache__/chebyshevs.cpython-39.pyc deleted file mode 100644 index 5fa3f33fce4d55025c1e1e14da1444bec0d5a6c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4045 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 diff --git a/src/__pycache__/data_theory.cpython-38.pyc b/src/__pycache__/data_theory.cpython-38.pyc deleted file mode 100644 index dea1659d9fff4514347cff71c9e2c4e2187705e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3747 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 IJ)ishf97eYT>t<8 diff --git a/src/__pycache__/data_theory.cpython-39.pyc b/src/__pycache__/data_theory.cpython-39.pyc deleted file mode 100644 index 4abee1924474eb6bc9fdca4689ad484d2d216c16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10111 zcmb7KTaX;rS?<%f>FJ%FUCqv3w33~%eACGCN?O~oWmLYzLKQn=typrf8^Wk}PS0-7 z&P}I#R$8S8J6>@Oc0^GS+XPqGmS|v zk1?FaRCC&!R=#v)-&K=Nfa(d2e2oSz|%1Ez>yY z9mJTK#-g`~e6n$`{<8yo-`Tcx>A4L8DU*w07KgbXByO1B{ck_=SFY}M{62IpL^N#Vy`4N6E zN)Pe-`2A=*&Y$29@CN~Tn4jiHc^Rc8{v$SHo3p8{l= zFY`x`Kf)j7k0F1QXD({xGq>ri%1p9jNX%+m1jvnNFFcPd*Yr1niU>N5u-xvj!b(tHj%eg_P+Quk+1ryrm+ddBjPzvil7wy() z2RX&VXcT~Mi-WQD={`Sb+l$8JTxD&uawiIHxq%f_Y8$b?+8|0ysd}~DY_?n6k9~mj z7cU^q2Al0hmq=07iG=;1g*=1rIebwENvzeGI2P-5gEOvwSzlv4JvQrBLM=8o5}liG znmwac7=c>ce$(g~=#dex#7;t`Y{GbkJ3RZQ)iYbgF=!@*CMHhQUAg@s<^^%`wBRU+ zD`BhCjU(yA>p@#=g!KQ)zY^v9#BM z7Ld!XbZTK->G%T6ZZ+EJa$K%XLqTmG;Z#e?ikuznK9p7` z3c6g-SxGab`7CiSRSYah=0^7`jYgGwHpY+J@%x&12;Dw<_C&W8UOSNvxO}4Fx7JRq zVY#*N8rD{cgD8$pyx_N%AFr+l)r}L8sGgt|R#J?m&X&xfUa9(xDqSz4dNhqh(`}Y# zb9w>!oL)4;j{5&Vv`%dwzx5`ZR=;X&%WJrXtcyRI2?6B z>tz8m`Y<&vU~X*hWRmPH#?1{={9fV^O-EK@U?t`l!~(=tSZ*KdJg{(AY4rYT3CkLT z5LV{Od7Krab4ctYljw<2b8sH^ilD>(H+<@Mn`&!2-~P}4`P3&rIDMN0P1#W-lun1& z`u79$<`rKE>7dkAB};%O1DS0RKh{JLh!en-hQAt>Cp@dV9-icB)|E!cH$5ZlZh96E zYc;?r>w4CD5Jjj_)|GnLp#ujq&~>1^yZ7L80Mo%MzFx+B(NQFtUSI{q0mKFP(~IDR zBKX{7XzAxgT|A4vW4xXPU?@w!i;CiPlAo|1VsQI5Q)m1SpgGA`V?&RYRLR`X#S0`) zsTSMy45*Eh;3QW~NY90R+A@&1W@6SIoL6?o#rW1X!!5G=v!SMD`-vW;aL?(Fn8m0r zX4~NtW3U`xAMAlm0`?)nuqsM(IQ`5)y06Z*PJD1iyK*C8n0+#_Z?So;$F9sJ41AGa z5g*6?6?26D{@GPMT>tNnba4nUNNy#x4e*0>JME}13Y9d5c&0}22}M#Nzp?Zz zZfU9FZ^X5Nk?S_on<#I69>?+TGZ*kq|Nqv0T5omq8tju9)*Y*3@TCFr-lcOCHu2m~G|3 zkS3c3lj5V?u=P1(S{E+^V@%Q0{)dA2Bq}755-{e5B?^f~3O(ryWe5jjK`R1AVmQrl zsOHMrC%^j5cfa%Z*Pl`ctIkH#{_AP6gyEn@*)?$qC29GM&blvNLV3@Q#0tUirE(U_ zb(jt9;V{)QwqOz-20kTcN!gGDT2Se{c1XLZz0X$E@UR@1FWKszxujX~qphE$$&|sv z#E+p|Eg~8Gs63qF0xC4cJd_eX2;{`XXW_H)W$-!pviRI&0%;E4B)&YpDSXrT4&W=` zn@N`_UcsR0B8%cxDtkyIt4hWt3nT+?tVy;mE>hd4RojMS4au64wIpjx){*RrWJ0n? zviQy|!lw8<&<0y>)ZMlkAemC9TtNTNOmx6eFuk6r5}Z# zW8!byU|MVXlop*isWJ8UDpC&mgCVX@)HYgvGl-VJ^=gBXxiGxVwoZ?iWbj_dl4c?;@p4Qi1aJqX>p1r^L8>L7x}3QSgKo9$#1 z3t~0f%Ej(BR53S`Y-J*W!t63}J+XIkP>kRUQi@4t8+}2rxluT019+0**5jm3AEkA1 z8v^$0iOnHY>ky$F0u?IOev63f{BsG)^f{P}a9c_wR7&ku$!|1DFv?2jK6Qx<{-_kT zRGr#aVLO-nDqJECTeTFosl_ef2QR3r%;pl#Mfl_dlz33Xz?}MsAZ#s_&W2IPkE`oy zyp6EMOYK@|#91mGt+j<3juz3kn4{yRzI;4h3gT+{j`=Y{dozS_Te^I?wo&W0s+TVx zFI`;^tLtj4XuaKS@Y1@!8K{Y2Y6sX94EUN~#de}nu(Yq+G;Si1?->{wJ`(HtJB6jQM#6rFM?7x>SAkKB{&gFrSmY!iHxHZ zAmbdoNgbk6)mNk!0S2X6+Mx0HY**LYIFV@G?_k1q5VanROK>0hBnByHsG+A;@!p1t(^i?_drAC%k-f%J91DBC7smY46D-iJGjnV+DZjR zWmlXf6gxdnX+o2qQt2{ocZbecY*B|PP;>OqV7b*cq>e8OSNf`QbN1f-!YD#z8AC^3 z#8|2F%et`1b*6vMv|Xq>Gvhion}+XUGlwncbIi3|mbb+hfH5W*4g)Zhf@k1I{osND z!Xbmtfq=*&cl$!(?|KtTNO%wu6GI`9>kEk-ghZ}FJ#yk-lU#iQDP4FA7ydmZE^;I; zw#|MSUiCJVO%Fl(ZyyeZf{a)cQv3O zH@2-22t_9V0VNAb0b|ih)3H)4wNk`2vfEZ~CYjl%hguwSJde( zjE$sr(L1QH7LtSWDHiY*KTalqEoi65_MvvD`tEyX;Ln>TRHIUnRDusth^M*1bIK!G z>MbUPbPdTOam4T@xT@a24dBVbP2)Iy&(sl7x~HB|S<=K?ySC#cPzjjzrq6;3^`5f{foZR$z77 zR|BDZKk){2aZ+Ok>Ms+EE&{=u<-O-6AH@pClP&r<`;U8qeD26Cm`I$CtJ*l2lFwdnN>`ND8H^)%pB zcIfE=VNrHTx?vQyqS$X$1F3ho%$|j9c}~ENMXa{bhWT_6VaFhXTP%dXRW`j0odJ*# z*QJ6qDF7=Klz50jwrQfmlP=Z{FYJ@$tL1MlXTquYk7i}$gfDsjc&Hx{HOE+K+ZC=PBidsD~R>s*JocWemP z72IqgP>mofyh{pF!>~~VEF0H9{XAX_f+k*j!SLN_IYfXf_l3MG6LMLTg z{5G;(noDDC^Ash^`-W-0g3j$-+D*f}Mo3i8F+nY3%to}MPchp$6mX9;@kFZp#Ssd7 zrfdiLSSfu5F!;qoSj$b>b6dZN5CxQse%-%Fz92lnUCQmD*zwY8>Ovu)u-8{3Vh;S@ zKEX=}>Xn*7b2Sj~r5jsID~LC~jwLIO5K}0DP`^chacU`1zaOFG;r-7t<-yMp1@jnA z1NS);p)+w|4e?b##@rL4A6;NYL%Q^7*uJKPFpl11Z!ug|lS5in%oq=G{cCLYxlLcW zgk^Vtrh=TQiYrl-w5OZ`74V9dKHk9VN8gLo_&d~S;;Ai`R+SW_G&uq-;ubaTkwFt9 zWBdZ`ibRa27j;|D8{z|$@3>FH{rosuaep-2pG9)JaQYBK+h!g2s+ETzQjl$f>bOZp zY$?h6gp#~QJ)>kY-7)OFj=*#Dl4>#Q*}k~?6-)r1lw`jmt$3SChEi@nx$1 z8YRDuq<_}ZhLah#PC^<}E`EdBcPQD960Q>2ikM#_LeTBfY+MgJZ=@;^68Vn-8&g9> zjG;t+1{D${>UcFe-c%XkkfC_emlzT`DCrcsBBE@Qmjn_}u3~S-iZl_Vf!~dE8SjBK zymWWN38FxN>0LlYJrR@6LD&NbzfbLYm5XC2h(Dp^Pbt}R^cjp_LD1uCwA&myXkcVg z#V%4oHp3VzPXI6!2loL7N>;0|#K7TWM{3VZ?HT(5#2RCAi+t)GC(hRKLZ!6Rgz!+y zafUZ8Z`cZ-4&gdOyv?E0HZ}1Ewbb(oUasm>6x)PXftNMBoj6zidaTXF>$TByT95WI zzcJRTFuA3A6h>R{4x=M1sMV*%e+=Mw-6m)@$-;tnDhJRy0e?9+Sg$G<5(n>PHdKQP z5l1zc6+M?b@l3s#Xt48L2)k@*R>;hzFG3&3(|-r~3s4i520~$FJ$)JZ79fK%wL&e- zBNMYo&Xs3VrTrd3h#|zcC{d!}EK1TURg?WdNA{r^7yNQB|ibMG*g>S$_#48=dQEDO{A)!OUSKUOsNmHJ{NKEgj zDj{|N%Swl!g4lwf`i#QS!If#f))!n3!qE_Acm+bfh~zDd=+(hWxlgG|vB(K%R}o`FFXEnlRKI82qV;Z!_^%Xel%N8_Y^sUm49FlM|`=m%jIAVTgphv%VDx z11NHGSYN`USSq-RyD;^?4s9|e(|>rF-EFG2TZ4aM5hP?ph7!_6g2Mj7MFMe-K&l@p z>d5I`WMz2@K>|vU921k2ka|{{U)f2ru-m`3LI1Y_kCNO^Z)AbHCnJ6dO?U=GgcpyQ zi@UhHQnx<_3FFk?{ar#CnFg2?xQ|i`4gwsp?`v@*Tvh)|q2A8bOS5{>OW)7v9ZNJQ zi6~K;PH8{#1X5e(D^wyoLn&vakd&-e*Fc@z$jK{-PZvr$XPO9OH-e{#6{8DC9GpG< z72#`;qeku>)xis@P9-v|ooQ#nS#%z7a*pAcj_aOwU(+U?NjLB2+yl;pdl2ofY3KeI D;<(3y diff --git a/src/__pycache__/error_calc.cpython-38.pyc b/src/__pycache__/error_calc.cpython-38.pyc deleted file mode 100644 index 4de170c56f34decd1b8d35c9f3d53c365374a8f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15845 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 diff --git a/src/__pycache__/global_pars.cpython-38.pyc b/src/__pycache__/global_pars.cpython-38.pyc deleted file mode 100644 index cfad5e8048369feacdae45e7b832fd382aa430a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7624 zcmeHMNpl;=6~?|109Wm@C9g5#SOh?7a}=8-7LhUlLIh}s*-Z0a&=X1x#l0_m|GumNvd4D<(N2^e6MHF1WBlzxRjfL>et^}dVk$L^JXiR zO8D@5@b}5RKNo$zzY#O~3xZija()dWe8O+}m>+q-3LFGk(C@qN6G0LB+$Tbx1y~4N zSVX`@z=gp@MGRaFTm)QPB)}!WMZryoB)BBF7`T*3gG+;pgPRmn;HJPOz)g!8a5La0 zz|D#|aC6|2!e95zpF2X|eARisjFh`gVc0F=M}K}W%Sg@)h@nQn0!HvN9}B4(0y1Ht zB=2;3Vy`+MmNCvd%>#pTnc)1OD+U(fB#f3q~e7exz zH@fz-+=A8Yv={cwK6m=fj%Zrlj=_gI$8PaKPw>9s^cUJzceiQrUek7N^q$!?>mekE z+KBlTe`Zi*uuMjugA4~H{49usVX?5lq#MykF%dN4BJ>MP z3i&kB4ALypoQSe>sOLP=1*D5@AG?Hf8R-hrRg`@Rb}x$<79uX=t$j16hEe(oy;8p; zf$U4a42%A=p3$&rG1{)`AMaP^uh}#ZJ4_@3!eRr*=x18pLmB92WRz+&J3@v`(d^4W zrzgXo8g|!_L9^3m6C}kv@}_OGq++b@6U9+q`rSUtvhbs3i|@*aF!%O&&dZl%2y4=p z$$o}+x^Nrw(Co;>F~{OfA^5)GI6XNbo?+R|7Vmd08R_S^f%al(f%m#jMx!iCKqd@} zADA7M1kP}DK=o&WtcMJlS>}OKq*@mG(Zr|~8*MeM7H?TBP|h5?mW$#vOSEI7NKOtU z76^I&v_Gx!P&O`C<6Y4%!o=z~SWeJcgxl``!NSZ|L_WyfA#K|19XVg$!f0t%I@MdKC?nkR0+}>XuEC z=XYog+Or+Pw1zOPVN7d;#jv5`NC~6~q$G4HZ=%Ant=&d;2hFd4G;;qoz5Xf<~Yi^Z+|CORohn_=skwv1q3Lnc#0 z6Rt``=+L8*FjkO7k#W=6V+jI#wqbCS#XCa=mQCC2(1s70sEft0-`p)mXh552?2^5X zB`6~~FN0`L3WmaGcZp55&tJ@o(4JXLI&s~-F+q#dvbxT|HcD)&T179HGVaWBD^s11 zoSwWWN;oYXMgVI1WVk0F8#|79wEh^$q2tmWhfT6G{Uz62Msf~8M*9m#3L%A&B1loB z6V8Wyo`g&}pE3DpN(78)5yTBL1L>?MnNyN;aL)6P;CAqA)ExnrzAPee)hIT)x?8bm z&Jmq5c9KYnh+-#zs`FP)Pf1wpS;T7FHkDJURW1=1z>IrlFC>K%r?~oi?=h0Exq&YK|4G5Q!oEbbuofwNc zvT0KdFCH2T!=nsKAfKQoP16q=RWzn(T+xK06N)AkO@XGxWZN&Mz6juXa)`oWM(Jl2 zom2FjqURO8py)+KFDZH%^oqFZ)%21^FKcv7Tn7%QmR`})S2cP~qt`WhL!&n}`kqE_ zX*4gs@3s84mi<7y1MIeULrWJl$|#f-xi5lZaRe`Ei<=tV(&)BEcQm@I(YqS`P@{X| zs`!!DkN33neT|kiTG41#qr651jfxtTG`g?R8rpjY?YSdc*YXD%eV|cUql!jVjW#r@ zY4lK|O^xarH8k4N=tGURHTq~|ZFWX5(-uD-qILy0{!hfm;-~OX?&Ux8@}`&XdU?ys zg`2mdc#Qua%eEtUvM{`Q_Po69<@;W4ibtwHpLn_D7MUb zp~pFBvZ6mmQ#LLe$P3PA(Hn-~4t=g_v8ykvNM?}@eht;h@ zrCKtER>8_jeLjFgiXJ9gd(9S`CZp9+Bbi()Zm#4vDy!9eu_7l&xZ2XK%t^t`+c!@N z?&MBc+=W2bn5P;?xf+`t*3awf_bV%##RAWd6Rxs!VW)WK&aF*7n1}g-jJm=aO99-< z+#D*&_-W2;CGi+nAXhnO

SL)j&U%XXYl{1QG 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 Z+nar{-E;5ICi3as0#FS5W%~!3^&g(8Ronmo diff --git a/src/__pycache__/levmar.cpython-38.pyc b/src/__pycache__/levmar.cpython-38.pyc deleted file mode 100644 index f2ab8496a79b74575c207bd1a2e5d6cb934b2e35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8313 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 diff --git a/src/__pycache__/levmar.cpython-39.pyc b/src/__pycache__/levmar.cpython-39.pyc deleted file mode 100644 index 446a18692794a192f98252e53aa299a43b5c25e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8313 zcmbVROKc(Ur`iAiPW#8{;EeUvDGuvA4{$N%(TaLPh(=YGchv_nbM;qs;Q#% zSeof!UL`=(Fuce@FaiYdO1+CWHed{bAU}BFl^0nANt{#yBykqwMvNc{j9?&mk#k=a zDM~YH+o4dm-uJ%y?tOL7yI0k8I-%gV`1L!iOb7$NFjWav7BKnyA#NgM7%M+bn_bg^m`Dlbtg$aJDu!_o_r7AnucP@Fc1N*t6 zf-ClEKKvM)px7&Z09N4~*63_J@JqsJVg3 ztL}O&(A@37Xzg$>(5ox0z})6_*9){}D=>C;>)v!MFgI$gRy{DPYjrn>5znovSFxi4 zI#_*cBT(ysy7?W24?v8=g}Gg~{&ddUs5SYA^K%WXG`C*&me=Y}x2t^FtF^q=+!w3v z{I%7M+Uk?J7GIrf)ZX8!@>z(Nj99N$8>=SRwF)4LmQquit!31VIk#2b3Y#JiPk+z!4d3)FKjz!Qk_SP8mCvpci zOFUO$G%6*j246NQh!q5ffx}eDsMt zW@o`2@(y;mi9xxZ)5Fnu3C9V@n!}EYAurSh#2_1duAv^TCi#(*@F$^#f=JN`Kxs$} zMx|jf6qT~%h-7b3-;u2jfzP&CN)cEZ=}awlPB#Z z9MYMuV%E5Dh!b4Sfgp|N#01PSjmYTc-Je*{H768iDx%uX{CaVGbwv7U(UHlk2UnW0G5I1@<;u z3#Y_gaJ{+MJ*MUBzHp_#d!W6q&tRi zQ)sa9+{4rQ3BEW_VRT)gFJC!O=?jME#l;0!r=5az7{zpW9l|=4fpt_%0L_x}G7~>A zPhg!6tTTai7O*ZBVjZ*nEG{i^FSbcom%x*Z@DAt}d73zrSO%YxiSSN;d=_}8u)Z$d z#aRcf;>YkVnhOlcNW5E#@UCCt-3oYQBfN{V{^RR)G{ACRYB~Mu>cPv1xJZN^5V-mG zU2Yk#Z#nyGbEE4a@ZTSV#6SSzd#c{@oqZfb)JPM!ix8rcHZ(rZ24Smyri(&eVS~d8 zD?HbR6@N%taEJ{>=&CSa$O&{MYh+lai>~`XPK!=LbSmQDk;60KxP+6s>nw&a%js6khd}Dz#HIV=5MrM#t)m6MpDyuXym*mF3FHW1uR45$ zT1SbH3*-dUd;;Wt+uDQ^b{4rqO_Lxm2-DZUDt~{s#L4^cvqa7jIZxyQk&8s8iCiM` z3XwA)(OQxk6-~h{U<8CnexlM!+ zkl!J4mk2pt{sxgZiQFghc_IjE75)VxUnKG+A`ghXP2?d+#US z9ufH}k>4cpE|K3N@--sAO$4@%$fxk^>NE7U{tQIX5-&qEVA}~y1NKCiCeg_Xkq~GU zB3x7l@+GuhoEz@qT(GaEi13@x2=%BGMsR)n`z+(f zAW4${fb~JHEaXZd60&7nV?Umun1%Ht5%8}fEpk9%NGI}76#g@jmt}Z+{)x!=X)n!k zktaND{Q>ENus#rMIPyV9(j*WiJ_8qcHQW`b9lkv(h4L0jN2~xTO7K4@<7Pm$QLhiN z(`e|i_U)a+P-dXes2CIDh(Y7PWYoZYsLOr$ICt0y(UtFDOp(U0elNS+&r~nB44i=% zoIun;QTZ5Rv!XxgPhn(9a{HC#B27b%OSFz_5S6RSl}=q_M2tzyNCQho!W~ETF;S%b zQ%&wz1MiOnXzL@&|RKR+o>lejL1TZjh(cZJSj2O zAK|q5_!s_J=ww2qr9@;wr=w$7{Orm3(#D9~LK|a5`s4_yFCAyEXE(IWdZ;{5&*sK2K?|E-&Ezd3vZH zH;4=Sn)`_`_s!NHyi_8CbD{4WyaEkPdLvjxl}Wk<|02%mMRAc5asD(`8We+_x|pUL zQK!CuTLmASbEMmM75A2*c*V`Jee=UNRK=e~ zKfV_+OW%t(P8xv)Cg`^DuJSdcQT^H9oplr8yR4KIk=!@=BhQgu@tpXTEd+Vait{AT zzUn@Jtt|czCr-@KS(-c2f?t-l!da1)+VC$Pt3UFuz)n}5XprjX?3_psDPoRV*0cr1 zo$r)ovUO6FyEZM0D>SC4M9J3foPBfWZ}I#v(%KyKJP)m1kF;ie=tWwC&+2Mz4qC&g z&(ha1X&;=B{yLcf-Hwf6ia<7vZsQAWpai zju*rYF&5>IPQ#RoJ^tgyr~F5nO^2re+%Ab3k`JX<#CTMi5jUdJW%wubiffSUuQ5iR zRF|VPC&uA{k^MutOyyr9(Ul&F#!pHlecnsGDs*G>cf2X=9a16#C=twG5(e6zi6wCX zUi&ti7Z>2q?m(ui;zG2CSH&GF0a+~n4o2QVBxds;iL3G}N`>DWX1pd*i~RHJ9a*C| zIL)qwaSd+%KN4p}3@6^^{|uB$$d*3Teg@>YP6*=K@K6I(LQL=p#$WaCio1vhZalpI zD7^dsRLAZ77vK5szj=G*ozC4KEx0S;clP%Bpa12L|M6eMKP{db4O|JMffr{m{skjK z_evQYwCzs*O@;~WAqovBBi3?wt%}q=3lnhd;Zr&snGie*FWLiq*LCaey3FE5iLiDb z8haaL?9n!nUvd`PG8N=3(uSPn1MRMiJ=(D-FDL)&(T-72P{!bt{Er6$1BYtyFnfd) zoeX5!IT=AAMO5Q*7wBmBQ+UxVM|nj`=e1?TfhI}>h8z~#c33DcwqtSvxQB)EqKt#u zci*}5<$G_vdGAZk{X1WHaMRgECak*Bs6kQd^``4I*Bq=~Mb?QH->$CKuw<*|$$ev~ zE43T#jAT7SlmrRGDj8rs#_rp3B(+!#@gGEl36^EHu{|EjvmhB!e$=f!^&H9-Ry{1- zo_Kk`(@wgz4@fr3vPQ?ozKtBAP3EEYz(fMCu@wezF-Q`a?HX^kdIGD@2;q>RTxUo5 zN>0HXuM$}yvPxu`$k&O;xbP?>JPO{9LN=4e(Z73wwR|GJl-t7@ z;{7CJXQ^^UCRNL!5M`1kI_|s=;{ua%tvnp$RpbZhc|1ofq}X2Fm4Ryo|049tpB27V zEO`pC5I*W=Ipl%2xPlr6{=)i;ntd2EP_rsme_ik>MYMD4mq83}U17 zt!kN6vNc1ODP0XzGYrGZsW};xCJgjz7R^DD*H&$vlEHWo6nBDMD@^#x#4dtjgx9^{ zvaMS9qkl?L;urlETI4#GQ7{u~R?UD~vKRbSBNOq}Wf(5!gehQ36=xtzUMpY?1o7H= z&7wBLidjfYr_^ysJ&X|GXgjh4yGQZBW`90(s3+Y|S3F*X`d^wEqLHLXM#T diff --git a/src/__pycache__/lhapdf_funs.cpython-38.pyc b/src/__pycache__/lhapdf_funs.cpython-38.pyc deleted file mode 100644 index 35d4dcac551c6e2a5f4796b133dd81b2fb735213..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3843 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 P7IibbVE7 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 RyXLODU&jB}v<>`Q{{wZi!YBX$ diff --git a/src/__pycache__/msht_theory.cpython-39.pyc b/src/__pycache__/msht_theory.cpython-39.pyc deleted file mode 100644 index c0babd6269dfd1e1ae4ebb739d8e6d38ca0f0f3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15983 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 diff --git a/src/__pycache__/outputs.cpython-38.pyc b/src/__pycache__/outputs.cpython-38.pyc deleted file mode 100644 index dcc442c9c80aa1eb4eba5b21de3aba300cbffc7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9090 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 Wo6y@2xXf$)GuQRtqqLlN>Hh*C+VSxK diff --git a/src/chi2s.py b/src/chi2s.py index 8fc94fc..57110ff 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -146,8 +146,8 @@ def chi2min_fun(afree,jac_calc,hess_calc): pdf_pars.deld_arr[ip]=parin1[10] pdf_pars.delu_arr[ip]=parin1[1] - if(pdf_pars.uselha): + # TODO what about this chi2_pars.ipdf_newmin=ip initlha(name,pdf_pars.lhapdfdir) pdf_pars.PDFlabel=name @@ -175,7 +175,7 @@ def chi2min_fun(afree,jac_calc,hess_calc): pdf_pars.delu_arr[pdf_pars.npar_free+ip]=parin1[1] if(pdf_pars.uselha): - + # TODO what about this 2 initlha(name,pdf_pars.lhapdfdir) pdf_pars.PDFlabel=name writelha(name,pdf_pars.lhapdfdir,parin1) @@ -199,7 +199,6 @@ def chi2min_fun(afree,jac_calc,hess_calc): idir_j=pdf_pars.idir+ip name=inout_pars.label+'_run'+str(idir_j) # name=inout_pars.label+'_irep'+str(fit_pars.irep)+'_run'+str(idir_j) - dellha(name) pdf_pars.idir+=pdf_pars.npar_free+1 @@ -209,7 +208,6 @@ def chi2min_fun(afree,jac_calc,hess_calc): idir_j=pdf_pars.idir+ip name=inout_pars.label+'_run'+str(idir_j) # name=inout_pars.label+'_irep'+str(fit_pars.irep)+'_run'+str(idir_j) - dellha(name) pdf_pars.idir+=pdf_pars.npar_free @@ -226,16 +224,16 @@ def chi2min_fun(afree,jac_calc,hess_calc): # write to temp lhapdf grid to be used by nnpdf code if(pdf_pars.uselha): - initlha(name,pdf_pars.lhapdfdir) + # TODO: instead of writting a temporary LHAPDF grid, create a validphys interface + initlha(name, pdf_pars.tmp_lhapdfdir) pdf_pars.PDFlabel=name chi2_pars.ipdf_newmin=0 - writelha(name,pdf_pars.lhapdfdir,parin1) + writelha(name,pdf_pars.tmp_lhapdfdir,parin1) + # calculate chi2 chi=chi2totcalc() out=chi[0]+chi[1] # exp + positivity out0=chi[0] - if(pdf_pars.uselha): - dellha(name) # delete temporary folder pdf_pars.idir+=1 # iterate up so new folder print('chi2/N_dat=',out/chi2_pars.ndat) diff --git a/src/global_pars.py b/src/global_pars.py index 3e04ece..7d6be7a 100644 --- a/src/global_pars.py +++ b/src/global_pars.py @@ -112,6 +112,8 @@ class pdf_pars: PDFlabel_cent='init' # absolute path to LHAPDF directory where grids are stored lhapdfdir='init' + # path to the temporary LHAPDF files + tmp_lhapdfdir = None # Path # counter to ensure new lhapdf grid used for every new theory evaluation idir=0 # if true then use lhapdf grids for theory evaluation diff --git a/src/inputs.py b/src/inputs.py index 5654ffc..dedb175 100644 --- a/src/inputs.py +++ b/src/inputs.py @@ -1,5 +1,17 @@ from global_pars import * import numpy as np +from pathlib import Path + +OUTPUT_F = Path("outputs") +BUFFER_F = OUTPUT_F / "buffer" +PARS_F = OUTPUT_F / "pars" +EVGRIDS_F = OUTPUT_F / "evgrids" +PLOTS_F = OUTPUT_F / "plots" +RES_F = OUTPUT_F / "res" +PARS_F.mkdir(exist_ok=True, parents=True) +EVGRIDS_F.mkdir(exist_ok=True, parents=True) +PLOTS_F.mkdir(exist_ok=True, parents=True) +RES_F.mkdir(exist_ok=True, parents=True) @@ -181,8 +193,8 @@ def readin(): afin=np.delete(afin,0) pdf_pars.par_free_i=np.delete(pdf_pars.par_free_i,0) - - outputfile=open('outputs/buffer/'+inout_pars.label+'.dat','w') + BUFFER_F.mkdir(exist_ok = True, parents=True) + outputfile = (BUFFER_F / f"{inout_pars.label}.dat").open("w") outputfile.write("Starting new buffer...") outputfile.write("\n") diff --git a/src/lhapdf_funs.py b/src/lhapdf_funs.py index 1154f60..6f31ffb 100644 --- a/src/lhapdf_funs.py +++ b/src/lhapdf_funs.py @@ -1,3 +1,4 @@ +from pathlib import Path from global_pars import * from pdfs import * import lhapdf @@ -9,27 +10,19 @@ def initlha(name,lhdir): # dirin=pdf_pars.lhapdfdir+'NNPDF40_nnlo_pch_as_01180/'+'NNPDF40_nnlo_pch_as_01180.info' dirin='input/MSHT20nnlo_as118_mem1.info' - - dirlha=lhdir+name+'/' - - - try: - os.mkdir(dirlha) - except OSError as error: - print(error) + lhdir = Path(lhdir) + dirlha = lhdir / name + dirlha.mkdir(exist_ok = True, parents=True) - sh.copy(dirin,dirlha+name+'.info') + sh.copy(dirin, dirlha / f"{name}.info") def writelha(name,lhdir,parin): - output=lhdir+name+'/'+name+'_0000.dat' - - # print(pdf_pars.parinarr[0,:]) - # print(parin) + lhdir = Path(lhdir) + output = lhdir / name / f"{name}_0000.dat" - with open(output,'w') as outputfile: - + with output.open("w") as outputfile: outputfile.write('PdfType: replica') outputfile.write('\n') outputfile.write('Format: lhagrid1') @@ -38,7 +31,7 @@ def writelha(name,lhdir,parin): # PDFlabelmsht='MSHT20nnlo_as118' PDFlabelmsht='NNPDF40_nnlo_pch_as_01180' - inputf=pdf_pars.lhapdfdir+PDFlabelmsht+'/'+PDFlabelmsht+'_0000.dat' + inputf=Path(pdf_pars.lhapdfdir) / PDFlabelmsht / f"{PDFlabelmsht}_0000.dat" filein=open(inputf,"r") content=filein.readlines() @@ -265,7 +258,3 @@ def writelha_end(name,lhdir,parin): outputfile.write('\n') outputfile.write('---') - -def dellha(name): - dirlha=pdf_pars.lhapdfdir+name+'/' - sh.rmtree(dirlha) From 9809b0c7b85de95a7da8a97aeee4562cc956cb04 Mon Sep 17 00:00:00 2001 From: juacrumar Date: Mon, 3 Feb 2025 14:42:21 +0100 Subject: [PATCH 02/19] added a mhst class to avoid passing through lhapdf --- README | 8 +++++ src/chi2s.py | 87 ++++++++++++++++++++++++++++++++++------------ src/lhapdf_funs.py | 4 +++ src/pdfs.py | 61 ++++++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 22 deletions(-) diff --git a/README b/README index d779d3a..8f84b52 100644 --- a/README +++ b/README @@ -6,6 +6,14 @@ Requires NNPDF code from https://docs.nnpdf.science either from source or conda conda install nnpdf -c https://packages.nnpdf.science/conda -c conda-forge ``` +> [!IMPORTANT] +> To run with this branch, it is necessary to install the specific ``api_extended_feb25`` branch [PR](https://github.com/NNPDF/nnpdf/pull/2268) + +```bash +python -m pip install git+https://github.com/NNPDF/nnpdf.git@api_extended_feb25 --no-deps # no-deps to avoid overwriting dependencies by conda +``` + + To run simply execute: python fixpar_nnpdf.py --config=configs/**.yaml diff --git a/src/chi2s.py b/src/chi2s.py index 57110ff..5bae705 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -4,6 +4,10 @@ from data_theory import * from validphys.calcutils import calc_chi2 from validphys.covmats import dataset_inputs_t0_covmat_from_systematics, dataset_inputs_covmat_from_systematics + +from validphys.api import API +from validphys.convolution import central_predictions + from pdfs import * from inputs import * from lhapdf_funs import * @@ -227,11 +231,15 @@ def chi2min_fun(afree,jac_calc,hess_calc): # TODO: instead of writting a temporary LHAPDF grid, create a validphys interface initlha(name, pdf_pars.tmp_lhapdfdir) pdf_pars.PDFlabel=name + writelha(name,pdf_pars.tmp_lhapdfdir,parin1) chi2_pars.ipdf_newmin=0 - writelha(name,pdf_pars.tmp_lhapdfdir,parin1) + vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = "msht") + pdf_pars.vp_pdf = vp_pdf - # calculate chi2 - chi=chi2totcalc() + + # TODO calculate chi2 + print("> Calculating chi2 <") + chi=chi2totcalc(vp_pdf=vp_pdf) out=chi[0]+chi[1] # exp + positivity out0=chi[0] pdf_pars.idir+=1 # iterate up so new folder @@ -257,13 +265,14 @@ def chi2min_fun(afree,jac_calc,hess_calc): return(out,jac,hess,err,hessp) -def chi2corr(imin,imax): - +def chi2corr(imin, imax, vp_pdf=None): + # TODO: add docstr + """ """ if(pdf_closure.pdpdf): (out,theorytot,cov,covin)=chi2corr_pdf() diffs_out=0. else: - (out,theorytot,cov,covin,diffs_out)=chi2corr_global(imin,imax) + (out,theorytot,cov,covin,diffs_out)=chi2corr_global(imin, imax, vp_pdf) return (out,theorytot,cov,covin,diffs_out) @@ -658,8 +667,11 @@ def chi2corr_ind(i): return (out,ndat,dlabel) -def chi2corr_global(imin,imax): - +def chi2corr_global(imin, imax, vp_pdf=None): + """Compute chi2 for the global dataset. + Takes from index 0 of the dataset all the way to index imax + as defined in ``global_pars.fit_pars.dataset_40``. + """ if fit_pars.nlo_cuts: # intersection=[{"dataset_inputs": dload_pars.dscomb, "theoryid": 212}] @@ -727,15 +739,23 @@ def chi2corr_global(imin,imax): # outputfile_label=open('outputs/pseudodata/datalabels.dat','w') + # TODO: in principle this entire loop could be replaced by a direct call to calc_chi2 with the following input + # 1. covmat -> needs information on t0 (on/off), datasets, cuts + # 2. data -> needs datasets, cuts, replica seed (if needed) + # 3. theory results -> data, cuts, theory + # if the replicas were prepared beforehand that would speed up things though + + vp_input = {"use_cuts": "internal", "theoryid": fit_pars.theoryidi} + if vp_pdf is not None: + vp_input["pdf"] = vp_pdf + all_ds_input = [] + for i in range(imin,imax+1): dataset_testii=fit_pars.dataset_40[i] - - # print(fit_pars.dataset_40[i]) - inptt = { - "dataset_input": dataset_testii, - "use_cuts": "internal", - "theoryid": fit_pars.theoryidi, - } + + inptt = {**vp_input, "dataset_input": dataset_testii} + all_ds_input.append(dataset_testii) + # if fit_pars.nlo_cuts: # # inptt = { # # "cuts_intersection_spec": [{"theoryid": 212, "theoryid": 211}], @@ -757,8 +777,13 @@ def chi2corr_global(imin,imax): # "use_cuts": "internal", # "theoryid": fit_pars.theoryidi, # } - - theory=theory_calc(i,dataset_testii,inptt,fit_pars.cftrue[i]) + + if vp_pdf is not None: + # NB: checked that it produce the same values as the line below + theory = API.central_predictions(**inptt).values[:,0] + else: + theory=theory_calc(i,dataset_testii,inptt,fit_pars.cftrue[i]) + fit_pars.preds_stored[str(dataset_testii["dataset"])]=theory # for j in range (0,len(theory)): @@ -825,8 +850,22 @@ def chi2corr_global(imin,imax): # print(len(theorytot)) # exit() + if vp_pdf is not None: + # Get the covmat for all the dataset we have calculated chi2 for. The order is the same as the vector of theories + # TODO: eventually we'll try to skip it and compute the chi2 directly + # TODO: in principle nlo intersenction cut should already be part of vp_input at this stage + cov = API.dataset_inputs_covmat_t0_considered(**vp_input, dataset_inputs = all_ds_input, use_t0=chi2_pars.t0, t0pdfset=vp_pdf) + covin = la.inv(cov) + + if chi2_pars.t0: + dload_pars.covt0=cov + dload_pars.covt0_inv=covin + dload_pars.dcov=0 + else: + dload_pars.covexp=cov + dload_pars.covexp_inv=covin - if(chi2_pars.t0): + elif(chi2_pars.t0): print('t0 cov1...') if fit_pars.nlo_cuts: inpt0 = dict(dataset_inputs=dload_pars.dscomb, theoryid=fit_pars.theoryidi, use_cuts="fromintersection", cuts_intersection_spec=intersection, t0pdfset=pdf_pars.PDFlabel, use_t0=True) @@ -1014,6 +1053,8 @@ def chi2corr_global(imin,imax): else: dattot=dload_pars.darr_gl + import ipdb; ipdb.set_trace() + chi2_pars.ndat=len(dattot) diffs=dattot-theorytot @@ -1244,11 +1285,13 @@ def chilim_fill(nd,chi,dlab): chi2_pars.chi0_ind_arr.append(chi) # print(i,chilim/chi,cl68,cl50,cl68/cl50,nd) -def chi2totcalc(): +def chi2totcalc(vp_pdf=None): + """If a VP pdf is used, use VP to compute the chi2""" - - chiarr=np.zeros(fit_pars.imaxdat-fit_pars.imindat) - chiarr[0]=chi2corr(fit_pars.imindat,fit_pars.imaxdat-1)[0] + # Prepare an array to save the chi2 for each dataset + chiarr = np.zeros(fit_pars.imaxdat - fit_pars.imindat) + + chiarr[0] = chi2corr(fit_pars.imindat, fit_pars.imaxdat - 1, vp_pdf=vp_pdf)[0] ndtot=0 chi2totind=0. diff --git a/src/lhapdf_funs.py b/src/lhapdf_funs.py index 6f31ffb..59facf1 100644 --- a/src/lhapdf_funs.py +++ b/src/lhapdf_funs.py @@ -5,6 +5,10 @@ import os import shutil as sh + + + + def initlha(name,lhdir): diff --git a/src/pdfs.py b/src/pdfs.py index 6aed497..6e36a33 100644 --- a/src/pdfs.py +++ b/src/pdfs.py @@ -5,6 +5,67 @@ from scipy.integrate import quadrature from scipy.misc import derivative as deriv +from validphys.core import PDF +from validphys.lhapdfset import LHAPDFSet + + +class MSHTSet(LHAPDFSet): + """Provides a few lhapdf-like functions to trick vp into thinking it is an LHAPDFset + Can work with any function with a signature of (flavour, parameters, x) + """ + + def __init__(self, pdf_function, parameters, name): + self._error_type = "replicas" + self._name = name + self._flavors = None + self._lhapdf_set = [None] + + self._parameters = parameters + self._pdf_function = pdf_function + + def xfxQ(self, x, Q, n, fl): + """Return the PDF value for one single point for one single member + Note that in this case both scale (Q) and member (n) are ignored. + """ + return self._pdf_function(fl, self._parameters, x) + + def grid_values(self, flavors: np.ndarray, xgrid: np.ndarray, qgrid: np.ndarray): + """Returns the PDF values for every member for the required flavors, x, q + + For the time being assume there is only one Q and only one member + Return shape: (members, flavours, xgrid, qgrid) + """ + out_ret = [] + for fl in flavors: + tmp = [] + for x in xgrid: + tmp.append(self.xfxQ(x, None, None, fl)) + out_ret.append(tmp) + return np.array(out_ret).reshape(len(flavors), 1, -1, 1) + + +class MSHTPDF(PDF): + """ + Creates a MSHT PDF object, extends validphys' PDF object + to utilize a MSHT set in the background instead of lhapdf / pdfflow + """ + + def __init__( + self, + name="msht", + boundary=None, + pdf_function="msht", + pdf_parameters=None, + Q=1.0, + ): + if isinstance(pdf_function, str): + if pdf_function == "msht": + pdf_function = pdfs_msht + + self._lhapdf_set = MSHTSet(pdf_function, pdf_parameters, name) + super().__init__(name, None) + + def func_pdfs_diff(eps,ipdf,x,iorder): # print(eps) From d7bd1aa1c596afe0f6cb9d0f86e68a51a7e8ba01 Mon Sep 17 00:00:00 2001 From: juacrumar Date: Tue, 4 Feb 2025 13:51:50 +0100 Subject: [PATCH 03/19] remove set_trace --- README | 4 ++-- src/chi2s.py | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README b/README index 8f84b52..55cbd19 100644 --- a/README +++ b/README @@ -7,10 +7,10 @@ Requires NNPDF code from https://docs.nnpdf.science either from source or conda ``` > [!IMPORTANT] -> To run with this branch, it is necessary to install the specific ``api_extended_feb25`` branch [PR](https://github.com/NNPDF/nnpdf/pull/2268) +> To run with this branch, it is necessary to install the latest NNPDF as the possibility of using the custom PDF class was introduce here [PR](https://github.com/NNPDF/nnpdf/pull/2268) ```bash -python -m pip install git+https://github.com/NNPDF/nnpdf.git@api_extended_feb25 --no-deps # no-deps to avoid overwriting dependencies by conda +python -m pip install git+https://github.com/NNPDF/nnpdf.git --no-deps # no-deps to avoid overwriting dependencies by conda ``` diff --git a/src/chi2s.py b/src/chi2s.py index 5bae705..8d63c20 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -1053,8 +1053,6 @@ def chi2corr_global(imin, imax, vp_pdf=None): else: dattot=dload_pars.darr_gl - import ipdb; ipdb.set_trace() - chi2_pars.ndat=len(dattot) diffs=dattot-theorytot From a268b3999c40b7a836a37cfb119d0464a097a9d3 Mon Sep 17 00:00:00 2001 From: juacrumar Date: Tue, 4 Feb 2025 18:25:29 +0100 Subject: [PATCH 04/19] reportengine.compat -> reportengine.utils --- README | 8 -------- fixpar_nnpdf.py | 4 ++-- src/outputs.py | 4 ++-- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/README b/README index 55cbd19..d779d3a 100644 --- a/README +++ b/README @@ -6,14 +6,6 @@ Requires NNPDF code from https://docs.nnpdf.science either from source or conda conda install nnpdf -c https://packages.nnpdf.science/conda -c conda-forge ``` -> [!IMPORTANT] -> To run with this branch, it is necessary to install the latest NNPDF as the possibility of using the custom PDF class was introduce here [PR](https://github.com/NNPDF/nnpdf/pull/2268) - -```bash -python -m pip install git+https://github.com/NNPDF/nnpdf.git --no-deps # no-deps to avoid overwriting dependencies by conda -``` - - To run simply execute: python fixpar_nnpdf.py --config=configs/**.yaml diff --git a/fixpar_nnpdf.py b/fixpar_nnpdf.py index 47e64bc..5d7e3fe 100644 --- a/fixpar_nnpdf.py +++ b/fixpar_nnpdf.py @@ -24,7 +24,7 @@ from scipy.optimize import minimize from scipy.optimize import least_squares import itertools as IT -from reportengine.compat import yaml +from reportengine.utils import yaml_safe import time import sys import argparse @@ -61,7 +61,7 @@ # Loading yaml config ################## with open(args.config, 'r') as file: - config = yaml.safe_load(file) + config = yaml_safe.load(file) inp = config.get("inputs", None) inout_pars.inputnam=inp.get("input file") diff --git a/src/outputs.py b/src/outputs.py index 393b8d9..d1597cf 100644 --- a/src/outputs.py +++ b/src/outputs.py @@ -2,7 +2,7 @@ from pdfs import * import numpy as np import os -from reportengine.compat import yaml +from reportengine.utils import yaml_safe from lhapdf_funs import * def covmatout(hessi,jaci): @@ -173,7 +173,7 @@ def evgrido(): with open(output,'w') as outputfile: - yaml.dump(data, outputfile) + yaml_safe.dump(data, outputfile) def resout_nofit(pospeni,chi2t0i,chi2expi,n): outputfile=open('outputs/res/'+inout_pars.label+'.dat','w') From fce87be6c2cbe813ce2e2f66521d6815031d5d93 Mon Sep 17 00:00:00 2001 From: juacrumar Date: Tue, 4 Feb 2025 20:18:52 +0100 Subject: [PATCH 05/19] dont write temporary pdfs to file --- fixpar_nnpdf.py | 10 +++++----- src/chi2s.py | 16 +++++++--------- src/data_theory.py | 10 ++++++---- src/lhapdf_funs.py | 3 --- src/pdfs.py | 18 +++++++++++++++--- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/fixpar_nnpdf.py b/fixpar_nnpdf.py index 5d7e3fe..c55818a 100644 --- a/fixpar_nnpdf.py +++ b/fixpar_nnpdf.py @@ -34,10 +34,10 @@ lhapdf.setVerbosity(0) -# Fake LHAPDF folder -TEMP_LHAPDF = pathlib.Path("tmp_lhapdf") -TEMP_LHAPDF.mkdir(exist_ok=True) -lhapdf.pathsAppend(TEMP_LHAPDF.as_posix()) +# # Fake LHAPDF folder, no longer needed +# TEMP_LHAPDF = pathlib.Path("tmp_lhapdf") +# TEMP_LHAPDF.mkdir(exist_ok=True) +# lhapdf.pathsAppend(TEMP_LHAPDF.as_posix()) sys.path.append("src/") @@ -256,7 +256,7 @@ fit_pars.imaxdat=len(fit_pars.dataset_40) pdf_pars.lhapdfdir = get_lha_datapath() + "/" -pdf_pars.tmp_lhapdfdir = TEMP_LHAPDF +# pdf_pars.tmp_lhapdfdir = TEMP_LHAPDF profile=_get_nnpdf_profile(None) fit_pars.datapath=pathlib.Path(profile["data_path"]) # fit_pars.theories_path=pathlib.Path(profile["theories_path"]) diff --git a/src/chi2s.py b/src/chi2s.py index 8d63c20..9234490 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -229,13 +229,12 @@ def chi2min_fun(afree,jac_calc,hess_calc): # write to temp lhapdf grid to be used by nnpdf code if(pdf_pars.uselha): # TODO: instead of writting a temporary LHAPDF grid, create a validphys interface - initlha(name, pdf_pars.tmp_lhapdfdir) - pdf_pars.PDFlabel=name - writelha(name,pdf_pars.tmp_lhapdfdir,parin1) + # in principle this is no longer necessary +# initlha(name, pdf_pars.tmp_lhapdfdir) +# pdf_pars.PDFlabel=name +# writelha(name,pdf_pars.tmp_lhapdfdir,parin1) chi2_pars.ipdf_newmin=0 vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = "msht") - pdf_pars.vp_pdf = vp_pdf - # TODO calculate chi2 print("> Calculating chi2 <") @@ -1198,8 +1197,6 @@ def jac_fun(afree): return out def chi2min(afree): - - hess_calc=False jac_calc=False outarr=chi2min_fun(afree,jac_calc,hess_calc) @@ -1406,9 +1403,10 @@ def chi2totcalc(vp_pdf=None): out1=0. if fit_pars.pos_const: - out31=pos_calc(fit_pars.pos_data31) + + out31=pos_calc(fit_pars.pos_data31, vp_pdf=vp_pdf) if(fit_pars.pos_40): - out40=pos_calc(fit_pars.pos_data40) + out40=pos_calc(fit_pars.pos_data40, vp_pdf=vp_pdf) chi2pos=out31+out40 out1=chi2pos else: diff --git a/src/data_theory.py b/src/data_theory.py index f5465e7..f520f93 100644 --- a/src/data_theory.py +++ b/src/data_theory.py @@ -73,18 +73,20 @@ def del_pen_calc(): return (chi0d,chi0u,diffd,diffu,hessd,hessu,idv,iuv) -def pos_calc(pdata): +def pos_calc(pdata, vp_pdf=None): tot=0. totdiff=0. + if vp_pdf is None: + vp_pdf = pdf_pars.PDFlabel for j in range(0,len(pdata)): if fit_pars.theoryidi==40001000 or fit_pars.theoryidi==50001000: - api_predictions = API.positivity_predictions_data_result(theoryid=fit_pars.theoryidi, pdf=pdf_pars.PDFlabel, posdataset=pdata[j],use_cuts="internal") + api_predictions = API.positivity_predictions_data_result(theoryid=fit_pars.theoryidi, pdf=vp_pdf, posdataset=pdata[j],use_cuts="internal") else: - api_predictions = API.positivity_predictions_data_result(theoryid=fit_pars.theoryidi, pdf=pdf_pars.PDFlabel, posdataset=pdata[j]) + api_predictions = API.positivity_predictions_data_result(theoryid=fit_pars.theoryidi, pdf=vp_pdf, posdataset=pdata[j]) out=api_predictions.central_value # print(pdata[j]) @@ -667,4 +669,4 @@ def plot_data_x(idat,ds,pred): # outputfile.writelines(L) # outputfile.write('\n') - \ No newline at end of file + diff --git a/src/lhapdf_funs.py b/src/lhapdf_funs.py index 59facf1..652f4dd 100644 --- a/src/lhapdf_funs.py +++ b/src/lhapdf_funs.py @@ -6,9 +6,6 @@ import shutil as sh - - - def initlha(name,lhdir): diff --git a/src/pdfs.py b/src/pdfs.py index 6e36a33..be2a243 100644 --- a/src/pdfs.py +++ b/src/pdfs.py @@ -1,5 +1,6 @@ from global_pars import * from chebyshevs import * +from copy import deepcopy import numpy as np import os from scipy.integrate import quadrature @@ -14,8 +15,8 @@ class MSHTSet(LHAPDFSet): Can work with any function with a signature of (flavour, parameters, x) """ - def __init__(self, pdf_function, parameters, name): - self._error_type = "replicas" + def __init__(self, pdf_function, parameters, name, error_type="replicas"): + self._error_type = error_type self._name = name self._flavors = None self._lhapdf_set = [None] @@ -41,7 +42,7 @@ def grid_values(self, flavors: np.ndarray, xgrid: np.ndarray, qgrid: np.ndarray) for x in xgrid: tmp.append(self.xfxQ(x, None, None, fl)) out_ret.append(tmp) - return np.array(out_ret).reshape(len(flavors), 1, -1, 1) + return np.array(out_ret).reshape(1, len(flavors), -1, 1) class MSHTPDF(PDF): @@ -65,6 +66,17 @@ def __init__( self._lhapdf_set = MSHTSet(pdf_function, pdf_parameters, name) super().__init__(name, None) + # Create some fake info: + self._info = {"NumMembers": 1} + + def load(self): + return self._lhapdf_set + + def load_t0(self): + t0_version = deepcopy(self._lhapdf_set) + t0_version._error_type = "t0" + return t0_version + def func_pdfs_diff(eps,ipdf,x,iorder): From 450fe2bbcf6f60624da18b0310029309b453d86c Mon Sep 17 00:00:00 2001 From: juacrumar Date: Mon, 10 Feb 2025 13:45:41 +0100 Subject: [PATCH 06/19] use lhapdf or internal class according to lhin --- fixpar_nnpdf.py | 16 +++++++++------- src/chi2s.py | 20 ++++++++++++++------ src/global_pars.py | 2 ++ src/lhapdf_funs.py | 2 +- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/fixpar_nnpdf.py b/fixpar_nnpdf.py index c55818a..27e216b 100644 --- a/fixpar_nnpdf.py +++ b/fixpar_nnpdf.py @@ -33,12 +33,6 @@ from validphys.lhaindex import get_lha_datapath lhapdf.setVerbosity(0) - -# # Fake LHAPDF folder, no longer needed -# TEMP_LHAPDF = pathlib.Path("tmp_lhapdf") -# TEMP_LHAPDF.mkdir(exist_ok=True) -# lhapdf.pathsAppend(TEMP_LHAPDF.as_posix()) - sys.path.append("src/") from global_pars import * @@ -52,6 +46,13 @@ from lhapdf_funs import * from error_calc import * +if DEBUG: +# # Fake LHAPDF folder, no longer needed + TEMP_LHAPDF = pathlib.Path("tmp_lhapdf") + TEMP_LHAPDF.mkdir(exist_ok=True) + lhapdf.pathsAppend(TEMP_LHAPDF.as_posix()) + + parser = argparse.ArgumentParser() parser.add_argument("--config", required=True, type=str, help="Path to the config file") @@ -256,7 +257,8 @@ fit_pars.imaxdat=len(fit_pars.dataset_40) pdf_pars.lhapdfdir = get_lha_datapath() + "/" -# pdf_pars.tmp_lhapdfdir = TEMP_LHAPDF +if DEBUG: + pdf_pars.tmp_lhapdfdir = TEMP_LHAPDF profile=_get_nnpdf_profile(None) fit_pars.datapath=pathlib.Path(profile["data_path"]) # fit_pars.theories_path=pathlib.Path(profile["theories_path"]) diff --git a/src/chi2s.py b/src/chi2s.py index 9234490..67583a4 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -228,13 +228,21 @@ def chi2min_fun(afree,jac_calc,hess_calc): # write to temp lhapdf grid to be used by nnpdf code if(pdf_pars.uselha): - # TODO: instead of writting a temporary LHAPDF grid, create a validphys interface - # in principle this is no longer necessary -# initlha(name, pdf_pars.tmp_lhapdfdir) -# pdf_pars.PDFlabel=name -# writelha(name,pdf_pars.tmp_lhapdfdir,parin1) + if DEBUG: + initlha(name, pdf_pars.tmp_lhapdfdir) + pdf_pars.PDFlabel=name + writelha(name,pdf_pars.tmp_lhapdfdir,parin1) + chi2_pars.ipdf_newmin=0 - vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = "msht") + + if pdf_pars.lhin: + # If using directly an LHAPDF input, load said PDF + vp_pdf = API.pdf(pdf = pdf_pars.PDFlabel_lhin) + else: + # TODO: the pdf_function I guess should depend on something? + vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = "msht") + + pdf_pars.vp_pdf = vp_pdf # TODO calculate chi2 print("> Calculating chi2 <") diff --git a/src/global_pars.py b/src/global_pars.py index 7d6be7a..52549b8 100644 --- a/src/global_pars.py +++ b/src/global_pars.py @@ -1,6 +1,8 @@ import numpy as np from validphys.loader import Loader +DEBUG = False + class load_nnpdf: l=Loader() diff --git a/src/lhapdf_funs.py b/src/lhapdf_funs.py index 652f4dd..6971c9e 100644 --- a/src/lhapdf_funs.py +++ b/src/lhapdf_funs.py @@ -19,6 +19,7 @@ def initlha(name,lhdir): sh.copy(dirin, dirlha / f"{name}.info") def writelha(name,lhdir,parin): + print(f"Writing {name}") lhdir = Path(lhdir) output = lhdir / name / f"{name}_0000.dat" @@ -107,7 +108,6 @@ def writelha(name,lhdir,parin): # os.quit() for ix in range(0,nx): - for iq in range(0,2): xin=xarr[ix] From f7aa810be3a8268637e93595b66977f134636236 Mon Sep 17 00:00:00 2001 From: juacrumar Date: Mon, 10 Feb 2025 19:22:01 +0100 Subject: [PATCH 07/19] remove writelha from a bunch of places ; global_pars.py::DEBUG = True still needed to finish the fit ; added the fit example runcards by Lucian --- configs/fit_example.yaml | 68 ++++++++++++++++++++++++++++++++ input/inputdef_2parfree.dat | 77 +++++++++++++++++++++++++++++++++++++ src/chi2s.py | 36 ++++++++++++----- src/inputs.py | 16 +------- src/lhapdf_funs.py | 3 +- src/outputs.py | 51 ++++++++++-------------- src/pdfs.py | 25 +++++++++--- 7 files changed, 214 insertions(+), 62 deletions(-) create mode 100644 configs/fit_example.yaml create mode 100644 input/inputdef_2parfree.dat diff --git a/configs/fit_example.yaml b/configs/fit_example.yaml new file mode 100644 index 0000000..5f278a0 --- /dev/null +++ b/configs/fit_example.yaml @@ -0,0 +1,68 @@ +# input files +inputs: + # PDF parameter inputs: + input file: inputdef_2parfree.dat + # input covariance matrix file (if used) + cov input file: newmin_final_remin_out.dat + # if true then read in covariance matrix and evaluate PDF errors + readcov: False + +# output files +outputs: + # label for output files + label: fitout_jcm + +basis pars: + # If true then two term gluon parameterisation uesd + g_second_term: True + # if true and g_second_term=False then includes 7th Chebyshev for gluon + g_cheb7: False + # If true then delta_S+ set to that of sea + asp_fix: True + # If true thedelta_d=delta_u for d_V and u_V (need to set delta_d fixed or will crash!) + dvd_eq_uvd: False + +pdf pars: + # use external LHAPDF grid as input + lhin: False + # if true then use lhapdf grids for theory evaluation + # (for PDF pd fits can use parameterisation directly instead, otherwise has to be true) + uselha: True + # if lhin=true, name of set input + PDFlabel_lhin: NNPDF40_nnlo_pch_as_01180 + +pdf closure: + # if true then scatters when doing direct PDF pd fit + pdfscat: False + # label of pseudodata used + pdlabel: 'NNPDF40pch_gl_l0' + # if true then do direct fit to PDF pseudodata + pdpdf: False + +pseudodata flags: + # if true then write pseudodata out to file + pdout: False + # if true then write pseudodata out to file + pdin: False + +fit pars: + # Only use t0 for chi2i and chi2o in levmar (i.e. no derivative at all) + t0_noderivin: True + # run with fixed input parameters (override input card flags) + fixpar: False + # NNPDF theory id (211 = NNLO pch) + theoryidi: 40001000 + # impose NNPDF positivity in fit + nnpdf_pos: False + # if true then impose 4.0 positivity constraint, if pos_const=True + pos_40: True + # if true impose weight to prefer delta_d > 0.25 + deld_const: False + # if true then generates a replica from baseline dataset with seed irep + pseud: False + # irep number - also used when generating error grids + irep: 0 + # NMC PD data - set covariance matrix to be diagonal + nmcpd_diag: False + # dataset flag - global, HERAonly, noHERA, noLHC + dset_type: 'global_new' \ No newline at end of file diff --git a/input/inputdef_2parfree.dat b/input/inputdef_2parfree.dat new file mode 100644 index 0000000..4f52fb4 --- /dev/null +++ b/input/inputdef_2parfree.dat @@ -0,0 +1,77 @@ +uv parameters (delu,etau,cu1-6) +0.17122373884608855 1 +3.2743726678269165 1 +-1.2122918898379094 0 +0.1517819079177516 0 +0.12285498035990065 0 +-0.010122247519152774 0 +-0.014270897304430395 0 +0.03262297673072622 0 +dv parameters (deld,etad,cd1-6) +0.13865892320621695 0 +2.3352051735263344 0 +-0.44034691419255034 0 +-0.7939290540562433 0 +0.04328245533312397 0 +0.903822027741519 0 +-0.40085984152229265 0 +0.33023220117596597 0 +sea parameters (AS,delS,etaS,cS1-6) +8.262723047435793 0 +-0.06750937068295088 0 +5.189572313265036 0 +-1.624315151833448 0 +1.3080917021760117 0 +-0.8792934176979688 0 +0.4786052188746685 0 +-0.17873098728686534 0 +0.041566782615336216 0 +s+ parameters (Asp,delsp,etasp,csp1-6) +6.3684990056840105 0 +-0.06815580231450868 0 +5.695241421086358 0 +-1.7316660809876203 0 +1.385230907196718 0 +-0.8683490279392682 0 +0.471977126805542 0 +-0.1727444537147735 0 +0.04482507708725548 0 +Gluon parameters (etagp,delgp,cg1-4,etagm,delgm) +6.814826793215428 0 +0.440844331381777 0 +-1.650826229386586 0 +0.881190652182608 0 +-0.5084408693656719 0 +0.03265726584557637 0 +-1370.7158962827482 0 +1209.670571783354 0 +0.8728597655753609 0 +s- parameters (Asm,delsm,etasm, cs1-4) +-0.003245394946185798 0 +0.022384494068275074 0 +6.526146784622549 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +db/ub parameters (Arho,etarho,crho1-6) +1.2857208900336687 0 +1.0071680503069815 0 +0.0971452909922652 0 +-1.1783327161950718 0 +0.8044045111588943 0 +-0.506706557884737 0 +0.2164830132196875 0 +-0.04654818746580779 0 +charm parameters (Ac,etac,cc1-6) +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 diff --git a/src/chi2s.py b/src/chi2s.py index 67583a4..d6adf8b 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -79,6 +79,7 @@ def chi2min_fun(afree,jac_calc,hess_calc): err=False + vp_pdf = None parin=initpars() @@ -153,10 +154,19 @@ def chi2min_fun(afree,jac_calc,hess_calc): if(pdf_pars.uselha): # TODO what about this chi2_pars.ipdf_newmin=ip - initlha(name,pdf_pars.lhapdfdir) + if DEBUG: + initlha(name,pdf_pars.lhapdfdir) + writelha(name,pdf_pars.lhapdfdir,parin1) + + if fit_pars.newmin and chi2_pars.ipdf_newmin > 0: + pdf_function = "diff" + else: + pdf_function = "msht" + + vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = pdf_function) + pdf_pars.PDFlabel=name pdf_pars.parin_newmin_reset=True - writelha(name,pdf_pars.lhapdfdir,parin1) if chi2_pars.diff_2 or fit_pars.pos_const: @@ -182,9 +192,11 @@ def chi2min_fun(afree,jac_calc,hess_calc): # TODO what about this 2 initlha(name,pdf_pars.lhapdfdir) pdf_pars.PDFlabel=name + print("Here 2") writelha(name,pdf_pars.lhapdfdir,parin1) - if chi2_pars.diff_2: + if chi2_pars.diff_2: + # TODO: vp_pdf should go through here as well (out0,out1,jac,hessd2)=jaccalc_d2(pdflabel_arr,pdflabel_marr,eps_arr,hess_calc,fit_pars.imindat,fit_pars.imaxdat) out=out0+out1 hess=hessd2.copy() @@ -192,9 +204,9 @@ def chi2min_fun(afree,jac_calc,hess_calc): else: print('JACCALC') if fit_pars.newmin: - (jac,hess,out0,out1,hessp)=jaccalc_newmin(pdflabel_arr,pdflabel_marr,eps_arr,hess_calc) + (jac,hess,out0,out1,hessp)=jaccalc_newmin(pdflabel_arr,pdflabel_marr,eps_arr,hess_calc, vp_pdf=vp_pdf) else: - (jac,hess,out0,out1,hessp)=jaccalc(pdflabel_arr,pdflabel_marr,eps_arr,hess_calc) + (jac,hess,out0,out1,hessp)=jaccalc(pdflabel_arr,pdflabel_marr,eps_arr,hess_calc, vp_pdf=vp_pdf) out=out0+out1 @@ -239,8 +251,12 @@ def chi2min_fun(afree,jac_calc,hess_calc): # If using directly an LHAPDF input, load said PDF vp_pdf = API.pdf(pdf = pdf_pars.PDFlabel_lhin) else: - # TODO: the pdf_function I guess should depend on something? - vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = "msht") + # TODO only these two options? Does it make sense to have this if here? + if fit_pars.newmin and chi2_pars.ipdf_newmin > 0: + pdf_function = "diff" + else: + pdf_function = "msht" + vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = pdf_function) pdf_pars.vp_pdf = vp_pdf @@ -1860,7 +1876,7 @@ def jaccalc_d0(label_arr,eps_arr,il,ih): return jacarr -def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc): +def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): print('JACCALC NEWMIN') @@ -1983,9 +1999,11 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc): return(jacarr,hessarr,out0,out1,hessparr) -def jaccalc(label_arr,label_arrm,eps_arr,hess_calc): +def jaccalc(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): + # TODO print('JACCALC OLDMIN') + import ipdb; ipdb.set_trace() imax=fit_pars.imaxdat diff --git a/src/inputs.py b/src/inputs.py index dedb175..81eca55 100644 --- a/src/inputs.py +++ b/src/inputs.py @@ -1,19 +1,6 @@ from global_pars import * import numpy as np -from pathlib import Path - -OUTPUT_F = Path("outputs") -BUFFER_F = OUTPUT_F / "buffer" -PARS_F = OUTPUT_F / "pars" -EVGRIDS_F = OUTPUT_F / "evgrids" -PLOTS_F = OUTPUT_F / "plots" -RES_F = OUTPUT_F / "res" -PARS_F.mkdir(exist_ok=True, parents=True) -EVGRIDS_F.mkdir(exist_ok=True, parents=True) -PLOTS_F.mkdir(exist_ok=True, parents=True) -RES_F.mkdir(exist_ok=True, parents=True) - - +from outputs import BUFFER_F def readincov(): @@ -193,7 +180,6 @@ def readin(): afin=np.delete(afin,0) pdf_pars.par_free_i=np.delete(pdf_pars.par_free_i,0) - BUFFER_F.mkdir(exist_ok = True, parents=True) outputfile = (BUFFER_F / f"{inout_pars.label}.dat").open("w") outputfile.write("Starting new buffer...") outputfile.write("\n") diff --git a/src/lhapdf_funs.py b/src/lhapdf_funs.py index 6971c9e..3fedeae 100644 --- a/src/lhapdf_funs.py +++ b/src/lhapdf_funs.py @@ -20,6 +20,7 @@ def initlha(name,lhdir): def writelha(name,lhdir,parin): print(f"Writing {name}") + # import ipdb; ipdb.set_trace() lhdir = Path(lhdir) output = lhdir / name / f"{name}_0000.dat" @@ -43,8 +44,6 @@ def writelha(name,lhdir,parin): # xarr=np.loadtxt(inputf,skiprows=4,max_rows=1) # msht xarr=np.loadtxt(inputf,skiprows=3,max_rows=1) - - nx=1000 diff --git a/src/outputs.py b/src/outputs.py index d1597cf..383fb38 100644 --- a/src/outputs.py +++ b/src/outputs.py @@ -5,13 +5,23 @@ from reportengine.utils import yaml_safe from lhapdf_funs import * +OUTPUT_F = Path("outputs") +BUFFER_F = OUTPUT_F / "buffer" +PARS_F = OUTPUT_F / "pars" +EVGRIDS_F = OUTPUT_F / "evgrids" +PLOTS_F = OUTPUT_F / "plots" +RES_F = OUTPUT_F / "res" +COV_F = OUTPUT_F / "cov" +for PF in [BUFFER_F, PARS_F, EVGRIDS_F, PLOTS_F, RES_F, COV_F]: + PF.mkdir(exist_ok=True, parents=True) + + def covmatout(hessi,jaci): # hessin=hessi.copy() # hessin=la.inv(hessin) pars=pdf_pars.pdfparsi.copy() - - output='outputs/cov/'+inout_pars.label+'.dat' + output = COV_F / f"{inout_pars.label}.dat" print('call covmatout') print(output) @@ -132,36 +142,19 @@ def evgrido(): test[195,13]=0. if inout_pars.pd_output: - dirgrid0='outputs/evgrids/'+inout_pars.pd_output_lab - dirgrid1='outputs/evgrids/'+inout_pars.pd_output_lab+'/nnfit' - dirgrid='outputs/evgrids/'+inout_pars.pd_output_lab+'/nnfit/replica_'+str(fit_pars.irep+1)+'/' + dirgrid0 = EVGRIDS_F / inout_pars.pd_output_lab else: - dirgrid0='outputs/evgrids/'+inout_pars.label - dirgrid1='outputs/evgrids/'+inout_pars.label+'/nnfit' - dirgrid='outputs/evgrids/'+inout_pars.label+'/nnfit/replica_'+str(fit_pars.irep+1)+'/' - + dirgrid0 = EVGRIDS_F / inout_pars.label - try: - os.mkdir(dirgrid0) - except OSError as error: - print(error) - - try: - os.mkdir(dirgrid1) - except OSError as error: - print(error) - - try: - os.mkdir(dirgrid) - except OSError as error: - print(error) + dirgrid1 = dirgrid0 / "nnfit" + dirgrid = dirgrid1 / f"replica_{str(fit_pars.irep+1)}" + + dirgrid.mkdir(exist_ok = True, parents = True) if inout_pars.pd_output: - output=dirgrid+inout_pars.pd_output_lab+'.exportgrid' + output = dirgrid / f"{inout_pars.pd_output_lab}.exportgrid" else: - output=dirgrid+inout_pars.label+'.exportgrid' - - + output = dirgrid / f"{inout_pars.label}.exportgrid" data = { "replica": 1, @@ -313,9 +306,7 @@ def parsout(): def plotout(): - outputdir='outputs/plots/' - - output=outputdir+inout_pars.label+'.dat' + output = PLOTS_F / f"{inout_pars.label}.dat" msht='MSHT20nnlo_as118' nnpdf='NNPDF40_nnlo_pch_as_01180' diff --git a/src/pdfs.py b/src/pdfs.py index be2a243..80b4534 100644 --- a/src/pdfs.py +++ b/src/pdfs.py @@ -2,7 +2,6 @@ from chebyshevs import * from copy import deepcopy import numpy as np -import os from scipy.integrate import quadrature from scipy.misc import derivative as deriv @@ -28,6 +27,8 @@ def xfxQ(self, x, Q, n, fl): """Return the PDF value for one single point for one single member Note that in this case both scale (Q) and member (n) are ignored. """ + if fl == 21: + fl = 0 return self._pdf_function(fl, self._parameters, x) def grid_values(self, flavors: np.ndarray, xgrid: np.ndarray, qgrid: np.ndarray): @@ -62,6 +63,10 @@ def __init__( if isinstance(pdf_function, str): if pdf_function == "msht": pdf_function = pdfs_msht + elif pdf_function == "diff": + pdf_function = pdfs_diff + else: + raise NotImplementedError(f"{pdf_function=}") self._lhapdf_set = MSHTSet(pdf_function, pdf_parameters, name) super().__init__(name, None) @@ -98,10 +103,18 @@ def func_pdfs_diff(eps,ipdf,x,iorder): return out -def pdfs_diff(ipdf,x): - +def pdfs_diff(ipdf, parin=None, x=None): eps=1e-5 # (pars,eps_out)=parinc_newmin(pdf_pars.parinarr[0,:],chi2_pars.ipdf_newmin-1,eps) + + # TODO + # Here we are assuming that we always want to set parinarr[0] == parin + # this might not be true in all scenarios. + if x is None: + # So that the old interface works as well + x = parin + else: + pdf_pars.parinarr[0,:] = parin eps=parinc_eps(pdf_pars.parinarr[0,:],chi2_pars.ipdf_newmin-1,eps) # # pdfout=pdfs_msht(ipdf,pars,x)-pdfs_msht(ipdf,pdf_pars.parinarr[0,:],x) @@ -123,11 +136,11 @@ def pdfs_diff(ipdf,x): return pdfout def pdfs_msht(ipdf,pars,x): - - + """ + Compute a MSHT PDF given a set of parameters ``pars'' for x=x + """ etaq=pars[57] - if etaq < 0.0: etaqt=np.power(1.-x,-etaq) else: From bcd082a6f461569e538794d3c9e6bee437af803f Mon Sep 17 00:00:00 2001 From: tgiani Date: Tue, 11 Feb 2025 11:09:31 +0100 Subject: [PATCH 08/19] adding vp_pdf input to chi2corr when calling jaccalc_newmin --- src/chi2s.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/chi2s.py b/src/chi2s.py index d6adf8b..23f6bbe 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -1888,7 +1888,7 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): pdf_pars.PDFlabel=label_arr[0].strip() pdf_pars.iPDF=0 - (chiarr[0],theory0,cov0,cov0in,diffs0)=chi2corr(fit_pars.imindat,imax-1) + (chiarr[0],theory0,cov0,cov0in,diffs0)=chi2corr(fit_pars.imindat,imax-1,vp_pdf) tarr=[theory0] covarr=[cov0] @@ -1902,7 +1902,7 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): # print(ip) pdf_pars.iPDF=ip pdf_pars.PDFlabel=label_arr[ip].strip() - (chiarr[ip],theory,cov,covin,diffs_out)=chi2corr(fit_pars.imindat,imax-1) + (chiarr[ip],theory,cov,covin,diffs_out)=chi2corr(fit_pars.imindat,imax-1,vp_pdf) tarr.append(theory) diffsarr.append(diffs_out) if(chi2_pars.uset0cov): @@ -2013,7 +2013,7 @@ def jaccalc(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): pdf_pars.PDFlabel=label_arr[0].strip() pdf_pars.iPDF=0 - (chiarr[0],theory0,cov0,cov0in,diffs_out)=chi2corr(fit_pars.imindat,imax-1) + (chiarr[0],theory0,cov0,cov0in,diffs_out)=chi2corr(fit_pars.imindat,imax-1,vp_pdf) tarr=[theory0] covarr=[cov0] @@ -2026,7 +2026,7 @@ def jaccalc(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): # print(ip) pdf_pars.iPDF=ip pdf_pars.PDFlabel=label_arr[ip].strip() - (chiarr[ip],theory,cov,covin,diffs_out)=chi2corr(fit_pars.imindat,imax-1) + (chiarr[ip],theory,cov,covin,diffs_out)=chi2corr(fit_pars.imindat,imax-1,vp_pdf) tarr.append(theory) if(chi2_pars.uset0cov): covarr.append(cov) From 6658ec16c65eef1d03c9dc5897766dd479ff3575 Mon Sep 17 00:00:00 2001 From: tgiani Date: Tue, 11 Feb 2025 13:49:37 +0100 Subject: [PATCH 09/19] reproduce old behaviour when running in debug mode --- src/chi2s.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/chi2s.py b/src/chi2s.py index 23f6bbe..b453e3c 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -157,13 +157,15 @@ def chi2min_fun(afree,jac_calc,hess_calc): if DEBUG: initlha(name,pdf_pars.lhapdfdir) writelha(name,pdf_pars.lhapdfdir,parin1) - - if fit_pars.newmin and chi2_pars.ipdf_newmin > 0: - pdf_function = "diff" + vp_pdf = None else: - pdf_function = "msht" + + if fit_pars.newmin and chi2_pars.ipdf_newmin > 0: + pdf_function = "diff" + else: + pdf_function = "msht" - vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = pdf_function) + vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = pdf_function) pdf_pars.PDFlabel=name pdf_pars.parin_newmin_reset=True From a8f18bdcb52f8fb6b5ebaa62326a2d2f32cf3d34 Mon Sep 17 00:00:00 2001 From: juacrumar Date: Mon, 17 Feb 2025 10:18:02 +0100 Subject: [PATCH 10/19] remove a bunch of newmin condition -> assume true --- fixpar_nnpdf.py | 30 ++---------------------------- src/chi2s.py | 39 ++++++++++++++++----------------------- src/data_theory.py | 2 ++ src/global_pars.py | 5 +++-- 4 files changed, 23 insertions(+), 53 deletions(-) diff --git a/fixpar_nnpdf.py b/fixpar_nnpdf.py index 27e216b..cd5e889 100644 --- a/fixpar_nnpdf.py +++ b/fixpar_nnpdf.py @@ -150,9 +150,8 @@ if fit_pars.nlo_cuts is None: fit_pars.nlo_cuts=False -fit_pars.newmin=fitp.get("newmin") -if fit_pars.newmin is None: - fit_pars.newmin=True +# Make sure that new_min is True +fit_pars.newmin=True fit_pars.dynT_group=fitp.get("dynT_group") if fit_pars.dynT_group is None: @@ -516,31 +515,6 @@ chi2_pars.t0=False chi2_pars.t0_noderiv=False - # chi2_pars.t0_noderiv=False - # chi2_pars.t0=True - - if not fit_pars.newmin: - chi2_pars.diff_2=True - outputfile=open('outputs/buffer/'+inout_pars.label+'.dat','a') - print('t0=True,diff2=True') - outputfile.write("t0=True,diff2=True") - outputfile.write(inout_pars.inputnam) - outputfile.write("\n") - afo=levmar(afo) - - - # chi2_pars.diff_2=True - # outputfile.write("lampos = 1e3, t0,d2=true") - # outputfile.write(inout_pars.inputnam) - # outputfile.write("\n") - # afo=levmar(afo) - - # else: - # afo=levmar(afi) - - # diff_2=True - # afo=levmar_meth3(afi) - print('afo = ', afo) if(pdf_closure.pdpdf): diff --git a/src/chi2s.py b/src/chi2s.py index b453e3c..cd6b8ae 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -1,4 +1,5 @@ from global_pars import * +import functools from validphys.api import API import scipy.linalg as la from data_theory import * @@ -140,11 +141,8 @@ def chi2min_fun(afree,jac_calc,hess_calc): pdf_pars.PDFlabel_cent=name else: parin=pdf_pars.pdfparsi.copy() - if fit_pars.newmin: - (parin1,eps_arr[ip])=parinc(parin,ip-1,1) - chi2_pars.eps_arr_newmin[ip]=eps_arr[ip] - else: - (parin1,eps_arr[ip])=parinc(parin,ip-1,1) + (parin1,eps_arr[ip])=parinc(parin,ip-1,1) + chi2_pars.eps_arr_newmin[ip]=eps_arr[ip] pdf_pars.parinarr[ip,:]=parin1 if fit_pars.deld_const: @@ -157,13 +155,12 @@ def chi2min_fun(afree,jac_calc,hess_calc): if DEBUG: initlha(name,pdf_pars.lhapdfdir) writelha(name,pdf_pars.lhapdfdir,parin1) - vp_pdf = None - else: - if fit_pars.newmin and chi2_pars.ipdf_newmin > 0: - pdf_function = "diff" - else: - pdf_function = "msht" + if ip > 0: + # internally writelha was using chi2_pars.ipdf_newmin + pdf_function = "diff" + else: + pdf_function = "msht" vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = pdf_function) @@ -205,10 +202,7 @@ def chi2min_fun(afree,jac_calc,hess_calc): else: print('JACCALC') - if fit_pars.newmin: - (jac,hess,out0,out1,hessp)=jaccalc_newmin(pdflabel_arr,pdflabel_marr,eps_arr,hess_calc, vp_pdf=vp_pdf) - else: - (jac,hess,out0,out1,hessp)=jaccalc(pdflabel_arr,pdflabel_marr,eps_arr,hess_calc, vp_pdf=vp_pdf) + (jac,hess,out0,out1,hessp)=jaccalc_newmin(pdflabel_arr,pdflabel_marr,eps_arr,hess_calc, vp_pdf=vp_pdf) out=out0+out1 @@ -242,23 +236,20 @@ def chi2min_fun(afree,jac_calc,hess_calc): # write to temp lhapdf grid to be used by nnpdf code if(pdf_pars.uselha): + # TODO: this might not be needed at all + # in any case here writelha uses always msht + chi2_pars.ipdf_newmin=0 + if DEBUG: initlha(name, pdf_pars.tmp_lhapdfdir) pdf_pars.PDFlabel=name writelha(name,pdf_pars.tmp_lhapdfdir,parin1) - chi2_pars.ipdf_newmin=0 - if pdf_pars.lhin: # If using directly an LHAPDF input, load said PDF vp_pdf = API.pdf(pdf = pdf_pars.PDFlabel_lhin) else: - # TODO only these two options? Does it make sense to have this if here? - if fit_pars.newmin and chi2_pars.ipdf_newmin > 0: - pdf_function = "diff" - else: - pdf_function = "msht" - vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = pdf_function) + vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = "msht") pdf_pars.vp_pdf = vp_pdf @@ -1880,6 +1871,8 @@ def jaccalc_d0(label_arr,eps_arr,il,ih): def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): + vp_pdf = None + print('JACCALC NEWMIN') imax=fit_pars.imaxdat diff --git a/src/data_theory.py b/src/data_theory.py index f520f93..b8536b9 100644 --- a/src/data_theory.py +++ b/src/data_theory.py @@ -205,6 +205,8 @@ def _predictions_2pdfs_new(dataset, fkfunc, pdf1, pdf2=None): all replicas, central, etc) according to the provided ``fkfunc``, which should have the same interface as e.g. ``fk_predictions``. """ + if not DEBUG: + print("We should not be entering here! Who's calling me?") opfunc = OP[dataset.op] if dataset.cuts is None: diff --git a/src/global_pars.py b/src/global_pars.py index 52549b8..fff5080 100644 --- a/src/global_pars.py +++ b/src/global_pars.py @@ -1,7 +1,8 @@ import numpy as np from validphys.loader import Loader -DEBUG = False +DEBUG = True +# TODO: The newmin parameter should always be true class load_nnpdf: l=Loader() @@ -1002,7 +1003,7 @@ class fit_pars: preds_stored={} datapath='' theories_path='' - newmin=False + newmin=True # This should always be set to True dataset_ii_global='' pdf_dict=[] From e372a117661e08b3fd25bdc3f75744e3014d36f9 Mon Sep 17 00:00:00 2001 From: juacrumar Date: Mon, 17 Feb 2025 17:06:09 +0100 Subject: [PATCH 11/19] move the preparation of the PDF outside of the chi2 calculation ; add a bunch of docstrings --- fixpar_nnpdf.py | 119 +++++++++++++++++++++++++++------------------ src/chi2s.py | 61 +++++++++++------------ src/global_pars.py | 2 +- src/inputs.py | 11 +++-- src/levmar.py | 19 ++++---- src/lhapdf_funs.py | 2 - src/pdfs.py | 28 ++++++----- 7 files changed, 134 insertions(+), 108 deletions(-) diff --git a/fixpar_nnpdf.py b/fixpar_nnpdf.py index cd5e889..2f99538 100644 --- a/fixpar_nnpdf.py +++ b/fixpar_nnpdf.py @@ -1,11 +1,11 @@ -import warnings as wa +import warnings as wa from validphys import core from validphys.api import API from validphys.fkparser import load_fktable from validphys.loader import Loader from validphys.convolution import predictions, linear_predictions, central_predictions import validphys.convolution as conv -# from validphys.results import experiments_index +# from validphys.results import experiments_index import validphys.results as rs from validphys.covmats import covmat_from_systematics import numpy as np @@ -179,7 +179,7 @@ if fit_pars.pos_gluononly: fit_pars.pos_data31=fit_pars.pos_data31_gluononly fit_pars.pos_data40=fit_pars.pos_data40_gluononly - + if fit_pars.pos_dyc: fit_pars.pos_40=False fit_pars.pos_data31=fit_pars.pos_data31_dyc @@ -229,17 +229,17 @@ fit_pars.cftrue[i]=True elif fit_pars.dset_type == 'lowenergyDISDY': fit_pars.dataset_40=fit_pars.dataset_lowenergyDISDY - fit_pars.imaxdat=len(fit_pars.dataset_40) + fit_pars.imaxdat=len(fit_pars.dataset_40) for i in range(10,19): fit_pars.cftrue[i]=True elif fit_pars.dset_type == 'lowenergyDISDY_HERAonly': fit_pars.dataset_40=fit_pars.dataset_lowenergyDISDY_HERAonly - fit_pars.imaxdat=len(fit_pars.dataset_40) + fit_pars.imaxdat=len(fit_pars.dataset_40) elif fit_pars.dset_type == 'test': fit_pars.dataset_40=fit_pars.dataset_test fit_pars.imaxdat=len(fit_pars.dataset_40) for i in range(0,fit_pars.imaxdat): - fit_pars.cftrue[i]=False + fit_pars.cftrue[i]=False elif fit_pars.dset_type == 'global_new': fit_pars.dataset_40=fit_pars.dataset_40_new fit_pars.imaxdat=len(fit_pars.dataset_40) @@ -253,7 +253,7 @@ if fit_pars.theoryidi==212: fit_pars.dataset_40=fit_pars.dataset_40_nlo - fit_pars.imaxdat=len(fit_pars.dataset_40) + fit_pars.imaxdat=len(fit_pars.dataset_40) pdf_pars.lhapdfdir = get_lha_datapath() + "/" if DEBUG: @@ -265,7 +265,7 @@ fit_pars.newmin=True if chi2_pars.diff_4: - chi2_pars.diff_2=True + chi2_pars.diff_2=True if not pdf_pars.uselha: pdf_pars.lhin=False @@ -287,7 +287,7 @@ # fit_pars.pos_const=False if fit_pars.nnpdf_pos: fit_pars.pos_const=True - else: + else: fit_pars.pos_const=False (afi,hess,jac)=readincov() if chi2_pars.dynamic_tol: @@ -311,28 +311,42 @@ use_levmar=True +# Prepare the initial PDF that might be used for the computation +# of the chi2, the minimization, etc. +if pdf_pars.lhin: + # If using directly an LHAPDF input, load said PDF + vp_pdf = API.pdf(pdf = pdf_pars.PDFlabel_lhin) +else: + # NB the name is irrelevant since the PDF object doesn't leave the program + pdfname = f"{inout_pars.label}_run+{pdf_pars.idir}" + + # Take the free parameters and create the parameter set + parin = initpars() + pdf_parameters_raw = parset(afi, parin, are_free = pdf_pars.par_isf) + # Modify it so the sumrules work (is this independent from the parametrization or need the function below?) + pdf_parameters = sumrules(pdf_parameters_raw) + + vp_pdf = MSHTPDF(name = pdfname, pdf_parameters = pdf_parameters, pdf_function = "msht") + + + if inout_pars.readcov: print('finish!') -elif len(afi)==0: # no free pars \ - +elif len(afi)==0: # no free pars if inout_pars.pdout: print('Output PD to file...') - chi2_pars.t0=False fit_pars.pos_const=False - chi2expi=chi2min(afi) + chi2expi=chi2min(afi, vp_pdf=vp_pdf) elif(chi2_pars.chi2ind): - chi2_pars.t0=True fit_pars.pos_const=False - chi2t0i=chi2min(afi) - - + chi2t0i=chi2min(afi, vp_pdf=vp_pdf) print('chi2(t0) in (no pos pen):',chi2t0i,chi2t0i/chi2_pars.ndat) t1=time.process_time() @@ -341,17 +355,17 @@ chi2_pars.t0=False fit_pars.pos_const=False - chi2expi=chi2min(afi) + chi2expi=chi2min(afi, vp_pdf=vp_pdf) chi2_pars.t0=True - chi2t0i=chi2min(afi) + chi2t0i=chi2min(afi, vp_pdf=vp_pdf) fit_pars.pos_const=True if(inout_pars.pdin): - - chi2posi=chi2min(afi) + + chi2posi=chi2min(afi, vp_pdf=vp_pdf) pospeni=chi2posi-chi2t0i - + # print('chi2(exp) in:',chi2expi,(chi2expi)/chi2_pars.ndat) # t1=time.process_time() # print('time= ',t1-tzero) @@ -373,8 +387,8 @@ else: fit_pars.pos_const=True - - chi2posi=chi2min(afi) + + chi2posi=chi2min(afi, vp_pdf=vp_pdf) pospeni=chi2posi-chi2t0i print('chi2(exp) in:',chi2expi+pospeni,(chi2expi+pospeni)/chi2_pars.ndat) @@ -410,22 +424,35 @@ print('afo = ', afo) else: - chi2_pars.t0=False - fit_pars.pos_const=False - chi2expi=chi2min(afi) - chi2_pars.t0=True - chi2t0i=chi2min(afi) - fit_pars.pos_const=True - chi2posi=chi2min(afi) - pospeni=chi2posi-chi2t0i - print('chi2(exp) in:',chi2expi+pospeni,(chi2expi+pospeni)/chi2_pars.ndat) - print('chi2(t0) in:',(chi2t0i+pospeni),(chi2t0i+pospeni)/chi2_pars.ndat) - print('pos penalty in = ',pospeni,pospeni/chi2_pars.ndat) - + # Compute the experimental chi2 + chi2_pars.t0=False + fit_pars.pos_const=False + chi2expi=chi2min(afi, vp_pdf = vp_pdf) + + # Now the t0 chi2 + chi2_pars.t0=True + chi2t0i=chi2min(afi, vp_pdf = vp_pdf) + + # And now the positivity + fit_pars.pos_const=True + chi2posi=chi2min(afi, vp_pdf = vp_pdf) + + # TODO: these three calls should have t0/pos as input parameter to the chi2 function + # and possibily also the PDF *object* should be an input + pospeni=chi2posi-chi2t0i + + # Now compute the loss functions (ie., chi2+positivity) + loss_exp = chi2expi+pospeni + loss_t0 = chi2posi + ndat = chi2_pars.ndat + print(f"chi2(exp) in:{loss_exp:.8} {loss_exp/ndat:.5}") + print(f"chi2(t0) in:{loss_t0:.8} {loss_t0/ndat:.5}") + print(f"chi2(exp) in:{pospeni:.5}") + chi2_pars.t0=True if fit_pars.nnpdf_pos: fit_pars.pos_const=True - else: + else: fit_pars.pos_const=False chi2_pars.diff_4=False @@ -433,7 +460,7 @@ # chi2_pars.t0=False # chi2_pars.diff_2=False # afo=levmar(afi) - # print('afo = ', afo) + # print('afo = ', afo) chi2_pars.t0=False dload_pars.dflag=1 @@ -483,7 +510,7 @@ outputfile.write("\n") afo=levmar(afo) else: - + # chi2_pars.diff_2=True if(inout_pars.pdin): @@ -495,12 +522,12 @@ chi2_pars.t0=False chi2_pars.t0_noderiv=False - + chi2_pars.t0=False chi2_pars.t0_noderiv=False # chi2_pars.diff_2=True - + # TODO this should open a context manager and pass down the file already opened outputfile=open('outputs/buffer/'+inout_pars.label+'.dat','a') outputfile.write("diff2=False") print("diff2=False") @@ -515,7 +542,7 @@ chi2_pars.t0=False chi2_pars.t0_noderiv=False - print('afo = ', afo) + print('afo = ', afo) if(pdf_closure.pdpdf): @@ -541,7 +568,7 @@ fit_pars.pos_const=True chi2posf=chi2min(afo) pospenf=chi2posf-chi2expf - + print('chi2(exp) in:',chi2expi+pospeni,(chi2expi+pospeni)/chi2_pars.ndat) print('chi2(t0) in:',(chi2t0i+pospeni),(chi2t0i+pospeni)/chi2_pars.ndat) print('pos penalty in = ',pospeni,pospeni/chi2_pars.ndat) @@ -562,7 +589,7 @@ chi2expi=chi2min(afi) chi2_pars.t0=True chi2t0i=chi2min(afi) - ## fit_pars.pos_const=True + ## fit_pars.pos_const=True fit_pars.pos_const=True chi2posi=chi2min(afi) pospeni=chi2posi-chi2t0i @@ -570,8 +597,8 @@ print('chi2(t0) in:',chi2t0i,chi2t0i/chi2_pars.ndat) print('pos penalty = ',pospeni) res = minimize(chi2min, afi, method='Nelder-Mead', tol=1e-4, options = {'maxiter': 10000, 'maxfev': 10000}) - # res = minimize(chi2min, afi, method='Newton-CG', jac=jac_fun, hess=hess_fun, options = {'disp': True}) -# res = minimize(chi2min, afi, method='CG', jac=jac_fun, options = {'maxiter': 10000}) + # res = minimize(chi2min, afi, method='Newton-CG', jac=jac_fun, hess=hess_fun, options = {'disp': True}) +# res = minimize(chi2min, afi, method='CG', jac=jac_fun, options = {'maxiter': 10000}) print('pars out =',res.x) print(chi2min(res.x),chi2min(res.x)/chi2_pars.ndat) gridout() diff --git a/src/chi2s.py b/src/chi2s.py index cd6b8ae..9f6a6f0 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -76,11 +76,14 @@ def af_matcalc(afree): return afree_mat -def chi2min_fun(afree,jac_calc,hess_calc): +def chi2min_fun(afree,jac_calc = False, hess_calc = False, vp_pdf=None): + """ + Compute the chi2 for vp_pdf for the parameters arfree. + If jac_calc is True + """ err=False - vp_pdf = None parin=initpars() @@ -224,47 +227,37 @@ def chi2min_fun(afree,jac_calc,hess_calc): pdf_pars.idir+=pdf_pars.npar_free else: + if DEBUG: + # TODO: to be removed + # when computing the chi2 no need to do anything with the PDF - name=inout_pars.label+'_run'+str(pdf_pars.idir) - # name=inout_pars.label+'_irep'+str(fit_pars.irep)+'_run'+str(pdf_pars.idir) + name=inout_pars.label+'_run'+str(pdf_pars.idir) + parin1=pdf_pars.pdfparsi.copy() + pdf_pars.parinarr[0,:]=parin1 + pdf_pars.iPDF=0 - parin1=pdf_pars.pdfparsi.copy() - - pdf_pars.parinarr[0,:]=parin1 - pdf_pars.iPDF=0 - - # write to temp lhapdf grid to be used by nnpdf code - if(pdf_pars.uselha): - # TODO: this might not be needed at all - # in any case here writelha uses always msht - chi2_pars.ipdf_newmin=0 + # write to temp lhapdf grid to be used by nnpdf code + if(pdf_pars.uselha): + # TODO: this might not be needed at all + # in any case here writelha uses always msht + chi2_pars.ipdf_newmin=0 - if DEBUG: initlha(name, pdf_pars.tmp_lhapdfdir) pdf_pars.PDFlabel=name writelha(name,pdf_pars.tmp_lhapdfdir,parin1) - if pdf_pars.lhin: - # If using directly an LHAPDF input, load said PDF - vp_pdf = API.pdf(pdf = pdf_pars.PDFlabel_lhin) - else: - vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = "msht") - - pdf_pars.vp_pdf = vp_pdf - - # TODO calculate chi2 print("> Calculating chi2 <") chi=chi2totcalc(vp_pdf=vp_pdf) out=chi[0]+chi[1] # exp + positivity out0=chi[0] pdf_pars.idir+=1 # iterate up so new folder - print('chi2/N_dat=',out/chi2_pars.ndat) - print('chi2tot (no pos)=',out0) - print('pos pen =',chi[1]) - print('chi2tot (no pos)/N_dat=',out0/chi2_pars.ndat) - + ndat = chi2_pars.ndat + print(f"chi2/N_dat={out/ndat:.5}") + print(f"chi2tot (no pos)={out0:.5}") + print(f"pos pen ={chi[1]:.5}") + print(f"chi2tot (no pos)/N_dat={out0/ndat:.5}") # if jac_calc and hess_calc: # print('testing...') @@ -1213,10 +1206,14 @@ def jac_fun(afree): print('Jacobian = ',out) return out -def chi2min(afree): +def chi2min(afree = None, vp_pdf=None): + """Compute the chi2 that will be used during the minimization + But disable the computation of the hessian and jacobian. + Takes as input the free parameters of the problem. + """ hess_calc=False jac_calc=False - outarr=chi2min_fun(afree,jac_calc,hess_calc) + outarr=chi2min_fun(afree,jac_calc,hess_calc, vp_pdf=vp_pdf) out=outarr[0] return out @@ -1881,6 +1878,7 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): jacarr=np.zeros((pdf_pars.npar_free+1)) hessarr=np.zeros((pdf_pars.npar_free+1,pdf_pars.npar_free+1)) + # TODO This writes (upon first call) the pdf_pars.PDFlabel=label_arr[0].strip() pdf_pars.iPDF=0 (chiarr[0],theory0,cov0,cov0in,diffs0)=chi2corr(fit_pars.imindat,imax-1,vp_pdf) @@ -1998,7 +1996,6 @@ def jaccalc(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): # TODO print('JACCALC OLDMIN') - import ipdb; ipdb.set_trace() imax=fit_pars.imaxdat diff --git a/src/global_pars.py b/src/global_pars.py index fff5080..2b6a64b 100644 --- a/src/global_pars.py +++ b/src/global_pars.py @@ -1,7 +1,7 @@ import numpy as np from validphys.loader import Loader -DEBUG = True +DEBUG = False # TODO: The newmin parameter should always be true class load_nnpdf: diff --git a/src/inputs.py b/src/inputs.py index 81eca55..d382b63 100644 --- a/src/inputs.py +++ b/src/inputs.py @@ -55,15 +55,18 @@ def readincov(): return (afin,hess,jac) def readin(): + """Read the input file inputs::input_file + + Uses ``np.loadtxt`` to read the file a few times once per flavour. + These parameters are the initial parameters of the fit. + For each set of parameters, the first column represents the parameter value + and the second whether it is a free parameter (1) or whether it should be considered fixed (0) + """ parfree_def=False inputfile='input/'+inout_pars.inputnam - with open(inputfile, 'r') as fp: - x = fp.readlines() - num_lines = len([l for l in x if l.strip(' \n') != '']) - # distuv=np.loadtxt(inputfile,skiprows=1,max_rows=8) nuv=basis_pars.i_uv_max-basis_pars.i_uv_min-1 distuv=np.loadtxt(inputfile,skiprows=1,max_rows=nuv) diff --git a/src/levmar.py b/src/levmar.py index 5f35635..73b13f5 100644 --- a/src/levmar.py +++ b/src/levmar.py @@ -259,6 +259,12 @@ def levmar_meth3(afree): return afout def levmar(afree): + """ + Levenberg–Marquardt algorithm, takes the set of free parameters + and runs the minimization. + + Returns the same array with the minimized parameters. + """ lev_comb=False lev_update=True @@ -300,15 +306,13 @@ def levmar(afree): # lmin=1e-30 - hessmax=np.zeros((pdf_pars.npar_free,pdf_pars.npar_free)) hessmaxp=np.zeros((pdf_pars.npar_free,pdf_pars.npar_free)) - + + # TODO use a context manager for this file outputfile=open('outputs/buffer/'+inout_pars.label+'.dat','a') outputfile.write("LM meth 1 ") outputfile.write("\n") - - if del_grat: nsteps=35 @@ -364,7 +368,7 @@ def levmar(afree): # lam=0.001 - + # TODO skip this condition if(min_pars.sgd): hess_calc=True # think has to be for lev update else: @@ -373,13 +377,8 @@ def levmar(afree): jac_calc=True dload_pars.dcov=1 - - (chi2i,jaci,hessi,err,hessp)=chi2min_fun(af,jac_calc,hess_calc) - - - print('chi2i = ',chi2i) print('jac =',-jaci/2.) diff --git a/src/lhapdf_funs.py b/src/lhapdf_funs.py index 3fedeae..46c84e4 100644 --- a/src/lhapdf_funs.py +++ b/src/lhapdf_funs.py @@ -109,8 +109,6 @@ def writelha(name,lhdir,parin): for ix in range(0,nx): for iq in range(0,2): xin=xarr[ix] - - if fit_pars.theoryidi==211 or fit_pars.theoryidi==40001000 or fit_pars.theoryidi==50001000: qin=1.00 elif fit_pars.theoryidi==200: diff --git a/src/pdfs.py b/src/pdfs.py index 80b4534..4e2d9b7 100644 --- a/src/pdfs.py +++ b/src/pdfs.py @@ -852,6 +852,8 @@ def int_g2_msht(ain,xmin): def sumrules(parin): + """ + Modify the set of input parameters so that the sum rules are fulfilled""" out=parin.copy() @@ -931,7 +933,7 @@ def sumrules(parin): return out def initpars(): - + """Prepare the whole set of initial parameters""" auv=uv_init() adv=dv_init() asea=sea_init() @@ -941,7 +943,6 @@ def initpars(): adbub=dbub_init() fitcharm=fitcharm_init() - # pdfpars=np.concatenate((auv,adv,asea,asp,ag,asm,adbub)) pdfpars=np.concatenate((auv,adv,asea,asp,ag,asm,adbub,fitcharm)) @@ -1008,19 +1009,20 @@ def dbub_init(): return a -def parset(af,parin): - - afi=af.copy() - out=parin.copy() - - - for i in range(1,basis_pars.n_pars): - if pdf_pars.par_isf[i]: - out[i]=afi[0] - afi=np.delete(afi,0) - +def parset(af, parin, are_free=None): + """ + Takes an array of free parameters (``af``) + and an array with all parameters in the problem (``parin``). + Returns an array where the free parameters of ``parin`` are substituted with those in ``af``. + Whether the parameters are to be considered free or not is given by the ``are_free`` array. + Note: the parameters in ``af`` should be order like in ``parin``. + """ + if are_free is None: + are_free = pdf_pars.par_isf + out = parin.copy() + out[are_free.astype(bool)] = af return out def parcheck(pars): From 5a579cb31d3483a2aed685209351d3b49cf03455 Mon Sep 17 00:00:00 2001 From: juacrumar Date: Fri, 21 Feb 2025 12:24:52 +0100 Subject: [PATCH 12/19] use the mshtpdf object also for the fit --- fixpar_nnpdf.py | 3 +- src/chi2s.py | 49 +++++++++---------- src/data_theory.py | 1 + src/levmar.py | 1 + src/lhapdf_funs.py | 8 +-- src/pdfs.py | 118 +++++++++++++++++++++++++++++++++------------ 6 files changed, 119 insertions(+), 61 deletions(-) diff --git a/fixpar_nnpdf.py b/fixpar_nnpdf.py index 2f99538..2877cd0 100644 --- a/fixpar_nnpdf.py +++ b/fixpar_nnpdf.py @@ -474,6 +474,7 @@ if fit_pars.nnpdf_pos: + # TODO: there are a few calls to levmar here that need to be treated if(inout_pars.pdin): chi2_pars.t0=False chi2_pars.t0_noderiv=False @@ -533,7 +534,7 @@ print("diff2=False") outputfile.write(inout_pars.inputnam) outputfile.write("\n") - afo=levmar(afi) + afo = levmar(afi) if chi2_pars.t0_noderivin and not inout_pars.pdin: chi2_pars.t0_noderiv=False diff --git a/src/chi2s.py b/src/chi2s.py index 9f6a6f0..2483452 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -76,21 +76,15 @@ def af_matcalc(afree): return afree_mat -def chi2min_fun(afree,jac_calc = False, hess_calc = False, vp_pdf=None): +def chi2min_fun(afree, jac_calc = False, hess_calc = False, vp_pdf=None): """ - Compute the chi2 for vp_pdf for the parameters arfree. + Compute the chi2 for a MSHTPDF for the parameters arfree. If jac_calc is True """ - - err=False - parin=initpars() - pdfparsii=parset(afree,parin) - dload_pars.xarr_tot=xgrid_calc() - # print('pdfparsi = ',pdfparsi) if not jac_calc and not hess_calc: @@ -104,6 +98,15 @@ def chi2min_fun(afree,jac_calc = False, hess_calc = False, vp_pdf=None): pdf_pars.pdfparsi=sumrules(pdfparsii) + # Reset the vp_pdf if not explicitly given + if vp_pdf is None: + parin = initpars() + pdf_parameters_raw = parset(afree, parin, are_free = pdf_pars.par_isf) + pdf_parameters = sumrules(pdf_parameters_raw) + vp_pdf = MSHTPDF(name = "pdf", pdf_parameters = pdf_parameters, pdf_function = "msht") + + # TODO Perhaps at this point we want to update the parameters in vp_pdf or to create a new one? + # note that upon first call at this point the parameters in pdfparsii are equal to those in the PDF if fit_pars.deld_const: pdf_pars.deld_arr=np.zeros((4*pdf_pars.npar_free+1)) @@ -112,9 +115,6 @@ def chi2min_fun(afree,jac_calc = False, hess_calc = False, vp_pdf=None): pdf_pars.delu_arr[0]=pdf_pars.pdfparsi[1] # print(pdf_pars.pdfparsi[10]) - - - jac=np.zeros((pdf_pars.npar_free)) hess=np.zeros((pdf_pars.npar_free,pdf_pars.npar_free)) hessp=np.zeros((pdf_pars.npar_free,pdf_pars.npar_free)) @@ -131,8 +131,11 @@ def chi2min_fun(afree,jac_calc = False, hess_calc = False, vp_pdf=None): eps_arr=np.zeros((pdf_pars.npar_free+1)) chi2_pars.eps_arr_newmin=eps_arr - for ip in range(0,pdf_pars.npar_free+1): + # TODO + # this loop creates the LHAPDF grids for each free parameter + pdf_pars.derivatives =[] + for ip in range(0,pdf_pars.npar_free+1): idir_j=pdf_pars.idir+ip name=inout_pars.label+'_run'+str(idir_j) # name=inout_pars.label+'_irep'+str(fit_pars.irep)+'_run'+str(idir_j) @@ -155,20 +158,17 @@ def chi2min_fun(afree,jac_calc = False, hess_calc = False, vp_pdf=None): if(pdf_pars.uselha): # TODO what about this chi2_pars.ipdf_newmin=ip + if ip > 0: + parameter_index = pdf_pars.par_free_i[ip - 1] + pdf_derivative = vp_pdf.make_derivative(parameter_index) + pdf_pars.derivatives.append(pdf_derivative) if DEBUG: initlha(name,pdf_pars.lhapdfdir) writelha(name,pdf_pars.lhapdfdir,parin1) - if ip > 0: - # internally writelha was using chi2_pars.ipdf_newmin - pdf_function = "diff" - else: - pdf_function = "msht" - - vp_pdf = MSHTPDF(name = name, pdf_parameters = parin1, pdf_function = pdf_function) - pdf_pars.PDFlabel=name pdf_pars.parin_newmin_reset=True + ####################### if chi2_pars.diff_2 or fit_pars.pos_const: @@ -202,7 +202,6 @@ def chi2min_fun(afree,jac_calc = False, hess_calc = False, vp_pdf=None): (out0,out1,jac,hessd2)=jaccalc_d2(pdflabel_arr,pdflabel_marr,eps_arr,hess_calc,fit_pars.imindat,fit_pars.imaxdat) out=out0+out1 hess=hessd2.copy() - else: print('JACCALC') (jac,hess,out0,out1,hessp)=jaccalc_newmin(pdflabel_arr,pdflabel_marr,eps_arr,hess_calc, vp_pdf=vp_pdf) @@ -1868,8 +1867,6 @@ def jaccalc_d0(label_arr,eps_arr,il,ih): def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): - vp_pdf = None - print('JACCALC NEWMIN') imax=fit_pars.imaxdat @@ -1878,7 +1875,6 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): jacarr=np.zeros((pdf_pars.npar_free+1)) hessarr=np.zeros((pdf_pars.npar_free+1,pdf_pars.npar_free+1)) - # TODO This writes (upon first call) the pdf_pars.PDFlabel=label_arr[0].strip() pdf_pars.iPDF=0 (chiarr[0],theory0,cov0,cov0in,diffs0)=chi2corr(fit_pars.imindat,imax-1,vp_pdf) @@ -1895,7 +1891,10 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): # print(ip) pdf_pars.iPDF=ip pdf_pars.PDFlabel=label_arr[ip].strip() - (chiarr[ip],theory,cov,covin,diffs_out)=chi2corr(fit_pars.imindat,imax-1,vp_pdf) + + parameter_index = pdf_pars.par_free_i[ip - 1] + pdf_derivative = vp_pdf.make_derivative(parameter_index) + (chiarr[ip],theory,cov,covin,diffs_out)=chi2corr(fit_pars.imindat,imax-1, vp_pdf=pdf_derivative) tarr.append(theory) diffsarr.append(diffs_out) if(chi2_pars.uset0cov): diff --git a/src/data_theory.py b/src/data_theory.py index b8536b9..008e236 100644 --- a/src/data_theory.py +++ b/src/data_theory.py @@ -207,6 +207,7 @@ def _predictions_2pdfs_new(dataset, fkfunc, pdf1, pdf2=None): """ if not DEBUG: print("We should not be entering here! Who's calling me?") + raise Exception opfunc = OP[dataset.op] if dataset.cuts is None: diff --git a/src/levmar.py b/src/levmar.py index 73b13f5..e4b6643 100644 --- a/src/levmar.py +++ b/src/levmar.py @@ -377,6 +377,7 @@ def levmar(afree): jac_calc=True dload_pars.dcov=1 + (chi2i,jaci,hessi,err,hessp)=chi2min_fun(af,jac_calc,hess_calc) diff --git a/src/lhapdf_funs.py b/src/lhapdf_funs.py index 46c84e4..22cc5c8 100644 --- a/src/lhapdf_funs.py +++ b/src/lhapdf_funs.py @@ -109,6 +109,7 @@ def writelha(name,lhdir,parin): for ix in range(0,nx): for iq in range(0,2): xin=xarr[ix] + # TODO: ask vp which is the starting scale for whatever theory is being used if fit_pars.theoryidi==211 or fit_pars.theoryidi==40001000 or fit_pars.theoryidi==50001000: qin=1.00 elif fit_pars.theoryidi==200: @@ -122,7 +123,7 @@ def writelha(name,lhdir,parin): pdfout=pdfs[fit_pars.lhrep].xfxQ(i,xin,qin) else: if iq==0: - if fit_pars.newmin and chi2_pars.ipdf_newmin > 0: + if chi2_pars.ipdf_newmin > 0: pdfout=pdfs_diff(i,xin) else: pdfout=pdfs_msht(i,parin,xin) @@ -136,7 +137,7 @@ def writelha(name,lhdir,parin): # pdfout=pdfs[0].xfxQ(i,xin,qin) else: if iq==0: - if fit_pars.newmin and chi2_pars.ipdf_newmin > 0: + if chi2_pars.ipdf_newmin > 0: pdfout=pdfs_diff(i,xin) else: pdfout=pdfs_msht(i,parin,xin) @@ -148,7 +149,7 @@ def writelha(name,lhdir,parin): pdfout=pdfs[fit_pars.lhrep].xfxQ(21,xin,qin) else: if iq==0: - if fit_pars.newmin and chi2_pars.ipdf_newmin > 0: + if chi2_pars.ipdf_newmin > 0: pdfout=pdfs_diff(0,xin) else: pdfout=pdfs_msht(0,parin,xin) @@ -156,7 +157,6 @@ def writelha(name,lhdir,parin): pdfout=1. pdfarr[5]=pdfout -# np.savetxt(outputfile,pdfarr,fmt="%.7E",delimiter=' ', newline=' ') np.savetxt(outputfile,pdfarr,fmt="%.14E",delimiter=' ', newline=' ') outputfile.write('\n') diff --git a/src/pdfs.py b/src/pdfs.py index 4e2d9b7..3ac9d2f 100644 --- a/src/pdfs.py +++ b/src/pdfs.py @@ -1,3 +1,4 @@ +import functools from global_pars import * from chebyshevs import * from copy import deepcopy @@ -8,13 +9,33 @@ from validphys.core import PDF from validphys.lhapdfset import LHAPDFSet +def _derivative(func, fl, parameters, x, eps): + """The scipy.misc.derivative function is deprecated and won't exist in newer versions + of scipy. + This implements the same derivative for order 5, evaluated at 0 + already specialized for the PDF functions which take only the variation as input + From: https://github.com/scipy/scipy/blob/92d2a8592782ee19a1161d0bf3fc2241ba78bb63/scipy/_lib/_finite_differences.py#L69 + """ + # TODO: we can probably have the exact derivative and that's it? + weights = np.array([1, -8, 8, -1]) / 12.0 + funvals = np.array([func(fl, p, x) for p in parameters]) + return np.sum(funvals * weights) / np.sum(eps) + class MSHTSet(LHAPDFSet): """Provides a few lhapdf-like functions to trick vp into thinking it is an LHAPDFset Can work with any function with a signature of (flavour, parameters, x) """ - def __init__(self, pdf_function, parameters, name, error_type="replicas"): + def __init__( + self, + pdf_function, + parameters, + name, + error_type="replicas", + variation=None, + theta_idx=None, + ): self._error_type = error_type self._name = name self._flavors = None @@ -22,6 +43,22 @@ def __init__(self, pdf_function, parameters, name, error_type="replicas"): self._parameters = parameters self._pdf_function = pdf_function + self._derivatives = [] + self._variation = variation + + if variation is not None: + # Compute the 4 variations needed for the derivative + for k in [-2, -1, 1, 2]: + self._derivatives.append( + parinc_newmin( + self._parameters, theta_idx, k * variation, true_idx=True + )[0] + ) + + @functools.cached_property + def is_derivative(self): + """Whether this is a PDF of its derivative""" + return self._variation is not None def xfxQ(self, x, Q, n, fl): """Return the PDF value for one single point for one single member @@ -29,7 +66,12 @@ def xfxQ(self, x, Q, n, fl): """ if fl == 21: fl = 0 - return self._pdf_function(fl, self._parameters, x) + if self.is_derivative: + return _derivative( + self._pdf_function, fl, self._derivatives, x, self._variation + ) + else: + return self._pdf_function(fl, self._parameters, x) def grid_values(self, flavors: np.ndarray, xgrid: np.ndarray, qgrid: np.ndarray): """Returns the PDF values for every member for the required flavors, x, q @@ -58,22 +100,45 @@ def __init__( boundary=None, pdf_function="msht", pdf_parameters=None, + variation=None, + theta_idx=None, Q=1.0, ): if isinstance(pdf_function, str): - if pdf_function == "msht": - pdf_function = pdfs_msht - elif pdf_function == "diff": - pdf_function = pdfs_diff - else: + if pdf_function != "msht": raise NotImplementedError(f"{pdf_function=}") + pdf_function = pdfs_msht - self._lhapdf_set = MSHTSet(pdf_function, pdf_parameters, name) + self._pdf_function = pdf_function + self._pdf_parameters = pdf_parameters + self._variation = variation + self._theta_idx = theta_idx super().__init__(name, None) # Create some fake info: self._info = {"NumMembers": 1} + @functools.cached_property + def _lhapdf_set(self): + return MSHTSet( + self._pdf_function, + self._pdf_parameters, + self.name, + variation=self._variation, + theta_idx=self._theta_idx + ) + + def make_derivative(self, idx, eps=1e-5): + """Constructs the derivative of the PDF with respect the parameter idx.""" + variation = np.maximum(1e-12, eps * np.abs(self._pdf_parameters[idx])) + return self.__class__( + "derivative", + pdf_function=self._pdf_function, + pdf_parameters=self._pdf_parameters, + variation=variation, + theta_idx=idx, + ) + def load(self): return self._lhapdf_set @@ -82,8 +147,7 @@ def load_t0(self): t0_version._error_type = "t0" return t0_version - -def func_pdfs_diff(eps,ipdf,x,iorder): +def func_pdfs_diff(eps,ipdf=1,x=0.0,iorder=5): # print(eps) @@ -103,35 +167,24 @@ def func_pdfs_diff(eps,ipdf,x,iorder): return out -def pdfs_diff(ipdf, parin=None, x=None): +def pdfs_diff(ipdf, x=None, parin=None): eps=1e-5 # (pars,eps_out)=parinc_newmin(pdf_pars.parinarr[0,:],chi2_pars.ipdf_newmin-1,eps) - # TODO - # Here we are assuming that we always want to set parinarr[0] == parin - # this might not be true in all scenarios. - if x is None: - # So that the old interface works as well - x = parin - else: - pdf_pars.parinarr[0,:] = parin eps=parinc_eps(pdf_pars.parinarr[0,:],chi2_pars.ipdf_newmin-1,eps) - # # pdfout=pdfs_msht(ipdf,pars,x)-pdfs_msht(ipdf,pdf_pars.parinarr[0,:],x) - # pdfout=func_pdfs_diff(eps,ipdf,x)-func_pdfs_diff(0.,ipdf,x) - # # pdfout/=chi2_pars.eps_arr_newmin[chi2_pars.ipdf_newmin] - # pdfout/=eps - - # derivative(func, x0, dx=1.0 - pdf_pars.parin_newmin_counter=0 iorder=5 pdfout=deriv(func_pdfs_diff,0.,eps,args=(ipdf,x,iorder),order=iorder) - pdf_pars.parin_newmin_reset=False +# test = functools.partial(func_pdfs_diff, x=x, ipdf=ipdf) +# ret = _derivative(test, eps, ipdf, pdf_pars.parinarr[0,:], x) - # print(pdfout,test) - # os.quit() + mypdf = pdf_pars.derivatives + if pdfout > 1e-5 and chi2_pars.ipdf_newmin >0: + pass + + pdf_pars.parin_newmin_reset=False return pdfout @@ -1160,9 +1213,12 @@ def parinc_eps(parin,ipar,eps): return eps_n -def parinc_newmin(parin,ipar,eps): +def parinc_newmin(parin,ipar,eps, true_idx=False): - npar=pdf_pars.par_free_i[ipar] + if true_idx: + npar = ipar + else: + npar=pdf_pars.par_free_i[ipar] # eps_n=eps*np.abs(parin[npar]) eps_n=eps From 260023a2bcd3c9b272835c84d9766e4b31f185e2 Mon Sep 17 00:00:00 2001 From: tgiani Date: Tue, 11 Mar 2025 15:56:35 +0100 Subject: [PATCH 13/19] adding some docstrings --- src/chi2s.py | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/chi2s.py b/src/chi2s.py index 2483452..a0f0885 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -128,7 +128,6 @@ def chi2min_fun(afree, jac_calc = False, hess_calc = False, vp_pdf=None): pdflabel_p2arr=np.empty(pdf_pars.npar_free+1, dtype='U256') if(jac_calc): - eps_arr=np.zeros((pdf_pars.npar_free+1)) chi2_pars.eps_arr_newmin=eps_arr @@ -1479,6 +1478,7 @@ def hess_ij_calc_not0_new(theoryi,theoryj,outi,outj,cov,covin): return out def hess_ij_calc_newmin(diffi,diffj,covin): + """Compute off-diagonal entries of the hessian""" out=diffi@covin@diffj*2. @@ -1612,6 +1612,7 @@ def hess_ii_calc_d2(diff2,cov,covin): return out def hess_ii_calc_newmin(diff2,cov,covin): + """Compute diagonal entries of the hessian""" @@ -1866,6 +1867,9 @@ def jaccalc_d0(label_arr,eps_arr,il,ih): return jacarr def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): + """Compute the derivative of the chi2 wrt the free parameters + (given in Eq.6 https://people.duke.edu/~hpgavin/lm.pdf) and the Hessian + (given after Eq.9 https://people.duke.edu/~hpgavin/lm.pdf)""" print('JACCALC NEWMIN') @@ -1877,6 +1881,8 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): pdf_pars.PDFlabel=label_arr[0].strip() pdf_pars.iPDF=0 + + # compute chi2, theory predictions, cov, cov_inv, and theory - data (chiarr[0],theory0,cov0,cov0in,diffs0)=chi2corr(fit_pars.imindat,imax-1,vp_pdf) tarr=[theory0] @@ -1893,7 +1899,11 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): pdf_pars.PDFlabel=label_arr[ip].strip() parameter_index = pdf_pars.par_free_i[ip - 1] + + # compute derivative of the PDF wrt the free parameter parameter_index pdf_derivative = vp_pdf.make_derivative(parameter_index) + + # compute J_i, i.e. the derivative of the theory predictions wrt the free parameter i=parameter_index (theory) (chiarr[ip],theory,cov,covin,diffs_out)=chi2corr(fit_pars.imindat,imax-1, vp_pdf=pdf_derivative) tarr.append(theory) diffsarr.append(diffs_out) @@ -1913,12 +1923,16 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): # print(tarr[ip]) - test1=-2.*tarr[ip]@cov0in@diffsarr[0] + + # compute the derivative of the chi2 wrt the free parameter parameter_index + # Eq.6 https://people.duke.edu/~hpgavin/lm.pdf + test1=-2.*tarr[ip]@cov0in@diffsarr[0] jacarr[ip]=test1 # print(np.sum(tarr[ip])) if(hess_calc): + # compute the diagonal entries of the hessian, defined as J cov0in J^T if ip==1: tii0=hess_ii_calc_newmin(tarr[ip],cov0,cov0in) print(tii0) @@ -1926,12 +1940,14 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): else: tii0=hess_ii_calc_newmin(tarr[ip],cov0,cov0in) tii.append(tii0) - + # I guess this should also happen only if(hess_calc)? for jp in range(1,ip+1): if ip==jp: + # fill the diagonal hii=tii[ip-1] hessarr[ip,jp]=hii else: + # compute the off-diagonal entries of the hessian (lower-triangular entries) hij=hess_ij_calc_newmin(tarr[ip],tarr[jp],cov0in) hessarr[ip,jp]=hij @@ -1939,8 +1955,10 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): hessarr=np.delete(hessarr,0,0) hessarr=np.delete(hessarr,0,1) + # compute the missing entries of the hessian using the fact that it s symmetric hessarr=hessarr+hessarr.T-np.diag(hessarr.diagonal()) + # save the chi2 out0=chiarr[0] chiarr=np.zeros((pdf_pars.npar_free+1)) @@ -1948,6 +1966,7 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): penarr=np.zeros((pdf_pars.npar_free+1)) if fit_pars.pos_const: + # what about this? for ip in range(0,pdf_pars.npar_free+1): pdf_pars.PDFlabel=label_arr[ip].strip() out31=pos_calc(fit_pars.pos_data31) @@ -1960,6 +1979,7 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): chiarr[ip]=chiarr[ip]+out1 if fit_pars.pos_const: + # what about this? for ip in range(1,pdf_pars.npar_free+1): pdf_pars.PDFlabel=label_arrm[ip].strip() out31m=pos_calc(fit_pars.pos_data31) @@ -2078,7 +2098,7 @@ def jaccalc(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): hessarr=np.delete(hessarr,0,0) hessarr=np.delete(hessarr,0,1) - hessarr=hessarr+hessarr.T-np.diag(hessarr.diagonal()) + hessarr=hessarr+hessarr.T-np.diag(hessarr.diagonal()) # hessian is symmetric, so fill the remaining entries out0=chiarr[0] From 42c90df13678fcc68f39cfcdee10fb5b40fe8235 Mon Sep 17 00:00:00 2001 From: tgiani Date: Thu, 13 Mar 2025 14:15:38 +0100 Subject: [PATCH 14/19] adding implementation of observable derivative --- fixpar_nnpdf.py | 2 +- src/chi2s.py | 19 ++++++++++++------- src/data_theory.py | 4 ++-- src/pdfs.py | 28 ++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/fixpar_nnpdf.py b/fixpar_nnpdf.py index 2877cd0..66f5503 100644 --- a/fixpar_nnpdf.py +++ b/fixpar_nnpdf.py @@ -9,7 +9,7 @@ import validphys.results as rs from validphys.covmats import covmat_from_systematics import numpy as np -from validphys.commondataparser import load_commondata +from nnpdf_data.commondataparser import load_commondata import validphys.commondata as cdat import pandas as pd from validphys.calcutils import calc_chi2 diff --git a/src/chi2s.py b/src/chi2s.py index a0f0885..35dc9e7 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -272,14 +272,14 @@ def chi2min_fun(afree, jac_calc = False, hess_calc = False, vp_pdf=None): return(out,jac,hess,err,hessp) -def chi2corr(imin, imax, vp_pdf=None): +def chi2corr(imin, imax, vp_pdf=None, theta_idx=None): # TODO: add docstr """ """ if(pdf_closure.pdpdf): (out,theorytot,cov,covin)=chi2corr_pdf() diffs_out=0. else: - (out,theorytot,cov,covin,diffs_out)=chi2corr_global(imin, imax, vp_pdf) + (out,theorytot,cov,covin,diffs_out)=chi2corr_global(imin, imax, vp_pdf, theta_idx=theta_idx) return (out,theorytot,cov,covin,diffs_out) @@ -674,7 +674,7 @@ def chi2corr_ind(i): return (out,ndat,dlabel) -def chi2corr_global(imin, imax, vp_pdf=None): +def chi2corr_global(imin, imax, vp_pdf=None, theta_idx=None): """Compute chi2 for the global dataset. Takes from index 0 of the dataset all the way to index imax as defined in ``global_pars.fit_pars.dataset_40``. @@ -784,9 +784,13 @@ def chi2corr_global(imin, imax, vp_pdf=None): # "use_cuts": "internal", # "theoryid": fit_pars.theoryidi, # } - - if vp_pdf is not None: - # NB: checked that it produce the same values as the line below + + if vp_pdf is not None and theta_idx is not None: + # computing derivative of th prediction wrt free parameter theta_idx + theory = vp_pdf.derivative_th_predictions("internal", fit_pars.theoryidi, dataset_testii, theta_idx) + elif vp_pdf is not None: + # computing central value of th prediction. + # In order to use this aslo to compute the derivative we need to modify vp API allowing central_predictions to take 2 pdfs as input theory = API.central_predictions(**inptt).values[:,0] else: theory=theory_calc(i,dataset_testii,inptt,fit_pars.cftrue[i]) @@ -1904,7 +1908,8 @@ def jaccalc_newmin(label_arr,label_arrm,eps_arr,hess_calc, vp_pdf=None): pdf_derivative = vp_pdf.make_derivative(parameter_index) # compute J_i, i.e. the derivative of the theory predictions wrt the free parameter i=parameter_index (theory) - (chiarr[ip],theory,cov,covin,diffs_out)=chi2corr(fit_pars.imindat,imax-1, vp_pdf=pdf_derivative) + # NB: for the time being vp_pdf=vp_pdf, but if using API.central_predictions to compute derivative then it should be vp_pdf=pdf_derivative + (chiarr[ip],theory,cov,covin,diffs_out)=chi2corr(fit_pars.imindat,imax-1, vp_pdf=vp_pdf, theta_idx=parameter_index) tarr.append(theory) diffsarr.append(diffs_out) if(chi2_pars.uset0cov): diff --git a/src/data_theory.py b/src/data_theory.py index 008e236..25f008f 100644 --- a/src/data_theory.py +++ b/src/data_theory.py @@ -14,7 +14,7 @@ from validphys.kinematics import * import operator import lhapdf -from validphys.commondataparser import load_commondata +from nnpdf_data.commondataparser import load_commondata from validphys.convolution import OP import functools from validphys.pdfbases import evolution @@ -207,7 +207,7 @@ def _predictions_2pdfs_new(dataset, fkfunc, pdf1, pdf2=None): """ if not DEBUG: print("We should not be entering here! Who's calling me?") - raise Exception + raise Exception opfunc = OP[dataset.op] if dataset.cuts is None: diff --git a/src/pdfs.py b/src/pdfs.py index 3ac9d2f..3f6c223 100644 --- a/src/pdfs.py +++ b/src/pdfs.py @@ -8,6 +8,7 @@ from validphys.core import PDF from validphys.lhapdfset import LHAPDFSet +from validphys.api import API def _derivative(func, fl, parameters, x, eps): """The scipy.misc.derivative function is deprecated and won't exist in newer versions @@ -21,6 +22,12 @@ def _derivative(func, fl, parameters, x, eps): funvals = np.array([func(fl, p, x) for p in parameters]) return np.sum(funvals * weights) / np.sum(eps) +def _derivative_th_prediction(func, use_cuts, theoryid, dataset_input, parameters, eps): + """As _derivative but specialized for the th_predictions function""" + weights = np.array([1, -8, 8, -1]) / 12.0 + funvals = np.array([func(use_cuts, theoryid, dataset_input, p) for p in parameters]) + return np.sum(funvals * weights[:,np.newaxis],axis=0) / np.sum(eps) + class MSHTSet(LHAPDFSet): """Provides a few lhapdf-like functions to trick vp into thinking it is an LHAPDFset @@ -147,6 +154,27 @@ def load_t0(self): t0_version._error_type = "t0" return t0_version + def th_predictions(self, use_cuts, theoryid, dataset_input, parameters): + """Compute theory predictions given the PDF""" + pdf = self.__class__( + pdf_function=self._pdf_function, + pdf_parameters=parameters + ) + return API.central_predictions(use_cuts=use_cuts, theoryid=theoryid, pdf=pdf, dataset_input=dataset_input).values[:,0] + + def derivative_th_predictions(self, use_cuts, theoryid, dataset_input, theta_idx): + """Compute the derivative of the theory predictions wrt the free parameter theta_idx""" + derivatives = [] + variation = np.maximum(1e-12, 1e-5 * np.abs(self._pdf_parameters[theta_idx])) + # Compute the 4 variations needed for the derivative + for k in [-2, -1, 1, 2]: + derivatives.append( + parinc_newmin( + self._pdf_parameters, theta_idx, k * variation, true_idx=True + )[0] + ) + return _derivative_th_prediction(self.th_predictions, use_cuts, theoryid, dataset_input, derivatives, variation) + def func_pdfs_diff(eps,ipdf=1,x=0.0,iorder=5): # print(eps) From ac0f823238ec2c50d8afe2c1f78acc4df2013ac7 Mon Sep 17 00:00:00 2001 From: LucianHL Date: Thu, 10 Apr 2025 11:21:59 +0100 Subject: [PATCH 15/19] Update fixpar_nnpdf.py set t0 definition to be used in minimisation (should have been the case) --- fixpar_nnpdf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixpar_nnpdf.py b/fixpar_nnpdf.py index 66f5503..22a7da3 100644 --- a/fixpar_nnpdf.py +++ b/fixpar_nnpdf.py @@ -525,7 +525,7 @@ chi2_pars.t0=False - chi2_pars.t0_noderiv=False + chi2_pars.t0_noderiv=True # chi2_pars.diff_2=True # TODO this should open a context manager and pass down the file already opened From e18200c5f4d68b952b853fb9c399c9fda43c5216 Mon Sep 17 00:00:00 2001 From: juacrumar Date: Mon, 14 Apr 2025 14:53:10 +0200 Subject: [PATCH 16/19] make every parameter change a unique pdf object --- fixpar_nnpdf.py | 8 +++++--- src/pdfs.py | 11 +++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/fixpar_nnpdf.py b/fixpar_nnpdf.py index 22a7da3..c457be7 100644 --- a/fixpar_nnpdf.py +++ b/fixpar_nnpdf.py @@ -17,8 +17,6 @@ import os import lhapdf import shutil as sh -from scipy.integrate import quadrature -from scipy.integrate import fixed_quad from validphys.covmats import dataset_inputs_covmat_from_systematics from validphys.pseudodata import make_replica from scipy.optimize import minimize @@ -255,7 +253,11 @@ fit_pars.dataset_40=fit_pars.dataset_40_nlo fit_pars.imaxdat=len(fit_pars.dataset_40) -pdf_pars.lhapdfdir = get_lha_datapath() + "/" +if os.environ.get("LHAPDF_DATA_PATH") is not None: + pdf_pars.lhapdfdir = os.environ["LHAPDF_DATA_PATH"] +else: + pdf_pars.lhapdfdir = get_lha_datapath() + "/" + if DEBUG: pdf_pars.tmp_lhapdfdir = TEMP_LHAPDF profile=_get_nnpdf_profile(None) diff --git a/src/pdfs.py b/src/pdfs.py index 3f6c223..5b542f7 100644 --- a/src/pdfs.py +++ b/src/pdfs.py @@ -3,8 +3,12 @@ from chebyshevs import * from copy import deepcopy import numpy as np -from scipy.integrate import quadrature -from scipy.misc import derivative as deriv +try: + from scipy.integrate import quadrature + from scipy.misc import derivative as deriv +except ImportError: + from scipy.integrate import quad as quadrature + from scipy.differentiate import derivative as deriv from validphys.core import PDF from validphys.lhapdfset import LHAPDFSet @@ -120,6 +124,9 @@ def __init__( self._pdf_parameters = pdf_parameters self._variation = variation self._theta_idx = theta_idx + + # Add a hash of the parameter to the name to make them unique and update cached quantities + name = f"{name}_{hash(pdf_parameters.tostring())}" super().__init__(name, None) # Create some fake info: From ed0435a96c745a66ee0a0b88a2a0af9b69b3248d Mon Sep 17 00:00:00 2001 From: LucianHL Date: Tue, 22 Apr 2025 10:37:29 +0100 Subject: [PATCH 17/19] minor fix to parameter checks --- src/pdfs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pdfs.py b/src/pdfs.py index 5b542f7..019ee12 100644 --- a/src/pdfs.py +++ b/src/pdfs.py @@ -1225,8 +1225,8 @@ def parcheck(pars): if(basis_pars.g_second_term): - if etagm < -1: - print('PARCHECK : etagm < -1') + if etagm < 0: + print('PARCHECK : etagm < 0') err=True if delgm < -1: From f97cb0abde9eb17e48fc8043c3d3d2bd55772613 Mon Sep 17 00:00:00 2001 From: LucianHL Date: Tue, 22 Apr 2025 10:54:49 +0100 Subject: [PATCH 18/19] add test fits and outputs --- configs/fit_mshtfit_publication_longmin.yaml | 68 +++++ configs/fit_mshtfit_publication_shortmin.yaml | 68 +++++ input/input_mshtfit_publication_longmin.dat | 67 +++++ input/input_mshtfit_publication_shortmin.dat | 67 +++++ .../mshtfit_publication_longmin_out.dat | 268 ++++++++++++++++++ .../mshtfit_publication_shortmin_out.dat | 93 ++++++ .../pars/mshtfit_publication_longmin_out.dat | 77 +++++ .../pars/mshtfit_publication_shortmin_out.dat | 77 +++++ 8 files changed, 785 insertions(+) create mode 100644 configs/fit_mshtfit_publication_longmin.yaml create mode 100644 configs/fit_mshtfit_publication_shortmin.yaml create mode 100644 input/input_mshtfit_publication_longmin.dat create mode 100644 input/input_mshtfit_publication_shortmin.dat create mode 100644 publication_tests/buffer/mshtfit_publication_longmin_out.dat create mode 100644 publication_tests/buffer/mshtfit_publication_shortmin_out.dat create mode 100644 publication_tests/pars/mshtfit_publication_longmin_out.dat create mode 100644 publication_tests/pars/mshtfit_publication_shortmin_out.dat diff --git a/configs/fit_mshtfit_publication_longmin.yaml b/configs/fit_mshtfit_publication_longmin.yaml new file mode 100644 index 0000000..19c1d51 --- /dev/null +++ b/configs/fit_mshtfit_publication_longmin.yaml @@ -0,0 +1,68 @@ +# input files +inputs: + # PDF parameter inputs: + input file: input_mshtfit_publication_longmin.dat + # input covariance matrix file (if used) + cov input file: newmin_final_remin_out.dat + # if true then read in covariance matrix and evaluate PDF errors + readcov: False + +# output files +outputs: + # label for output files + label: mshtfit_publication_longmin_out + +basis pars: + # If true then two term gluon parameterisation uesd + g_second_term: True + # if true and g_second_term=False then includes 7th Chebyshev for gluon + g_cheb7: False + # If true then delta_S+ set to that of sea + asp_fix: True + # If true thedelta_d=delta_u for d_V and u_V (need to set delta_d fixed or will crash!) + dvd_eq_uvd: False + +pdf pars: + # use external LHAPDF grid as input + lhin: False + # if true then use lhapdf grids for theory evaluation + # (for PDF pd fits can use parameterisation directly instead, otherwise has to be true) + uselha: True + # if lhin=true, name of set input + PDFlabel_lhin: NNPDF40_nnlo_pch_as_01180 + +pdf closure: + # if true then scatters when doing direct PDF pd fit + pdfscat: False + # label of pseudodata used + pdlabel: 'NNPDF40pch_gl_l0' + # if true then do direct fit to PDF pseudodata + pdpdf: False + +pseudodata flags: + # if true then write pseudodata out to file + pdout: False + # if true then write pseudodata out to file + pdin: False + +fit pars: + # Only use t0 for chi2i and chi2o in levmar (i.e. no derivative at all) + t0_noderivin: True + # run with fixed input parameters (override input card flags) + fixpar: False + # NNPDF theory id (211 = NNLO pch) + theoryidi: 40001000 + # impose NNPDF positivity in fit + nnpdf_pos: False + # if true then impose 4.0 positivity constraint, if pos_const=True + pos_40: True + # if true impose weight to prefer delta_d > 0.25 + deld_const: False + # if true then generates a replica from baseline dataset with seed irep + pseud: False + # irep number - also used when generating error grids + irep: 0 + # NMC PD data - set covariance matrix to be diagonal + nmcpd_diag: False + # dataset flag - global, HERAonly, noHERA, noLHC + dset_type: 'global_new' \ No newline at end of file diff --git a/configs/fit_mshtfit_publication_shortmin.yaml b/configs/fit_mshtfit_publication_shortmin.yaml new file mode 100644 index 0000000..6538865 --- /dev/null +++ b/configs/fit_mshtfit_publication_shortmin.yaml @@ -0,0 +1,68 @@ +# input files +inputs: + # PDF parameter inputs: + input file: input_mshtfit_publication_shortmin.dat + # input covariance matrix file (if used) + cov input file: newmin_final_remin_out.dat + # if true then read in covariance matrix and evaluate PDF errors + readcov: False + +# output files +outputs: + # label for output files + label: mshtfit_publication_shortmin_out + +basis pars: + # If true then two term gluon parameterisation uesd + g_second_term: True + # if true and g_second_term=False then includes 7th Chebyshev for gluon + g_cheb7: False + # If true then delta_S+ set to that of sea + asp_fix: True + # If true thedelta_d=delta_u for d_V and u_V (need to set delta_d fixed or will crash!) + dvd_eq_uvd: False + +pdf pars: + # use external LHAPDF grid as input + lhin: False + # if true then use lhapdf grids for theory evaluation + # (for PDF pd fits can use parameterisation directly instead, otherwise has to be true) + uselha: True + # if lhin=true, name of set input + PDFlabel_lhin: NNPDF40_nnlo_pch_as_01180 + +pdf closure: + # if true then scatters when doing direct PDF pd fit + pdfscat: False + # label of pseudodata used + pdlabel: 'NNPDF40pch_gl_l0' + # if true then do direct fit to PDF pseudodata + pdpdf: False + +pseudodata flags: + # if true then write pseudodata out to file + pdout: False + # if true then write pseudodata out to file + pdin: False + +fit pars: + # Only use t0 for chi2i and chi2o in levmar (i.e. no derivative at all) + t0_noderivin: True + # run with fixed input parameters (override input card flags) + fixpar: False + # NNPDF theory id (211 = NNLO pch) + theoryidi: 40001000 + # impose NNPDF positivity in fit + nnpdf_pos: False + # if true then impose 4.0 positivity constraint, if pos_const=True + pos_40: True + # if true impose weight to prefer delta_d > 0.25 + deld_const: False + # if true then generates a replica from baseline dataset with seed irep + pseud: False + # irep number - also used when generating error grids + irep: 0 + # NMC PD data - set covariance matrix to be diagonal + nmcpd_diag: False + # dataset flag - global, HERAonly, noHERA, noLHC + dset_type: 'global_new' \ No newline at end of file diff --git a/input/input_mshtfit_publication_longmin.dat b/input/input_mshtfit_publication_longmin.dat new file mode 100644 index 0000000..6b174c5 --- /dev/null +++ b/input/input_mshtfit_publication_longmin.dat @@ -0,0 +1,67 @@ +uv parameters (delu,etau,cu1-6) +0.34359110680421356 1 +3.748657630257328 1 +-1.4485203963068545 1 +0.7414364465358945 1 +-0.3388642818301362 1 +0.2280848321195746 1 +-0.09711848793057141 1 +0.0 1 +dv parameters (deld,etad,cd1-6) +0.1282679461193071 1 +3.979488631894834 1 +-0.6458627025417831 1 +-1.0084703291029582 1 +0.9089438747936651 1 +-0.037370288283984136 1 +-0.13569928165046855 1 +0.0 1 +sea parameters (AS,delS,etaS,cS1-6) +41.58449323857026 1 +-0.009876269835192724 1 +7.04310422436405 1 +-1.7767116962046965 1 +1.3784164636765508 1 +-0.8889378927790684 1 +0.46253485385558746 1 +-0.1714246671894168 1 +0.0 1 +s+ parameters (Asp,delsp,etasp,csp1-6) +0.3507526996185292 1 +-0.009876269835192724 1 +3.3216182269099597 1 +-0.12325713325327833 1 +0.7069012358154876 1 +-0.01869621773020992 1 +-0.01803450004502132 1 +0.16233132301019212 1 +-0.11341329021966999 1 +Gluon parameters (etagp,delgp,cg1-4,etagm,delgm) +5.251270998324863 1 +0.6697611015665883 1 +-0.7692192888244083 1 +1.053858946235386 1 +-0.2945725663935634 1 +0.18899337352783627 1 +-0.36797267610953976 1 +1.34544084908059 1 +-0.2780248209456775 1 +s- parameters (Asm,delsm,etasm, cs1-4) +-0.00020242971145737493 1 +0.0014906899461692123 0 +7.459056728811248 1 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +db/ub parameters (Arho,etarho,crho1-6) +3.2658603567888016 1 +2.7349338912295797 1 +-0.5233663315323309 1 +-1.1131362882747111 1 +1.5019462076096963 1 +-1.154365488496816 1 +0.5317645918880659 1 +-0.13328110490804296 1 diff --git a/input/input_mshtfit_publication_shortmin.dat b/input/input_mshtfit_publication_shortmin.dat new file mode 100644 index 0000000..043d443 --- /dev/null +++ b/input/input_mshtfit_publication_shortmin.dat @@ -0,0 +1,67 @@ +uv parameters (delu,etau,cu1-6) +0.34359110680421356 1 +3.748657630257328 1 +-1.4485203963068545 1 +0.7414364465358945 1 +-0.3388642818301362 1 +0.2280848321195746 1 +-0.09711848793057141 1 +0.0 1 +dv parameters (deld,etad,cd1-6) +0.1282679461193071 1 +3.979488631894834 1 +-0.6458627025417831 1 +-1.0084703291029582 1 +0.9089438747936651 1 +-0.037370288283984136 1 +-0.13569928165046855 1 +0.18212207494760163 1 +sea parameters (AS,delS,etaS,cS1-6) +41.58449323857026 1 +-0.009876269835192724 1 +7.04310422436405 1 +-1.7767116962046965 1 +1.3784164636765508 1 +-0.8889378927790684 1 +0.46253485385558746 1 +-0.1714246671894168 1 +0.03857700228145249 1 +s+ parameters (Asp,delsp,etasp,csp1-6) +0.3507526996185292 1 +-0.009876269835192724 1 +3.3216182269099597 1 +-0.12325713325327833 1 +0.7069012358154876 1 +-0.01869621773020992 1 +-0.01803450004502132 1 +0.16233132301019212 1 +-0.11341329021966999 1 +Gluon parameters (etagp,delgp,cg1-4,etagm,delgm) +5.251270998324863 1 +0.6697611015665883 1 +-0.7692192888244083 1 +1.053858946235386 1 +-0.2945725663935634 1 +0.18899337352783627 1 +-0.36797267610953976 1 +1.34544084908059 1 +-0.2780248209456775 1 +s- parameters (Asm,delsm,etasm, cs1-4) +-0.00020242971145737493 1 +0.0014906899461692123 0 +7.459056728811248 1 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +db/ub parameters (Arho,etarho,crho1-6) +3.2658603567888016 1 +2.7349338912295797 1 +-0.5233663315323309 1 +-1.1131362882747111 1 +1.5019462076096963 1 +-1.154365488496816 1 +0.5317645918880659 1 +-0.13328110490804296 1 diff --git a/publication_tests/buffer/mshtfit_publication_longmin_out.dat b/publication_tests/buffer/mshtfit_publication_longmin_out.dat new file mode 100644 index 0000000..1b85d2a --- /dev/null +++ b/publication_tests/buffer/mshtfit_publication_longmin_out.dat @@ -0,0 +1,268 @@ +Starting new buffer... +inputnam = input_mshtfit_publication_cheb5a.dat +LM meth 1 +ntries = 1 +chi2i = 224491.18852929212 +step = 1 +lam = 0.001 +chi2o = 28114116.969667714 +chi2i = 224491.18852929212 +step = 2 +lam = 0.01 +chi2o = 27428.51314989846 +chi2i = 224491.18852929212 +chi2o < chi2i - next iteration +ntries = 2 +chi2i = 27428.51314989846 +step = 1 +lam = 0.001 +chi2o = 8474.104554231028 +chi2i = 27428.51314989846 +chi2o < chi2i - next iteration +ntries = 3 +chi2i = 8474.104554231028 +step = 1 +lam = 0.0001 +step = 2 +lam = 0.001 +step = 3 +lam = 0.01 +step = 4 +lam = 0.1 +chi2o = 6200.859157310142 +chi2i = 8474.104554231028 +chi2o < chi2i - next iteration +ntries = 4 +chi2i = 6200.859157310142 +step = 1 +lam = 0.001 +chi2o = 12472.525727836812 +chi2i = 6200.859157310142 +step = 2 +lam = 0.01 +chi2o = 6585.52496575855 +chi2i = 6200.859157310142 +step = 3 +lam = 0.1 +chi2o = 6030.680942074619 +chi2i = 6200.859157310142 +chi2o < chi2i - next iteration +ntries = 5 +chi2i = 6030.680942074619 +step = 1 +lam = 0.001 +chi2o = 8448.523817363162 +chi2i = 6030.680942074619 +step = 2 +lam = 0.01 +chi2o = 6055.462052951501 +chi2i = 6030.680942074619 +step = 3 +lam = 0.1 +chi2o = 5985.536674218513 +chi2i = 6030.680942074619 +chi2o < chi2i - next iteration +ntries = 6 +chi2i = 5985.536674218513 +step = 1 +lam = 0.001 +chi2o = 6984.665335303685 +chi2i = 5985.536674218513 +step = 2 +lam = 0.01 +chi2o = 5937.890342960325 +chi2i = 5985.536674218513 +chi2o < chi2i - next iteration +ntries = 7 +chi2i = 5937.890342960325 +step = 1 +lam = 0.001 +chi2o = 6085.568826105325 +chi2i = 5937.890342960325 +step = 2 +lam = 0.01 +chi2o = 5843.461176393787 +chi2i = 5937.890342960325 +chi2o < chi2i - next iteration +ntries = 8 +chi2i = 5843.461176393787 +step = 1 +lam = 0.001 +chi2o = 5905.060067253815 +chi2i = 5843.461176393787 +step = 2 +lam = 0.01 +chi2o = 5812.092612527062 +chi2i = 5843.461176393787 +chi2o < chi2i - next iteration +ntries = 9 +chi2i = 5812.092612527062 +step = 1 +lam = 0.001 +chi2o = 5836.290572148721 +chi2i = 5812.092612527062 +step = 2 +lam = 0.01 +chi2o = 5792.33014393892 +chi2i = 5812.092612527062 +chi2o < chi2i - next iteration +ntries = 10 +chi2i = 5792.33014393892 +step = 1 +lam = 0.001 +chi2o = 5793.51710759696 +chi2i = 5792.33014393892 +step = 2 +lam = 0.01 +chi2o = 5779.336042082064 +chi2i = 5792.33014393892 +chi2o < chi2i - next iteration +ntries = 11 +chi2i = 5779.336042082064 +step = 1 +lam = 0.001 +chi2o = 5774.668412877901 +chi2i = 5779.336042082064 +chi2o < chi2i - next iteration +ntries = 12 +chi2i = 5774.668412877901 +step = 1 +lam = 0.0001 +chi2o = 5786.924471457789 +chi2i = 5774.668412877901 +step = 2 +lam = 0.001 +chi2o = 5751.955055480534 +chi2i = 5774.668412877901 +chi2o < chi2i - next iteration +ntries = 13 +chi2i = 5751.955055480534 +step = 1 +lam = 0.0001 +chi2o = 5760.356661780489 +chi2i = 5751.955055480534 +step = 2 +lam = 0.001 +chi2o = 5750.449909155048 +chi2i = 5751.955055480534 +chi2o < chi2i - next iteration +ntries = 14 +chi2i = 5750.449909155048 +step = 1 +lam = 0.0001 +chi2o = 5754.3091901395055 +chi2i = 5750.449909155048 +step = 2 +lam = 0.001 +chi2o = 5749.74124546488 +chi2i = 5750.449909155048 +chi2o < chi2i - next iteration +ntries = 15 +chi2i = 5749.74124546488 +step = 1 +lam = 0.0001 +chi2o = 5751.529495643029 +chi2i = 5749.74124546488 +step = 2 +lam = 0.001 +chi2o = 5749.4481462335925 +chi2i = 5749.74124546488 +chi2o < chi2i - next iteration +ntries = 16 +chi2i = 5749.4481462335925 +step = 1 +lam = 0.0001 +chi2o = 5749.829636490144 +chi2i = 5749.4481462335925 +step = 2 +lam = 0.001 +chi2o = 5749.206078771691 +chi2i = 5749.4481462335925 +chi2o < chi2i - next iteration +ntries = 17 +chi2i = 5749.206078771691 +step = 1 +lam = 0.0001 +chi2o = 5749.023307639162 +chi2i = 5749.206078771691 +chi2o < chi2i - next iteration +ntries = 18 +chi2i = 5749.023307639162 +step = 1 +lam = 1e-05 +chi2o = 5887.462372675723 +chi2i = 5749.023307639162 +step = 2 +lam = 0.0001 +chi2o = 5747.259449616578 +chi2i = 5749.023307639162 +chi2o < chi2i - next iteration +ntries = 19 +chi2i = 5747.259449616578 +step = 1 +lam = 1e-05 +chi2o = 5816.9042152212205 +chi2i = 5747.259449616578 +step = 2 +lam = 0.0001 +chi2o = 5747.062489199895 +chi2i = 5747.259449616578 +chi2o < chi2i - next iteration +ntries = 20 +chi2i = 5747.062489199895 +step = 1 +lam = 1e-05 +chi2o = 5791.238423182862 +chi2i = 5747.062489199895 +step = 2 +lam = 0.0001 +chi2o = 5747.197786153675 +chi2i = 5747.062489199895 +step = 3 +lam = 0.001 +chi2o = 5747.961765014968 +chi2i = 5747.062489199895 +step = 4 +lam = 0.01 +chi2o = 5747.990979051017 +chi2i = 5747.062489199895 +step = 5 +lam = 0.1 +chi2o = 5747.935821468584 +chi2i = 5747.062489199895 +step = 6 +lam = 1.0 +chi2o = 5747.6697945260075 +chi2i = 5747.062489199895 +step = 7 +lam = 10.0 +chi2o = 5747.213308812315 +chi2i = 5747.062489199895 +step = 8 +lam = 100.0 +chi2o = 5747.078552338051 +chi2i = 5747.062489199895 +step = 9 +lam = 1000.0 +chi2o = 5747.06407643748 +chi2i = 5747.062489199895 +step = 10 +lam = 10000.0 +chi2o = 5747.062647579913 +chi2i = 5747.062489199895 +step = 11 +lam = 100000.0 +chi2o = 5747.06250484707 +chi2i = 5747.062489199895 +step = 12 +lam = 1000000.0 +chi2o = 5747.062490643631 +chi2i = 5747.062489199895 +step = 13 +lam = 10000000.0 +chi2o = 5747.062489133743 +chi2i = 5747.062489199895 +chi2o < chi2i - next iteration +ntries = 21 +chi2i - chi2o < tol : exit +diff2=Falseinput_mshtfit_publication_cheb5a.dat diff --git a/publication_tests/buffer/mshtfit_publication_shortmin_out.dat b/publication_tests/buffer/mshtfit_publication_shortmin_out.dat new file mode 100644 index 0000000..8598112 --- /dev/null +++ b/publication_tests/buffer/mshtfit_publication_shortmin_out.dat @@ -0,0 +1,93 @@ +Starting new buffer... +inputnam = input_mshtfit_publication_cheb5b.dat +LM meth 1 +ntries = 1 +chi2i = 14996.168159534356 +step = 1 +lam = 0.001 +chi2o = 5757.553093443755 +chi2i = 14996.168159534356 +chi2o < chi2i - next iteration +ntries = 2 +chi2i = 5757.553093443755 +step = 1 +lam = 0.0001 +chi2o = 5753.952189066632 +chi2i = 5757.553093443755 +chi2o < chi2i - next iteration +ntries = 3 +chi2i = 5753.952189066632 +step = 1 +lam = 1e-05 +chi2o = 167895.25292698928 +chi2i = 5753.952189066632 +step = 2 +lam = 0.0001 +chi2o = 5747.014812610185 +chi2i = 5753.952189066632 +chi2o < chi2i - next iteration +ntries = 4 +chi2i = 5747.014812610185 +step = 1 +lam = 1e-05 +chi2o = 185568.01416140993 +chi2i = 5747.014812610185 +step = 2 +lam = 0.0001 +chi2o = 5748.075615315986 +chi2i = 5747.014812610185 +step = 3 +lam = 0.001 +chi2o = 5748.177081861058 +chi2i = 5747.014812610185 +step = 4 +lam = 0.01 +chi2o = 5748.320584433638 +chi2i = 5747.014812610185 +step = 5 +lam = 0.1 +chi2o = 5748.216187143117 +chi2i = 5747.014812610185 +step = 6 +lam = 1.0 +chi2o = 5747.548831056266 +chi2i = 5747.014812610185 +step = 7 +lam = 10.0 +chi2o = 5746.798337847987 +chi2i = 5747.014812610185 +chi2o < chi2i - next iteration +ntries = 5 +chi2i = 5746.798337847987 +step = 1 +lam = 0.001 +chi2o = 5748.138283189406 +chi2i = 5746.798337847987 +step = 2 +lam = 0.01 +chi2o = 5748.284491926071 +chi2i = 5746.798337847987 +step = 3 +lam = 0.1 +chi2o = 5748.212478063861 +chi2i = 5746.798337847987 +step = 4 +lam = 1.0 +chi2o = 5747.675484011465 +chi2i = 5746.798337847987 +step = 5 +lam = 10.0 +chi2o = 5746.914004947866 +chi2i = 5746.798337847987 +step = 6 +lam = 100.0 +chi2o = 5746.79941299915 +chi2i = 5746.798337847987 +step = 7 +lam = 1000.0 +chi2o = 5746.798185759394 +chi2i = 5746.798337847987 +chi2o < chi2i - next iteration +ntries = 6 +chi2i - chi2o < tol : exit +diff2=Falseinput_mshtfit_publication_cheb5b.dat diff --git a/publication_tests/pars/mshtfit_publication_longmin_out.dat b/publication_tests/pars/mshtfit_publication_longmin_out.dat new file mode 100644 index 0000000..2b55b97 --- /dev/null +++ b/publication_tests/pars/mshtfit_publication_longmin_out.dat @@ -0,0 +1,77 @@ +uv parameters (delu,etau,cu1-6) +0.3231802826346196 0 +3.8193447177404902 0 +-1.4790548326024462 0 +0.7660025304264685 0 +-0.3507487513245998 0 +0.21760597361821568 0 +-0.09124873859308547 0 +0.050828814377725386 0 +dv parameters (deld,etad,cd1-6) +0.12662824587568577 0 +3.982330510540003 0 +-0.6585212650241054 0 +-0.9963193544674869 0 +0.921333950051162 0 +-0.0664097167591226 0 +-0.11939531921744188 0 +0.17354231943120665 0 +sea parameters (AS,delS,etaS,cS1-6) +44.548062830019695 0 +-3.818205036831553e-05 0 +7.234497361744915 0 +-1.775925111896799 0 +1.3757350892631226 0 +-0.8840404297924626 0 +0.4601395697562931 0 +-0.17014231047507294 0 +0.03865306619890488 0 +s+ parameters (Asp,delsp,etasp,csp1-6) +0.08432248873755688 0 +-3.818205036831553e-05 0 +2.634050092199919 0 +5.664559974250834 0 +-1.49914583803317 0 +3.0420745731884318 0 +-1.6412568678642165 0 +1.3542335339981215 0 +-0.5933600417058799 0 +Gluon parameters (etagp,delgp,cg1-4,etagm,delgm) +5.082584857437277 0 +0.6328402336238066 0 +-0.7256170495882449 0 +1.005814307749848 0 +-0.26507890152018887 0 +0.17103579763891572 0 +-0.8949942245437073 0 +1.7102060131747245 0 +-0.16279510930111443 0 +s- parameters (Asm,delsm,etasm, cs1-4) +-0.00021449844304874093 0 +0.0014906899461692123 0 +7.476855031950739 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +db/ub parameters (Arho,etarho,crho1-6) +2.8882928979166604 0 +2.722878946030263 0 +-0.4257715551550677 0 +-1.1925984037066522 0 +1.4868970037128817 0 +-1.0852571516825906 0 +0.4823879311091083 0 +-0.10795203062170497 0 +charm parameters (Ac,etac,cc1-6) +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 diff --git a/publication_tests/pars/mshtfit_publication_shortmin_out.dat b/publication_tests/pars/mshtfit_publication_shortmin_out.dat new file mode 100644 index 0000000..9954eda --- /dev/null +++ b/publication_tests/pars/mshtfit_publication_shortmin_out.dat @@ -0,0 +1,77 @@ +uv parameters (delu,etau,cu1-6) +0.33869402321599046 0 +3.7911746289835935 0 +-1.4657698067657148 0 +0.7619271740728625 0 +-0.35227766637714336 0 +0.2281620215453435 0 +-0.09620238410730757 0 +0.055183834088221674 0 +dv parameters (deld,etad,cd1-6) +0.12856069297793873 0 +3.9797546235646126 0 +-0.6520851966112214 0 +-1.0010023705079036 0 +0.9167715550920073 0 +-0.05237437558262494 0 +-0.1292481879613925 0 +0.1807500511638142 0 +sea parameters (AS,delS,etaS,cS1-6) +45.33050714456857 0 +-0.0005868965682626107 0 +7.214923118760184 0 +-1.7778202968885553 0 +1.3781054404617266 0 +-0.8864061059709096 0 +0.4614854490052164 0 +-0.17075431271931935 0 +0.03875069984791884 0 +s+ parameters (Asp,delsp,etasp,csp1-6) +0.2783476494842286 0 +-0.0005868965682626107 0 +3.2784405390724864 0 +0.48141017788320234 0 +0.43531002356349435 0 +0.358105832724931 0 +-0.19590839669722512 0 +0.30688730073245785 0 +-0.15277468168399974 0 +Gluon parameters (etagp,delgp,cg1-4,etagm,delgm) +5.220200599548408 0 +0.6816593602021185 0 +-0.7221389981372724 0 +1.038528146218595 0 +-0.2705525707981772 0 +0.18264551369788973 0 +-0.596879131187242 0 +1.504815443893027 0 +-0.21035098202338054 0 +s- parameters (Asm,delsm,etasm, cs1-4) +-0.00021305540179974164 0 +0.0014906899461692123 0 +7.52815689494676 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +db/ub parameters (Arho,etarho,crho1-6) +2.960373417745138 0 +2.6800966945975553 0 +-0.4588362546068339 0 +-1.149553092425683 0 +1.4709676975053088 0 +-1.0967204556173658 0 +0.4961499163919127 0 +-0.1149656984403958 0 +charm parameters (Ac,etac,cc1-6) +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 +0.0 0 From ad6effb2f4e1c64ccd75187c69891c49c95a619d Mon Sep 17 00:00:00 2001 From: LucianHL Date: Tue, 29 Apr 2025 12:20:41 +0100 Subject: [PATCH 19/19] Fix so that t0 cov matrix consistently used in minimisation --- README | 6 +++++- configs/fit_mshtfit_publication_longmin.yaml | 4 ++++ configs/fit_mshtfit_publication_shortmin.yaml | 4 ++++ src/chi2s.py | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/README b/README index d779d3a..55b1c5f 100644 --- a/README +++ b/README @@ -10,7 +10,11 @@ To run simply execute: python fixpar_nnpdf.py --config=configs/**.yaml -for the corresponding .yaml file. Some explanation of the various flags is provided in the example .yaml files but clearly this needs better documentation + some specific example cases to be provided. +for the corresponding .yaml file. Some explanation of the various flags is provided in the example .yaml files but clearly this needs better documentation + some specific example cases to be provided. Adding to this, to run: + +- A fixed chi^2 output. Set fixpar to False. +- A fit. Set fixpar to True. The second column of 0/1's in the input file (in input/) specify whether a given parmeter is free (1) or fixed (0). If all are fixed this will be as if fixpar is set to True. The parameters for the best fit will be output to outputs/pars/$label.dat and the covariance matrix to outputs/cov/$label.dat. +- An eigenvector scan. Set readcov to True, with the 'cov input file' given by the output of a previous fit. Then specify if dynamic tolerance is used (dynamic_tol) and if not the size of the fixed tolerance (t2_err). The outputs are in the outputs/ folder: diff --git a/configs/fit_mshtfit_publication_longmin.yaml b/configs/fit_mshtfit_publication_longmin.yaml index 19c1d51..47cb4ec 100644 --- a/configs/fit_mshtfit_publication_longmin.yaml +++ b/configs/fit_mshtfit_publication_longmin.yaml @@ -46,6 +46,10 @@ pseudodata flags: pdin: False fit pars: + # Use dynamic tolerance in error calc + dynamic_tol: False + # T value for error calculation + t2_err: 1. # Only use t0 for chi2i and chi2o in levmar (i.e. no derivative at all) t0_noderivin: True # run with fixed input parameters (override input card flags) diff --git a/configs/fit_mshtfit_publication_shortmin.yaml b/configs/fit_mshtfit_publication_shortmin.yaml index 6538865..58d08dc 100644 --- a/configs/fit_mshtfit_publication_shortmin.yaml +++ b/configs/fit_mshtfit_publication_shortmin.yaml @@ -46,6 +46,10 @@ pseudodata flags: pdin: False fit pars: + # Use dynamic tolerance in error calc + dynamic_tol: False + # T value for error calculation + t2_err: 1. # Only use t0 for chi2i and chi2o in levmar (i.e. no derivative at all) t0_noderivin: True # run with fixed input parameters (override input card flags) diff --git a/src/chi2s.py b/src/chi2s.py index 35dc9e7..33955dd 100644 --- a/src/chi2s.py +++ b/src/chi2s.py @@ -872,6 +872,25 @@ def chi2corr_global(imin, imax, vp_pdf=None, theta_idx=None): dload_pars.covt0=cov dload_pars.covt0_inv=covin dload_pars.dcov=0 + # LHL ADDED NEW - so that t0 def is used in minimisation + elif chi2_pars.t0_noderiv: + if dload_pars.dcov==1: + try: + # cov = API.dataset_inputs_t0_covmat_from_systematics(**inpt0) + cov = API.dataset_inputs_covmat_t0_considered(**vp_input, dataset_inputs = all_ds_input, use_t0=True, t0pdfset=vp_pdf) + covin=la.inv(cov) + except (la.LinAlgError,ValueError) as err: + print('t0 cov may be ill behaved, trying exp cov instead...') + cov=dload_pars.covexp + covin=dload_pars.covexp_inv + print('t0 cov2...') + # cov = API.dataset_inputs_covmat_t0_considered(**vp_input, dataset_inputs = all_ds_input, use_t0=True, t0pdfset=vp_pdf) + # # print(cov) + # covin = la.inv(cov) + dload_pars.covt0=cov + dload_pars.covt0_inv=covin + print('...finish') + dload_pars.dcov=0 else: dload_pars.covexp=cov dload_pars.covexp_inv=covin