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