diff --git a/benchmarks/data/baryons_vd19_fk_500c.txt b/benchmarks/data/baryons_vd19_fk_500c.txt new file mode 100644 index 000000000..094b4ab4d --- /dev/null +++ b/benchmarks/data/baryons_vd19_fk_500c.txt @@ -0,0 +1,200 @@ +1.000000000000000021e-02 9.999979956162716732e-01 +1.023411402105453213e-02 9.999978902040697060e-01 +1.047370897959449751e-02 9.999977792485890138e-01 +1.071891319205127598e-02 9.999976624583727380e-01 +1.096985797892383561e-02 9.999975395266442746e-01 +1.122667773510813496e-02 9.999974101305028062e-01 +1.148951000187309161e-02 9.999972739300760916e-01 +1.175849554052156923e-02 9.999971305676296218e-01 +1.203377840777589310e-02 9.999969796666277055e-01 +1.231550603292825598e-02 9.999968208307469242e-01 +1.260382929679727468e-02 9.999966536428365194e-01 +1.289890261253308704e-02 9.999964776638249342e-01 +1.320088400831418048e-02 9.999962924315689561e-01 +1.350993521198026563e-02 9.999960974596427965e-01 +1.382622173764655633e-02 9.999958922360625557e-01 +1.414991297434575919e-02 9.999956762219456285e-01 +1.448118227674533715e-02 9.999954488500986116e-01 +1.482020705798858633e-02 9.999952095235312699e-01 +1.516716888470922599e-02 9.999949576138937868e-01 +1.552225357427047120e-02 9.999946924598307474e-01 +1.588565129428052766e-02 9.999944133652500788e-01 +1.625755666443794156e-02 9.999941195975009522e-01 +1.663816886076129042e-02 9.999938103854564275e-01 +1.702769172225899671e-02 9.999934849174956231e-01 +1.742633386009649968e-02 9.999931423393808583e-01 +1.783430876931909465e-02 9.999927817520235518e-01 +1.825183494319043351e-02 9.999924022091333242e-01 +1.867913599020782842e-02 9.999920027147445323e-01 +1.911644075385701691e-02 9.999915822206131288e-01 +1.956398343517063917e-02 9.999911396234785199e-01 +2.002200371815584384e-02 9.999906737621817587e-01 +2.049074689815847186e-02 9.999901834146339707e-01 +2.097046401323232959e-02 9.999896672946262388e-01 +2.146141197858403640e-02 9.999891240484735100e-01 +2.196385372416545870e-02 9.999885522514840863e-01 +2.247805833548725124e-02 9.999879504042442635e-01 +2.300430119772918156e-02 9.999873169287111230e-01 +2.354286414322417920e-02 9.999866501641002658e-01 +2.409403560239524456e-02 9.999859483625617163e-01 +2.465811075822603796e-02 9.999852096846298943e-01 +2.523539170434765944e-02 9.999844321944375558e-01 +2.582618760682675943e-02 9.999836138546821518e-01 +2.643081486974105734e-02 9.999827525213302870e-01 +2.704959730463134260e-02 9.999818459380481750e-01 +2.768286630392066683e-02 9.999808917303442124e-01 +2.833096101839324005e-02 9.999798873994077963e-01 +2.899422853882876669e-02 9.999788303156301739e-01 +2.967302408188869645e-02 9.999777177117906701e-01 +3.036771118035457365e-02 9.999765466758909760e-01 +3.107866187782013997e-02 9.999753141436207304e-01 +3.180625692794119413e-02 9.999740168904348581e-01 +3.255088599835058438e-02 9.999726515232227886e-01 +3.331294787934673679e-02 9.999712144715513507e-01 +3.409285069746811198e-02 9.999697019784559160e-01 +3.489101213406773511e-02 9.999681100907619191e-01 +3.570785964900462933e-02 9.999664346489094413e-01 +3.654383070957256674e-02 9.999646712762579881e-01 +3.739937302478797687e-02 9.999628153678463693e-01 +3.827494478516311333e-02 9.999608620785778168e-01 +3.917101490809260511e-02 9.999588063108063585e-01 +4.008806328898464888e-02 9.999566427012904768e-01 +4.102658105827192148e-02 9.999543656074868503e-01 +4.198707084443910331e-02 9.999519690931498728e-01 +4.297004704320839252e-02 9.999494469132035324e-01 +4.397603609302721400e-02 9.999467924978514555e-01 +4.500557675700497806e-02 9.999439989358873682e-01 +4.605922041145105866e-02 9.999410589571686714e-01 +4.713753134116724364e-02 9.999379649142121629e-01 +4.824108704165368938e-02 9.999347087628717157e-01 +4.937047852839003548e-02 9.999312820420532821e-01 +5.052631065335679711e-02 9.999276758524232589e-01 +5.170920242896757946e-02 9.999238808340631390e-01 +5.291978735958442065e-02 9.999198871430216018e-01 +5.415871378079470388e-02 9.999156844267136357e-01 +5.542664520663106997e-02 9.999112617981147366e-01 +5.672426068491977919e-02 9.999066078086948917e-01 +5.805225516094898730e-02 9.999017104200375039e-01 +5.941133984965033671e-02 9.998965569740840831e-01 +6.080224261649423700e-02 9.998911341619446391e-01 +6.222570836730231120e-02 9.998854279912122722e-01 +6.368249944718586131e-02 9.998794237517181216e-01 +6.517339604882423088e-02 9.998731059796595044e-01 +6.669919663030121626e-02 9.998664584200358529e-01 +6.826071834272388894e-02 9.998594639873205070e-01 +6.985879746785249311e-02 9.998521047242995285e-01 +7.149428986597576585e-02 9.998443617590035970e-01 +7.316807143427195292e-02 9.998362152596589336e-01 +7.488103857590022727e-02 9.998276443875826480e-01 +7.663410868007458632e-02 9.998186272479449022e-01 +7.842822061337681450e-02 9.998091408383210643e-01 +8.026433522257174491e-02 9.997991609949565817e-01 +8.214343584919425734e-02 9.997886623366645242e-01 +8.406652885618325077e-02 9.997776182062779737e-01 +8.603464416684504512e-02 9.997660006095810958e-01 +8.804883581643464796e-02 9.997537801516380718e-01 +9.011018251665019185e-02 9.997409259704473916e-01 +9.221978823334327224e-02 9.997274056678456811e-01 +9.437878277775381408e-02 9.997131852375900074e-01 +9.658832241158703258e-02 9.996982289905500529e-01 +9.884959046625586832e-02 9.996824994769475392e-01 +1.011637979766207007e-01 9.996659574055807296e-01 +1.035321843295662070e-01 9.996485615599838281e-01 +1.059560179277615893e-01 9.996302687114730912e-01 +1.084365968689610382e-01 9.996110335290420146e-01 +1.109752496412072104e-01 9.995908084860777310e-01 +1.135733358343105209e-01 9.995695437638809633e-01 +1.162322468679852366e-01 9.995471871519853169e-01 +1.189534067370319470e-01 9.995236839452859012e-01 +1.217382727739661358e-01 9.994989768380042605e-01 +1.245883364295008178e-01 9.994730058145349094e-01 +1.275051240713013512e-01 9.994457080372397551e-01 +1.304901978014402220e-01 9.994170177312806658e-01 +1.335451562929898806e-01 9.993868660666067605e-01 +1.366716356462006621e-01 9.993551810372424127e-01 +1.398713102647238526e-01 9.993218873380533829e-01 +1.431458937523479302e-01 9.992869062392065738e-01 +1.464971398307285677e-01 9.992501554585774270e-01 +1.499268432786045602e-01 9.992115490324012805e-01 +1.534368408930012473e-01 9.991709971845164073e-01 +1.570290124729377401e-01 9.991284061945949757e-01 +1.607052818261639204e-01 9.990836782658178983e-01 +1.644676177994663646e-01 9.990367113925088249e-01 +1.683180353330956669e-01 9.989873992283134774e-01 +1.722585965398786556e-01 9.989356309555779134e-01 +1.762914118095947891e-01 9.988812911566614661e-01 +1.804186409392072588e-01 9.988242596880023694e-01 +1.846424942895543431e-01 9.987644115578406812e-01 +1.889652339691209604e-01 9.987016168086045864e-01 +1.933891750455231096e-01 9.986357404050585362e-01 +1.979166867853557332e-01 9.985666421294274731e-01 +2.025501939230667514e-01 9.984941764848151990e-01 +2.072921779595370828e-01 9.984181926083578462e-01 +2.121451784910629856e-01 9.983385341956740877e-01 +2.171117945694504281e-01 9.982550394382970760e-01 +2.221946860939523760e-01 9.981675409759077633e-01 +2.273965752357928749e-01 9.980758658653174908e-01 +2.327202478960408438e-01 9.979798355682835131e-01 +2.381685551976158166e-01 9.978792659603744619e-01 +2.437444150122220488e-01 9.977739673632349815e-01 +2.494508135230316670e-01 9.976637446027281086e-01 +2.552908068239517769e-01 9.975483970955576485e-01 +2.612675225563327874e-01 9.974277189670880395e-01 +2.673841615839946395e-01 9.973014992031848935e-01 +2.736439997074670560e-01 9.971695218389885484e-01 +2.800503894183630771e-01 9.970315661876103519e-01 +2.866067616948251850e-01 9.968874071117900248e-01 +2.933166278390043624e-01 9.967368153415827603e-01 +3.001835813575589040e-01 9.965795578411406064e-01 +3.072112998861757371e-01 9.964153982276174881e-01 +3.144035471591500319e-01 9.962440972451482857e-01 +3.217641750250737065e-01 9.960654132967341479e-01 +3.292971255097151273e-01 9.958791030366913599e-01 +3.370064329271928449e-01 9.956849220260978184e-01 +3.448962260405757929e-01 9.954826254533788443e-01 +3.529707302730650254e-01 9.952719689218241239e-01 +3.612342699709432114e-01 9.950527093054002403e-01 +3.696912707195028069e-01 9.948246056737242160e-01 +3.783462617131929107e-01 9.945874202864835034e-01 +3.872038781812555119e-01 9.943409196569327202e-01 +3.962688638701478139e-01 9.940848756833490230e-01 +4.055460735840829556e-01 9.938190668465096689e-01 +4.150404757850476578e-01 9.935432794703462633e-01 +4.247571552536898443e-01 9.932573090419519746e-01 +4.347013158125024312e-01 9.929609615860615079e-01 +4.448782831127585102e-01 9.926540550880122993e-01 +4.552935074866950038e-01 9.923364209580253226e-01 +4.659525668664681874e-01 9.920079055284416469e-01 +4.768611697714469355e-01 9.916683715743223049e-01 +4.880251583654431347e-01 9.913176998465925704e-01 +4.994505115855140120e-01 9.909557906057033794e-01 +5.111433483440167569e-01 9.905825651426192202e-01 +5.231099308056263997e-01 9.901979672728519200e-01 +5.353566677410723784e-01 9.898019647882707606e-01 +5.478901179593942405e-01 9.893945508505626041e-01 +5.607169938205458504e-01 9.889757453095212592e-01 +5.738441648302395892e-01 9.885455959288464989e-01 +5.872786613189482363e-01 9.881041795018604690e-01 +6.010276782070381740e-01 9.876516028395242452e-01 +6.150985788580500824e-01 9.871880036133986458e-01 +6.294988990221888070e-01 9.867135510367466278e-01 +6.442363508721373755e-01 9.862284463678491209e-01 +6.593188271333548789e-01 9.857329232208016379e-01 +6.747544053110693385e-01 9.852272476705832283e-01 +6.905513520162327445e-01 9.847117181410398601e-01 +7.067181273927490848e-01 9.841866650665724858e-01 +7.232633896483536828e-01 9.836524503207655368e-01 +7.401959996915644657e-01 9.831094664078784406e-01 +7.575250258771912826e-01 9.825581354160292102e-01 +7.752597488629460187e-01 9.819989077339639216e-01 +7.934096665797492065e-01 9.814322605364802499e-01 +8.119844993184013315e-01 9.808586960467884364e-01 +8.309941949353395474e-01 9.802787395872940568e-01 +8.504489341802676794e-01 9.796929374333865903e-01 +8.703591361485161215e-01 9.791018544877717611e-01 +8.907354638610439634e-01 9.785060717956002296e-01 +9.115888299750822821e-01 9.779061839230799302e-01 +9.329304026284686024e-01 9.773027962243379108e-01 +9.547716114208061322e-01 9.766965220229870681e-01 +9.771241535346496532e-01 9.760879797360993981e-01 +1.000000000000000000e+00 9.754777899690698639e-01 diff --git a/benchmarks/data/baryons_vd20_from_marcel/VD20_r200_k0.1.txt b/benchmarks/data/baryons_vd20_from_marcel/VD20_r200_k0.1.txt new file mode 100644 index 000000000..22338703e --- /dev/null +++ b/benchmarks/data/baryons_vd20_from_marcel/VD20_r200_k0.1.txt @@ -0,0 +1,110 @@ + 0.010000000 -0.61923694 + 0.020000000 -0.55763766 + 0.030000000 -0.48728581 + 0.040000000 -0.41555631 + 0.050000000 -0.34829225 + 0.060000000 -0.28883801 + 0.070000000 -0.23833645 + 0.080000000 -0.19650618 + 0.090000000 -0.16236108 + 0.10000000 -0.13469009 + 0.11000000 -0.11231532 + 0.12000000 -0.094203008 + 0.13000000 -0.079493403 + 0.14000000 -0.067492344 + 0.15000000 -0.057648360 + 0.16000000 -0.049526853 + 0.17000000 -0.042786349 + 0.18000000 -0.037158484 + 0.19000000 -0.032431860 + 0.20000000 -0.028439348 + 0.21000000 -0.025048223 + 0.22000000 -0.022152562 + 0.23000000 -0.019667381 + 0.24000000 -0.017524132 + 0.25000000 -0.015667226 + 0.26000000 -0.014051338 + 0.27000000 -0.012639322 + 0.28000000 -0.011400573 + 0.29000000 -0.010309756 + 0.30000000 -0.0093457911 + 0.31000000 -0.0084910591 + 0.32000000 -0.0077307670 + 0.33000000 -0.0070524395 + 0.34000000 -0.0064455121 + 0.35000000 -0.0059010017 + 0.36000000 -0.0054112402 + 0.37000000 -0.0049696569 + 0.38000000 -0.0045706015 + 0.39000000 -0.0042091975 + 0.40000000 -0.0038812222 + 0.41000000 -0.0035830073 + 0.42000000 -0.0033113556 + 0.43000000 -0.0030634725 + 0.44000000 -0.0028369077 + 0.45000000 -0.0026295069 + 0.46000000 -0.0024393709 + 0.47000000 -0.0022648209 + 0.48000000 -0.0021043691 + 0.49000000 -0.0019566938 + 0.50000000 -0.0018206182 + 0.51000000 -0.0016950918 + 0.52000000 -0.0015791750 + 0.53000000 -0.0014720257 + 0.54000000 -0.0013728874 + 0.55000000 -0.0012810793 + 0.56000000 -0.0011959876 + 0.57000000 -0.0011170577 + 0.58000000 -0.0010437880 + 0.59000000 -0.00097572357 + 0.60000000 -0.00091245154 + 0.61000000 -0.00085359645 + 0.62000000 -0.00079881637 + 0.63000000 -0.00074779948 + 0.64000000 -0.00070026101 + 0.65000000 -0.00065594057 + 0.66000000 -0.00061459973 + 0.67000000 -0.00057601991 + 0.68000000 -0.00054000054 + 0.69000000 -0.00050635728 + 0.70000000 -0.00047492063 + 0.71000000 -0.00044553448 + 0.72000000 -0.00041805497 + 0.73000000 -0.00039234939 + 0.74000000 -0.00036829519 + 0.75000000 -0.00034577914 + 0.76000000 -0.00032469648 + 0.77000000 -0.00030495027 + 0.78000000 -0.00028645069 + 0.79000000 -0.00026911448 + 0.80000000 -0.00025286441 + 0.81000000 -0.00023762879 + 0.82000000 -0.00022334101 + 0.83000000 -0.00020993919 + 0.84000000 -0.00019736576 + 0.85000000 -0.00018556718 + 0.86000000 -0.00017449357 + 0.87000000 -0.00016409849 + 0.88000000 -0.00015433866 + 0.89000000 -0.00014517374 + 0.90000000 -0.00013656607 + 0.91000000 -0.00012848054 + 0.92000000 -0.00012088436 + 0.93000000 -0.00011374691 + 0.94000000 -0.00010703958 + 0.95000000 -0.00010073563 + 0.96000000 -9.4810071e-05 + 0.97000000 -8.9239524e-05 + 0.98000000 -8.4002119e-05 + 0.99000000 -7.9077393e-05 + 1.0000000 -7.4446188e-05 + 1.0100000 -7.0090569e-05 + 1.0200000 -6.5993737e-05 + 1.0300000 -6.2139955e-05 + 1.0400000 -5.8514476e-05 + 1.0500000 -5.5103480e-05 + 1.0600000 -5.1894010e-05 + 1.0700000 -4.8873916e-05 + 1.0800000 -4.6031805e-05 + 1.0900000 -4.3356988e-05 + 1.1000000 -4.0839436e-05 diff --git a/benchmarks/data/baryons_vd20_from_marcel/VD20_r200_k0.5.txt b/benchmarks/data/baryons_vd20_from_marcel/VD20_r200_k0.5.txt new file mode 100644 index 000000000..411baf76a --- /dev/null +++ b/benchmarks/data/baryons_vd20_from_marcel/VD20_r200_k0.5.txt @@ -0,0 +1,110 @@ + 0.010000000 -0.63212363 + 0.020000000 -0.59640996 + 0.030000000 -0.56271404 + 0.040000000 -0.53092188 + 0.050000000 -0.50092590 + 0.060000000 -0.47262463 + 0.070000000 -0.44592233 + 0.080000000 -0.42072864 + 0.090000000 -0.39695835 + 0.10000000 -0.37453104 + 0.11000000 -0.35337081 + 0.12000000 -0.33340610 + 0.13000000 -0.31456935 + 0.14000000 -0.29679684 + 0.15000000 -0.28002844 + 0.16000000 -0.26420742 + 0.17000000 -0.24928025 + 0.18000000 -0.23519644 + 0.19000000 -0.22190833 + 0.20000000 -0.20937097 + 0.21000000 -0.19754195 + 0.22000000 -0.18638124 + 0.23000000 -0.17585109 + 0.24000000 -0.16591587 + 0.25000000 -0.15654197 + 0.26000000 -0.14769768 + 0.27000000 -0.13935306 + 0.28000000 -0.13147991 + 0.29000000 -0.12405157 + 0.30000000 -0.11704291 + 0.31000000 -0.11043023 + 0.32000000 -0.10419116 + 0.33000000 -0.098304572 + 0.34000000 -0.092750569 + 0.35000000 -0.087510356 + 0.36000000 -0.082566203 + 0.37000000 -0.077901385 + 0.38000000 -0.073500119 + 0.39000000 -0.069347516 + 0.40000000 -0.065429526 + 0.41000000 -0.061732895 + 0.42000000 -0.058245115 + 0.43000000 -0.054954388 + 0.44000000 -0.051849579 + 0.45000000 -0.048920186 + 0.46000000 -0.046156298 + 0.47000000 -0.043548564 + 0.48000000 -0.041088161 + 0.49000000 -0.038766765 + 0.50000000 -0.036576524 + 0.51000000 -0.034510027 + 0.52000000 -0.032560282 + 0.53000000 -0.030720694 + 0.54000000 -0.028985039 + 0.55000000 -0.027347445 + 0.56000000 -0.025802371 + 0.57000000 -0.024344591 + 0.58000000 -0.022969173 + 0.59000000 -0.021671462 + 0.60000000 -0.020447070 + 0.61000000 -0.019291853 + 0.62000000 -0.018201904 + 0.63000000 -0.017173534 + 0.64000000 -0.016203265 + 0.65000000 -0.015287815 + 0.66000000 -0.014424085 + 0.67000000 -0.013609154 + 0.68000000 -0.012840266 + 0.69000000 -0.012114817 + 0.70000000 -0.011430356 + 0.71000000 -0.010784564 + 0.72000000 -0.010175259 + 0.73000000 -0.0096003781 + 0.74000000 -0.0090579767 + 0.75000000 -0.0085462200 + 0.76000000 -0.0080633764 + 0.77000000 -0.0076078125 + 0.78000000 -0.0071779869 + 0.79000000 -0.0067724457 + 0.80000000 -0.0063898166 + 0.81000000 -0.0060288053 + 0.82000000 -0.0056881904 + 0.83000000 -0.0053668195 + 0.84000000 -0.0050636054 + 0.85000000 -0.0047775223 + 0.86000000 -0.0045076022 + 0.87000000 -0.0042529321 + 0.88000000 -0.0040126503 + 0.89000000 -0.0037859440 + 0.90000000 -0.0035720460 + 0.91000000 -0.0033702329 + 0.92000000 -0.0031798218 + 0.93000000 -0.0030001685 + 0.94000000 -0.0028306652 + 0.95000000 -0.0026707386 + 0.96000000 -0.0025198474 + 0.97000000 -0.0023774813 + 0.98000000 -0.0022431586 + 0.99000000 -0.0021164248 + 1.0000000 -0.0019968512 + 1.0100000 -0.0018840333 + 1.0200000 -0.0017775893 + 1.0300000 -0.0016771592 + 1.0400000 -0.0015824032 + 1.0500000 -0.0014930008 + 1.0600000 -0.0014086493 + 1.0700000 -0.0013290636 + 1.0800000 -0.0012539743 + 1.0900000 -0.0011831273 + 1.1000000 -0.0011162831 diff --git a/benchmarks/data/baryons_vd20_from_marcel/VD20_r200_k1.0.txt b/benchmarks/data/baryons_vd20_from_marcel/VD20_r200_k1.0.txt new file mode 100644 index 000000000..c3bc3a04a --- /dev/null +++ b/benchmarks/data/baryons_vd20_from_marcel/VD20_r200_k1.0.txt @@ -0,0 +1,110 @@ + 0.010000000 -0.63401840 + 0.020000000 -0.59897350 + 0.030000000 -0.56641837 + 0.040000000 -0.53617400 + 0.050000000 -0.50806573 + 0.060000000 -0.48192723 + 0.070000000 -0.45760193 + 0.080000000 -0.43494348 + 0.090000000 -0.41381574 + 0.10000000 -0.39409249 + 0.11000000 -0.37565713 + 0.12000000 -0.35840215 + 0.13000000 -0.34222873 + 0.14000000 -0.32704615 + 0.15000000 -0.31277137 + 0.16000000 -0.29932847 + 0.17000000 -0.28664818 + 0.18000000 -0.27466742 + 0.19000000 -0.26332883 + 0.20000000 -0.25258034 + 0.21000000 -0.24237475 + 0.22000000 -0.23266934 + 0.23000000 -0.22342551 + 0.24000000 -0.21460838 + 0.25000000 -0.20618655 + 0.26000000 -0.19813170 + 0.27000000 -0.19041836 + 0.28000000 -0.18302361 + 0.29000000 -0.17592686 + 0.30000000 -0.16910960 + 0.31000000 -0.16255519 + 0.32000000 -0.15624869 + 0.33000000 -0.15017663 + 0.34000000 -0.14432688 + 0.35000000 -0.13868853 + 0.36000000 -0.13325169 + 0.37000000 -0.12800742 + 0.38000000 -0.12294756 + 0.39000000 -0.11806473 + 0.40000000 -0.11335212 + 0.41000000 -0.10880352 + 0.42000000 -0.10441315 + 0.43000000 -0.10017569 + 0.44000000 -0.096086148 + 0.45000000 -0.092139863 + 0.46000000 -0.088332431 + 0.47000000 -0.084659684 + 0.48000000 -0.081117651 + 0.49000000 -0.077702534 + 0.50000000 -0.074410681 + 0.51000000 -0.071238567 + 0.52000000 -0.068182779 + 0.53000000 -0.065239998 + 0.54000000 -0.062406991 + 0.55000000 -0.059680600 + 0.56000000 -0.057057734 + 0.57000000 -0.054535361 + 0.58000000 -0.052110507 + 0.59000000 -0.049780252 + 0.60000000 -0.047541724 + 0.61000000 -0.045392099 + 0.62000000 -0.043328603 + 0.63000000 -0.041348506 + 0.64000000 -0.039449126 + 0.65000000 -0.037627828 + 0.66000000 -0.035882023 + 0.67000000 -0.034209171 + 0.68000000 -0.032606781 + 0.69000000 -0.031072410 + 0.70000000 -0.029603668 + 0.71000000 -0.028198214 + 0.72000000 -0.026853760 + 0.73000000 -0.025568071 + 0.74000000 -0.024338964 + 0.75000000 -0.023164312 + 0.76000000 -0.022042042 + 0.77000000 -0.020970135 + 0.78000000 -0.019946627 + 0.79000000 -0.018969609 + 0.80000000 -0.018037229 + 0.81000000 -0.017147688 + 0.82000000 -0.016299241 + 0.83000000 -0.015490199 + 0.84000000 -0.014718928 + 0.85000000 -0.013983843 + 0.86000000 -0.013283416 + 0.87000000 -0.012616168 + 0.88000000 -0.011980674 + 0.89000000 -0.011375557 + 0.90000000 -0.010799489 + 0.91000000 -0.010251192 + 0.92000000 -0.0097294355 + 0.93000000 -0.0092330339 + 0.94000000 -0.0087608476 + 0.95000000 -0.0083117811 + 0.96000000 -0.0078847816 + 0.97000000 -0.0074788382 + 0.98000000 -0.0070929806 + 0.99000000 -0.0067262780 + 1.0000000 -0.0063778376 + 1.0100000 -0.0060468038 + 1.0200000 -0.0057323571 + 1.0300000 -0.0054337123 + 1.0400000 -0.0051501180 + 1.0500000 -0.0048808551 + 1.0600000 -0.0046252359 + 1.0700000 -0.0043826027 + 1.0800000 -0.0041523269 + 1.0900000 -0.0039338079 + 1.1000000 -0.0037264721 diff --git a/benchmarks/data/baryons_vd20_from_marcel/VD20_r500_k0.1.txt b/benchmarks/data/baryons_vd20_from_marcel/VD20_r500_k0.1.txt new file mode 100644 index 000000000..c295ee4c0 --- /dev/null +++ b/benchmarks/data/baryons_vd20_from_marcel/VD20_r500_k0.1.txt @@ -0,0 +1,110 @@ + 0.010000000 -0.45399371 + 0.020000000 -0.40946537 + 0.030000000 -0.35925797 + 0.040000000 -0.30817316 + 0.050000000 -0.26004385 + 0.060000000 -0.21714458 + 0.070000000 -0.18034058 + 0.080000000 -0.14954413 + 0.090000000 -0.12416232 + 0.10000000 -0.10341289 + 0.11000000 -0.086505663 + 0.12000000 -0.072728389 + 0.13000000 -0.061476186 + 0.14000000 -0.052252307 + 0.15000000 -0.044656484 + 0.16000000 -0.038369490 + 0.17000000 -0.033137937 + 0.18000000 -0.028760951 + 0.19000000 -0.025079107 + 0.20000000 -0.021965548 + 0.21000000 -0.019318964 + 0.22000000 -0.017058105 + 0.23000000 -0.015117508 + 0.24000000 -0.013444170 + 0.25000000 -0.011994971 + 0.26000000 -0.010734653 + 0.27000000 -0.0096342455 + 0.28000000 -0.0086698332 + 0.29000000 -0.0078215775 + 0.30000000 -0.0070729474 + 0.31000000 -0.0064101070 + 0.32000000 -0.0058214256 + 0.33000000 -0.0052970858 + 0.34000000 -0.0048287675 + 0.35000000 -0.0044093916 + 0.36000000 -0.0040329126 + 0.37000000 -0.0036941489 + 0.38000000 -0.0033886436 + 0.39000000 -0.0031125505 + 0.40000000 -0.0028625392 + 0.41000000 -0.0026357169 + 0.42000000 -0.0024295637 + 0.43000000 -0.0022418774 + 0.44000000 -0.0020707286 + 0.45000000 -0.0019144217 + 0.46000000 -0.0017714633 + 0.47000000 -0.0016405342 + 0.48000000 -0.0015204663 + 0.49000000 -0.0014102232 + 0.50000000 -0.0013088826 + 0.51000000 -0.0012156228 + 0.52000000 -0.0011297091 + 0.53000000 -0.0010504844 + 0.54000000 -0.00097735879 + 0.55000000 -0.00090980239 + 0.56000000 -0.00084733803 + 0.57000000 -0.00078953536 + 0.58000000 -0.00073600556 + 0.59000000 -0.00068639676 + 0.60000000 -0.00064039005 + 0.61000000 -0.00059769592 + 0.62000000 -0.00055805119 + 0.63000000 -0.00052121629 + 0.64000000 -0.00048697282 + 0.65000000 -0.00045512144 + 0.66000000 -0.00042547998 + 0.67000000 -0.00039788176 + 0.68000000 -0.00037217410 + 0.69000000 -0.00034821699 + 0.70000000 -0.00032588189 + 0.71000000 -0.00030505072 + 0.72000000 -0.00028561483 + 0.73000000 -0.00026747421 + 0.74000000 -0.00025053672 + 0.75000000 -0.00023471736 + 0.76000000 -0.00021993767 + 0.77000000 -0.00020612521 + 0.78000000 -0.00019321298 + 0.79000000 -0.00018113902 + 0.80000000 -0.00016984595 + 0.81000000 -0.00015928065 + 0.82000000 -0.00014939386 + 0.83000000 -0.00014013990 + 0.84000000 -0.00013147637 + 0.85000000 -0.00012336391 + 0.86000000 -0.00011576596 + 0.87000000 -0.00010864851 + 0.88000000 -0.00010197997 + 0.89000000 -9.5730917e-05 + 0.90000000 -8.9873987e-05 + 0.91000000 -8.4383687e-05 + 0.92000000 -7.9236271e-05 + 0.93000000 -7.4409610e-05 + 0.94000000 -6.9883071e-05 + 0.95000000 -6.5637413e-05 + 0.96000000 -6.1654685e-05 + 0.97000000 -5.7918133e-05 + 0.98000000 -5.4412115e-05 + 0.99000000 -5.1122026e-05 + 1.0000000 -4.8034222e-05 + 1.0100000 -4.5135953e-05 + 1.0200000 -4.2415305e-05 + 1.0300000 -3.9861137e-05 + 1.0400000 -3.7463032e-05 + 1.0500000 -3.5211248e-05 + 1.0600000 -3.3096668e-05 + 1.0700000 -3.1110762e-05 + 1.0800000 -2.9245546e-05 + 1.0900000 -2.7493548e-05 + 1.1000000 -2.5847767e-05 diff --git a/benchmarks/data/baryons_vd20_from_marcel/VD20_r500_k0.5.txt b/benchmarks/data/baryons_vd20_from_marcel/VD20_r500_k0.5.txt new file mode 100644 index 000000000..aa249c011 --- /dev/null +++ b/benchmarks/data/baryons_vd20_from_marcel/VD20_r500_k0.5.txt @@ -0,0 +1,110 @@ + 0.010000000 -0.56518428 + 0.020000000 -0.53232579 + 0.030000000 -0.50137762 + 0.040000000 -0.47222871 + 0.050000000 -0.44477444 + 0.060000000 -0.41891630 + 0.070000000 -0.39456149 + 0.080000000 -0.37162261 + 0.090000000 -0.35001735 + 0.10000000 -0.32966816 + 0.11000000 -0.31050203 + 0.12000000 -0.29245017 + 0.13000000 -0.27544780 + 0.14000000 -0.25943392 + 0.15000000 -0.24435104 + 0.16000000 -0.23014504 + 0.17000000 -0.21676495 + 0.18000000 -0.20416275 + 0.19000000 -0.19229320 + 0.20000000 -0.18111373 + 0.21000000 -0.17058420 + 0.22000000 -0.16066684 + 0.23000000 -0.15132604 + 0.24000000 -0.14252830 + 0.25000000 -0.13424204 + 0.26000000 -0.12643753 + 0.27000000 -0.11908675 + 0.28000000 -0.11216332 + 0.29000000 -0.10564241 + 0.30000000 -0.099500609 + 0.31000000 -0.093715877 + 0.32000000 -0.088267456 + 0.33000000 -0.083135794 + 0.34000000 -0.078302474 + 0.35000000 -0.073750152 + 0.36000000 -0.069462492 + 0.37000000 -0.065424106 + 0.38000000 -0.061620502 + 0.39000000 -0.058038031 + 0.40000000 -0.054663836 + 0.41000000 -0.051485809 + 0.42000000 -0.048492545 + 0.43000000 -0.045673302 + 0.44000000 -0.043017964 + 0.45000000 -0.040517001 + 0.46000000 -0.038161437 + 0.47000000 -0.035942821 + 0.48000000 -0.033853190 + 0.49000000 -0.031885045 + 0.50000000 -0.030031323 + 0.51000000 -0.028285373 + 0.52000000 -0.026640928 + 0.53000000 -0.025092087 + 0.54000000 -0.023633292 + 0.55000000 -0.022259308 + 0.56000000 -0.020965204 + 0.57000000 -0.019746336 + 0.58000000 -0.018598331 + 0.59000000 -0.017517067 + 0.60000000 -0.016498666 + 0.61000000 -0.015539473 + 0.62000000 -0.014636044 + 0.63000000 -0.013785139 + 0.64000000 -0.012983703 + 0.65000000 -0.012228861 + 0.66000000 -0.011517904 + 0.67000000 -0.010848280 + 0.68000000 -0.010217587 + 0.69000000 -0.0096235602 + 0.70000000 -0.0090640690 + 0.71000000 -0.0085371053 + 0.72000000 -0.0080407781 + 0.73000000 -0.0075733061 + 0.74000000 -0.0071330119 + 0.75000000 -0.0067183154 + 0.76000000 -0.0063277283 + 0.77000000 -0.0059598490 + 0.78000000 -0.0056133574 + 0.79000000 -0.0052870100 + 0.80000000 -0.0049796357 + 0.81000000 -0.0046901314 + 0.82000000 -0.0044174581 + 0.83000000 -0.0041606375 + 0.84000000 -0.0039187478 + 0.85000000 -0.0036909210 + 0.86000000 -0.0034763396 + 0.87000000 -0.0032742333 + 0.88000000 -0.0030838771 + 0.89000000 -0.0029045877 + 0.90000000 -0.0027357218 + 0.91000000 -0.0025766734 + 0.92000000 -0.0024268717 + 0.93000000 -0.0022857790 + 0.94000000 -0.0021528892 + 0.95000000 -0.0020277253 + 0.96000000 -0.0019098381 + 0.97000000 -0.0017988046 + 0.98000000 -0.0016942263 + 0.99000000 -0.0015957280 + 1.0000000 -0.0015029561 + 1.0100000 -0.0014155778 + 1.0200000 -0.0013332794 + 1.0300000 -0.0012557657 + 1.0400000 -0.0011827584 + 1.0500000 -0.0011139956 + 1.0600000 -0.0010492305 + 1.0700000 -0.00098823074 + 1.0800000 -0.00093077733 + 1.0900000 -0.00087666412 + 1.1000000 -0.00082569693 diff --git a/benchmarks/data/baryons_vd20_from_marcel/VD20_r500_k1.0.txt b/benchmarks/data/baryons_vd20_from_marcel/VD20_r500_k1.0.txt new file mode 100644 index 000000000..f50f02028 --- /dev/null +++ b/benchmarks/data/baryons_vd20_from_marcel/VD20_r500_k1.0.txt @@ -0,0 +1,110 @@ + 0.010000000 -0.61767203 + 0.020000000 -0.58248259 + 0.030000000 -0.54979845 + 0.040000000 -0.51943368 + 0.050000000 -0.49120990 + 0.060000000 -0.46495900 + 0.070000000 -0.44052386 + 0.080000000 -0.41775844 + 0.090000000 -0.39652747 + 0.10000000 -0.37670600 + 0.11000000 -0.35817889 + 0.12000000 -0.34084023 + 0.13000000 -0.32459281 + 0.14000000 -0.30934750 + 0.15000000 -0.29502275 + 0.16000000 -0.28154399 + 0.17000000 -0.26884318 + 0.18000000 -0.25685827 + 0.19000000 -0.24553277 + 0.20000000 -0.23481527 + 0.21000000 -0.22465907 + 0.22000000 -0.21502175 + 0.23000000 -0.20586482 + 0.24000000 -0.19715339 + 0.25000000 -0.18885583 + 0.26000000 -0.18094349 + 0.27000000 -0.17339043 + 0.28000000 -0.16617313 + 0.29000000 -0.15927031 + 0.30000000 -0.15266267 + 0.31000000 -0.14633273 + 0.32000000 -0.14026460 + 0.33000000 -0.13444386 + 0.34000000 -0.12885739 + 0.35000000 -0.12349321 + 0.36000000 -0.11834042 + 0.37000000 -0.11338900 + 0.38000000 -0.10862979 + 0.39000000 -0.10405433 + 0.40000000 -0.099654839 + 0.41000000 -0.095424082 + 0.42000000 -0.091355349 + 0.43000000 -0.087442380 + 0.44000000 -0.083679308 + 0.45000000 -0.080060625 + 0.46000000 -0.076581129 + 0.47000000 -0.073235898 + 0.48000000 -0.070020256 + 0.49000000 -0.066929744 + 0.50000000 -0.063960097 + 0.51000000 -0.061107226 + 0.52000000 -0.058367198 + 0.53000000 -0.055736222 + 0.54000000 -0.053210636 + 0.55000000 -0.050786896 + 0.56000000 -0.048461567 + 0.57000000 -0.046231315 + 0.58000000 -0.044092898 + 0.59000000 -0.042043167 + 0.60000000 -0.040079054 + 0.61000000 -0.038197574 + 0.62000000 -0.036395819 + 0.63000000 -0.034670956 + 0.64000000 -0.033020226 + 0.65000000 -0.031440939 + 0.66000000 -0.029930478 + 0.67000000 -0.028486295 + 0.68000000 -0.027105906 + 0.69000000 -0.025786899 + 0.70000000 -0.024526926 + 0.71000000 -0.023323704 + 0.72000000 -0.022175017 + 0.73000000 -0.021078711 + 0.74000000 -0.020032698 + 0.75000000 -0.019034952 + 0.76000000 -0.018083510 + 0.77000000 -0.017176469 + 0.78000000 -0.016311990 + 0.79000000 -0.015488289 + 0.80000000 -0.014703647 + 0.81000000 -0.013956398 + 0.82000000 -0.013244937 + 0.83000000 -0.012567714 + 0.84000000 -0.011923233 + 0.85000000 -0.011310053 + 0.86000000 -0.010726787 + 0.87000000 -0.010172097 + 0.88000000 -0.0096446983 + 0.89000000 -0.0091433536 + 0.90000000 -0.0086668744 + 0.91000000 -0.0082141190 + 0.92000000 -0.0077839908 + 0.93000000 -0.0073754377 + 0.94000000 -0.0069874505 + 0.95000000 -0.0066190615 + 0.96000000 -0.0062693434 + 0.97000000 -0.0059374080 + 0.98000000 -0.0056224046 + 0.99000000 -0.0053235194 + 1.0000000 -0.0050399736 + 1.0100000 -0.0047710226 + 1.0200000 -0.0045159546 + 1.0300000 -0.0042740894 + 1.0400000 -0.0040447773 + 1.0500000 -0.0038273980 + 1.0600000 -0.0036213593 + 1.0700000 -0.0034260962 + 1.0800000 -0.0032410698 + 1.0900000 -0.0030657661 + 1.1000000 -0.0028996953 diff --git a/benchmarks/data/codes/make_baryons_vd19_benchmark.py b/benchmarks/data/codes/make_baryons_vd19_benchmark.py new file mode 100644 index 000000000..5821f29fe --- /dev/null +++ b/benchmarks/data/codes/make_baryons_vd19_benchmark.py @@ -0,0 +1,43 @@ +"""Script to make benchmark data for Van Daalen (2019) baryon model in CCL.""" + +from pathlib import Path + +import numpy as np + +import pyccl as ccl + +# This file is in benchmarks/data/codes/, so parent is benchmarks/data/ +HERE = Path(__file__).resolve() +DATADIR = HERE.parent.parent + +# Same-ish cosmology as other baryon benchmarks +cosmo = ccl.Cosmology( + Omega_c=0.25, + Omega_b=0.05, + h=0.7, + A_s=2.2e-9, + n_s=0.96, + Neff=3.046, + mass_split="normal", + m_nu=0.0, + Omega_g=0.0, + Omega_k=0.0, + w0=-1.0, + wa=0.0, +) + +baryons_500c = ccl.BaryonsvanDaalen19(fbar=0.7, mass_def="500c") + +# Define k and a +k_hmpc = np.logspace(-2, 0, 200) # 0.01–1 h/Mpc +a = 1.0 + +# Convert to 1/Mpc for the model +k_1mpc = k_hmpc * cosmo["h"] + +fk_500c = baryons_500c.boost_factor(cosmo, k_1mpc, a) +data_500c = np.column_stack([k_hmpc, fk_500c]) + +out_500c = DATADIR / "baryons_vd19_fk_500c.txt" +np.savetxt(out_500c, data_500c) +print("Wrote", out_500c) diff --git a/benchmarks/test_baccoemu_baryons.py b/benchmarks/test_baccoemu_baryons.py deleted file mode 100644 index b8fac74c0..000000000 --- a/benchmarks/test_baccoemu_baryons.py +++ /dev/null @@ -1,58 +0,0 @@ -import numpy as np -import pyccl as ccl - -BEMBAR_TOLERANCE = 1e-3 - - -def test_baccoemu_baryons(): - baryons = ccl.BaryonsBaccoemu() - cosmo = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - sigma8=0.83, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0) - - data = np.loadtxt("./benchmarks/data/baccoemu_baryons_fk.txt") - - k = data[:, 0] * cosmo['h'] - fk = data[:, 1] - a = 1 - - cclfk = baryons.boost_factor(cosmo, k, a) - err = np.abs(fk / cclfk - 1) - assert np.allclose(err, 0, atol=BEMBAR_TOLERANCE, rtol=0) - - -def test_baccoemu_baryons_A_s(): - baryons = ccl.BaryonsBaccoemu() - cosmo = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - A_s=2.2194e-9, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0) - - data = np.loadtxt("./benchmarks/data/baccoemu_baryons_fk.txt") - - k = data[:, 0] * cosmo['h'] - fk = data[:, 1] - a = 1 - - cclfk = baryons.boost_factor(cosmo, k, a) - err = np.abs(fk / cclfk - 1) - assert np.allclose(err, 0, atol=BEMBAR_TOLERANCE, rtol=0) diff --git a/benchmarks/test_baccoemu_linear.py b/benchmarks/test_baccoemu_linear.py deleted file mode 100644 index 1af2e9831..000000000 --- a/benchmarks/test_baccoemu_linear.py +++ /dev/null @@ -1,70 +0,0 @@ -import numpy as np -import pyccl as ccl - -BEMULIN_TOLERANCE = 1e-3 - - -def test_baccoemu_linear(): - bemu = ccl.BaccoemuLinear() - cosmo = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - sigma8=0.83, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0, - transfer_function=bemu) - - data = np.loadtxt("./benchmarks/data/baccoemu_linear.txt") - - k = data[:, 0] * cosmo['h'] - pk = data[:, 1] / cosmo['h']**3 - a = 1 - - linpk = cosmo.get_linear_power() - err = np.abs(pk / linpk(k, a) - 1) - assert np.allclose(err, 0, atol=BEMULIN_TOLERANCE, rtol=0) - - ktest, pktest = bemu.get_pk_at_a(cosmo, 1.0) - pktest = np.exp(np.interp(np.log(k), np.log(ktest), np.log(pktest))) - err = np.abs(pktest / pk - 1) - assert np.allclose(err, 0, atol=BEMULIN_TOLERANCE, rtol=0) - - -def test_baccoemu_linear_A_s(): - bemu = ccl.BaccoemuLinear() - cosmo = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - A_s=2.2194e-9, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0, - transfer_function=bemu) - - data = np.loadtxt("./benchmarks/data/baccoemu_linear.txt") - - k = data[:, 0] * cosmo['h'] - pk = data[:, 1] / cosmo['h']**3 - a = 1 - - linpk = cosmo.get_linear_power() - err = np.abs(pk / linpk(k, a) - 1) - assert np.allclose(err, 0, atol=BEMULIN_TOLERANCE, rtol=0) - - ktest, pktest = bemu.get_pk_at_a(cosmo, 1.0) - pktest = np.exp(np.interp(np.log(k), np.log(ktest), np.log(pktest))) - err = np.abs(pktest / pk - 1) - assert np.allclose(err, 0, atol=BEMULIN_TOLERANCE, rtol=0) diff --git a/benchmarks/test_baccoemu_nonlinear.py b/benchmarks/test_baccoemu_nonlinear.py deleted file mode 100644 index 74bdf242e..000000000 --- a/benchmarks/test_baccoemu_nonlinear.py +++ /dev/null @@ -1,70 +0,0 @@ -import numpy as np -import pyccl as ccl - -BEMUNL_TOLERANCE = 5e-3 - - -def test_baccoemu_nonlinear(): - bemu = ccl.BaccoemuNonlinear() - cosmo = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - sigma8=0.83, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0, - matter_power_spectrum=bemu) - - data = np.loadtxt("./benchmarks/data/baccoemu_nonlinear.txt") - - k = data[:, 0] * cosmo['h'] - pk = data[:, 1] / cosmo['h']**3 - a = 1 - - nlpk = cosmo.get_nonlin_power() - err = np.abs(pk / nlpk(k, a) - 1) - assert np.allclose(err, 0, atol=BEMUNL_TOLERANCE, rtol=0) - - ktest, pktest = bemu.get_pk_at_a(cosmo, 1.0) - pktest = np.exp(np.interp(np.log(k), np.log(ktest), np.log(pktest))) - err = np.abs(pktest / pk - 1) - assert np.allclose(err, 0, atol=BEMUNL_TOLERANCE, rtol=0) - - -def test_baccoemu_nonlinear_A_s(): - bemu = ccl.BaccoemuNonlinear() - cosmo = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - A_s=2.2194e-9, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0, - matter_power_spectrum=bemu) - - data = np.loadtxt("./benchmarks/data/baccoemu_nonlinear.txt") - - k = data[:, 0] * cosmo['h'] - pk = data[:, 1] / cosmo['h']**3 - a = 1 - - nlpk = cosmo.get_nonlin_power() - err = np.abs(pk / nlpk(k, a) - 1) - assert np.allclose(err, 0, atol=BEMUNL_TOLERANCE, rtol=0) - - ktest, pktest = bemu.get_pk_at_a(cosmo, 1.0) - pktest = np.exp(np.interp(np.log(k), np.log(ktest), np.log(pktest))) - err = np.abs(pktest / pk - 1) - assert np.allclose(err, 0, atol=BEMUNL_TOLERANCE, rtol=0) diff --git a/benchmarks/test_baryons_arico21_benchmark.py b/benchmarks/test_baryons_arico21_benchmark.py new file mode 100644 index 000000000..091b4de22 --- /dev/null +++ b/benchmarks/test_baryons_arico21_benchmark.py @@ -0,0 +1,68 @@ +"""Benchmark tests for the Arico21 BACCOemu baryonic correction model.""" + +from pathlib import Path + +import numpy as np + +import pyccl as ccl + +DATA_PATH = Path(__file__).parent / "data" / "baccoemu_baryons_fk.txt" +DATA = np.loadtxt(DATA_PATH) + +BEMBAR_TOLERANCE = 1e-3 + + +def _check_baccoemu_baryons( + cosmo: ccl.Cosmology, + baryons: ccl.BaryonsBaccoemu +) -> None: + """Checks that the BACCOemu boost factor matches the reference fk(k).""" + k = DATA[:, 0] * cosmo["h"] + fk_ref = DATA[:, 1] + a = 1.0 + + fk_ccl = baryons.boost_factor(cosmo, k, a) + err = np.abs(fk_ref / fk_ccl - 1.0) + np.testing.assert_allclose(err, 0.0, atol=BEMBAR_TOLERANCE, rtol=0.0) + + +def test_baccoemu_baryons_sigma8(): + """Tests that BACCOemu baryons match the reference for sigma8 cosmology.""" + baryons = ccl.BaryonsBaccoemu() + cosmo = ccl.Cosmology( + Omega_c=0.27, + Omega_b=0.05, + h=0.67, + sigma8=0.83, + n_s=0.96, + Neff=3.046, + mass_split="normal", + m_nu=0.1, + Omega_g=0.0, + Omega_k=0.0, + w0=-1.0, + wa=0.0, + ) + + _check_baccoemu_baryons(cosmo, baryons) + + +def test_baccoemu_baryons_a_s(): + """Tests that BACCOemu baryons match reference fk(k) for As cosmology.""" + baryons = ccl.BaryonsBaccoemu() + cosmo = ccl.Cosmology( + Omega_c=0.27, + Omega_b=0.05, + h=0.67, + A_s=2.2194e-9, + n_s=0.96, + Neff=3.046, + mass_split="normal", + m_nu=0.1, + Omega_g=0.0, + Omega_k=0.0, + w0=-1.0, + wa=0.0, + ) + + _check_baccoemu_baryons(cosmo, baryons) diff --git a/benchmarks/test_baryons_arico21_lin_benchmark.py b/benchmarks/test_baryons_arico21_lin_benchmark.py new file mode 100644 index 000000000..e0dfec29a --- /dev/null +++ b/benchmarks/test_baryons_arico21_lin_benchmark.py @@ -0,0 +1,77 @@ +"""Benchmark tests for the Baccoemu linear transfer function.""" + +from pathlib import Path + +import numpy as np + +import pyccl as ccl + +DATA_PATH = Path(__file__).parent / "data" / "baccoemu_linear.txt" +DATA = np.loadtxt(DATA_PATH) + +BEMULIN_TOLERANCE = 1e-3 + + +def _check_baccoemu_linear( + cosmo: ccl.Cosmology, + bemu: ccl.BaccoemuLinear +) -> None: + """Checks that BACCOemu baryons match the reference fk(k).""" + k = DATA[:, 0] * cosmo["h"] + pk = DATA[:, 1] / cosmo["h"] ** 3 + a = 1.0 + + # 1) Cosmology linear power vs reference + linpk = cosmo.get_linear_power() + err = np.abs(pk / linpk(k, a) - 1.0) + np.testing.assert_allclose(err, 0.0, atol=BEMULIN_TOLERANCE, rtol=0.0) + + # 2) Emulator helper vs reference + ktest, pktest = bemu.get_pk_at_a(cosmo, a) + pktest = np.exp(np.interp(np.log(k), np.log(ktest), np.log(pktest))) + err = np.abs(pktest / pk - 1.0) + np.testing.assert_allclose(err, 0.0, atol=BEMULIN_TOLERANCE, rtol=0.0) + + +def test_baccoemu_linear_sigma8(): + """Checks that BACCOemu linear T(k) matches the sigma8 reference.""" + bemu = ccl.BaccoemuLinear() + cosmo = ccl.Cosmology( + Omega_c=0.27, + Omega_b=0.05, + h=0.67, + sigma8=0.83, + n_s=0.96, + Neff=3.046, + mass_split="normal", + m_nu=0.1, + Omega_g=0.0, + Omega_k=0.0, + w0=-1.0, + wa=0.0, + transfer_function=bemu, + ) + + _check_baccoemu_linear(cosmo, bemu) + + +def test_baccoemu_linear_A_s(): + """Checks that BACCOemu linear T(k) matches the A_s reference.""" + bemu = ccl.BaccoemuLinear() + cosmo = ccl.Cosmology( + Omega_c=0.27, + Omega_b=0.05, + h=0.67, + A_s=2.2194e-9, + n_s=0.96, + Neff=3.046, + mass_split="normal", + m_nu=0.1, + Omega_g=0.0, + Omega_k=0.0, + w0=-1.0, + wa=0.0, + transfer_function=bemu, + ) + + _check_baccoemu_linear(cosmo, bemu) diff --git a/benchmarks/test_baryons_arico21_nlin_benchmark.py b/benchmarks/test_baryons_arico21_nlin_benchmark.py new file mode 100644 index 000000000..f5ad3f261 --- /dev/null +++ b/benchmarks/test_baryons_arico21_nlin_benchmark.py @@ -0,0 +1,77 @@ +"""Benchmark tests for the BACCOemu nonlinear matter power spectrum.""" + +from pathlib import Path + +import numpy as np + +import pyccl as ccl + +DATA_PATH = Path(__file__).parent / "data" / "baccoemu_nonlinear.txt" +DATA = np.loadtxt(DATA_PATH) + +BEMUNL_TOLERANCE = 5e-3 + + +def _check_baccoemu_nonlinear( + cosmo: ccl.Cosmology, + bemu: ccl.BaccoemuNonlinear +) -> None: + """Checks that BACCOemu baryons match the reference fk(k).""" + k = DATA[:, 0] * cosmo["h"] + pk_ref = DATA[:, 1] / cosmo["h"] ** 3 + a = 1.0 + + # 1) Cosmology nonlinear power vs reference + nlpk = cosmo.get_nonlin_power() + err = np.abs(pk_ref / nlpk(k, a) - 1.0) + np.testing.assert_allclose(err, 0.0, atol=BEMUNL_TOLERANCE, rtol=0.0) + + # 2) Emulator helper vs reference + ktest, pktest = bemu.get_pk_at_a(cosmo, a) + pktest = np.exp(np.interp(np.log(k), np.log(ktest), np.log(pktest))) + err = np.abs(pktest / pk_ref - 1.0) + np.testing.assert_allclose(err, 0.0, atol=BEMUNL_TOLERANCE, rtol=0.0) + + +def test_baccoemu_nonlinear_sigma8(): + """Checks that BACCOemu nonlinear P(k) matches the sigma8 reference.""" + bemu = ccl.BaccoemuNonlinear() + cosmo = ccl.Cosmology( + Omega_c=0.27, + Omega_b=0.05, + h=0.67, + sigma8=0.83, + n_s=0.96, + Neff=3.046, + mass_split="normal", + m_nu=0.1, + Omega_g=0.0, + Omega_k=0.0, + w0=-1.0, + wa=0.0, + matter_power_spectrum=bemu, + ) + + _check_baccoemu_nonlinear(cosmo, bemu) + + +def test_baccoemu_nonlinear_a_s(): + """Checks that BACCOemu nonlinear P(k) matches the sigma8 reference.""" + bemu = ccl.BaccoemuNonlinear() + cosmo = ccl.Cosmology( + Omega_c=0.27, + Omega_b=0.05, + h=0.67, + A_s=2.2194e-9, + n_s=0.96, + Neff=3.046, + mass_split="normal", + m_nu=0.1, + Omega_g=0.0, + Omega_k=0.0, + w0=-1.0, + wa=0.0, + matter_power_spectrum=bemu, + ) + + _check_baccoemu_nonlinear(cosmo, bemu) diff --git a/benchmarks/test_baryons_schneider15_benchmark.py b/benchmarks/test_baryons_schneider15_benchmark.py new file mode 100644 index 000000000..8e97182ea --- /dev/null +++ b/benchmarks/test_baryons_schneider15_benchmark.py @@ -0,0 +1,54 @@ +"""Benchmark tests for the Schneider2015 baryonic correction model.""" + +from pathlib import Path + +import numpy as np + +import pyccl as ccl + + +BCM_TOLERANCE = 1e-4 + +DATA_WITH_BAR_PATH = Path(__file__).parent / "data" / "w_baryonspk_nl.dat" +DATA_NO_BAR_PATH = Path(__file__).parent / "data" / "wo_baryonspk_nl.dat" + +DATA_WITH_BAR = np.loadtxt(DATA_WITH_BAR_PATH) +DATA_NO_BAR = np.loadtxt(DATA_NO_BAR_PATH) + + +def test_bcm(): + """Tests that the Schneider15 model matches the reference fk(k).""" + cosmo = ccl.Cosmology( + Omega_c=0.25, + Omega_b=0.05, + h=0.7, + A_s=2.2e-9, + n_s=0.96, + Neff=3.046, + mass_split="normal", + m_nu=0.0, + Omega_g=0.0, + Omega_k=0.0, + w0=-1.0, + wa=0.0, + ) + + k = DATA_WITH_BAR[:, 0] * cosmo["h"] + a = 1.0 + + bar = ccl.BaryonsSchneider15(log10Mc=14.0) + + # 1) Direct boost-factor comparison + fbcm = bar.boost_factor(cosmo, k, a) + ratio_ref = DATA_WITH_BAR[:, 1] / DATA_NO_BAR[:, 1] + err = np.abs(ratio_ref / fbcm - 1.0) + np.testing.assert_allclose(err, 0.0, atol=BCM_TOLERANCE, rtol=0.0) + + # 2) Full P(k) with and without baryons + cosmo.compute_nonlin_power() + pk_nobar = cosmo.get_nonlin_power() + pk_wbar = bar.include_baryonic_effects(cosmo, pk_nobar) + + ratio = pk_wbar(k, a) / pk_nobar(k, a) + err = np.abs(ratio_ref / ratio - 1.0) + np.testing.assert_allclose(err, 0.0, atol=BCM_TOLERANCE, rtol=0.0) diff --git a/benchmarks/test_baryons_vandaalen19_benchmark.py b/benchmarks/test_baryons_vandaalen19_benchmark.py new file mode 100644 index 000000000..5b69bca11 --- /dev/null +++ b/benchmarks/test_baryons_vandaalen19_benchmark.py @@ -0,0 +1,128 @@ +r"""Benchmark: CCL van Daalen 2019 model vs Marcel's fbar tables. + +Each file in benchmarks/data/baryons_vd20_from_marcel has the form + + VD20_rXXX_kY.txt + +where: + - rXXX encodes the mass definition: + r500 -> 500c + r200 -> 200c + - kY encodes a fixed wavenumber in h/Mpc, e.g. k0.1, k0.5, k1.0 + +The file contents are two columns: + + col0: fbar = \bar{f}_{bar,Rcrit}(10^{14} M_\odot) / (\Omega_b / \Omega_m) + col1: ΔP/P = (P_vD − P_DMO) / P_DMO + +i.e. the *fractional change* in the power spectrum at the given k and mass +definition, as a function of the baryon fraction parameter fbar. +DMO is dark matter only (no baryons). + +CCL's BaryonsvanDaalen19 implements the analytic model of van Daalen+2019, +which provides the ratio + + ratio(k, fbar) = P_{\rm vD} / P_{\rm DMO} + +so the corresponding fractional change is + + DeltaP_over_P = ratio - 1. + +This benchmark checks that CCL reproduces Marcel's tables for all six +(k, mass_def) combinations. + +Note +---- +The VD20_rXXX_kY.txt tables were obtained by (Niko Šarčević +directly from Marcel van Daalen on December 1st 2025 via personal +correspondence, and are used here as an external validation target for +the BaryonsvanDaalen19 implementation. +""" + +from pathlib import Path + +import pytest + +import numpy as np + +import pyccl as ccl + +DATA_DIR = Path(__file__).parent / "data" / "baryons_vd20_from_marcel" + +# Relative tol for DeltaP/P +VD19_FBAR_RTOL = 5e-3 # 0.5% + + +def _make_cosmo() -> ccl.Cosmology: + """Creates a pyccl Cosmology object used for the test. + + The van Daalen+19 model is cosmology-independent except for the + conversion between k [1/Mpc] and k [h/Mpc], so a Vanilla LCDM + cosmology is sufficient here. + """ + return ccl.CosmologyVanillaLCDM() + + +def _parse_meta(stem: str) -> tuple[str, float]: + """Parses mass_def and k[h/Mpc] from filename stem. + + Example stems: + "VD20_r500_k0.1" + "VD20_r200_k1.0" + """ + parts = stem.split("_") + if len(parts) != 3: + raise ValueError(f"Unexpected filename stem format: {stem!r}") + + r_part = parts[1] # e.g. "r500" or "r200" + k_part = parts[2] # e.g. "k0.1" + + if r_part == "r500": + mass_def = "500c" + elif r_part == "r200": + mass_def = "200c" + else: + raise ValueError(f"Cannot infer mass_def from stem {stem!r}") + + if not k_part.startswith("k"): + raise ValueError(f"Cannot parse k from stem {stem!r}") + k_hmpc = float(k_part[1:]) # strip leading 'k' + + return mass_def, k_hmpc + + +@pytest.mark.parametrize("path", sorted(DATA_DIR.glob("VD20_r*.txt"))) +def test_vd19_against_marcel_fbar_tables(path: Path) -> None: + """Compares CCL van Daalen19 deltaP/P to Marcel's tables.""" + cosmo = _make_cosmo() + mass_def, k_hmpc = _parse_meta(path.stem) + + # Load fbar and fractional change: DeltaP/P_DMO + fbar_tab, delta_tab = np.loadtxt(path, unpack=True) + + # Make sure fbar is sorted (just in case smth weird in the files) + order = np.argsort(fbar_tab) + fbar_tab = fbar_tab[order] + delta_tab = delta_tab[order] + + # CCL instance with correct mass definition; we'll vary fbar per point + vd = ccl.baryons.BaryonsvanDaalen19(mass_def=mass_def) + + # Now we convert k from h/Mpc to 1/Mpc for CCL; internal formula uses k/h + k = k_hmpc * cosmo["h"] + a = 1.0 # z = 0 + + # Evaluate CCL model at each fbar in the table + delta_ccl = np.empty_like(delta_tab) + for i, fbar in enumerate(fbar_tab): + vd.update_parameters(fbar=fbar) + ratio = vd.boost_factor(cosmo, k, a) # P_vD / P_DMO + delta_ccl[i] = ratio - 1.0 # (P_vD - P_DMO) / P_DMO + + # Compare fractional changes + np.testing.assert_allclose( + delta_ccl, + delta_tab, + rtol=VD19_FBAR_RTOL, + atol=0.0, + ) diff --git a/benchmarks/test_baryons_vandaalen19_regression.py b/benchmarks/test_baryons_vandaalen19_regression.py new file mode 100644 index 000000000..80149d0c9 --- /dev/null +++ b/benchmarks/test_baryons_vandaalen19_regression.py @@ -0,0 +1,65 @@ +"""Regression test for the van Daalen+2019 baryonic model. + +The reference data in ``baryons_vd19_fk_500c.txt`` were generated once using +``benchmarks/data/codes/make_baryons_vd19_benchmark.py`` with the same +cosmology and BaryonsvanDaalen19 configuration. This is a frozen regression +target (not an external benchmark) intended to catch unintended changes in +the implementation or numerical settings. +""" + +from pathlib import Path + +import numpy as np + +import pyccl as ccl + + +VD19_REGRESSION_TOLERANCE = 1e-8 + +DATA_PATH = Path(__file__).parent / "data" / "baryons_vd19_fk_500c.txt" +DATA = np.loadtxt(DATA_PATH) + + +def _make_cosmo() -> ccl.Cosmology: + """Cosmology used to generate the vd19 regression reference file.""" + return ccl.Cosmology( + Omega_c=0.25, + Omega_b=0.05, + h=0.7, + A_s=2.2e-9, + n_s=0.96, + Neff=3.046, + mass_split="normal", + m_nu=0.0, + Omega_g=0.0, + Omega_k=0.0, + w0=-1.0, + wa=0.0, + ) + + +def _check_vd19_baryons( + cosmo: ccl.Cosmology, + baryons: ccl.BaryonsvanDaalen19 +) -> None: + """Checks that the vd19 boost factor matches the frozen regression data.""" + # First column is k in h/Mpc, second is boost factor f(k) + k_hmpc = DATA[:, 0] + fk_ref = DATA[:, 1] + a = 1.0 + + # Convert to 1/Mpc for the model: k = k_hmpc * h + k = k_hmpc * cosmo["h"] + + fk_ccl = baryons.boost_factor(cosmo, k, a) + err = np.abs(fk_ref / fk_ccl - 1.0) + np.testing.assert_allclose( + err, 0.0, atol=VD19_REGRESSION_TOLERANCE, rtol=0.0 + ) + + +def test_baryons_vd19_500c(): + """Tests that the vd19 baryonic model is stable for the 500c config.""" + cosmo = _make_cosmo() + baryons = ccl.BaryonsvanDaalen19(fbar=0.7, mass_def="500c") + _check_vd19_baryons(cosmo, baryons) diff --git a/benchmarks/test_bcm.py b/benchmarks/test_bcm.py deleted file mode 100644 index 6e1e23f2b..000000000 --- a/benchmarks/test_bcm.py +++ /dev/null @@ -1,38 +0,0 @@ -import numpy as np -import pyccl as ccl - -BCM_TOLERANCE = 1e-4 - - -def test_bcm(): - cosmo = ccl.Cosmology( - Omega_c=0.25, - Omega_b=0.05, - h=0.7, - A_s=2.2e-9, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.0, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0) - - data = np.loadtxt("./benchmarks/data/w_baryonspk_nl.dat") - data_nobar = np.loadtxt("./benchmarks/data/wo_baryonspk_nl.dat") - - k = data[:, 0] * cosmo['h'] - a = 1 - - bar = ccl.BaryonsSchneider15(log10Mc=14.) - fbcm = bar.boost_factor(cosmo, k, a) - err = np.abs(data[:, 1]/data_nobar[:, 1]/fbcm - 1) - assert np.allclose(err, 0, atol=BCM_TOLERANCE, rtol=0) - - cosmo.compute_nonlin_power() - pk_nobar = cosmo.get_nonlin_power() - pk_wbar = bar.include_baryonic_effects(cosmo, pk_nobar) - ratio = pk_wbar(k, a)/pk_nobar(k, a) - err = np.abs(data[:, 1]/data_nobar[:, 1]/ratio - 1) - assert np.allclose(err, 0, atol=BCM_TOLERANCE, rtol=0) diff --git a/pyccl/tests/test_baccoemu.py b/pyccl/tests/test_baccoemu.py deleted file mode 100644 index 3b7cd7977..000000000 --- a/pyccl/tests/test_baccoemu.py +++ /dev/null @@ -1,162 +0,0 @@ -import numpy as np -import pyccl as ccl - -import pytest - -BEMULIN_TOLERANCE = 1e-3 -BEMUNL_TOLERANCE = 5e-3 -BEMBAR_TOLERANCE = 1e-3 - - -def test_baccoemu_linear_As_sigma8(): - bemu = ccl.BaccoemuLinear() - cosmo1 = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - sigma8=0.83, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0) - - cosmo2 = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - A_s=2.2194e-09, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0) - - k1, pk1 = bemu.get_pk_at_a(cosmo1, 1.0) - k2, pk2 = bemu.get_pk_at_a(cosmo2, 1.0) - - err = np.abs(pk1 / pk2 - 1) - assert np.allclose(err, 0, atol=BEMULIN_TOLERANCE, rtol=0) - - -def test_baccoemu_nonlinear_As_sigma8(): - bemu = ccl.BaccoemuNonlinear() - cosmo1 = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - sigma8=0.83, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0) - - cosmo2 = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - A_s=2.2194e-09, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0) - - k1, pk1 = bemu.get_pk_at_a(cosmo1, 1.0) - k2, pk2 = bemu.get_pk_at_a(cosmo2, 1.0) - - err = np.abs(pk1 / pk2 - 1) - assert np.allclose(err, 0, atol=BEMUNL_TOLERANCE, rtol=0) - - -def test_baccoemu_baryons_boost(): - baryons = ccl.BaryonsBaccoemu() - nlpkemu = ccl.BaccoemuNonlinear() - cosmo = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - sigma8=0.83, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0, - matter_power_spectrum=nlpkemu) - - k = np.logspace(-2, 0.5, 100) - cclfk = baryons.boost_factor(cosmo, k, 1) - pk_gro = cosmo.get_nonlin_power() - pk_bcm = baryons.include_baryonic_effects(cosmo, pk_gro) - fk = pk_bcm(k, 1) / pk_gro(k, 1) - err = np.abs(fk / cclfk - 1) - assert np.allclose(err, 0, atol=BEMBAR_TOLERANCE, rtol=0) - - -def test_baccoemu_baryons_changepars(): - baryons = ccl.BaryonsBaccoemu() - baryons.update_parameters(log10_M_c=12.7, log10_eta=-0.4) - assert ((baryons.bcm_params['M_c'] == 12.7) - & (baryons.bcm_params['eta'] == -0.4)) - - -def test_baccoemu_baryons_a_range(): - baryons = ccl.BaryonsBaccoemu() - cosmo = ccl.CosmologyVanillaLCDM() - k = 1e-1 - with pytest.raises(ValueError): - baryons.boost_factor(cosmo, k, baryons.a_min * 0.9) - - -def test_baccoemu_baryons_As_sigma8(): - baryons = ccl.BaryonsBaccoemu() - cosmo1 = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - sigma8=0.83, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0) - - cosmo2 = ccl.Cosmology( - Omega_c=0.27, - Omega_b=0.05, - h=0.67, - A_s=2.2194e-09, - n_s=0.96, - Neff=3.046, - mass_split='normal', - m_nu=0.1, - Omega_g=0, - Omega_k=0, - w0=-1, - wa=0) - - k = np.logspace(-2, 0.5, 100) - fk1 = baryons.boost_factor(cosmo1, k, 1) - fk2 = baryons.boost_factor(cosmo2, k, 1) - - err = np.abs(fk1 / fk2 - 1) - assert np.allclose(err, 0, atol=BEMUNL_TOLERANCE, rtol=0) diff --git a/pyccl/tests/test_baryons.py b/pyccl/tests/test_baryons.py deleted file mode 100644 index 20034c5ff..000000000 --- a/pyccl/tests/test_baryons.py +++ /dev/null @@ -1,67 +0,0 @@ -import numpy as np -import pyccl as ccl -import pytest - - -COSMO = ccl.CosmologyVanillaLCDM(transfer_function='bbks') -bar = ccl.BaryonsSchneider15() - - -@pytest.mark.parametrize('k', [ - 1, - 1.0, - [0.3, 0.5, 10], - np.array([0.3, 0.5, 10])]) -def test_bcm_smoke(k): - a = 0.8 - fka = bar.boost_factor(COSMO, k, a) - assert np.all(np.isfinite(fka)) - assert np.shape(fka) == np.shape(k) - - -def test_bcm_correct_smoke(): - k_arr = np.geomspace(1E-2, 1, 10) - fka = bar.boost_factor(COSMO, k_arr, 0.5) - pk_nobar = ccl.nonlin_matter_power(COSMO, k_arr, 0.5) - pkb = bar.include_baryonic_effects( - COSMO, COSMO.get_nonlin_power()) - pk_wbar = pkb(k_arr, 0.5) - assert np.all(np.fabs(pk_wbar/(pk_nobar*fka)-1) < 1E-5) - - -def test_bcm_update_params(): - bar2 = ccl.BaryonsSchneider15(log10Mc=14.1, eta_b=0.7, k_s=40.) - bar2.update_parameters(log10Mc=bar.log10Mc, - eta_b=bar.eta_b, - k_s=bar.k_s) - assert bar == bar2 - - -def test_baryons_from_name(): - bar2 = ccl.Baryons.from_name('Schneider15') - assert bar.name == bar2.name - assert bar2.name == 'Schneider15' - - -def test_baryons_in_cosmology(): - # Test that applying baryons during cosmology creation works. - # 1. Outside of cosmo - cosmo_nb = ccl.CosmologyVanillaLCDM( - transfer_function='bbks', baryonic_effects=None) - pk_nb = cosmo_nb.get_nonlin_power() - pk_wb = bar.include_baryonic_effects(cosmo_nb, pk_nb) - # 2. In cosmo - from object. - cosmo_wb2 = ccl.CosmologyVanillaLCDM( - transfer_function='bbks', baryonic_effects=bar) - pk_wb2 = cosmo_wb2.get_nonlin_power() - - ks = np.geomspace(1E-2, 10, 128) - pk_wb = pk_wb(ks, 1.0) - pk_wb2 = pk_wb2(ks, 1.0) - - assert np.allclose(pk_wb, pk_wb2, atol=0, rtol=1E-6) - - -def test_baryons_in_cosmology_error(): - with pytest.raises(ValueError): - ccl.CosmologyVanillaLCDM(baryonic_effects=3.1416) diff --git a/pyccl/tests/test_baryons_arico21.py b/pyccl/tests/test_baryons_arico21.py new file mode 100644 index 000000000..20b4fb6a9 --- /dev/null +++ b/pyccl/tests/test_baryons_arico21.py @@ -0,0 +1,170 @@ +"""Unit tests for the BACCO-based baryonic correction model in CCL.""" + +from __future__ import annotations + +import pytest + +import numpy as np + +import pyccl as ccl + + +BEMULIN_TOLERANCE = 1e-3 +BEMUNL_TOLERANCE = 5e-3 +BEMBAR_TOLERANCE = 1e-3 + + +def _bacco_cosmo(**extra_kwargs): + """Returns a BACCO-compatible cosmology, allowing overrides.""" + base = dict( + Omega_c=0.27, + Omega_b=0.05, + h=0.67, + sigma8=0.83, + n_s=0.96, + Neff=3.046, + mass_split="normal", + m_nu=0.1, + Omega_g=0, + Omega_k=0, + w0=-1, + wa=0, + ) + base.update(extra_kwargs) + return ccl.Cosmology(**base) + + +@pytest.mark.parametrize( + "k_in", + [ + np.array([0.01]), + np.array([0.01, 0.1, 1.0]), + np.logspace(-2, 0.5, 5), + ], +) +def test_bacco_baryons_boost_smoke(k_in): + """Tests that boost_factor runs and returns finite values.""" + baryons = ccl.BaryonsBaccoemu() + cosmo = _bacco_cosmo() + a = 1.0 + + fk = baryons.boost_factor(cosmo, k_in, a) + assert np.all(np.isfinite(fk)) + assert np.shape(fk) == np.shape(k_in) + + +def test_bacco_baryons_boost_vs_include(): + """Tests that boost_factor and include_baryonic_effects are consistent.""" + baryons = ccl.BaryonsBaccoemu() + nlpkemu = ccl.BaccoemuNonlinear() + + cosmo = ccl.Cosmology( + Omega_c=0.27, + Omega_b=0.05, + h=0.67, + sigma8=0.83, + n_s=0.96, + Neff=3.046, + mass_split="normal", + m_nu=0.1, + Omega_g=0, + Omega_k=0, + w0=-1, + wa=0, + matter_power_spectrum=nlpkemu, + ) + + k = np.logspace(-2, 0.5, 100) + a = 1.0 + + fk_boost = baryons.boost_factor(cosmo, k, a) + + pk_dmo = cosmo.get_nonlin_power() + pk_bary = baryons.include_baryonic_effects(cosmo, pk_dmo) + fk_ratio = pk_bary(k, a) / pk_dmo(k, a) + + err = np.abs(fk_ratio / fk_boost - 1.0) + assert np.allclose(err, 0.0, atol=BEMBAR_TOLERANCE, rtol=0.0) + + +def test_bacco_baryons_update_params(): + """Tests that update_parameters correctly updates bcm_params.""" + baryons = ccl.BaryonsBaccoemu() + baryons.update_parameters(log10_M_c=12.7, log10_eta=-0.4) + assert baryons.bcm_params["M_c"] == 12.7 + assert baryons.bcm_params["eta"] == -0.4 + + +def test_bacco_baryons_a_range(): + """Tests that boost_factor raises outside valid a-range.""" + baryons = ccl.BaryonsBaccoemu() + cosmo = ccl.CosmologyVanillaLCDM() + k = 1e-1 + + with pytest.raises(ValueError): + baryons.boost_factor(cosmo, k, baryons.a_min * 0.9) + + +def test_bacco_baryons_as_sigma8(): + """Tests that boost_factor is consistent for A_s and sigma8 cosmologies.""" + baryons = ccl.BaryonsBaccoemu() + + cosmo1 = _bacco_cosmo() + cosmo2 = ccl.Cosmology( + Omega_c=0.27, + Omega_b=0.05, + h=0.67, + A_s=2.2194e-09, + n_s=0.96, + Neff=3.046, + mass_split="normal", + m_nu=0.1, + Omega_g=0, + Omega_k=0, + w0=-1, + wa=0, + ) + + k = np.logspace(-2, 0.5, 100) + a = 1.0 + + fk1 = baryons.boost_factor(cosmo1, k, a) + fk2 = baryons.boost_factor(cosmo2, k, a) + + err = np.abs(fk1 / fk2 - 1.0) + assert np.allclose(err, 0.0, atol=BEMUNL_TOLERANCE, rtol=0.0) + + +def test_bacco_baryons_include_returns_pk2d(): + """Tests that include_baryonic_effects returns a Pk2D object.""" + baryons = ccl.BaryonsBaccoemu() + cosmo = _bacco_cosmo() + + # Restrict a-grid to the emulator's valid range [a_min, 1] + a_min = float(baryons.a_min) + a_arr = np.linspace(a_min, 1.0, 5) + lk_arr = np.linspace(np.log(1e-3), np.log(1.0), 10) + + # Simple baseline P(k, a) = 1 everywhere on this grid + pk_arr = np.ones((a_arr.size, lk_arr.size)) + + pk_dmo = ccl.Pk2D( + a_arr=a_arr, + lk_arr=lk_arr, + pk_arr=pk_arr, + is_logp=False, + extrap_order_lok=1, + extrap_order_hik=1, + ) + + pk_bary = baryons.include_baryonic_effects(cosmo, pk_dmo) + assert isinstance(pk_bary, ccl.Pk2D) + + +def test_bacco_baryons_in_cosmology_raises_outside_a_range(): + """Tests that get_nonlin_power raises if baryons are included.""" + baryons = ccl.BaryonsBaccoemu() + cosmo_wb = _bacco_cosmo(baryonic_effects=baryons) + + with pytest.raises(ValueError): + cosmo_wb.get_nonlin_power() diff --git a/pyccl/tests/test_baryons_base.py b/pyccl/tests/test_baryons_base.py new file mode 100644 index 000000000..05474033d --- /dev/null +++ b/pyccl/tests/test_baryons_base.py @@ -0,0 +1,67 @@ +"""Tests for the base Baryons class API.""" + +from __future__ import annotations + +import pytest + +import pyccl as ccl +from pyccl.baryons import Baryons + + +class _DummyBaryons(Baryons): + """A dummy subclass of Baryons for testing.""" + + # CCLNamedClass expects subclasses to have a name + name = "DummyBaryons" + + def __init__(self): + """Initializes the base class and a list to record calls.""" + self.calls: list[tuple[object, object]] = [] + + def _include_baryonic_effects(self, cosmo, pk): + """Records the inputs and returns the pk unchanged.""" + self.calls.append((cosmo, pk)) + return pk + + +def test_baryons_is_abstract(): + """Tests that Baryons cannot be instantiated directly.""" + with pytest.raises(TypeError, match="abstract"): + Baryons() # type: ignore[abstract] + + +def test_include_baryonic_effects_delegates_to_impl(): + """Tests that include_baryonic_effects calls the subclass method.""" + cosmo = ccl.CosmologyVanillaLCDM() + pk = cosmo.get_nonlin_power() + + bar = _DummyBaryons() + pk_out = bar.include_baryonic_effects(cosmo, pk) + + # Retruned object is whatever the subclass returns + assert pk_out is pk + + # And the subclass saw exactly the inputs we passed in + assert len(bar.calls) == 1 + call_cosmo, call_pk = bar.calls[0] + assert call_cosmo is cosmo + assert call_pk is pk + + +class _NoneBaryons(Baryons): + """A subclass of Baryons that returns None.""" + name = "NoneBaryons" + + def _include_baryonic_effects(self, cosmo, pk): + """A helper that returns None.""" + return None + + +def test_include_baryonic_effects_allows_none(): + """Tests that include_baryonic_effects can return None.""" + cosmo = ccl.CosmologyVanillaLCDM() + pk = cosmo.get_nonlin_power() + + bar = _NoneBaryons() + pk_out = bar.include_baryonic_effects(cosmo, pk) + assert pk_out is None diff --git a/pyccl/tests/test_baryons_mead20.py b/pyccl/tests/test_baryons_mead20.py new file mode 100644 index 000000000..acf7f9bde --- /dev/null +++ b/pyccl/tests/test_baryons_mead20.py @@ -0,0 +1,133 @@ +"""Tests for HMCode/Mead2020 nonlinear P(k) with baryonic feedback.""" + +import pytest + +import numpy as np + +import pyccl as ccl + + +camb = pytest.importorskip("camb") + +TOL_MEAD20 = 3e-5 + + +def _compute_camb_mead2020_pk( + logT_AGN=7.93, + Omega_c=0.25, + Omega_b=0.05, + A_s=2.1e-9, + n_s=0.97, + h=0.7, + T_CMB=2.7255, +): + """Returns k, z, P_nl(k,z) from CAMB with Mead2020 baryons.""" + p = camb.CAMBparams( + WantTransfer=True, + NonLinearModel=camb.nonlinear.Halofit( + halofit_version="mead2020_feedback", + HMCode_logT_AGN=logT_AGN, + ), + ) + # This affects k_min + p.WantCls = False + p.DoLensing = False + p.Want_CMB = False + p.Want_CMB_lensing = False + p.Want_cl_2D_array = False + + p.set_cosmology( + H0=h * 100, + omch2=Omega_c * h**2, + ombh2=Omega_b * h**2, + mnu=0.0, + TCMB=T_CMB, + ) + p.share_delta_neff = False + p.InitPower.set_params(As=A_s, ns=n_s) + + zs = [0.0, 0.5, 1.0, 1.5] + p.set_matter_power(redshifts=zs, kmax=10.0, nonlinear=True) + p.set_for_lmax(5000) + + results = camb.get_results(p) + k, z_out, pk_nl = results.get_nonlinear_matter_power_spectrum( + hubble_units=False, k_hunit=False + ) + return k, z_out, pk_nl + + +def _make_ccl_mead2020_cosmo( + logT_AGN=7.93, + Omega_c=0.25, + Omega_b=0.05, + A_s=2.1e-9, + n_s=0.97, + h=0.7, +): + """Returns a CCL Cosmology using CAMB+Mead2020_feedback+HMCode.""" + extras = { + "camb": { + "halofit_version": "mead2020_feedback", + "HMCode_logT_AGN": logT_AGN, + } + } + return ccl.Cosmology( + Omega_c=Omega_c, + Omega_b=Omega_b, + h=h, + m_nu=0.0, + A_s=A_s, + n_s=n_s, + transfer_function="boltzmann_camb", + matter_power_spectrum="camb", + extra_parameters=extras, + ) + + +def test_baryons_mead20_hmcode_matches_camb(): + """Tests that CCL's CAMB HMCode Mead2020 matches CAMB's output.""" + k, zs, pk_camb_all = _compute_camb_mead2020_pk() + cosmo_ccl = _make_ccl_mead2020_cosmo() + + for z_val, pk_camb in zip(zs, pk_camb_all): + a = 1.0 / (1.0 + z_val) + pk_ccl = ccl.nonlin_matter_power(cosmo_ccl, k, a) + np.testing.assert_allclose(pk_camb, pk_ccl, rtol=TOL_MEAD20) + + +def test_baryons_mead20_pk_responds_to_logt_agn(): + """Tests that changing logT_AGN changes the matter power spectrum.""" + cosmo_lo = _make_ccl_mead2020_cosmo(logT_AGN=7.0) + cosmo_hi = _make_ccl_mead2020_cosmo(logT_AGN=8.3) + + a = 1.0 + k = np.logspace(-2, 1, 50) # 0.01–10 1/Mpc + + pk_lo = ccl.nonlin_matter_power(cosmo_lo, k, a) + pk_hi = ccl.nonlin_matter_power(cosmo_hi, k, a) + + ratio = pk_hi / pk_lo + + assert np.all(np.isfinite(ratio)) + assert np.any(np.abs(ratio - 1.0) > 1e-3) + + +def test_baryons_mead20_cls_finite(): + """Tests that angular C_ells can be computed with Mead2020 baryons.""" + cosmo = _make_ccl_mead2020_cosmo() + z = np.linspace(0.0, 2.0, 50) + nz = z**2 * np.exp(-0.5 * ((z - 1.0) / 0.3) ** 2) + tr = ccl.WeakLensingTracer(cosmo, dndz=(z, nz)) + ells = np.geomspace(10, 1000, 20) + cl = ccl.angular_cl(cosmo, tr, tr, ells) + assert np.all(np.isfinite(cl)) + + +def test_baryons_mead20_invalid_combo_raises(): + """Tests that invalid (trf, mps) combo raises CCLError.""" + with pytest.raises(ccl.CCLError): + ccl.CosmologyVanillaLCDM( + transfer_function="boltzmann_class", + matter_power_spectrum="camb", + ) diff --git a/pyccl/tests/test_baryons_schneider15.py b/pyccl/tests/test_baryons_schneider15.py new file mode 100644 index 000000000..fdfb29724 --- /dev/null +++ b/pyccl/tests/test_baryons_schneider15.py @@ -0,0 +1,105 @@ +"""Unit tests for the Schneider15 baryonic correction model in CCL.""" + +from __future__ import annotations + +import pytest + +import numpy as np + +import pyccl as ccl + + +COSMO = ccl.CosmologyVanillaLCDM(transfer_function="bbks") +bar = ccl.BaryonsSchneider15() + + +@pytest.mark.parametrize( + "k", + [ + 1, + 1.0, + [0.3, 0.5, 10], + np.array([0.3, 0.5, 10]), + ], +) +def test_bcm_smoke(k): + """Tests that boost_factor runs and returns finite values.""" + a = 0.8 + fka = bar.boost_factor(COSMO, k, a) + assert np.all(np.isfinite(fka)) + assert np.shape(fka) == np.shape(k) + + +def test_bcm_correct_smoke(): + """Tests that include_baryonic_effects matches boost_factor application.""" + k_arr = np.geomspace(1e-2, 1.0, 10) + a = 0.5 + fka = bar.boost_factor(COSMO, k_arr, a) + pk_nobar = ccl.nonlin_matter_power(COSMO, k_arr, a) + + pkb = bar.include_baryonic_effects(COSMO, COSMO.get_nonlin_power()) + pk_wbar = pkb(k_arr, a) + + np.testing.assert_allclose(pk_wbar, pk_nobar * fka, rtol=1e-6, atol=0.0) + + +def test_bcm_update_params(): + """Tests that updating parameters works correctly.""" + bar2 = ccl.BaryonsSchneider15(log10Mc=14.1, eta_b=0.7, k_s=40.0) + bar2.update_parameters( + log10Mc=bar.log10Mc, + eta_b=bar.eta_b, + k_s=bar.k_s, + ) + assert bar == bar2 + + +def test_baryons_from_name(): + """Tests that from_name('Schneider15') works correctly.""" + bar2 = ccl.Baryons.from_name("Schneider15") + assert bar.name == bar2.name + assert bar2.name == "Schneider15" + + +def test_baryons_in_cosmology(): + """Test that baryonic effects are consistent via two methods.""" + # 1. Apply baryons outside the cosmology + cosmo_nb = ccl.CosmologyVanillaLCDM( + transfer_function="bbks", + baryonic_effects=None, + ) + pk_nb = cosmo_nb.get_nonlin_power() + pk_wb = bar.include_baryonic_effects(cosmo_nb, pk_nb) + + # 2. Apply baryons via Cosmology(baryonic_effects=...) + cosmo_wb2 = ccl.CosmologyVanillaLCDM( + transfer_function="bbks", + baryonic_effects=bar, + ) + pk_wb2 = cosmo_wb2.get_nonlin_power() + + ks = np.geomspace(1e-2, 10.0, 128) + pk_wb = pk_wb(ks, 1.0) + pk_wb2 = pk_wb2(ks, 1.0) + + np.testing.assert_allclose(pk_wb, pk_wb2, rtol=1e-6, atol=0.0) + + +def test_baryons_in_cosmology_error(): + """Test that passing invalid baryonic_effects raises ValueError.""" + with pytest.raises(ValueError): + ccl.CosmologyVanillaLCDM(baryonic_effects=3.1416) + + +def test_bcm_include_baryonic_effects_returns_pk2d(): + """Tests that include_baryonic_effects returns a Pk2D object.""" + pk_nb = COSMO.get_nonlin_power() + pk_wb = bar.include_baryonic_effects(COSMO, pk_nb) + assert isinstance(pk_wb, ccl.Pk2D) + + +def test_baryons_from_name_type(): + """Test that from_name returns the correct class type.""" + bar_cls = ccl.Baryons.from_name("Schneider15") + assert issubclass(bar_cls, ccl.Baryons) + assert bar_cls.name == "Schneider15" diff --git a/pyccl/tests/test_baryons_vandaalen19.py b/pyccl/tests/test_baryons_vandaalen19.py new file mode 100644 index 000000000..c2ce50c1d --- /dev/null +++ b/pyccl/tests/test_baryons_vandaalen19.py @@ -0,0 +1,144 @@ +"""Unit tests for the Van Daalen et al. 2019 baryonic effects model in CCL.""" + +from __future__ import annotations + +import pytest + +import numpy as np + +import pyccl as ccl + + +# Set tolerances +BOOST_TOLERANCE = 1e-5 + +# Set up cosmology and k,a values +cosmo = ccl.CosmologyVanillaLCDM() +k = 0.5*cosmo['h'] +a = 1. + +# Set up power without baryons +pk2D_no_baryons = cosmo.get_nonlin_power() + +# Set up fbarc and mass definition vectors +fbarcvec = np.linspace(0.25, 1, 20) +mdef_vec = ['500c', '200c'] + + +def compare_boost(): + """Compares boost factor to expected values from Van Daalen+19.""" + vdboost = [] + vdboost_expect = [] + + pk_nl = pk2D_no_baryons(k, a) + + for mdef in mdef_vec: + for f in fbarcvec: + # Takes ftilde as argument + vd19 = ccl.BaryonsvanDaalen19(fbar=f, mass_def=mdef) + pk2D_with_baryons = vd19.include_baryonic_effects( + cosmo, pk2D_no_baryons) + # Takes k in units of 1/Mpc as argument + pk_nl_bar = pk2D_with_baryons(k, a) + vdboost.append(pk_nl_bar/pk_nl-1) + if mdef == '500c': + vdboost_expect.append(-np.exp(-5.99*f-0.5107)) + else: + vdboost_expect.append(-np.exp(-5.816*f-0.4005)) + + assert np.allclose( + vdboost, vdboost_expect, atol=1e-5, rtol=BOOST_TOLERANCE) + + +def test_boost_model(): + """Tests that the boost factor matches Van Daalen+19 results.""" + compare_boost() + + +def test_baryons_from_name(): + """Tests that from_name('vanDaalen19') works correctly.""" + baryons = ccl.BaryonsvanDaalen19(fbar=0.7, mass_def='500c') + bar2 = ccl.Baryons.from_name('vanDaalen19') + + assert baryons.name == bar2.name + assert baryons.name == 'vanDaalen19' + + +def test_baryons_vd19_raises(): + """Tests that invalid parameters raise ValueError.""" + with pytest.raises(ValueError): + ccl.BaryonsvanDaalen19(fbar=0.7, mass_def='blah') + + b = ccl.BaryonsvanDaalen19(fbar=0.7, mass_def='500c') + + with pytest.raises(ValueError): + b.update_parameters(mass_def='blah') + + +def test_update_params(): + """Tests that updating parameters works correctly.""" + b = ccl.BaryonsvanDaalen19(fbar=0.7, mass_def='500c') + b.update_parameters(fbar=0.6, mass_def='200c') + + assert b.mass_def == '200c' + assert b.fbar == 0.6 + + +@pytest.mark.parametrize( + "k_in", + [ + 0.5 * cosmo["h"], # scalar + [0.1 * cosmo["h"], 0.5 * cosmo["h"], 1.0 * cosmo["h"]], + np.array([0.1, 0.5, 1.0]) * cosmo["h"], + ], +) +def test_vd19_boost_smoke(k_in): + """Tests that boost_factor runs and returns finite values.""" + bar = ccl.BaryonsvanDaalen19(fbar=0.7, mass_def="500c") + fka = bar.boost_factor(cosmo, k_in, a) + assert np.all(np.isfinite(fka)) + assert np.shape(fka) == np.shape(k_in) + + +def test_vd19_include_baryonic_effects_returns_pk2d(): + """Tests that include_baryonic_effects returns a Pk2D instance.""" + bar = ccl.BaryonsvanDaalen19(fbar=0.7, mass_def="500c") + pk_nb = cosmo.get_nonlin_power() + pk_wb = bar.include_baryonic_effects(cosmo, pk_nb) + assert isinstance(pk_wb, ccl.Pk2D) + + +def test_vd19_baryons_in_cosmology(): + """Tests that baryonic effects are consistent via two methods.""" + bar = ccl.BaryonsvanDaalen19(fbar=0.7, mass_def="500c") + + cosmo_nb = ccl.Cosmology( + Omega_c=0.27, + Omega_b=0.045, + h=0.67, + sigma8=0.8, + n_s=0.96, + transfer_function="eisenstein_hu", + baryonic_effects=None, + ) + pk_nb = cosmo_nb.get_nonlin_power() + pk_wb = bar.include_baryonic_effects(cosmo_nb, pk_nb) + + cosmo_wb = ccl.Cosmology( + Omega_c=0.27, + Omega_b=0.045, + h=0.67, + sigma8=0.8, + n_s=0.96, + transfer_function="eisenstein_hu", + baryonic_effects=bar, + ) + pk_wb2 = cosmo_wb.get_nonlin_power() + + ks = np.geomspace(1e-2, 10.0, 64) + np.testing.assert_allclose( + pk_wb(ks, a), + pk_wb2(ks, a), + rtol=1e-6, + atol=0.0, + ) diff --git a/pyccl/tests/test_baryons_vd19.py b/pyccl/tests/test_baryons_vd19.py deleted file mode 100644 index 7aca69b16..000000000 --- a/pyccl/tests/test_baryons_vd19.py +++ /dev/null @@ -1,66 +0,0 @@ -import numpy as np -import pyccl as ccl -import pytest - -# Set tolerances -BOOST_TOLERANCE = 1e-5 - -# Set up the cosmological parameters to be used -cosmo = ccl.Cosmology(Omega_c=0.27, Omega_b=0.045, h=0.67, - sigma8=0.8, n_s=0.96, - transfer_function='eisenstein_hu') -k = 0.5*cosmo['h'] -a = 1. - -# Set up power without baryons -pk2D_no_baryons = cosmo.get_nonlin_power() - -fbarcvec = np.linspace(0.25, 1, 20) -mdef_vec = ['500c', '200c'] - - -def compare_boost(): - vdboost = [] - vdboost_expect = [] - pk_nl = pk2D_no_baryons(k, a) - for mdef in mdef_vec: - for f in fbarcvec: - # Takes ftilde as argument - vD19 = ccl.BaryonsvanDaalen19(fbar=f, mass_def=mdef) - pk2D_with_baryons = vD19.include_baryonic_effects( - cosmo, pk2D_no_baryons) - # Takes k in units of 1/Mpc as argument - pk_nl_bar = pk2D_with_baryons(k, a) - vdboost.append(pk_nl_bar/pk_nl-1) - if mdef == '500c': - vdboost_expect.append(-np.exp(-5.99*f-0.5107)) - else: - vdboost_expect.append(-np.exp(-5.816*f-0.4005)) - assert np.allclose( - vdboost, vdboost_expect, atol=1e-5, rtol=BOOST_TOLERANCE) - - -def test_boost_model(): - compare_boost() - - -def test_baryons_from_name(): - baryons = ccl.BaryonsvanDaalen19(fbar=0.7, mass_def='500c') - bar2 = ccl.Baryons.from_name('vanDaalen19') - assert baryons.name == bar2.name - assert baryons.name == 'vanDaalen19' - - -def test_baryons_vd19_raises(): - with pytest.raises(ValueError): - ccl.BaryonsvanDaalen19(fbar=0.7, mass_def='blah') - b = ccl.BaryonsvanDaalen19(fbar=0.7, mass_def='500c') - with pytest.raises(ValueError): - b.update_parameters(mass_def='blah') - - -def test_update_params(): - b = ccl.BaryonsvanDaalen19(fbar=0.7, mass_def='500c') - b.update_parameters(fbar=0.6, mass_def='200c') - assert b.mass_def == '200c' - assert b.fbar == 0.6 diff --git a/pyccl/tests/test_cells_baryons.py b/pyccl/tests/test_cells_baryons.py new file mode 100644 index 000000000..e14004040 --- /dev/null +++ b/pyccl/tests/test_cells_baryons.py @@ -0,0 +1,214 @@ +"""Tests for propagating baryonic correction models into C_ells.""" + +from __future__ import annotations + +import pytest + +import numpy as np + +import pyccl as ccl + + +BASE_COSMO = ccl.CosmologyVanillaLCDM() +Z = np.linspace(0.0, 2.0, 200) +NZ = Z**2 * np.exp(-0.5 * ((Z - 1.0) / 0.3) ** 2) # simple dN/dz +BZ = np.ones_like(Z) # simple constant bias for clustering +ELLS = np.geomspace(10.0, 2000.0, 64) # ell values for Cls + + +def _make_tracers(cosmo: ccl.Cosmology): + """Returns WL and NC tracers for a given cosmology.""" + tracer_wl = ccl.WeakLensingTracer(cosmo, dndz=(Z, NZ)) + tracer_gg = ccl.NumberCountsTracer( + cosmo, has_rsd=False, dndz=(Z, NZ), bias=(Z, BZ) + ) + return tracer_wl, tracer_gg + + +def _build_cosmo_from_pk(pk2d: ccl.Pk2D) -> ccl.CosmologyCalculator: + """Builds a CosmologyCalculator using pk2d as the nonlinear P(k).""" + a_arr, lk_arr, pk_arr = pk2d.get_spline_arrays() + pk_nonlin = { + "a": a_arr, + "k": np.exp(lk_arr), + "delta_matter:delta_matter": pk_arr, + } + + cosmo_calc = ccl.CosmologyCalculator( + Omega_c=BASE_COSMO["Omega_c"], + Omega_b=BASE_COSMO["Omega_b"], + h=BASE_COSMO["h"], + n_s=BASE_COSMO["n_s"], + sigma8=BASE_COSMO["sigma8"], + pk_nonlin=pk_nonlin, + ) + cosmo_calc.compute_growth() + return cosmo_calc + + +@pytest.mark.parametrize( + "baryon_model", + [ + ccl.BaryonsSchneider15(log10Mc=14.0), + ccl.BaryonsvanDaalen19(fbar=0.7, mass_def="500c"), + ], +) +def test_cells_baryons_consistent_with_pk(baryon_model): + """Tests that two routes to Cls with baryons agree for 3x2pt probes. + + Route 1: use pk_bar directly as p_of_k_a. + Route 2: build a CosmologyCalculator that uses pk_bar as pk_nonlin. + """ + BASE_COSMO.compute_nonlin_power() + pk_dmo = BASE_COSMO.get_nonlin_power() + + # Apply baryons to get baryon-modified P(k) + pk_bar = baryon_model.include_baryonic_effects(BASE_COSMO, pk_dmo) + + # Tracers for BASE_COSMO + wl_base, gg_base = _make_tracers(BASE_COSMO) + + # Route 1: use pk_bar directly as p_of_k_a + cl_bar_mm_direct = ccl.angular_cl( + BASE_COSMO, wl_base, wl_base, ELLS, p_of_k_a=pk_bar + ) + cl_bar_gg_direct = ccl.angular_cl( + BASE_COSMO, gg_base, gg_base, ELLS, p_of_k_a=pk_bar + ) + cl_bar_gm_direct = ccl.angular_cl( + BASE_COSMO, gg_base, wl_base, ELLS, p_of_k_a=pk_bar + ) + + # Route 2: build a CosmologyCalculator that uses pk_bar as pk_nonlin + cosmo_calc = _build_cosmo_from_pk(pk_bar) + wl_calc, gg_calc = _make_tracers(cosmo_calc) + + cl_bar_mm_calc = ccl.angular_cl(cosmo_calc, wl_calc, wl_calc, ELLS) + cl_bar_gg_calc = ccl.angular_cl(cosmo_calc, gg_calc, gg_calc, ELLS) + cl_bar_gm_calc = ccl.angular_cl(cosmo_calc, gg_calc, wl_calc, ELLS) + + np.testing.assert_allclose( + cl_bar_mm_calc, cl_bar_mm_direct, rtol=1e-4, atol=0.0) + np.testing.assert_allclose( + cl_bar_gg_calc, cl_bar_gg_direct, rtol=1e-4, atol=0.0) + np.testing.assert_allclose( + cl_bar_gm_calc, cl_bar_gm_direct, rtol=1e-4, atol=0.0) + + +@pytest.mark.parametrize( + "baryon_model", + [ + ccl.BaryonsSchneider15(log10Mc=14.0), + ccl.BaryonsvanDaalen19(fbar=0.7, mass_def="500c"), + ], +) +def test_cells_baryons_modify_cls(baryon_model): + """Tests that baryonic effects modify LL, GG, and GL angular Cls.""" + BASE_COSMO.compute_nonlin_power() + pk_dmo = BASE_COSMO.get_nonlin_power() + pk_bar = baryon_model.include_baryonic_effects(BASE_COSMO, pk_dmo) + + wl_base, gg_base = _make_tracers(BASE_COSMO) + + cl_dmo_mm = ccl.angular_cl( + BASE_COSMO, wl_base, wl_base, ELLS, p_of_k_a=pk_dmo) + cl_bar_mm = ccl.angular_cl( + BASE_COSMO, wl_base, wl_base, ELLS, p_of_k_a=pk_bar) + + cl_dmo_gg = ccl.angular_cl( + BASE_COSMO, gg_base, gg_base, ELLS, p_of_k_a=pk_dmo) + cl_bar_gg = ccl.angular_cl( + BASE_COSMO, gg_base, gg_base, ELLS, p_of_k_a=pk_bar) + + cl_dmo_gm = ccl.angular_cl( + BASE_COSMO, gg_base, wl_base, ELLS, p_of_k_a=pk_dmo) + cl_bar_gm = ccl.angular_cl( + BASE_COSMO, gg_base, wl_base, ELLS, p_of_k_a=pk_bar) + + for cl_dmo, cl_bar in [(cl_dmo_mm, cl_bar_mm), + (cl_dmo_gg, cl_bar_gg), + (cl_dmo_gm, cl_bar_gm)]: + ratio = cl_bar / cl_dmo + assert np.all(np.isfinite(ratio)) + assert np.any(np.abs(ratio - 1.0) > 1e-3) + + +def _make_ccl_mead2020_cosmo(logT_AGN: float = 7.93) -> ccl.Cosmology: + """Creates a CCL Cosmology using CAMB with Mead2020+HMCode baryons.""" + extras = { + "camb": { + "halofit_version": "mead2020_feedback", + "HMCode_logT_AGN": logT_AGN, + } + } + return ccl.Cosmology( + Omega_c=0.25, + Omega_b=0.05, + h=0.7, + m_nu=0.0, + A_s=2.1e-9, + n_s=0.97, + transfer_function="boltzmann_camb", + matter_power_spectrum="camb", + extra_parameters=extras, + ) + + +def test_cells_mead20_cls_finite(): + """Tests that angular Cls are finite for 3x2pt probes.""" + cosmo = _make_ccl_mead2020_cosmo() + z = np.linspace(0.0, 2.0, 100) + nz = z**2 * np.exp(-0.5 * ((z - 1.0) / 0.3) ** 2) + bz = np.ones_like(z) + + tracer_wl = ccl.WeakLensingTracer(cosmo, dndz=(z, nz)) + tracer_gg = ccl.NumberCountsTracer( + cosmo, has_rsd=False, dndz=(z, nz), bias=(z, bz) + ) + ells = np.geomspace(10.0, 1000.0, 32) + + cl_mm = ccl.angular_cl(cosmo, tracer_wl, tracer_wl, ells) + cl_gg = ccl.angular_cl(cosmo, tracer_gg, tracer_gg, ells) + cl_gm = ccl.angular_cl(cosmo, tracer_gg, tracer_wl, ells) + + assert np.all(np.isfinite(cl_mm)) + assert np.all(np.isfinite(cl_gg)) + assert np.all(np.isfinite(cl_gm)) + + +def test_cells_mead20_cls_respond_to_logT_AGN(): + """Tests that changing logT_AGN changes mm, gg, and gm angular Cls.""" + cosmo_lo = _make_ccl_mead2020_cosmo(logT_AGN=7.0) + cosmo_hi = _make_ccl_mead2020_cosmo(logT_AGN=8.3) + + z = np.linspace(0.0, 2.0, 100) + nz = z**2 * np.exp(-0.5 * ((z - 1.0) / 0.3) ** 2) + bz = np.ones_like(z) + + tracer_wl_lo = ccl.WeakLensingTracer(cosmo_lo, dndz=(z, nz)) + tracer_wl_hi = ccl.WeakLensingTracer(cosmo_hi, dndz=(z, nz)) + + tracer_gg_lo = ccl.NumberCountsTracer( + cosmo_lo, has_rsd=False, dndz=(z, nz), bias=(z, bz) + ) + tracer_gg_hi = ccl.NumberCountsTracer( + cosmo_hi, has_rsd=False, dndz=(z, nz), bias=(z, bz) + ) + + ells = np.geomspace(10.0, 1000.0, 32) + + cl_mm_lo = ccl.angular_cl(cosmo_lo, tracer_wl_lo, tracer_wl_lo, ells) + cl_mm_hi = ccl.angular_cl(cosmo_hi, tracer_wl_hi, tracer_wl_hi, ells) + + cl_gg_lo = ccl.angular_cl(cosmo_lo, tracer_gg_lo, tracer_gg_lo, ells) + cl_gg_hi = ccl.angular_cl(cosmo_hi, tracer_gg_hi, tracer_gg_hi, ells) + + cl_gm_lo = ccl.angular_cl(cosmo_lo, tracer_gg_lo, tracer_wl_lo, ells) + cl_gm_hi = ccl.angular_cl(cosmo_hi, tracer_gg_hi, tracer_wl_hi, ells) + + for cl_lo, cl_hi in [(cl_mm_lo, cl_mm_hi), + (cl_gg_lo, cl_gg_hi), + (cl_gm_lo, cl_gm_hi)]: + ratio = cl_hi / cl_lo + assert np.all(np.isfinite(ratio)) + assert np.any(np.abs(ratio - 1.0) > 1e-3)