Current task: —

E-022b-valley-analysis.py

Experiments: E-022b · script updated 08-19-2026

E-022b-valley.csv — 87.2 KB, updated 08-19-2026

← prev page 2 of 10 · 500/page · 4600 rows next →
# azlogK
502 4 39.000 2.045604
503 4 39.050 2.053064
504 4 39.100 2.059821
505 4 39.150 2.065292
506 4 39.200 2.069024
507 4 39.250 2.070706
508 4 39.300 2.070178
509 4 39.350 2.067439
510 4 39.400 2.062656
511 4 39.450 2.056179
512 4 39.500 2.048535
513 4 39.550 2.040427
514 4 39.600 2.032694
515 4 39.650 2.026251
516 4 39.700 2.021989
517 4 39.750 2.020649
518 4 39.800 2.022681
519 4 39.850 2.028117
520 4 39.900 2.036478
521 4 39.950 2.046741
522 4 40.000 2.057377
523 4 40.050 2.066438
524 4 40.100 2.071674
525 4 40.150 2.070652
526 4 40.200 2.060854
527 4 40.250 2.039738
528 4 40.300 2.004759
529 4 40.350 1.953357
530 4 40.400 1.882915
531 4 40.450 1.790693
532 4 40.500 1.673766
533 4 40.550 1.528990
534 4 40.600 1.353071
535 4 40.650 1.142960
536 4 40.700 0.897061
537 4 40.750 0.618548
538 4 40.800 0.323390
539 4 40.850 0.055412
540 4 40.900 -0.104219
541 4 40.950 -0.079987
542 4 41.000 0.114790
543 4 41.050 0.394949
544 4 41.100 0.687803
545 4 41.150 0.958276
546 4 41.200 1.194826
547 4 41.250 1.396029
548 4 41.300 1.564063
549 4 41.350 1.702104
550 4 41.400 1.813392
551 4 41.450 1.900951
552 4 41.500 1.967545
553 4 41.550 2.015723
554 4 41.600 2.047890
555 4 41.650 2.066367
556 4 41.700 2.073448
557 4 41.750 2.071443
558 4 41.800 2.062687
559 4 41.850 2.049528
560 4 41.900 2.034284
561 4 41.950 2.019153
562 4 42.000 2.006104
563 4 42.050 1.996744
564 4 42.100 1.992186
565 4 42.150 1.992957
566 4 42.200 1.998946
567 4 42.250 2.009428
568 4 42.300 2.023134
569 4 42.350 2.038375
570 4 42.400 2.053166
571 4 42.450 2.065353
572 4 42.500 2.072704
573 4 42.550 2.072976
574 4 42.600 2.063941
575 4 42.650 2.043390
576 4 42.700 2.009108
577 4 42.750 1.958832
578 4 42.800 1.890194
579 4 42.850 1.800655
580 4 42.900 1.687444
581 4 42.950 1.547516
582 4 43.000 1.377605
583 4 43.050 1.174533
584 4 43.100 0.936217
585 4 43.150 0.664451
586 4 43.200 0.371827
587 4 43.250 0.095691
588 4 43.300 -0.088629
589 4 43.350 -0.097708
590 4 43.400 0.074444
591 4 43.450 0.348637
592 4 43.500 0.645555
593 4 43.550 0.923782
594 4 43.600 1.168619
595 4 43.650 1.377384
596 4 43.700 1.551807
597 4 43.750 1.694940
598 4 43.800 1.810029
599 4 43.850 1.900169
600 4 43.900 1.968251
601 4 43.950 2.017012
602 4 44.000 2.049108
603 4 44.050 2.067191
604 4 44.100 2.073959
605 4 44.150 2.072165
606 4 44.200 2.064587
607 4 44.250 2.053935
608 4 44.300 2.042703
609 4 44.350 2.032999
610 4 44.400 2.026362
611 4 44.450 2.023651
612 4 44.500 2.025008
613 4 44.550 2.029935
614 4 44.600 2.037461
615 4 44.650 2.046357
616 4 44.700 2.055346
617 4 44.750 2.063291
618 4 44.800 2.069325
619 4 44.850 2.072921
620 4 44.900 2.073919
621 4 44.950 2.072507
622 4 45.000 2.069169
623 4 45.050 2.064606
624 4 45.100 2.059638
625 4 45.150 2.055087
626 4 45.200 2.051667
627 4 45.250 2.049890
628 4 45.300 2.049993
629 4 45.350 2.051916
630 4 45.400 2.055326
631 4 45.450 2.059680
632 4 45.500 2.064313
633 4 45.550 2.068538
634 4 45.600 2.071748
635 4 45.650 2.073490
636 4 45.700 2.073521
637 4 45.750 2.071841
638 4 45.800 2.068687
639 4 45.850 2.064505
640 4 45.900 2.059897
641 4 45.950 2.055540
642 4 46.000 2.052092
643 4 46.050 2.050088
644 4 46.100 2.049858
645 4 46.150 2.051462
646 4 46.200 2.054668
647 4 46.250 2.058981
648 4 46.300 2.063701
649 4 46.350 2.068027
650 4 46.400 2.071162
651 4 46.450 2.072424
652 4 46.500 2.071348
653 4 46.550 2.067760
654 4 46.600 2.061830
655 4 46.650 2.054086
656 4 46.700 2.045390
657 4 46.750 2.036863
658 4 46.800 2.029748
659 4 46.850 2.025235
660 4 46.900 2.024236
661 4 46.950 2.027183
662 4 47.000 2.033858
663 4 47.050 2.043330
664 4 47.100 2.053988
665 4 47.150 2.063658
666 4 47.200 2.069780
667 4 47.250 2.069583
668 4 47.300 2.060218
669 4 47.350 2.038851
670 4 47.400 2.002687
671 4 47.450 1.948956
672 4 47.500 1.874857
673 4 47.550 1.777481
674 4 47.600 1.653744
675 4 47.650 1.500354
676 4 47.700 1.313941
677 4 47.750 1.091605
678 4 47.800 0.832576
679 4 47.850 0.542649
680 4 47.900 0.244489
681 4 47.950 -0.005720
682 4 48.000 -0.118652
683 4 48.050 -0.038215
684 4 48.100 0.190489
685 4 48.150 0.477261
686 4 48.200 0.761020
687 4 48.250 1.016076
688 4 48.300 1.235475
689 4 48.350 1.419750
690 4 48.400 1.571959
691 4 48.450 1.695788
692 4 48.500 1.794903
693 4 48.550 1.872757
694 4 48.600 1.932560
695 4 48.650 1.977274
696 4 48.700 2.009590
697 4 48.750 2.031878
698 4 48.800 2.046095
699 4 48.850 2.053689
700 4 48.900 2.055501
701 4 48.950 2.051700
702 4 49.000 2.041776
703 4 49.050 2.024576
704 4 49.100 1.998394
705 4 49.150 1.961067
706 4 49.200 1.910083
707 4 49.250 1.842641
708 4 49.300 1.755697
709 4 49.350 1.645971
710 4 49.400 1.509952
711 4 49.450 1.343980
712 4 49.500 1.144586
713 4 49.550 0.909536
714 4 49.600 0.640732
715 4 49.650 0.351401
716 4 49.700 0.080387
717 4 49.750 -0.095278
718 4 49.800 -0.093494
719 4 49.850 0.086945
720 4 49.900 0.364746
721 4 49.950 0.661986
722 4 50.000 0.938891
723 4 50.050 1.181678
724 4 50.100 1.388092
725 4 50.150 1.560076
726 4 50.200 1.700806
727 4 50.250 1.813619
728 4 50.300 1.901685
729 4 50.350 1.967959
730 4 50.400 2.015223
731 4 50.450 2.046162
732 4 50.500 2.063426
733 4 50.550 2.069677
734 4 50.600 2.067594
735 4 50.650 2.059853
736 4 50.700 2.049035
737 4 50.750 2.037518
738 4 50.800 2.027321
739 4 50.850 2.019964
740 4 50.900 2.016360
741 4 50.950 2.016785
742 4 51.000 2.020922
743 4 51.050 2.027987
744 4 51.100 2.036892
745 4 51.150 2.046427
746 4 51.200 2.055413
747 4 51.250 2.062824
748 4 51.300 2.067874
749 4 51.350 2.070059
750 4 51.400 2.069186
751 4 51.450 2.065371
752 4 51.500 2.059029
753 4 51.550 2.050847
754 4 51.600 2.041740
755 4 51.650 2.032779
756 4 51.700 2.025096
757 4 51.750 2.019757
758 4 51.800 2.017616
759 4 51.850 2.019171
760 4 51.900 2.024439
761 4 51.950 2.032889
762 4 52.000 2.043429
763 4 52.050 2.054469
764 4 52.100 2.064018
765 4 52.150 2.069814
766 4 52.200 2.069435
767 4 52.250 2.060390
768 4 52.300 2.040173
769 4 52.350 2.006272
770 4 52.400 1.956151
771 4 52.450 1.887205
772 4 52.500 1.796688
773 4 52.550 1.681651
774 4 52.600 1.538893
775 4 52.650 1.365026
776 4 52.700 1.156828
777 4 52.750 0.912392
778 4 52.800 0.634315
779 4 52.850 0.337593
780 4 52.900 0.064928
781 4 52.950 -0.101970
782 4 53.000 -0.083387
783 4 53.050 0.110801
784 4 53.100 0.393817
785 4 53.150 0.690203
786 4 53.200 0.963530
787 4 53.250 1.201887
788 4 53.300 1.403845
789 4 53.350 1.571673
790 4 53.400 1.708669
791 4 53.450 1.818221
792 4 53.500 1.903528
793 4 53.550 1.967579
794 4 53.600 2.013203
795 4 53.650 2.043139
796 4 53.700 2.060088
797 4 53.750 2.066747
798 4 53.800 2.065790
799 4 53.850 2.059814
800 4 53.900 2.051240
801 4 53.950 2.042185
802 4 54.000 2.034327
803 4 54.050 2.028807
804 4 54.100 2.026182
805 4 54.150 2.026466
806 4 54.200 2.029234
807 4 54.250 2.033780
808 4 54.300 2.039283
809 4 54.350 2.044954
810 4 54.400 2.050151
811 4 54.450 2.054434
812 4 54.500 2.057581
813 4 54.550 2.059563
814 4 54.600 2.060496
815 4 54.650 2.060572
816 4 54.700 2.059998
817 4 54.750 2.058939
818 4 54.800 2.057486
819 4 54.850 2.055652
820 4 54.900 2.053388
821 4 54.950 2.050632
822 4 55.000 2.047359
823 4 55.050 2.043639
824 4 55.100 2.039681
825 4 55.150 2.035845
826 4 55.200 2.032626
827 4 55.250 2.030590
828 4 55.300 2.030276
829 4 55.350 2.032067
830 4 55.400 2.036054
831 4 55.450 2.041920
832 4 55.500 2.048869
833 4 55.550 2.055614
834 4 55.600 2.060421
835 4 55.650 2.061196
836 4 55.700 2.055591
837 4 55.750 2.041096
838 4 55.800 2.015108
839 4 55.850 1.974963
840 4 55.900 1.917930
841 4 55.950 1.841174
842 4 56.000 1.741695
843 4 56.050 1.616271
844 4 56.100 1.461443
845 4 56.150 1.273663
846 4 56.200 1.049907
847 4 56.250 0.789530
848 4 56.300 0.499224
849 4 56.350 0.204493
850 4 56.400 -0.032745
851 4 56.450 -0.119317
852 4 56.500 -0.007672
853 4 56.550 0.244238
854 4 56.600 0.544220
855 4 56.650 0.835050
856 4 56.700 1.094088
857 4 56.750 1.315776
858 4 56.800 1.501084
859 4 56.850 1.653046
860 4 56.900 1.775120
861 4 56.950 1.870667
862 4 57.000 1.942846
863 4 57.050 1.994648
864 4 57.100 2.028989
865 4 57.150 2.048782
866 4 57.200 2.056989
867 4 57.250 2.056630
868 4 57.300 2.050719
869 4 57.350 2.042136
870 4 57.400 2.033444
871 4 57.450 2.026669
872 4 57.500 2.023116
873 4 57.550 2.023268
874 4 57.600 2.026817
875 4 57.650 2.032812
876 4 57.700 2.039913
877 4 57.750 2.046660
878 4 57.800 2.051732
879 4 57.850 2.054150
880 4 57.900 2.053406
881 4 57.950 2.049531
882 4 58.000 2.043095
883 4 58.050 2.035141
884 4 58.100 2.027057
885 4 58.150 2.020367
886 4 58.200 2.016478
887 4 58.250 2.016402
888 4 58.300 2.020504
889 4 58.350 2.028357
890 4 58.400 2.038712
891 4 58.450 2.049608
892 4 58.500 2.058568
893 4 58.550 2.062822
894 4 58.600 2.059498
895 4 58.650 2.045764
896 4 58.700 2.018890
897 4 58.750 1.976259
898 4 58.800 1.915320
899 4 58.850 1.833527
900 4 58.900 1.728257
901 4 58.950 1.596753
902 4 59.000 1.436127
903 4 59.050 1.243564
904 4 59.100 1.017017
905 4 59.150 0.757155
906 4 59.200 0.472230
907 4 59.250 0.188454
908 4 59.300 -0.036028
909 4 59.350 -0.119299
910 4 59.400 -0.021057
911 4 59.450 0.209683
912 4 59.500 0.491814
913 4 59.550 0.771651
914 4 59.600 1.026073
915 4 59.650 1.248311
916 4 59.700 1.438287
917 4 59.750 1.598183
918 4 59.800 1.730669
919 4 59.850 1.838241
920 4 59.900 1.923014
921 4 59.950 1.986659
922 6 14.000 1.139002
923 6 14.050 0.609653
924 6 14.100 0.078270
925 6 14.150 -0.047285
926 6 14.200 0.388495
927 6 14.250 0.944376
928 6 14.300 1.409275
929 6 14.350 1.764809
930 6 14.400 2.028178
931 6 14.450 2.217183
932 6 14.500 2.346145
933 6 14.550 2.426747
934 6 14.600 2.469266
935 6 14.650 2.483461
936 6 14.700 2.478982
937 6 14.750 2.465186
938 6 14.800 2.450359
939 6 14.850 2.440572
940 6 14.900 2.438759
941 6 14.950 2.444588
942 6 15.000 2.455326
943 6 15.050 2.467256
944 6 15.100 2.477045
945 6 15.150 2.482618
946 6 15.200 2.483470
947 6 15.250 2.480510
948 6 15.300 2.475577
949 6 15.350 2.470796
950 6 15.400 2.467911
951 6 15.450 2.467801
952 6 15.500 2.470317
953 6 15.550 2.474468
954 6 15.600 2.478857
955 6 15.650 2.482182
956 6 15.700 2.483629
957 6 15.750 2.483055
958 6 15.800 2.480960
959 6 15.850 2.478265
960 6 15.900 2.475987
961 6 15.950 2.474908
962 6 16.000 2.475343
963 6 16.050 2.477079
964 6 16.100 2.479492
965 6 16.150 2.481791
966 6 16.200 2.483283
967 6 16.250 2.483591
968 6 16.300 2.482743
969 6 16.350 2.481135
970 6 16.400 2.479379
971 6 16.450 2.478094
972 6 16.500 2.477706
973 6 16.550 2.478316
974 6 16.600 2.479691
975 6 16.650 2.481355
976 6 16.700 2.482767
977 6 16.750 2.483493
978 6 16.800 2.483347
979 6 16.850 2.482431
980 6 16.900 2.481095
981 6 16.950 2.479810
982 6 17.000 2.479013
983 6 17.050 2.478966
984 6 17.100 2.479669
985 6 17.150 2.480877
986 6 17.200 2.482183
987 6 17.250 2.483159
988 6 17.300 2.483494
989 6 17.350 2.483094
990 6 17.400 2.482105
991 6 17.450 2.480862
992 6 17.500 2.479782
993 6 17.550 2.479221
994 6 17.600 2.479362
995 6 17.650 2.480154
996 6 17.700 2.481329
997 6 17.750 2.482496
998 6 17.800 2.483262
999 6 17.850 2.483369
1000 6 17.900 2.482768
1001 6 17.950 2.481646

E-022b-valley.json — 3.5 KB, updated 08-19-2026

JSON sidecar (click to expand)
{
  "experiment": "E-022b",
  "task": "2.10 analysis: K-diagonal valleys + mass concentration",
  "script": "research/numerics/scripts/E-022b-valley-analysis.py",
  "checks": {
    "V1_valleys_at_gamma": true,
    "V2_mass_concentrated": true,
    "V4_fit_quality": true
  },
  "key_values": {
    "4": {
      "valley_depth": 2.1593140478568413,
      "logK_at_gamma": -0.106956845297883,
      "logK_at_midpoints": 2.0523572025589583,
      "mass_frac_pm0.1": 0.6338714893637662,
      "uniform_expectation": 0.09000000000000001,
      "mass_ratio_vs_uniform": 7.043016548486291,
      "within_bin_meanlogw": {
        "z10-60_d0.0-0.1": 0.05321233524569066,
        "z10-60_d0.3-0.7": -1.7997896503200193,
        "z120-200_d0.0-0.1": 0.10247759965464488,
        "z120-200_d0.3-0.7": -1.7570525979064509
      },
      "elapsed_s": 2.9
    },
    "6": {
      "valley_depth": 2.5087271936533595,
      "logK_at_gamma": -0.04029578260580941,
      "logK_at_midpoints": 2.46843141104755,
      "mass_frac_pm0.1": 0.6986826134175042,
      "uniform_expectation": 0.09000000000000001,
      "mass_ratio_vs_uniform": 7.7631401490833785,
      "within_bin_meanlogw": {
        "z10-60_d0.0-0.1": -0.10145611105454076,
        "z10-60_d0.3-0.7": -2.4097253102207548,
        "z120-200_d0.0-0.1": 0.029192545882919238,
        "z120-200_d0.3-0.7": -2.314439077156247
      },
      "elapsed_s": 5.1
    },
    "8": {
      "valley_depth": 2.7352201581877043,
      "logK_at_gamma": 0.030554703235580436,
      "logK_at_midpoints": 2.7657748614232847,
      "mass_frac_pm0.1": 0.7251109123178877,
      "uniform_expectation": 0.09000000000000001,
      "mass_ratio_vs_uniform": 8.056787914643197,
      "within_bin_meanlogw": {
        "z10-60_d0.0-0.1": -0.1389960979715335,
        "z10-60_d0.3-0.7": -2.7392603482112916,
        "z120-200_d0.0-0.1": -0.20043183472111312,
        "z120-200_d0.3-0.7": -2.6451890375288283
      },
      "elapsed_s": 7.9
    },
    "10": {
      "valley_depth": 2.8706885758089333,
      "logK_at_gamma": 0.11948603922925684,
      "logK_at_midpoints": 2.9901746150381903,
      "mass_frac_pm0.1": 0.7251715332604941,
      "uniform_expectation": 0.09000000000000001,
      "mass_ratio_vs_uniform": 8.057461480672156,
      "within_bin_meanlogw": {
        "z10-60_d0.0-0.1": -0.07371951844373904,
        "z10-60_d0.3-0.7": -2.974563705268562,
        "z120-200_d0.0-0.1": -0.2233480705431757,
        "z120-200_d0.3-0.7": -2.8788847145178686
      },
      "elapsed_s": 11.4
    },
    "12": {
      "valley_depth": 2.9442229398281423,
      "logK_at_gamma": 0.22834844487190686,
      "logK_at_midpoints": 3.172571384700049,
      "mass_frac_pm0.1": 0.7241062961289328,
      "uniform_expectation": 0.09000000000000001,
      "mass_ratio_vs_uniform": 8.045625512543698,
      "within_bin_meanlogw": {
        "z10-60_d0.0-0.1": -0.1831905054381875,
        "z10-60_d0.3-0.7": -3.1605455546413452,
        "z120-200_d0.0-0.1": -0.35321115246295404,
        "z120-200_d0.3-0.7": -3.0663074224107776
      },
      "elapsed_s": 15.5
    },
    "V4_saturation_fit": {
      "Delta_inf": 3.3338697242432738,
      "c": 4.760242352939846,
      "max_resid": 0.03176880509994007
    },
    "valley_depths": {
      "4.0": 2.1593140478568413,
      "6.0": 2.5087271936533595,
      "8.0": 2.7352201581877043,
      "10.0": 2.8706885758089333,
      "12.0": 2.9442229398281423
    }
  },
  "elapsed_seconds": 59.7,
  "timestamp_utc": "2026-08-19T17:37:47.138364+00:00"
}

Source code

Python script (click to expand)
"""E-022b — task 2.10 analysis stage: reproducing-kernel valley structure
and gamma-mass concentration (post-hoc analysis of E-022).

E-022 found the coarse weak metric flat (O3) but a persistent mass
elevation near the true zeros. This script resolves the mechanism:

  K_a(z,z) := Re(b_z^H v), v the bordered (L^2_0) Galerkin solution of
  T_a v = e^{-izx} — the diagonal of the model-space reproducing kernel.

Measurements (a in {4,6,8,10,12}, theta=pi):
  V1. valley depth: Delta(a) = mean log K at gamma-gap midpoints minus
      mean log K at gammas, z-grid step 0.05 in [14,60).
  V2. mass concentration: fraction of the E-022 spectral mass within
      +/-0.1 of a true zero (vs uniform-lattice expectation).
  V3. artifact control: mean log w vs distance-to-nearest-gamma WITHIN
      z-bins (controls the gamma-density/weight-trend confound that
      naive O5 fails — shifted-gamma null test showed the raw O5
      elevation is mostly distributional).
  V4. saturation model: Delta(a) ~ Delta_inf - c/a fit.

Outputs: research/numerics/data/E-022b-valley.csv (+ .json)
"""
import importlib.util
import json
import sys
import time
from datetime import datetime, timezone
from pathlib import Path

import mpmath as mp
import numpy as np
import scipy.linalg

REPO = Path(__file__).resolve().parents[3]
DATA = REPO / "research" / "numerics" / "data"
CSV = DATA / "E-022b-valley.csv"
JSON = DATA / "E-022b-valley.json"

spec = importlib.util.spec_from_file_location(
    "E16", Path(__file__).with_name("E-016-herglotz-fine-structure.py"))
E16 = importlib.util.module_from_spec(spec)
spec.loader.exec_module(E16)                     # runs the e^20 sieve
sys.path.insert(0, str(Path(__file__).parent))
from prime_backend_v2 import PrimeBackendV2       # noqa: E402

H = E16.H_MAIN
LAM = E16.LAM_SHIFT
A_LIST = (4.0, 6.0, 8.0, 10.0, 12.0)
XN = E16.XN


def collect_t_points(a, h):
    n_elem = int(round(2 * a / h))
    pts = []

    def add_quad(lo, hi, peak):
        n_lo = int(np.ceil(np.exp(lo)))
        n_hi = int(np.floor(np.exp(hi)))
        if n_hi - n_lo > 64:
            for aa, bb in ((lo, peak), (peak, hi)):
                if bb - aa > 0:
                    mid, half = 0.5 * (aa + bb), 0.5 * (bb - aa)
                    pts.extend(mid + half * XN)
            return
        segs = sorted({lo, peak, hi} |
                      {float(np.log(n))
                       for n in range(max(n_lo, 2), n_hi + 1)
                       if lo < np.log(n) < hi})
        for p0, p1 in zip(segs, segs[1:]):
            if p1 - p0 > 0:
                mid, half = 0.5 * (p0 + p1), 0.5 * (p1 - p0)
                pts.extend(mid + half * XN)

    for k in range(n_elem):
        if k == 0:
            add_quad(0.0, h, 0.0)
        else:
            add_quad((k - 1) * h, (k + 1) * h, k * h)
    return np.array(pts)


def make_K1(a):
    x, h, Q, M, _b = E16.build(a, H)
    n = Q.shape[0]
    mc = np.zeros(n)
    mc[0] = 2 * h / 3
    mc[1] = h / 6
    tc = Q[:, 0] - LAM * mc
    u1 = scipy.linalg.solve_toeplitz((tc, tc), np.ones(n))
    s1 = u1.sum()

    def K1(z):
        bz = E16.hat_FT(np.array([z]), h)[0] * np.exp(-1j * z * x)
        u0 = scipy.linalg.solve_toeplitz((tc, tc), bz)
        v = u0 - (u0.sum() / s1) * u1
        return float(np.real(np.conj(bz) @ v))

    return K1


def main() -> int:
    if JSON.exists() and "--force" not in sys.argv:
        print(f"cached: {JSON} (use --force to recompute)")
        return 0
    t0 = time.time()

    tq = np.concatenate([collect_t_points(a, H) for a in A_LIST])
    be = PrimeBackendV2(tq)
    be.load_cache(DATA / "E-022-backend-cache.npz")
    E16._BUILD.clear()
    E16.prime_sum_vec = be.prime_sum

    mp.mp.dps = 30
    gam_all = np.array([float(mp.zetazero(k).imag)
                        for k in range(1, 201)])
    gam = gam_all[gam_all <= 280]

    # E-022 weights
    import csv as csvmod
    data = {}
    with open(DATA / "E-022-spectral-measure.csv") as f:
        for r in csvmod.DictReader(f):
            data.setdefault(float(r["a"]), []).append(
                (float(r["z_k"]), float(r["w_k"])))

    zgrid = np.arange(14.0, 60.0, 0.05)
    gsel = gam_all[(gam_all >= 14) & (gam_all < 60)]
    mids = (gsel[:-1] + gsel[1:]) / 2
    idxg = np.round((gsel - 14) / 0.05).astype(int)
    idxm = np.round((mids - 14) / 0.05).astype(int)

    per_a = {}
    grid_rows = []
    for a in A_LIST:
        ta = time.time()
        K1 = make_K1(a)
        lg = np.array([np.log(K1(z)) for z in zgrid])
        dip = float(lg[idxm].mean() - lg[idxg].mean())
        # mass fraction within +-0.1 of gamma (full window to 280)
        z = np.array([p[0] for p in data[a]])
        w = np.array([p[1] for p in data[a]])
        m = z <= 280
        zm, wm = z[m], w[m]
        idx = np.clip(np.searchsorted(gam, zm), 1, len(gam) - 1)
        d = np.minimum(np.abs(zm - gam[idx - 1]), np.abs(zm - gam[idx]))
        frac = float(wm[d <= 0.1].sum() / wm.sum())
        unif = float(0.2 * len(gam) / 280.0)
        # V3: within-z-bin mean log w by distance bin
        lw = np.log(wm)
        bins = {}
        for lo, hi in ((10, 60), (120, 200)):
            sel = (zm >= lo) & (zm < hi)
            for blo, bhi in ((0.0, 0.1), (0.3, 0.7)):
                s2 = sel & (d >= blo) & (d < bhi)
                if s2.sum() > 3:
                    bins[f"z{lo}-{hi}_d{blo}-{bhi}"] = float(lw[s2].mean())
        per_a[f"{a:g}"] = {
            "valley_depth": dip,
            "logK_at_gamma": float(lg[idxg].mean()),
            "logK_at_midpoints": float(lg[idxm].mean()),
            "mass_frac_pm0.1": frac,
            "uniform_expectation": unif,
            "mass_ratio_vs_uniform": frac / unif,
            "within_bin_meanlogw": bins,
            "elapsed_s": round(time.time() - ta, 1),
        }
        print(f"a={a:g}: dip={dip:.4f}, massfrac={frac:.4f} "
              f"({per_a[f'{a:g}']['elapsed_s']}s)", flush=True)
        for zz, ll in zip(zgrid, lg):
            grid_rows.append((a, zz, ll))

    # V4: saturation fit Delta(a) = Dinf - c/a
    av = np.array(A_LIST)
    dv = np.array([per_a[f"{a:g}"]["valley_depth"] for a in A_LIST])
    Afit = np.vstack([np.ones_like(av), -1.0 / av]).T
    Dinf, c = np.linalg.lstsq(Afit, dv, rcond=None)[0]
    resid = dv - (Dinf - c / av)
    print(f"V4: Delta_inf = {Dinf:.3f}, c = {c:.3f}, "
          f"max fit resid {np.abs(resid).max():.4f}", flush=True)

    checks = {
        "V1_valleys_at_gamma": bool(np.all(dv > 1.5)),
        "V2_mass_concentrated": bool(np.all(
            [per_a[f"{a:g}"]["mass_frac_pm0.1"] > 0.5 for a in A_LIST])),
        "V4_fit_quality": bool(np.abs(resid).max() < 0.1),
    }

    with open(CSV, "w", newline="") as f:
        wcsv = csvmod.writer(f)
        wcsv.writerow(["a", "z", "logK"])
        for a, zz, ll in grid_rows:
            wcsv.writerow([f"{a:g}", f"{zz:.3f}", f"{ll:.6f}"])

    meta = {
        "experiment": "E-022b",
        "task": "2.10 analysis: K-diagonal valleys + mass concentration",
        "script": "research/numerics/scripts/E-022b-valley-analysis.py",
        "checks": checks,
        "key_values": {**per_a,
                       "V4_saturation_fit": {"Delta_inf": float(Dinf),
                                             "c": float(c),
                                             "max_resid": float(
                                                 np.abs(resid).max())},
                       "valley_depths": dict(zip([str(a) for a in av],
                                                 dv.tolist()))},
        "elapsed_seconds": round(time.time() - t0, 1),
        "timestamp_utc": datetime.now(timezone.utc).isoformat(),
    }
    JSON.write_text(json.dumps(meta, indent=2))
    print(f"wrote {CSV.name}, {JSON.name}; elapsed "
          f"{meta['elapsed_seconds']}s", flush=True)
    return 0 if all(checks.values()) else 1


if __name__ == "__main__":
    sys.exit(main())