"""Независимая FEMM-карта: полные угловые серии и отдельные контрольные точки."""
import sys,json,os
ROOT=globals().get('TVV_ROOT','')
if ROOT in sys.path:sys.path.remove(ROOT)
sys.path.insert(0,ROOT)
for module in ('run_record','geometry','physics','build','field_session'):sys.modules.pop(module,None)
from run_record import start,finish,save_json,sha
from field_session import FieldSession
names=['run_magnetic_map.py','field_session.py','run_record.py','geometry.py','physics.py','build.py','machine.json','winding.json','rotor-bh.json','stator-bh.json','magnetic-map-plan.json','model-scope.json']
part=globals().get('TVV_PART',0);parts=globals().get('TVV_PARTS',1)
resume=globals().get('TVV_RESUME_DIR','')
if parts<1 or not 0<=part<parts:raise ValueError('Неверная часть')
if resume:
    folder=resume
    with open(folder+'/receipt.json') as f:record=json.loads(f.read())
    if (record['part'],record['parts'])!=(part,parts):raise ValueError('Изменён состав части')
    for name,digest in record['inputs_and_programs'].items():
        if sha(ROOT+'/'+name)!=digest or sha(folder+'/snapshot/'+name)!=digest:raise ValueError('Изменена версия карты: '+name)
else:
    folder,record=start(ROOT,globals().get('TVV_OUTPUT_ROOT',ROOT+'/runs'),'map',names,'nonlinear electrical map from new FEMM solutions')
    record.update(part=part,parts=parts,points={})
def load(name):
    with open(folder+'/snapshot/'+name+'.json') as f:return json.loads(f.read())
plan=load('magnetic-map-plan');machine=load('machine');winding=load('winding')['rows']
session=FieldSession(globals(),machine,winding,{'rotor':load('rotor-bh'),'stator':load('stator-bh')},folder,plan['mesh'])
rows=[]
try:
    # Sort by angle so all assigned currents reuse the same independently built template.
    cases=[]
    for point in plan['points']:
        for k in range(point['angles']):cases.append({'point':point,'angle_index':k,'theta':360*k/point['angles']})
    cases.sort(key=lambda c:(c['theta'],c['point']['id']))
    for index,case in enumerate(cases):
        if index%parts!=part:continue
        stem=case['point']['id']+'-a%03d'%case['angle_index']
        if stem in record['points']:
            for name,digest in record['points'][stem].items():
                if sha(folder+'/'+name)!=digest:raise ValueError('Повреждена точка карты')
            with open(folder+'/'+stem+'.json') as f:row=json.loads(f.read())
        else:
            record['active_case']=stem;save_json(folder+'/receipt.json',record)
            row=session.solve(case['theta'],case['point']['currents_A'],stem)
            row.update(point=case['point']['id'],purpose=case['point']['purpose'],angle_index=case['angle_index'])
            save_json(folder+'/'+stem+'.json',row)
            record['points'][stem]={stem+ext:sha(folder+'/'+stem+ext) for ext in ('.json','.fem','.ans')}
            save_json(folder+'/receipt.json',record);print('TVV_MAP_POINT',stem)
        rows.append(row)
    save_json(folder+'/results.json',rows);record['checks']={'solutions':len(rows),'field_energy_identity':True}
    finish(folder,record,'passed_map_field_points_not_interpolation_validation')
except Exception as error:record['error']=str(error);save_json(folder+'/results.json',rows);finish(folder,record,'failed');raise
print('TVV_MAP_RESULT',folder,len(rows))
