"""Запустить во встроенном Python после полевых серий. FEMM-решатель не вызывается."""
import sys,json,os
ROOT=globals().get('TVV_ROOT','')
if not ROOT:raise ValueError('Задайте TVV_ROOT')
if ROOT in sys.path:sys.path.remove(ROOT)
sys.path.insert(0,ROOT)
for module in ('run_record','physics','field_analysis'):
    sys.modules.pop(module,None)
from run_record import start,finish,sha,save_json
from field_analysis import angular,comparison,identities,integrals
paths=globals().get('TVV_FIELD_RUNS',[])
if not paths:raise ValueError('Задайте TVV_FIELD_RUNS — список каталогов завершённых расчётов')
folder,record=start(ROOT,globals().get('TVV_OUTPUT_ROOT',ROOT+'/runs'),'analysis',
    ['run_field_analysis.py','field_analysis.py','physics.py','run_record.py'], 'verified analysis of native field series')
rows=[];sources=[];common={};targets=None
try:
    for path in paths:
        with open(path+'/receipt.json') as f:receipt=json.loads(f.read())
        if receipt['status']!='passed_field_identities_not_convergence':raise ValueError('Серия не завершена: '+path)
        for prefix,files in [('/snapshot/',receipt['inputs_and_programs']),('/',receipt['outputs'])]:
            for name,expected in files.items():
                if sha(path+prefix+name)!=expected:raise ValueError('Неверный SHA-256: '+path+prefix+name)
        for name in ['machine.json','winding.json','geometry.py','build.py','physics.py','rotor-bh.json','stator-bh.json','stator-cross-bh.json','model-scope.json','current-mapping.json']:
            digest=receipt['inputs_and_programs'][name]
            if name in common and common[name]!=digest:raise ValueError('Разные физические входы/версии: '+name)
            common[name]=digest
        with open(path+'/snapshot/field-plan.json') as f:plan=json.loads(f.read())
        if targets is not None and targets!=plan['convergence_targets']:raise ValueError('Разные критерии сходимости')
        targets=plan['convergence_targets']
        with open(path+'/results.json') as f:values=json.loads(f.read())
        if not all(identities(row,plan['acceptance'])['passed'] for row in values):raise ValueError('Не выполнено тождество')
        rows.extend(values);sources.append({'path':path,'receipt_sha256':sha(path+'/receipt.json')})
    indexed={r['case']['id']:r for r in rows}
    if len(indexed)!=len(rows):raise ValueError('Одна точка включена повторно')
    result={'sources':sources,'targets':targets,'scope':'educational model, no factory validation','cases':len(rows)}
    if 'state-2' in indexed:
        base=indexed['state-2'];result['comparisons_to_state_2']={}
        for row in rows:
            if row['case']['series'] in ['mesh','boundary','input-sensitivity']:
                result['comparisons_to_state_2'][row['case']['id']]=comparison(base,row,targets)
    angles=[r for r in rows if r['case']['series']=='angular']
    if angles:result['angular']=angular(angles)
    save_json(folder+'/results.json',result)
    save_json(folder+'/source-results.json',rows)
    record['sources']=sources;finish(folder,record,'passed_analysis_not_course_release')
except Exception as error:
    record['error']=str(error);finish(folder,record,'failed');raise
print('TVV_ANALYSIS_RESULT',folder)
