diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 79d87125..f91f9fb6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -38,7 +38,7 @@ repos: hooks: - id: detect-secrets args: [ "--baseline", ".secrets.baseline" ] - exclude: package.lock.json + exclude: ^(package\.lock\.json|docs/tutorials/data/multisignal_he/) #### # Typos - repo: https://github.com/crate-ci/typos diff --git a/docs/tutorials/.gitignore b/docs/tutorials/.gitignore index bc25cb69..909fcf0e 100644 --- a/docs/tutorials/.gitignore +++ b/docs/tutorials/.gitignore @@ -8,3 +8,9 @@ _compiled *.ipynb *.py *.md +!data/ +!data/multisignal_he/ +!data/multisignal_he/README.md +!data/multisignal_he/*.csv +!data/multisignal_he/*.json +!data/multisignal_he/*.npz diff --git a/docs/tutorials/.pages b/docs/tutorials/.pages index fd693b8d..78eeb285 100644 --- a/docs/tutorials/.pages +++ b/docs/tutorials/.pages @@ -8,3 +8,4 @@ nav: - right_truncation.md - day_of_week_effects.md - ascertainment.md + - multisignal_H_E_model.md diff --git a/docs/tutorials/ascertainment.qmd b/docs/tutorials/ascertainment.qmd index f9abaa74..62aea650 100644 --- a/docs/tutorials/ascertainment.qmd +++ b/docs/tutorials/ascertainment.qmd @@ -99,8 +99,13 @@ independent_iedr = dist.Beta(2, 98).sample(key_iedr, (n_draws,)) ## Model-level ascertainment -To share ascertainment structure across count signals, define an ascertainment model once and register it with the builder. -Each observation process receives the appropriate signal-specific accessor from `for_signal()`. +To share ascertainment structure across count signals, define an `AscertainmentModel` object and register it with the builder. +Each observation process receives the appropriate signal-specific accessor via the object's `for_signal()` method. + +All all `AscertainmentModel` objects are specified with arguments `name` which identified this component in larger multisignal model and `signals` which is a list of unique signal names. + +The `JointAscertainment` model is the joint prior for scalar ascertainment rates across multiple signals. +It samples from a logit multivariate normal vector given natural-scale baseline ascertainment rates and a covariance structure on the logit scale which can be specified either as a lower-triangular scale matrix, a covariance matrix, or a precision matrix. ```python builder = PyrenewBuilder() diff --git a/docs/tutorials/building_multisignal_models.qmd b/docs/tutorials/building_multisignal_models.qmd index 7490b9e4..c39d3381 100644 --- a/docs/tutorials/building_multisignal_models.qmd +++ b/docs/tutorials/building_multisignal_models.qmd @@ -4,6 +4,8 @@ format: gfm: code-fold: true engine: jupyter +execute: + eval: false jupyter: jupytext: text_representation: diff --git a/docs/tutorials/data/multisignal_he/README.md b/docs/tutorials/data/multisignal_he/README.md new file mode 100644 index 00000000..ad03da06 --- /dev/null +++ b/docs/tutorials/data/multisignal_he/README.md @@ -0,0 +1,13 @@ +# Multisignal H+E tutorial artifacts + +This directory stores precomputed fit artifacts for `docs/tutorials/multisignal_H_E_model.qmd`. + +Regenerate the artifacts from the repository root with: + +```bash +uv run python docs_scripts/generate_multisignal_he_artifacts.py +``` + +The generator must be run on a machine that can fit the PyRenew tutorial models, including the linked-ascertainment variant, and the custom NumPyro H+E model. +The documentation build reads the generated `npz`, `csv`, and `json` files from this directory instead of running the fits during Quarto rendering. +The custom-H-E artifacts include reduced scalar draws and latent infection draws for plotting posterior infection uncertainty. diff --git a/docs/tutorials/data/multisignal_he/custom_he_fit_artifacts.npz b/docs/tutorials/data/multisignal_he/custom_he_fit_artifacts.npz new file mode 100644 index 00000000..990d3e9d Binary files /dev/null and b/docs/tutorials/data/multisignal_he/custom_he_fit_artifacts.npz differ diff --git a/docs/tutorials/data/multisignal_he/custom_he_scalar_draws.csv b/docs/tutorials/data/multisignal_he/custom_he_scalar_draws.csv new file mode 100644 index 00000000..c4804efc --- /dev/null +++ b/docs/tutorials/data/multisignal_he/custom_he_scalar_draws.csv @@ -0,0 +1,2001 @@ +chain,draw,I0,IHR,IEDR_first_day,IEDR_mean,ratio +0,0,0.0004,0.00029978754593103544,0.0004488715079146225,0.00044704299532491123,0.6706011481359855 +0,1,0.0004,0.0002921049516525956,0.00040437300632408343,0.00040459495580356047,0.7219688418320737 +0,2,0.0004,0.0002820395951211979,0.0004131030169588476,0.00041166283027217624,0.6851228101762886 +0,3,0.0004,0.00031453692912607607,0.00044970974947052754,0.00044317933146116904,0.7097283352295402 +0,4,0.0004,0.00026822971675631146,0.0003848507820065332,0.0003873485495636648,0.6924763680113513 +0,5,0.0004,0.00030717003137718465,0.0004434364767681675,0.00044296146455761906,0.6934463964804526 +0,6,0.0004,0.0002851486957163523,0.0004305249031405825,0.0004296609469773025,0.6636597943620315 +0,7,0.0004,0.00031144396661040164,0.00043544777721892983,0.00043287559014662167,0.719476851316358 +0,8,0.0004,0.0002937918837220397,0.00043128537492247734,0.00042886530348086236,0.6850446546677793 +0,9,0.0004,0.0002907600719644454,0.0004114728012281619,0.00041240571746225895,0.7050340469420241 +0,10,0.0004,0.0003038103204123747,0.0004616899723942781,0.0004600674854270578,0.6603603385063447 +0,11,0.0004,0.0003021239452283498,0.00045098151847713344,0.00045302264770483467,0.6669069344744937 +0,12,0.0004,0.000308479836195656,0.00045469119169063056,0.0004552408463047408,0.6776189761960812 +0,13,0.0004,0.00025903498161814625,0.0003671496991531217,0.0003707211814922372,0.6987326178004489 +0,14,0.0004,0.0002768967938142324,0.0004089047010884815,0.0004095145222768738,0.6761586677676397 +0,15,0.0004,0.000298703791243466,0.00044528719056333616,0.00044498649136945356,0.6712648519378643 +0,16,0.0004,0.0003078158407041687,0.00047263779536999175,0.00047257267971996243,0.6513619045573572 +0,17,0.0004,0.00027174252805872414,0.0004075313515681192,0.0004075946084299366,0.6666980436897395 +0,18,0.0004,0.00029219849399478293,0.0004248329953383572,0.000425271611273963,0.6870867611394511 +0,19,0.0004,0.00034906882949967393,0.00046637560383190764,0.00047301996263576264,0.7379579237091645 +0,20,0.0004,0.0003175692728383534,0.00043754121155602883,0.00044152138137857434,0.7192613681511825 +0,21,0.0004,0.00030097116485983713,0.0004539619003240294,0.0004610943201046575,0.6527323190437995 +0,22,0.0004,0.00027655324737276503,0.0003957591781492435,0.00039306475600203977,0.7035818987834409 +0,23,0.0004,0.00029471778484559276,0.0004500588992504911,0.00044950280989548434,0.6556528198658397 +0,24,0.0004,0.0002967941269436738,0.00041681960373474305,0.00041657416956339285,0.7124640667344802 +0,25,0.0004,0.00032458802646532554,0.0004979485198351652,0.0005091680743878709,0.6374869965198621 +0,26,0.0004,0.0003144885318440963,0.00045099576205514646,0.00045155481980909486,0.6964570369928805 +0,27,0.0004,0.0003143797046551925,0.00046476468067512726,0.00046484112741218575,0.676316457636556 +0,28,0.0004,0.00032936044974932877,0.00048484534911316733,0.00048490479138261214,0.6792270474585768 +0,29,0.0004,0.000273769527931473,0.0004113483879314105,0.0004087443955073075,0.6697817289743818 +0,30,0.0004,0.00026798426346765034,0.00041145000806719166,0.00041326155054564347,0.6484616415774017 +0,31,0.0004,0.0002791429895158363,0.0003979226869467844,0.00039434277955341433,0.7078688998235505 +0,32,0.0004,0.00032516310583902293,0.000496646124945512,0.0005040020314737335,0.6451622920808983 +0,33,0.0004,0.0003139806807400974,0.00045921217655761187,0.00046072012426228603,0.681499817796866 +0,34,0.0004,0.0002744952689909299,0.0003833978328387307,0.0003789286142639506,0.724398365966959 +0,35,0.0004,0.0002518853854392236,0.00036549822448252867,0.0003646210591228553,0.6908141456370281 +0,36,0.0004,0.00027179630218424154,0.0003812818771474016,0.00038197489984241514,0.7115553987876478 +0,37,0.0004,0.0002773312014156742,0.00039591959559082856,0.000396367624234113,0.6996817713140708 +0,38,0.0004,0.0002805342827657274,0.0004107604777786018,0.00041024658251123924,0.6838186952064172 +0,39,0.0004,0.00028758275416915983,0.0004091494379430084,0.00040709986392706017,0.7064182026370951 +0,40,0.0004,0.00028407420121536137,0.0004180067646397743,0.0004169543631581765,0.6813076593411124 +0,41,0.0004,0.0003084113260105201,0.00044858863931235835,0.00045301039386808653,0.6808040834937825 +0,42,0.0004,0.0002834059792567315,0.00040241264901815947,0.00040176057529816504,0.7054101290212532 +0,43,0.0004,0.0003081086009079605,0.0004450426055640837,0.0004504069808350012,0.6840671082334552 +0,44,0.0004,0.0003131794161492048,0.00045873198734518286,0.0004640604873102777,0.6748676621110566 +0,45,0.0004,0.0003150069694944562,0.00045528468673751313,0.0004551759508173932,0.6920553885344224 +0,46,0.0004,0.0003063410663499449,0.00047691131567698206,0.0004716584397231695,0.649497688475045 +0,47,0.0004,0.00026842504904241784,0.00043467476751659197,0.00043516006288590116,0.6168421046321956 +0,48,0.0004,0.00027839555345996494,0.00044010467961687967,0.00044030016316647216,0.6322858285081011 +0,49,0.0004,0.0002829317056030397,0.0004338478633765515,0.00043399705077301864,0.651920802454977 +0,50,0.0004,0.0002949475014317833,0.0004312143229261709,0.00043197562577766945,0.6827873700068156 +0,51,0.0004,0.0003277611704694751,0.0004761445095645754,0.0004744076982698821,0.6908850165475553 +0,52,0.0004,0.0002919197416812745,0.0004319947647308344,0.00043114554638595343,0.6770793392817595 +0,53,0.0004,0.000297006821235491,0.0004159242330565244,0.00041766143892934735,0.7111186084040989 +0,54,0.0004,0.00025955888905131603,0.00039378552639515393,0.00039408313244627475,0.6586399357924857 +0,55,0.0004,0.0002855338839129996,0.00040249298211482486,0.00040194707589162056,0.7103768158522189 +0,56,0.0004,0.00029339037570855355,0.00044038788765636463,0.0004410195154475621,0.6652548593247868 +0,57,0.0004,0.000310098142197385,0.00045709616768794875,0.000459931068789557,0.6742274293700117 +0,58,0.0004,0.00027345979014843343,0.000391554068883571,0.0003904440260108315,0.7003815449358348 +0,59,0.0004,0.0003159723368654617,0.0004646856499725412,0.0004636521648636527,0.6814857360978364 +0,60,0.0004,0.0003068303127955728,0.0004530813061993177,0.0004538211543306447,0.6761040332025214 +0,61,0.0004,0.00028144310250184234,0.0004146387196854721,0.00041638186355296976,0.6759254596256898 +0,62,0.0004,0.0003136642483368846,0.0004578184537772776,0.0004565757289479149,0.6869928216720137 +0,63,0.0004,0.00026673429708024454,0.0003992077295710666,0.0003892267817807773,0.6852927639251614 +0,64,0.0004,0.0002856394662977948,0.0004140664433122726,0.00040827236272794176,0.6996296893310283 +0,65,0.0004,0.00028225270159333034,0.00040370997309492585,0.0003987998002877448,0.7077553734722972 +0,66,0.0004,0.0002760850522176985,0.00038384323542134944,0.00038892906015333873,0.7098596646618526 +0,67,0.0004,0.000291034014515045,0.00045646076006356585,0.00044791570292440034,0.6497517559998695 +0,68,0.0004,0.00031938599917058556,0.00043686120261369565,0.0004380128848437351,0.7291703285955373 +0,69,0.0004,0.0003157466098190808,0.00043355834373019807,0.0004335665607784771,0.728254063810068 +0,70,0.0004,0.00030458232241892025,0.00045388521958484245,0.0004519294957661737,0.6739598217694331 +0,71,0.0004,0.00031112219905839313,0.0004429036981499752,0.0004432673664264117,0.7018838349563989 +0,72,0.0004,0.00030998553633056333,0.000479573153634261,0.0004836270477672045,0.6409598837817191 +0,73,0.0004,0.000306475372880395,0.0004485282788609176,0.0004424517689062784,0.6926752121208349 +0,74,0.0004,0.0002792442419970988,0.0003982709456857331,0.00040096318997525493,0.6964336103130366 +0,75,0.0004,0.0003160116331582009,0.0004629634793484795,0.00046032579507392226,0.6864956005940392 +0,76,0.0004,0.0002945656963555264,0.00042469288119999996,0.00042459694559554323,0.6937536866695216 +0,77,0.0004,0.0002921875319982514,0.0004210484148231026,0.00042113185075825745,0.693814850318638 +0,78,0.0004,0.00027452451750763993,0.00040502790406106545,0.0004065723250064398,0.6752169309686578 +0,79,0.0004,0.0002692932135431453,0.00037785344105186825,0.00038206222714749397,0.7048412389618025 +0,80,0.0004,0.00032791979546205823,0.0004942404465855612,0.0004921179362440067,0.6663439214689908 +0,81,0.0004,0.00028004072614300543,0.0004097102338688181,0.00040972223914688584,0.683489201675017 +0,82,0.0004,0.0003065713735851191,0.0004353318866325486,0.0004327666593641316,0.7083987801545699 +0,83,0.0004,0.00027967943480126885,0.000414375549166101,0.0004088839160707356,0.6840069364647867 +0,84,0.0004,0.0002666677759779368,0.0003949805068935032,0.0003940041662632155,0.6768146096196067 +0,85,0.0004,0.0002679204770235303,0.00039272110865609634,0.0003922746857304389,0.6829920124074444 +0,86,0.0004,0.0002773466873086916,0.00039456496713386624,0.0003942992950133155,0.7033912837691622 +0,87,0.0004,0.00027043017194217865,0.0003954633862702257,0.0003941258812885216,0.686151772266407 +0,88,0.0004,0.00030160314815260586,0.00043572511223683965,0.0004350551621860539,0.6932526593573057 +0,89,0.0004,0.00028132387327758576,0.0003937739406512584,0.0004008775698230776,0.7017700526416197 +0,90,0.0004,0.0003235649245281745,0.0004986014271580807,0.0004929303462238862,0.6564110467266974 +0,91,0.0004,0.00028284455279658523,0.0003851984968064036,0.00039905150281095914,0.7087921002782839 +0,92,0.0004,0.00029403404160889996,0.0004307080888475059,0.00042979808523272334,0.6841213390927252 +0,93,0.0004,0.0002788433389530984,0.00040552395609055745,0.0004081493199606862,0.6831895223541159 +0,94,0.0004,0.000260830446382441,0.00038833661563290146,0.0003837660346151853,0.6796600607033506 +0,95,0.0004,0.0002517980392731565,0.00038124891464674375,0.0003773248310105068,0.6673243279505904 +0,96,0.0004,0.0002922354955063511,0.000418705339622551,0.0004159678547189938,0.7025434590463009 +0,97,0.0004,0.00028337858149289245,0.00040522251478853684,0.00040766190413077386,0.6951313787760444 +0,98,0.0004,0.00029316286689282686,0.00042109521646812226,0.0004207481761451837,0.6967656273135403 +0,99,0.0004,0.0002583349297765871,0.0003805257201337537,0.00038046215656131256,0.6790029581692593 +0,100,0.0004,0.00030072819356513625,0.0004532223265441805,0.0004534380077156365,0.663217878625056 +0,101,0.0004,0.0002921962010666725,0.00042068511518812945,0.0004211984369123427,0.6937257488623649 +0,102,0.0004,0.0003174154893656257,0.00045027073744816716,0.0004528187408827152,0.7009769267651393 +0,103,0.0004,0.00029538980742891796,0.0004223312752425973,0.0004211712648400062,0.7013531835822896 +0,104,0.0004,0.0003168733603707667,0.0004531665287235399,0.00045533910728546775,0.6959063153170103 +0,105,0.0004,0.0002916984509002943,0.00043651818538976387,0.000433543354456609,0.6728241775632817 +0,106,0.0004,0.00026687453832716367,0.00037984460702247217,0.00038284850178347396,0.6970760942878099 +0,107,0.0004,0.0002838192838950142,0.0004141241439323622,0.00041323297147174835,0.686826326767147 +0,108,0.0004,0.0003003442400071984,0.00044631480841738816,0.0004411944323533647,0.6807525616430364 +0,109,0.0004,0.00028872851183650805,0.00042691028697508965,0.00043011471083328996,0.6712825777968278 +0,110,0.0004,0.0002642708007202249,0.0003873765261921933,0.000384054350458114,0.6881078170446269 +0,111,0.0004,0.00029478656748731696,0.00042616811893743877,0.00042591525095800667,0.6921249399364232 +0,112,0.0004,0.0002951247938955587,0.000413100739917403,0.00040700515836587385,0.7251131535543309 +0,113,0.0004,0.0003245665105120032,0.00045848461549611127,0.00046117845694656026,0.7037763920304128 +0,114,0.0004,0.00033393095575994365,0.0004953902252865071,0.000495163778617787,0.6743848604841154 +0,115,0.0004,0.0002910611511275974,0.0004247559291569056,0.00042492728753575754,0.684966957089346 +0,116,0.0004,0.00033461866922736923,0.0004971018323053306,0.000498804748634609,0.6708409856628861 +0,117,0.0004,0.000276705170077819,0.0004004422895440002,0.00039758135998665446,0.6959711845824641 +0,118,0.0004,0.0002600728499792511,0.00037833267017649535,0.0003769062328476404,0.6900200296883451 +0,119,0.0004,0.00026787871781581903,0.00038802017385745555,0.0003863302320076189,0.6933931016057168 +0,120,0.0004,0.0002862326622776767,0.0004054839116515274,0.00040531193004016516,0.706203398082341 +0,121,0.0004,0.0003055072957299742,0.00044999467308225687,0.00044743288861201887,0.6828002668236751 +0,122,0.0004,0.00026656354253533707,0.00039341164501325833,0.0003991933276467757,0.6677555061020573 +0,123,0.0004,0.0003011078371023989,0.00046517958143790507,0.00045250006066318145,0.66543159499492 +0,124,0.0004,0.0003418260894110851,0.0005261896862088893,0.0005255422061414951,0.6504255708038282 +0,125,0.0004,0.0002958066274269776,0.00041774044329265984,0.00041709065515173024,0.7092142290250265 +0,126,0.0004,0.0003011344793323842,0.0004455854623168916,0.0004482188418723666,0.6718469890164375 +0,127,0.0004,0.0002842674584326921,0.0003983127420110763,0.00039789734346820627,0.7144241174241625 +0,128,0.0004,0.00029659512871476126,0.00043823576979181437,0.0004385972528031982,0.6762357192598415 +0,129,0.0004,0.0002567895727582021,0.0004116840055381626,0.0004103231376651889,0.6258227947353397 +0,130,0.0004,0.00030434518246906273,0.00044422281739316593,0.0004425771059769106,0.6876658967645302 +0,131,0.0004,0.00028270898201431064,0.0004194733801568632,0.0004167020643325219,0.6784439200395062 +0,132,0.0004,0.0002730835504788112,0.0003717682554921072,0.0003742460771592697,0.7296898141235392 +0,133,0.0004,0.0002740813357974022,0.00038768669546979914,0.0003905203121180028,0.7018363124594235 +0,134,0.0004,0.000269338950004493,0.0004143457385872177,0.0004068065674482615,0.6620811254202479 +0,135,0.0004,0.0003095106623906065,0.00044594779370743135,0.000448750435827491,0.689716683661537 +0,136,0.0004,0.0002961798353000408,0.0004179844845019761,0.00041483736801981594,0.7139661422350286 +0,137,0.0004,0.0002792467419238504,0.00040663368834177165,0.0004061955878716712,0.6874686733723766 +0,138,0.0004,0.0002590408472827065,0.000402832501583917,0.0004047622779373762,0.6399826797169686 +0,139,0.0004,0.00027072599888292134,0.0004201334598064872,0.000417267736299724,0.6488064504667537 +0,140,0.0004,0.000258459835816668,0.00039901178437985204,0.0004005327700797662,0.6452901113813875 +0,141,0.0004,0.0002540048965303005,0.00039067505973817046,0.0003922185455259937,0.6476106227706837 +0,142,0.0004,0.00028220871599342665,0.00043603363644298263,0.0004387695530674856,0.6431820850386606 +0,143,0.0004,0.00029236979345447487,0.00042272712131195855,0.00042991051025000656,0.6800712857297966 +0,144,0.0004,0.00030202963862034806,0.00043145657846789857,0.0004318238383262431,0.6994278958545234 +0,145,0.0004,0.0002767794413208207,0.00041688868399571486,0.0004171265393515781,0.6635383156177823 +0,146,0.0004,0.00030884751194842403,0.0004420815477476929,0.0004416986700614509,0.6992267192143818 +0,147,0.0004,0.0003096737829269452,0.00045595707074611616,0.00046426562594668007,0.6670185463235448 +0,148,0.0004,0.0002867535857592782,0.0004017231096052953,0.0004097915615497762,0.6997547354923928 +0,149,0.0004,0.0003187155320849353,0.0004357845597327935,0.0004435820500329348,0.7185041235579112 +0,150,0.0004,0.000291861428303049,0.00040709872784925466,0.0004213669960256121,0.692653746154596 +0,151,0.0004,0.00028428301159978345,0.0004057013236488439,0.00041456459034882427,0.6857387683800518 +0,152,0.0004,0.0002837739205710889,0.0004171111048668502,0.0004142205283770595,0.6850793264228885 +0,153,0.0004,0.00034688061451174985,0.00051426353179703,0.0005145350203361658,0.674163275193823 +0,154,0.0004,0.00025490337992199237,0.000356842784395844,0.00035732673907828646,0.7133621754126431 +0,155,0.0004,0.0003390837806241057,0.0005138996365658452,0.0005114150521506732,0.6630305056492644 +0,156,0.0004,0.0002802860086638476,0.00043701894752017886,0.000436914658020215,0.6415120287653051 +0,157,0.0004,0.0003069064443817047,0.00042942203186350917,0.00042949189766061684,0.7145802890657118 +0,158,0.0004,0.00029696121173875223,0.00042464680758517775,0.0004254618711962234,0.6979737359397675 +0,159,0.0004,0.0002926672883365673,0.00043567771469301347,0.00043569797534671943,0.6717205607936753 +0,160,0.0004,0.0002908756074949386,0.0004111674416094768,0.00041121047503188407,0.7073642943370665 +0,161,0.0004,0.00028872305308028074,0.0004051625010168144,0.0004051806351746237,0.7125786081949539 +0,162,0.0004,0.0002746027453076236,0.00039635678307150656,0.0003967583462828079,0.6921158631704946 +0,163,0.0004,0.0002706358986229832,0.00039396259871351364,0.00039327991024710844,0.6881508349941783 +0,164,0.0004,0.00030066211567558244,0.0004311042655288748,0.0004308657933974373,0.6978092025008981 +0,165,0.0004,0.00029996252601178244,0.00043733309002898197,0.0004368715242228278,0.6866149643087873 +0,166,0.0004,0.0002962898433067862,0.00040726931751430205,0.00040992727562921957,0.7227863597317229 +0,167,0.0004,0.0002684280916921658,0.00038220126003367854,0.000381993549774447,0.7027032049380484 +0,168,0.0004,0.0002749350441307205,0.000407937447394643,0.0004080580103524781,0.6737646049227981 +0,169,0.0004,0.00033577591589583223,0.0004940083668897971,0.0004947336846259818,0.6787003317748185 +0,170,0.0004,0.0002687197683083506,0.00040922466934593927,0.0004088034880113402,0.6573323765302519 +0,171,0.0004,0.00030809602303367637,0.0004441241440146364,0.00044395793982414194,0.6939757021931348 +0,172,0.0004,0.0003070090291766433,0.0004797246606349071,0.00047919301860303035,0.6406792612956942 +0,173,0.0004,0.0003332738950432488,0.0004713882099246231,0.000471639390072328,0.7066286278424281 +0,174,0.0004,0.00034929665024819754,0.0004981044110508564,0.0004979727750584185,0.7014372426428745 +0,175,0.0004,0.00031083034637472724,0.0004692222659307248,0.00047312391291496166,0.6569745005270855 +0,176,0.0004,0.0002976963650469088,0.0004153947039385232,0.00041372845790131434,0.7195452944112382 +0,177,0.0004,0.00030014937409964415,0.0004232085915606381,0.00042593296813078535,0.7046868792919581 +0,178,0.0004,0.00030933239431155254,0.00043895902987220535,0.00043810204028574127,0.7060738500779364 +0,179,0.0004,0.000277342016924341,0.00041648518493123745,0.00041665858109831333,0.665633757483805 +0,180,0.0004,0.00030787665589544267,0.00044701070840297866,0.0004467231341554027,0.6891889681906217 +0,181,0.0004,0.00028450350219079125,0.0004087720049060992,0.0004087113022458227,0.696098934938859 +0,182,0.0004,0.0003150462284606052,0.000463352171840467,0.0004624243088022396,0.6812925325587454 +0,183,0.0004,0.00028269670011115555,0.0004575345365259302,0.0004543205903702591,0.6222405633888733 +0,184,0.0004,0.0003110889215725272,0.00041623891196189254,0.0004202157536848377,0.7403076130407149 +0,185,0.0004,0.0002635114365144756,0.00039163878422316864,0.00039449393316283985,0.6679733561471601 +0,186,0.0004,0.0002726837253057798,0.0004004035172351169,0.0003999086172675348,0.6818650900021921 +0,187,0.0004,0.0002868284832825726,0.0004210066567577003,0.00042272818812430426,0.6785175234120654 +0,188,0.0004,0.0003076688401841072,0.0004490787825601612,0.0004488842268551027,0.6854080000530315 +0,189,0.0004,0.00028375135061022347,0.00042274861426035447,0.00042323001629412645,0.6704424064597266 +0,190,0.0004,0.0003025350777620633,0.0004404978268280201,0.0004392081121531353,0.6888194215697472 +0,191,0.0004,0.0003097365231062897,0.00041191453163310206,0.0004126377446173671,0.7506257659330312 +0,192,0.0004,0.00029415175999000884,0.00042325144976990576,0.0004259970756169046,0.6905018293002013 +0,193,0.0004,0.0002790855536176659,0.00042197371018250197,0.0004301764385771219,0.6487699664369961 +0,194,0.0004,0.00027476782730752867,0.0003947866160488947,0.00040677283744770695,0.6754822397472685 +0,195,0.0004,0.0003241112066085321,0.0004500369291183238,0.00045458270930731913,0.7129862178489016 +0,196,0.0004,0.0002666445597613328,0.00039734297463385633,0.0003969596367211411,0.6717170591040396 +0,197,0.0004,0.00030772199707682134,0.0004551291263564767,0.00045458451040737913,0.6769302297631173 +0,198,0.0004,0.00033198449357785454,0.00046681694316153476,0.0004700621564800374,0.7062565854351078 +0,199,0.0004,0.00030783137348588057,0.0004848872279241701,0.00047897197004766016,0.6426918332094669 +0,200,0.0004,0.0002844276907059496,0.0004095633272016664,0.00041076705113202074,0.6924306365909918 +0,201,0.0004,0.00029918048993362646,0.00045021690728457616,0.000449308301079197,0.6658690462985496 +0,202,0.0004,0.0003267463426811666,0.00044919493930619775,0.0004503275214364994,0.7255748918895267 +0,203,0.0004,0.00034597514802402136,0.0004969194080377282,0.000491269206033163,0.7042475770416321 +0,204,0.0004,0.0003007788693051779,0.0004234071901195983,0.00042806317145586324,0.7026506585049459 +0,205,0.0004,0.0003090851427302907,0.0004693405001575972,0.0004522108113660611,0.6834979062012931 +0,206,0.0004,0.0002951079678937421,0.0004606420212422143,0.0004449759516350905,0.6631998129547235 +0,207,0.0004,0.0002888317453228028,0.00042773323861846415,0.0004295538618854538,0.6723993681607816 +0,208,0.0004,0.0002706255928115205,0.00040438402254647763,0.0004082687708922483,0.6628613602262147 +0,209,0.0004,0.00028463743477359746,0.00043072734002260073,0.0004327768392413148,0.657700248637577 +0,210,0.0004,0.00028251464489031946,0.00041433997089523303,0.0004110931604344904,0.6872277918506977 +0,211,0.0004,0.0002851460376241224,0.0004168819693207339,0.00041755347327140826,0.6828970560107843 +0,212,0.0004,0.0002916575534854307,0.0004204495633105656,0.0004189073278537845,0.6962340691906705 +0,213,0.0004,0.00030484634419488353,0.0004557334282467405,0.00045761900761773493,0.6661575221314502 +0,214,0.0004,0.0002937668483102271,0.0004164869322134838,0.0004179992836419133,0.7027927075633169 +0,215,0.0004,0.0003107853262302696,0.00046154297177182176,0.0004613200457328662,0.6736870186001719 +0,216,0.0004,0.00029196870605791367,0.00043722110142830744,0.00043763204338637243,0.6671556858558072 +0,217,0.0004,0.0003135559652645995,0.000451963371578294,0.0004520762222279189,0.6935909252633 +0,218,0.0004,0.0002887339946549704,0.0004514132211128796,0.00044938291161341227,0.6425121810224901 +0,219,0.0004,0.0003197133438363996,0.0004690132001071076,0.00047068766118648936,0.679247344258993 +0,220,0.0004,0.00031955215982376465,0.00046862640675636403,0.0004697151438582118,0.6803105328880447 +0,221,0.0004,0.00027246058044231246,0.0004022857616736321,0.0004035455866181907,0.6751667952203314 +0,222,0.0004,0.00027832560446530106,0.0004172623601436785,0.00041507407564144306,0.6705444179696961 +0,223,0.0004,0.0002905444191421016,0.00042322757519242026,0.00041907733743300825,0.6932954688549502 +0,224,0.0004,0.00031230975495671236,0.00045472681550398034,0.00045419135868209233,0.6876171221375242 +0,225,0.0004,0.00032108493965911535,0.000461042668240796,0.0004573201319775313,0.7021010386546697 +0,226,0.0004,0.0002988708634050527,0.00043561512008712046,0.00043669968072623463,0.6843853490069615 +0,227,0.0004,0.00029085830809071186,0.0004303950613152055,0.0004299960402435051,0.6764208989599065 +0,228,0.0004,0.00029289693448487946,0.000414344700166845,0.00041479143682213995,0.7061306200746663 +0,229,0.0004,0.000256647705574429,0.0003766792223808991,0.0003784579063525619,0.6781406895364009 +0,230,0.0004,0.0002850281656272523,0.00041268048618485666,0.0004134803428876122,0.6893390956307821 +0,231,0.0004,0.00028724154695612794,0.00039874989315696316,0.00039861470199289257,0.72059947994906 +0,232,0.0004,0.00031021351111712366,0.00045964706797635527,0.0004599522458552337,0.674447214710983 +0,233,0.0004,0.000278781154787403,0.0003925720780802522,0.00039357088000259297,0.7083378597155519 +0,234,0.0004,0.0002659716027632071,0.0003838212288218284,0.0003866814555658395,0.6878312857646742 +0,235,0.0004,0.0003021207576693387,0.0004578398123352328,0.00044795290806056494,0.6744475864156926 +0,236,0.0004,0.0002660580535267518,0.0003846973391928563,0.00038676871456735397,0.6878996245194465 +0,237,0.0004,0.00029333118341826357,0.00043387811628462864,0.0004336986383558798,0.6763479464225687 +0,238,0.0004,0.00028417914437189266,0.0003989049637641852,0.00039754818814832717,0.7148294290951819 +0,239,0.0004,0.00026735356629770113,0.0004069610829126396,0.0004072010818799369,0.6565639881490547 +0,240,0.0004,0.0003098937772904279,0.0004346830233498151,0.0004331217408382626,0.7154888523736083 +0,241,0.0004,0.00025490793702582186,0.00037411380796919375,0.00037351855645541667,0.682450530556834 +0,242,0.0004,0.00033326368062933277,0.00044976797193740686,0.00044681835595649207,0.7458594218134216 +0,243,0.0004,0.000258154969031262,0.0004088502417799415,0.0004086584236397313,0.6317133187467304 +0,244,0.0004,0.00034686658212658493,0.0004734821183575745,0.0004791438272750956,0.7239299817326771 +0,245,0.0004,0.0003132826353530844,0.0004943428695127435,0.0004896052168252889,0.6398678457400433 +0,246,0.0004,0.0003052978309763744,0.00042072449673660864,0.0004215282328053598,0.7242642537714558 +0,247,0.0004,0.000311560057969374,0.00046896837112301546,0.000472898200307901,0.6588311348330766 +0,248,0.0004,0.00028691910486849416,0.00039745735254629764,0.0003942910164456768,0.7276835963824813 +0,249,0.0004,0.0002603754094753647,0.00037516824969607295,0.00037707460144065046,0.6905143132965598 +0,250,0.0004,0.0003163334666283002,0.0004636917066374033,0.00046698642669309814,0.6773932785763674 +0,251,0.0004,0.0002787595531510637,0.00041185295376599277,0.00041028840274998004,0.679423428209676 +0,252,0.0004,0.000293775980797614,0.0004144718474886456,0.00041447151287546754,0.7087965557861685 +0,253,0.0004,0.00030781269503228734,0.00046445256518339744,0.0004642638969463541,0.6630123450410258 +0,254,0.0004,0.00029730097831595913,0.0004366586565840286,0.00043584131030031145,0.68213125119119 +0,255,0.0004,0.0002813210592732272,0.0004281124142646121,0.00042694170791930707,0.658921473482271 +0,256,0.0004,0.00034806560273350394,0.00045165738674211056,0.0004527697899430483,0.7687474086495157 +0,257,0.0004,0.0002841286297597728,0.0004308921103901252,0.0004311393522950647,0.6590180837060771 +0,258,0.0004,0.0002780567286624443,0.00039018988252933546,0.0003892442608342298,0.7143502336206886 +0,259,0.0004,0.00031155368217365893,0.0004564226046344,0.0004552988120051264,0.6842839778157624 +0,260,0.0004,0.00027508195242251113,0.0004330548113636389,0.0004324730012348775,0.6360673420931385 +0,261,0.0004,0.00026323785375412126,0.00041081525583790466,0.00041167699537063003,0.6394281359276099 +0,262,0.0004,0.00029727609232115757,0.0004425226495540822,0.0004428678979968467,0.6712522936653996 +0,263,0.0004,0.00030664316174457053,0.0004230287530283522,0.00042239303458617173,0.7259664261390957 +0,264,0.0004,0.00027705136042300394,0.0004331294480962965,0.00043270105019272326,0.6402835405636441 +0,265,0.0004,0.00025115899003124673,0.000398839154042295,0.00039773968250645633,0.6314657578255842 +0,266,0.0004,0.0003267339141029833,0.00046542289154760604,0.0004598492567985751,0.7105239581720157 +0,267,0.0004,0.0002798365160008256,0.0004438826583366601,0.00043936053199588324,0.6369177375346214 +0,268,0.0004,0.0002874865206440167,0.000429720610157848,0.00043190015483722473,0.665631899929198 +0,269,0.0004,0.0002827815180953155,0.0004243277077868689,0.00042241476348976357,0.6694404233392004 +0,270,0.0004,0.0002804023763974684,0.00042564204081876807,0.00042718006572014974,0.6564032334344997 +0,271,0.0004,0.0003062712914921136,0.000433282867396187,0.0004326455341654061,0.707903508314088 +0,272,0.0004,0.0002816476126610321,0.00043596326587263894,0.00043799257858552856,0.6430419747535372 +0,273,0.0004,0.0002623117520241597,0.0003936558225119945,0.0003957855827503804,0.6627622719385363 +0,274,0.0004,0.000291819761925032,0.0004386339912217849,0.00043820852008154255,0.6659381288860602 +0,275,0.0004,0.00028916281584814103,0.0004067958655938969,0.00040682194199139046,0.7107847094792654 +0,276,0.0004,0.0003054463568214396,0.00042915478905605444,0.000429630251078128,0.7109516987105603 +0,277,0.0004,0.000284978343070476,0.00039002906568045393,0.0003917139406575505,0.7275164692686127 +0,278,0.0004,0.0002756546144446064,0.0004014666072269609,0.000398293407665602,0.6920893219403713 +0,279,0.0004,0.00026118924097359806,0.0003718181833956067,0.0003724746238231241,0.7012269407583273 +0,280,0.0004,0.00031694126048913433,0.0004853291924751022,0.000485638692403187,0.6526276951301964 +0,281,0.0004,0.00032730642446951913,0.000485234877409833,0.00048007206823121756,0.6817860194938028 +0,282,0.0004,0.000306083252938158,0.0004397670594652804,0.0004308639691288015,0.7103941727990214 +0,283,0.0004,0.0002994019254104602,0.0004483483171641791,0.00045081322825044567,0.6641374002542132 +0,284,0.0004,0.00031146094111913716,0.00042358554546273697,0.0004216179645436129,0.7387278705172894 +0,285,0.0004,0.0002731098113527851,0.00041947422981576915,0.0004199211717354811,0.650383523707692 +0,286,0.0004,0.00030836314063854365,0.00043106519051347875,0.00043461301989607473,0.7095119716208222 +0,287,0.0004,0.0002927073073569622,0.0004349666932827118,0.0004330526332422543,0.6759162394775663 +0,288,0.0004,0.00028495499075155043,0.000407077004489867,0.0004043654060146437,0.7046967582118809 +0,289,0.0004,0.00028042051131675253,0.00040859448339047063,0.00041040346450385595,0.683280078192707 +0,290,0.0004,0.0002865612750492657,0.0004182859718729715,0.00042328290114698736,0.6769970491904083 +0,291,0.0004,0.00027922649764662377,0.0004186594810133364,0.0004223224673330227,0.6611689390099142 +0,292,0.0004,0.00027725037145384483,0.00041902247503138626,0.0004123811984017426,0.6723157421540518 +0,293,0.0004,0.00031088280028168295,0.00045776223702933774,0.00045446645270934695,0.6840610531939689 +0,294,0.0004,0.00029296577500729457,0.00043181450087495163,0.00043115502026419404,0.6794905805057708 +0,295,0.0004,0.00031453627287574763,0.00046817856293503114,0.0004713091367485949,0.6673672295971786 +0,296,0.0004,0.000289879692808137,0.0003970377786255888,0.0004008667143190565,0.7231323590948411 +0,297,0.0004,0.00027954269464486303,0.0004119336707300917,0.0004066915028498028,0.6873580900658804 +0,298,0.0004,0.0002805788920113313,0.00041216949061713713,0.00041329193196543395,0.6788879005622538 +0,299,0.0004,0.00032009760892148635,0.0004631963132631258,0.00046642769224273736,0.6862748808552769 +0,300,0.0004,0.00030748526028058314,0.00044700932940699463,0.0004460099466230956,0.6894134595173639 +0,301,0.0004,0.00030895110427853824,0.0004496623573074766,0.00045224080654163206,0.6831561853985351 +0,302,0.0004,0.0002786362289755999,0.00039912980424670056,0.00039953255829663643,0.6974055635504028 +0,303,0.0004,0.0002969061658359134,0.00041055223682873274,0.0004136169723431741,0.717828778045339 +0,304,0.0004,0.00027946500177134594,0.00045099301577803075,0.000449167729305482,0.622184060737097 +0,305,0.0004,0.00034024488996110916,0.0004833036156361465,0.0004915074030301184,0.6922477420757379 +0,306,0.0004,0.00024196089498682867,0.00040648813398133735,0.0004056340354069648,0.5965004754694068 +0,307,0.0004,0.00036986402708570555,0.0005147138724745374,0.0005068559994626282,0.7297221054458024 +0,308,0.0004,0.0002488493978347572,0.0004107880308343246,0.0004149407279950102,0.5997227580844986 +0,309,0.0004,0.0002687594605703031,0.0004076654649502509,0.00038931952877768196,0.6903313106694328 +0,310,0.0004,0.00031898188921528916,0.0004345347914510673,0.0004514203230047104,0.7066183620004204 +0,311,0.0004,0.0003005737747069794,0.00046361603472939896,0.0004579450221253933,0.6563534052886311 +0,312,0.0004,0.00030885362023530923,0.0004180397031249568,0.0004225038074463033,0.7310078981348871 +0,313,0.0004,0.0003170647645919921,0.00044058732343545793,0.0004465341589066764,0.7100571328480543 +0,314,0.0004,0.00024352547812426186,0.00036847876798526186,0.00036573217969861494,0.6658573996002795 +0,315,0.0004,0.00029486109211134963,0.0004153710676299275,0.0004151910752854886,0.710181672158056 +0,316,0.0004,0.00031606517485829584,0.0004382996581041007,0.0004381275744871114,0.7213998690410975 +0,317,0.0004,0.0002779010929530326,0.00041877144331398607,0.0004152135328508305,0.6692968098726957 +0,318,0.0004,0.00028927577602043495,0.00043697621408109996,0.00042629565532477815,0.6785801647451625 +0,319,0.0004,0.00029973950395612275,0.0004344215357550333,0.0004270954072439536,0.7018092418514672 +0,320,0.0004,0.00027313494887928257,0.0003968461253485747,0.000398037238530991,0.6862045116364569 +0,321,0.0004,0.0002984204010585332,0.00044873606535897716,0.00044949470484850263,0.663901927741535 +0,322,0.0004,0.00033706625696071216,0.0004558427019972642,0.00045276706835000846,0.7444584213888662 +0,323,0.0004,0.00027483509778247273,0.00041543114678661044,0.0004148463268623032,0.6624985687138473 +0,324,0.0004,0.00027551809292424343,0.00039451162155866766,0.0003950418341369525,0.6974402939530886 +0,325,0.0004,0.0002999553033583299,0.00045423350050924826,0.0004548653670811678,0.6594375502428718 +0,326,0.0004,0.00030726443308603445,0.0004434142130753411,0.0004428924335903245,0.6937676279433892 +0,327,0.0004,0.000350394239189776,0.0004919695300383569,0.0004922483518840751,0.7118240982395289 +0,328,0.0004,0.0002878667512166812,0.00044617426393968784,0.00044445158107419446,0.6476897900125284 +0,329,0.0004,0.0003020608044220782,0.00044478269251659405,0.00044585611058219163,0.6774849491860774 +0,330,0.0004,0.0002977111147143616,0.0004504754495577343,0.0004450789053807081,0.6688951354809948 +0,331,0.0004,0.0002427312416147504,0.00037750374705398856,0.0003795040495192413,0.6396011898219379 +0,332,0.0004,0.00034372090453204263,0.0004964544744546093,0.0004924615941456936,0.697964894355505 +0,333,0.0004,0.00027352496523245373,0.0004092156555859504,0.000413140934274616,0.6620621258764954 +0,334,0.0004,0.0002870977713062043,0.0003925142507840521,0.0003859459446744764,0.7438807824457258 +0,335,0.0004,0.0002725749931394133,0.00043548659043267255,0.0004371943584997528,0.6234641134775014 +0,336,0.0004,0.0002724540667836469,0.0003737959319878299,0.0003763457286956428,0.7239462175588689 +0,337,0.0004,0.00031010767122614927,0.0004300617742097434,0.00043119276595258147,0.7191857000222772 +0,338,0.0004,0.0002851983731654604,0.00043588342553614986,0.0004358739170219524,0.6543139243431643 +0,339,0.0004,0.0002870869531349178,0.00041027584429137155,0.00040998345146070275,0.7002403441213904 +0,340,0.0004,0.0002878461486544361,0.0004182314164492782,0.0004367356681046112,0.6590855056644661 +0,341,0.0004,0.00029473682818407495,0.00040476553722893307,0.0004044321499699882,0.7287670582221185 +0,342,0.0004,0.00028339966919561785,0.0004121089224806984,0.00041187822375145916,0.6880666489584322 +0,343,0.0004,0.00028883133173549213,0.00041749286577753484,0.0004173547272994568,0.6920523785711246 +0,344,0.0004,0.0002828356142366354,0.0004256891421697964,0.00042546359849457996,0.6647704180507901 +0,345,0.0004,0.0002935670024162014,0.0004208358834783718,0.00042086748303496,0.6975283533411295 +0,346,0.0004,0.00029275053223219044,0.00045956398988074055,0.00045874804128622496,0.6381510238417251 +0,347,0.0004,0.0003342759126865205,0.0004444854333440588,0.00044540210865293535,0.7505036599343848 +0,348,0.0004,0.00024621692597259683,0.00037048631901966735,0.000371087208777228,0.6635015170258978 +0,349,0.0004,0.000288635389663755,0.00039338856604352514,0.00038991558861940816,0.7402509622293878 +0,350,0.0004,0.00028802135492036964,0.00039049578820706015,0.0003911927777842284,0.7362644999525901 +0,351,0.0004,0.0002870678443621213,0.0004219347639071433,0.0004213839076463404,0.6812501359284274 +0,352,0.0004,0.00026593938787493093,0.00038293893883379595,0.00038580028365958947,0.6893187981934775 +0,353,0.0004,0.0002806796754936429,0.00040863922436509766,0.0004087166217670289,0.6867341834060081 +0,354,0.0004,0.00030188367683283546,0.00045202855257215447,0.0004519327458818154,0.6679836315994258 +0,355,0.0004,0.0003133517182453129,0.00045824356930594564,0.00045947489537266666,0.6819778869336539 +0,356,0.0004,0.00024864080788067735,0.00036897724879016364,0.00036755300258572765,0.6764760623134473 +0,357,0.0004,0.0003004217332716313,0.0004270241894087494,0.0004288024253467152,0.700606422710227 +0,358,0.0004,0.0002942272036680158,0.00041913118249904067,0.00041751128250890686,0.7047167729215533 +0,359,0.0004,0.00029913199622614173,0.00043106328246913047,0.0004303616498911581,0.6950712181296698 +0,360,0.0004,0.00030246285610883533,0.00043912543043922203,0.0004417217995279158,0.6847360859982198 +0,361,0.0004,0.00029056316577864496,0.00044411509091302556,0.00044741550701643155,0.6494257825712194 +0,362,0.0004,0.0003192036221022207,0.00042858836203754684,0.00043227211211190926,0.7384321429914111 +0,363,0.0004,0.00032142853669526057,0.0004688137273984977,0.0004647509021924706,0.691614658904191 +0,364,0.0004,0.00028158173335230405,0.0004049063325711823,0.00039818754441778607,0.7071585671119412 +0,365,0.0004,0.0002910510126633118,0.00046191635244742074,0.0004423905777552677,0.6579050895254881 +0,366,0.0004,0.00030879753863576677,0.0004458870127703718,0.00044598317089577177,0.6923972893764956 +0,367,0.0004,0.00030418103395331677,0.00044656442568374817,0.0004516513838973138,0.6734863321540813 +0,368,0.0004,0.000342203336075313,0.0005083153186350727,0.0005082848504409986,0.6732511027594276 +0,369,0.0004,0.00029468982604622925,0.0004001864456409994,0.00040032138716522363,0.7361331057853341 +0,370,0.0004,0.0002848542011108293,0.0003775749859428237,0.0003795879444550638,0.750430052565989 +0,371,0.0004,0.0003083593450280944,0.00047289808167568686,0.0004728552920931834,0.6521220131915695 +0,372,0.0004,0.00032242207142192414,0.00047487301898153906,0.00047811496284898145,0.6743609727264803 +0,373,0.0004,0.00031244716689651005,0.00045312306239136783,0.0004564861379030005,0.6844614566650925 +0,374,0.0004,0.00028830118121664784,0.00041607299824420406,0.00040957171207688315,0.7039089192823188 +0,375,0.0004,0.00026870984968779187,0.0003735091935767763,0.00037021791278796657,0.7258153655079596 +0,376,0.0004,0.0002500774242799002,0.00038582723449631586,0.00038608124116829733,0.6477326469505638 +0,377,0.0004,0.0002631922877401416,0.00040738599817742897,0.0003990040834317868,0.6596230431439597 +0,378,0.0004,0.000279962314860318,0.00041393416094543317,0.00040266217685298855,0.695278401980457 +0,379,0.0004,0.0002774237912900693,0.0004105175958918459,0.0004072948557525045,0.6811374790813655 +0,380,0.0004,0.0003015955813554411,0.0004330450090427033,0.0004347861712853516,0.6936641532637497 +0,381,0.0004,0.000283601741071111,0.00041850682436333304,0.0004091814385521158,0.6930953223944684 +0,382,0.0004,0.0003134463765545227,0.00047068385137705735,0.00046801731369799156,0.6697324380541775 +0,383,0.0004,0.0002711074547594581,0.00040239337134523247,0.0004026365099199387,0.6733305303420344 +0,384,0.0004,0.0002992247862321053,0.00042817637410157833,0.0004255731597623159,0.7031100983887786 +0,385,0.0004,0.00026333172698832615,0.00040006153403539935,0.000400681176373135,0.6572101274433167 +0,386,0.0004,0.00026846941336848356,0.00041021814397323124,0.00041038863867747986,0.6541833473598446 +0,387,0.0004,0.00028659499029154385,0.00041256210401582297,0.0004124526666493744,0.6948554669793855 +0,388,0.0004,0.00031413131109954596,0.00043206806038605496,0.00043357999071216597,0.7245060146423672 +0,389,0.0004,0.00026864374939360506,0.00042061801588063913,0.0004194115630946581,0.6405253765809364 +0,390,0.0004,0.0003509426567230595,0.00048320681519372656,0.00048256028840386236,0.7272514236176642 +0,391,0.0004,0.00025695334728689296,0.0004062542130680026,0.0004043363466788002,0.6354940618064533 +0,392,0.0004,0.0002722639909442202,0.00038936560487199757,0.0003935509754890401,0.6918137875427587 +0,393,0.0004,0.00028719779215390296,0.0004219324284967453,0.0004364389001162682,0.6580481072548595 +0,394,0.0004,0.0003163476628988164,0.00038145395590781717,0.0004055212539930157,0.7801013135165163 +0,395,0.0004,0.0002695744933939293,0.0004141605481003325,0.000426505148377492,0.6320544884849403 +0,396,0.0004,0.000286639958786445,0.0004205875038164435,0.0004235104350923803,0.6768191171580464 +0,397,0.0004,0.00027317257425411645,0.0004069332069266478,0.00041425320191304765,0.6594338269265949 +0,398,0.0004,0.0002889404656921276,0.0004128309342879055,0.00041627007808852436,0.6941177877086838 +0,399,0.0004,0.00027074635184266756,0.0004047392456818101,0.0004043405778790952,0.6695997548967875 +0,400,0.0004,0.00031486302735962734,0.00043551887628218497,0.00043694751175600506,0.7205969112726046 +0,401,0.0004,0.0003002607140841023,0.00045168748789348265,0.00045100859401035775,0.665753863832596 +0,402,0.0004,0.00029856583265458014,0.0004226278986899599,0.000423212867063839,0.7054743744583346 +0,403,0.0004,0.0003010103186153639,0.00042722427726011827,0.0004260915378624806,0.706445192799191 +0,404,0.0004,0.00029466589217436043,0.0004331984941557731,0.00043253307211164736,0.6812563273735054 +0,405,0.0004,0.00030051374457861483,0.0004376774487301384,0.0004401306907752064,0.6827829798674505 +0,406,0.0004,0.00033323448834528946,0.0004682785607519289,0.0004703627345478246,0.7084627753634414 +0,407,0.0004,0.00032307441321131783,0.0004928296724087771,0.0004967904598979265,0.6503233038687953 +0,408,0.0004,0.0002960842193112066,0.00043658117883937914,0.00042793027989995627,0.6918982675879508 +0,409,0.0004,0.00032024469944659083,0.0004873315157054659,0.0004906607380144124,0.6526805073960985 +0,410,0.0004,0.0003159005989141823,0.0004355677407792699,0.00043716669072432226,0.7226090313303158 +0,411,0.0004,0.00027490410741650117,0.00041562761465047425,0.000414667603275651,0.6629505301231796 +0,412,0.0004,0.00029380744949059095,0.00043223609023309976,0.0004296405371561301,0.6838448053234376 +0,413,0.0004,0.00027414888623315483,0.00038324123939303517,0.00038644959630792543,0.7094039917555285 +0,414,0.0004,0.0003066226523897618,0.00045581941282749587,0.0004498108542792607,0.6816701941998894 +0,415,0.0004,0.0002848128805477878,0.0003989174955800105,0.0003993421358680141,0.7132051816388362 +0,416,0.0004,0.0003020554609226169,0.0004474727626963568,0.00044687209016754613,0.6759327055072224 +0,417,0.0004,0.00032314843984571155,0.0004609558132938239,0.00046024534342878093,0.702122127816196 +0,418,0.0004,0.0002712224150257164,0.0004001808948279403,0.0003980390540486369,0.6813964917939317 +0,419,0.0004,0.0002862574471022162,0.00040652754520098934,0.0004050401312998868,0.7067384809093761 +0,420,0.0004,0.00029771953375309787,0.0004189899891247562,0.00041807094253893187,0.7121268269568231 +0,421,0.0004,0.00028113481968034123,0.00041593133219567036,0.00041575328018398104,0.6762058968144091 +0,422,0.0004,0.00027720721074787376,0.00040863073696372317,0.0004102884803949834,0.6756397607873544 +0,423,0.0004,0.00032220850140266525,0.00046634089713295466,0.00047283874526314455,0.6814342196584368 +0,424,0.0004,0.0003040530704332175,0.0004604308993732168,0.0004604897951674497,0.6602818859919654 +0,425,0.0004,0.00030356846787735507,0.00046791107757071905,0.00046860729227887174,0.6478099527668024 +0,426,0.0004,0.00028173929774667614,0.00042071239178576757,0.0004129322629651987,0.6822893801602049 +0,427,0.0004,0.0002897197399503473,0.0004507563791848653,0.0004419708076910973,0.6555178190701647 +0,428,0.0004,0.0003217799449416696,0.00047243034544214595,0.00047669139627381217,0.6750278009147008 +0,429,0.0004,0.00031990340933184583,0.0004747629647351718,0.0004778314953416087,0.6694900031718132 +0,430,0.0004,0.00027504437326288594,0.0004065653699915879,0.00040510320893874166,0.6789488880708353 +0,431,0.0004,0.00031106755885407586,0.0004679021268378809,0.00046574727093127505,0.667889171378476 +0,432,0.0004,0.00028044324319319194,0.0003916466446767899,0.00039166699938724086,0.7160246935073483 +0,433,0.0004,0.0002715200725699683,0.0004018701231745042,0.000402883289524095,0.6739422548170235 +0,434,0.0004,0.0003336596978395965,0.0004813794959766005,0.0004818120698107337,0.6925100443636982 +0,435,0.0004,0.0002930035161124805,0.00042115283560491257,0.00042245078877354024,0.6935802320623634 +0,436,0.0004,0.0002885807227161973,0.00041333441402239965,0.0004153948631836887,0.694714230466028 +0,437,0.0004,0.0002863448029433728,0.00041561037099504964,0.0004199525334949655,0.6818503999971834 +0,438,0.0004,0.0002732158101555931,0.0003831172190915559,0.00038584641531212667,0.7080947219234313 +0,439,0.0004,0.00027877476562692245,0.00038687110568460566,0.0003851588687306626,0.7237916305696355 +0,440,0.0004,0.000281812154421898,0.00043718819265105,0.0004396745783862225,0.6409562168826287 +0,441,0.0004,0.00027934733403353076,0.00043092594339698827,0.0004273306855839111,0.6537029599262836 +0,442,0.0004,0.0002707354050380168,0.00040694742124072357,0.000411237355679255,0.6583434148165692 +0,443,0.0004,0.0002960320713301326,0.00041714282162975844,0.000414892726490312,0.7135147290586332 +0,444,0.0004,0.00026235311673539376,0.00038939535985862365,0.0003871337631672849,0.6776807958804357 +0,445,0.0004,0.00029656875311640803,0.0004187654987269721,0.0004191559061655333,0.7075380514840865 +0,446,0.0004,0.00026017822774882063,0.0004131687282635578,0.00041377412200774874,0.6287928942640552 +0,447,0.0004,0.00029240744542614313,0.0003970641167791981,0.0003983530903280585,0.7340408610495146 +0,448,0.0004,0.00031705507462308593,0.00048471761002741597,0.00048354532841393856,0.6556884246261836 +0,449,0.0004,0.0003165166857079737,0.0004438051399145849,0.0004432598930075819,0.7140656998321293 +0,450,0.0004,0.0003076238006008935,0.0004597565506142691,0.0004600031786605816,0.668742771510014 +0,451,0.0004,0.00029105631198202386,0.0004191267351628609,0.0004212625297953748,0.690914314461821 +0,452,0.0004,0.00027840244147214944,0.0003930738034194843,0.0003930556614352431,0.7083028405075318 +0,453,0.0004,0.00032173447694240837,0.00047474083799534865,0.0004769259317705671,0.6746005102888469 +0,454,0.0004,0.0003308714898710534,0.0004726678264880628,0.00047211946193687787,0.7008215431612322 +0,455,0.0004,0.00034349641008587606,0.000493530767992776,0.0004936052809645494,0.6958928993114761 +0,456,0.0004,0.0002606879258443865,0.00039575429895587346,0.000395749334363073,0.6587198087495029 +0,457,0.0004,0.00028226955072766267,0.00040293375227049596,0.00040148563022200797,0.7030626490207811 +0,458,0.0004,0.00027820802076563905,0.0004084840972753965,0.0004051307158514383,0.6867117448277067 +0,459,0.0004,0.0002765697307844782,0.0004033211034618924,0.0004047278196567831,0.6833474679823457 +0,460,0.0004,0.0002973922103086975,0.0004101033430310325,0.00041004416534686113,0.7252687282042654 +0,461,0.0004,0.00029345092577608053,0.00042094230887539184,0.0004264029285628864,0.6882010092311128 +0,462,0.0004,0.00027390875659762484,0.0003919292355973745,0.00039183580853309247,0.6990396248445269 +0,463,0.0004,0.00028884749561180323,0.00041558677818930414,0.00041469019743298815,0.6965380358634581 +0,464,0.0004,0.0002746485364313698,0.0004156345175093755,0.000409547433568934,0.6706147174162225 +0,465,0.0004,0.00030356601391591536,0.0004545618963194499,0.00045269976085257564,0.6705680898620431 +0,466,0.0004,0.00029979415927535493,0.0004465322491465004,0.00044493249004891344,0.6737969601689398 +0,467,0.0004,0.0003221761554503148,0.00046607567238836573,0.0004662056935927359,0.6910601047523002 +0,468,0.0004,0.00029054597186458194,0.00042340123099284964,0.0004260196420664066,0.6820013519923397 +0,469,0.0004,0.0002701422577433035,0.0003980252868798725,0.00039911164503504134,0.6768588717064005 +0,470,0.0004,0.0003476067794326292,0.0004735926076435565,0.00046941744468689356,0.740506735246038 +0,471,0.0004,0.00029972125687400674,0.00042593415139125575,0.0004281402659021932,0.7000538859441844 +0,472,0.0004,0.0002562613879658325,0.0004289677471526111,0.00042927628683435653,0.5969614344542522 +0,473,0.0004,0.0003130436592896897,0.00043577702139637576,0.00043403347961661314,0.7212431160061772 +0,474,0.0004,0.0003139793238111461,0.00046859786017491335,0.00046299836152006405,0.6781434879819543 +0,475,0.0004,0.00027753743316311406,0.000380177944551919,0.0003896074561929677,0.712351441820593 +0,476,0.0004,0.00026954043109980226,0.0003960361849062199,0.0004028877148220015,0.6690212215055678 +0,477,0.0004,0.00029541460426282486,0.0003959367422699682,0.0004163122389288625,0.7095986537001713 +0,478,0.0004,0.0003350141442358822,0.0005134633326056681,0.000499667387543397,0.670474304682904 +0,479,0.0004,0.00033096531682028736,0.00048719536906413754,0.0004757355519872841,0.6956917880905686 +0,480,0.0004,0.00032082774747967753,0.00047690641716538034,0.0004673608800758365,0.68646684212769 +0,481,0.0004,0.00033955440613356194,0.0005181153873636314,0.0005057345453335346,0.6714083688106061 +0,482,0.0004,0.0002657924066793082,0.0003953348127979655,0.0003951675267460763,0.6726069038818037 +0,483,0.0004,0.0003387966291210507,0.00047812039943835865,0.00047943862161267073,0.7066527681509105 +0,484,0.0004,0.0002839524233120989,0.00042647676315961007,0.000424245132021905,0.6693121544113265 +0,485,0.0004,0.0003010835909525369,0.00042629725768913583,0.0004270661579747337,0.7050045650546485 +0,486,0.0004,0.0003242538433700883,0.00044901386335755505,0.00045572424898431886,0.7115132541065324 +0,487,0.0004,0.0002765119044926926,0.00039719796416010805,0.00040304311716425867,0.68606035611818 +0,488,0.0004,0.00031641198490524737,0.00045773351713456124,0.0004600474075658436,0.6877812584129417 +0,489,0.0004,0.0003003106574812048,0.0004260224635773121,0.0004280838704286313,0.70152294497924 +0,490,0.0004,0.0002555254545720473,0.00037650832206115575,0.000373849615931506,0.6834979726684081 +0,491,0.0004,0.00032739142463787614,0.00048546105399150687,0.00048617063986340387,0.6734084656569577 +0,492,0.0004,0.0003047333504045976,0.000452423246522627,0.000453424973532365,0.672070062728572 +0,493,0.0004,0.0003483735574659813,0.0004983347996910396,0.000497490181932826,0.7002621762554114 +0,494,0.0004,0.0002752594009152378,0.0004373983539560537,0.00043423743423278316,0.6338914594076164 +0,495,0.0004,0.00028147987864298916,0.00041596727173288597,0.0004212732583679373,0.6681646011272486 +0,496,0.0004,0.00029590997476435107,0.0004386827034311841,0.00043657924857833395,0.6777921207385489 +0,497,0.0004,0.0003123826513221379,0.0004632928712580761,0.00046309623883480076,0.6745523395053387 +0,498,0.0004,0.00029613984877518285,0.000441976809128737,0.0004435939418289983,0.6675921847673525 +0,499,0.0004,0.00030487859364103554,0.00045721537564333184,0.00045803706959497855,0.665619911311165 +1,0,0.0004,0.00025515661047640064,0.00039621162038251174,0.0003933312817028221,0.648706630634026 +1,1,0.0004,0.0003262691231997483,0.0004249011175396702,0.00042902440789850617,0.7604908186877177 +1,2,0.0004,0.0002642308391569838,0.00038953365346443703,0.00038955507945149544,0.6782887789039442 +1,3,0.0004,0.0002708010191475595,0.000384474253179022,0.0003857379929771583,0.7020335670269201 +1,4,0.0004,0.000306200840390601,0.0004394210805827397,0.00043939414381026536,0.696870553929871 +1,5,0.0004,0.00029178336888494624,0.0004287148010830519,0.00042892897529961377,0.6802603360641022 +1,6,0.0004,0.0002941874295986627,0.00046813504172149735,0.0004674603251771972,0.6293313330647835 +1,7,0.0004,0.0002902389527676527,0.0004050102207214697,0.000405359791980648,0.7160033099225313 +1,8,0.0004,0.0003133599442318005,0.00046489802345167283,0.0004617214251068742,0.6786775037768008 +1,9,0.0004,0.00032321478553477405,0.0005063531943474071,0.0005137522246939552,0.6291258120143708 +1,10,0.0004,0.0003004339330096213,0.00041925993141318384,0.0004202782303912147,0.7148453364571449 +1,11,0.0004,0.00032118628929484524,0.0005224741716654994,0.0005223515199300342,0.6148853349519614 +1,12,0.0004,0.00029309760308647743,0.00039821281987854787,0.0003986573007448331,0.7352119289898047 +1,13,0.0004,0.0002706471905964297,0.0004178316525154893,0.00041673860028957856,0.6494411374621056 +1,14,0.0004,0.0002865724533720641,0.00041225729241084735,0.0003969706355947346,0.7218983664691626 +1,15,0.0004,0.0003277702662588752,0.00047171112428795643,0.00047795786132829216,0.6857723091905408 +1,16,0.0004,0.0002872761392188075,0.000442016355022246,0.0004458144904128491,0.6443849300474144 +1,17,0.0004,0.00029654282584069597,0.0004485728237177463,0.0004355646784846973,0.680823860356056 +1,18,0.0004,0.0002843274235602303,0.0004284005539458565,0.000420871472937531,0.6755682954126767 +1,19,0.0004,0.00027882332503139057,0.00041759782573143746,0.0004087664399552594,0.6821091405202162 +1,20,0.0004,0.0002623764476296483,0.00040697137597873236,0.0003996109790197746,0.6565796772482186 +1,21,0.0004,0.0003037296108525705,0.00045758009103135695,0.0004525111942190504,0.6712090545665969 +1,22,0.0004,0.00029837894713292176,0.00042627179918338525,0.00042646331014295046,0.6996591266735354 +1,23,0.0004,0.0003245833168455834,0.00046869859361591617,0.00046842284089427627,0.692928031062521 +1,24,0.0004,0.0003054181865680971,0.0004619654435359572,0.00046137907965086597,0.6619679999344847 +1,25,0.0004,0.0002775665444095108,0.00043731255935219784,0.0004372631044313357,0.6347815344962351 +1,26,0.0004,0.0002986331451398517,0.00042323522622615423,0.00042304519652193944,0.7059130976904128 +1,27,0.0004,0.0002889331869403233,0.0003972476633842453,0.00039697988499788953,0.7278282801201864 +1,28,0.0004,0.0002597256056337452,0.00039210076739810214,0.00039196106624616727,0.6626311335489303 +1,29,0.0004,0.00031081677139344554,0.0004659658079087262,0.00046662956865060656,0.6660888899352467 +1,30,0.0004,0.0002658137337003768,0.00040103920378546296,0.0004033932128770455,0.6589444869549578 +1,31,0.0004,0.00028678417895214477,0.0004312834290098877,0.00043225893438759766,0.663454601252941 +1,32,0.0004,0.00030588160846088544,0.00044955420487636084,0.00044947560887473526,0.6805299384913495 +1,33,0.0004,0.0003468900123343806,0.0004900669907699899,0.0004903657749641168,0.707410733058939 +1,34,0.0004,0.0003041334374660594,0.00044684252773542803,0.00044710424957865487,0.6802293598252996 +1,35,0.0004,0.00029969664230181906,0.0004303242822316899,0.0004296941542745328,0.6974650209235614 +1,36,0.0004,0.0002680651996415876,0.0003814524159679303,0.00038140344236103023,0.7028389622866631 +1,37,0.0004,0.0002922002453382081,0.000444759769189167,0.00044517752600233365,0.6563679167772641 +1,38,0.0004,0.0003215860111754685,0.00042865729825320294,0.00042927355094251354,0.7491400540969595 +1,39,0.0004,0.000291778453551042,0.00041276702140082136,0.00041295321792373063,0.7065653950296407 +1,40,0.0004,0.00026953386839258876,0.0003930945432203705,0.0003928006933055912,0.6861848081894721 +1,41,0.0004,0.0002800040825691152,0.0004010950402270234,0.0003997640615650706,0.7004233483943085 +1,42,0.0004,0.0003221767511526004,0.0004720691793210722,0.0004801851144244131,0.6709428124168036 +1,43,0.0004,0.00027591608138342834,0.0003985346085551571,0.000399139050609679,0.6912780920883852 +1,44,0.0004,0.0002703791026995758,0.0004080208284039408,0.0004057431718711492,0.6663799207086579 +1,45,0.0004,0.00029108898494678527,0.0004270014564596443,0.0004287523870675212,0.6789209663360865 +1,46,0.0004,0.00029704147347572776,0.0004354956151245175,0.00043396703797100416,0.6844793440177703 +1,47,0.0004,0.0003092490842929891,0.00045641023839960814,0.0004556658712193933,0.678675107849129 +1,48,0.0004,0.00033159760615587223,0.0004940657920416709,0.0004945123191575586,0.6705547937021576 +1,49,0.0004,0.00030280373790484723,0.00045497310250773197,0.00045515717311350783,0.6652729118460659 +1,50,0.0004,0.00028915569951611894,0.00041545599644299155,0.0004158387200679873,0.695355399970555 +1,51,0.0004,0.00029807779711666944,0.00042035686356974304,0.0004194609877366405,0.7106210251519701 +1,52,0.0004,0.0002998017503519124,0.00044944494445280396,0.00045037157032055074,0.6656764549736772 +1,53,0.0004,0.00028308202596574115,0.00043971847267864944,0.00043841607935479,0.6456926178034995 +1,54,0.0004,0.0003094302492831121,0.0004323466897635117,0.00044175913991083515,0.7004501352152388 +1,55,0.0004,0.0002861683645449784,0.00043527595653154716,0.00043070770511124094,0.6644143142762406 +1,56,0.0004,0.00031099552940378237,0.00042604823768805635,0.0004368201992514858,0.7119531787602529 +1,57,0.0004,0.00030805091515646383,0.0004704032812745531,0.0004646408215166246,0.6629871954662984 +1,58,0.0004,0.0002742019601687652,0.00040115800960585326,0.00040380870192806084,0.6790392551213884 +1,59,0.0004,0.00034563932057955153,0.00045831829279793665,0.0004614428202493366,0.7490404128355239 +1,60,0.0004,0.00031579419102664697,0.0004407982644181247,0.0004460010142100511,0.708057114143509 +1,61,0.0004,0.0003187558329738929,0.0004537360790970053,0.00046110652562764837,0.6912845844894719 +1,62,0.0004,0.00028741647844670465,0.0004273187537643601,0.00042797396547289575,0.6715746789156201 +1,63,0.0004,0.00030283849362598806,0.0004508240045542445,0.0004542847932438364,0.6666269664532666 +1,64,0.0004,0.0003050747051091466,0.000426676658445572,0.0004267622674895469,0.7148586657010839 +1,65,0.0004,0.0002725522140529276,0.0004055988941995388,0.0004070035556459088,0.6696556093235871 +1,66,0.0004,0.00029678018366326457,0.00044202678296815774,0.00043860900580474743,0.676639512038155 +1,67,0.0004,0.00033014376266164887,0.00047158997652399336,0.00047116995860268244,0.7006893301108041 +1,68,0.0004,0.0002866996898688901,0.0004368914805802953,0.0004371414515032216,0.6558510726516569 +1,69,0.0004,0.0002886795239367257,0.0004034611539667497,0.0004035682959824883,0.7153176471257101 +1,70,0.0004,0.00027280918769425374,0.00038839792487411145,0.0003877382558189966,0.7035911045661848 +1,71,0.0004,0.00029082715354077456,0.00046396752707545904,0.0004665250697814326,0.6233901935367103 +1,72,0.0004,0.0003096908171450015,0.0004533061348697313,0.0004463195803179665,0.6938768335558388 +1,73,0.0004,0.0002893480630285143,0.000419032587821663,0.0004087132215950441,0.7079488691344622 +1,74,0.0004,0.0003126433869635358,0.00043251088206768776,0.00041908125303571176,0.7460209319763919 +1,75,0.0004,0.00029756974649446143,0.00043104185711622365,0.00043210415165572335,0.688652829078922 +1,76,0.0004,0.0003213891519458902,0.00047769931626467373,0.0004779811383245792,0.6723887747378994 +1,77,0.0004,0.0002813820163122251,0.0004127312068131747,0.0004133403309751922,0.6807514177200218 +1,78,0.0004,0.00030134363070916125,0.00043086799345463576,0.0004292914057737252,0.7019558897668596 +1,79,0.0004,0.00030637952868714047,0.000439282063443019,0.00043792426232230626,0.6996176166682662 +1,80,0.0004,0.0002881915103741507,0.0004283584634930913,0.00042760571880358936,0.6739655194053302 +1,81,0.0004,0.0002611291222079435,0.0003675939903283988,0.0003680280187642364,0.7095359833872493 +1,82,0.0004,0.0002877144031162418,0.0004523035399475351,0.00045109883078707925,0.637807911437581 +1,83,0.0004,0.00029928979684934074,0.00044937881488305335,0.00045196666874681296,0.6621943995985239 +1,84,0.0004,0.00025144557952483615,0.00038296098464746546,0.00038154682829583044,0.6590163012176294 +1,85,0.0004,0.00030796542517415597,0.0004570547039306531,0.0004619919570252572,0.6666034343046354 +1,86,0.0004,0.00029767825184078337,0.000410371076190698,0.0004137434768837422,0.7194753959212945 +1,87,0.0004,0.00028460518814496977,0.0004082615720274316,0.00041144109151627597,0.6917276713809011 +1,88,0.0004,0.00027097618005579983,0.00039940390967455964,0.00039543808932188785,0.6852556376662653 +1,89,0.0004,0.0003043888764157928,0.0004607903774306332,0.00047710803425663113,0.6379873206076957 +1,90,0.0004,0.0002926578041518725,0.00040056528296528393,0.00039976293790456566,0.7320783804669204 +1,91,0.0004,0.0002909494903734002,0.00042391273128302006,0.0004291072501376577,0.6780344314389084 +1,92,0.0004,0.0003375179652439452,0.0004901780068292508,0.0004905034096275878,0.6881052376378056 +1,93,0.0004,0.0002801427815241129,0.00040700816964614716,0.0004068285774414581,0.6886015315982195 +1,94,0.0004,0.00025731311681595145,0.00040688874690654876,0.00040853336928884276,0.6298460203235564 +1,95,0.0004,0.0002636657517271192,0.00040840625823832693,0.0004095091668755939,0.6438579964858736 +1,96,0.0004,0.0002850682684453767,0.000433998244091335,0.0004320909490372036,0.6597413555654736 +1,97,0.0004,0.00029702426244215086,0.0004254342040958043,0.0004271370626924389,0.6953839607592749 +1,98,0.0004,0.0003273133281798133,0.0005186547085448034,0.0005152386537162577,0.6352654751715601 +1,99,0.0004,0.00028864711755006067,0.0003940461222208822,0.0003933362352138796,0.7338431898935184 +1,100,0.0004,0.00031406303493886295,0.0004675823769078324,0.00046734409226845033,0.6720167006165124 +1,101,0.0004,0.0002505998066941156,0.00037438738765036445,0.00037299437072641525,0.6718594873323869 +1,102,0.0004,0.00030558127455392417,0.00041654748956185424,0.0004164668202866863,0.7337469869594149 +1,103,0.0004,0.0002945510182221718,0.00044642325250973653,0.0004482381978907552,0.6571305605105077 +1,104,0.0004,0.00027438206905279385,0.00038850600654145596,0.00039503237371956747,0.694581222468559 +1,105,0.0004,0.00028010339082758023,0.00039506321128766854,0.0003954530367420314,0.708310127380061 +1,106,0.0004,0.0002863520532856413,0.00040783347709231707,0.0004059061425516456,0.7054637101216255 +1,107,0.0004,0.0003289636750498164,0.0004727050424257292,0.0004751261615586476,0.6923712093029221 +1,108,0.0004,0.0002741882889156863,0.0003988002639843973,0.0004015246549648734,0.6828678775396075 +1,109,0.0004,0.00027224300600449836,0.0004032497786548896,0.00040536580191237286,0.6715983556584001 +1,110,0.0004,0.000294515332033142,0.000404901946848519,0.0004062663688022257,0.724931608051748 +1,111,0.0004,0.000288859122601034,0.0004326111584748531,0.00043525703418529775,0.6636518193019273 +1,112,0.0004,0.0003084984054999421,0.0004559350405253517,0.00045036863738702796,0.6849908716774864 +1,113,0.0004,0.00032027886510730313,0.00048287700041223344,0.0004766682374077799,0.6719114888985379 +1,114,0.0004,0.0002867275400907161,0.00041847206477143016,0.0004158281286690121,0.6895337768718947 +1,115,0.0004,0.0003146349656397591,0.0004379180294731998,0.0004354217190827739,0.7225982348848952 +1,116,0.0004,0.0002660675376888736,0.00040913641568308474,0.00041100770049707735,0.6473541429201656 +1,117,0.0004,0.00028554536461218577,0.00040755664122302753,0.0004038400564527775,0.7070753880146003 +1,118,0.0004,0.0002794782061953997,0.0003997945669083691,0.0004045938483822617,0.6907623714816042 +1,119,0.0004,0.00029582731812969443,0.0004282104066993282,0.0004276050891232245,0.6918236607900726 +1,120,0.0004,0.0002736359886873267,0.00038654890770766734,0.00038712691249671643,0.7068379382940669 +1,121,0.0004,0.0002717092815167238,0.0003916907218755794,0.0003896997559625519,0.6972272303471333 +1,122,0.0004,0.00026914551666189235,0.0004232932443853129,0.00042762509734910285,0.6293959786980613 +1,123,0.0004,0.0003602500151635435,0.0004968380305799115,0.0004930245776026516,0.730693826492933 +1,124,0.0004,0.0002724738310032801,0.0004361944311952245,0.00044206942797639544,0.6163598153587517 +1,125,0.0004,0.0003020665167410432,0.000444829204219727,0.0004484490042997334,0.6735805272056054 +1,126,0.0004,0.00026394671286986593,0.00038947635988999897,0.00039221485191869406,0.6729646049318447 +1,127,0.0004,0.00029873728615634665,0.0004199408374282196,0.00041931569094755353,0.7124400364824688 +1,128,0.0004,0.00025685494880833885,0.00042372286344511295,0.0004206739327830514,0.6105796646563391 +1,129,0.0004,0.0003164561969559955,0.00040672205474810697,0.0004107215291730316,0.7704884562374053 +1,130,0.0004,0.00027221271669817436,0.00045867723691070617,0.00045639064371092347,0.5964467511533674 +1,131,0.0004,0.0002877328208885535,0.000453538802613913,0.00045408183312298917,0.6336585168132467 +1,132,0.0004,0.0002774634840300284,0.0004078452607872985,0.0004136586453514218,0.6707547083763004 +1,133,0.0004,0.00031530459633663364,0.0004302966401655959,0.0004320480162730444,0.7297906354403173 +1,134,0.0004,0.00029442209208720534,0.0004261308272018022,0.0004275026418032484,0.6887023922128384 +1,135,0.0004,0.00034068411808344017,0.00046961836568681025,0.0004712103817250841,0.722997903476167 +1,136,0.0004,0.00026899900207808853,0.00041834421649006504,0.00041834326159173374,0.6430102424850527 +1,137,0.0004,0.00030266842794716975,0.00044977520978819145,0.0004497030035596647,0.673040708092609 +1,138,0.0004,0.00031135040756336143,0.0004596211189785302,0.0004587156757139687,0.6787437710271392 +1,139,0.0004,0.00034219241077831485,0.00048675149774404,0.00048602354774661134,0.7040654971654111 +1,140,0.0004,0.00026010283572832726,0.0003621178910396458,0.00036195816332670216,0.7185991699641799 +1,141,0.0004,0.0003446848302537081,0.0005125950784528121,0.0005127660735881616,0.6722067781156456 +1,142,0.0004,0.00030881227205945363,0.00047726430737923315,0.00047734913736504253,0.6469316646597312 +1,143,0.0004,0.00032913958195150716,0.0004922976998141786,0.000492357152651613,0.668497614341358 +1,144,0.0004,0.00030693441078674606,0.0004486304471626422,0.0004481665212159656,0.6848668882137191 +1,145,0.0004,0.00031315292852143853,0.00044073140175687026,0.0004358872426797036,0.7184264595501088 +1,146,0.0004,0.00033687915721823024,0.0005077278623139939,0.0005064541700248314,0.6651720474563633 +1,147,0.0004,0.0002684655965688332,0.0003854418442747593,0.00038542076360942475,0.6965519814103455 +1,148,0.0004,0.0002917314977889862,0.00044906397548202153,0.0004449363349364779,0.6556702046611583 +1,149,0.0004,0.00031693938061046965,0.00044457346809931617,0.00044350998899764005,0.7146161044236505 +1,150,0.0004,0.00028532969160748257,0.00040263093023517,0.00040531598089197057,0.703968521003202 +1,151,0.0004,0.0003204838854239122,0.00045142308204557574,0.0004518991238627879,0.7091934206122119 +1,152,0.0004,0.0002751600195428987,0.00041124880795073747,0.00041623653990044613,0.661066468620728 +1,153,0.0004,0.00025387178826205006,0.00038344834582672283,0.0003801288876244566,0.6678571309025569 +1,154,0.0004,0.00032578541148831384,0.0004651617725970638,0.00046930138851869474,0.6941923025555593 +1,155,0.0004,0.00026323423991115935,0.0003917444767199589,0.00038896556449518255,0.6767546125909549 +1,156,0.0004,0.00031373020509576613,0.0004601163716627347,0.0004595884813602479,0.6826328722756849 +1,157,0.0004,0.0002713702453843465,0.00039396111239871747,0.0003939755608806334,0.6887996930006686 +1,158,0.0004,0.00028913801237330207,0.0004312425496883071,0.0004308537087503428,0.6710816374586263 +1,159,0.0004,0.0002874029416432526,0.00042201604497891934,0.0004226545575868476,0.6799948953210961 +1,160,0.0004,0.0002487781482194965,0.0003876998940059096,0.00039126072223603616,0.6358372667661129 +1,161,0.0004,0.00030955983496332797,0.0004202345699664287,0.0004287814886962058,0.7219524236099962 +1,162,0.0004,0.00026029593701493023,0.00037328728921363273,0.000374977712638918,0.6941637549151628 +1,163,0.0004,0.00027361878832320727,0.0004089593605414024,0.0004131504560892909,0.6622739592572838 +1,164,0.0004,0.00033283906471553786,0.00048343551587382244,0.0004744620357018828,0.7015083182011839 +1,165,0.0004,0.0002955130411723301,0.00041522294657657865,0.00041322028776830545,0.7151464967228948 +1,166,0.0004,0.00026929504444114213,0.0003982154977334136,0.0003983506138096754,0.6760251775833999 +1,167,0.0004,0.00032648295275938013,0.00047568633698580304,0.0004750622794985611,0.6872424245174553 +1,168,0.0004,0.0003289225417359007,0.00046475122319807467,0.0004653424490242619,0.7068397530154217 +1,169,0.0004,0.0002760046517504163,0.00039808977320541936,0.00039848485357191877,0.6926352388964838 +1,170,0.0004,0.0002882779456431977,0.00043669587099479936,0.00043684891963504,0.6599030756080063 +1,171,0.0004,0.0002962482552116819,0.00046687837713100573,0.00046620351405171785,0.6354483530958925 +1,172,0.0004,0.000289210825060794,0.00041057320841527545,0.0004100707245538268,0.7052705978352073 +1,173,0.0004,0.00030031164250169436,0.000473583425790433,0.0004736620120339126,0.6340209577123382 +1,174,0.0004,0.00029133527725041104,0.0004252368583947875,0.00042542908418298037,0.6848033857626562 +1,175,0.0004,0.000306943549721308,0.0004454070813058209,0.00044555737540451896,0.6888979212668979 +1,176,0.0004,0.0002776262437653274,0.0004065214107068646,0.00040750675852811957,0.6812800964776394 +1,177,0.0004,0.00030500771172038113,0.0004553068166966529,0.00045505913589280803,0.6702595062111391 +1,178,0.0004,0.000307744249526587,0.0004653895790837178,0.0004652156844285914,0.6615087578239732 +1,179,0.0004,0.0002963611510292397,0.0004346186929130924,0.00043570059912264973,0.6801944996770914 +1,180,0.0004,0.00032817135518944484,0.0004553912055834984,0.0004502838781242027,0.7288099155504846 +1,181,0.0004,0.0003141110387284186,0.00044087274630175724,0.0004450411091796526,0.7058023006176254 +1,182,0.0004,0.0002842481030598333,0.00042516662130663894,0.0004259072445742452,0.6673943838264119 +1,183,0.0004,0.0002619210615769254,0.0003944026823245705,0.0003915894721616771,0.6688664537661141 +1,184,0.0004,0.0003193399274500496,0.00044818606090956287,0.00045256973195315916,0.7056148586691193 +1,185,0.0004,0.0002822479186077642,0.00043274437939972685,0.0004400242186601595,0.6414372360393884 +1,186,0.0004,0.0002783090462092409,0.0004063543554413623,0.0004120391653078102,0.6754431851189014 +1,187,0.0004,0.0002620696475152618,0.0003648755773909933,0.0003699077920946832,0.7084729035612781 +1,188,0.0004,0.00025583554915238865,0.00037523616239005565,0.00037663688434425176,0.6792631305821634 +1,189,0.0004,0.0003100490152705404,0.00048179059242468717,0.00048011329598891643,0.6457830221758698 +1,190,0.0004,0.0002819239822576057,0.00040977981779643965,0.000405559182322139,0.6951488082291062 +1,191,0.0004,0.00027817735396367294,0.00045683624198583216,0.0004438481089796084,0.6267399777892333 +1,192,0.0004,0.0003081928280281813,0.00043513434251462983,0.0004470374434859332,0.6894116645463482 +1,193,0.0004,0.00028965575299956883,0.0004009985594608435,0.00040639223044936705,0.7127492390277315 +1,194,0.0004,0.0003031955185514195,0.00044785260928849134,0.00044409186457595984,0.6827315308757684 +1,195,0.0004,0.0003009299320625077,0.0004243077678343575,0.00042920590896708145,0.7011318478506501 +1,196,0.0004,0.00028611869639449125,0.00042357503830240664,0.0004188622420583128,0.6830854339806037 +1,197,0.0004,0.0003151175848400251,0.00047800308812748075,0.0004703456597832631,0.6699702193174959 +1,198,0.0004,0.00028004003382104374,0.00042029648702460697,0.0004081820708615814,0.6860664733018322 +1,199,0.0004,0.0002732826907846906,0.0004067822342306716,0.0004073603393818181,0.6708622916001237 +1,200,0.0004,0.000312682395941377,0.0004467924043706094,0.00044973752535004663,0.695255295181351 +1,201,0.0004,0.00030455571914043625,0.00043468493878349437,0.00043405696653993624,0.7016491903544071 +1,202,0.0004,0.00028362108594263963,0.0004337791343235363,0.00043708146243844504,0.6488975404272207 +1,203,0.0004,0.00028117485172788064,0.000394756013961596,0.0003941346152166461,0.7133980139585703 +1,204,0.0004,0.0002705971760912148,0.0003959164469922703,0.00039569042070480473,0.6838608213189151 +1,205,0.0004,0.00031008736501964576,0.00045249858019600963,0.0004524854090147526,0.6852980424160723 +1,206,0.0004,0.0002594990105212139,0.00037274762618493354,0.0003725848684759153,0.6964829559040143 +1,207,0.0004,0.0003097963532939163,0.0004431905477012512,0.00044336132807938633,0.6987446438685458 +1,208,0.0004,0.0002968673143039528,0.0004462949786027536,0.0004456464707299381,0.666149815609904 +1,209,0.0004,0.00032332024882961386,0.00046092827613380396,0.0004609761719713009,0.7013816949517792 +1,210,0.0004,0.0002640707616467759,0.00040920733060609835,0.0004088164876944173,0.6459396076123131 +1,211,0.0004,0.0003022938349764185,0.00044841692358325093,0.000447406351256898,0.6756583453211714 +1,212,0.0004,0.00028241612035943934,0.00040117704833632394,0.0004017161271718732,0.7030241039802924 +1,213,0.0004,0.00030372873337948514,0.0004529345159258864,0.00045593161587002384,0.6661716862953228 +1,214,0.0004,0.00027413481815183175,0.00043049706275629203,0.0004347020153520932,0.6306269777235615 +1,215,0.0004,0.0002896202241345227,0.00041953707133125995,0.00041596881348545636,0.6962546583907516 +1,216,0.0004,0.0003056396831931958,0.0004597079713410508,0.0004630584666544344,0.6600455562370373 +1,217,0.0004,0.00028254969288560885,0.00043128134453187633,0.0004340817254433369,0.6509135868298414 +1,218,0.0004,0.00033489950878617616,0.00047332708682769207,0.00047785083532848226,0.7008452931885343 +1,219,0.0004,0.0002652455589799409,0.0003997491604105052,0.00040723976779276166,0.6513252878459563 +1,220,0.0004,0.0002624597965354846,0.0003953400771404582,0.0004006064012387774,0.6551562724007699 +1,221,0.0004,0.00031121521472333015,0.0004426791885106952,0.0004481819850850505,0.6943947438321768 +1,222,0.0004,0.0002921869112656498,0.00043193157623318447,0.00043624575631676484,0.6697759394442987 +1,223,0.0004,0.00025628206917454596,0.0003902247299329695,0.0003951489511574116,0.6485707944406346 +1,224,0.0004,0.0002607385781102218,0.000387553549890982,0.00038761321478922404,0.6726772157445818 +1,225,0.0004,0.00030716450772638526,0.00044101234660949904,0.00044087985584293925,0.6967079662533068 +1,226,0.0004,0.00028489673047289125,0.00043294203496476634,0.0004319996308511271,0.6594837359272432 +1,227,0.0004,0.00030116945111625254,0.0004506072724709565,0.00045010605414370696,0.6691077543695892 +1,228,0.0004,0.0003232736907200729,0.00043492131581744067,0.0004346390039239524,0.7437751508758639 +1,229,0.0004,0.00028188758054640975,0.00041803391212669167,0.0004184379935821281,0.673666313456029 +1,230,0.0004,0.00027553977235716997,0.00040204895575104396,0.00040163650225356776,0.6860426550154838 +1,231,0.0004,0.00029060478376016297,0.00042385383885514477,0.000421396832498061,0.6896226106813467 +1,232,0.0004,0.00028224776652624716,0.0004271137576639686,0.0004235338151179841,0.6664114090810463 +1,233,0.0004,0.0003113196503721313,0.0004416601769665954,0.00044860362894842513,0.6939748817946432 +1,234,0.0004,0.0003143164027261078,0.0004334932985023969,0.0004404882720687842,0.7135636126017582 +1,235,0.0004,0.00026491437775642265,0.0004037188207263296,0.00040261933181548503,0.6579772922523981 +1,236,0.0004,0.00031881783431570864,0.0004512222992910859,0.00046512969210391465,0.685438577085037 +1,237,0.0004,0.0002669517555179327,0.0003901376231990362,0.00039776030578085906,0.6711372443106637 +1,238,0.0004,0.0002740287092772495,0.00039850602061753337,0.000401949797013219,0.6817485947585575 +1,239,0.0004,0.00034391425421272136,0.0004692274052231905,0.0004683383253726594,0.7343286585377502 +1,240,0.0004,0.0002917605307514708,0.0004128856629388251,0.0004144946832127204,0.7038945071383172 +1,241,0.0004,0.00032989165805683473,0.00047497846134839436,0.00047765761335769003,0.6906446141156721 +1,242,0.0004,0.0002791127091330394,0.0004014185731943708,0.00039860496336572323,0.7002238677016955 +1,243,0.0004,0.000294008485822217,0.00044813464928253983,0.0004471715806834784,0.657484729626244 +1,244,0.0004,0.00026141245343497195,0.0003707760579458034,0.0003703440945708116,0.705863701533895 +1,245,0.0004,0.0002733982491086125,0.00038535744697359195,0.00038345333407399315,0.7129896256316189 +1,246,0.0004,0.0002882283461168742,0.0004116551592068821,0.0004102433531428752,0.702578954439496 +1,247,0.0004,0.0002860584352847508,0.00043476830918311795,0.00042975575087849754,0.6656302671924604 +1,248,0.0004,0.0002823461586496203,0.0004065506701086005,0.00040914766826363687,0.6900837534962775 +1,249,0.0004,0.00034300165845072955,0.0004938708149262958,0.0004915834974957658,0.6977485212543856 +1,250,0.0004,0.00029026550186557866,0.0004232039447173644,0.00041371265033732956,0.7016113759850089 +1,251,0.0004,0.00027246330967332347,0.00040066343231862686,0.00040868905896043045,0.6666762999880149 +1,252,0.0004,0.0003163128820888175,0.00045434556797407797,0.0004532915509985754,0.6978133199085628 +1,253,0.0004,0.00030744867487651474,0.00043180473051802963,0.00043167850291667115,0.7122167835535302 +1,254,0.0004,0.00030600415472174634,0.00047434157672220995,0.0004742282211606864,0.6452677024846664 +1,255,0.0004,0.00028137457741533466,0.00039961994589786,0.0003989793281722961,0.7052359797794467 +1,256,0.0004,0.00027776387191545557,0.00041341185888528974,0.00041228923052605,0.6737111992012254 +1,257,0.0004,0.00034957914171959795,0.0004735740983752344,0.0004736954906369182,0.7379828362933395 +1,258,0.0004,0.0003292461152156907,0.0004707405870796931,0.0004706217787975597,0.6995981275174211 +1,259,0.0004,0.0002871601500122553,0.0004259273702685967,0.00042677549393455754,0.6728599792946145 +1,260,0.0004,0.00030441458484338485,0.0004211733835167869,0.0004212914201778643,0.7225748502422968 +1,261,0.0004,0.00030115720211164093,0.0004138181068981413,0.000415010993006303,0.7256607829351333 +1,262,0.0004,0.0003099102228980379,0.0004292540232828905,0.0004317989659808261,0.7177187703404537 +1,263,0.0004,0.0002943604590577543,0.0004581882992525319,0.0004410325768748152,0.6674347304310515 +1,264,0.0004,0.0002996918752717468,0.0004334455729373769,0.00043571477564166377,0.6878166452592749 +1,265,0.0004,0.0003473616938208725,0.00047451264114133134,0.00047319355483503036,0.7340795120127394 +1,266,0.0004,0.00026915350036926957,0.00041402978287102,0.00041438467638797304,0.6495257081303631 +1,267,0.0004,0.00028136975550597913,0.0003987740655980179,0.00039780843090418905,0.7072996287847559 +1,268,0.0004,0.00030763107112964216,0.00042109288356036796,0.00042493451910482886,0.7239493552505472 +1,269,0.0004,0.00031001314070827347,0.0004584011978372874,0.00045439679151731076,0.6822520459994559 +1,270,0.0004,0.0003049908553223767,0.0004677476286103466,0.0004694520156774403,0.6496741842342743 +1,271,0.0004,0.000321237429426928,0.0004913688083382986,0.0004965409680091683,0.6469505038323374 +1,272,0.0004,0.00031342947778934476,0.00046385793564845056,0.00046227186348966637,0.6780198029429736 +1,273,0.0004,0.0003401859473792292,0.0005038445813914529,0.0005008836976669676,0.679171530165103 +1,274,0.0004,0.0002684282374791275,0.0003867108352166054,0.00038664653910325475,0.6942470973662154 +1,275,0.0004,0.0002674413821182964,0.0003933676189670359,0.00039337763750647305,0.6798591394608587 +1,276,0.0004,0.0002910385147641331,0.0004037986498546651,0.000404499633647227,0.7195025422889608 +1,277,0.0004,0.00028223423815441304,0.0004255605704419078,0.0004253597394525673,0.6635189275732701 +1,278,0.0004,0.00033362461826326874,0.0005117423980788312,0.0005120485133678237,0.6515488465516033 +1,279,0.0004,0.00028246471228624026,0.00039761557659115355,0.0003988341935246704,0.7082259166145644 +1,280,0.0004,0.00030236060526973196,0.00044236571772240246,0.0004460877907971501,0.6778051574319475 +1,281,0.0004,0.0003126855635502111,0.00045763133442960896,0.00045463333125759245,0.6877752730651536 +1,282,0.0004,0.00027682683931594426,0.0004045379699795659,0.0004040062360615066,0.6852043721270671 +1,283,0.0004,0.0002859615718233337,0.0004177099023428034,0.00041915186560141627,0.6822385757797459 +1,284,0.0004,0.0002733347787509205,0.0003880566406303315,0.0003864942766575641,0.7072155922068065 +1,285,0.0004,0.0002673654752294517,0.00038268819789564996,0.00038539608522152594,0.6937420629889632 +1,286,0.0004,0.0002884374442880453,0.0004086126063253243,0.0004104860034282372,0.702673031185267 +1,287,0.0004,0.0002897696839470748,0.0004051569862973734,0.0004061694208927107,0.7134207280060534 +1,288,0.0004,0.00027136969973988126,0.0003820522412655342,0.00038246399383097453,0.7095300580368094 +1,289,0.0004,0.0002860311810733747,0.0004019051495408482,0.0004020400664257661,0.7114494423808587 +1,290,0.0004,0.0002809352744722074,0.00040415362193890503,0.00040406178860501884,0.6952780054805655 +1,291,0.0004,0.0002833016020281212,0.00040704920231240455,0.0004069592383370763,0.6961424519707502 +1,292,0.0004,0.0002807144336630138,0.0004145672172706295,0.00042065271996576104,0.667330603938238 +1,293,0.0004,0.0002884696721819445,0.0004038156935937138,0.00041289365645278656,0.6986536791584986 +1,294,0.0004,0.00025940632669500666,0.0003866618887723878,0.00038523458128103663,0.6733723795833488 +1,295,0.0004,0.00028417791252973904,0.00042429385086443605,0.0004238876450911875,0.6704085760003836 +1,296,0.0004,0.0003126131842438659,0.0004696924936587798,0.00046965708416843,0.6656200763954738 +1,297,0.0004,0.0002889791361225834,0.00039240532760645224,0.0003910014659043701,0.739074303606987 +1,298,0.0004,0.0002735057310278268,0.0003895512552768704,0.00039073190210687386,0.6999831074786848 +1,299,0.0004,0.0002914209123039623,0.00041682314493073373,0.00041752351524724417,0.697974848509771 +1,300,0.0004,0.000308172208140825,0.00045920229266863344,0.00046049826504521125,0.6692146996700823 +1,301,0.0004,0.000313928581043127,0.00045583868890844117,0.00044869602241736674,0.6996464540778073 +1,302,0.0004,0.0002953906471920756,0.0004364708075665509,0.0004297054951107436,0.6874258080314929 +1,303,0.0004,0.0002951307028606088,0.0004233088981048885,0.00042291076927657216,0.6978557282082389 +1,304,0.0004,0.0003071320224021,0.00048547230742703855,0.00048186537740766794,0.6373813865905954 +1,305,0.0004,0.0003404183331863004,0.0005129094263572167,0.00050111240086613,0.6793253022633572 +1,306,0.0004,0.0002513346032532704,0.0003836923861883252,0.0003799084198389381,0.6615662884224137 +1,307,0.0004,0.00028689385154436457,0.0003959397017190254,0.00040256209593738973,0.7126698078126685 +1,308,0.0004,0.0002785929672708665,0.00039451209688230005,0.00039834835805230956,0.6993701910383744 +1,309,0.0004,0.0002832362056767316,0.0004170975113956839,0.0004135278606207762,0.6849265373596485 +1,310,0.0004,0.0002708772989394965,0.00040587150423235935,0.0004068496830328483,0.6657920854706095 +1,311,0.0004,0.00027966670404807546,0.00041579141152379344,0.00041611689989242697,0.672086868186257 +1,312,0.0004,0.0003203842539618069,0.00048574404768143945,0.0004857313701829611,0.6595914401022263 +1,313,0.0004,0.00030420915740892693,0.00045995799446488093,0.00045432893478333385,0.669579095934099 +1,314,0.0004,0.0002821377607166109,0.0003938316206360227,0.00039869811521469245,0.7076475908713146 +1,315,0.0004,0.0002783751713610236,0.00040772355157343604,0.00040424727701719385,0.6886259653127693 +1,316,0.0004,0.00030365190285595753,0.00045507432532709515,0.0004497641064023115,0.6751359179924032 +1,317,0.0004,0.00027667333429441616,0.0003870737009735814,0.0003869267625176166,0.7150534961556694 +1,318,0.0004,0.0002895719026629068,0.0003977136580232204,0.00039828916224496586,0.7270393726777004 +1,319,0.0004,0.0003011702927206531,0.0004395983327905061,0.00043890119171465826,0.6861915583871373 +1,320,0.0004,0.0002877873375271286,0.00040353235786491913,0.0004039238111681901,0.7124792586374579 +1,321,0.0004,0.00029899453093420114,0.000416896504038244,0.0004181724916030792,0.7150028682852737 +1,322,0.0004,0.0002941642879867529,0.00040369463795277705,0.00040471541552839933,0.7268423111649699 +1,323,0.0004,0.00030859878968590476,0.0004663082861322227,0.00046917234132662507,0.6577514540036934 +1,324,0.0004,0.0002910006645516361,0.0004375899010901717,0.00043774858320546863,0.6647666622259457 +1,325,0.0004,0.00029784436097250353,0.00041751036671632945,0.00041754080396591494,0.7133299503749038 +1,326,0.0004,0.0002582839527539773,0.0004123955285711557,0.00041240967045047614,0.6262800590292975 +1,327,0.0004,0.0003114135496290901,0.00044835024266269726,0.00044838898345771184,0.6945165049052993 +1,328,0.0004,0.0003095834113287801,0.00041637044652222864,0.0004164182263594866,0.7434434703670298 +1,329,0.0004,0.00032125684542304295,0.00045821380693924824,0.0004598202695225387,0.6986574249034841 +1,330,0.0004,0.0002737486820135034,0.0004150950533673552,0.00041720720319544957,0.65614562720112 +1,331,0.0004,0.0003199753199640917,0.0004715020406411973,0.0004718609814232582,0.6781135388625714 +1,332,0.0004,0.00029029686633627973,0.00045216158969543487,0.000454072674912723,0.639318070377341 +1,333,0.0004,0.0002880838964024831,0.00041941441559421714,0.0004197641455107844,0.6862994362034711 +1,334,0.0004,0.00030317043425786086,0.00044478160833183087,0.00044583614675541453,0.6800041595195734 +1,335,0.0004,0.0003103255831509123,0.0004898666135526814,0.0004805734016406637,0.6457402388302593 +1,336,0.0004,0.00030688912206721703,0.00044245103054385223,0.00044297666380672555,0.6927884630083253 +1,337,0.0004,0.0003223160118445683,0.0004619980000870758,0.00046229818299246286,0.6972037176486658 +1,338,0.0004,0.00029125381032678126,0.00042713828335269225,0.0004267915313402379,0.6824264047886974 +1,339,0.0004,0.00029456281700944773,0.0004531650212802409,0.0004542664509347639,0.6484362127190175 +1,340,0.0004,0.0003399150578198099,0.0004886150418703523,0.0004905203545192247,0.6929683033295774 +1,341,0.0004,0.00028575639500659955,0.0004288715772404409,0.00042752650240928595,0.6683945752982468 +1,342,0.0004,0.00027443845326400213,0.0004097075398336023,0.0003998147925753611,0.6864139555623701 +1,343,0.0004,0.00030049087258082307,0.00042958122725351327,0.0004322373802852532,0.6951987178492416 +1,344,0.0004,0.00031388726469225406,0.0004448547506115738,0.0004439038585099942,0.7071064120637444 +1,345,0.0004,0.0002803296517686789,0.00039452842130617837,0.0003940308012702371,0.7114409606177492 +1,346,0.0004,0.0003038641896638831,0.0004413804434434927,0.00044055160606664735,0.6897357437346717 +1,347,0.0004,0.0002581131922174804,0.00037703137775015744,0.0003779509500569965,0.682927750753255 +1,348,0.0004,0.0002873828718453749,0.0004149431540043564,0.00041541506179493124,0.6917969478613677 +1,349,0.0004,0.0003081985482923307,0.0004554970743492783,0.00045823503545570747,0.672577442678149 +1,350,0.0004,0.00032908378811141216,0.000493798509292703,0.0004853518205542559,0.6780314282855872 +1,351,0.0004,0.00032364476747640507,0.0004852633174567068,0.00047076190566121653,0.6874914125046384 +1,352,0.0004,0.0002703422215606809,0.00042144040281788525,0.00041828220956727447,0.6463153712426787 +1,353,0.0004,0.0003309029131382316,0.0004771989279982418,0.00047381282046657966,0.6983831986909518 +1,354,0.0004,0.0003455412384093574,0.000516915100080044,0.0005218107703812903,0.662196447491623 +1,355,0.0004,0.00028460919083474174,0.0004486997885872791,0.00044446224843203527,0.6403450278145786 +1,356,0.0004,0.00030765242177828624,0.0004359657004066407,0.00044187644479258136,0.6962408279597243 +1,357,0.0004,0.0002908874388944352,0.00045573073055066364,0.0004474780456162469,0.6500596883894895 +1,358,0.0004,0.0002922641175663381,0.0004395917808737959,0.0004403717707427592,0.6636758688536886 +1,359,0.0004,0.00029830043334981115,0.00042198407353737734,0.0004216757237663849,0.7074166629404408 +1,360,0.0004,0.0003045048482025447,0.0004453120793538459,0.00044496037870588864,0.6843414892089017 +1,361,0.0004,0.00026776088163292354,0.000393066948249299,0.0003927033495110464,0.6818400758901387 +1,362,0.0004,0.00028138774256932306,0.00041404541068725713,0.00041355034180472005,0.6804195623230687 +1,363,0.0004,0.00032549101677425784,0.0004681445940960415,0.00047030562077394745,0.6920840457713883 +1,364,0.0004,0.00029762673596796344,0.00042126862353618057,0.00042084762181349427,0.7072078361413713 +1,365,0.0004,0.00027601701109908756,0.00039473502795013776,0.000395290113779439,0.698264392347281 +1,366,0.0004,0.0003084127419783651,0.00041610391722362244,0.00041502393491885613,0.7431203745843351 +1,367,0.0004,0.00030566559272095857,0.00045639371851941474,0.00046396418798705103,0.6588129011575555 +1,368,0.0004,0.00029501003368580573,0.000423957044458926,0.0004272123153829675,0.6905466510752359 +1,369,0.0004,0.0002771922660330141,0.0004026374916228067,0.00040082487547162687,0.6915545491203817 +1,370,0.0004,0.0002763522225588415,0.0003930868856015119,0.00039344062003116893,0.7023988080766761 +1,371,0.0004,0.00026335234854534033,0.00038549084725304176,0.00038777897334576567,0.6791300370753225 +1,372,0.0004,0.0002900987700786892,0.000404090042624645,0.0004095702849233132,0.7083003351500622 +1,373,0.0004,0.00026392546272267683,0.0003866961306516431,0.0003876291150978132,0.6808711018935681 +1,374,0.0004,0.00031115537720867453,0.0004649326091449615,0.0004658622008487366,0.667912907812208 +1,375,0.0004,0.00032677209788636614,0.0004736449133690256,0.00047358351139847914,0.6899988914762194 +1,376,0.0004,0.00030606457657680896,0.0004646402982127794,0.0004658261025226789,0.6570361233930813 +1,377,0.0004,0.00026740373375467154,0.0003700071127309138,0.0003688241740156381,0.7250168307659075 +1,378,0.0004,0.00025698932651956773,0.0003712484384437052,0.0003717738639041968,0.6912517298036632 +1,379,0.0004,0.0002662892513944763,0.0003821620179949795,0.0003828001720172332,0.6956351403689764 +1,380,0.0004,0.00031504190441121227,0.0004698918367143008,0.0004699162519487676,0.67042138488447 +1,381,0.0004,0.0002979662345057085,0.0004472911882113012,0.00044735529648580886,0.6660617116783386 +1,382,0.0004,0.0002681402659342119,0.00038053046099899496,0.00038048529626347134,0.7047322684147436 +1,383,0.0004,0.0002643473079770869,0.00037708810724900664,0.00037680641486957764,0.7015467294222798 +1,384,0.0004,0.00027691736321368743,0.00042821920973879174,0.00042997892994655804,0.6440254252646878 +1,385,0.0004,0.00025823830603028595,0.0003961384823003077,0.0003915022238817511,0.6596087845168511 +1,386,0.0004,0.00030074726925207357,0.0004366610920557831,0.00043546211874607765,0.690639337626156 +1,387,0.0004,0.00029570493815481033,0.00044237690980893616,0.0004437329123545612,0.6664029868456763 +1,388,0.0004,0.00028615974662905564,0.00042542916686370575,0.00042614989837570777,0.6715002108876905 +1,389,0.0004,0.00027177363085579284,0.00039991687810426226,0.00039600298437002197,0.6862918755224576 +1,390,0.0004,0.00029381386502427945,0.00042126170115783994,0.0004286324646163211,0.6854680624513103 +1,391,0.0004,0.00029995377177636536,0.00046055073365615156,0.0004521158980995172,0.6634444243992085 +1,392,0.0004,0.00028296051769201254,0.0004180298725500878,0.00042087392849965324,0.6723165739933583 +1,393,0.0004,0.0002960760453749432,0.00046008683501865563,0.0004591273928375398,0.6448668713602728 +1,394,0.0004,0.00026656087336424214,0.0004234035902288694,0.00042332562347019274,0.6296828223605304 +1,395,0.0004,0.0002637204172026328,0.0004188445087042078,0.0004206778351062495,0.6268940153122772 +1,396,0.0004,0.0002895368351001552,0.0004223115796511154,0.0004215980508147757,0.686760374106568 +1,397,0.0004,0.00028860292321964537,0.0004185081151199962,0.0004177206565268267,0.6908993335863696 +1,398,0.0004,0.00026414227631009474,0.00037240139929692583,0.0003727100768217957,0.7087070963106517 +1,399,0.0004,0.0002660786804145454,0.0004114365051341204,0.0004112246319829194,0.647039743537535 +1,400,0.0004,0.00027470497599086085,0.00037477357754284836,0.0003767031755633999,0.7292345640039009 +1,401,0.0004,0.00029638088032627987,0.0004206818865626249,0.00042398595462380697,0.6990346663470299 +1,402,0.0004,0.00028043688162047764,0.0003796311630542112,0.00038145749989791313,0.7351720222974487 +1,403,0.0004,0.000298708065118047,0.0004255456904888691,0.0004344450616479388,0.6875623444423244 +1,404,0.0004,0.00030386782128443123,0.00045015396590267356,0.00044028613637380067,0.6901598669153848 +1,405,0.0004,0.00029772534216409685,0.00045425102823487513,0.0004436811962485542,0.6710343928961741 +1,406,0.0004,0.00028074915540401323,0.0004284755358384913,0.00042263511933324737,0.6642825987743882 +1,407,0.0004,0.00025445483474259843,0.0003614664528380218,0.0003637348358496159,0.6995613553159954 +1,408,0.0004,0.0002549211204409581,0.00036219033403752217,0.0003651609424688067,0.6981062068617438 +1,409,0.0004,0.00025637183635564964,0.0003691867733445066,0.00037315542926522256,0.6870376691569768 +1,410,0.0004,0.00030165128152093986,0.00044547061689746297,0.000446265359149313,0.6759459934240881 +1,411,0.0004,0.0002881579550140686,0.00040795025211035985,0.0004084109620146655,0.7055588165229543 +1,412,0.0004,0.00025345939398392636,0.0003874547852658931,0.0003907016053230634,0.6487288266306094 +1,413,0.0004,0.00027824668773276104,0.0003944797080903216,0.00039282455578562776,0.7083230506715212 +1,414,0.0004,0.0002935769557667598,0.0004318741153442386,0.00043016344838309975,0.6824776881212437 +1,415,0.0004,0.0003003787532610433,0.00045147382276459737,0.0004574977165932664,0.6565688578684031 +1,416,0.0004,0.00030923043598608395,0.00045211465441105046,0.00045789990053253456,0.6753232215740842 +1,417,0.0004,0.0003118920259050948,0.0004513055296572455,0.0004530850360667451,0.6883741485100584 +1,418,0.0004,0.0002792694406107598,0.00038971620823923057,0.00038234900477841023,0.730404518177339 +1,419,0.0004,0.0002879678050932847,0.00044038862181305645,0.00044194268741101165,0.651595361335782 +1,420,0.0004,0.00031142290615439875,0.0004695363137938727,0.00047157795512257325,0.6603847842578927 +1,421,0.0004,0.0003027374247955072,0.00042941471309800575,0.0004297108582907807,0.7045142540723234 +1,422,0.0004,0.0003034073821345359,0.00043102051701060274,0.000431688987650951,0.7028379013917787 +1,423,0.0004,0.000315986615981047,0.00044759986477773463,0.00044782459920707614,0.7056035254439726 +1,424,0.0004,0.0003070494257839539,0.00043958613213110787,0.00044085614817441035,0.6964843907824549 +1,425,0.0004,0.00030740444811155757,0.0004375021602502851,0.0004412074363166901,0.6967345126316244 +1,426,0.0004,0.00031207904323059997,0.0004432691498679631,0.00043551872163488637,0.7165686059581818 +1,427,0.0004,0.0002743020930036666,0.0003994769915622577,0.0004059517945870269,0.6757011464445255 +1,428,0.0004,0.0002953367980906019,0.00043448155104129567,0.00043109534422454995,0.6850846385776929 +1,429,0.0004,0.00033986727482636863,0.0005100597898721642,0.0005180448579420596,0.6560576166637309 +1,430,0.0004,0.0003047028626217324,0.0004376049089825163,0.0004401590825624146,0.6922562198373483 +1,431,0.0004,0.00026273241688535675,0.00038166282165880394,0.0003777771545741501,0.6954693096291709 +1,432,0.0004,0.00029452542508558985,0.00043428085691466845,0.0004339076728958701,0.6787744109707656 +1,433,0.0004,0.0002720402963655947,0.00040801009097982447,0.00040856806240428486,0.6658383789587702 +1,434,0.0004,0.0002983047796711862,0.00041410896753881534,0.00040865979481089355,0.7299587173952997 +1,435,0.0004,0.00035935210699929415,0.000488669891646042,0.00047966606991421055,0.749171412235944 +1,436,0.0004,0.00029918007373029587,0.0004462298348364982,0.0004545016993149816,0.6582595272607689 +1,437,0.0004,0.0003053877119230632,0.0004376331442982399,0.0004478988403423217,0.681822957366133 +1,438,0.0004,0.00029637889349769876,0.0004537093918903303,0.00044976649650449257,0.6589616963493374 +1,439,0.0004,0.0002697938580151402,0.00037571293818649285,0.00037989750658239243,0.7101753850459325 +1,440,0.0004,0.0003324912985416622,0.0005091379871367915,0.0005139890429278376,0.6468840204213125 +1,441,0.0004,0.00027773141756447006,0.0003778170277060094,0.0003781221400729832,0.7345018662775572 +1,442,0.0004,0.00034407072797039916,0.00048543621342227384,0.0004844667514931207,0.7102050386532767 +1,443,0.0004,0.0002923115470422202,0.00041041201426340906,0.00041462531825145065,0.7050016826636406 +1,444,0.0004,0.0003143968598564167,0.0004513127016563064,0.0004537366780527149,0.6929059850433564 +1,445,0.0004,0.00029517849472022263,0.0004448953935177204,0.0004396790325137956,0.671349945965324 +1,446,0.0004,0.00027537689806784505,0.00039174345733851656,0.0003889523369138839,0.707996512510516 +1,447,0.0004,0.0002788542729271599,0.00039825471963408346,0.00039432761395698023,0.7071639496126739 +1,448,0.0004,0.00029327382941072715,0.000445749452503165,0.0004482967077363936,0.6541958135083547 +1,449,0.0004,0.00029367596263030497,0.00043865157601705987,0.0004337963026852568,0.6769904695185545 +1,450,0.0004,0.00028002266793237797,0.0004131213210608027,0.0004147917635004603,0.6750921608694557 +1,451,0.0004,0.00028109600188300476,0.00038163873115472634,0.0003808298495269635,0.7381144157480298 +1,452,0.0004,0.00030027505111662056,0.0004006411930000529,0.00040123402962259186,0.7483788236981415 +1,453,0.0004,0.00030032828405986904,0.0004698342954687961,0.00046584506456632754,0.6446956443328551 +1,454,0.0004,0.00028017271936679327,0.000390249212884372,0.00038385890437814046,0.7298846429541057 +1,455,0.0004,0.00027710968440026134,0.00040563506963408637,0.0004014605136808949,0.6902538978479086 +1,456,0.0004,0.0002693753429668736,0.00039503210134047065,0.0003939620324251544,0.6837596539662741 +1,457,0.0004,0.00031799224053874676,0.0004610961177627193,0.0004604993853507546,0.6905378175402719 +1,458,0.0004,0.00028974417830349044,0.00042584540200631826,0.00042809649376040034,0.676819788357473 +1,459,0.0004,0.00028112496941831147,0.00040860756226743277,0.00039865271543671453,0.7051876446153033 +1,460,0.0004,0.00030688396845241904,0.00046038995079342794,0.00044766222094251514,0.6855257247446539 +1,461,0.0004,0.00029562763843641183,0.0004146402651918442,0.0004177400208379594,0.7076833046625554 +1,462,0.0004,0.00029481564517198135,0.0004032288147140633,0.0004144848761550014,0.7112820325481107 +1,463,0.0004,0.0002754890631089392,0.0003689396786073832,0.00037357930368901363,0.7374312773447168 +1,464,0.0004,0.0002901255791089647,0.00044086720770873347,0.0004382070925469929,0.6620741289755641 +1,465,0.0004,0.00025820160263301045,0.0003809279603737153,0.0003715796186608591,0.6948755789231571 +1,466,0.0004,0.0003350817506083318,0.0004914018993509034,0.0004958737955323323,0.6757399838977448 +1,467,0.0004,0.00026938545045790055,0.00036551770832542565,0.0003643886607243809,0.7392805525901378 +1,468,0.0004,0.00027884384244171873,0.0003918540022687031,0.0003948445229937939,0.7062117522296278 +1,469,0.0004,0.0003035731530384134,0.00044874855978090057,0.0004473835418396178,0.6785523485958747 +1,470,0.0004,0.0002558740034583871,0.00037034611780789676,0.0003709837898439028,0.6897174767826111 +1,471,0.0004,0.00030173854914980334,0.000444168357287935,0.000436123033131764,0.6918656576861887 +1,472,0.0004,0.00027163103563333725,0.00038684345716214993,0.00039003940425555986,0.6964194711346662 +1,473,0.0004,0.00027871370773456565,0.00041812468880325,0.00041390631041200504,0.6733739030389081 +1,474,0.0004,0.0002747915845000633,0.0003850277836156995,0.00037301403573518474,0.7366789401328242 +1,475,0.0004,0.00031426619753441016,0.000511329162220033,0.0005022314468877436,0.6257397848778145 +1,476,0.0004,0.00030006771833054636,0.00040571912967143307,0.00040214389463617904,0.746170021061786 +1,477,0.0004,0.00030856984202703454,0.00048164337639033196,0.00048176348959981665,0.6405006786283292 +1,478,0.0004,0.0003013550638076126,0.0004334923024745816,0.0004327401005110687,0.6963881171440097 +1,479,0.0004,0.00029686716851691936,0.0004366827366629604,0.0004370364217829075,0.6792732910127671 +1,480,0.0004,0.00030635464384458306,0.0004369351356838652,0.0004371614119758788,0.7007815316084823 +1,481,0.0004,0.00030255931170062526,0.00044172278228989977,0.00044171100558269084,0.6849711867638408 +1,482,0.0004,0.00030325245625329085,0.0004383869015572905,0.000437491876437358,0.6931613421551426 +1,483,0.0004,0.00031675865811798973,0.00046359156727753475,0.00046327568719844704,0.6837368479954447 +1,484,0.0004,0.00031923282219167756,0.0004574434827027479,0.0004574197281383451,0.697899112246262 +1,485,0.0004,0.0003198132022272384,0.00045993835417093863,0.0004598520647440357,0.6954697537462483 +1,486,0.0004,0.00026616303064262237,0.00041369620821327216,0.00041427994860772046,0.6424714291317313 +1,487,0.0004,0.0002735794990125369,0.00038506868387758945,0.00038096684825057427,0.7181189131517154 +1,488,0.0004,0.0002942831633329405,0.00040785730998636326,0.00040960625142401943,0.7184537889982107 +1,489,0.0004,0.0002814775614059948,0.0004205612671415296,0.00042177576457858826,0.6673630517562559 +1,490,0.0004,0.0002729369959095925,0.0003853100262021058,0.00038333123862568583,0.7120134453120041 +1,491,0.0004,0.0002946252206945452,0.00040161428819295724,0.00040341137054650977,0.7303344481723713 +1,492,0.0004,0.00027672851400178716,0.00041928533528800725,0.00042027247210365436,0.6584502492314936 +1,493,0.0004,0.0003217659165880317,0.0004542607771873473,0.0004545273919981338,0.707913147266057 +1,494,0.0004,0.00026400316229167225,0.0003910488010668142,0.0003964901254763719,0.6658505353052103 +1,495,0.0004,0.00032333977817475756,0.0004496312102277359,0.00045258408741294983,0.7144302841556461 +1,496,0.0004,0.0002654215039518395,0.00038660718761508663,0.0003860221502317712,0.6875810203960525 +1,497,0.0004,0.0002801777627273018,0.0004164896875135406,0.00041658541689777577,0.6725577789393753 +1,498,0.0004,0.00028012009375029433,0.00039907684046589415,0.00039944790292686613,0.7012681546148479 +1,499,0.0004,0.0003032842456483349,0.00046456843358029905,0.0004642878090460267,0.6532246587983729 +2,0,0.0004,0.00029586956244288603,0.00041702618563633554,0.00040856154536871166,0.7241737892289268 +2,1,0.0004,0.0003148805220737228,0.00045817965752104365,0.0004553522688414797,0.6915097247123658 +2,2,0.0004,0.00027697064119239125,0.0004024461527496213,0.0004022395638633868,0.688571354175541 +2,3,0.0004,0.0002776472147211627,0.0004047092468882752,0.0004021015931418471,0.6904902130621966 +2,4,0.0004,0.00030552717899260626,0.0004625623619042736,0.00045933165415504756,0.6651559417446015 +2,5,0.0004,0.00031087735052170995,0.0004606676066088929,0.0004612853462101283,0.6739371911027424 +2,6,0.0004,0.000284104549234746,0.0004184551722380557,0.0004195924184307246,0.6770964792388214 +2,7,0.0004,0.0003030064014613429,0.0004643038449926556,0.00046377973119149596,0.6533411899715614 +2,8,0.0004,0.0002891461539992558,0.0004171235870943776,0.00041725755836931566,0.6929680438366843 +2,9,0.0004,0.0003107200548380984,0.00044823064685271965,0.00044971705057786495,0.6909234471738129 +2,10,0.0004,0.0002764043518155822,0.0004054834920681139,0.00040160288992203074,0.6882528954640859 +2,11,0.0004,0.0003098840569646853,0.00042293837902779454,0.0004174521354275191,0.7423223662452423 +2,12,0.0004,0.0002729256755259126,0.00041334491046574723,0.00042134525485660744,0.6477483070713467 +2,13,0.0004,0.0002877288963395591,0.00043648710174266046,0.0004356127497785353,0.6605153234973952 +2,14,0.0004,0.00031300791143976494,0.0004482484201060232,0.0004494869615452407,0.6963670544829826 +2,15,0.0004,0.00031644824014824194,0.0004471608827387761,0.00045580472378410944,0.6942627481371314 +2,16,0.0004,0.00031795879388667213,0.0004522035926859807,0.0004647360135552982,0.6841707649343571 +2,17,0.0004,0.00031876894975659643,0.000488894207594951,0.0004848346265779144,0.6574797514083275 +2,18,0.0004,0.00025447464949462467,0.0003717066279889124,0.0003731198230589148,0.6820185735734648 +2,19,0.0004,0.00028473563466289943,0.0004255151090551961,0.0004254138355486948,0.6693144671603124 +2,20,0.0004,0.00024634746794491833,0.0003756077698308148,0.0003765101691953403,0.654291671514213 +2,21,0.0004,0.00033510833429957845,0.00047308708524501994,0.0004739371790675965,0.7070733192083729 +2,22,0.0004,0.00025488033550527685,0.00039159262347484013,0.00039134780788393245,0.6512885223081927 +2,23,0.0004,0.000307030601502383,0.00044927176159764004,0.0004443440613550835,0.6909749183235494 +2,24,0.0004,0.00027200431504933,0.0004360287859807302,0.00043372610169787365,0.6271338385781625 +2,25,0.0004,0.00033619243868009314,0.000480619992151142,0.0004788229120063118,0.7021227060154998 +2,26,0.0004,0.0003152938383087508,0.0004692612640690592,0.00046805582590173263,0.6736244286700666 +2,27,0.0004,0.0003119968897609706,0.00048123607278577135,0.00048280814342858036,0.6462129813001444 +2,28,0.0004,0.00027220237578285897,0.0003870372167883821,0.00038574262940042946,0.7056580088281939 +2,29,0.0004,0.00028537263897503477,0.00041162734633870383,0.00041791117529390806,0.6828547687779305 +2,30,0.0004,0.0002725443593336493,0.00039876300963106835,0.0003937128824263052,0.6922414061080765 +2,31,0.0004,0.000287882936295634,0.0004117438379724411,0.000413389039385792,0.6963971195834479 +2,32,0.0004,0.00030340281462697436,0.00042846759761661454,0.00042628595604600104,0.7117354215493644 +2,33,0.0004,0.0003358589446407196,0.00047413086615281426,0.00047212996660982534,0.7113696829124978 +2,34,0.0004,0.0002662839730692593,0.0004079382790540765,0.00040755846994233535,0.6533638550241277 +2,35,0.0004,0.0003176106676484257,0.00044707671908420643,0.0004470771466498776,0.7104157974264745 +2,36,0.0004,0.0002582835996564053,0.0003854237570686647,0.0003843718382399984,0.6719628598157997 +2,37,0.0004,0.0003076119529565154,0.00042502037274329626,0.00042483266235784277,0.7240779257631782 +2,38,0.0004,0.0002837966075241485,0.0004212864287505162,0.0004210094198121517,0.6740861229441717 +2,39,0.0004,0.0003101686116630757,0.00042713898871484397,0.00042716032251804265,0.7261175612816301 +2,40,0.0004,0.0003013909580344742,0.00041850280923601366,0.0004185263518405753,0.720124208927422 +2,41,0.0004,0.00027481520264273856,0.000382285514988019,0.0003822573285160653,0.7189272307991572 +2,42,0.0004,0.00026324870603234814,0.0003743077659300872,0.00037425225709607565,0.7033991139424675 +2,43,0.0004,0.000272516377057826,0.0003850062838025139,0.0003849896468789646,0.7078537806589416 +2,44,0.0004,0.0002928610492623551,0.0004248690118566431,0.00042488765406259037,0.6892670249703552 +2,45,0.0004,0.00032933040763181526,0.00048431693984684433,0.00048430835530078383,0.6800014991012943 +2,46,0.0004,0.0003021070023618572,0.0004423042490197321,0.0004422971148468041,0.6830408614953237 +2,47,0.0004,0.000276791727363749,0.00041328426523316847,0.0004102379598348927,0.6747101791242054 +2,48,0.0004,0.00032557155854494557,0.00046784468776757415,0.0004674384072039429,0.6965015144827391 +2,49,0.0004,0.0002833867643717723,0.0004188492161413711,0.000420220611831464,0.6743761643120662 +2,50,0.0004,0.00028499210797234295,0.000434559330146253,0.00043429336930121996,0.6562202605830629 +2,51,0.0004,0.00028190836489452663,0.0004011900764393234,0.00040124518423759496,0.7025837965636399 +2,52,0.0004,0.0003191855556505788,0.0005130977036930885,0.0005119581910559528,0.6234601989514695 +2,53,0.0004,0.0002928213001654177,0.000405370298598422,0.0004056351500454342,0.7218834465716778 +2,54,0.0004,0.00033030347833449555,0.0004768189292443203,0.0004770558139667125,0.6923791067297277 +2,55,0.0004,0.00032565644553992593,0.0004664304005664116,0.00046605849331756783,0.6987458660430993 +2,56,0.0004,0.0002809662139197157,0.00043138007005925655,0.00043060355234692416,0.6524939527051319 +2,57,0.0004,0.0002979034513595109,0.0004578584581222252,0.0004575948585925245,0.6510201016589341 +2,58,0.0004,0.0002731081917940942,0.0003933848316301667,0.0003996346071231296,0.6833947484181421 +2,59,0.0004,0.0003032623587894172,0.00041787800465188494,0.0004349700112996042,0.6972029126406424 +2,60,0.0004,0.0002809750608969407,0.0004136824194581717,0.0004071267371174452,0.6901415094629043 +2,61,0.0004,0.000301280808643152,0.00043592796298366375,0.00043592554652497066,0.6911290495472122 +2,62,0.0004,0.0002723261775771956,0.000398554651456902,0.00040001640553164044,0.6807875222398977 +2,63,0.0004,0.00028817529609037655,0.00041254799347413264,0.0004147491232210664,0.694818337052338 +2,64,0.0004,0.00034404390016976066,0.000517694481710418,0.00050914884014178,0.6757236254804323 +2,65,0.0004,0.00034147742285829533,0.0005064409270155592,0.0005056996182543528,0.6752574266064438 +2,66,0.0004,0.0003622494296348112,0.0005049544353047093,0.0005105802393229161,0.7094858001461094 +2,67,0.0004,0.00029346260898729573,0.00048477350084371343,0.00048221517607499446,0.6085719063757882 +2,68,0.0004,0.0002620111940770775,0.00036562262642117515,0.0003715381759724261,0.7052066544475979 +2,69,0.0004,0.00028005884841488817,0.00042205679180748164,0.00042154819352690056,0.6643578426271125 +2,70,0.0004,0.0003092427603931935,0.00044225307931905966,0.0004434440869352158,0.697365844994054 +2,71,0.0004,0.0003067057686080485,0.0004379687747209681,0.0004376322672906121,0.7008298782602767 +2,72,0.0004,0.0002529750886840992,0.00040308530667627825,0.0004027861243898105,0.6280630671360308 +2,73,0.0004,0.00035420304760411936,0.0004988932086350587,0.0004990073958349034,0.7098152263084042 +2,74,0.0004,0.0002871734768186594,0.0004171689145776772,0.000417184505234553,0.6883608408639298 +2,75,0.0004,0.00028225601262981466,0.00041101919161206035,0.00041113477646963925,0.6865291597405363 +2,76,0.0004,0.0003069604882339418,0.00045809563002973715,0.00045657475351573707,0.6723115675369062 +2,77,0.0004,0.0002891834695951472,0.0004196068369599758,0.00041842070055788945,0.6911308862338135 +2,78,0.0004,0.0002994956519022576,0.0004246245845161083,0.00042466131696082955,0.70525767226847 +2,79,0.0004,0.0002988823935935581,0.0004591232976258622,0.00045382212155521164,0.6585893005156126 +2,80,0.0004,0.0002812678865982713,0.0004319832276734187,0.00041835682145605855,0.6723157653300361 +2,81,0.0004,0.0002861612916397322,0.00043759385275849545,0.000422481759245463,0.6773340750871845 +2,82,0.0004,0.0002984439159694229,0.00044940648028079426,0.0004347055396642928,0.6865427024461207 +2,83,0.0004,0.00026972599118878986,0.0004104099512840068,0.0003955419515234663,0.6819150033262346 +2,84,0.0004,0.00031317841207173654,0.0004641089777776736,0.0004681324768299801,0.66899526858821 +2,85,0.0004,0.00029577325584965027,0.0004128954839834666,0.00040792509930503333,0.7250675586119806 +2,86,0.0004,0.0002954456207423531,0.00041256508242376133,0.00040756727289122563,0.7249002567024161 +2,87,0.0004,0.0002890870439782733,0.0004302806954886041,0.0004312955181029064,0.6702760215312454 +2,88,0.0004,0.000291943676908942,0.00044367649171942565,0.00044224998986481346,0.6601326932719276 +2,89,0.0004,0.0003093327435092426,0.0004428454383783257,0.0004420066553487014,0.6998372982986159 +2,90,0.0004,0.00029599348962732055,0.00041539003397003286,0.0004113835885774001,0.7195072867415337 +2,91,0.0004,0.0002615901268180847,0.00038481338587130037,0.00039091181404385687,0.6691793837388005 +2,92,0.0004,0.0003428366715836921,0.000452305634231247,0.0004425537121804227,0.7746781060643834 +2,93,0.0004,0.0003157523870162628,0.00044556807046623303,0.0004375642237671285,0.721613810877523 +2,94,0.0004,0.0003239807276619047,0.00047758556350841266,0.0004652732919825282,0.6963235011436477 +2,95,0.0004,0.0002982619969879003,0.00042172368904277037,0.0004022165645706091,0.7415457821989835 +2,96,0.0004,0.0002920327249028169,0.0004471058858789847,0.00044202065058250285,0.6606766550792839 +2,97,0.0004,0.0002965882749470834,0.00044404756597556886,0.0004341338768766135,0.6831723824017025 +2,98,0.0004,0.0002751070839045159,0.0004233474987995654,0.00041742278792681405,0.6590610092728093 +2,99,0.0004,0.00025660338309140094,0.0003855980719286911,0.00038367114552060797,0.66881074088387 +2,100,0.0004,0.0002841719616732794,0.0003906721256851243,0.0003903243229810492,0.728040618895985 +2,101,0.0004,0.00026370946192043153,0.00038192219835641016,0.00038284516625510423,0.6888149183127258 +2,102,0.0004,0.00027763834321455327,0.00040845436514698816,0.0004083158148378536,0.6799598083772639 +2,103,0.0004,0.00030512385438748017,0.0004308383902037812,0.00043147725356653516,0.7071609264807492 +2,104,0.0004,0.0002977732567799495,0.0004153573536955327,0.00041658520748048524,0.7147955602669799 +2,105,0.0004,0.0002862446624593364,0.0004391405612966838,0.000439061682240119,0.6519463529563752 +2,106,0.0004,0.0003107220685575257,0.0004384026135527499,0.00043890442643928666,0.7079492705925299 +2,107,0.0004,0.00031325578654514127,0.0004419070367101442,0.00044214176882099613,0.7084962530919915 +2,108,0.0004,0.00029090615800929793,0.0004282230924265078,0.00042865245930879853,0.6786527213173668 +2,109,0.0004,0.00029026668747248,0.0004261400047367868,0.00042562992136745126,0.6819696475753391 +2,110,0.0004,0.0002944429302066674,0.0004521554613752524,0.00045367431472778566,0.6490182949487442 +2,111,0.0004,0.0002782931242351176,0.00039834520677900335,0.000397721778023385,0.6997180934325269 +2,112,0.0004,0.0002846774013760606,0.00040454478159375365,0.00040495160740358773,0.7029911628239124 +2,113,0.0004,0.00028572742236730985,0.0004148411093876742,0.0004150694246524043,0.6883846542216147 +2,114,0.0004,0.00031782716694943764,0.0004823374509147121,0.0004814223313973932,0.6601836811909024 +2,115,0.0004,0.0002665015153572453,0.0003780775385319331,0.00037757214145037323,0.7058293928506728 +2,116,0.0004,0.0002937497727353824,0.0004337541649067544,0.00043033449756309217,0.6826080047006112 +2,117,0.0004,0.0002795467039620468,0.00040492500182479156,0.00040533447349707974,0.6896692046699571 +2,118,0.0004,0.000297028664794863,0.0004310861562262306,0.0004268845714190416,0.6958055752811256 +2,119,0.0004,0.00025991338417364913,0.0003718570790745568,0.0003672689063609617,0.707692319366125 +2,120,0.0004,0.00027468438617826745,0.00039504087334784027,0.00039650959293415704,0.6927559662443793 +2,121,0.0004,0.00032692511666048595,0.00045351713865357307,0.00045656284881723437,0.7160572033125643 +2,122,0.0004,0.0002848767062550564,0.0004321417363858519,0.0004401834206683987,0.6471772740156454 +2,123,0.0004,0.0003410638718581308,0.0004832468930655626,0.0004735250210001086,0.7202657868802514 +2,124,0.0004,0.00027940425357443816,0.0004162401825910485,0.00040032813593781583,0.697938087513886 +2,125,0.0004,0.0002949766446015713,0.000439522500690876,0.000425603582782395,0.6930783868715424 +2,126,0.0004,0.00026818722340220556,0.00036933947284116764,0.0003908937926637358,0.6860871889897523 +2,127,0.0004,0.0002582896503200283,0.00035949418327100755,0.00038323329606412983,0.6739749728760687 +2,128,0.0004,0.00034357146561653527,0.00044318881845945674,0.0004815177423097503,0.7135177698094517 +2,129,0.0004,0.0003377099851387402,0.0004517824350691244,0.0004983904340987084,0.6776012580366968 +2,130,0.0004,0.0003496578804415828,0.0004625202341809672,0.0005115911605421624,0.6834713095336329 +2,131,0.0004,0.0002940439854257345,0.00039188073429621237,0.0004352376811456915,0.6755940447337009 +2,132,0.0004,0.0002826799656447494,0.00038640227444146423,0.0004271562878497535,0.6617717535371463 +2,133,0.0004,0.00029640114002594235,0.0004024362361554759,0.00042900869019567355,0.690897752888763 +2,134,0.0004,0.000323643548274904,0.0004195237015755929,0.0004519975109307193,0.7160294923051269 +2,135,0.0004,0.0002771296704696402,0.0003760211723167771,0.0003962568454792684,0.6993687897920219 +2,136,0.0004,0.00029262759757913326,0.0004103226497425407,0.00042834294095191465,0.6831619471277416 +2,137,0.0004,0.0003047498543363701,0.000434316529227593,0.00043937090131871575,0.6936050007447062 +2,138,0.0004,0.0002984931443438547,0.0004371554225738942,0.000442101001054361,0.6751695735408475 +2,139,0.0004,0.00029210452358857745,0.0004228703334230562,0.00041883639567738155,0.6974191512563243 +2,140,0.0004,0.0002689629029545091,0.0003740099836561309,0.0003757559376385254,0.7157914912664655 +2,141,0.0004,0.0002899389699155265,0.0004213874437126193,0.0004223137705774339,0.6865486993689313 +2,142,0.0004,0.00028445643138339926,0.0004230775822068425,0.00042493312389074164,0.6694145864151047 +2,143,0.0004,0.00028732593212521545,0.0004016687002976706,0.0004012186320451679,0.7161330735330089 +2,144,0.0004,0.00030742090367078114,0.0004643230762705738,0.00046426507125633433,0.6621667721822757 +2,145,0.0004,0.00028899230442389946,0.0004397458306750037,0.0004400082338380551,0.6567884012149259 +2,146,0.0004,0.0003056249053301694,0.0004269906608872862,0.00042802317380113194,0.7140382204449724 +2,147,0.0004,0.00027011648721781475,0.0004162200993695362,0.00040930791736672233,0.6599346745003273 +2,148,0.0004,0.00029309854177395555,0.0004382367199848559,0.0004377793000468617,0.669512107453644 +2,149,0.0004,0.0002943417764819586,0.00041545928965352493,0.0004125512618160331,0.7134671584478463 +2,150,0.0004,0.0003170870373844967,0.00041252325578001255,0.00041899327284128325,0.7567831226364603 +2,151,0.0004,0.00028117214847748454,0.00041189379064356454,0.0004130972037171355,0.6806440371598704 +2,152,0.0004,0.00033028660066778906,0.00046735457700866373,0.00046626356794171126,0.7083688784131618 +2,153,0.0004,0.0003135816055508668,0.0004568324659913126,0.0004565659055695325,0.6868265933254406 +2,154,0.0004,0.00025418828520080966,0.0003698608042271504,0.0003702164574642981,0.6865936942452711 +2,155,0.0004,0.00029119139898197994,0.00042884296771171883,0.00042879073388174153,0.6790990942035822 +2,156,0.0004,0.00031624919702543915,0.00046149394788130697,0.0004619291156825008,0.6846271133140862 +2,157,0.0004,0.00030935680215144547,0.0004601201184459869,0.0004602724105036368,0.6721167619257099 +2,158,0.0004,0.00026348685174963345,0.00038646178960990226,0.0003864887955592679,0.6817451237321259 +2,159,0.0004,0.0002872387331463906,0.0003981152881364074,0.00040021797869636285,0.7177057214721299 +2,160,0.0004,0.00027275636613964077,0.000361750028981133,0.0003615515915507029,0.7544051043166 +2,161,0.0004,0.00026969997230458015,0.0004315054362841513,0.00042843283258844656,0.62950351091242 +2,162,0.0004,0.00030563494014017165,0.0004214921571076648,0.00042654968077825953,0.7165283527642704 +2,163,0.0004,0.0002759710318080152,0.00041171427340662447,0.00040609367102090307,0.6795748161113548 +2,164,0.0004,0.0002465050472314957,0.0003465026415185165,0.0003565083428654677,0.6914425767716663 +2,165,0.0004,0.00027132880989757537,0.0004306871043093208,0.0004222720558538396,0.6425450278705869 +2,166,0.0004,0.00027660298097777924,0.00041125705604293515,0.00040656398940116975,0.6803430411660149 +2,167,0.0004,0.0003115302021282584,0.0004776191353847078,0.0004702748379175308,0.6624428462040947 +2,168,0.0004,0.000274515766875187,0.0004098431064307505,0.0003955491259497065,0.6940118151344147 +2,169,0.0004,0.0003134773219327112,0.0004591813276692224,0.00044514442283089505,0.7042148701743871 +2,170,0.0004,0.0003142815911513011,0.0004702041506199002,0.00046087188281388706,0.6819283251398021 +2,171,0.0004,0.0002792879258758274,0.00044945351626340214,0.00044024748534508633,0.6343884636999315 +2,172,0.0004,0.00028273574269553983,0.000433474729480474,0.0004335965802789992,0.6520709700099862 +2,173,0.0004,0.000278343470341294,0.00041136594263839954,0.0004102359535659787,0.6784960409291081 +2,174,0.0004,0.00026647027832792043,0.0004011175563471006,0.00039805956111533993,0.669423132511341 +2,175,0.0004,0.0002709829953975333,0.0004013142043099147,0.00039816910093685835,0.6805726380071511 +2,176,0.0004,0.00029740078829898785,0.00043318984526390623,0.00042894626031233303,0.6933287822172371 +2,177,0.0004,0.0002882552669584581,0.0004427720597936349,0.0004427490687637413,0.6510578729467101 +2,178,0.0004,0.0002956792053004505,0.000421081714370206,0.0004213492835831674,0.7017437001102395 +2,179,0.0004,0.00027054780521738067,0.0004009213067597219,0.0004008513164629926,0.6749330589821281 +2,180,0.0004,0.00030581569661947833,0.00044274316118002733,0.0004432033955690112,0.6900120795032577 +2,181,0.0004,0.0002735849074965052,0.0004104344853906427,0.00041044281020889743,0.6665603604001796 +2,182,0.0004,0.0003250368682250988,0.0004705225503259875,0.00047064538105137416,0.6906194797853945 +2,183,0.0004,0.0002972613121025449,0.00042134530407393823,0.0004214738365343268,0.7052900710204216 +2,184,0.0004,0.0003073285150869387,0.0004695444419367006,0.00046882750178773886,0.6555257827559812 +2,185,0.0004,0.00028815958256532786,0.0004194485553619211,0.0004190756729972266,0.6876075160946764 +2,186,0.0004,0.00028567317464376485,0.00042363190872774935,0.00042278775898775046,0.6756893230015246 +2,187,0.0004,0.0002949895856173856,0.00043437774056033127,0.00043486804352004096,0.678342752503935 +2,188,0.0004,0.00029413406435675786,0.000428195872501918,0.00041983834519765655,0.7005888521647109 +2,189,0.0004,0.00028357943513199603,0.00039282700934186067,0.00039826402552891097,0.7120387907378551 +2,190,0.0004,0.00025358078389181094,0.0003883062679360223,0.00037558143484831073,0.6751685796030541 +2,191,0.0004,0.00029794271646890025,0.0004470012833825986,0.00043089789891410365,0.6914462038913143 +2,192,0.0004,0.00029703558875153463,0.0004359807072363922,0.00043812502084085474,0.6779699278106975 +2,193,0.0004,0.0003514213925921899,0.0005129463721728853,0.000509599925629219,0.6896025193847485 +2,194,0.0004,0.00030678345821913655,0.0004948543920436347,0.000498043104401986,0.6159777246338947 +2,195,0.0004,0.00026966126795710635,0.00045640733649489725,0.00045396093402350356,0.5940186649257903 +2,196,0.0004,0.0003304808801637564,0.00047689812885492024,0.00047544831833471916,0.695093172947339 +2,197,0.0004,0.0002877271252289566,0.00042763008573494266,0.00043112836495697656,0.6673815703535759 +2,198,0.0004,0.0002945735976419666,0.00045084058351949405,0.0004390855497842458,0.6708797358207568 +2,199,0.0004,0.00027090925921643527,0.00040206051074489796,0.00040787902495900225,0.6641902197438703 +2,200,0.0004,0.00028959486622689263,0.00041886085136793385,0.00042457067328125283,0.6820887179719388 +2,201,0.0004,0.00027377746591721475,0.0004127581534416189,0.00040790293137456284,0.6711828841107655 +2,202,0.0004,0.00028913818969154696,0.00039624407237111975,0.0003996485982412265,0.7234810555172376 +2,203,0.0004,0.00029027224330170046,0.0003958737710704835,0.00039819386953005123,0.7289721553078655 +2,204,0.0004,0.0002762225456884094,0.00043287801846176135,0.00042980836156033354,0.6426644299930289 +2,205,0.0004,0.0002745792289198146,0.0004024628104081714,0.00040333046692671775,0.6807797858962726 +2,206,0.0004,0.0003062056712415102,0.00045956956643495244,0.00046016754027023495,0.6654221439906212 +2,207,0.0004,0.0002890025621799867,0.00043634433404431236,0.00043549043350454034,0.6636255126301727 +2,208,0.0004,0.00032337144999325677,0.0004923425258232079,0.0004926307506841568,0.6564175085379146 +2,209,0.0004,0.00025726009707805283,0.0004174238327917375,0.00041734987451084944,0.6164135004942121 +2,210,0.0004,0.00029414805888395234,0.00041584083348354515,0.00041857013595816817,0.7027449729795091 +2,211,0.0004,0.00032058593640578974,0.0004521190609375682,0.00045084263497176805,0.711081675817694 +2,212,0.0004,0.00030881663192965705,0.0004968003955343724,0.0004904898946991676,0.6296085510978033 +2,213,0.0004,0.00024805120897789895,0.0003665288200533689,0.0003665827146361897,0.6766582249358761 +2,214,0.0004,0.00034834768508648216,0.0005276424240916762,0.0005272361809558691,0.6607051975358262 +2,215,0.0004,0.0002575953032725457,0.00037486476785008504,0.00037632208125621303,0.6845075431467067 +2,216,0.0004,0.000301176763006623,0.00044933165031530353,0.0004487724063596307,0.671112480933755 +2,217,0.0004,0.00028883254211576546,0.00040363603891257425,0.0004042094976523271,0.714561492971645 +2,218,0.0004,0.00027134401301415293,0.0004090994026767747,0.00040972192753212976,0.6622638301262862 +2,219,0.0004,0.00030138313088067984,0.000441121934577808,0.00043345166060544573,0.695309669502033 +2,220,0.0004,0.00031274456736270873,0.00044714390870829334,0.00044959477656174193,0.6956143257588763 +2,221,0.0004,0.00028315405422250694,0.0004191596156439812,0.00041793944699061156,0.6775001887507106 +2,222,0.0004,0.00029832783244100684,0.0004322049922365055,0.00043814009916432324,0.6808959805551141 +2,223,0.0004,0.0003064047763688307,0.00040254496099514193,0.0003989833460079172,0.7679638246423213 +2,224,0.0004,0.0002851537061878542,0.0004049336899045221,0.0004079814360417476,0.6989379442222347 +2,225,0.0004,0.00030220777525594806,0.00041670196465646073,0.0004193256790632958,0.7206994237296181 +2,226,0.0004,0.00029512470051742533,0.0004312868214781191,0.0004303172683071138,0.6858304842807221 +2,227,0.0004,0.0002935937900935022,0.00043402339723267006,0.0004290870890141371,0.6842289073951354 +2,228,0.0004,0.0002830127777156892,0.00040920413042857683,0.00040461316061651885,0.699465082362758 +2,229,0.0004,0.0002817875220713729,0.0004224790402635673,0.00042146384106941584,0.6685924025092392 +2,230,0.0004,0.000294957824421446,0.00040688998444019523,0.0004065265273125027,0.7255561558832979 +2,231,0.0004,0.0002913546558163355,0.00041864065971270657,0.00041873541285591004,0.6957965504498489 +2,232,0.0004,0.00030423023472423,0.0004826901767960167,0.00048287782938562625,0.6300356243551446 +2,233,0.0004,0.0002716826394072981,0.00037983247674926494,0.0003797397483776343,0.715444302494038 +2,234,0.0004,0.00027897013075039626,0.00044931112168207005,0.00044756301759983765,0.6233091649226057 +2,235,0.0004,0.00027540557153806654,0.00044358229386307757,0.0004406446410215114,0.6250060613459765 +2,236,0.0004,0.0003096000309751197,0.00047694343341154403,0.0004704822387578675,0.6580482863550872 +2,237,0.0004,0.000299265108464022,0.0004442793208394609,0.0004321112789349658,0.6925649087467176 +2,238,0.0004,0.00027808617903181604,0.0003867876646242874,0.0003879964365433551,0.716723538775961 +2,239,0.0004,0.00029876518565109366,0.00042961196531774587,0.00042783613685073557,0.6983168552574313 +2,240,0.0004,0.00029367776698393285,0.00040950899640137867,0.00040952869566537517,0.7171115726256608 +2,241,0.0004,0.0002942381428439849,0.0004303040568879141,0.0004305854849421456,0.6833443140414251 +2,242,0.0004,0.00027824356687212467,0.0004029014709246735,0.00040337935665882323,0.6897813739820653 +2,243,0.0004,0.000264732716176248,0.0004050705018155409,0.0004064509227654059,0.6513276298527328 +2,244,0.0004,0.0002807179790115184,0.0003994830033931242,0.00040087742933504815,0.7002588783238728 +2,245,0.0004,0.00029474710785744307,0.0004352345093058347,0.00043429666780023506,0.6786768808298085 +2,246,0.0004,0.000264686614214955,0.0003902611284832404,0.0003846835205778933,0.6880633041345984 +2,247,0.0004,0.00025107896606359166,0.0003746769636347466,0.0003738048673982659,0.6716845818812803 +2,248,0.0004,0.0002861269370813767,0.0004544101073288135,0.0004507909013641983,0.634722076722245 +2,249,0.0004,0.0002807686754964012,0.0004303637041155738,0.0004190416724779567,0.6700256655527995 +2,250,0.0004,0.00026756168052969757,0.00040468961187740444,0.00040109138208954404,0.6670840922479959 +2,251,0.0004,0.0002695018560993283,0.0004050656340676708,0.00039997445405953725,0.673797672236368 +2,252,0.0004,0.0002986909907871149,0.00042938576856343247,0.00044411319437331524,0.6725559937677499 +2,253,0.0004,0.0003049755998787542,0.0004325210473866114,0.00044740704559871635,0.6816513125550769 +2,254,0.0004,0.0002995956679656421,0.0004439590573492979,0.0004319612334302955,0.6935707299159454 +2,255,0.0004,0.0002652769023494762,0.0003825739855219452,0.0003904414337636834,0.679428153391211 +2,256,0.0004,0.0002900384976771726,0.00044077749370803967,0.00043989965976321276,0.659328761093594 +2,257,0.0004,0.00029800285775574475,0.00040756322242193656,0.00040894235334675103,0.7287160532943422 +2,258,0.0004,0.00028192902250399914,0.00042075613027694103,0.00043158525502013767,0.653240626793064 +2,259,0.0004,0.0003307071994687758,0.0004527246419831463,0.00045253009207512566,0.730796040440719 +2,260,0.0004,0.0002875231522241939,0.0004160626385246509,0.00041317131653752264,0.6958933031307901 +2,261,0.0004,0.0003043111433569066,0.0004480720174393505,0.00045075905308734877,0.6751082230575561 +2,262,0.0004,0.00029292816993968426,0.00043509554468093705,0.0004349318606652095,0.6735035908651605 +2,263,0.0004,0.0002727034481710996,0.0004036127603947874,0.0004053425998701781,0.6727727316557406 +2,264,0.0004,0.0003012034976639285,0.0004256616517457307,0.00042651953380432625,0.706189221809736 +2,265,0.0004,0.00029838372965504547,0.00041190791129645186,0.0004149348132121543,0.7191098942630374 +2,266,0.0004,0.0003150618932082869,0.00041437777252504264,0.0004182547246175843,0.7532775475431917 +2,267,0.0004,0.0003048922081585734,0.0004532607521987296,0.00045197308137454105,0.6745804578257955 +2,268,0.0004,0.0003160566685334701,0.00046222762959203313,0.0004629257036171759,0.6827373508618965 +2,269,0.0004,0.00025006590024242406,0.00036870246012440786,0.0003677643634164306,0.6799622941151232 +2,270,0.0004,0.00033132578664505383,0.00048703116061137226,0.0004883240372922054,0.6784957555689476 +2,271,0.0004,0.00031940737683067784,0.00046366683585343177,0.0004692386521985135,0.6806928102238925 +2,272,0.0004,0.0003219763711102082,0.0005071046919912218,0.0005028478960346731,0.6403056941258571 +2,273,0.0004,0.00032857187323027595,0.0005065875574326337,0.0005022185492353169,0.6542408155384999 +2,274,0.0004,0.00026456284134066503,0.0003837058035296367,0.0003870885619097118,0.68346850662659 +2,275,0.0004,0.0002953646677423831,0.0004509310738905047,0.00044869633464769974,0.6582729675612189 +2,276,0.0004,0.0003438315039773661,0.0005133890630876526,0.000516550415281833,0.6656300988351148 +2,277,0.0004,0.0002825357329710374,0.00042894266204587204,0.0004351012415117594,0.6493563015112688 +2,278,0.0004,0.00029366337383948264,0.00042905831100996047,0.0004386736315546778,0.6694347522068452 +2,279,0.0004,0.0002833162639911842,0.0004086423131920413,0.00041971318940494263,0.6750234949558338 +2,280,0.0004,0.0003278252829017954,0.00044237364632687535,0.00045702597529978555,0.7173012052252803 +2,281,0.0004,0.00028763407115037166,0.00042938428432588043,0.00042566817560869895,0.6757236919087488 +2,282,0.0004,0.00031992796606144434,0.00046199138487219485,0.00046254706538972516,0.6916657568498134 +2,283,0.0004,0.00026449534472174524,0.0003843267969215651,0.00038725336950120546,0.6830033398093439 +2,284,0.0004,0.0003471645639012206,0.0005005008749352735,0.0005010086863029561,0.6929312273266512 +2,285,0.0004,0.00027884014773755237,0.0004017590198844667,0.00040201853037012854,0.6936002364886791 +2,286,0.0004,0.0002999874170514643,0.0004312804742459569,0.00043146800324523666,0.6952715260347087 +2,287,0.0004,0.0002715081641432814,0.0004137783221743602,0.0004137508343706266,0.6562117622222651 +2,288,0.0004,0.0002852069107592396,0.000421944520970048,0.0004219445375596233,0.6759345965438365 +2,289,0.0004,0.00029258461584212526,0.0004368007728038159,0.0004368528262210962,0.6697555750596079 +2,290,0.0004,0.0002904075722473566,0.00040938258097985365,0.0004094474227228229,0.7092670661257262 +2,291,0.0004,0.00025744271993674534,0.00037951392116925643,0.0003796176224351399,0.6781632482847423 +2,292,0.0004,0.0002747309748104966,0.0004013335444969433,0.00040174118151211757,0.6838506666815535 +2,293,0.0004,0.00029004741477139473,0.0004107227729536511,0.00041073107302869123,0.7061735374258712 +2,294,0.0004,0.0002808216183290557,0.00040164842560582185,0.00040180907577196985,0.6988931690742207 +2,295,0.0004,0.0002677281781925136,0.0004154823761961199,0.000415565493718598,0.6442502619666658 +2,296,0.0004,0.00033850451368913794,0.00047215917986750814,0.0004719633744488447,0.7172262341001375 +2,297,0.0004,0.00028162641841620147,0.0004413685788726104,0.0004410030156790127,0.6386042915887572 +2,298,0.0004,0.00030574780583098434,0.0004346012713103895,0.00043486578312812766,0.7030854523242627 +2,299,0.0004,0.000283037210709155,0.00043619896678448493,0.00043603071313867345,0.6491221883701092 +2,300,0.0004,0.0002821612686464068,0.00040676939067988457,0.0004066318795082656,0.6938985427990068 +2,301,0.0004,0.00028922083793453683,0.00039892330385243256,0.00039950954509092643,0.7239397443400547 +2,302,0.0004,0.000311249648297726,0.0004884372170573095,0.00048616045982397574,0.6402199973449512 +2,303,0.0004,0.000317723941682717,0.0005002319545810744,0.0004985824481143629,0.637254566189299 +2,304,0.0004,0.0002758005879630176,0.0004155628690562272,0.0004097984813234668,0.6730151538685658 +2,305,0.0004,0.0002681845127198809,0.0004020275140961617,0.0003973399133959252,0.6749498443984691 +2,306,0.0004,0.0002941079602474232,0.000416317014409964,0.00041324677809041977,0.7117005524071416 +2,307,0.0004,0.00028522963541026056,0.0004066590662083645,0.000407419533904968,0.7000882669430164 +2,308,0.0004,0.00029976185906422346,0.00043253634521585234,0.0004337440497519578,0.6911031038596293 +2,309,0.0004,0.0002502022280782601,0.0003512859706686326,0.0003527714573775355,0.7092473692124531 +2,310,0.0004,0.00028006506030086795,0.0003970756842428565,0.0003990596055148748,0.7018126025046367 +2,311,0.0004,0.00028260698599132724,0.00039013929363590375,0.0003949239680313448,0.7155984667127039 +2,312,0.0004,0.00026128840146720576,0.0003836273250367662,0.0003798332792042939,0.6879028662643102 +2,313,0.0004,0.0002653050898636942,0.0003774452612428918,0.0003787952911332015,0.7003917315603614 +2,314,0.0004,0.00031248001614270064,0.0004533026922727906,0.00045167940163791685,0.6918181679517817 +2,315,0.0004,0.00030617166640900046,0.00045062957593107244,0.0004505693293315418,0.679521766080333 +2,316,0.0004,0.00029717736931553657,0.00044485714662054307,0.0004461416352614021,0.6661054378872646 +2,317,0.0004,0.0002797995636456752,0.00040036463164349944,0.0004003016036501078,0.6989718779399146 +2,318,0.0004,0.0003197187666311507,0.0004440190691494372,0.00044399607022506924,0.7200936856695145 +2,319,0.0004,0.0002749412868015532,0.0004324318678253107,0.0004324444878900291,0.6357840011859995 +2,320,0.0004,0.0002821030045769308,0.00045636459696722805,0.0004563810306408495,0.6181304340822453 +2,321,0.0004,0.0002854913550216381,0.00046369755088077134,0.00046369056175328435,0.6156936943942787 +2,322,0.0004,0.0002849751319602353,0.00040610084375340217,0.0004061073711354821,0.701723613544469 +2,323,0.0004,0.0003238856077968466,0.00047184297323234615,0.0004718810934406087,0.6863712327088838 +2,324,0.0004,0.0002637981447156001,0.00038447065158456884,0.00038444972651933566,0.6861707175706172 +2,325,0.0004,0.0002980613210827157,0.0004376245760235682,0.0004376452577984271,0.6810568965881457 +2,326,0.0004,0.0003035770139272793,0.00045464355591077056,0.0004546240914175595,0.6677539084668795 +2,327,0.0004,0.0003182715912079669,0.0004681898700218703,0.0004698260548672835,0.677424310360719 +2,328,0.0004,0.0003336279870646476,0.0004250623513519482,0.0004240949228214026,0.7866823418802092 +2,329,0.0004,0.00029193696518868664,0.00040939355661162954,0.0004093730763648835,0.7131318155580818 +2,330,0.0004,0.0002631036724827007,0.0004072240275247545,0.00040720723547682996,0.6461173809316344 +2,331,0.0004,0.0003023283687697614,0.0004234437784496115,0.00042346254606903156,0.7139435862185478 +2,332,0.0004,0.0002565300697633239,0.0003730538535174164,0.000373133314184814,0.6875024555868625 +2,333,0.0004,0.0003001019843367545,0.00043623426791959664,0.0004373525007717025,0.6861787318175354 +2,334,0.0004,0.00030828462053549715,0.0004609391245033393,0.0004618513631515185,0.6674974789115409 +2,335,0.0004,0.00032635213416152853,0.0004710440483048224,0.0004683154083200173,0.6968639689482948 +2,336,0.0004,0.0002632104177995361,0.00038304809799700817,0.00039445362511579025,0.6672784860888825 +2,337,0.0004,0.00026913960006576444,0.0003916811229897875,0.00040083185609447156,0.671452620278592 +2,338,0.0004,0.00032192504086812684,0.0004637069984857724,0.0004593064726001247,0.7008937606424652 +2,339,0.0004,0.0002924256186762183,0.0004195893702692974,0.0004211583161395231,0.6943365653008792 +2,340,0.0004,0.0003032321065467843,0.00046949342996087026,0.000465523890794409,0.6513781838979813 +2,341,0.0004,0.0002989429667262092,0.0004616618966975646,0.00045804383614282896,0.6526514345080973 +2,342,0.0004,0.00031276048927170923,0.0004422764240131895,0.0004413822837437509,0.7085932099922833 +2,343,0.0004,0.00029819518378458793,0.00045468581075346965,0.0004544155044756079,0.6562170103080065 +2,344,0.0004,0.00030272682589965657,0.0004488763708369471,0.00044912939576308836,0.6740303100965188 +2,345,0.0004,0.00028577498336711693,0.00042068896825706763,0.00041999367279216374,0.6804268775461632 +2,346,0.0004,0.0002810414777053273,0.00044639934811845723,0.00044509849434512365,0.6314141280545679 +2,347,0.0004,0.0002871990178710726,0.000398087873175894,0.0004008861584726094,0.7164104117870048 +2,348,0.0004,0.00029386080684690874,0.000424082268528536,0.00042453509691235556,0.6921943768233978 +2,349,0.0004,0.00027027828159497514,0.0003837165485328804,0.0003803743103159768,0.7105587161510857 +2,350,0.0004,0.00029966124489946714,0.00044514947601626275,0.00044403383413534975,0.6748612872777727 +2,351,0.0004,0.0003117421582010648,0.00041854266050414925,0.0004266302570852907,0.7307080382222919 +2,352,0.0004,0.00030743829042963823,0.00046656073968303133,0.00047860849385291,0.642358617488562 +2,353,0.0004,0.00029196775193530907,0.00041403424524142653,0.00041298194013175135,0.706974624222464 +2,354,0.0004,0.0002856683466642458,0.00041186533980889356,0.00041337832134560567,0.6910578806705547 +2,355,0.0004,0.000270828332928428,0.0004338895170305291,0.00043436636055878215,0.6235020883754123 +2,356,0.0004,0.00031240822235769147,0.0004208118024307973,0.00041642226034567693,0.7502197939619217 +2,357,0.0004,0.0002561602635469495,0.00040605767572245865,0.00040100113346732113,0.638801844104575 +2,358,0.0004,0.0002726798652547365,0.00042041644836767817,0.00041619245191493046,0.6551773440390797 +2,359,0.0004,0.00028080075566626935,0.0003789401078294262,0.00038344311414241765,0.732313986898132 +2,360,0.0004,0.0002751045865912043,0.0004098054191919722,0.00041094115942682245,0.6694500667076475 +2,361,0.0004,0.0002853869801836689,0.00041500142087020774,0.00041291273625534655,0.6911556731618583 +2,362,0.0004,0.0002837791856923414,0.00039512928653453306,0.0003960242255647573,0.7165702686184239 +2,363,0.0004,0.00028528071828215197,0.00043517203255841603,0.00043119918812360925,0.6615984587623395 +2,364,0.0004,0.00027381363489105957,0.00040608697798311507,0.00040164487761299057,0.6817306784001756 +2,365,0.0004,0.000245892457504767,0.00036814789734099614,0.00036770858609343156,0.6687155720706719 +2,366,0.0004,0.00030365644885111976,0.0004193570509831865,0.00041729070209326803,0.727685633367527 +2,367,0.0004,0.00032327835896678433,0.0004165706727773028,0.00041546370836170916,0.7781145560019244 +2,368,0.0004,0.0003102940389061199,0.0004472250715117877,0.0004394215782484761,0.7061420154716673 +2,369,0.0004,0.00034353717613920206,0.00043279186124760266,0.0004370094045505881,0.7861093435563222 +2,370,0.0004,0.0002719226859552444,0.0003921280656431173,0.00040608554912762904,0.6696192133391615 +2,371,0.0004,0.000275368165013475,0.0004022388153711101,0.00039906271770983167,0.6900373119137178 +2,372,0.0004,0.0002497160340258977,0.0003759105543896843,0.0003705684814879223,0.6738728372775452 +2,373,0.0004,0.00030228470415805006,0.00046542497004655803,0.0004614215957070921,0.6551160738257659 +2,374,0.0004,0.00026432360569061866,0.0003961704846498324,0.00040293161840659225,0.6560011515996088 +2,375,0.0004,0.0002857831637639514,0.00041897726596529206,0.0004167115318601911,0.6858057478952446 +2,376,0.0004,0.0002900670208615305,0.0004429063660348719,0.0004439439638000229,0.6533865634271646 +2,377,0.0004,0.000289415950622096,0.00045022876090275926,0.00045153024244963536,0.6409669240579784 +2,378,0.0004,0.000277791559426878,0.0004091253641342489,0.00040875870290536836,0.6795979081360121 +2,379,0.0004,0.0003500281565815198,0.0005412100126893189,0.00054170779534264,0.6461567649402582 +2,380,0.0004,0.00029105756523723034,0.0004105510860058042,0.000408481207844578,0.7125359983462791 +2,381,0.0004,0.00030072543271005995,0.0004665915560385465,0.0004686813106288476,0.641641614227299 +2,382,0.0004,0.00027166556465866323,0.000437952002622496,0.0004374263318649892,0.6210544378990708 +2,383,0.0004,0.00028839923654671,0.00045590774155019763,0.00045576327513245293,0.6327829649348031 +2,384,0.0004,0.00031352001460332535,0.00044365993634886856,0.0004467334688407372,0.7018055204525024 +2,385,0.0004,0.000330766650729032,0.00045633266840769393,0.00045654677415047956,0.7244967426273173 +2,386,0.0004,0.00031616395972454436,0.0004448420773001821,0.00044638595163459235,0.70827488760971 +2,387,0.0004,0.0002566222058594679,0.0003687868458636668,0.0003669941671537071,0.699254181203342 +2,388,0.0004,0.0003167854596710002,0.0004891232218272976,0.0004892339839413697,0.647513194236654 +2,389,0.0004,0.0003037408217800441,0.00047522405943990146,0.0004768662172139257,0.6369518552910695 +2,390,0.0004,0.00033435733820789997,0.0005090660019118818,0.0005126714496986494,0.652186382534929 +2,391,0.0004,0.0003001651528134983,0.00043763583933630366,0.00042694844129089425,0.7030477776331446 +2,392,0.0004,0.0002639287827155552,0.000384852044747458,0.00039063182132368556,0.6756458852256647 +2,393,0.0004,0.0003170482145772347,0.0004512346604354837,0.0004509288575418405,0.7031002990262529 +2,394,0.0004,0.0003135349594708481,0.00045021711063605467,0.0004512871621601256,0.6947570987175561 +2,395,0.0004,0.00029346819051421786,0.00043862935830212447,0.00043785831900780087,0.6702355026146927 +2,396,0.0004,0.0002920652733224619,0.0004407048568503724,0.0004415858923551301,0.6614008245706784 +2,397,0.0004,0.00028921426947105716,0.000434093076487007,0.0004328150284548333,0.6682167911395395 +2,398,0.0004,0.00032455762848357134,0.00048150011918997353,0.000479810386756089,0.6764289341000861 +2,399,0.0004,0.00030890121589616465,0.0004513396899915554,0.0004527343061443341,0.6823013226607247 +2,400,0.0004,0.0003098033185773834,0.00046979106059080364,0.0004690237347566264,0.6605280194149203 +2,401,0.0004,0.00034535094902401006,0.0005442415987648855,0.000545631432185677,0.6329381495501675 +2,402,0.0004,0.0002945506815421719,0.0004718254764126925,0.0004638235527430521,0.6350489961111276 +2,403,0.0004,0.0002839594473617381,0.0004647995920282959,0.0004502320709619763,0.6306957359901612 +2,404,0.0004,0.00030211353513838793,0.0004496341946910281,0.00045516128591320537,0.6637505088602766 +2,405,0.0004,0.00027353219037600174,0.0004324968790336938,0.00040563004328678684,0.6743390804083271 +2,406,0.0004,0.0003233951070982697,0.00048274073905556973,0.00047588704945168703,0.679562739668757 +2,407,0.0004,0.000330943798714361,0.00048686720907766516,0.000485980644725351,0.6809814388830071 +2,408,0.0004,0.00027905563497080755,0.000403584809662912,0.0004162843096377773,0.6703486739954794 +2,409,0.0004,0.00028065187362311773,0.0003887098200871068,0.0004000695878742236,0.7015076429937255 +2,410,0.0004,0.000333547512808733,0.00047332621347144315,0.0004642487396477029,0.7184672446539045 +2,411,0.0004,0.000311670533611146,0.0004541600749212576,0.00044622328263904703,0.6984631814096943 +2,412,0.0004,0.0002829301663753228,0.0003970005002480261,0.0003987494961372415,0.7095436335747594 +2,413,0.0004,0.0003003746347885807,0.0004388143063068411,0.0004406470362721863,0.6816672076810253 +2,414,0.0004,0.00029729485467991753,0.00040611621821166097,0.0004061289509377003,0.732020837208235 +2,415,0.0004,0.0003080571996787319,0.00046814979859624296,0.0004682119879670197,0.6579438536298885 +2,416,0.0004,0.00029272317827867583,0.00040469950259672206,0.0004048888115642279,0.7229717638968172 +2,417,0.0004,0.00029127632570347925,0.00041981945699827336,0.0004226826533407913,0.6891135072643622 +2,418,0.0004,0.0002716439050127632,0.00038448567543967647,0.0003834149019453887,0.7084855169543058 +2,419,0.0004,0.00027309382666121514,0.0004074159110353993,0.00040467713578034903,0.6748437272953449 +2,420,0.0004,0.0003315709447333492,0.0004850834286103087,0.0004878448106795476,0.6796647980563422 +2,421,0.0004,0.00026717563628259674,0.0003940900151037936,0.0003957660695150606,0.6750847454153205 +2,422,0.0004,0.0002891944545463329,0.0003986134804048161,0.000398749992395287,0.7252525644179825 +2,423,0.0004,0.0003022680699534556,0.0004370690957924081,0.0004397461685886255,0.6873694225093336 +2,424,0.0004,0.00029880002299590054,0.0004176445255245136,0.000418101260105522,0.7146594653182539 +2,425,0.0004,0.0002725887413115924,0.00041058464675465425,0.0003997230364157482,0.6819440374411532 +2,426,0.0004,0.0002788122127004349,0.0004040096281883174,0.00039787922790350094,0.700745837297282 +2,427,0.0004,0.0003538191029613652,0.0004939331408745687,0.0004908019288666111,0.7208999845995414 +2,428,0.0004,0.00028516876897834804,0.0004412789658029669,0.0004329201503601713,0.6587098538635812 +2,429,0.0004,0.00030700798062921095,0.00041727570748857775,0.00042347664878237797,0.7249702705260154 +2,430,0.0004,0.00032164075352759936,0.0004260338930130958,0.00042767467089087704,0.7520687462215112 +2,431,0.0004,0.0003187395011576968,0.00040987037201371216,0.0004117234767190195,0.7741591606524308 +2,432,0.0004,0.00031721033399725087,0.00046847623291124585,0.0004820150975027237,0.6580921129663546 +2,433,0.0004,0.0003143255595456426,0.0004326427394549969,0.00043618000191924866,0.7206326703713359 +2,434,0.0004,0.0002899579848264977,0.00038964920854509314,0.000392686340756335,0.7383959021035035 +2,435,0.0004,0.0002930643321552196,0.000422998563535122,0.00042168304348637033,0.6949872343270831 +2,436,0.0004,0.0002845591568791848,0.0004168119284013721,0.0004182752962211163,0.6803154751189417 +2,437,0.0004,0.00027959373209085855,0.0004056951588861432,0.00040625191250223767,0.6882274851797 +2,438,0.0004,0.0002898667791633705,0.00042227302490963444,0.00042106194815742776,0.6884183679665927 +2,439,0.0004,0.00028353394936045677,0.00040107166984335073,0.00040253837341766737,0.7043650197946879 +2,440,0.0004,0.00026277872417595826,0.0003744278253272503,0.0003737886576872841,0.7030141733080675 +2,441,0.0004,0.0003127780727462651,0.0004565013500372435,0.00045962582163424016,0.6805058767894178 +2,442,0.0004,0.0002736480139878979,0.00040203087849676063,0.0004025561311346834,0.679776043198168 +2,443,0.0004,0.00028691869334254445,0.00044553513498216883,0.00044658452942180726,0.6424734276263845 +2,444,0.0004,0.00029683025301823374,0.0004583919668855276,0.0004602970175926356,0.6448667744376513 +2,445,0.0004,0.00025355055759696926,0.00036006926358146506,0.0003613962579167025,0.7015860071672619 +2,446,0.0004,0.0002662567972405161,0.000388736554690389,0.0003863688029990294,0.6891260246008655 +2,447,0.0004,0.0002661199593523435,0.00038722816333692595,0.00038472667750413347,0.6917117395621319 +2,448,0.0004,0.0002649376233251167,0.0003786170286732287,0.0003793860091768984,0.6983326135297276 +2,449,0.0004,0.00029190576028534674,0.0004422495903232482,0.00044345662975206094,0.6582509781138076 +2,450,0.0004,0.00029241431829340277,0.0004297667649610147,0.0004313904763796489,0.6778413857149248 +2,451,0.0004,0.0003055757337176815,0.00042910040383756064,0.00042959705181289717,0.7113077997815711 +2,452,0.0004,0.00027189971566893983,0.00043798321084044544,0.0004382855361809397,0.6203711809387432 +2,453,0.0004,0.000289687534580699,0.00039002360509741887,0.00039070747462360356,0.7414435438169584 +2,454,0.0004,0.000312382356495431,0.00045194195462304075,0.00046122560954495683,0.6772875357108337 +2,455,0.0004,0.00029313460701253953,0.00042032894850058415,0.0004301513275955198,0.6814685628221054 +2,456,0.0004,0.0003531343333684715,0.00046703664612512806,0.0004743593699280107,0.7444447306312587 +2,457,0.0004,0.0003256242637167942,0.0004311274983763596,0.0004257131309366029,0.7648912848903552 +2,458,0.0004,0.00023900981419469885,0.00040791141292718827,0.00039305723873105217,0.6080789021118636 +2,459,0.0004,0.0002924194662945106,0.00044024395355405505,0.00043198310515684616,0.6769233861318205 +2,460,0.0004,0.00028669655054182396,0.000397884630743559,0.0003968348262682871,0.7224581401734074 +2,461,0.0004,0.00026519907574140336,0.0003898683152189949,0.00039026385867619765,0.6795378814758231 +2,462,0.0004,0.0002730869117405974,0.00038378698076745846,0.00038532332313747324,0.7087214693286737 +2,463,0.0004,0.0002829144287749514,0.00041404279172404027,0.00041569039658866,0.6805892825445882 +2,464,0.0004,0.0003108550916925704,0.0004358038007742064,0.0004331607807004398,0.7176436684547114 +2,465,0.0004,0.0003025850957661119,0.00044428329588343474,0.0004384224374309263,0.690167906412829 +2,466,0.0004,0.0002514314777054949,0.0003753180936927992,0.0003740948767670112,0.672106177658477 +2,467,0.0004,0.0003155362940082369,0.00045670535278641603,0.00045662629743815236,0.6910164740369003 +2,468,0.0004,0.0003228684909018882,0.00046668051508107027,0.00046645909675862424,0.6921689235893731 +2,469,0.0004,0.00026954864263880533,0.000382650333213425,0.0003800623256805308,0.7092222102155423 +2,470,0.0004,0.00026486651632920313,0.00039061475256526587,0.00039276410625717627,0.6743653814327227 +2,471,0.0004,0.00030867077782428034,0.00044418289270763996,0.0004432801832272366,0.6963333564271875 +2,472,0.0004,0.00028640339732814984,0.0004132062769435886,0.00041365054564074136,0.6923800786591815 +2,473,0.0004,0.00029472146309254913,0.0004363773878470378,0.0004358033963629343,0.6762716067662469 +2,474,0.0004,0.00027258583570375093,0.00037754768703251817,0.0003774546985707008,0.7221683469193669 +2,475,0.0004,0.0002982157887397058,0.00040634306846707525,0.0004062432470573606,0.7340818361901249 +2,476,0.0004,0.0002806684275849591,0.00040852257795296384,0.00041153689152760017,0.6820006501558944 +2,477,0.0004,0.0002970426851139498,0.0004099646075311741,0.00040534315004582696,0.732817823812656 +2,478,0.0004,0.00026890427578147983,0.0004337427935839604,0.00043658301879472044,0.6159293060088477 +2,479,0.0004,0.0003035835304835602,0.0004098716325334714,0.00042101186765813197,0.721080695829873 +2,480,0.0004,0.0002750970894584142,0.0004193099383939918,0.0004070250644757418,0.6758726021276994 +2,481,0.0004,0.0003146651321549498,0.000461896232379867,0.00045429733584929487,0.6926413767465597 +2,482,0.0004,0.00030917162355354393,0.0004619303215917271,0.0004559206081177417,0.6781260115219451 +2,483,0.0004,0.0002892692512360327,0.0004917942347342463,0.0004825821647753958,0.5994196892267348 +2,484,0.0004,0.0002717172011190883,0.0004612200109788356,0.0004512298963219538,0.6021702093187932 +2,485,0.0004,0.0003080726448534774,0.0004433456656705141,0.0004449997539465612,0.6922984611143695 +2,486,0.0004,0.0002526450158160635,0.00038771621481666687,0.0003872982720853936,0.652326731166926 +2,487,0.0004,0.0002704016701544352,0.0004159112810330005,0.0004109911976472852,0.657925696954939 +2,488,0.0004,0.0002679322984507294,0.0004171307500837621,0.0004131619717220672,0.6484921575283957 +2,489,0.0004,0.0002721558778274696,0.00042509639507148185,0.0004200943467317465,0.6478446566700795 +2,490,0.0004,0.0003156282164118234,0.0004760781280982317,0.0004679101728935224,0.6745487375493495 +2,491,0.0004,0.0002959335600858512,0.00040987851480271616,0.0004102297422871973,0.7213849450210545 +2,492,0.0004,0.0003354065726262285,0.0005002370521742135,0.0005013236690719994,0.6690419649387387 +2,493,0.0004,0.0002709322245097208,0.0003832727303661138,0.00038407820634155993,0.7054090027403985 +2,494,0.0004,0.00028895132002272996,0.00043802954649308325,0.00043679652704738624,0.6615238495048356 +2,495,0.0004,0.00026409776001127096,0.00041363780064317595,0.00041276835629864276,0.6398207517152626 +2,496,0.0004,0.0002952880118376817,0.0003960622314685089,0.00039765491014416804,0.7425735337472039 +2,497,0.0004,0.0003425574679451659,0.0004364517435762974,0.0004370558215330532,0.7837842469265892 +2,498,0.0004,0.0002863569790345449,0.0004458100365040993,0.0004403699511964449,0.6502645747207301 +2,499,0.0004,0.0002783281952486799,0.0003959982598614939,0.00039743237294245754,0.7003158630184809 +3,0,0.0004,0.0003046442612055867,0.00046331771105872686,0.0004693598310354802,0.6490633434341717 +3,1,0.0004,0.0003053077758252013,0.00043964724406418394,0.00044069011906852775,0.6927946931746968 +3,2,0.0004,0.0002913479015806696,0.00041650494923713,0.00041830672682224694,0.6964934649603984 +3,3,0.0004,0.00030492255960732343,0.00044650065342903604,0.0004470015309356995,0.6821510408902516 +3,4,0.0004,0.0002669139280825888,0.00040045551351124094,0.00040013831235652554,0.6670541656225284 +3,5,0.0004,0.0003003949851814211,0.0004271108321282187,0.00043210515411141743,0.6951895443116257 +3,6,0.0004,0.0003253359519303099,0.0004455153850388965,0.0004519543743452756,0.7198424672880052 +3,7,0.0004,0.0003197399385244002,0.00048095916668647906,0.00048334737065291165,0.6615116951862002 +3,8,0.0004,0.00026658300049565856,0.00037817075138174723,0.00037747165850233615,0.7062331554992988 +3,9,0.0004,0.0003081363507155927,0.00043700713600089967,0.00043337949247363095,0.7110081489016035 +3,10,0.0004,0.00026351222879958906,0.00038624944444278284,0.0003899946483684251,0.6756816533304093 +3,11,0.0004,0.0003023871248547873,0.00043971196510998126,0.0004393730441780746,0.6882241158431923 +3,12,0.0004,0.0003091747653757103,0.00046530894330367584,0.00046535562401607317,0.6643838591817073 +3,13,0.0004,0.00030810910434678245,0.00047049533216870327,0.00047062550143661105,0.6546800022656272 +3,14,0.0004,0.0002815338236657093,0.0004085699224901157,0.0004071565557444033,0.6914633196829699 +3,15,0.0004,0.0002589396616933361,0.0003789610754853622,0.0003781249656646272,0.6847991674873939 +3,16,0.0004,0.00029840462446381193,0.00045053834528576184,0.0004425122769988706,0.6743420238814606 +3,17,0.0004,0.00030465247336733777,0.000430655126685094,0.0004249187724733624,0.7169663782892436 +3,18,0.0004,0.00028064421321885623,0.0004082228036555679,0.0004080296591552102,0.6878034645812404 +3,19,0.0004,0.0003033391289089394,0.00047357620813306836,0.00047523320933782424,0.6382953104889347 +3,20,0.0004,0.00029956990583944346,0.0004304696701217226,0.0004245922342221138,0.7055473032573922 +3,21,0.0004,0.0002720867955512251,0.0004212620535037771,0.00041575850399718346,0.6544347089363886 +3,22,0.0004,0.00030471873813644795,0.0004556529278753218,0.000445258556507529,0.6843635763601443 +3,23,0.0004,0.00027161950472035873,0.0004056694099537178,0.0003984388773449645,0.6817093415439809 +3,24,0.0004,0.00028655542539898,0.00040864681845193776,0.0004014045303517841,0.7138818915368188 +3,25,0.0004,0.00028529075124730357,0.00040821287803819144,0.00041518830910829894,0.6871358007647742 +3,26,0.0004,0.00028568268012098497,0.00039454758496346105,0.000392778409381599,0.7273380442951829 +3,27,0.0004,0.00031335855753385916,0.0004673332700827983,0.0004660691521980043,0.6723434839144476 +3,28,0.0004,0.0003255221246151986,0.0005044451150135288,0.0005079741657442528,0.6408241728952169 +3,29,0.0004,0.00027899338514430426,0.0004011737490562883,0.00039942603144969087,0.6984857349725452 +3,30,0.0004,0.0002783483079676571,0.0003888363359493532,0.0003878980525830611,0.717581091511291 +3,31,0.0004,0.00027090885201307,0.0003829121725376499,0.0003845509620326999,0.7044810148987055 +3,32,0.0004,0.0002866530218712076,0.0004243784695744946,0.00042360275518062656,0.6767024490881254 +3,33,0.0004,0.00030084338304797856,0.0004225867930708886,0.0004238030739015269,0.7098659768519784 +3,34,0.0004,0.0003099112313428807,0.00045308339446054264,0.00045233516897660625,0.6851362719464084 +3,35,0.0004,0.0002528633066129976,0.0003590979674122471,0.00036195631005634115,0.6986017361422366 +3,36,0.0004,0.00029808361913024207,0.0004390111932191573,0.0004400743715326987,0.6773482811372797 +3,37,0.0004,0.0002734930168434523,0.00040455374926163265,0.00040319091379049606,0.678321379498059 +3,38,0.0004,0.0002924525662268559,0.00043069986487946643,0.0004323771570427185,0.6763830176115474 +3,39,0.0004,0.0002717362984140939,0.00037425217700547727,0.00037516821512506804,0.7243052248536206 +3,40,0.0004,0.00025061283877612906,0.0003837969283875648,0.00037866134584315546,0.6618389796774633 +3,41,0.0004,0.0003312733881152313,0.00046555641029288327,0.0004565101457329381,0.7256648975092631 +3,42,0.0004,0.00028251784197801675,0.00043860036969973744,0.00044656367177406457,0.6326485109181798 +3,43,0.0004,0.00029277536654970834,0.00044491408866680684,0.000443054223008399,0.6608115922284261 +3,44,0.0004,0.0002830181074062942,0.0004263350213812154,0.0004290876550713114,0.6595810997155315 +3,45,0.0004,0.00027248425463361435,0.00038047164466963404,0.0003799581369823241,0.7171428326228753 +3,46,0.0004,0.00027783147350487174,0.0004349012480997495,0.0004348504960013298,0.6389126287302708 +3,47,0.0004,0.00027285416621886815,0.00038798264719176685,0.00038613353757986727,0.7066316174684293 +3,48,0.0004,0.00031351574439799805,0.0004504286562654209,0.0004519550101007702,0.6936879498870805 +3,49,0.0004,0.0003165548144375487,0.0004317524177286412,0.0004267942346940822,0.7417035861893707 +3,50,0.0004,0.0002785231725106069,0.0004484794307315322,0.0004493845907253244,0.6197879906408441 +3,51,0.0004,0.00031964003348060067,0.000442777523769094,0.0004416744284711495,0.7237005651131551 +3,52,0.0004,0.0003098911339687895,0.0004896547196824594,0.0004835200390097824,0.6409064960439413 +3,53,0.0004,0.00029859434512025123,0.0004362163668660075,0.00043368019611241166,0.6885127515549601 +3,54,0.0004,0.0002653349840774178,0.00039405471151300364,0.00040041690984087805,0.6626468002634041 +3,55,0.0004,0.00029953953282423415,0.00040630741584138884,0.0004055105545740479,0.7386725929707879 +3,56,0.0004,0.0003054824519855839,0.000498114827335735,0.0004945544567634628,0.6176922436100724 +3,57,0.0004,0.00029947716929767433,0.00041623441390814054,0.000415849470255114,0.7201576308704974 +3,58,0.0004,0.0002788027885174208,0.00044441856888555734,0.00044464970892429945,0.6270166895912358 +3,59,0.0004,0.0002848106803383766,0.00040859420567129437,0.00040751895337216756,0.6988894086559764 +3,60,0.0004,0.00028563366886392104,0.00042019158556551523,0.0004183112288962717,0.6828257267144732 +3,61,0.0004,0.00030080124725990565,0.00043506430314178433,0.0004354918121087496,0.690716194647514 +3,62,0.0004,0.00028694035052397114,0.00038528295648265466,0.00038467820569756565,0.7459230761556684 +3,63,0.0004,0.00027544678755858334,0.00041572265836536536,0.0004116590068955361,0.6691139582632322 +3,64,0.0004,0.00030456978221556373,0.00043774699281861094,0.000435169255755329,0.6998880968438774 +3,65,0.0004,0.00028943732604135047,0.00042439578748538874,0.000425296088099085,0.6805548749226155 +3,66,0.0004,0.0003116703331980743,0.00046129247987925875,0.00046352633345741133,0.6723897019471289 +3,67,0.0004,0.00026448880089034564,0.0003791370626707626,0.00038241977927129127,0.6916190407157665 +3,68,0.0004,0.0003033950684188095,0.00042736928835878746,0.0004355882937673733,0.6965179568871476 +3,69,0.0004,0.00028878436651886283,0.0004206500156740304,0.00043261677795757556,0.6675292804921735 +3,70,0.0004,0.0002734741595474755,0.0003875330632351979,0.0003743927714173441,0.730447221275615 +3,71,0.0004,0.00029070386081483175,0.00041357520062513034,0.00041919178849415665,0.6934865347890373 +3,72,0.0004,0.00028533548244627445,0.0004268716257200093,0.00041460695386137805,0.6882071798093263 +3,73,0.0004,0.0002729582957220342,0.00039888498527636463,0.0004071231552057179,0.6704563280958789 +3,74,0.0004,0.0003005600955833466,0.00042626357606994486,0.0004253520094558295,0.7066149657265417 +3,75,0.0004,0.0002829878151232141,0.0004188157330256872,0.0004175196167960925,0.6777832794894023 +3,76,0.0004,0.0002726013622585769,0.00040341485744322406,0.00040335260245014006,0.6758388581173818 +3,77,0.0004,0.0004005605460962481,0.0005900854750224005,0.0005899773741626842,0.6789422164955683 +3,78,0.0004,0.0002665155854809952,0.0003942799470778439,0.0003944081573692002,0.6757354798610657 +3,79,0.0004,0.0003400613174948108,0.0005020888600936556,0.0005033622440529062,0.6755797072834657 +3,80,0.0004,0.00030249202419507375,0.0004299743249837832,0.00043141226410721976,0.7011669564402898 +3,81,0.0004,0.0002523870880659595,0.0003701683778221918,0.00037259482256885804,0.6773767985445279 +3,82,0.0004,0.000265518933144141,0.00038033733618228336,0.00037825531330671936,0.701956915880352 +3,83,0.0004,0.0002709281265200728,0.00041219298746423725,0.0004135204590996398,0.6551746607893743 +3,84,0.0004,0.0003105478473198115,0.00043040233348607993,0.00043211328467031925,0.7186722980681881 +3,85,0.0004,0.00030171162552639243,0.0004236846130720883,0.00042287665019356824,0.7134743083787825 +3,86,0.0004,0.0002848396485258678,0.0004283105296311959,0.00042787588694727136,0.6657062414946734 +3,87,0.0004,0.0002867532305063493,0.0004322441249634362,0.0004322718850024525,0.6633631296764129 +3,88,0.0004,0.0003162637703693755,0.00044301512261504344,0.00044340357908167805,0.7132639096517476 +3,89,0.0004,0.0003018963170194088,0.0004454131291311436,0.00044521607739898616,0.6780894319520732 +3,90,0.0004,0.00030371056469025387,0.0004402471931034969,0.00044042178724623373,0.6895902370979969 +3,91,0.0004,0.0002600802511914467,0.0003869498377093485,0.0003867164464306028,0.6725347566466087 +3,92,0.0004,0.0002867547880045248,0.00042732329976460096,0.0004250334821162413,0.6746639972379893 +3,93,0.0004,0.0002719775152090591,0.00040785267997587357,0.0004074132166006325,0.6675716548382512 +3,94,0.0004,0.0003360437598697662,0.00044537028852802173,0.00044680114603746487,0.7521103355486659 +3,95,0.0004,0.0003161970305369134,0.0004213725223180356,0.0004225452250716576,0.7483152376962512 +3,96,0.0004,0.00025294555584495093,0.00039404604844043884,0.00038705929336181995,0.653505961962524 +3,97,0.0004,0.00034078288751099127,0.0005148450390130337,0.0004994858213879574,0.682267389620857 +3,98,0.0004,0.00023644778002945285,0.00032626228622425005,0.0003394254743969057,0.6966117686056872 +3,99,0.0004,0.0002763862109125388,0.00040265661383296416,0.0004132958170963678,0.6687370146988303 +3,100,0.0004,0.0002902752333917373,0.0004237170353113431,0.0004163582547046277,0.6971766023893629 +3,101,0.0004,0.00027911387598030803,0.00040483724978165626,0.0004033118781410839,0.6920546879669889 +3,102,0.0004,0.0002798017188603509,0.00040998276401529627,0.00040652772454362915,0.6882721693199603 +3,103,0.0004,0.0002992555180360548,0.00045189310484787304,0.0004546875864199906,0.658156340691552 +3,104,0.0004,0.0002635906908759387,0.00037661177377612645,0.0003755843963136497,0.7018148077052028 +3,105,0.0004,0.0002880763053825375,0.0004092518650813812,0.000409606841064091,0.7032995460577827 +3,106,0.0004,0.00030449626058490963,0.0004559193094215608,0.00045602796828439983,0.6677140038810336 +3,107,0.0004,0.0002851148221752242,0.00042967395972039624,0.00042934092264285356,0.6640755798915456 +3,108,0.0004,0.00027464761191117775,0.0004015609480293069,0.000401584598591764,0.6839097238148176 +3,109,0.0004,0.0003102316028634229,0.0004523683677476324,0.0004525629564107391,0.6854993288090984 +3,110,0.0004,0.00029038563911459707,0.00042608577500232147,0.0004263975637952074,0.6810208682478897 +3,111,0.0004,0.00034737852449412545,0.00045642920852167806,0.0004586761329268642,0.757350338412997 +3,112,0.0004,0.0002405213534374926,0.0003825785357146033,0.00038227407765877697,0.6291856222910966 +3,113,0.0004,0.0003353345871236062,0.0004919866284773054,0.0004923562870227292,0.68108115192632 +3,114,0.0004,0.00030382750572749477,0.00047283520115572506,0.00047238904167651443,0.6431722138371527 +3,115,0.0004,0.0003555890017313079,0.0005360594351076096,0.0005389304012675065,0.6598050525540973 +3,116,0.0004,0.0003339883816257257,0.0005352651162985356,0.0005325857497899687,0.6271072437770591 +3,117,0.0004,0.0003328184933733718,0.0004897957700160276,0.0004897968445086813,0.6795031391172485 +3,118,0.0004,0.0003065277604928066,0.00042975883860684697,0.00042977644253854724,0.7132260639560618 +3,119,0.0004,0.00031245307658710696,0.0004439918202212492,0.0004444858638025091,0.7029539115465188 +3,120,0.0004,0.0003143037653698098,0.00048194086854762394,0.000482652860512999,0.6512004612087964 +3,121,0.0004,0.00025882759718217426,0.00038196889936581034,0.00038174143362220797,0.6780180886477314 +3,122,0.0004,0.00029901002993910024,0.0004395302880348333,0.00043884296187443914,0.681359975928365 +3,123,0.0004,0.0003038630516799753,0.0004246815647710252,0.00042669768195578825,0.712127261360327 +3,124,0.0004,0.00028944556882623367,0.0004441183403782225,0.000435268722103408,0.6649813187299713 +3,125,0.0004,0.0002472405966958753,0.00040128751139576873,0.00039944062132110826,0.6189670842143015 +3,126,0.0004,0.00031546045522206343,0.00040953837263640056,0.00041509105457300326,0.7599789293136465 +3,127,0.0004,0.00030259766767269127,0.0004710421881707813,0.0004620485303563117,0.6549045128210691 +3,128,0.0004,0.00028756953916734656,0.0003984735800601736,0.00039923447762910136,0.720302366857468 +3,129,0.0004,0.00029158788297119393,0.0004610991554032331,0.00046103872612419456,0.6324585472948883 +3,130,0.0004,0.0003127766145534758,0.0004814855670406093,0.0004814330079771212,0.649678375539094 +3,131,0.0004,0.0002888008939337542,0.00039670451757562467,0.00039666804083009964,0.7280669582792354 +3,132,0.0004,0.0003116083890889438,0.0004960845989058167,0.0004925596214338096,0.6326308035195245 +3,133,0.0004,0.00025658987237841147,0.000349365545768901,0.0003478945912480537,0.7375506226121789 +3,134,0.0004,0.0003049818304434063,0.0004637326141301119,0.0004623925352075385,0.6595734299787503 +3,135,0.0004,0.00036663780931966343,0.000521381863686133,0.0005210238755749699,0.7036871562076968 +3,136,0.0004,0.0003040877346198351,0.00045443858109647805,0.0004546344740047168,0.6688620243450351 +3,137,0.0004,0.0002895422548928255,0.0004423427814514445,0.0004422826036373372,0.6546544053770749 +3,138,0.0004,0.0003600781034870184,0.0004879863404676643,0.0004879390081632134,0.7379571984672598 +3,139,0.0004,0.0002685753075751154,0.0004007841728048084,0.00040080642228786063,0.6700873355323225 +3,140,0.0004,0.00032518633089560284,0.0004599760098737997,0.00045997701593419003,0.7069621299124389 +3,141,0.0004,0.0002892082679669123,0.0004430774081248752,0.00044258485576374545,0.6534526977156522 +3,142,0.0004,0.0003010268019187053,0.00044132163050901896,0.00044156079239769354,0.6817335395294433 +3,143,0.0004,0.0002925546772651339,0.00044678881649663446,0.00044438548709036966,0.6583353546954164 +3,144,0.0004,0.00033683384454327476,0.00046871645706671633,0.0004720144608294323,0.7136091634806786 +3,145,0.0004,0.00032842229042282916,0.0004604363431994857,0.00046229508974069956,0.7104169992526648 +3,146,0.0004,0.0002884701700816024,0.0004313885031636876,0.0004369230407895663,0.660231077675158 +3,147,0.0004,0.0002905943556445721,0.00041649964951779623,0.00041942880593921186,0.6928335668167916 +3,148,0.0004,0.0003047887030304438,0.00043677920004458554,0.0004449589802289267,0.6849815748715382 +3,149,0.0004,0.00026407391338134954,0.0003907160489999364,0.00039268248659745785,0.6724871171859873 +3,150,0.0004,0.0002904444761662052,0.0004050880137146982,0.0004069468051499881,0.713716074166392 +3,151,0.0004,0.000272863937845639,0.00040856404566477257,0.00041005507243320585,0.6654324167397929 +3,152,0.0004,0.0003190613483921113,0.0004502780623228349,0.0004522655644541675,0.705473450708505 +3,153,0.0004,0.0002921835436002744,0.00041902744114970535,0.0004189186152706533,0.6974708999539245 +3,154,0.0004,0.00030422451395457293,0.0004229389754438895,0.0004229010253393775,0.7193752100989426 +3,155,0.0004,0.00026554251517340265,0.0003961618505876744,0.00039684422575433784,0.6691353884982162 +3,156,0.0004,0.00029669540986997187,0.0004301142991910618,0.00043136210660214727,0.6878105548191306 +3,157,0.0004,0.00029786102497743365,0.00044592844952919024,0.00044617301656479626,0.6675908535902603 +3,158,0.0004,0.00028312797991938537,0.000405979874364774,0.0004064269134092317,0.6966270455478019 +3,159,0.0004,0.0002822952296374105,0.0004059284272443388,0.0004072878479948552,0.6931098755516428 +3,160,0.0004,0.0002877890285037027,0.0004184595011759004,0.00041744505183499714,0.6894057726607252 +3,161,0.0004,0.0002732218701315103,0.0003983276198387178,0.00040475353275342313,0.6750327002036515 +3,162,0.0004,0.00030286985895153787,0.000437411322230491,0.0004389251708262523,0.6900261800465947 +3,163,0.0004,0.00030567131248356955,0.00043035633694536534,0.00043043324321004686,0.7101480132063247 +3,164,0.0004,0.0002794507440990522,0.00040302212503744346,0.00040300763164873986,0.6934130327899611 +3,165,0.0004,0.0003104449567880884,0.00045496557187981796,0.0004549530207067695,0.6823670635394665 +3,166,0.0004,0.00030386760350461345,0.00045470448691866365,0.0004547006588682008,0.6682805436459512 +3,167,0.0004,0.0002945311895171457,0.0004373826202745171,0.0004373758129880157,0.6734052976203693 +3,168,0.0004,0.0003196963577838658,0.00045413524216471996,0.00045411115803359434,0.7040046299858046 +3,169,0.0004,0.0003265132254277696,0.0004565334807867147,0.0004579624326556255,0.7129694537047281 +3,170,0.0004,0.00029821398737834724,0.00043814342396934585,0.00043918479114889993,0.6790171093999511 +3,171,0.0004,0.0002998296314147365,0.00045794525742074105,0.0004525228426484214,0.6625734728880486 +3,172,0.0004,0.00025969020261474185,0.00039634557848293553,0.0003951714618941531,0.657158291162989 +3,173,0.0004,0.00029022488759236663,0.0004228594175144466,0.00041764915256194997,0.694901176770178 +3,174,0.0004,0.0002882222348010699,0.00044178585253378433,0.00044414908171797805,0.6489312860587715 +3,175,0.0004,0.0003181211205136025,0.00045555851879351054,0.00045300359910502584,0.7022485497733281 +3,176,0.0004,0.0002596018079270767,0.0003762939718149085,0.00037071545538640575,0.7002724169039227 +3,177,0.0004,0.0002621006696895107,0.0003851727165367456,0.00037871673824107436,0.6920757474486616 +3,178,0.0004,0.00029321362546347204,0.00046658706616344687,0.0004474032007785493,0.6553677420126542 +3,179,0.0004,0.00029407998458564255,0.0004156522829073802,0.00042483964607374533,0.6922140796026249 +3,180,0.0004,0.00025645821062624804,0.0003851389224464153,0.0003821746407105693,0.6710497853793247 +3,181,0.0004,0.0003061270329087582,0.0004422455704172765,0.0004424764579098889,0.6918493118363859 +3,182,0.0004,0.000292647263955451,0.0004296043770450803,0.0004295292649003619,0.6813208967806572 +3,183,0.0004,0.00027198345036199433,0.0004179228727213551,0.00041894892757103765,0.6492043121792606 +3,184,0.0004,0.0003687240660910762,0.0005058471290088931,0.0005133609196474798,0.7182550365233793 +3,185,0.0004,0.00031118357174215355,0.00045494372765579854,0.0004609758166519185,0.6750540060914462 +3,186,0.0004,0.0002721526775436874,0.0003695267991601774,0.00037286026339255547,0.7299052869497094 +3,187,0.0004,0.00029516597266447984,0.00039786361390604816,0.00040393622998275845,0.7307241855405707 +3,188,0.0004,0.0002949013023639824,0.00042712702535028065,0.00043541355144157627,0.6772901334550039 +3,189,0.0004,0.0003076928441845696,0.00043315105917934724,0.0004335951198904275,0.7096317049470615 +3,190,0.0004,0.0002687958419929087,0.0004130286373119342,0.0004179335469318924,0.643154501394243 +3,191,0.0004,0.00028293340174921183,0.00038985046682736985,0.0003829311717581804,0.7388622880977765 +3,192,0.0004,0.0002848589819119119,0.0004354364949851555,0.00042336148209191004,0.6728504929271534 +3,193,0.0004,0.00031378704730246473,0.00048094204410237197,0.00047310969137219245,0.6632437530340304 +3,194,0.0004,0.0002941238520388556,0.0004127117570772148,0.0004163198626413318,0.7064852735413429 +3,195,0.0004,0.0002836835773146039,0.00041243523860369356,0.0004111325576756681,0.6900051382902022 +3,196,0.0004,0.0003170837618337019,0.0004509368250416781,0.00044896250489600957,0.7062588932836297 +3,197,0.0004,0.00030124034302244257,0.00044299192922862075,0.00044223832453490905,0.6811719525648291 +3,198,0.0004,0.00028754394674313053,0.00042701680839511214,0.0004262618694153297,0.6745711201837786 +3,199,0.0004,0.0002918159886011269,0.000428656895661614,0.00043546200750920784,0.6701296176680958 +3,200,0.0004,0.00029610007981750204,0.0004382650470861034,0.0004327424767897678,0.6842408492322595 +3,201,0.0004,0.0002745448373310182,0.0003845544148360925,0.0003938421622575078,0.6970935660045233 +3,202,0.0004,0.00028320236583821403,0.00039019120580863393,0.0003956403614870294,0.7158075702230863 +3,203,0.0004,0.00026991945786401203,0.0004023573454851142,0.0004015866593662987,0.6721325312198948 +3,204,0.0004,0.00032375308795399427,0.00045432996497367216,0.0004544822278586662,0.7123558812836004 +3,205,0.0004,0.0003056655502074164,0.000460656604421403,0.0004603763456998489,0.6639471229625269 +3,206,0.0004,0.0002970564975616343,0.000438266124871071,0.00043860994159521663,0.6772680447717282 +3,207,0.0004,0.00026972401618631156,0.00040763516351011403,0.00040691722751982066,0.6628473752027948 +3,208,0.0004,0.0002498049761377409,0.00037086372860059563,0.0003716332477897199,0.6721814520725747 +3,209,0.0004,0.0002883432768050246,0.0004178923158789312,0.00041078074329348516,0.7019396150199176 +3,210,0.0004,0.00027006545755920265,0.00040105808939535064,0.00040509218643305385,0.6666765408071728 +3,211,0.0004,0.00029501482578518634,0.00041131858401268113,0.00040967426280725465,0.7201204775804679 +3,212,0.0004,0.0002758691491897071,0.0004204769767367992,0.00041043578191241053,0.6721371803995863 +3,213,0.0004,0.00029045915346695254,0.00044547203690746377,0.000434930629352254,0.6678286923584479 +3,214,0.0004,0.0002874645773091861,0.0004258228793386776,0.00041495621595672176,0.6927588170872646 +3,215,0.0004,0.00026797858652990834,0.00038812995466626214,0.00038469717313310397,0.6965961936954204 +3,216,0.0004,0.0002969189208464193,0.00043967314624074474,0.0004378623619977914,0.6781101702637711 +3,217,0.0004,0.00027141516554040766,0.0003962864360915659,0.0004009143640614724,0.6769903746795948 +3,218,0.0004,0.0003151639628415376,0.00043284104710183854,0.0004349929128021616,0.7245266613915542 +3,219,0.0004,0.0002997820644333925,0.0004156228094496211,0.00041601905537222883,0.7205969547841157 +3,220,0.0004,0.00029374840815765414,0.00044049387708702256,0.0004373811889499618,0.6716073200652902 +3,221,0.0004,0.0002951942608215039,0.0003954569111223383,0.00039843761879073346,0.7408794925474775 +3,222,0.0004,0.0002878842943750531,0.00043679391939645246,0.0004359724484131776,0.6603268060238083 +3,223,0.0004,0.00030589190707823536,0.00047102211100494463,0.0004694272917346536,0.6516278718007356 +3,224,0.0004,0.0003231006980528367,0.0004665355301485456,0.0004663933971895788,0.6927643058409407 +3,225,0.0004,0.00028161785701028187,0.00042381172851112134,0.0004220183448701295,0.6673118845033763 +3,226,0.0004,0.0003387781391291091,0.0004697592116949279,0.00047171626242900475,0.7181820219312379 +3,227,0.0004,0.0002728815122881229,0.0004273207329917727,0.0004251403759377846,0.6418621418541922 +3,228,0.0004,0.00030963393416686314,0.0004386044414823031,0.00043578479367468743,0.7105202812514939 +3,229,0.0004,0.0003111546533066847,0.0004419782432044019,0.0004445689441015862,0.6999019104572998 +3,230,0.0004,0.00030359310351194007,0.00044367441473280736,0.00044265313727340206,0.6858487559400887 +3,231,0.0004,0.0003116204351355695,0.00045585324804270827,0.0004534526644981529,0.6872171221674205 +3,232,0.0004,0.0003345262402817163,0.0004898462017755188,0.0004956760575119384,0.6748888416375836 +3,233,0.0004,0.0003000463697807556,0.0004315002704975128,0.0004308914406358248,0.6963386632558916 +3,234,0.0004,0.0003026542207345739,0.0004444981834244215,0.0004429326417039574,0.6832962672840417 +3,235,0.0004,0.0002477956653928561,0.0003810536376628602,0.00038384421239180243,0.6455631149126795 +3,236,0.0004,0.00032267468294002724,0.0004629708299140027,0.0004556002735439559,0.7082407576932587 +3,237,0.0004,0.0002592122686001961,0.00039165421469809455,0.0003946304796919716,0.6568480691165162 +3,238,0.0004,0.00026473118063260955,0.0003892001227001789,0.00037509572866994175,0.7057696486476247 +3,239,0.0004,0.0003020596052388012,0.00045155174570645797,0.0004522179728247981,0.6679513495493634 +3,240,0.0004,0.00032001646743360203,0.00046613568290301377,0.0004647182239840581,0.6886247427313718 +3,241,0.0004,0.00029306179091256483,0.0004205978993240542,0.0004243415213568151,0.6906271862708873 +3,242,0.0004,0.0002650273626354609,0.0003773452702206503,0.0003800704117214616,0.6973112204001002 +3,243,0.0004,0.00031400049515673624,0.0004646631004430626,0.00046185476676684656,0.6798684732753877 +3,244,0.0004,0.0003443541788730658,0.00046501813797309013,0.00046586605811594777,0.7391699242174897 +3,245,0.0004,0.00025672713372327605,0.00038879153598040935,0.00039073098769748353,0.657043187785358 +3,246,0.0004,0.000257971596856453,0.00039922510653904653,0.0004007886076304716,0.643660004164349 +3,247,0.0004,0.00032327551704685453,0.000455090100953747,0.0004509426718453983,0.7168882814392129 +3,248,0.0004,0.00025141833629168986,0.00038189989473792725,0.0003831092849844167,0.6562574861685133 +3,249,0.0004,0.00032792182297670166,0.00046985771753218635,0.00046743573655169874,0.7015334886369632 +3,250,0.0004,0.0002789422666991925,0.00039979421227445564,0.00039809306508476237,0.7006961214956101 +3,251,0.0004,0.00030079726449783607,0.00045513158815114216,0.0004597001398663918,0.6543336371080078 +3,252,0.0004,0.00029425724280055025,0.00043706102987392965,0.0004364013324139202,0.6742812657626159 +3,253,0.0004,0.00031338537252603737,0.00045820736761852695,0.0004574129911012527,0.6851256492989867 +3,254,0.0004,0.0002799258838295116,0.0004262382347699192,0.0004221296840925353,0.6631276936405849 +3,255,0.0004,0.00029457406543410006,0.00044350522024047746,0.00044187538726853613,0.6666451083755017 +3,256,0.0004,0.0002837143415443952,0.00041954044126790463,0.0004198674294034144,0.6757236253060215 +3,257,0.0004,0.0002847066547842016,0.0003989556534033848,0.0003969061315580447,0.7173148312589503 +3,258,0.0004,0.00031207436488721394,0.00045413424765933583,0.0004522961854315487,0.6899778838272865 +3,259,0.0004,0.0003089073164843256,0.00045379578179389915,0.0004532148489734662,0.681591340583836 +3,260,0.0004,0.0002660332159113447,0.00041984985472539086,0.00041456129008046624,0.6417222791344259 +3,261,0.0004,0.000326653755188877,0.0004594613431734435,0.00045862882723647077,0.7122399112091858 +3,262,0.0004,0.0002969362702759674,0.00043957376633965267,0.00043806989394886884,0.6778285254878199 +3,263,0.0004,0.0002958606578043011,0.0004225887558942248,0.00042572196250445396,0.694962167476163 +3,264,0.0004,0.0002678524988717571,0.0003907387984921844,0.00039237717982600756,0.6826403589284458 +3,265,0.0004,0.0003234583396945218,0.000480330354617132,0.0004842823724389399,0.66791268504266 +3,266,0.0004,0.0003060162181967738,0.0004689649012828354,0.0004680089113333339,0.6538683576023135 +3,267,0.0004,0.00028403812713905966,0.0004103412413847611,0.0004105888001807131,0.6917824524537579 +3,268,0.0004,0.00031253886678783086,0.00044288013021467264,0.0004434326373118482,0.704817012754149 +3,269,0.0004,0.00029949781970736874,0.0004536307771635605,0.00045503012873078334,0.658193382804692 +3,270,0.0004,0.0002922435953721373,0.00042024402758575053,0.0004184988868030299,0.6983139133406686 +3,271,0.0004,0.00027094407315510184,0.00041173632559550184,0.00041581527369626204,0.6515972122587701 +3,272,0.0004,0.00027676342473728237,0.000421340374483354,0.0004248172620098581,0.6514881797125747 +3,273,0.0004,0.00030349562893036735,0.00045761932506346013,0.00045587563914766357,0.6657421517363894 +3,274,0.0004,0.0003342146456746383,0.00047856056270984785,0.00047906289294280324,0.6976425237647058 +3,275,0.0004,0.00032959605627028095,0.0004989634478935517,0.0004991724072546064,0.6602850067034417 +3,276,0.0004,0.0003085946246393456,0.0004575834432268458,0.0004582633595431239,0.6734001709126517 +3,277,0.0004,0.00033760243400498993,0.0004510951684035436,0.00045317832953733393,0.7449659703491568 +3,278,0.0004,0.0002775501015561402,0.0004177731323826397,0.0004165687500671245,0.6662768186797898 +3,279,0.0004,0.0002878371108538356,0.00042178484820784313,0.0004234910798771065,0.6796769153611534 +3,280,0.0004,0.0002781889187996148,0.00039527149456109937,0.00039235149700700563,0.7090298391155306 +3,281,0.0004,0.00030573995132695506,0.0004519965828665037,0.000453765656328832,0.6737838068233912 +3,282,0.0004,0.0002851066649807029,0.00041769604112680997,0.0004161562056566256,0.6850953106198472 +3,283,0.0004,0.0003101216050372759,0.0004397526326634536,0.0004382959323643811,0.7075621335665365 +3,284,0.0004,0.00027951756390928153,0.0004233715117145701,0.0004247804313899016,0.6580283441840457 +3,285,0.0004,0.0002899762491064952,0.00043210981790785084,0.0004344496042002629,0.6674565848443688 +3,286,0.0004,0.0002629335079686371,0.0004041393298332028,0.00040450769949175816,0.6500086606484838 +3,287,0.0004,0.000314875721811034,0.00046019953953925486,0.000458751008447982,0.6863760864009913 +3,288,0.0004,0.0003131640685187388,0.0004627095545037396,0.00046346091165434957,0.6757076177166316 +3,289,0.0004,0.00029487448870186346,0.00040573122041129636,0.0004135298513453541,0.7130669956293019 +3,290,0.0004,0.0002826233701360257,0.0004230143968389119,0.00042290323492129365,0.6682932330574974 +3,291,0.0004,0.0003317499528387155,0.0004968291824398381,0.0004924409555850436,0.673684731288405 +3,292,0.0004,0.000284348309913296,0.0004044215296226762,0.0004075328913150051,0.6977309463189002 +3,293,0.0004,0.00026878350888106286,0.00039569189754996083,0.00039380243964010894,0.6825338845709049 +3,294,0.0004,0.0003159600107863327,0.00045308246098908696,0.00046264175793799017,0.6829474541912884 +3,295,0.0004,0.00027621556080474033,0.0004037887432024515,0.00040085681514173384,0.6890629031892018 +3,296,0.0004,0.0003278554505047027,0.00045038590695824535,0.000453550880370072,0.722863662478598 +3,297,0.0004,0.000253891131300965,0.00039555370087139926,0.0003922655686213755,0.6472429690764602 +3,298,0.0004,0.00032161156482285263,0.00042866136114822796,0.00042799527128905787,0.7514371919442161 +3,299,0.0004,0.00027912670791599474,0.0004262178390113378,0.00042436858935193336,0.6577459192779982 +3,300,0.0004,0.0003247323508168161,0.0004385856762008802,0.0004382634182190675,0.7409524439352076 +3,301,0.0004,0.00032142249491923236,0.0004610729635727418,0.0004599211428500778,0.6988643595017497 +3,302,0.0004,0.0002760924352158563,0.0004219765624590329,0.000422862951433938,0.6529123307672628 +3,303,0.0004,0.0002757622915944168,0.00038363748931812984,0.0003847579572935496,0.716716279330969 +3,304,0.0004,0.00026310214163149183,0.0003685998897053197,0.00037071674509944286,0.7097120513423694 +3,305,0.0004,0.00034674434070921395,0.0004898954548706089,0.0004957221498327434,0.6994731642033858 +3,306,0.0004,0.00025984261446344284,0.00039029962698241394,0.0003932356560834942,0.6607809094714225 +3,307,0.0004,0.00030682259217442896,0.0004492501681590576,0.0004437923929633302,0.6913651451429479 +3,308,0.0004,0.0002535682774808991,0.00039236621481528227,0.00039184138297792295,0.6471196981641564 +3,309,0.0004,0.00028051115737499834,0.0003931493066615892,0.0003921845749397195,0.7152529071754394 +3,310,0.0004,0.00025033805625080877,0.00037457862358264996,0.00037422636320655865,0.6689482111997324 +3,311,0.0004,0.0003200749090207102,0.000456655134894934,0.000460968880876305,0.6943525307223464 +3,312,0.0004,0.0002795663324707552,0.00041258808102991013,0.00041336900598911683,0.6763117902412733 +3,313,0.0004,0.0003466134219753219,0.0005141052798749936,0.0005129290538414794,0.6757531463258517 +3,314,0.0004,0.00030795499728307653,0.0004508425905443194,0.00045025504379649626,0.6839567963224512 +3,315,0.0004,0.0002936767661867077,0.00044651598574749603,0.00044692920748536997,0.6570990690876275 +3,316,0.0004,0.00030663615355757773,0.00044600674939218794,0.0004461673714968789,0.6872670955942433 +3,317,0.0004,0.00029479703211323255,0.0004367237714422097,0.0004362638366014328,0.6757310768862943 +3,318,0.0004,0.00028172250790145585,0.0004127708320956947,0.00041242487239590903,0.6830880646573011 +3,319,0.0004,0.0002533578771623979,0.00039524077370697955,0.0003941285582443662,0.6428305482124232 +3,320,0.0004,0.0003195664429190842,0.00042406797436321064,0.00042599844436098,0.7501587086742784 +3,321,0.0004,0.00027728817855736604,0.0004375682387929668,0.0004374563713188139,0.6338647616936436 +3,322,0.0004,0.00027362267359741635,0.0003824312314084903,0.00038522970064413354,0.7102844696031959 +3,323,0.0004,0.0003077330319265615,0.00047926749906801127,0.0004794294378166415,0.6418734596857494 +3,324,0.0004,0.00027008110216811265,0.00042027865732455015,0.00041868851091664906,0.645064517239355 +3,325,0.0004,0.0003146904630683945,0.00046941855529004066,0.0004664788661575827,0.6746081889207987 +3,326,0.0004,0.00030036257655080556,0.000428099464065499,0.00042771414180676755,0.7022507492551022 +3,327,0.0004,0.00029996051776453523,0.00043806817278847993,0.0004378869170522256,0.6850182229325653 +3,328,0.0004,0.00028544529499432145,0.0004271522592515658,0.000421672667838066,0.6769357294552949 +3,329,0.0004,0.0003145814848316648,0.00043128537020270855,0.0004324319091647824,0.7274705639536662 +3,330,0.0004,0.00028771279689810515,0.00039218998611611507,0.00039230230520495053,0.733395631585176 +3,331,0.0004,0.0003056597927139988,0.00043065483367975147,0.00043125245533810974,0.7087722955092649 +3,332,0.0004,0.00031530561997296873,0.000467117749399798,0.00046547372770275764,0.6773865015520633 +3,333,0.0004,0.00027318002749292236,0.00038329750056338664,0.0003855888774069148,0.7084748640314992 +3,334,0.0004,0.00035342713514042366,0.0005032210443927345,0.000502392724611229,0.7034877653013771 +3,335,0.0004,0.0003173234374771717,0.00046828389711621536,0.00046696159820365155,0.6795493220382126 +3,336,0.0004,0.0003254377717703179,0.0004929799756168592,0.0004921589875412762,0.6612452073589821 +3,337,0.0004,0.0002840163810929973,0.0004378616423544058,0.00043688545674044747,0.6500934666308443 +3,338,0.0004,0.0003084261990702152,0.0004592715902411889,0.0004607245083058295,0.6694373611778464 +3,339,0.0004,0.0003073532224771425,0.0004634313830207529,0.00045889402487636535,0.6697695019235633 +3,340,0.0004,0.000310565599667829,0.00045344780531761164,0.0004545879577486211,0.6831804370840069 +3,341,0.0004,0.00033905084446112546,0.0004674696929461621,0.0004673659216209064,0.7254505062868899 +3,342,0.0004,0.00030403619392721564,0.00048210110119110305,0.0004812873837754171,0.631714447908919 +3,343,0.0004,0.0003155948279362132,0.0004160991505522232,0.0004179832088633045,0.755041880257501 +3,344,0.0004,0.0002808807844809015,0.00044849802707437267,0.00044439226079183994,0.6320559768084493 +3,345,0.0004,0.0002621688770901988,0.00042375440284191194,0.00042003812513805456,0.6241549549913628 +3,346,0.0004,0.0003183507781542479,0.00043637017015994456,0.0004291200440532205,0.741868814020641 +3,347,0.0004,0.0002510455322684178,0.0003815875695846347,0.00038247213760537454,0.656376001243365 +3,348,0.0004,0.0003441336596713911,0.00047783019348328023,0.00048136048095819527,0.7149188046894902 +3,349,0.0004,0.00027753275738174585,0.0004476709956749107,0.00044641857975199887,0.6216872907393886 +3,350,0.0004,0.00031564750130706304,0.00040748554070505204,0.0004100268663514599,0.7698215097849263 +3,351,0.0004,0.0002595002004152523,0.00043353444515939607,0.0004322661713441547,0.6003250256857311 +3,352,0.0004,0.00029612282519038657,0.00038521375769123676,0.00039070334904918436,0.7579224132862722 +3,353,0.0004,0.000417530546857648,0.0005499602045049698,0.000549506189036495,0.7598286519570356 +3,354,0.0004,0.0002983349271937032,0.000432701702672506,0.00042913630934162127,0.695198520142486 +3,355,0.0004,0.000288253843712328,0.00045412577847196006,0.00045581540398456063,0.6323916243122221 +3,356,0.0004,0.00025590967999810954,0.00040030758988890083,0.00039799730218293447,0.6429935042134629 +3,357,0.0004,0.0002918969573395214,0.00044081514215440934,0.00043550576715480245,0.6702482018700003 +3,358,0.0004,0.0002804081622915469,0.0004317415048958061,0.00043351794390502035,0.6468201979500569 +3,359,0.0004,0.00031785648421941726,0.00043900392999617023,0.0004395991485399286,0.72305982683346 +3,360,0.0004,0.00029237798330098217,0.0004276241126117112,0.0004236621404777901,0.6901206300172334 +3,361,0.0004,0.00030532156262881463,0.0004677288435897156,0.0004676661380790791,0.6528622403215066 +3,362,0.0004,0.00028380202339114253,0.00046679203495120957,0.0004535484246495208,0.6257369841168566 +3,363,0.0004,0.00031610663777128346,0.00044785631584714515,0.0004446824468064908,0.7108592660704713 +3,364,0.0004,0.0003050490229058632,0.00044575617526285615,0.0004460468111533105,0.6838946390337829 +3,365,0.0004,0.000304558678663178,0.0004468374828063782,0.0004463632144356708,0.6823113303550925 +3,366,0.0004,0.00027695595748916066,0.00040839326874787715,0.0004106377693286233,0.6744531998164046 +3,367,0.0004,0.000300019950801626,0.00046374812236606936,0.00046344761164258887,0.6473654049877845 +3,368,0.0004,0.00029129354877776057,0.00042102740838679186,0.00042116175054008703,0.6916429338709253 +3,369,0.0004,0.00026622122071118194,0.00040697174394049396,0.00040700908083330875,0.654091599543975 +3,370,0.0004,0.0003234782374207952,0.0004589740798544763,0.00045875860330112854,0.7051164492461072 +3,371,0.0004,0.00027199717607996295,0.00042250585308871777,0.0004226369596280055,0.6435716751307508 +3,372,0.0004,0.0002678814994140518,0.0003693284707372565,0.00036949250771322353,0.7249984609213357 +3,373,0.0004,0.0002781754590739674,0.000406051171400143,0.0004073176433708095,0.6829447817970531 +3,374,0.0004,0.00031786195371895316,0.0004554306628707195,0.0004552905415844873,0.6981518935419575 +3,375,0.0004,0.000333940757266157,0.00046452694770655304,0.000462917604858229,0.7213827120885328 +3,376,0.0004,0.00027899814775283723,0.00042988541771683456,0.0004320391972510315,0.6457704521442496 +3,377,0.0004,0.00032193520819671115,0.0004566094217683898,0.0004524845160271611,0.7114833696925587 +3,378,0.0004,0.00029795138273825127,0.0004307275338054414,0.0004387749745065609,0.679052817616416 +3,379,0.0004,0.00031016069509189146,0.0004619501267397996,0.0004546992401744956,0.6821227477153119 +3,380,0.0004,0.0002638261353267247,0.0004025497840305553,0.0004044480921507749,0.6523114843335013 +3,381,0.0004,0.0003019057169174639,0.00045593510347083556,0.0004540218700274908,0.6649585336036427 +3,382,0.0004,0.00031259717976986817,0.0004349076880971522,0.0004315900743804506,0.7242918647251162 +3,383,0.0004,0.0002799620491894485,0.00044249124937988864,0.0004307716219894952,0.6499082922325734 +3,384,0.0004,0.00028755255892249493,0.00042570695642199264,0.00041070737377658283,0.7001397522483201 +3,385,0.0004,0.00028133387987451823,0.0004470568059612375,0.0004264407396870421,0.659725616461937 +3,386,0.0004,0.0002774995615086081,0.00041723170395188637,0.0004050484525151332,0.6851021397205321 +3,387,0.0004,0.0002954908132348465,0.000428161357543525,0.0004300685367068771,0.6870784259120191 +3,388,0.0004,0.00028068292520882636,0.00040371616196172017,0.0004093261126616608,0.6857195681547739 +3,389,0.0004,0.00030944441360891624,0.00045582908740593816,0.0004542312750413177,0.6812485854937412 +3,390,0.0004,0.00027171391034631274,0.0004158759127552243,0.0004151356399004202,0.6545183892461981 +3,391,0.0004,0.0003155808628881464,0.0004438538705725453,0.0004534109963163259,0.6960150182771015 +3,392,0.0004,0.00034487967189103367,0.0004821041086417205,0.00048422598000019094,0.7122287653605403 +3,393,0.0004,0.0002623775317629523,0.00038086581930982683,0.00038645121172357157,0.678940895521453 +3,394,0.0004,0.0003171950752773745,0.00046473233164891355,0.0004545305372821701,0.6978520677048845 +3,395,0.0004,0.00026848678605331485,0.00039740438975622303,0.00039906779292050667,0.672784902255434 +3,396,0.0004,0.000264757460417196,0.0003915292302190352,0.00039605905941253965,0.6684797484746375 +3,397,0.0004,0.00032135515620837756,0.0004654929596683183,0.0004653193222287045,0.6906121041120907 +3,398,0.0004,0.0002847462842753738,0.0004156647199044808,0.00041551237460343,0.6852895405272564 +3,399,0.0004,0.0003283140884405248,0.00044751851925206213,0.0004460059709093672,0.7361203881892456 +3,400,0.0004,0.00025964389881306276,0.00038460912231820857,0.0003837802977375794,0.6765430647265838 +3,401,0.0004,0.00029945685159258066,0.00040788317336390233,0.00040862631588026735,0.7328379009254149 +3,402,0.0004,0.0002946019164442876,0.000449108463499512,0.00045015976801190824,0.6544385735432812 +3,403,0.0004,0.0002694059500821597,0.00038096331509659227,0.0003816299075318296,0.7059351082427681 +3,404,0.0004,0.0002934437497172925,0.00045566439810948287,0.00045461858197302647,0.6454724055575519 +3,405,0.0004,0.00029764589868347,0.0004156264038654684,0.00041532087902420174,0.7166649058982789 +3,406,0.0004,0.00028902440547318755,0.00041224744228751464,0.0004143539459930469,0.6975302353655817 +3,407,0.0004,0.00032421489475589,0.0004798404159844479,0.0004800226385486077,0.6754158423364851 +3,408,0.0004,0.000306658438255712,0.00043759811932026865,0.0004374244048794712,0.7010547075904676 +3,409,0.0004,0.00030937085644641997,0.00047436413036495783,0.00047424588151043435,0.6523427371917265 +3,410,0.0004,0.0002998596634022616,0.0004241995252223073,0.00042422073324840313,0.7068482040142963 +3,411,0.0004,0.0002815448948827786,0.0004210041053789898,0.00042062278161052836,0.6693524630424617 +3,412,0.0004,0.00030163229060220894,0.0004411950705636584,0.00043884059187417876,0.6873390843677715 +3,413,0.0004,0.0002668890295309509,0.0003665195892699731,0.00036854812379522235,0.7241633108387315 +3,414,0.0004,0.0002612319609230221,0.00040032327593072695,0.0004012231088197049,0.6510890204990916 +3,415,0.0004,0.00032169572239852185,0.0004606128957208455,0.0004600561616279979,0.699253154789057 +3,416,0.0004,0.00029077067043483377,0.00042824134700506514,0.00042793551578768324,0.6794730974820452 +3,417,0.0004,0.00029947932012213183,0.00043001288257415245,0.0004295802091814353,0.6971441275024969 +3,418,0.0004,0.00028859856554067743,0.00042106915655974346,0.00042165745511523394,0.6844384275425817 +3,419,0.0004,0.00029203652102673984,0.000421790444918141,0.0004223925722301426,0.6913864973639318 +3,420,0.0004,0.0002889521247109139,0.0004146007125546537,0.00041433645342889313,0.6973852344384726 +3,421,0.0004,0.0003165562109902371,0.0004974577562386364,0.0004955101585086496,0.6388490842306542 +3,422,0.0004,0.00029118808631112443,0.0004368250958351316,0.00043684430415859613,0.666571782072289 +3,423,0.0004,0.00031161191466007034,0.0004551161797793051,0.00045417257486402517,0.6861090517263485 +3,424,0.0004,0.0002699211689677277,0.00038835966800510686,0.00038795879505501975,0.6957470030533729 +3,425,0.0004,0.00027180232908818837,0.0004022954612253072,0.00040283730835133976,0.6747198520429306 +3,426,0.0004,0.00027369040781696736,0.0004062594739086122,0.0004063906402858371,0.6734663170993941 +3,427,0.0004,0.0002950655495947485,0.00042668888231800603,0.0004266246286820514,0.6916280255696411 +3,428,0.0004,0.000296913796650396,0.00046184204914846943,0.00045901756253041443,0.6468462666517744 +3,429,0.0004,0.00029272353758665303,0.0004043509928075265,0.0004069054010325463,0.7193896587360352 +3,430,0.0004,0.0002903028788618455,0.000425419663702499,0.00042453617367136244,0.6838118795657017 +3,431,0.0004,0.0003464123583042042,0.0004888412889426501,0.0004834112271078803,0.7165997371982783 +3,432,0.0004,0.00027747244844953214,0.00041407148029150396,0.00040727934046086016,0.681282895752964 +3,433,0.0004,0.00027106181719117634,0.00039884002378684,0.0003926383973706187,0.6903599316989776 +3,434,0.0004,0.00035074190366257555,0.0005029020327346109,0.0005050037423209573,0.694533276229981 +3,435,0.0004,0.00026521444489543646,0.0003844246771114387,0.00038265968156480095,0.693081758211112 +3,436,0.0004,0.0003026591836460804,0.00044686251920325425,0.00044688247838748474,0.6772679580953482 +3,437,0.0004,0.00029067096796420367,0.0004310373134941872,0.00043102938270119705,0.6743646248490345 +3,438,0.0004,0.0002845089340630361,0.00040948177171493746,0.0004094971168914493,0.6947764033670952 +3,439,0.0004,0.00031007237153855334,0.0004727443393541825,0.0004684526665430289,0.6619075814569457 +3,440,0.0004,0.00028588230247757304,0.00039837818410748155,0.00039988735029405556,0.7149070913779859 +3,441,0.0004,0.00025541367851674904,0.0003570468748426496,0.0003670721889259776,0.6958132111944193 +3,442,0.0004,0.00030420081888005043,0.0004390867119013658,0.00044556166816542845,0.6827356135292737 +3,443,0.0004,0.0002729578819781894,0.0003984447931436782,0.00040134707069804977,0.680104333397632 +3,444,0.0004,0.0003036544850073202,0.00043893458441582485,0.000433224989590945,0.7009163651755951 +3,445,0.0004,0.0002777621795796027,0.0004047880539957329,0.0004014676009492105,0.691866987330672 +3,446,0.0004,0.0003041000219330336,0.00042333116646941837,0.0004142017232886929,0.7341833817554643 +3,447,0.0004,0.0002908505495041581,0.0004451992606493047,0.00044258685593039776,0.6571603869544149 +3,448,0.0004,0.0002969992242420314,0.0004356279533139095,0.0004345739559285143,0.6834261929191325 +3,449,0.0004,0.0002724818100811094,0.0004088406266681308,0.0004087869181970673,0.666561961627529 +3,450,0.0004,0.0003054405039792722,0.0004262934065828199,0.000426295064678299,0.7165002114433837 +3,451,0.0004,0.00032344258638869586,0.000448622510568963,0.000448385665505028,0.7213490779737447 +3,452,0.0004,0.00028262819272866776,0.0004678734738419488,0.00047235091384163254,0.5983436983958624 +3,453,0.0004,0.00029351564001366907,0.00041319397231345513,0.00041184709503513445,0.7126810982814615 +3,454,0.0004,0.0002978373876942896,0.0004154037955609057,0.0004142980138482011,0.718896489335856 +3,455,0.0004,0.0002820141624247217,0.0004000720315299961,0.00040067370308987955,0.7038499413610381 +3,456,0.0004,0.0002646019690881923,0.00040371021849568844,0.00040203209402879617,0.6581613085577187 +3,457,0.0004,0.00029176692896933115,0.00041977582722787566,0.00042351782750044695,0.6889129808095817 +3,458,0.0004,0.00027672126719027637,0.0003877153660194612,0.0003946655984980095,0.7011537571133706 +3,459,0.0004,0.00027509514467809513,0.0003859242526148192,0.00039335663152231484,0.6993530110664709 +3,460,0.0004,0.0002658480367689206,0.0003697743001998689,0.0003804690362096041,0.6987376408272613 +3,461,0.0004,0.0002559114853417129,0.0003816315852799277,0.00039632593870688983,0.6457096554837833 +3,462,0.0004,0.0002605901359596718,0.00038015073083803825,0.00038797948057107094,0.6716595825534549 +3,463,0.0004,0.0003027796168866525,0.000434930889864505,0.0004303104180525001,0.7036306912042083 +3,464,0.0004,0.0003056157598959498,0.0004491387496955259,0.0004430601548538311,0.6897838962674826 +3,465,0.0004,0.0002656636383755866,0.00042451926607254946,0.00042635383148315525,0.6231060184247053 +3,466,0.0004,0.0002815817725600024,0.0003918374798425057,0.00039223996712098633,0.7178813893617031 +3,467,0.0004,0.00027592027045505394,0.00040975062676030773,0.0004104598545987601,0.6722223071602857 +3,468,0.0004,0.0002782030992163522,0.0004103728259462951,0.00041003283901847975,0.6784898006762182 +3,469,0.0004,0.00029204553453099136,0.00042511771590945187,0.0004255224478730428,0.6863222751015121 +3,470,0.0004,0.000284321797022864,0.00041128432266646987,0.0004119008893333834,0.6902674997449212 +3,471,0.0004,0.00029681734570430476,0.00041012688949596004,0.0004118899836489875,0.7206228786501698 +3,472,0.0004,0.00029578640078599047,0.0004415785498684822,0.0004392612178640551,0.6733724461819709 +3,473,0.0004,0.00030072174492255,0.00043515517998712737,0.00043530942877580424,0.6908229526942538 +3,474,0.0004,0.0003056109980019729,0.00046344536886947624,0.0004659997076933696,0.6558180036521968 +3,475,0.0004,0.00027976954920378154,0.0004205589721366728,0.000422148952242089,0.6627270960117001 +3,476,0.0004,0.00027300783897335343,0.0003854319753735827,0.0003872985644086279,0.7049027909262026 +3,477,0.0004,0.0002798049193840721,0.0004316971888775116,0.0004314415971424046,0.6485348683050554 +3,478,0.0004,0.0002611672183797372,0.00039577248111659846,0.00039650862153061637,0.6586671870376245 +3,479,0.0004,0.00026330199047944897,0.0004082697215356946,0.00040668190118474206,0.6474396566761392 +3,480,0.0004,0.00027184424996877553,0.00039854062452456993,0.0003995242616701366,0.6804198794645947 +3,481,0.0004,0.00024443882144285263,0.0003887733023706334,0.000383209391653466,0.6378727316367476 +3,482,0.0004,0.0003069736865943238,0.0004151156347000374,0.0004238410450015251,0.7242660667591059 +3,483,0.0004,0.0002874193662637036,0.0004280758878009895,0.0004261662704906439,0.6744301137037395 +3,484,0.0004,0.0002982569104610146,0.0004361492049112822,0.00043905072562548105,0.6793222127946865 +3,485,0.0004,0.00026026453310447475,0.0003633460110396587,0.00036749940180596933,0.7082039639397509 +3,486,0.0004,0.00030474236124880923,0.00042635936848701983,0.00043447019270196106,0.7014114348181698 +3,487,0.0004,0.0002842837000278567,0.00040822993468343853,0.00041279739358539416,0.6886761022366963 +3,488,0.0004,0.0002963948225633775,0.0004076074942961351,0.00041196535590614053,0.719465407258435 +3,489,0.0004,0.00027427752020316973,0.0004393450038336803,0.0004391208044601798,0.6246060706241069 +3,490,0.0004,0.00032217639680967645,0.00044014715049140216,0.00044191096591305733,0.7290527315700562 +3,491,0.0004,0.0002799844545898769,0.0003956218575400596,0.0004016232579942664,0.6971320734464884 +3,492,0.0004,0.00025843979658030184,0.0003552944618222639,0.00036031792267206166,0.7172549027363183 +3,493,0.0004,0.00028248583081933885,0.0004192960329047472,0.0004160609371207528,0.6789530225409106 +3,494,0.0004,0.00028415434685445613,0.00041790654338931917,0.00041828447097273536,0.679332766510899 +3,495,0.0004,0.00026901583960808504,0.00039191518532651266,0.0003937496283154026,0.6832154756793754 +3,496,0.0004,0.0002632538329443505,0.00037870004797894427,0.0003780966756012215,0.696260638964211 +3,497,0.0004,0.0002746436343254281,0.0003956303029407178,0.0003965325604749725,0.6926130706554234 +3,498,0.0004,0.00034771907534432444,0.0004994128952436174,0.0004916201493435443,0.7072921559635634 +3,499,0.0004,0.0002628248187623652,0.0003866421343316849,0.0003876246475255165,0.6780394911421725 diff --git a/docs/tutorials/data/multisignal_he/linked_pyrenew_fit_artifacts.npz b/docs/tutorials/data/multisignal_he/linked_pyrenew_fit_artifacts.npz new file mode 100644 index 00000000..8a1dfab7 Binary files /dev/null and b/docs/tutorials/data/multisignal_he/linked_pyrenew_fit_artifacts.npz differ diff --git a/docs/tutorials/data/multisignal_he/metadata.json b/docs/tutorials/data/multisignal_he/metadata.json new file mode 100644 index 00000000..4e238b3f --- /dev/null +++ b/docs/tutorials/data/multisignal_he/metadata.json @@ -0,0 +1,6 @@ +{ + "generated_at": "2026-05-15T17:42:23.770328+00:00", + "pyrenew_sha": "7b76267c40aa3170d7a1a704aca8cca91f051ec6", + "pyrenew_multisignal_sha": "362cd6038060599859cc6104fd97321146952499", + "cfa_stf_sha": "cf46267785c213c2a6e6b36ed3595cd798660a03" +} diff --git a/docs/tutorials/data/multisignal_he/pyrenew_fit_artifacts.npz b/docs/tutorials/data/multisignal_he/pyrenew_fit_artifacts.npz new file mode 100644 index 00000000..600ef638 Binary files /dev/null and b/docs/tutorials/data/multisignal_he/pyrenew_fit_artifacts.npz differ diff --git a/docs/tutorials/data/multisignal_he/timings.json b/docs/tutorials/data/multisignal_he/timings.json new file mode 100644 index 00000000..003dc685 --- /dev/null +++ b/docs/tutorials/data/multisignal_he/timings.json @@ -0,0 +1,23 @@ +{ + "pyrenew-H-E": { + "elapsed_seconds": 65.24473595619202, + "num_warmup": 500, + "num_samples": 500, + "num_chains": 4, + "rng_key": 42 + }, + "custom-H-E": { + "elapsed_seconds": 67.23963212966919, + "num_warmup": 500, + "num_samples": 500, + "num_chains": 4, + "rng_key": 42 + }, + "linked-pyrenew-H-E": { + "elapsed_seconds": 70.60192012786865, + "num_warmup": 500, + "num_samples": 500, + "num_chains": 4, + "rng_key": 42 + } +} diff --git a/docs/tutorials/multisignal_H_E_model.qmd b/docs/tutorials/multisignal_H_E_model.qmd new file mode 100644 index 00000000..5bd7175d --- /dev/null +++ b/docs/tutorials/multisignal_H_E_model.qmd @@ -0,0 +1,1972 @@ +--- +title: Multi-signal Model for Weekly Hospital and Daily ED Data +format: + gfm: + code-fold: true +engine: jupyter +jupyter: + jupytext: + text_representation: + extension: .qmd + format_name: quarto + format_version: "1.0" + jupytext_version: 1.19.1 + kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +```{python} +#| label: setup +#| output: false + +from datetime import date +import json +from pathlib import Path +import warnings +from collections.abc import Mapping + +import arviz as az +import numpyro + +numpyro.set_host_device_count(4) +numpyro.enable_x64() + +import jax +import jax.numpy as jnp +import numpy as np +import numpyro.distributions as dist +import pandas as pd +import plotnine as p9 + +warnings.filterwarnings("ignore") + +ARTIFACT_DIR = Path("data/multisignal_he") + +from _tutorial_theme import theme_tutorial +from pyrenew.ascertainment import AscertainmentModel, JointAscertainment +from pyrenew.datasets import ( + load_synthetic_daily_infections, + load_example_infection_admission_interval, + load_synthetic_daily_ed_visits, + load_synthetic_true_parameters, + load_synthetic_weekly_hospital_admissions, +) +from pyrenew.deterministic import DeterministicPMF, DeterministicVariable +from pyrenew.latent import DifferencedAR1, PopulationInfections, WeeklyTemporalProcess +from pyrenew.metaclass import RandomVariable +from pyrenew.model import PyrenewBuilder +from pyrenew.observation import NegativeBinomialNoise, PopulationCounts +from pyrenew.randomvariable import DistributionalVariable, TransformedVariable +from pyrenew.time import MMWR_WEEK +import pyrenew.transformation as transformation +``` + +```{python} +#| label: helper functions +#| output: false + +def plot_delay_distribution(delay_pmf, title): + """Plot a discrete delay probability distribution over days.""" + delay_pmf = np.asarray(delay_pmf) + + days = np.arange(len(delay_pmf)) + mean_delay = float(np.sum(days * delay_pmf)) + mode_delay = int(np.argmax(delay_pmf)) + + delay_df = pd.DataFrame( + { + "days": days, + "probability": delay_pmf, + } + ) + + max_probability = delay_df["probability"].max() + + return ( + p9.ggplot(delay_df, p9.aes(x="days", y="probability")) + + p9.geom_col(fill="steelblue", alpha=0.7, color="black") + + p9.geom_vline( + xintercept=mode_delay, + color="purple", + linetype="solid", + size=1, + ) + + p9.geom_vline( + xintercept=mean_delay, + color="red", + linetype="dashed", + size=1, + ) + + p9.labs( + x="Days", + y="Probability", + title=title, + ) + + theme_tutorial + + p9.annotate( + "text", + x=mode_delay + 8, + y=max_probability * 0.95, + label=f"Mode: {mode_delay} days", + color="purple", + size=10, + ) + + p9.annotate( + "text", + x=mean_delay + 8, + y=max_probability * 0.8, + label=f"Mean: {mean_delay:.1f} days", + color="red", + size=10, + ) + ) +``` + +This tutorial builds a small hospital + emergency department model using PyRenew's high-level components and `PyrenewBuilder` class to specify a `MultiSignalModel` object, then fits it to a synthetic dataset. + +We then compare this PyRenew model with a custom H+E model coded directly in NumPyro. +The custom model uses a more specialized H+E ascertainment structure, so the comparison below is a structural comparison rather than a direct benchmark. + +The PyRenew model has the following components: + +- one latent population-level infection process +- a weekly-parameterized $\mathcal{R}(t)$ process +- weekly hospital admissions +- daily ED visits with a day-of-week effect +- joint scalar ascertainment for the two clinical signals + +The renewal equation and delay convolutions run on a daily model axis, while the hospital likelihood is evaluated on weekly totals and the ED likelihood is evaluated on daily counts. + +## Model Structure + +The model has one latent infection process. +Both observations receive the same aggregate infection trajectory, but they map it to data on different reporting grids. + +```mermaid +flowchart TB + + subgraph Latent["Latent Infection Process"] + R["Weekly DifferencedAR1
for log Rt"] + I["Daily renewal equation
(PopulationInfections)"] + end + + subgraph Shared["Shared Daily Axis"] + D["Daily latent infections"] + end + + subgraph Asc["Ascertainment"] + A["JointAscertainment
scalar IHR and IEDR"] + end + + subgraph Obs["Observation Processes"] + H["Hospital admissions
PopulationCounts
weekly MMWR totals"] + E["ED visits
PopulationCounts
daily counts + day-of-week"] + end + + subgraph Data["Observed Data"] + HD["Weekly hospital data"] + ED["Daily ED data"] + end + + R -->|"broadcast to days"| I + I --> D + D --> H + D --> E + A --> H + A --> E + H -->|"delay + IHR + weekly aggregation + noise"| HD + E -->|"delay + IEDR + day-of-week + noise"| ED +``` + +The components are: + +- **Latent infections**: `PopulationInfections` produces a single aggregate infection trajectory. +- **$\mathcal{R}(t)$process**: `WeeklyTemporalProcess` samples weekly values and broadcasts them to the daily renewal equation. +- **Ascertainment**: `JointAscertainment` samples scalar hospital and ED ascertainment rates from one joint prior. +- **Hospital observation**: `PopulationCounts` scores weekly hospital totals. +- **ED observation**: `PopulationCounts` scores daily ED counts and includes a day-of-week effect. + +### Temporal Cadence and Aggregation + +This model has two different temporal questions: + +1. How often should latent transmission parameters vary? +2. On what time grid is each observation likelihood evaluated? + +PyRenew treats these as separate modeling choices. + +The renewal equation always runs on the shared daily model axis. +The latent process therefore produces daily infections, even when the temporal process for $\mathcal{R}(t)$ is parameterized more coarsely. +If `single_rt_process` is a daily process, PyRenew estimates a daily $\mathcal{R}(t)$ trajectory. +If it is wrapped in `WeeklyTemporalProcess`, PyRenew estimates weekly $\mathcal{R}(t)$ values and broadcasts them to the daily axis before computing infections. + +Observation aggregation happens later, inside each count observation process. +For weekly hospital admissions, `PopulationCounts(..., aggregation="weekly", start_dow=MMWR_WEEK)` first computes daily predicted admissions from daily infections using ascertainment and the delay distribution. +It then sums those daily predictions to the weekly grid, so the negative-binomial observation model is evaluated against weekly observed admissions rather than daily counts. +For daily ED visits, no aggregation is applied. +Each observed daily count is modeled with a negative-binomial distribution whose mean is the corresponding daily prediction. + +The end-to-end flow for the weekly hospital signal is: + +1. Sample or construct daily $\mathcal{R}(t)$, possibly by broadcasting weekly values. +2. Run the daily renewal equation to produce daily infections. +3. Convert daily infections to daily predicted hospital admissions using hospital delay and joint ascertainment component's `for_signal("hospital")`. +4. Sum daily predicted admissions to MMWR weeks. +5. Evaluate the negative-binomial observation model on the weekly hospital observations. + +The daily ED signal shares steps 1--3, but remains on the daily grid for the likelihood. + +1. Sample or construct daily $\mathcal{R}(t)$, possibly by broadcasting weekly values. +2. Run the daily renewal equation to produce daily infections. +3. Convert daily infections to daily predicted ED visits using delay and joint ascertainment component's `for_signal("ed_visits")`. +4. Evaluate the negative-binomial observation model on the daily ED visits. + +This separation means that mixed-cadence models are natural: weekly hospital admissions and daily ED visits can share the same latent daily infection trajectory, regardless of whether $\mathcal{R}(t)$ is parameterized daily, weekly, or with another stepwise cadence. + +The cadence of the temporal process affects both model flexibility and computational cost. +A daily $\mathcal{R}(t)$ process estimates one latent $\mathcal{R}(t)$ state per day, while a `WeeklyTemporalProcess` estimates one latent $\mathcal{R}(t)$ state per week and broadcasts the weekly trajectory to the daily renewal equation. +The daily infections and expected observations are still computed on the daily axis, but they are deterministic functions of the sampled parameters. + +A coarser $\mathcal{R}(t)$ cadence reduces the number of latent dimensions sampled by HMC/NUTS. +It also regularizes the latent process: the model cannot use day-to-day changes in $\mathcal{R}(t)$ to explain short-term noise or reporting artifacts. +This can improve sampling and forecast stability when the data do not support daily transmission changes, but it is a modeling assumption rather than a universal improvement. + +### Custom NumPyro Extensions + +The model implemented here uses the same high-level H+E structure as the custom NumPyro model, but omits several model-specific components. +We keep these components out of the tutorial model so the example can focus on the mixed daily/weekly observation cadence. + +- **Infection feedback**: the latent infection process includes a state-dependent damping term, so higher infection levels can reduce future transmission. + This can help regularize epidemic trajectories, but it is a substantive modeling assumption. + +- **Inferred delay distributions**: some delay distributions are estimated rather than fixed, allowing the model to learn timing relationships between latent infections and observed signals. + PyRenew's observation API accepts delay distributions as `RandomVariable` objects, so fixed delays can be replaced by inferred PMFs or custom parametric delay models, provided the sampled value is a valid fixed-length PMF. + In this tutorial we keep the delays fixed. + +- **Time-varying ED ascertainment with a hospital-to-ED link**: the custom H+E model uses a time-varying ED ascertainment rate and defines scalar hospital ascertainment as a multiplier of the first ED ascertainment value. + In this tutorial model, `JointAscertainment` instead samples two scalar rates from one joint prior. + +These alternatives are good candidates for model comparison and sensitivity analysis. +One advantage of specifying the model with `PyrenewBuilder` is that closely related models can be built from the same components while changing only the feature under study: fixed versus inferred delays, scalar versus time-varying ascertainment, or renewal dynamics with versus without feedback. +In practice, each candidate model can be defined as a named Python object, factory function, or separate model specification file. +This makes it easier to compare posterior predictive checks, held-out forecast performance, and the stability of inferred latent infections across model variants. + +## Specifying Model Components for `PyrenewBuilder` + +The `PyrenewBuilder` class assembles the model components. +It checks component compatibility and coherence, computes initialization requirements, and produces a model ready for inference. + +### Latent Infection Process + +The `PyrenewBuilder` object's `configure_latent` method handles configuration of the latent process. +It requires the following: + +- **Generation interval**: PMF for secondary infection timing. +- **Initial conditions ($I(0)$ and $\log(\mathcal{R}(0))$)**: Infection prevalence at time $0$ as a proportion of the population, and the starting point of the $\log(\mathcal{R}(t))$ trajectory. +- **Temporal dynamics**: How $\mathcal{R}(t)$ evolves over time. + +We use the same seven-day generation interval PMF used to generate the synthetic data; this PMF also matches the default/test-data parameterization used in the H+E pipeline. +For the initial infection level and initial $\mathcal{R}(t)$ value, we specify priors rather than fixing them to the true synthetic-data values. + +Following the custom NumPyro model, we use a weekly differenced AR(1) process for log $\mathcal{R}(t)$ temporal dynamics. +The differenced process allows persistent upward or downward movement. +The weekly wrapper estimates one latent $\mathcal{R}(t)$ state per week and broadcasts the weekly trajectory to the daily renewal equation. + +```python +weekly_rt_process = WeeklyTemporalProcess( + DifferencedAR1( + autoreg_rv=DeterministicVariable("rt_diff_autoreg", 0.5), + innovation_sd_rv=DeterministicVariable("rt_diff_innovation_sd", 0.05), + ), + start_dow=MMWR_WEEK, +) +``` + +`WeeklyTemporalProcess` uses calendar weeks, not arbitrary 7-day blocks starting at index 0. +The `start_dow=MMWR_WEEK` argument says that each $\mathcal{R}(t)$ value applies to an MMWR week, which runs Sunday through Saturday. + +At model runtime, `obs_start_date` is used to align the weekly $\mathcal{R}(t)$ blocks with the daily model axis. +The same calendar anchor is used when daily predicted hospital admissions are aggregated to MMWR weeks. + +### Ascertainment + +`JointAscertainment` defines one shared ascertainment component for the hospital and ED signals. +The component has a `name`, used to identify it in the multisignal model, and a tuple of signal names supplied through `signals`. + +For each signal, the model samples a scalar ascertainment rate. +The rates are modeled jointly: `baseline_rates` gives their prior centers on the probability scale, while `covariance_matrix` describes uncertainty and dependence on the logit scale. +The logit-scale representation keeps sampled rates between 0 and 1 after transformation back to the probability scale. + +We use a common generic baseline rate and a logit-scale standard deviation of $0.3$, matching the prior scale used by custom-H-E. +The prior correlation of $0.5$ says that the two rates may differ, but prior draws that are high for hospital ascertainment also tend to be high for ED ascertainment. + +```python +ascertainment_center = 0.004 +ascertainment_sd = 0.3 +ascertainment_corr = 0.5 +ascertainment_cov = jnp.array( + [ + [ascertainment_sd**2, ascertainment_corr * ascertainment_sd**2], + [ascertainment_corr * ascertainment_sd**2, ascertainment_sd**2], + ] +) + +ascertainment = JointAscertainment( + name="he_ascertainment", + signals=("hospital", "ed_visits"), + baseline_rates=jnp.array([ascertainment_center, ascertainment_center]), + covariance_matrix=ascertainment_cov, +) +``` +The order of `signals` determines how `baseline_rates` and the rows and columns of `covariance_matrix` are interpreted. +Observation processes do not access those values by row or column index. +Instead, the ascertainment object provides signal-specific accessors: `ascertainment.for_signal("hospital")` returns the hospital ascertainment rate, and `ascertainment.for_signal("ed_visits")` returns the ED ascertainment rate. + +### Observation Processes + +Both hospital admissions and ED visits are count observations, so both components are specified as `PopulationCounts` objects. +They share the same daily latent infection trajectory, but the observation model is evaluated at different reporting cadences: weekly totals for hospital admissions and daily counts for ED visits. + +To define a `PopulationCounts` object, you must specify its + +- **Ascertainment rate**: the probability that an infection results in an observed event +- **Delay distribution**: the distribution of times from infection to the corresponding event +- **Noise model**: the count distribution used to model variation around the expected number of events. + +In addition, count data observation processes have optional parameters for: + +- **Day-of-week effects**: recurring multiplicative adjustments for systematic differences among days of the week. +- **Right truncation**: adjustment for recent observations that may be incomplete because not all reports have arrived. + +#### ED Visits + +For ED visits, we include a day-of-week effect. + +ED visits often have systematic day-of-week patterns. +Day-to-day volumes may differ because of care-seeking behavior, clinic availability, staffing, coding, or reporting workflows. +Those patterns are part of the observation process, not necessarily evidence that infections changed from one day to the next. + +The ED observation model includes $7$ multiplicative effects, one for each day of the week. +The day-of-week effect multiplies the expected daily ED visits before the count observation model is applied. +Each day of the week has its own multiplier: a value above 1 increases expected ED visits on that day, and a value below 1 decreases them. + +Following the custom H+E model, we place a symmetric Dirichlet prior with concentration value $5$ on these weights and scale the draw by $7$. +Because the prior is symmetric, it does not assume in advance which days have higher or lower ED volume. +It centers the multipliers near equal day-of-week effects while still allowing per-day variation. + +```python +ed_day_of_week_rv = TransformedVariable( + name="ed_day_of_week_effect", + base_rv=DistributionalVariable( + name="ed_day_of_week_effect_raw", + distribution=dist.Dirichlet(jnp.ones(7) * 5), + ), + transforms=transformation.AffineTransform(loc=0.0, scale=7.0), +) +``` + +This is passed to `PopulationCounts` constructor as `day_of_week_rv`. + +In this tutorial, `ascertainment.for_signal("ed_visits")` connects the ED observation process to the ED component of the joint ascertainment model. +The delay PMF matches the synthetic data-generating process, and the observation model uses negative-binomial noise. + +```python +ed_obs = PopulationCounts( + name="ed_visits", + ascertainment_rate_rv=ascertainment.for_signal("ed_visits"), + delay_distribution_rv=DeterministicPMF("ed_delay", ed_delay_pmf), + noise=NegativeBinomialNoise( + DistributionalVariable("ed_conc", dist.LogNormal(4.0, 1.0)) + ), + day_of_week_rv=ed_day_of_week_rv, +) +``` + +Count observation processes also support an optional `right_truncation_rv` for incomplete recent reports. +The synthetic ED data used here are complete, so the tutorial model omits right truncation. +The custom H+E model applies a right-truncation adjustment to recent ED observations when reports are incomplete; the reporting-delay PMF is supplied as an external input rather than inferred by the model. + +#### Hospital Admissions + +Hospital admissions are also modeled with `PopulationCounts`. +The hospital signal uses the hospital component of the joint ascertainment model, a fixed infection-to-hospital-admission delay PMF, and negative-binomial observation noise. + +The hospital data are reported as weekly MMWR totals. +PyRenew still computes daily predicted hospital admissions from the shared daily infection trajectory, delay distribution, and ascertainment rate. +The argument `aggregation="weekly"` then sums those daily predictions before comparing them with the observed weekly totals. +The argument `start_dow=MMWR_WEEK` aligns the aggregation to MMWR weeks, and `reporting_schedule="regular"` indicates that the data are supplied as one value per week. + +```python +hospital_obs = PopulationCounts( + name="hospital", + ascertainment_rate_rv=ascertainment.for_signal("hospital"), + delay_distribution_rv=DeterministicPMF("hosp_delay", hosp_delay_pmf), + noise=NegativeBinomialNoise( + DistributionalVariable("hosp_conc", dist.LogNormal(5.0, 1.0)) + ), + aggregation="weekly", + reporting_schedule="regular", + start_dow=MMWR_WEEK, +) +``` + +The hospital and ED observation processes therefore share the same latent infections, but differ in reporting cadence and signal-specific observation details. + +### Full model specification via `PyrenewBuilder` + +The full specification of the model requires defining all model `RandomVariable` objects passed in to all components. +In this example we use the synthetic H+E data bundled with PyRenew, which includes the parameters used to generate the data, including the generation interval pmf and hospitalization and ED visits delay pmfs and ascertainment rates. + +```{python} +#| label: load-data + +N_DAYS_FIT = 126 +OBS_START_DATE = date(2023, 11, 5) + +true_params = load_synthetic_true_parameters() +daily_infections = load_synthetic_daily_infections() +weekly_hosp = load_synthetic_weekly_hospital_admissions() +daily_ed = load_synthetic_daily_ed_visits() + +hosp_delay_pmf = jnp.array( + load_example_infection_admission_interval()["probability_mass"].to_numpy() +) +ed_delay_pmf = jnp.array(true_params["ed_visits"]["delay_pmf"]) + +population_size = float(weekly_hosp["pop"][0]) + +true_i0 = float(true_params["i0_per_capita"]) +true_ihr = float(true_params["hospitalizations"]["ihr"]) +true_iedr = float(true_params["ed_visits"]["iedr"]) +true_dow_effects = jnp.array(true_params["ed_visits"]["day_of_week_effects"]) + + +print(f"Weekly hospital rows: {len(weekly_hosp)}") +print(f"Daily ED rows: {len(daily_ed)}") +print(f"Population size: {population_size:,.0f}") +print() +print("Data-generating values (used as reference points):") +print(f" Initial infections per capita (I0): {true_i0:.5f}") +print(f" Hospital ascertainment (IHR): {true_ihr:.5f}") +print(f" ED ascertainment (IEDR): {true_iedr:.5f}") +print(f" Ratio IHR / IEDR: {true_ihr / true_iedr:.3f}") +print(f" ED visits day-of-week effects: {true_dow_effects}") +``` + +First we specify the latent components + +```{python} +#| code-fold: false +#| label: latent-components + +gen_int_pmf = jnp.array( + [0.6326975, 0.2327564, 0.0856263, 0.03150015, 0.01158826, 0.00426308, 0.0015683] +) +gen_int_rv = DeterministicPMF("gen_int", gen_int_pmf) +I0_rv = TransformedVariable( + name="I0", + base_rv=DistributionalVariable( + name="logit_I0", + distribution=dist.Normal( + transformation.SigmoidTransform().inv(true_params["i0_per_capita"]), + 0.25, + ), + ), + transforms=transformation.SigmoidTransform(), +) +log_rt_time_0_rv = DistributionalVariable("log_rt_time_0", dist.Normal(0.0, 0.5)) + +weekly_rt_process = WeeklyTemporalProcess( + DifferencedAR1( + autoreg_rv=DeterministicVariable("rt_diff_autoreg", 0.5), + innovation_sd_rv=DeterministicVariable("rt_diff_innovation_sd", 0.03), + ), + start_dow=MMWR_WEEK, +) +``` + +Next we specify the joint ascertainment + +```{python} +#| code-fold: false +#| label: joint-ascertainment + +ascertainment_center = 0.004 +ascertainment_sd = 0.3 +ascertainment_corr = 0.5 +ascertainment_cov = jnp.array( + [ + [ascertainment_sd**2, ascertainment_corr * ascertainment_sd**2], + [ascertainment_corr * ascertainment_sd**2, ascertainment_sd**2], + ] +) + +ascertainment = JointAscertainment( + name="he_ascertainment", + signals=("hospital", "ed_visits"), + baseline_rates=jnp.array([ascertainment_center, ascertainment_center]), + covariance_matrix=ascertainment_cov, +) +``` + +Next we specify the hospital and ED visit observation processes + +Here we don't try to estimate the day-of-week effect on ED visits, we supply the true day-of-week effects. + +```{python} +#| code-fold: false +#| label: observation-processes + +hospital_obs = PopulationCounts( + name="hospital", + ascertainment_rate_rv=ascertainment.for_signal("hospital"), + delay_distribution_rv=DeterministicPMF("hosp_delay", hosp_delay_pmf), + noise=NegativeBinomialNoise( + DistributionalVariable("hosp_conc", dist.LogNormal(5.0, 1.0)) + ), + aggregation="weekly", + reporting_schedule="regular", + start_dow=MMWR_WEEK, +) + + +ed_day_of_week_rv = DeterministicVariable( + "ed_day_of_week_effect", + jnp.array(true_params["ed_visits"]["day_of_week_effects"]), +) + +ed_obs = PopulationCounts( + name="ed_visits", + ascertainment_rate_rv=ascertainment.for_signal("ed_visits"), + delay_distribution_rv=DeterministicPMF("ed_delay", ed_delay_pmf), + noise=NegativeBinomialNoise( + DistributionalVariable("ed_conc", dist.LogNormal(4.0, 1.0)) + ), + day_of_week_rv=ed_day_of_week_rv, +) +``` + +Finally, we instantiate a `PyrenewBuilder` object. + +```{python} +#| code-fold: false +#| label: build-model + +builder = PyrenewBuilder() +builder.configure_latent( + PopulationInfections, + gen_int_rv=gen_int_rv, + I0_rv=I0_rv, + log_rt_time_0_rv=log_rt_time_0_rv, + single_rt_process=weekly_rt_process, +) +builder.add_ascertainment(ascertainment) +builder.add_observation(hospital_obs) +builder.add_observation(ed_obs) + +model = builder.build() +``` + +The `PyrenewBuilder` computes the initialization period from the generation interval and both observation delay distributions. + +```{python} +#| code-fold: false +#| label: inspect-model + +print(f"Initialization points: {model.latent.n_initialization_points}") +print(f"Observations: {list(model.observations)}") +print(f"Ascertainment models: {list(model.ascertainment_models)}") +``` + +## Fit the Model + +After the model is built, we prepare the observed data for `model.run()`. +Each observation process receives a data dictionary whose keyword matches the name registered with the builder: `hospital={...}` and `ed_visits={...}`. + +The model includes an initialization period before the first observed day. +During that period, PyRenew computes latent infections and predicted observations, but there are no data to condition on. +We mark those unobserved positions with `NaN`. + +We prepare one observed array for each signal. +Daily ED observations are padded with `model.pad_observations()`. +Weekly hospital observations are padded with `model.pad_aggregated_observations()`, which pads on the hospital observation process's weekly reporting cadence. + +```{python} +#| code-fold: false +#| label: align-observed-data + +ed_observed = model.pad_observations( + jnp.array(daily_ed["ed_visits"].to_numpy(), dtype=jnp.float32) +) + +hospital_observed = model.pad_aggregated_observations( + jnp.array(weekly_hosp["weekly_hosp_admits"].to_numpy(), dtype=jnp.float32), + observation_name="hospital", + n_days_post_init=N_DAYS_FIT, + obs_start_date=OBS_START_DATE, +) + +print(f"ED observation array shape: {ed_observed.shape}") +print(f"Hospital observation array shape: {hospital_observed.shape}") +``` + +```{python} +#| label: plot-observed-data + +# Raw observations on a shared calendar axis +ed_dates = pd.date_range( + start=pd.Timestamp(OBS_START_DATE), + periods=len(daily_ed), + freq="D", +) + +ed_plot_df = pd.DataFrame( + { + "date": ed_dates, + "count": daily_ed["ed_visits"].to_numpy(), + "signal": "Daily ED visits", + } +) + +hosp_plot_df = pd.DataFrame( + { + "week_end": pd.to_datetime(weekly_hosp["week_end"]), + "count": weekly_hosp["weekly_hosp_admits"].to_numpy(), + "signal": "Weekly hospital admissions", + } +) +hosp_plot_df["week_start"] = hosp_plot_df["week_end"] - pd.Timedelta(days=6) + +raw_obs_plot = ( + p9.ggplot() + + p9.geom_rect( + hosp_plot_df, + p9.aes( + xmin="week_start", + xmax="week_end", + ymin=0, + ymax="count", + ), + fill="steelblue", + alpha=0.7, + color="black", + ) + + p9.geom_col( + ed_plot_df, + p9.aes(x="date", y="count"), + fill="darkorange", + alpha=0.65, + width=0.9, + ) + + p9.facet_wrap("~signal", ncol=1, scales="free_y") + + p9.labs( + x="Date", + y="Observed count", + title="Observed Hospital Admissions and ED Visits", + ) + + theme_tutorial +) + +raw_obs_plot +``` + +### Check the Mixed-Cadence Structure + +Before fitting, it can be useful to run one seeded model execution and inspect selected site shapes. +This is a quick check that the weekly and daily pieces are aligned as intended. + +```{python} +#| code-fold: false +#| label: trace-model + +with numpyro.handlers.seed(rng_seed=0): + with numpyro.handlers.trace() as trace: + model.sample( + n_days_post_init=N_DAYS_FIT, + population_size=population_size, + obs_start_date=OBS_START_DATE, + hospital={"obs": hospital_observed}, + ed_visits={"obs": ed_observed}, + ) + +for site in [ + "log_rt_single_weekly", + "PopulationInfections::log_rt_single", + "hospital_predicted_daily", + "hospital_predicted", + "ed_visits_predicted", +]: + print(f"{site}: {trace[site]['value'].shape}") +``` + +The expected pattern is: + +- `log_rt_single_weekly` has one value for each calendar week touched by the padded daily model axis, including a leading partial week. +- `PopulationInfections::log_rt_single` is daily, because the renewal equation runs daily. +- `hospital_predicted_daily` is daily before aggregation. +- `hospital_predicted` contains complete weekly hospital reporting periods only, so it can be one shorter than `log_rt_single_weekly`. +- `ed_visits_predicted` is daily, matching the ED data. + +### Load Precomputed Fits + +The PyRenew and custom NumPyro fits are run offline and saved as small, portable artifacts. +This keeps the documentation build independent of the local pipeline software needed by the custom NumPyro model. +To regenerate the artifacts, run `uv run python docs_scripts/generate_multisignal_he_artifacts.py` from the repository root on a machine that has access to both model implementations. + +```{python} +#| code-fold: false +#| label: load-fit-artifacts + +required_artifacts = [ + ARTIFACT_DIR / "pyrenew_fit_artifacts.npz", + ARTIFACT_DIR / "linked_pyrenew_fit_artifacts.npz", + ARTIFACT_DIR / "custom_he_scalar_draws.csv", + ARTIFACT_DIR / "custom_he_fit_artifacts.npz", + ARTIFACT_DIR / "timings.json", +] +missing_artifacts = [path for path in required_artifacts if not path.exists()] +if missing_artifacts: + missing_text = "\n".join(f" - {path}" for path in missing_artifacts) + raise FileNotFoundError( + "The multisignal H+E tutorial uses precomputed fit artifacts.\n" + "Run `uv run python docs_scripts/generate_multisignal_he_artifacts.py` " + "locally and commit the generated files.\n" + f"Missing artifacts:\n{missing_text}" + ) + +pyrenew_artifacts = np.load(ARTIFACT_DIR / "pyrenew_fit_artifacts.npz") +linked_pyrenew_artifacts = np.load(ARTIFACT_DIR / "linked_pyrenew_fit_artifacts.npz") +custom_scalar_draws = pd.read_csv(ARTIFACT_DIR / "custom_he_scalar_draws.csv") +custom_artifacts = np.load(ARTIFACT_DIR / "custom_he_fit_artifacts.npz") +custom_latent_infections = custom_artifacts["latent_infections_trimmed"] +if np.nanmax(custom_latent_infections) < 1.0: + custom_latent_infections = population_size * custom_latent_infections +if "rt_trimmed" in custom_artifacts: + custom_rt = custom_artifacts["rt_trimmed"] +else: + custom_rt = None + +with open(ARTIFACT_DIR / "timings.json") as file: + timings = json.load(file) + +pyrenew_elapsed = timings["pyrenew-H-E"]["elapsed_seconds"] +linked_pyrenew_elapsed = timings["linked-pyrenew-H-E"]["elapsed_seconds"] +custom_elapsed = timings["custom-H-E"]["elapsed_seconds"] + +print(f"pyrenew-H-E elapsed time: {pyrenew_elapsed:.1f} seconds") +print(f"linked-pyrenew-H-E elapsed time: {linked_pyrenew_elapsed:.1f} seconds") +print(f"custom-H-E elapsed time: {custom_elapsed:.1f} seconds") +``` + +The saved artifacts include posterior draws for the PyRenew model and reduced scalar posterior draws for the custom NumPyro model. +We keep the custom artifact intentionally narrow: the tutorial only needs scalar summaries for the comparison plots, and avoiding pickled model objects keeps the docs build independent of the custom model's Python package layout. + +```{python} +#| label: build-artifact-idata + +n_init = int(pyrenew_artifacts["n_init"]) + +if {"chain", "draw"}.issubset(custom_scalar_draws.columns): + custom_scalar_draws = custom_scalar_draws.sort_values(["chain", "draw"]) + n_custom_chains = custom_scalar_draws["chain"].nunique() + n_custom_draws = custom_scalar_draws["draw"].nunique() + + def custom_draw_array(column): + return ( + custom_scalar_draws[column] + .to_numpy() + .reshape( + n_custom_chains, + n_custom_draws, + ) + ) + +else: + + def custom_draw_array(column): + return custom_scalar_draws[column].to_numpy()[None, :] + + +idata = az.from_dict( + { + "posterior": { + "PopulationInfections::rt_single": pyrenew_artifacts["rt_single_full"], + } + }, + dims={"PopulationInfections::rt_single": ["time", "dummy"]}, +) + +idata_trimmed = az.from_dict( + { + "posterior": { + "I0": pyrenew_artifacts["I0"], + "log_rt_time_0": pyrenew_artifacts["log_rt_time_0"], + "he_ascertainment_hospital": pyrenew_artifacts["he_ascertainment_hospital"], + "he_ascertainment_ed_visits": pyrenew_artifacts[ + "he_ascertainment_ed_visits" + ], + "PopulationInfections::rt_single": pyrenew_artifacts["rt_single_trimmed"], + "latent_infections": pyrenew_artifacts["latent_infections_trimmed"], + } + }, + dims={ + "PopulationInfections::rt_single": ["time", "dummy"], + "latent_infections": ["time"], + }, +) + +linked_idata_trimmed = az.from_dict( + { + "posterior": { + "I0": linked_pyrenew_artifacts["I0"], + "log_rt_time_0": linked_pyrenew_artifacts["log_rt_time_0"], + "he_ascertainment_hospital": linked_pyrenew_artifacts[ + "he_ascertainment_hospital" + ], + "he_ascertainment_ed_visits": linked_pyrenew_artifacts[ + "he_ascertainment_ed_visits" + ], + "ihr_rel_iedr": linked_pyrenew_artifacts["ihr_rel_iedr"], + "PopulationInfections::rt_single": linked_pyrenew_artifacts[ + "rt_single_trimmed" + ], + "latent_infections": linked_pyrenew_artifacts["latent_infections_trimmed"], + } + }, + dims={ + "PopulationInfections::rt_single": ["time", "dummy"], + "latent_infections": ["time"], + }, +) + +custom_scalar_idata = az.from_dict( + { + "posterior": { + "I0": custom_draw_array("I0"), + "IHR": custom_draw_array("IHR"), + "IEDR_first_day": custom_draw_array("IEDR_first_day"), + "IEDR_mean": custom_draw_array("IEDR_mean"), + "latent_infections": custom_latent_infections, + **({"rt": custom_rt} if custom_rt is not None else {}), + } + }, + dims={ + "latent_infections": ["time"], + **({"rt": ["time"]} if custom_rt is not None else {}), + }, + sample_dims=["chain", "draw"], +) +``` + +We use ArviZ for convergence checks and posterior summaries. +The first `n_init` daily time points are initialization points, so the saved daily posterior quantities are trimmed before summarizing or plotting. + +```{python} +#| label: arviz-checks-recovered-params + +pyrenew_parameter_summary = az.summary( + idata_trimmed, + var_names=[ + "I0", + "log_rt_time_0", + "he_ascertainment_hospital", + "he_ascertainment_ed_visits", + ], +) +pyrenew_parameter_summary +``` + +```{python} +pyrenew_ratio = ( + idata_trimmed.posterior["he_ascertainment_hospital"] + / idata_trimmed.posterior["he_ascertainment_ed_visits"] +) + +az.summary( + az.from_dict( + {"posterior": {"IHR_over_IEDR": pyrenew_ratio.values}}, + sample_dims=["chain", "draw"], + ) +) +``` + +We compare the model estimates to the data-generating parameters. + +```{python} +#| label: print-data-generating-params + +print("Data-generating values (used as reference points):") +print(f" Initial infections per capita (I0): {true_i0:.5f}") +print(f" Hospital ascertainment (IHR): {true_ihr:.5f}") +print(f" ED ascertainment (IEDR): {true_iedr:.5f}") +print(f" IHR/IEDR: {true_ihr / true_iedr:.5f}") +``` + +The pyrenew-H-E model learns the structure of the synthetic data rather than recovering every data-generating parameter. +Its posterior $\mathcal{R}(t)$ trajectory follows the true falling-rising-falling pattern, and the fitted hospital and ED signals match the observations well. +However, with a diffuse ascertainment prior, the absolute IHR and IEDR can shift away from their data-generating values because H+E observations weakly identify the absolute infection scale. + +Next we inspect the estimates for $\mathcal{R}(t)$. + +```{python} +#| label: arviz-checks-recovered-rt + +rt_days = list(range(0, 126, 7)) +pyrenew_rt_summary = az.summary( + idata_trimmed, + var_names=[ + "PopulationInfections::rt_single", + ], + coords={ + "time": rt_days, + "dummy": [0], + }, +) +pyrenew_rt_summary +``` + +The synthetic data-generating program creates a true $\mathcal{R}(t)$ trajectory which has a falling, rising, falling cadence: + +```python +def build_true_rt() -> np.ndarray: + """ + Build a piecewise-linear true R(t) trajectory. + + Phases: decline from 1.2 to 0.8 (63 d), rise from 0.8 to 1.1 (42 d), + decline from 1.1 to 0.85 (21 d). Total 126 days = 18 weeks. +``` + +```{python} +#| label: plot-recovered-rt + +rt = idata.posterior["PopulationInfections::rt_single"].squeeze() +rt_q = rt.quantile([0.05, 0.5, 0.95], dim=["chain", "draw"]) +rt_q05 = rt_q.sel(quantile=0.05).values +rt_q50 = rt_q.sel(quantile=0.5).values +rt_q95 = rt_q.sel(quantile=0.95).values + +n_init = model.latent.n_initialization_points +days = np.arange(len(rt_q50)) - n_init + +rt_df = pd.DataFrame( + { + "day": days, + "q05": rt_q05, + "median": rt_q50, + "q95": rt_q95, + "period": np.where(days < 0, "Initialization", "Observed period"), + } +) + +rt_plot = ( + p9.ggplot(rt_df, p9.aes(x="day")) + + p9.geom_ribbon( + p9.aes(ymin="q05", ymax="q95"), + fill="steelblue", + alpha=0.25, + ) + + p9.geom_line( + p9.aes(y="median"), + color="steelblue", + size=1, + ) + + p9.geom_hline(yintercept=1.0, linetype="dashed", alpha=0.6) + + p9.geom_vline(xintercept=0, linetype="dotted", alpha=0.8) + + p9.annotate( + "text", + x=-n_init / 2, + y=max(rt_q95) * 0.95, + label="Initialization period", + size=9, + color="gray", + ) + + p9.annotate( + "text", + x=20, + y=max(rt_q95) * 0.95, + label="Observed period", + size=9, + color="gray", + ) + + p9.labs( + x="Day relative to first observation", + y="Rt", + title="Posterior Rt Over Initialization and Observation Periods", + ) + + theme_tutorial +) + +rt_plot +``` + +Rt is useful as a companion to latent infections because it focuses on epidemic shape rather than absolute infection scale. +The plot below compares Rt across all three models against the synthetic data-generating Rt trajectory. +The dashed black line is the synthetic truth, and the gray horizontal line marks Rt = 1. + +```{python} +#| label: all-model-rt-data + +true_rt = daily_infections["true_rt"].to_numpy() + +pyrenew_rt = idata_trimmed.posterior["PopulationInfections::rt_single"].squeeze() +pyrenew_rt_q = pyrenew_rt.quantile([0.05, 0.5, 0.95], dim=["chain", "draw"]) + +linked_rt = linked_idata_trimmed.posterior["PopulationInfections::rt_single"].squeeze() +linked_rt_q = linked_rt.quantile([0.05, 0.5, 0.95], dim=["chain", "draw"]) + +rt_comparison_parts = [ + pd.DataFrame( + { + "model": "pyrenew-H-E", + "day": np.arange(N_DAYS_FIT), + "q05": pyrenew_rt_q.sel(quantile=0.05).values[:N_DAYS_FIT], + "median": pyrenew_rt_q.sel(quantile=0.5).values[:N_DAYS_FIT], + "q95": pyrenew_rt_q.sel(quantile=0.95).values[:N_DAYS_FIT], + "truth": true_rt[:N_DAYS_FIT], + } + ), + pd.DataFrame( + { + "model": "linked-pyrenew-H-E", + "day": np.arange(N_DAYS_FIT), + "q05": linked_rt_q.sel(quantile=0.05).values[:N_DAYS_FIT], + "median": linked_rt_q.sel(quantile=0.5).values[:N_DAYS_FIT], + "q95": linked_rt_q.sel(quantile=0.95).values[:N_DAYS_FIT], + "truth": true_rt[:N_DAYS_FIT], + } + ), +] + +if "rt" in custom_scalar_idata.posterior: + custom_rt = custom_scalar_idata.posterior["rt"].squeeze() + custom_rt_q = custom_rt.quantile([0.05, 0.5, 0.95], dim=["chain", "draw"]) + rt_comparison_parts.append( + pd.DataFrame( + { + "model": "custom-H-E", + "day": np.arange(N_DAYS_FIT), + "q05": custom_rt_q.sel(quantile=0.05).values[:N_DAYS_FIT], + "median": custom_rt_q.sel(quantile=0.5).values[:N_DAYS_FIT], + "q95": custom_rt_q.sel(quantile=0.95).values[:N_DAYS_FIT], + "truth": true_rt[:N_DAYS_FIT], + } + ) + ) + +rt_comparison_df = pd.concat(rt_comparison_parts, ignore_index=True) +``` + +```{python} +#| label: all-model-rt +#| fig-cap: Posterior Rt under the two PyRenew parameterizations and custom-H-E. +#| The dashed black line is the synthetic data-generating Rt trajectory. + +( + p9.ggplot(rt_comparison_df, p9.aes(x="day")) + + p9.geom_ribbon( + p9.aes(ymin="q05", ymax="q95"), + fill="steelblue", + alpha=0.25, + ) + + p9.geom_line(p9.aes(y="median"), color="darkblue", size=1) + + p9.geom_line(p9.aes(y="truth"), color="black", linetype="dashed", size=0.7) + + p9.geom_hline(yintercept=1.0, color="gray", linetype="dotted", alpha=0.8) + + p9.facet_wrap("~model", ncol=1) + + p9.labs( + x="Day", + y="Rt", + title="Posterior Rt vs Synthetic Truth", + ) + + theme_tutorial +) +``` + +For this synthetic example, the sampler should mix well for the core scalar parameters. +The latent infection interval should be interpreted as a scale diagnostic, not just a coverage check: uncertainty in the absolute infection-to-observation rates propagates directly into uncertainty in latent infections. +The direction of the scale trade-off is simple. +For hospital and ED count observations, the expected count is approximately latent infections times an ascertainment rate, after delay convolution and calendar aggregation. +If the posterior puts IHR or IEDR below the data-generating value, the model can still match the observed counts by putting latent infections above the data-generating trajectory. + +```{python} +#| label: synthetic-recovery-check + +rhat = pyrenew_parameter_summary["r_hat"].astype(float) +ess = pyrenew_parameter_summary["ess_bulk"].astype(float) +print(f"Max R-hat: {rhat.max():.3f}") +print(f"Min bulk ESS: {ess.min():.0f}") + +latent_inf = idata_trimmed.posterior["latent_infections"] +inf_q05 = latent_inf.quantile(0.05, dim=["chain", "draw"]).values +inf_q50 = latent_inf.quantile(0.50, dim=["chain", "draw"]).values +inf_q95 = latent_inf.quantile(0.95, dim=["chain", "draw"]).values + +true_infections = daily_infections["true_infections"].to_numpy() +n_compare = min(len(true_infections), len(inf_q05)) +inf_covered = (true_infections[:n_compare] >= inf_q05[:n_compare]) & ( + true_infections[:n_compare] <= inf_q95[:n_compare] +) +print(f"90% interval coverage for true infections: {np.mean(inf_covered):.1%}") +``` + +We visualize posterior latent infections alongside the observed hospital and ED signals. +The panels use separate y-axes because latent infections, weekly hospital admissions, and daily ED visits are on different scales. + +```{python} +#| label: fig-fit-synthetic-data +#| fig-cap: Posterior latent infections and observed synthetic H+E data. + +infections_df = pd.DataFrame( + { + "day": np.arange(n_compare), + "median": inf_q50[:n_compare], + "q05": inf_q05[:n_compare], + "q95": inf_q95[:n_compare], + "raw": np.nan, + "signal": "Latent Infections", + } +) + +week_end_dates = pd.to_datetime(weekly_hosp["week_end"].to_numpy()) +hosp_df = pd.DataFrame( + { + "day": (week_end_dates - pd.Timestamp(OBS_START_DATE)).days, + "median": weekly_hosp["weekly_hosp_admits"].to_numpy(), + "raw": weekly_hosp["weekly_hosp_admits"].to_numpy(), + "q05": np.nan, + "q95": np.nan, + "signal": "Weekly Hospital Admissions", + } +) + +ed_raw = np.array(daily_ed["ed_visits"].to_numpy(), dtype=float) +ed_ma = pd.Series(ed_raw).rolling(window=7, center=True).mean().values +ed_df = pd.DataFrame( + { + "day": np.arange(len(ed_raw)), + "median": ed_ma, + "raw": ed_raw, + "q05": np.nan, + "q95": np.nan, + "signal": "Daily ED Visits (7-day MA)", + } +) + +plot_df = pd.concat([infections_df, hosp_df, ed_df], ignore_index=True) +plot_df["signal"] = pd.Categorical( + plot_df["signal"], + categories=[ + "Weekly Hospital Admissions", + "Daily ED Visits (7-day MA)", + "Latent Infections", + ], + ordered=True, +) + +( + p9.ggplot(plot_df, p9.aes(x="day")) + + p9.geom_ribbon( + p9.aes(ymin="q05", ymax="q95"), + fill="steelblue", + alpha=0.3, + ) + + p9.geom_point( + p9.aes(y="raw"), + color="gray", + alpha=0.35, + size=1, + ) + + p9.geom_line( + p9.aes(y="median"), + color="darkblue", + size=1, + ) + + p9.facet_wrap("~signal", ncol=1, scales="free_y") + + p9.scale_y_log10() + + p9.labs( + x="Day", + y="Count", + title="Posterior Latent Infections vs Observed H+E Data", + ) + + theme_tutorial +) +``` + +The relative width of the posterior interval is another simple way to inspect uncertainty in the inferred latent infections. +This scales the 90% interval width by the posterior median, so the diagnostic is not dominated by periods with larger infection counts. +The interval width check shows how the ascertainment uncertainty propagates into latent infections. + +```{python} +#| label: fig-latent-infection-interval-width +#| fig-cap: |- +#| +#| Relative posterior interval width for latent infections over the +#| +#| synthetic H+E fit. + +inf_relative_width = (inf_q95[:n_compare] - inf_q05[:n_compare]) / np.maximum( + inf_q50[:n_compare], 1.0 +) +period_edges = list(range(-1, n_compare, 14)) +if period_edges[-1] != n_compare - 1: + period_edges.append(n_compare - 1) +period_labels = [ + f"Days {start + 1}-{end}" + for start, end in zip(period_edges[:-1], period_edges[1:], strict=True) +] + +ci_width_df = pd.DataFrame( + { + "day": np.arange(n_compare), + "relative_width": inf_relative_width, + "period": pd.cut( + np.arange(n_compare), + bins=period_edges, + labels=period_labels, + ), + } +) + +period_summary_df = ( + ci_width_df.groupby("period", observed=True) + .agg( + start=("day", "min"), + end=("day", "max"), + mean_relative_width=("relative_width", "mean"), + ) + .reset_index() +) + +print("\nMean relative 90% interval width by time period:") +for row in period_summary_df.itertuples(index=False): + print(f" {row.period}: {row.mean_relative_width:.2f}") + +( + p9.ggplot(ci_width_df, p9.aes(x="day", y="relative_width")) + + p9.geom_line(color="gray", alpha=0.6, size=0.7) + + p9.geom_segment( + data=period_summary_df, + mapping=p9.aes( + x="start", + xend="end", + y="mean_relative_width", + yend="mean_relative_width", + color="period", + ), + size=1.6, + ) + + p9.labs( + x="Day", + y="Relative 90% interval width", + color="Period", + title="Posterior Uncertainty in Latent Infections", + ) + + theme_tutorial +) +``` + +### Linked PyRenew Ascertainment + +The joint ascertainment fit above leaves substantial uncertainty in the absolute IHR and IEDR levels. +That is expected for H+E-only data: counts constrain the relative scale of the two clinical signals more strongly than they constrain the absolute infection-to-observation rates. + +A linked ascertainment component makes that relative scale explicit. +Instead of sampling hospital and ED ascertainment as two rates from one joint prior, it samples ED ascertainment as a base rate and samples the multiplier $IHR / IEDR$ directly. +Hospital ascertainment is then computed as `IEDR * (IHR / IEDR)`. + +```{python} +#| label: linked-ascertainment-class +#| code-fold: false + +class RatioLinkedAscertainment(AscertainmentModel): + """Two ascertainment rates expressed as a base rate and a ratio.""" + + def __init__( + self, + name: str, + base_signal: str, + linked_signal: str, + base_rate_rv: RandomVariable, + ratio_rv: RandomVariable, + ) -> None: + super().__init__(name=name, signals=(base_signal, linked_signal)) + self.base_signal = base_signal + self.linked_signal = linked_signal + self.base_rate_rv = base_rate_rv + self.ratio_rv = ratio_rv + + def sample(self, **kwargs: object) -> Mapping[str, object]: + base_rate = self.base_rate_rv() + ratio = self.ratio_rv() + linked_rate = base_rate * ratio + numpyro.deterministic(f"{self.name}_{self.base_signal}", base_rate) + numpyro.deterministic(f"{self.name}_{self.linked_signal}", linked_rate) + return {self.base_signal: base_rate, self.linked_signal: linked_rate} +``` + +This component follows the same registration pattern as `JointAscertainment`. +The observation processes still call `ascertainment.for_signal(...)`, and `PyrenewBuilder` still receives the component through `builder.add_ascertainment(...)`. + +To isolate the effect of the ascertainment parameterization, the linked model keeps the same latent process, observation processes, and initial-infection prior as `pyrenew-H-E`. +The ED base-rate prior has the same logit-scale center and $0.3$ standard deviation used by the marginal rates in `JointAscertainment` and custom-H-E. +The ratio prior places its mode at equal hospital and ED ascertainment rates while still allowing roughly two-fold variation in either direction. + +```{python} +#| label: linked-ascertainment-model +#| code-fold: false + +linked_iedr_rv = TransformedVariable( + name="iedr", + base_rv=DistributionalVariable( + name="logit_iedr", + distribution=dist.Normal( + transformation.SigmoidTransform().inv(ascertainment_center), + ascertainment_sd, + ), + ), + transforms=transformation.SigmoidTransform(), +) + +linked_ratio_rv = DistributionalVariable( + "ihr_rel_iedr", + dist.LogNormal(0.0, jnp.log(jnp.sqrt(2.0))), +) + +linked_ascertainment = RatioLinkedAscertainment( + name="he_ascertainment", + base_signal="ed_visits", + linked_signal="hospital", + base_rate_rv=linked_iedr_rv, + ratio_rv=linked_ratio_rv, +) + +linked_hospital_obs = PopulationCounts( + name="hospital", + ascertainment_rate_rv=linked_ascertainment.for_signal("hospital"), + delay_distribution_rv=DeterministicPMF("hosp_delay", hosp_delay_pmf), + noise=NegativeBinomialNoise( + DistributionalVariable("hosp_conc", dist.LogNormal(5.0, 1.0)) + ), + aggregation="weekly", + reporting_schedule="regular", + start_dow=MMWR_WEEK, +) + +linked_ed_obs = PopulationCounts( + name="ed_visits", + ascertainment_rate_rv=linked_ascertainment.for_signal("ed_visits"), + delay_distribution_rv=DeterministicPMF("ed_delay", ed_delay_pmf), + noise=NegativeBinomialNoise( + DistributionalVariable("ed_conc", dist.LogNormal(4.0, 1.0)) + ), + day_of_week_rv=ed_day_of_week_rv, +) + +linked_builder = PyrenewBuilder() +linked_builder.configure_latent( + PopulationInfections, + gen_int_rv=gen_int_rv, + I0_rv=I0_rv, + log_rt_time_0_rv=log_rt_time_0_rv, + single_rt_process=weekly_rt_process, +) +linked_builder.add_ascertainment(linked_ascertainment) +linked_builder.add_observation(linked_hospital_obs) +linked_builder.add_observation(linked_ed_obs) + +linked_model = linked_builder.build() +print(f"Initialization points: {linked_model.latent.n_initialization_points}") +``` + +Before fitting, a seeded trace confirms that the linked ascertainment sites and mixed-cadence observation sites are present. + +```{python} +#| label: trace-linked-model +#| code-fold: false + +with numpyro.handlers.seed(rng_seed=0): + with numpyro.handlers.trace() as linked_trace: + linked_model.sample( + n_days_post_init=N_DAYS_FIT, + population_size=population_size, + obs_start_date=OBS_START_DATE, + hospital={"obs": hospital_observed}, + ed_visits={"obs": ed_observed}, + ) + +for site in [ + "logit_iedr", + "ihr_rel_iedr", + "he_ascertainment_ed_visits", + "he_ascertainment_hospital", + "latent_infections", + "hospital_predicted", + "ed_visits_predicted", +]: + print(f"{site}: {linked_trace[site]['value'].shape}") +``` + +The linked model is fit by the artifact-generation script with the same MCMC settings as the other fits. +The rendered tutorial loads those draws from disk. + +```{python} +#| label: linked-summary + +linked_parameter_summary = az.summary( + linked_idata_trimmed, + var_names=[ + "I0", + "he_ascertainment_ed_visits", + "he_ascertainment_hospital", + "ihr_rel_iedr", + "log_rt_time_0", + ], +) +linked_parameter_summary +``` + +The linked parameterization samples the hospital-to-ED ratio directly. +In this synthetic fit, that gives slightly cleaner sampler diagnostics for the main ascertainment quantities than the more diffuse joint parameterization. + +```{python} +#| label: linked-sampler-diagnostics + +sampler_diagnostics = pd.DataFrame( + [ + { + "model": "pyrenew-H-E", + "max_r_hat": float( + az.summary( + idata_trimmed, + var_names=[ + "he_ascertainment_hospital", + "he_ascertainment_ed_visits", + ], + )["r_hat"] + .astype(float) + .max() + ), + "min_bulk_ess": float( + az.summary( + idata_trimmed, + var_names=[ + "he_ascertainment_hospital", + "he_ascertainment_ed_visits", + ], + )["ess_bulk"] + .astype(float) + .min() + ), + }, + { + "model": "linked-pyrenew-H-E", + "max_r_hat": float( + az.summary( + linked_idata_trimmed, + var_names=[ + "he_ascertainment_ed_visits", + "he_ascertainment_hospital", + "ihr_rel_iedr", + ], + )["r_hat"] + .astype(float) + .max() + ), + "min_bulk_ess": float( + az.summary( + linked_idata_trimmed, + var_names=[ + "he_ascertainment_ed_visits", + "he_ascertainment_hospital", + "ihr_rel_iedr", + ], + )["ess_bulk"] + .astype(float) + .min() + ), + }, + ] +) +sampler_diagnostics +``` + +```{python} +#| label: linked-ratio-prior-posterior +#| fig-cap: Prior and posterior for the linked PyRenew IHR / IEDR multiplier. + +linked_ratio_post = linked_idata_trimmed.posterior["ihr_rel_iedr"].values.ravel() +linked_prior_ratio = np.random.default_rng(42).lognormal( + mean=0.0, + sigma=float(jnp.log(jnp.sqrt(2.0))), + size=4000, +) + +linked_ratio_density_df = pd.concat( + [ + pd.DataFrame({"ratio": linked_prior_ratio, "source": "Prior"}), + pd.DataFrame({"ratio": linked_ratio_post, "source": "Posterior"}), + ], + ignore_index=True, +) + +( + p9.ggplot(linked_ratio_density_df, p9.aes(x="ratio", fill="source")) + + p9.geom_density(alpha=0.45) + + p9.geom_vline(xintercept=true_ihr / true_iedr, color="red", linetype="dashed") + + p9.scale_x_log10() + + p9.labs( + x="IHR / IEDR", + y="Density", + fill="", + title="Linked PyRenew Prior and Posterior Ratio", + ) + + theme_tutorial +) +``` + +The three models infer similar ratio values, but they do not imply the same uncertainty in the absolute latent infection scale. +The linked parameterization improves sampler geometry for the ascertainment block in this fit, but its latent infection intervals are wider than the joint PyRenew intervals. +That is not a contradiction: R-hat and ESS describe how well the sampler explores the posterior, while interval width describes how much uncertainty the posterior itself contains. + +The plots below compare posterior latent infections and the relative width of the 90% latent-infection interval. +Because these data are synthetic, the data-generating latent infection trajectory is known. +In the posterior infection plots, the dashed black line is that synthetic truth; it is not an observed data stream used to fit the models. +When the posterior infection trajectories sit above that dashed line, the most direct explanation is the same ascertainment-scale trade-off: fitted absolute IHR and IEDR values are below the synthetic data-generating values, so more infections are needed to produce the observed hospital and ED counts. + +This is also why $\mathcal{R}(t)$ and latent infections answer different diagnostic questions. +Plotting $\mathcal{R}(t)$ is useful because it focuses on epidemic shape and growth or decline, which H+E data can often constrain better than the absolute infection level. +It should be shown alongside latent infections rather than instead of them: $\mathcal{R}(t)$ can look reasonable while the infection scale is still shifted by ascertainment assumptions. + +```{python} +#| label: linked-latent-infection-data + +linked_latent_inf = linked_idata_trimmed.posterior["latent_infections"] +linked_inf_q05 = linked_latent_inf.quantile(0.05, dim=["chain", "draw"]).values +linked_inf_q50 = linked_latent_inf.quantile(0.50, dim=["chain", "draw"]).values +linked_inf_q95 = linked_latent_inf.quantile(0.95, dim=["chain", "draw"]).values +custom_latent_inf = custom_scalar_idata.posterior["latent_infections"] +custom_inf_q05 = custom_latent_inf.quantile(0.05, dim=["chain", "draw"]).values +custom_inf_q50 = custom_latent_inf.quantile(0.50, dim=["chain", "draw"]).values +custom_inf_q95 = custom_latent_inf.quantile(0.95, dim=["chain", "draw"]).values + +latent_comparison_df = pd.concat( + [ + pd.DataFrame( + { + "model": "pyrenew-H-E", + "day": np.arange(n_compare), + "median": inf_q50[:n_compare], + "q05": inf_q05[:n_compare], + "q95": inf_q95[:n_compare], + "truth": true_infections[:n_compare], + } + ), + pd.DataFrame( + { + "model": "linked-pyrenew-H-E", + "day": np.arange(n_compare), + "median": linked_inf_q50[:n_compare], + "q05": linked_inf_q05[:n_compare], + "q95": linked_inf_q95[:n_compare], + "truth": true_infections[:n_compare], + } + ), + pd.DataFrame( + { + "model": "custom-H-E", + "day": np.arange(n_compare), + "median": custom_inf_q50[:n_compare], + "q05": custom_inf_q05[:n_compare], + "q95": custom_inf_q95[:n_compare], + "truth": true_infections[:n_compare], + } + ), + ], + ignore_index=True, +) + +latent_width_df = pd.concat( + [ + pd.DataFrame( + { + "model": "pyrenew-H-E", + "day": np.arange(n_compare), + "relative_width": inf_relative_width[:n_compare], + } + ), + pd.DataFrame( + { + "model": "linked-pyrenew-H-E", + "day": np.arange(n_compare), + "relative_width": ( + linked_inf_q95[:n_compare] - linked_inf_q05[:n_compare] + ) + / np.maximum(linked_inf_q50[:n_compare], 1.0), + } + ), + pd.DataFrame( + { + "model": "custom-H-E", + "day": np.arange(n_compare), + "relative_width": ( + custom_inf_q95[:n_compare] - custom_inf_q05[:n_compare] + ) + / np.maximum(custom_inf_q50[:n_compare], 1.0), + } + ), + ], + ignore_index=True, +) + +latent_width_summary = ( + latent_width_df.groupby("model", observed=True) + .agg( + mean_relative_width=("relative_width", "mean"), + median_relative_width=("relative_width", "median"), + ) + .reset_index() +) +latent_width_summary +``` + +```{python} +#| label: linked-latent-infections +#| fig-cap: Posterior latent infections under the two PyRenew parameterizations +#| and custom-H-E. The dashed black line is the synthetic data-generating +#| latent infection trajectory, not an observed signal used for fitting. + +( + p9.ggplot(latent_comparison_df, p9.aes(x="day")) + + p9.geom_ribbon( + p9.aes(ymin="q05", ymax="q95"), + fill="steelblue", + alpha=0.25, + ) + + p9.geom_line(p9.aes(y="median"), color="darkblue", size=1) + + p9.geom_line(p9.aes(y="truth"), color="black", linetype="dashed", size=0.7) + + p9.facet_wrap("~model", ncol=1) + + p9.scale_y_log10() + + p9.labs( + x="Day", + y="Latent infections", + title="Posterior Latent Infections vs Synthetic Truth", + ) + + theme_tutorial +) +``` + +```{python} +#| label: linked-latent-infection-uncertainty +#| fig-cap: Relative posterior interval width for latent infections under the +#| two PyRenew parameterizations and custom-H-E. + +( + p9.ggplot( + latent_width_df, + p9.aes(x="day", y="relative_width", color="model"), + ) + + p9.geom_line(size=0.9, alpha=0.85) + + p9.labs( + x="Day", + y="Relative 90% interval width", + color="Model", + title="Posterior Uncertainty in Latent Infections", + ) + + theme_tutorial +) +``` + +The linked parameterization is a useful sensitivity analysis because it asks whether the model can learn the relative hospital-to-ED scale directly. +It should not be interpreted as an absolute-scale fix. +The posterior can still move along the weakly identified direction where lower ascertainment rates imply higher latent infections, and the prior still determines where the fit sits along that direction. + +### Summarize custom-H-E + +The custom H+E fit is represented here by reduced scalar posterior draws. +Because its ED ascertainment is time-varying, we summarize both the first-day IEDR and the posterior mean over the time-varying IEDR trajectory. + +```{python} +#| label: custom-summary + +custom_parameter_summary = az.summary(custom_scalar_idata) +custom_parameter_summary +``` + +The three models parameterize some quantities differently, so this table compares only the closest scalar summaries. +For custom-H-E, ED ascertainment is time-varying; `IEDR_mean` is the posterior mean across that time-varying trajectory for each posterior draw. +Differences from the data-generating values should not be read as a win/loss ranking. +The PyRenew models and custom-H-E use different ascertainment structures, so this table is a compact way to compare their implied absolute scales and relative hospital-to-ED scale rather than a direct test of which implementation is correct. + +```{python} +#| label: inference-comparison + +inference_comparison = pd.DataFrame( + [ + { + "quantity": "I0", + "truth": true_i0, + "pyrenew-H-E median": float( + idata_trimmed.posterior["I0"].median(dim=["chain", "draw"]) + ), + "linked-pyrenew-H-E median": float( + linked_idata_trimmed.posterior["I0"].median(dim=["chain", "draw"]) + ), + "custom-H-E median": float( + custom_scalar_idata.posterior["I0"].median(dim=["chain", "draw"]) + ), + }, + { + "quantity": "IHR", + "truth": true_ihr, + "pyrenew-H-E median": float( + idata_trimmed.posterior["he_ascertainment_hospital"].median( + dim=["chain", "draw"] + ) + ), + "linked-pyrenew-H-E median": float( + linked_idata_trimmed.posterior["he_ascertainment_hospital"].median( + dim=["chain", "draw"] + ) + ), + "custom-H-E median": float( + custom_scalar_idata.posterior["IHR"].median(dim=["chain", "draw"]) + ), + }, + { + "quantity": "IEDR", + "truth": true_iedr, + "pyrenew-H-E median": float( + idata_trimmed.posterior["he_ascertainment_ed_visits"].median( + dim=["chain", "draw"] + ) + ), + "linked-pyrenew-H-E median": float( + linked_idata_trimmed.posterior["he_ascertainment_ed_visits"].median( + dim=["chain", "draw"] + ) + ), + "custom-H-E median": float( + custom_scalar_idata.posterior["IEDR_mean"].median(dim=["chain", "draw"]) + ), + }, + { + "quantity": "IHR / IEDR", + "truth": true_ihr / true_iedr, + "pyrenew-H-E median": float( + ( + idata_trimmed.posterior["he_ascertainment_hospital"] + / idata_trimmed.posterior["he_ascertainment_ed_visits"] + ).median(dim=["chain", "draw"]) + ), + "linked-pyrenew-H-E median": float( + linked_idata_trimmed.posterior["ihr_rel_iedr"].median( + dim=["chain", "draw"] + ) + ), + "custom-H-E median": float( + ( + custom_scalar_idata.posterior["IHR"] + / custom_scalar_idata.posterior["IEDR_mean"] + ).median(dim=["chain", "draw"]) + ), + }, + ] +) + +inference_comparison +``` + +### Runtime Comparison + +The two runtimes are comparable in this synthetic example. +They should not be interpreted as a formal benchmark because pyrenew-H-E and custom-H-E use different implementations, priors, time aggregation choices, and model-specific components. + +```{python} +#| label: runtime-comparison + +pd.DataFrame( + [ + {"model": "pyrenew-H-E", "elapsed_seconds": pyrenew_elapsed}, + { + "model": "linked-pyrenew-H-E", + "elapsed_seconds": linked_pyrenew_elapsed, + }, + {"model": "custom-H-E", "elapsed_seconds": custom_elapsed}, + ] +) +``` + +### Identifiability Check + +The comparison above points back to the main identifiability issue in H+E-only models. +All three fits are useful diagnostics for scale and structure, not a contest between implementations. +H+E observations identify the epidemic shape and the relative magnitude of the two clinical signals better than they identify the absolute infection scale. + +Here we compare the posterior distributions of the three absolute-scale quantities that matter most for H+E alone: $I_0$, IHR, and IEDR. +For linked-pyrenew-H-E, IHR is the sampled IEDR base rate times the sampled ratio. +For custom-H-E, IEDR is time-varying, so we use `IEDR_mean` as a scalar summary for each posterior draw. + +```{python} +#| label: identifiability-scale-data + +pyrenew_i0 = idata_trimmed.posterior["I0"].values.ravel() +pyrenew_ihr = idata_trimmed.posterior["he_ascertainment_hospital"].values.ravel() +pyrenew_iedr = idata_trimmed.posterior["he_ascertainment_ed_visits"].values.ravel() + +linked_i0 = linked_idata_trimmed.posterior["I0"].values.ravel() +linked_ihr = linked_idata_trimmed.posterior["he_ascertainment_hospital"].values.ravel() +linked_iedr = linked_idata_trimmed.posterior[ + "he_ascertainment_ed_visits" +].values.ravel() +linked_ratio = linked_idata_trimmed.posterior["ihr_rel_iedr"].values.ravel() + +custom_i0 = custom_scalar_idata.posterior["I0"].values.ravel() +custom_ihr = custom_scalar_idata.posterior["IHR"].values.ravel() +custom_iedr = custom_scalar_idata.posterior["IEDR_mean"].values.ravel() + +scale_draws_df = pd.concat( + [ + pd.DataFrame( + { + "model": "pyrenew-H-E", + "I0": pyrenew_i0, + "IHR": pyrenew_ihr, + "IEDR": pyrenew_iedr, + "ratio": pyrenew_ihr / pyrenew_iedr, + } + ), + pd.DataFrame( + { + "model": "linked-pyrenew-H-E", + "I0": linked_i0, + "IHR": linked_ihr, + "IEDR": linked_iedr, + "ratio": linked_ratio, + } + ), + pd.DataFrame( + { + "model": "custom-H-E", + "I0": custom_i0, + "IHR": custom_ihr, + "IEDR": custom_iedr, + "ratio": custom_ihr / custom_iedr, + } + ), + ], + ignore_index=True, +) + +scale_density_df = scale_draws_df.melt( + id_vars="model", + value_vars=["I0", "IHR", "IEDR"], + var_name="quantity", + value_name="value", +) + +truth_scale_df = pd.DataFrame( + { + "quantity": ["I0", "IHR", "IEDR"], + "truth": [true_i0, true_ihr, true_iedr], + } +) +``` + +The marginal densities show how each model places posterior mass for the absolute-scale quantities. + +```{python} +#| label: identifiability-scale-densities +#| fig-cap: |- +#| Posterior densities for $I_0$, IHR, and IEDR under all three models. +#| Red dashed lines mark data-generating values. + +( + p9.ggplot(scale_density_df, p9.aes(x="value", fill="model", color="model")) + + p9.geom_density(alpha=0.35) + + p9.geom_vline( + truth_scale_df, + p9.aes(xintercept="truth"), + color="red", + linetype="dashed", + ) + + p9.facet_wrap("~quantity", scales="free") + + p9.scale_x_log10() + + p9.labs( + x="Value", + y="Density", + fill="Model", + color="Model", + title="Posterior Scale Parameters", + ) + + theme_tutorial +) +``` + +The joint posterior for IHR and IEDR shows how each model constrains the two clinical ascertainment rates together. +The red point marks the data-generating values. + +```{python} +#| label: identifiability-ihr-iedr +#| fig-cap: |- +#| Joint posterior of hospital and ED ascertainment rates under both +#| PyRenew parameterizations and custom-H-E. + +truth_asc_df = pd.DataFrame({"IHR": [true_ihr], "IEDR": [true_iedr]}) + +( + p9.ggplot(scale_draws_df, p9.aes(x="IHR", y="IEDR", color="model")) + + p9.geom_point(alpha=0.16, size=0.7) + + p9.geom_point(data=truth_asc_df, color="red", size=3) + + p9.facet_wrap("~model") + + p9.scale_x_log10() + + p9.scale_y_log10() + + p9.labs( + x="Hospital ascertainment (IHR)", + y="ED ascertainment (IEDR)", + color="Model", + title="Hospital and ED Ascertainment Are Jointly Constrained", + ) + + theme_tutorial +) +``` + +The ratio is the most directly interpretable relative-scale quantity for the two clinical signals. +This plot checks whether each model captures the data-generating IHR / IEDR relationship, even when the absolute IHR and IEDR scales are weakly identified. + +```{python} +#| label: identifiability-ratio +#| fig-cap: Posterior distribution of the IHR / IEDR ratio under all three +#| models. + +( + p9.ggplot(scale_draws_df, p9.aes(x="ratio", fill="model", color="model")) + + p9.geom_density(alpha=0.35) + + p9.geom_vline(xintercept=true_ihr / true_iedr, color="red", linetype="dashed") + + p9.scale_x_log10() + + p9.labs( + x="IHR / IEDR", + y="Density", + fill="Model", + color="Model", + title="Relative Ascertainment Is Better Identified Than Absolute Scale", + ) + + theme_tutorial +) +``` + +All three models put the hospital-to-ED ascertainment ratio in roughly the same part of parameter space. +That is the main quantity the H+E data can learn directly. +The linked PyRenew model is still useful because it samples that ratio directly, which can improve R-hat and effective sample size for the ascertainment block even when the posterior ratio is similar to the other fits. +In this example, however, the linked prior and parameterization place more posterior uncertainty on the common absolute ascertainment scale, so the latent infection interval is wider than under `JointAscertainment`. + +These plots are diagnostic rather than corrective. +They show why external information matters: H+E data alone generally need either informative priors or another signal, such as wastewater or prevalence data, to anchor the absolute infection scale. +The ratio plot and the infection plot should therefore be read together. +The models can agree on the relative hospital-to-ED ascertainment ratio while all choosing an absolute ascertainment level that is too low, which pushes latent infections upward. + +If the original PyRenew fit lies closer to the synthetic truth for some quantities, that should be interpreted in light of the data-generating process. +The synthetic data were generated with scalar hospital and ED ascertainment rates, which is closer to the `JointAscertainment` model used here than to the custom H+E model. +The linked PyRenew model and custom model define hospital ascertainment through a multiplier on ED ascertainment, which makes the relative scale explicit but does not anchor the absolute scale. +The custom model also allows ED ascertainment to vary over time. +Those features can be useful in applied forecasting, but they are additional structure relative to this simplified synthetic generator. diff --git a/docs_scripts/generate_multisignal_he_artifacts.py b/docs_scripts/generate_multisignal_he_artifacts.py new file mode 100644 index 00000000..f76aa0a4 --- /dev/null +++ b/docs_scripts/generate_multisignal_he_artifacts.py @@ -0,0 +1,585 @@ +# numpydoc ignore=GL08 + +"""Generate precomputed artifacts for the multisignal H+E tutorial. + +Run this script from the repository root on a machine that can run both the +PyRenew tutorial model and the custom NumPyro H+E model. +""" + +from __future__ import annotations + +import argparse +import contextlib +import io +import json +import pickle +import runpy +import subprocess +import sys +import time +from collections.abc import Mapping +from datetime import UTC, date, datetime +from pathlib import Path + +import arviz as az +import jax +import jax.numpy as jnp +import jax.random as random +import numpy as np +import numpyro +import numpyro.distributions as dist +import pandas as pd +import xarray as xr + +import pyrenew.transformation as transformation +from pyrenew.ascertainment import AscertainmentModel, JointAscertainment +from pyrenew.datasets import ( + load_example_infection_admission_interval, + load_synthetic_daily_ed_visits, + load_synthetic_true_parameters, + load_synthetic_weekly_hospital_admissions, + write_synthetic_hew_model_dir, +) +from pyrenew.deterministic import DeterministicPMF, DeterministicVariable +from pyrenew.latent import DifferencedAR1, PopulationInfections, WeeklyTemporalProcess +from pyrenew.metaclass import RandomVariable +from pyrenew.model import PyrenewBuilder +from pyrenew.observation import NegativeBinomialNoise, PopulationCounts +from pyrenew.randomvariable import DistributionalVariable, TransformedVariable +from pyrenew.time import MMWR_WEEK + +N_DAYS_FIT = 126 +OBS_START_DATE = date(2023, 11, 5) + + +class RatioLinkedAscertainment(AscertainmentModel): + """Two ascertainment rates expressed as a base rate and a ratio.""" + + def __init__( + self, + name: str, + base_signal: str, + linked_signal: str, + base_rate_rv: RandomVariable, + ratio_rv: RandomVariable, + ) -> None: # numpydoc ignore=GL08 + super().__init__(name=name, signals=(base_signal, linked_signal)) + self.base_signal = base_signal + self.linked_signal = linked_signal + self.base_rate_rv = base_rate_rv + self.ratio_rv = ratio_rv + + def sample( + self, **kwargs: object + ) -> Mapping[str, jax.Array]: # numpydoc ignore=RT01 + """Sample the base rate and ratio, then compute the linked rate.""" + base_rate = self.base_rate_rv() + ratio = self.ratio_rv() + linked_rate = base_rate * ratio + numpyro.deterministic(f"{self.name}_{self.base_signal}", base_rate) + numpyro.deterministic(f"{self.name}_{self.linked_signal}", linked_rate) + return {self.base_signal: base_rate, self.linked_signal: linked_rate} + + +def git_sha(path: Path) -> str | None: # numpydoc ignore=RT01 + """Return the git SHA for a repo path, or None if unavailable.""" + try: + result = subprocess.run( + ["git", "-C", str(path), "rev-parse", "HEAD"], + check=True, + capture_output=True, + text=True, + ) + except Exception: + return None + return result.stdout.strip() + + +def build_pyrenew_model( + ascertainment_parameterization: str = "joint", +) -> tuple[object, float, jax.Array, jax.Array]: # numpydoc ignore=RT01 + """Build the PyRenew H+E tutorial model and aligned observations.""" + true_params = load_synthetic_true_parameters() + weekly_hosp = load_synthetic_weekly_hospital_admissions() + daily_ed = load_synthetic_daily_ed_visits() + + hosp_delay_pmf = jnp.array( + load_example_infection_admission_interval()["probability_mass"].to_numpy() + ) + ed_delay_pmf = jnp.array(true_params["ed_visits"]["delay_pmf"]) + population_size = float(weekly_hosp["pop"][0]) + + gen_int_pmf = jnp.array( + [ + 0.6326975, + 0.2327564, + 0.0856263, + 0.03150015, + 0.01158826, + 0.00426308, + 0.0015683, + ] + ) + gen_int_rv = DeterministicPMF("gen_int", gen_int_pmf) + i0_rv = TransformedVariable( + name="I0", + base_rv=DistributionalVariable( + name="logit_I0", + distribution=dist.Normal( + transformation.SigmoidTransform().inv(true_params["i0_per_capita"]), + 0.25, + ), + ), + transforms=transformation.SigmoidTransform(), + ) + log_rt_time_0_rv = DistributionalVariable("log_rt_time_0", dist.Normal(0.0, 0.5)) + + weekly_rt_process = WeeklyTemporalProcess( + DifferencedAR1( + autoreg_rv=DeterministicVariable("rt_diff_autoreg", 0.5), + innovation_sd_rv=DeterministicVariable("rt_diff_innovation_sd", 0.03), + ), + start_dow=MMWR_WEEK, + ) + + if ascertainment_parameterization == "joint": + ascertainment_center = 0.004 + ascertainment_sd = 0.3 + ascertainment_corr = 0.5 + ascertainment_cov = jnp.array( + [ + [ascertainment_sd**2, ascertainment_corr * ascertainment_sd**2], + [ascertainment_corr * ascertainment_sd**2, ascertainment_sd**2], + ] + ) + ascertainment = JointAscertainment( + name="he_ascertainment", + signals=("hospital", "ed_visits"), + baseline_rates=jnp.array([ascertainment_center, ascertainment_center]), + covariance_matrix=ascertainment_cov, + ) + elif ascertainment_parameterization == "linked": + iedr_rv = TransformedVariable( + name="iedr", + base_rv=DistributionalVariable( + name="logit_iedr", + distribution=dist.Normal( + transformation.SigmoidTransform().inv(0.004), + 0.3, + ), + ), + transforms=transformation.SigmoidTransform(), + ) + ratio_rv = DistributionalVariable( + "ihr_rel_iedr", + dist.LogNormal(0.0, jnp.log(jnp.sqrt(2.0))), + ) + ascertainment = RatioLinkedAscertainment( + name="he_ascertainment", + base_signal="ed_visits", + linked_signal="hospital", + base_rate_rv=iedr_rv, + ratio_rv=ratio_rv, + ) + else: + raise ValueError( + "ascertainment_parameterization must be either 'joint' or 'linked'." + ) + + hospital_obs = PopulationCounts( + name="hospital", + ascertainment_rate_rv=ascertainment.for_signal("hospital"), + delay_distribution_rv=DeterministicPMF("hosp_delay", hosp_delay_pmf), + noise=NegativeBinomialNoise( + DistributionalVariable("hosp_conc", dist.LogNormal(5.0, 1.0)) + ), + aggregation="weekly", + reporting_schedule="regular", + start_dow=MMWR_WEEK, + ) + ed_day_of_week_rv = DeterministicVariable( + "ed_day_of_week_effect", + jnp.array(true_params["ed_visits"]["day_of_week_effects"]), + ) + ed_obs = PopulationCounts( + name="ed_visits", + ascertainment_rate_rv=ascertainment.for_signal("ed_visits"), + delay_distribution_rv=DeterministicPMF("ed_delay", ed_delay_pmf), + noise=NegativeBinomialNoise( + DistributionalVariable("ed_conc", dist.LogNormal(4.0, 1.0)) + ), + day_of_week_rv=ed_day_of_week_rv, + ) + + builder = PyrenewBuilder() + builder.configure_latent( + PopulationInfections, + gen_int_rv=gen_int_rv, + I0_rv=i0_rv, + log_rt_time_0_rv=log_rt_time_0_rv, + single_rt_process=weekly_rt_process, + ) + builder.add_ascertainment(ascertainment) + builder.add_observation(hospital_obs) + builder.add_observation(ed_obs) + model = builder.build() + + ed_observed = model.pad_observations( + jnp.array(daily_ed["ed_visits"].to_numpy(), dtype=jnp.float32) + ) + hospital_observed = model.pad_aggregated_observations( + jnp.array(weekly_hosp["weekly_hosp_admits"].to_numpy(), dtype=jnp.float32), + observation_name="hospital", + n_days_post_init=N_DAYS_FIT, + obs_start_date=OBS_START_DATE, + ) + return model, population_size, hospital_observed, ed_observed + + +def trim_time(ds: xr.Dataset, n_init: int) -> xr.Dataset: # numpydoc ignore=RT01 + """Trim initialization points from an ArviZ dataset.""" + if "time" in ds.dims: + ds = ds.isel(time=slice(n_init, None)) + ds = ds.assign_coords(time=range(ds.sizes["time"])) + return ds + + +def run_pyrenew_fit(output_dir: Path) -> float: # numpydoc ignore=RT01 + """Fit pyrenew-H-E and write posterior artifacts.""" + model, population_size, hospital_observed, ed_observed = build_pyrenew_model() + + jax.clear_caches() + start_time = time.time() + model.run( + num_warmup=500, + num_samples=500, + rng_key=random.PRNGKey(42), + mcmc_args={"num_chains": 4, "progress_bar": True}, + n_days_post_init=N_DAYS_FIT, + population_size=population_size, + obs_start_date=OBS_START_DATE, + hospital={"obs": hospital_observed}, + ed_visits={"obs": ed_observed}, + ) + samples = model.mcmc.get_samples() + jax.block_until_ready(samples) + elapsed = time.time() - start_time + + n_init = model.latent.n_initialization_points + idata = az.from_numpyro( + model.mcmc, + dims={ + "latent_infections": ["time"], + "PopulationInfections::infections_aggregate": ["time"], + "PopulationInfections::log_rt_single": ["time", "dummy"], + "PopulationInfections::rt_single": ["time", "dummy"], + "log_rt_single_weekly": ["rt_week", "dummy"], + "hospital_predicted_daily": ["time"], + "hospital_predicted": ["week"], + "ed_visits_predicted": ["time"], + }, + ) + idata_trimmed = idata.map_over_datasets(lambda ds: trim_time(ds, n_init)) + idata_trimmed.posterior["I0"] = 1 / ( + 1 + np.exp(-idata_trimmed.posterior["logit_I0"]) + ) + + posterior = idata_trimmed.posterior + output_dir.mkdir(parents=True, exist_ok=True) + np.savez_compressed( + output_dir / "pyrenew_fit_artifacts.npz", + n_init=np.array(n_init, dtype=np.int64), + I0=posterior["I0"].values, + log_rt_time_0=posterior["log_rt_time_0"].values, + he_ascertainment_hospital=posterior["he_ascertainment_hospital"].values, + he_ascertainment_ed_visits=posterior["he_ascertainment_ed_visits"].values, + rt_single_full=idata.posterior["PopulationInfections::rt_single"].values, + rt_single_trimmed=posterior["PopulationInfections::rt_single"].values, + latent_infections_trimmed=posterior["latent_infections"].values, + ) + return elapsed + + +def run_linked_pyrenew_fit(output_dir: Path) -> float: # numpydoc ignore=RT01 + """Fit linked-pyrenew-H-E and write posterior artifacts.""" + model, population_size, hospital_observed, ed_observed = build_pyrenew_model( + ascertainment_parameterization="linked" + ) + + jax.clear_caches() + start_time = time.time() + model.run( + num_warmup=500, + num_samples=500, + rng_key=random.PRNGKey(42), + mcmc_args={"num_chains": 4, "progress_bar": True}, + n_days_post_init=N_DAYS_FIT, + population_size=population_size, + obs_start_date=OBS_START_DATE, + hospital={"obs": hospital_observed}, + ed_visits={"obs": ed_observed}, + ) + samples = model.mcmc.get_samples() + jax.block_until_ready(samples) + elapsed = time.time() - start_time + + n_init = model.latent.n_initialization_points + idata = az.from_numpyro( + model.mcmc, + dims={ + "latent_infections": ["time"], + "PopulationInfections::infections_aggregate": ["time"], + "PopulationInfections::log_rt_single": ["time", "dummy"], + "PopulationInfections::rt_single": ["time", "dummy"], + "log_rt_single_weekly": ["rt_week", "dummy"], + "hospital_predicted_daily": ["time"], + "hospital_predicted": ["week"], + "ed_visits_predicted": ["time"], + }, + ) + idata_trimmed = idata.map_over_datasets(lambda ds: trim_time(ds, n_init)) + idata_trimmed.posterior["I0"] = 1 / ( + 1 + np.exp(-idata_trimmed.posterior["logit_I0"]) + ) + + posterior = idata_trimmed.posterior + output_dir.mkdir(parents=True, exist_ok=True) + np.savez_compressed( + output_dir / "linked_pyrenew_fit_artifacts.npz", + n_init=np.array(n_init, dtype=np.int64), + I0=posterior["I0"].values, + log_rt_time_0=posterior["log_rt_time_0"].values, + he_ascertainment_hospital=posterior["he_ascertainment_hospital"].values, + he_ascertainment_ed_visits=posterior["he_ascertainment_ed_visits"].values, + ihr_rel_iedr=posterior["ihr_rel_iedr"].values, + rt_single_full=idata.posterior["PopulationInfections::rt_single"].values, + rt_single_trimmed=posterior["PopulationInfections::rt_single"].values, + latent_infections_trimmed=posterior["latent_infections"].values, + ) + return elapsed + + +def find_sample( # numpydoc ignore=RT01 + samples: dict[str, np.ndarray], candidates: list[str] +) -> np.ndarray: + """Get a posterior sample array from candidate variable names.""" + for name in candidates: + if name in samples: + return np.asarray(samples[name]) + raise KeyError(f"Could not find any of {candidates} in custom posterior samples.") + + +def reduce_to_chain_draw( # numpydoc ignore=RT01 + values: np.ndarray, reducer: str = "mean" +) -> np.ndarray: + """Reduce non-sample dimensions in a chain/draw posterior array.""" + values = np.asarray(values, dtype=float) + if values.ndim <= 2: + return values + axes = tuple(range(2, values.ndim)) + if reducer == "first": + index = (slice(None), slice(None), *([0] * (values.ndim - 2))) + return values[index] + if reducer == "mean": + return values.mean(axis=axes) + raise ValueError(f"Unknown reducer: {reducer}") + + +def reduce_to_chain_draw_time(values: np.ndarray) -> np.ndarray: # numpydoc ignore=RT01 + """Normalize a posterior trajectory array to chain/draw/time shape.""" + values = np.asarray(values, dtype=float) + values = np.squeeze(values) + if values.ndim == 2: + values = values[None, :, :] + if values.ndim != 3: + raise ValueError( + "Expected custom latent infections to have chain/draw/time shape " + f"after squeezing; got shape {values.shape}." + ) + if values.shape[-1] < N_DAYS_FIT: + raise ValueError( + "Custom latent infections are shorter than the fit period: " + f"{values.shape[-1]} < {N_DAYS_FIT}." + ) + return values[..., -N_DAYS_FIT:] + + +def run_custom_fit( + output_dir: Path, + pyrenew_multisignal_dir: Path, + cfa_stf_dir: Path, + model_dir: Path, +) -> float: # numpydoc ignore=RT01 + """Fit custom-H-E and write scalar posterior artifacts.""" + sys.path.insert(0, str(pyrenew_multisignal_dir / "src")) + sys.path.insert(0, str(cfa_stf_dir)) + + from pipelines.pyrenew_hew.fit_pyrenew_model import fit_and_save_model + + write_synthetic_hew_model_dir(model_dir, overwrite=True) + with open(model_dir / "data" / "model_params.json") as file: + model_params = json.load(file) + population_size = float(model_params["population_size"]) + + jax.clear_caches() + stdout = io.StringIO() + stderr = io.StringIO() + start_time = time.time() + try: + with contextlib.redirect_stdout(stdout), contextlib.redirect_stderr(stderr): + fit_and_save_model( + model_dir=model_dir, + fit_ed_visits=True, + fit_hospital_admissions=True, + fit_wastewater=False, + n_warmup=500, + n_samples=500, + n_chains=4, + rng_key=42, + ) + if hasattr(jax, "effects_barrier"): + jax.effects_barrier() + except Exception: + print("fit_and_save_model failed. Last captured stdout:") + print(stdout.getvalue()[-4000:]) + print("Last captured stderr:") + print(stderr.getvalue()[-4000:]) + raise + elapsed = time.time() - start_time + + with open(model_dir / "posterior_samples.pickle", "rb") as file: + custom_mcmc = pickle.load(file) + + samples = custom_mcmc.get_samples(group_by_chain=True) + ihr = reduce_to_chain_draw(find_sample(samples, ["IHR", "ihr"])) + iedr = find_sample(samples, ["IEDR", "iedr"]) + latent_infections = population_size * reduce_to_chain_draw_time( + find_sample( + samples, + [ + "latent_infections", + "infections", + "infections_aggregate", + "PopulationInfections::infections_aggregate", + "i_t", + "I_t", + ], + ) + ) + rt = reduce_to_chain_draw_time( + find_sample(samples, ["rt", "rtu_subpop", "Rt", "R_t"]) + ) + iedr_first_day = reduce_to_chain_draw(iedr, reducer="first") + iedr_mean = reduce_to_chain_draw(iedr, reducer="mean") + + try: + i0 = reduce_to_chain_draw( + find_sample(samples, ["I0", "i0_first_obs_n_rv", "i0_first_obs_n"]) + ) + except KeyError: + custom_priors = runpy.run_path(str(model_dir / "priors.py")) + i0_value = float(custom_priors["i0_first_obs_n_rv"]()) + i0 = np.full_like(ihr, i0_value, dtype=float) + + scalar_draws = pd.DataFrame( + { + "chain": np.repeat(np.arange(ihr.shape[0]), ihr.shape[1]), + "draw": np.tile(np.arange(ihr.shape[1]), ihr.shape[0]), + "I0": i0.ravel(), + "IHR": ihr.ravel(), + "IEDR_first_day": iedr_first_day.ravel(), + "IEDR_mean": iedr_mean.ravel(), + } + ) + scalar_draws["ratio"] = scalar_draws["IHR"] / scalar_draws["IEDR_mean"] + output_dir.mkdir(parents=True, exist_ok=True) + scalar_draws.to_csv(output_dir / "custom_he_scalar_draws.csv", index=False) + np.savez_compressed( + output_dir / "custom_he_fit_artifacts.npz", + latent_infections_trimmed=latent_infections, + rt_trimmed=rt, + ) + return elapsed + + +def parse_args() -> argparse.Namespace: # numpydoc ignore=GL08 + parser = argparse.ArgumentParser() + parser.add_argument( + "--output-dir", + type=Path, + default=Path("docs/tutorials/data/multisignal_he"), + ) + parser.add_argument( + "--pyrenew-multisignal-dir", + type=Path, + default=Path("~/github/CDC/pyrenew-multisignal").expanduser(), + ) + parser.add_argument( + "--cfa-stf-dir", + type=Path, + default=Path("~/github/CDC/cfa-stf-routine-forecasting").expanduser(), + ) + parser.add_argument( + "--model-dir", + type=Path, + default=Path("docs/tutorials/scratch/synthetic_pyrenew_hew_model"), + ) + return parser.parse_args() + + +def main() -> None: # numpydoc ignore=GL08 + args = parse_args() + numpyro.set_host_device_count(4) + numpyro.enable_x64() + + pyrenew_elapsed = run_pyrenew_fit(args.output_dir) + linked_pyrenew_elapsed = run_linked_pyrenew_fit(args.output_dir) + custom_elapsed = run_custom_fit( + output_dir=args.output_dir, + pyrenew_multisignal_dir=args.pyrenew_multisignal_dir, + cfa_stf_dir=args.cfa_stf_dir, + model_dir=args.model_dir, + ) + + timings = { + "pyrenew-H-E": { + "elapsed_seconds": pyrenew_elapsed, + "num_warmup": 500, + "num_samples": 500, + "num_chains": 4, + "rng_key": 42, + }, + "custom-H-E": { + "elapsed_seconds": custom_elapsed, + "num_warmup": 500, + "num_samples": 500, + "num_chains": 4, + "rng_key": 42, + }, + "linked-pyrenew-H-E": { + "elapsed_seconds": linked_pyrenew_elapsed, + "num_warmup": 500, + "num_samples": 500, + "num_chains": 4, + "rng_key": 42, + }, + } + with open(args.output_dir / "timings.json", "w") as file: + json.dump(timings, file, indent=2) + file.write("\n") + + metadata = { + "generated_at": datetime.now(UTC).isoformat(), + "pyrenew_sha": git_sha(Path.cwd()), + "pyrenew_multisignal_sha": git_sha(args.pyrenew_multisignal_dir), + "cfa_stf_sha": git_sha(args.cfa_stf_dir), + } + with open(args.output_dir / "metadata.json", "w") as file: + json.dump(metadata, file, indent=2) + file.write("\n") + + print(f"Wrote multisignal H+E artifacts to {args.output_dir}") + + +if __name__ == "__main__": + main() diff --git a/pyproject.toml b/pyproject.toml index afdb841b..6214fb53 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,6 +33,7 @@ dev = [ "pytest-cov>=6.3.0", "ruff>=0.15.0", "scipy>=1.16.1", + "xarray>=2026.4.0", ] [build-system] @@ -71,10 +72,11 @@ exclude = [ # don't report on objects that match any of these regex [tool.deptry] -known_first_party = ["pyrenew", "test"] +known_first_party = ["pyrenew", "test", "_tutorial_theme"] [tool.deptry.per_rule_ignores] -DEP004 = ["arviz", "pytest", "scipy", "bs4"] +DEP001 = ["pipelines"] +DEP004 = ["arviz", "pytest", "scipy", "bs4", "pandas", "plotnine", "xarray"] [tool.pytest.ini_options] markers = [ diff --git a/pyrenew/datasets/__init__.py b/pyrenew/datasets/__init__.py index 47b4b4bf..cd0c4df1 100644 --- a/pyrenew/datasets/__init__.py +++ b/pyrenew/datasets/__init__.py @@ -11,6 +11,7 @@ load_synthetic_true_parameters, load_synthetic_weekly_hospital_admissions, ) +from pyrenew.datasets.synthetic_hew_export import write_synthetic_hew_model_dir from pyrenew.datasets.wastewater_nwss import load_wastewater_data_for_state __all__ = [ @@ -22,4 +23,5 @@ "load_synthetic_true_parameters", "load_synthetic_weekly_hospital_admissions", "load_wastewater_data_for_state", + "write_synthetic_hew_model_dir", ] diff --git a/pyrenew/datasets/synthetic_hew_export.py b/pyrenew/datasets/synthetic_hew_export.py new file mode 100644 index 00000000..073a33c2 --- /dev/null +++ b/pyrenew/datasets/synthetic_hew_export.py @@ -0,0 +1,336 @@ +""" +Export PyRenew synthetic H+E data to a production-style HEW model directory. + +This module does not import or depend on ``pyrenew-multisignal`` or +``cfa-stf-routine-forecasting``. It only writes the file layout those +repositories expect for a direct model fit. +""" + +from __future__ import annotations + +import json +import shutil +from collections.abc import Iterable +from pathlib import Path +from textwrap import dedent + +import numpy as np + +from pyrenew.datasets.infection_admission_interval import ( + load_example_infection_admission_interval, +) +from pyrenew.datasets.synthetic_data import ( + load_synthetic_daily_ed_visits, + load_synthetic_true_parameters, + load_synthetic_weekly_hospital_admissions, +) + +DEFAULT_RIGHT_TRUNCATION_PMF = [1.0] +"""Default PMF used when synthetic ED reports are treated as complete.""" + + +def _as_float_list(values: Iterable[float]) -> list[float]: + """ + Convert an array-like object to a JSON-serializable list of floats. + + Returns + ------- + list of float + Values converted to built-in Python floats. + """ + return [float(x) for x in values] + + +def _lognormal_moment_match(pmf: list[float]) -> tuple[float, float]: + """ + Approximate lognormal parameters for a discrete delay PMF. + + The production HEW model expects a lognormal reference location and scale + for the inferred hospital delay. The pipeline derives these from the delay + PMF; here we use a moment-matching approximation over positive day indices. + + Returns + ------- + tuple of float + Moment-matched lognormal location and scale parameters. + """ + probs = np.asarray(pmf, dtype=float) + probs = probs / probs.sum() + days = np.arange(probs.size, dtype=float) + + positive = days > 0 + probs = probs[positive] + days = days[positive] + probs = probs / probs.sum() + + mean = float(np.sum(days * probs)) + variance = float(np.sum(((days - mean) ** 2) * probs)) + sigma2 = np.log1p(variance / mean**2) + loc = np.log(mean) - 0.5 * sigma2 + scale = np.sqrt(sigma2) + return float(loc), float(scale) + + +def _default_priors_text() -> str: + """ + Return a minimal priors.py compatible with the production HEW model builder. + + These priors are intended for synthetic-data smoke tests, not production + forecasting. + + Returns + ------- + str + Python source code defining the default synthetic-data priors. + """ + return dedent( + """ + import jax.numpy as jnp + import numpyro.distributions as dist + import pyrenew.transformation as transformation + from pyrenew.deterministic import DeterministicVariable + from pyrenew.randomvariable import DistributionalVariable, TransformedVariable + + i0_first_obs_n_rv = DeterministicVariable("i0_first_obs_n_rv", 4 / 10000) + log_r_mu_intercept_rv = DeterministicVariable( + "log_r_mu_intercept_rv", jnp.log(1.2) + ) + eta_sd_rv = DistributionalVariable( + "eta_sd", dist.TruncatedNormal(0.15, 0.05, low=0) + ) + autoreg_rt_rv = DistributionalVariable("autoreg_rt", dist.Beta(2, 40)) + + inf_feedback_strength_rv = TransformedVariable( + "inf_feedback", + DistributionalVariable( + "inf_feedback_raw", + dist.LogNormal(jnp.log(50), jnp.log(1.5)), + ), + transforms=transformation.AffineTransform(loc=0, scale=-1), + ) + + delay_offset_loc_rv = DistributionalVariable( + "delay_offset_loc", dist.Normal(0.75, 0.5) + ) + delay_log_offset_scale_rv = DistributionalVariable( + "delay_log_offset_scale", dist.Normal(0, 0.5) + ) + + p_ed_visit_mean_rv = DistributionalVariable( + "p_ed_visit_mean", + dist.Normal(transformation.SigmoidTransform().inv(0.005), 0.3), + ) + p_ed_visit_w_sd_rv = DistributionalVariable( + "p_ed_visit_w_sd_sd", dist.TruncatedNormal(0, 0.01, low=0) + ) + autoreg_p_ed_visit_rv = DistributionalVariable( + "autoreg_p_ed_visit_rv", dist.Beta(1, 100) + ) + ed_visit_wday_effect_rv = TransformedVariable( + "ed_visit_wday_effect", + DistributionalVariable( + "ed_visit_wday_effect_raw", + dist.Dirichlet(jnp.array([5, 5, 5, 5, 5, 5, 5])), + ), + transformation.AffineTransform(loc=0, scale=7), + ) + + ihr_rv = TransformedVariable( + "ihr", + DistributionalVariable( + "logit_ihr", + dist.Normal(transformation.SigmoidTransform().inv(0.005), 0.3), + ), + transforms=transformation.SigmoidTransform(), + ) + ihr_rel_iedr_rv = DistributionalVariable( + "ihr_rel_iedr", dist.LogNormal(0, jnp.log(jnp.sqrt(2))) + ) + + ed_neg_bin_concentration_rv = DistributionalVariable( + "ed_visit_neg_bin_concentration", dist.LogNormal(4, 1) + ) + hosp_admit_neg_bin_concentration_rv = DistributionalVariable( + "hosp_admit_neg_bin_concentration", dist.LogNormal(4 + jnp.log(7), 1.5) + ) + + t_peak_rv = DistributionalVariable("t_peak", dist.TruncatedNormal(5, 1, low=0)) + duration_shed_after_peak_rv = DistributionalVariable( + "durtion_shed_after_peak", dist.TruncatedNormal(12, 3, low=0) + ) + log10_genome_per_inf_ind_rv = DistributionalVariable( + "log10_genome_per_inf_ind", dist.Normal(12, 2) + ) + mode_sigma_ww_site_rv = DistributionalVariable( + "mode_sigma_ww_site", dist.TruncatedNormal(1, 1, low=0) + ) + sd_log_sigma_ww_site_rv = DistributionalVariable( + "sd_log_sigma_ww_site", dist.TruncatedNormal(0, 0.693, low=0) + ) + mode_sd_ww_site_rv = DistributionalVariable( + "mode_sd_ww_site", dist.TruncatedNormal(0, 0.25, low=0) + ) + + autoreg_rt_subpop_rv = DistributionalVariable( + "autoreg_rt_subpop", dist.Beta(1, 4) + ) + sigma_rt_rv = DistributionalVariable( + "sigma_rt", dist.TruncatedNormal(0, 0.1, low=0) + ) + sigma_i_first_obs_rv = DistributionalVariable( + "sigma_i_first_obs", dist.TruncatedNormal(0, 0.5, low=0) + ) + offset_ref_logit_i_first_obs_rv = DistributionalVariable( + "offset_ref_logit_i_first_obs", dist.Normal(0, 0.25) + ) + offset_ref_log_rt_rv = DistributionalVariable( + "offset_ref_log_r_t", dist.Normal(0, 0.2) + ) + + ww_ml_produced_per_day = 227000 + max_shed_interval = 26 + """ + ).lstrip() + + +def write_synthetic_hew_model_dir( + model_dir: str | Path, + priors_path: str | Path | None = None, + overwrite: bool = False, + location: str = "CA", + disease: str = "COVID-19", + right_truncation_offset: int | None = None, + right_truncation_pmf: list[float] | None = None, + other_ed_visits_multiplier: float = 10.0, + delay_pmf_source: str = "ed", +) -> Path: + """ + Write synthetic H+E data in the production HEW ``model_dir`` layout. + + Parameters + ---------- + model_dir + Directory to create. The function writes ``priors.py``, + ``data/data_for_model_fit.json``, and ``data/model_params.json``. + priors_path + Optional path to an external priors file. If omitted, a minimal + synthetic-data priors file is written. + overwrite + Whether to replace an existing ``model_dir``. + location + Jurisdiction code to write in the production-shaped data. + disease + Disease label to write in the ED data. + right_truncation_offset + Offset used by the production ED right-truncation adjustment. Use + ``None`` for complete synthetic data. + right_truncation_pmf + Reporting-delay PMF. Defaults to ``[1.0]`` for complete reports. + other_ed_visits_multiplier + Multiplier used to create the production-required + ``other_ed_visits`` field from disease ED visits. This field is + included for schema compatibility and is not used by the HEW model. + delay_pmf_source + Source for ``inf_to_hosp_admit_pmf`` in ``model_params.json``. + ``"ed"`` uses the synthetic ED delay PMF. ``"hospital"`` uses the + example infection-to-admission PMF. + + Returns + ------- + pathlib.Path + Path to the created model directory. + """ + model_dir = Path(model_dir) + if model_dir.exists(): + if not overwrite: + raise FileExistsError( + f"{model_dir} already exists. Pass overwrite=True to replace it." + ) + shutil.rmtree(model_dir) + + data_dir = model_dir / "data" + data_dir.mkdir(parents=True) + + true_params = load_synthetic_true_parameters() + daily_ed = load_synthetic_daily_ed_visits() + weekly_hosp = load_synthetic_weekly_hospital_admissions() + hosp_delay = _as_float_list( + load_example_infection_admission_interval()["probability_mass"].to_numpy() + ) + ed_delay = _as_float_list(true_params["ed_visits"]["delay_pmf"]) + + if delay_pmf_source == "ed": + delay_pmf = ed_delay + elif delay_pmf_source == "hospital": + delay_pmf = hosp_delay + else: + raise ValueError("delay_pmf_source must be one of {'ed', 'hospital'}.") + + delay_loc, delay_scale = _lognormal_moment_match(delay_pmf) + right_truncation_pmf = ( + DEFAULT_RIGHT_TRUNCATION_PMF + if right_truncation_pmf is None + else _as_float_list(right_truncation_pmf) + ) + + ed_visits = daily_ed["ed_visits"].to_list() + data_for_model_fit = { + "loc_pop": [int(true_params["population"])], + "right_truncation_offset": right_truncation_offset, + "nssp_step_size": 1, + "nhsn_step_size": 7, + "nssp_training_data": { + "date": daily_ed["date"].to_list(), + "geo_value": [location] * len(daily_ed), + "observed_ed_visits": [float(x) for x in ed_visits], + "other_ed_visits": [ + float(max(1.0, round(x * other_ed_visits_multiplier))) + for x in ed_visits + ], + "data_type": ["train"] * len(daily_ed), + }, + "nssp_training_dates": daily_ed["date"].to_list(), + "nhsn_training_data": { + "weekendingdate": weekly_hosp["week_end"].to_list(), + "jurisdiction": [location] * len(weekly_hosp), + "hospital_admissions": [ + float(x) for x in weekly_hosp["weekly_hosp_admits"].to_list() + ], + "data_type": ["train"] * len(weekly_hosp), + }, + "nhsn_training_dates": weekly_hosp["week_end"].to_list(), + } + + model_params = { + "population_size": int(true_params["population"]), + "pop_fraction": [1.0], + "generation_interval_pmf": _as_float_list( + true_params["generation_interval_pmf"] + ), + "right_truncation_pmf": right_truncation_pmf, + "inf_to_hosp_admit_lognormal_loc": delay_loc, + "inf_to_hosp_admit_lognormal_scale": delay_scale, + "inf_to_hosp_admit_pmf": delay_pmf, + } + + with open(data_dir / "data_for_model_fit.json", "w") as f: + json.dump(data_for_model_fit, f, indent=2) + with open(data_dir / "model_params.json", "w") as f: + json.dump(model_params, f, indent=2) + + if priors_path is None: + (model_dir / "priors.py").write_text(_default_priors_text()) + else: + shutil.copyfile(priors_path, model_dir / "priors.py") + + metadata = { + "source": "pyrenew.datasets.write_synthetic_hew_model_dir", + "location": location, + "disease": disease, + "delay_pmf_source": delay_pmf_source, + "other_ed_visits_multiplier": other_ed_visits_multiplier, + } + with open(model_dir / "metadata.json", "w") as f: + json.dump(metadata, f, indent=2) + + return model_dir diff --git a/pyrenew/model/multisignal_model.py b/pyrenew/model/multisignal_model.py index 1a0f4b88..748835a6 100644 --- a/pyrenew/model/multisignal_model.py +++ b/pyrenew/model/multisignal_model.py @@ -157,6 +157,100 @@ def pad_observations( padding = jnp.full(pad_shape, jnp.nan) return jnp.concatenate([padding, obs], axis=axis) + def pad_aggregated_observations( + self, + obs: ArrayLike, + observation_name: str, + n_days_post_init: int, + obs_start_date: dt.date | dt.datetime | np.datetime64 | None, + axis: int = 0, + ) -> jnp.ndarray: + """ + Pad regular aggregated observations to the expected period sequence. + + User data for weekly observations usually contains only observed + weekly totals. This method prepends one NaN per unobserved reporting + period before the first observed period, including periods created by + the model's initialization window. The result is the dense array + expected by regular aggregated observation processes such as + ``PopulationCounts(aggregation="weekly", reporting_schedule="regular")``. + + Parameters + ---------- + obs + Observations in natural coordinates. Integer arrays are converted + to float so NaN padding can be represented. + observation_name + Name of the registered observation process whose reporting cadence + should be used for padding. + n_days_post_init + Number of modeled days after the initialization period. + obs_start_date + Date of the first observed day. Required for aggregated + observations that need calendar alignment. + axis + Axis along which to pad (typically 0 for time or reporting period). + + Returns + ------- + jnp.ndarray + Padded observations with leading NaN values. + + Raises + ------ + ValueError + If ``observation_name`` is unknown, if the observation is not + aggregated, if it uses an irregular reporting schedule, if a + calendar anchor is missing, or if ``obs`` is longer than the + model's reporting-period sequence. + """ + if observation_name not in self.observations: + raise ValueError( + f"Unknown observation '{observation_name}'. " + f"Available: {list(self.observations.keys())}" + ) + + observation = self.observations[observation_name] + aggregation = getattr(observation, "aggregation", "daily") + if aggregation == "daily": + raise ValueError( + "pad_aggregated_observations is only for aggregated " + f"observations; observation '{observation_name}' has " + "aggregation='daily'. Use pad_observations for daily " + "observations." + ) + + if getattr(observation, "reporting_schedule", "regular") != "regular": + raise ValueError( + "pad_aggregated_observations requires a regular reporting " + f"schedule; observation '{observation_name}' has " + f"reporting_schedule={observation.reporting_schedule!r}." + ) + + if obs_start_date is None: + raise ValueError( + "obs_start_date is required to pad aggregated observations " + f"for observation '{observation_name}'." + ) + + first_day_dow = self._resolve_first_day_dow(obs_start_date) + n_total = self.latent.n_initialization_points + n_days_post_init + n_periods = observation._n_periods(n_total, first_day_dow) + + obs = jnp.asarray(obs, dtype=float) + n_pre = n_periods - obs.shape[axis] + if n_pre < 0: + raise ValueError( + f"Observation '{observation_name}' has length {obs.shape[axis]} " + f"along axis {axis}, which exceeds the model reporting-period " + f"length {n_periods}." + ) + + pad_shape = list(obs.shape) + pad_shape[axis] = n_pre + padding = jnp.full(pad_shape, jnp.nan) + return jnp.concatenate([padding, obs], axis=axis) + def _resolve_first_day_dow( self, obs_start_date: dt.date | dt.datetime | np.datetime64 | None, diff --git a/test/integration/conftest.py b/test/integration/conftest.py index 9d9018cc..f0ad8bfd 100644 --- a/test/integration/conftest.py +++ b/test/integration/conftest.py @@ -28,7 +28,7 @@ from pyrenew.observation import NegativeBinomialNoise, PopulationCounts from pyrenew.randomvariable import DistributionalVariable from pyrenew.time import MMWR_WEEK -from test.test_helpers import fixed_ar1 +from test.test_helpers import fixed_ar1, fixed_differenced_ar1 @pytest.fixture(scope="module") @@ -404,7 +404,10 @@ def he_weekly_joint_ascertainment_model( gen_int_rv=DeterministicPMF("gen_int", gen_int_pmf), I0_rv=DistributionalVariable("I0", dist.Beta(1, 10)), log_rt_time_0_rv=DistributionalVariable("log_rt_time_0", dist.Normal(0.0, 0.5)), - single_rt_process=fixed_ar1(autoreg=0.9, innovation_sd=0.05), + single_rt_process=WeeklyTemporalProcess( + fixed_differenced_ar1(autoreg=0.5, innovation_sd=0.01), + start_dow=MMWR_WEEK, + ), ) builder.add_ascertainment(ascertainment) diff --git a/test/integration/test_population_infections_he_weekly.py b/test/integration/test_population_infections_he_weekly.py index 0f9aa407..cf876cd0 100644 --- a/test/integration/test_population_infections_he_weekly.py +++ b/test/integration/test_population_infections_he_weekly.py @@ -27,43 +27,6 @@ OBS_START_DATE = date(2023, 11, 5) -def _build_hospital_obs_on_period_grid( - model: MultiSignalModel, - weekly_values: jnp.ndarray, - first_day_dow: int, -) -> jnp.ndarray: - """ - Build a dense weekly-observation array on the model's period grid. - - Pads ``n_pre`` NaN values at the front for periods that precede the - first observed week (periods that overlap the initialization window - and any pre-observation gap). - - Parameters - ---------- - model : MultiSignalModel - Built model exposing ``latent.n_initialization_points``. - weekly_values : jnp.ndarray - Observed weekly hospital admissions, one per MMWR epiweek. - first_day_dow : int - Day-of-week index of element 0 of the shared daily axis. - - Returns - ------- - jnp.ndarray - Dense array of shape ``(n_periods,)`` with NaN for unobserved - periods and observed counts for periods covered by - ``weekly_values``. - """ - hosp = model.observations["hospital"] - n_init = model.latent.n_initialization_points - n_total = n_init + N_DAYS_FIT - offset = hosp._compute_period_offset(first_day_dow, hosp.start_dow) - n_periods = (n_total - offset) // hosp.aggregation_period - n_pre = n_periods - len(weekly_values) - return jnp.concatenate([jnp.full(n_pre, jnp.nan, dtype=jnp.float32), weekly_values]) - - class TestDataAssembly: """Verify synthetic data can be loaded and aligned to the weekly model.""" @@ -144,8 +107,11 @@ def test_weekly_obs_alignment( weekly_values = jnp.array( weekly_hosp["weekly_hosp_admits"].to_numpy(), dtype=jnp.float32 ) - hosp_obs = _build_hospital_obs_on_period_grid( - he_weekly_model, weekly_values, first_day_dow + hosp_obs = he_weekly_model.pad_aggregated_observations( + weekly_values, + observation_name="hospital", + n_days_post_init=N_DAYS_FIT, + obs_start_date=OBS_START_DATE, ) n_init = he_weekly_model.latent.n_initialization_points @@ -186,8 +152,11 @@ def test_weekly_hospital_and_daily_ed_sites( weekly_values = jnp.array( weekly_hosp["weekly_hosp_admits"].to_numpy(), dtype=jnp.float32 ) - hosp_obs = _build_hospital_obs_on_period_grid( - he_weekly_model, weekly_values, first_day_dow + hosp_obs = he_weekly_model.pad_aggregated_observations( + weekly_values, + observation_name="hospital", + n_days_post_init=N_DAYS_FIT, + obs_start_date=OBS_START_DATE, ) ed_obs = he_weekly_model.pad_observations( jnp.array(daily_ed["ed_visits"].to_numpy(), dtype=jnp.float32) diff --git a/test/integration/test_population_infections_he_weekly_joint_ascertainment.py b/test/integration/test_population_infections_he_weekly_joint_ascertainment.py index 53b34f91..7df51133 100644 --- a/test/integration/test_population_infections_he_weekly_joint_ascertainment.py +++ b/test/integration/test_population_infections_he_weekly_joint_ascertainment.py @@ -26,37 +26,6 @@ OBS_START_DATE = date(2023, 11, 5) -def _build_hospital_obs_on_period_grid( - model: MultiSignalModel, - weekly_values: jnp.ndarray, - first_day_dow: int, -) -> jnp.ndarray: - """ - Build a dense weekly-observation array on the model's period grid. - - Parameters - ---------- - model : MultiSignalModel - Built model exposing ``latent.n_initialization_points``. - weekly_values : jnp.ndarray - Observed weekly hospital admissions, one per MMWR epiweek. - first_day_dow : int - Day-of-week index of element 0 of the shared daily axis. - - Returns - ------- - jnp.ndarray - Dense array with NaN for unobserved pre-data periods. - """ - hosp = model.observations["hospital"] - n_init = model.latent.n_initialization_points - n_total = n_init + N_DAYS_FIT - offset = hosp._compute_period_offset(first_day_dow, hosp.start_dow) - n_periods = (n_total - offset) // hosp.aggregation_period - n_pre = n_periods - len(weekly_values) - return jnp.concatenate([jnp.full(n_pre, jnp.nan, dtype=jnp.float32), weekly_values]) - - class TestJointStructure: """Check that the fixture has the intended H+E joint structure.""" @@ -126,12 +95,14 @@ def test_weekly_obs_alignment( Weekly hospital admissions. """ model = he_weekly_joint_ascertainment_model - first_day_dow = model._resolve_first_day_dow(OBS_START_DATE) weekly_values = jnp.array( weekly_hosp["weekly_hosp_admits"].to_numpy(), dtype=jnp.float32 ) - hosp_obs = _build_hospital_obs_on_period_grid( - model, weekly_values, first_day_dow + hosp_obs = model.pad_aggregated_observations( + weekly_values, + observation_name="hospital", + n_days_post_init=N_DAYS_FIT, + obs_start_date=OBS_START_DATE, ) assert int((~jnp.isnan(hosp_obs)).sum()) == len(weekly_hosp) @@ -161,12 +132,14 @@ def test_joint_ascertainment_sites_are_sampled_once( Daily ED visits. """ model = he_weekly_joint_ascertainment_model - first_day_dow = model._resolve_first_day_dow(OBS_START_DATE) weekly_values = jnp.array( weekly_hosp["weekly_hosp_admits"].to_numpy(), dtype=jnp.float32 ) - hosp_obs = _build_hospital_obs_on_period_grid( - model, weekly_values, first_day_dow + hosp_obs = model.pad_aggregated_observations( + weekly_values, + observation_name="hospital", + n_days_post_init=N_DAYS_FIT, + obs_start_date=OBS_START_DATE, ) ed_obs = model.pad_observations( jnp.array(daily_ed["ed_visits"].to_numpy(), dtype=jnp.float32) @@ -185,6 +158,7 @@ def test_joint_ascertainment_sites_are_sampled_once( n_total = model.latent.n_initialization_points + N_DAYS_FIT hospital = model.observations["hospital"] + first_day_dow = model._resolve_first_day_dow(OBS_START_DATE) offset = hospital._compute_period_offset(first_day_dow, hospital.start_dow) n_periods = (n_total - offset) // hospital.aggregation_period @@ -192,6 +166,9 @@ def test_joint_ascertainment_sites_are_sampled_once( assert trace["he_ascertainment_eta"]["value"].shape == (2,) assert trace["he_ascertainment_hospital"]["type"] == "deterministic" assert trace["he_ascertainment_ed_visits"]["type"] == "deterministic" + assert trace["log_rt_single_weekly"]["type"] == "deterministic" + assert trace["log_rt_single_weekly"]["value"].shape[-1] == 1 + assert trace["log_rt_single_weekly"]["value"].shape[0] < n_total assert trace["hospital_predicted"]["value"].shape == (n_periods,) assert trace["hospital_predicted_daily"]["value"].shape == (n_total,) assert trace["ed_visits_predicted"]["value"].shape == (n_total,) diff --git a/test/integration/test_population_infections_he_weekly_rt.py b/test/integration/test_population_infections_he_weekly_rt.py index 613c41c2..619edb45 100644 --- a/test/integration/test_population_infections_he_weekly_rt.py +++ b/test/integration/test_population_infections_he_weekly_rt.py @@ -34,39 +34,6 @@ WEEK_START_DOW = 6 -def _build_hospital_obs_on_period_grid( - model: MultiSignalModel, - weekly_values: jnp.ndarray, - first_day_dow: int, -) -> jnp.ndarray: - """ - Build a dense weekly-observation array on the model's period grid. - - Parameters - ---------- - model : MultiSignalModel - Built model exposing ``latent.n_initialization_points``. - weekly_values : jnp.ndarray - Observed weekly hospital admissions, one per MMWR epiweek. - first_day_dow : int - Day-of-week index of element 0 of the shared daily axis. - - Returns - ------- - jnp.ndarray - Dense array of shape ``(n_periods,)`` with NaN for unobserved - periods and observed counts for periods covered by - ``weekly_values``. - """ - hosp = model.observations["hospital"] - n_init = model.latent.n_initialization_points - n_total = n_init + N_DAYS_FIT - offset = hosp._compute_period_offset(first_day_dow, hosp.start_dow) - n_periods = (n_total - offset) // hosp.aggregation_period - n_pre = n_periods - len(weekly_values) - return jnp.concatenate([jnp.full(n_pre, jnp.nan, dtype=jnp.float32), weekly_values]) - - def _expected_n_weekly(model: MultiSignalModel, first_day_dow: int) -> int: """ Expected number of weekly R(t) samples for calendar-week alignment. @@ -114,8 +81,11 @@ def test_weekly_rt_recorded( weekly_values = jnp.array( weekly_hosp["weekly_hosp_admits"].to_numpy(), dtype=jnp.float32 ) - hosp_obs = _build_hospital_obs_on_period_grid( - he_weekly_rt_model, weekly_values, first_day_dow + hosp_obs = he_weekly_rt_model.pad_aggregated_observations( + weekly_values, + observation_name="hospital", + n_days_post_init=N_DAYS_FIT, + obs_start_date=OBS_START_DATE, ) ed_obs = he_weekly_rt_model.pad_observations( jnp.array(daily_ed["ed_visits"].to_numpy(), dtype=jnp.float32) @@ -178,13 +148,14 @@ def fitted_model( MultiSignalModel Model with MCMC results attached. """ - first_day_dow = he_weekly_rt_model._resolve_first_day_dow(OBS_START_DATE) - weekly_values = jnp.array( weekly_hosp["weekly_hosp_admits"].to_numpy(), dtype=jnp.float32 ) - hosp_obs = _build_hospital_obs_on_period_grid( - he_weekly_rt_model, weekly_values, first_day_dow + hosp_obs = he_weekly_rt_model.pad_aggregated_observations( + weekly_values, + observation_name="hospital", + n_days_post_init=N_DAYS_FIT, + obs_start_date=OBS_START_DATE, ) ed_obs = he_weekly_rt_model.pad_observations( diff --git a/test/test_pyrenew_builder.py b/test/test_pyrenew_builder.py index 9a1dd421..e81b5c54 100644 --- a/test/test_pyrenew_builder.py +++ b/test/test_pyrenew_builder.py @@ -756,6 +756,128 @@ def test_pad_observations_prepends_nans(self, simple_builder): # Integer input should be converted to float assert jnp.issubdtype(padded.dtype, jnp.floating) + def test_pad_aggregated_observations_rejects_daily_observations( + self, simple_builder + ): + """Daily observations should use pad_observations instead.""" + model = simple_builder.build() + + with pytest.raises(ValueError, match="Use pad_observations"): + model.pad_aggregated_observations( + jnp.array([1, 2, 3]), + observation_name="hospital", + n_days_post_init=3, + obs_start_date=None, + ) + + def test_pad_aggregated_observations_weekly_prepends_period_nans(self): + """Weekly regular observations are padded on the reporting-period axis.""" + builder = _coherence_builder( + single_rt_process=fixed_ar1(autoreg=0.9, innovation_sd=0.05), + observations=[_weekly_hosp_counts()], + ) + model = builder.build() + n_days_post_init = 28 + obs_start_date = _obs_date_for_dow( + target_first_day_dow=6, + n_init=model.latent.n_initialization_points, + ) + + padded = model.pad_aggregated_observations( + jnp.array([10, 20, 30]), + observation_name="hospital", + n_days_post_init=n_days_post_init, + obs_start_date=obs_start_date, + ) + + n_total = model.latent.n_initialization_points + n_days_post_init + hospital = model.observations["hospital"] + first_day_dow = model._resolve_first_day_dow(obs_start_date) + n_periods = hospital._n_periods(n_total, first_day_dow) + n_pre = n_periods - 3 + + assert padded.shape == (n_periods,) + assert jnp.all(jnp.isnan(padded[:n_pre])) + assert jnp.array_equal(padded[n_pre:], jnp.array([10.0, 20.0, 30.0])) + + def test_pad_aggregated_observations_unknown_observation_raises( + self, simple_builder + ): + """Unknown observation names raise an informative error.""" + model = simple_builder.build() + + with pytest.raises(ValueError, match="Unknown observation"): + model.pad_aggregated_observations( + jnp.array([1, 2, 3]), + observation_name="missing", + n_days_post_init=3, + obs_start_date=None, + ) + + def test_pad_aggregated_observations_rejects_irregular_reporting_schedule(self): + """Aggregated padding only supports regular reporting schedules.""" + builder = _coherence_builder( + single_rt_process=fixed_ar1(autoreg=0.9, innovation_sd=0.05), + observations=[ + PopulationCounts( + name="hospital", + ascertainment_rate_rv=DeterministicVariable("hospital_ihr", 0.01), + delay_distribution_rv=DeterministicPMF( + "hospital_delay", jnp.array([1.0]) + ), + noise=PoissonNoise(), + aggregation="weekly", + reporting_schedule="irregular", + start_dow=MMWR_WEEK, + ) + ], + ) + model = builder.build() + + with pytest.raises(ValueError, match="requires a regular reporting schedule"): + model.pad_aggregated_observations( + jnp.array([1, 2, 3]), + observation_name="hospital", + n_days_post_init=28, + obs_start_date=date(2024, 1, 7), + ) + + def test_pad_aggregated_observations_weekly_requires_obs_start_date(self): + """Calendar-aligned aggregated padding requires obs_start_date.""" + builder = _coherence_builder( + single_rt_process=fixed_ar1(autoreg=0.9, innovation_sd=0.05), + observations=[_weekly_hosp_counts()], + ) + model = builder.build() + + with pytest.raises(ValueError, match="obs_start_date is required"): + model.pad_aggregated_observations( + jnp.array([1, 2, 3]), + observation_name="hospital", + n_days_post_init=28, + obs_start_date=None, + ) + + def test_pad_aggregated_observations_rejects_too_many_periods(self): + """Observed period arrays cannot exceed the model period count.""" + builder = _coherence_builder( + single_rt_process=fixed_ar1(autoreg=0.9, innovation_sd=0.05), + observations=[_weekly_hosp_counts()], + ) + model = builder.build() + obs_start_date = _obs_date_for_dow( + target_first_day_dow=6, + n_init=model.latent.n_initialization_points, + ) + + with pytest.raises(ValueError, match="exceeds the model reporting-period"): + model.pad_aggregated_observations( + jnp.arange(10), + observation_name="hospital", + n_days_post_init=14, + obs_start_date=obs_start_date, + ) + @pytest.mark.parametrize( "obs_start_dow, expected", [ diff --git a/test/test_synthetic_hew_export.py b/test/test_synthetic_hew_export.py new file mode 100644 index 00000000..a5ad7ac3 --- /dev/null +++ b/test/test_synthetic_hew_export.py @@ -0,0 +1,121 @@ +""" +Unit tests for exporting synthetic H+E data to a HEW model directory. +""" + +import json +from pathlib import Path + +import pytest + +from pyrenew.datasets import write_synthetic_hew_model_dir + + +def test_write_synthetic_hew_model_dir_creates_expected_files(tmp_path: Path): + """Exporter writes the model directory files expected by HEW fit helpers.""" + model_dir = write_synthetic_hew_model_dir(tmp_path / "synthetic_he") + + assert (model_dir / "priors.py").exists() + assert (model_dir / "metadata.json").exists() + assert (model_dir / "data" / "data_for_model_fit.json").exists() + assert (model_dir / "data" / "model_params.json").exists() + + +def test_data_for_model_fit_has_production_he_schema(tmp_path: Path): + """Exported data JSON has NSSP and NHSN training-data sections.""" + model_dir = write_synthetic_hew_model_dir(tmp_path / "synthetic_he") + with open(model_dir / "data" / "data_for_model_fit.json") as f: + data = json.load(f) + + assert data["loc_pop"] == [39512223] + assert data["right_truncation_offset"] is None + assert data["nssp_step_size"] == 1 + assert data["nhsn_step_size"] == 7 + + nssp = data["nssp_training_data"] + assert set(nssp) == { + "date", + "geo_value", + "observed_ed_visits", + "other_ed_visits", + "data_type", + } + assert len(nssp["date"]) == 126 + assert len(nssp["observed_ed_visits"]) == 126 + + nhsn = data["nhsn_training_data"] + assert set(nhsn) == { + "weekendingdate", + "jurisdiction", + "hospital_admissions", + "data_type", + } + assert len(nhsn["weekendingdate"]) == 18 + assert len(nhsn["hospital_admissions"]) == 18 + + +def test_model_params_has_production_he_schema(tmp_path: Path): + """Exported model params JSON has fields required by PyrenewHEWParam.""" + model_dir = write_synthetic_hew_model_dir(tmp_path / "synthetic_he") + with open(model_dir / "data" / "model_params.json") as f: + params = json.load(f) + + assert set(params) == { + "population_size", + "pop_fraction", + "generation_interval_pmf", + "right_truncation_pmf", + "inf_to_hosp_admit_lognormal_loc", + "inf_to_hosp_admit_lognormal_scale", + "inf_to_hosp_admit_pmf", + } + assert params["population_size"] == 39512223 + assert params["pop_fraction"] == [1.0] + assert params["right_truncation_pmf"] == [1.0] + assert len(params["generation_interval_pmf"]) == 7 + assert len(params["inf_to_hosp_admit_pmf"]) == 12 + assert params["inf_to_hosp_admit_lognormal_scale"] > 0 + + +def test_model_params_can_use_hospital_delay(tmp_path: Path): + """Exporter can write the example hospital delay PMF instead of ED delay.""" + model_dir = write_synthetic_hew_model_dir( + tmp_path / "synthetic_he", + delay_pmf_source="hospital", + ) + with open(model_dir / "data" / "model_params.json") as f: + params = json.load(f) + + assert len(params["inf_to_hosp_admit_pmf"]) > 12 + + +def test_invalid_delay_pmf_source_raises(tmp_path: Path): + """Exporter rejects unknown delay PMF source names.""" + with pytest.raises(ValueError, match="delay_pmf_source"): + write_synthetic_hew_model_dir( + tmp_path / "synthetic_he", + delay_pmf_source="unknown", + ) + + +def test_overwrite_guard(tmp_path: Path): + """Exporter refuses to replace an existing model directory by default.""" + model_dir = write_synthetic_hew_model_dir(tmp_path / "synthetic_he") + + with pytest.raises(FileExistsError): + write_synthetic_hew_model_dir(model_dir) + + write_synthetic_hew_model_dir(model_dir, overwrite=True) + assert (model_dir / "data" / "data_for_model_fit.json").exists() + + +def test_can_copy_external_priors_file(tmp_path: Path): + """Exporter can copy a caller-provided priors file.""" + priors_path = tmp_path / "custom_priors.py" + priors_path.write_text("# custom priors\n") + + model_dir = write_synthetic_hew_model_dir( + tmp_path / "synthetic_he", + priors_path=priors_path, + ) + + assert (model_dir / "priors.py").read_text() == "# custom priors\n" diff --git a/uv.lock b/uv.lock index d455ebaf..bd9ae7a0 100644 --- a/uv.lock +++ b/uv.lock @@ -1756,6 +1756,7 @@ dev = [ { name = "pytest-cov" }, { name = "ruff" }, { name = "scipy" }, + { name = "xarray" }, ] [package.metadata] @@ -1786,6 +1787,7 @@ dev = [ { name = "pytest-cov", specifier = ">=6.3.0" }, { name = "ruff", specifier = ">=0.15.0" }, { name = "scipy", specifier = ">=1.16.1" }, + { name = "xarray", specifier = ">=2026.4.0" }, ] [[package]]