"""Scaling dimensions of the 3D O(N) CFTs -- numberdb.org/T475.

Run with SageMath or passagemath and the NumberDB Python package:

    sage -pip install numberdb
    sage -python generate.py                  # verify all stored entries
    sage -python checks.py                    # independent checks, no writes
    sage -python generate.py --fill           # fill the existing draft

A private draft requires its author's NUMBERDB_API_KEY even for verification.
Alternatively --key-stdin reads the key from standard input. --fill only sends
entries to T475; it does not offer, review or make the draft public.

This is a transcription, not a bootstrap solver. It preserves the conservative
bounds of Chester et al., arXiv:1912.03324v2 equations (40)-(42), and
arXiv:2011.14647v2 equations (21)-(23). These are conditional numerical bounds,
not statistical confidence intervals; the family records them as measured.
The narrower starred interpolation estimates are deliberately not used.

The range is the complete set phi,s,t for XY (N=2) and Heisenberg (N=3).
All operators are spatial scalars. Their internal representations are vector,
singlet and symmetric traceless rank two. The identity is excluded from s.
The uncertainty, not the count of printed decimal places, controls accuracy.
Strings are returned verbatim, with no floating-point arithmetic or padding.
"""
import os
import sys
import numberdb.sage as numberdb

# Centre, radius, citation and equation. Each radius is the source's own.
DATA = {
    'xy': {
        'phi': ('0.519088', '0.000022', 'Chester2020', 40),
        's': ('1.51136', '0.00022', 'Chester2020', 41),
        't': ('1.23629', '0.00011', 'Chester2020', 42),
    },
    'heisenberg': {
        'phi': ('0.518936', '0.000067', 'Chester2021', 21),
        's': ('1.59488', '0.00081', 'Chester2021', 22),
        't': ('1.20954', '0.00032', 'Chester2021', 23),
    },
}


class ScalingDimensionsON(numberdb.Generator):
    table = 'T475'
    parameters = ('class', 'operator')
    type = 'R'
    # Minimum supported precision; strings retain every source digit and radius.
    digits = 3
    rigour = 'measured'
    files = ('generate.py', 'checks.py', 'check.py', 'source-evidence.md',
             'sources.json')

    def enumerate(self):
        for universality in ('xy', 'heisenberg'):
            for operator in ('phi', 's', 't'):
                yield {'class': universality, 'operator': operator}

    def value(self, params, digits):
        centre, radius, citation, equation = DATA[params['class']][params['operator']]
        return {
            'number': centre + ' +/- ' + radius,
            'comment': 'Conservative bootstrap interval from equation (%s) '
                       'of CITE{%s}.' % (equation, citation),
        }


if __name__ == '__main__':
    if '--key-stdin' in sys.argv or os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
        client = numberdb.Client(api_key=sys.stdin.read().strip())
    else:
        client = numberdb.Client()
    generator = ScalingDimensionsON()
    if '--fill' in sys.argv or os.environ.get('NUMBERDB_PUBLISH') == '1':
        outcome = generator.publish(client=client, assisted_by='codex-cli',
                                    message='Transcribe six conservative O(2) and O(3) bootstrap intervals.')
        print(outcome)
    result = generator.verify(sample=None, client=client)
    print(result)
    sys.exit(0 if result.ok else 1)
