Ë
    ôEºjBH  ã                  óR  — d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	 ddl
Z
 e
j                  d«       ddlmZ ddlZddlZddlmZ ddlmc mZ dd	lmZ dd
lmZmZmZmZ ddlmZ edz  Z dZ!ejD                  fdd„Z#dd„Z$dd„Z%dd„Z&dd„Z'dd„Z(dd„Z)e*dk(  r e)«        yy)a*  Diagnostic weak-label GNN training for CAD risk and deformation fields.

This command deliberately requires an opt-in flag. The current two runs have
unvalidated registration, point-dilated defect areas, and one defect class.
The result is a pipeline/training diagnostic, never a production model.
é    )ÚannotationsN)ÚPath)ÚAnyÚAgg)ÚTensoré   )ÚPhysicsConstrainedRiskGNN)ÚROOTÚfixed_physical_normalizeÚgraph_inputsÚsplit_embedded_units)Úseed_everythingzresults/models/weak_gnng      >@c                ó0   — t        j                  | |¬«      S )N)Údtype)ÚtorchÚ	as_tensor)Úvaluer   s     úmodels/train_weak_gnn.pyÚ_tensorr      s   € Ü�?‰?˜5¨Ô.Ð.ó    c                ó¬  — t        j                  | d   t         j                  «      j                  «       }t        j                  | d   t        «      }t        j                  | d   «      j                  t        «      }t        |«      \  }}t        j                  t        |«      t        «      }|j                  «       }d| d   | d   fd| d   | d	   ffD ]M  \  }}}	t        d
d«      D ]8  }
|› |
d›�}||v sŒ|j                  |«      }|	|
d
z
     sŒ)||
d
z
     ||<   d||<   Œ: ŒO ||z  }t        j                  ||d«      j                  t         j                  «      }t        |d   t        j                  |«      |«      d   }t        j                  ||j                  t         j                  «      |j                  t         j                  «      g«      S )zFUse interpolated heater values while retaining observed/imputed flags.Ú	process_xÚprocess_feature_validÚprocess_feature_namesu   ìƒ�ë¶€ì˜¨ë�„Úheater_top_cÚheater_top_imputedu   í•˜ë¶€ì˜¨ë�„Úheater_bottom_cÚheater_bottom_imputedr   é   Ú02dTr   N)ÚnpÚasarrayÚfloat32ÚcopyÚboolÚastypeÚstrr   ÚzerosÚlenÚtolistÚrangeÚindexÚwherer   Úconcatenate)ÚdataÚrawÚobservedÚnamesÚ
base_namesÚunitsÚimputedÚprefixÚfilledÚfilled_maskÚzoneÚkeyr,   ÚusableÚvaluesÚ
normalizeds                   r   Ú_process_vectorr>   #   s«  € ä
�*‰*�T˜+Ñ&¬¯
©
Ó
3×
8Ñ
8Ó
:€CÜ�z‰z˜$Ð6Ñ7¼Ó>€HÜ�J‰J�tÐ3Ñ4Ó5×<Ñ<¼SÓA€EÜ,¨UÓ3Ñ€J�Ü�h‰h”s˜3“x¤Ó&€GØ×"Ñ"Ó$€Jà	˜˜nÑ-¨tÐ4HÑ/IÐJØ	˜Ð/Ñ0°$Ð7NÑ2OÐPó(Ñ#ˆ�˜ô ˜!˜R–LˆDØ�H˜T #˜JÐ'ˆCØ�jÒ Ø"×(Ñ(¨Ó-�Ø˜t a™xÓ(Ø!'¨¨q©Ñ!1�C˜‘JØ%)�G˜E’Nñ !ð	(ð ˜Ñ€FÜ�X‰X�f˜c 1Ó%×,Ñ,¬R¯Z©ZÓ8€FÜ)¨&°©,¼¿
¹
À:Ó8NÐPUÓVÐWXÑY€JÜ�>‰>˜: x§¡´r·z±zÓ'BÀGÇNÁNÔSU×S]ÑS]ÓD^Ð_Ó`Ð`r   c                 ój  — t        t        «       d„ ¬«      } t        t        dz  j	                  d«      «      }|st        d«      ‚g }|D ]‚  }t        j                  |d¬«      5 }|j                  D �ci c]  }|||   “Œ
 }}d d d «       d   j                  d	   | d
   k7  rt        |j                  › d�«      ‚|j                  ||f«       Œ„ t        j                  | d   | d   j                  t        j                  «      gd¬«      }t        j                  |D �cg c]  }|‘Œ c}d	¬«      }	| d
   }
t        j                  t        t!        |«      «      D �cg c]  }| d   ||
z  z   ‘Œ c}d¬«      }t        j                  |D �cg c]  }| d   ‘Œ	 c}d	¬«      j                  t        j                  «      }|d d …d	fxx   dz  cc<   t        j"                  t        j$                  t!        |«      «      |
«      }t        j&                  |D ��cg c]  \  }}t)        |«      ‘Œ c}}«      }t        j                  |D ��cg c]  \  }}|d   d d …df   ‘Œ c}}«      j                  t        j                  «      }t        j                  |D ��cg c]  \  }}|d   d d …df   ‘Œ c}}«      j                  t        j                  «      }t        j                  |D ��cg c]
  \  }}|d   ‘Œ c}}«      j                  t        j                  «      }t        j                  |D ��cg c]
  \  }}|d   ‘Œ c}}«      j                  t        j                  «      }g }t+        ||D ��cg c]!  \  }}t-        |d   j/                  «       «      ‘Œ# c}}«      D �]  \  \  }}}t        j0                  |d   t        j                  «      }t        j0                  |d   t        j                  «      }|j                  |t3        t!        |«      «      t3        |t4        k\  j7                  «       «      t3        t        j8                  |«      t4        k\  j7                  «       «      t;        |j                  «       «      t;        t        j8                  |«      j                  «       «      dœ«       �Œ t        j<                  |t4         t4        «      t4        z  }t        j<                  |d	t4        «      t4        z  }|D ��cg c]!  \  }}t-        |d   j/                  «       «      ‘Œ# }}}t        t?        |«      «      }t        j0                  |D �cg c]  }|jA                  |«      ‘Œ c}t        jB                  «      }i d|	“d|“d|“d|“d|“d|“d|“d |“d!|“d"|“d#|“d$|“d%|D ��cg c]!  \  }}t-        |d   j/                  «       «      ‘Œ# c}}“d|d	   d   d   “d&|
“d'|“S c c}w # 1 sw Y   �ŒexY wc c}w c c}w c c}w c c}}w c c}}w c c}}w c c}}w c c}}w c c}}w c c}}w c c}w c c}}w )(Nc                ó   — | d   S )NÚnodes© )Úitems    r   Ú<lambda>z$load_training_data.<locals>.<lambda>=   s   € °°g²r   )r:   zdata_processed/pairedz*_cad_ply_targets.npzzIAt least one paired target file is required for the diagnostic experimentF)Úallow_pickleÚ
cad_pos_mmr   rA   z0: target nodes do not match the finest CAD graphÚxÚmaskr   )ÚaxisÚ
edge_indexÚ	edge_attrg     @�@Úweak_defect_probabilityÚweak_defect_maskÚcad_to_scan_normal_residual_mmÚcad_to_scan_distance_mmÚrun_id)ÚrunrA   Údistance_nodes_at_or_above_capÚsigned_nodes_outside_capÚraw_max_distance_mmÚraw_max_abs_signed_mmÚdefect_classÚnodeÚedgeÚbatchÚprocessÚriskÚrisk_binaryÚsignedÚ	magnitudeÚclass_labelsÚclass_namesÚpathsÚrunsÚnodes_per_runÚdeformation_clip_by_run)"Úmaxr   Úsortedr
   ÚglobÚRuntimeErrorr!   ÚloadÚfilesÚshapeÚnameÚappendr.   r&   r#   r+   r)   ÚrepeatÚarangeÚstackr>   Úzipr'   rC   r"   ÚintÚDEFORMATION_SCALE_MMÚsumÚabsÚfloatÚclipÚsetr,   Úint64)Úgraphra   rb   Úpathr0   r:   rC   Únode_oneÚ_rW   Úcountr,   rX   rK   rY   rZ   r[   r\   r]   r^   rd   rQ   ÚdistanceÚnormalÚclassesr`   r   Úlabelss                               r   Úload_training_datarƒ   <   sª  € Ü”“Ñ$>Ô?€EÜ”DÐ2Ñ2×8Ñ8Ð9PÓQÓR€EÙÜÐfÓgÐgØ€DÛˆÜ�W‰W�T¨Õ.°#Ø-0¯YªYÓ7©Y c�C˜˜S™‘M¨YˆDÐ7÷ /à�Ñ×#Ñ# AÑ&¨%°©.Ò8Ü $§)¡) Ð,\Ð]Ó^Ð^Ø�‰�T˜4�LÕ!ð ô �~‰~˜u S™z¨5°©=×+?Ñ+?ÄÇ
Á
Ó+KÐLÐSTÔU€HÜ�>‰>©TÓ2©T¨š8¨TÑ2¸Ô;€DØ�'‰N€EÜ�>‰>ÌEÔRUÐVZÓR[ÔL\Ó]ÑL\À5˜5 Ñ.°¸±Ó>ÐL\Ñ]ÐdeÔf€DÜ—‘¹DÓA¹D°q  kÓ 2¸DÑAÈÔJ×QÑQÔRT×R\ÑR\Ó]€IØŠa�ˆdƒO�vÑƒOÜ�I‰I”b—i‘i¤ D£	Ó*¨EÓ2€EÜ�h‰h¹TÔB¹T±'°!°Tœ¨Õ-¸TÒBÓC€GÜ�>‰>ÑPTÔUÑPTÁWÀQÈ˜4Ð 9Ñ:º1¸a¸4Ó@ÐPTÒUÓV×]Ñ]Ô^`×^hÑ^hÓi€DÜ—.‘.ÑPTÔ!UÑPTÁWÀQÈ $Ð'9Ñ":º1¸a¸4Ó"@ÐPTÒ!UÓV×]Ñ]Ô^`×^hÑ^hÓi€KÜ�^‰^ÑSWÔXÑSWÉÈÈ4˜TÐ"BÓCÐSWÒXÓY×`Ñ`Ôac×akÑakÓl€FÜ—‘ÉtÔTÉtÁGÀAÀt Ð%>Ó ?ÈtÒTÓU×\Ñ\Ô]_×]gÑ]gÓh€IØ ÐÜ˜dÉtÔ$TÉtÁGÀAÀt¤S¨¨h©×)<Ñ)<Ó)>Õ%?ÈtÒ$T×U‰‰	ˆˆD�3Ü—:‘:˜dÐ#<Ñ=¼r¿z¹zÓJˆÜ—‘˜DÐ!AÑBÄBÇJÁJÓOˆØ×&Ñ&Ø¤¤S¨£]Ó!3Ü.1°8Ô?SÑ3S×2XÑ2XÓ2ZÓ.[Ü(+¬R¯V©V°F«^Ô?SÑ-S×,XÑ,XÓ,ZÓ([Ü#(¨¯©«Ó#8Ü%*¬2¯6©6°&«>×+=Ñ+=Ó+?Ó%@ñ(
ö 	ð Vô �W‰W�VÔ2Ð2Ô4HÓIÔL`Ñ`€FÜ—‘˜	 1Ô&:Ó;Ô>RÑR€IÙ?CÔD¹t±G°A°tŒs�4˜Ñ'×,Ñ,Ó.Õ/¸t€GÑDÜœ˜W›Ó&€KÜ�Z‰Z¹wÓG¹w°e˜×*Ñ*¨5Õ1¸wÑGÌÏÉÓR€FðØ�ðØ˜dðØ$/°ðØ<CÀUðà�7ðà" Dðà*7¸ðð 	�&ðð & yðð 3AÀ&ðð 	�{ð	ð %,¨Uð	ð 5;ÑgkÔ<lÑgkÑ\cÐ\]Ð_c¼SÀÀhÁ×ATÑATÓAVÕ=WÐgkÒ<lð	ð
 	�d˜1‘g˜a‘j Ñ.ðð
 1@Àðð 	"Ð#:ðð ùòC 8÷ /Ñ.üò 3ùâ]ùÚAùó CùÛUùÛ!UùÛXùÛTùã$Tùó EùâGùó
 =msf   Á#W$Á2WÁ?W$Ä	W1ÅW6ÆW;ÈX 
ÉX
ÊX
ËX
Ì'X
Í(&XÓ9&X$Õ	X*Ö"&X/
×W$×$W.	c                ó®   — t        j                  | «      }dd||z  j                  «       z  dz   |j                  «       |j                  «       z   dz   z  z
  S )Nr   é   )r   Úsigmoidrt   )ÚlogitÚtargetÚprobabilitys      r   Úsoft_dice_lossrŠ   o   sP   € Ü—-‘- Ó&€KØ��[ 6Ñ)×.Ñ.Ó0Ñ0°1Ñ4¸¿¹Ó9JÈVÏZÉZË\Ñ9YÐ\]Ñ9]Ñ^Ñ^Ð^r   c                ó˜  — t        «        t        «       }t        |d   «      }t        |d   t        j                  «      }t        |d   «      }t        |d   t        j                  «      }t        |d   «      }t        |d   «      }t        |d   «      }	t        |d   «      }
t        |d	   «      }t        |d
   t        j                  «      }t        |j                  d   |j                  d   |j                  d   t        dt        |d   «      «      «      }t        j                  j                  |j                  «       |d¬«      }|	j                  «       j                  d«      }t        |	«      |z
  |z  j                  d¬«      }|\  }}||k  }g }t        d«      }d}d }t        |d   «      dkD  rdnd}t!        | «      D �]   }|j#                  «        |j%                  d¬«        ||||||«      }t'        j(                  |d   ||¬«      }t+        |d   |«      }t'        j,                  |d   |
d¬«      }|t'        j,                  |d   |d¬«      z   }t        j.                  |d   «      }|||      |||      z
  j1                  «       j3                  «       }|d   ||      |d   ||      z
  j1                  «       j3                  «       } t        |d   «      dkD  rt'        j4                  |d   |«      }!n|d   j                  «       dz  }!||z   d|z  z   d|z  z   d | z  z   |!z   }"|"j7                  «        |j9                  «        t        |"j;                  «       «      }#|#|k  rT|#}|dz   }|j=                  «       j?                  «       D �$�%ci c]$  \  }$}%|$|%j;                  «       jA                  «       “Œ& }}$}%|jC                  |dz   |#t        |j;                  «       «      t        |j;                  «       «      t        |j;                  «       «      t        |j;                  «       «      t        | j;                  «       «      t        |!j;                  «       «      d!œ«       �Œ£ |€tE        d"«      ‚|jG                  |«       |jI                  «        t        jJ                  «       5   ||||||«      }t        j.                  |d   «      }|d#k\  }&|&|	jM                  «       z  j                  «       jO                  «       }'|&|	jM                  «       z  j                  «       jO                  «       }(d$|'z  t        d|&j                  «       jO                  «       |	j                  «       jO                  «       z   «      z  })|'t        d|(«      z  }*t        jP                  |d   jS                  «       |d   z
  «      j                  «       jO                  «       }+g },|d%   }-tU        |d&   «      D �]-  \  }.}/tW        |.|-z  |.dz   |-z  «      }0|&|0   }1|	|0   jM                  «       }2|1|2z  j                  «       jO                  «       }3|1|2z  j                  «       jO                  «       }4|,jC                  |/tY        |2j                  «       «      tY        |1j                  «       «      |3t        d|4«      z  d$|3z  t        d|1j                  «       jO                  «       |2j                  «       jO                  «       z   «      z  t        ||0   j                  «       «      d'œ«       �Œ0 	 d d d «       tZ        j]                  dd¬(«       tZ        d)z  }5t        j^                  |j=                  «       d*|d   g d+¢t        |d&   «      › d,�d-œ|5«       ta        ||«       i d.d/“d0d*“d1d*“d2d3“d4d5“d&|d&   “d6t        |d&   «      “d7|d   “d8|“d9d:“d;| “d<|“d=|d   d>   “d?|“d@|dA   d>   “dB|“dC*“),tb        dD|dE   dFœdG+dHdIgdJdKgte        |5jg                  th        «      «      dLdMg|dNœ
¥}6tZ        dOz  jk                  tm        jn                  |6d*d$¬P«      dQ¬R«       dSjq                  dT„ |,D «       «      }7tZ        dUz  jk                  dVt        |d&   «      › dW|6d?   dX›dY|*dX›dZ|)dX›d[ts        jt                  |«      › d\|7› d]�dQ¬R«       |6S c c}%}$w # 1 sw Y   �Œ¤xY w)^NrW   rX   rK   rY   rZ   r[   r\   r]   r^   r_   r   r`   gñhãˆµøä>)ÚlrÚweight_decayéÈ   )re   Úinfr   Útrained_multiclassÚ!unavailable_single_observed_classT)Úset_to_noneÚ
risk_logit)Ú
pos_weightÚsigned_normal_deformationg333333Ã?)ÚdeltaÚdeformation_magnitudeÚdefect_type_logitsgš™™™™™É?g{®Gáz„?g{®Gázt?)ÚepochÚtotalÚbceÚ	dice_lossÚdeformationÚrisk_graph_smoothnessÚdeformation_graph_smoothnessÚ	type_losszNo training epoch completedg      à?r…   rc   rb   )rQ   Útarget_positive_nodesÚpredicted_positive_nodesÚtraining_iouÚtraining_diceÚmax_fitted_risk_probability)ÚparentsÚexist_okzdiagnostic_weak_gnn.ptF)r[   Úsigned_deformationr^   zK unvalidated NG run(s); weak point-dilated labels; training diagnostic only)Ú
state_dictÚproduction_validr`   Úoutput_channelsÚwarningÚstatusÚ(diagnostic_weak_label_training_completedrª   Úgeneralization_measuredÚinputz`STEP-derived CAD graph + XLS process values/masks; interpolated heaters include imputation flagsÚtarget_sourcezNregistered fused all_merge_pointcloud_full PLY + defect CSV weak geodesic areaÚindependent_samplesÚdefect_classesÚdefect_type_trainingÚdefect_type_reasonzHThe supplied run-level target has only one class and no reviewed OK run.ÚepochsÚlearning_rateÚloss_initialrš   Ú
loss_finalÚloss_last_epochéÿÿÿÿÚselected_epochÚtraining_threshold_iouzFbound the influence of unvalidated nearest-scan registration residualsrd   )Údiagnostic_clip_mmÚreasonÚcounts_by_runz?predicted magnitude >= abs(predicted signed normal deformation)zrisk graph smoothnessz#signed-deformation graph smoothnesszmheat-equation residual: missing time histories, material conductivity/capacity and physical heater footprintszrthermo-mechanical residual: missing temperature-dependent material law, thickness, contact and boundary conditionsz$results/models/weak_gnn/training.pngz'results/models/weak_gnn/predictions.png)
Útraining_threshold_diceÚtraining_metrics_by_runÚ deformation_target_preprocessingÚhard_constraintÚhard_constraint_max_violationÚsoft_constraintsÚphysics_constraints_unavailableÚ
checkpointÚfiguresÚhistoryzreport.json©Úensure_asciiÚindentzutf-8)ÚencodingÚ c              3  óˆ   K  — | ]:  }d t        j                  |d   «      › d|d   › d|d   › d|d   d›d|d   d›d�–— Œ< y	­w)
z<tr><td>rQ   z	</td><td>r¡   r¢   r£   ú.4fr¤   z
</td></tr>N)ÚhtmlÚescape)Ú.0Úrows     r   Ú	<genexpr>ztrain.<locals>.<genexpr>í   s   è ø€ ð 	ñ ˆCð	Ü�{‰{˜3˜u™:Ó&Ð'ð (ØÐ*Ñ+Ð,ð -ØÐ-Ñ.Ð/ð 0Ø�>Ñ" 3Ð'ð (Ø�?Ñ# CÐ(ð )ô	ñ ùs   ‚A Az
index.htmla  <!doctype html>
<html lang="ko"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Diagnostic weak-label GNN</title>
<style>
body{font:16px/1.5 system-ui,sans-serif;max-width:1180px;margin:2rem auto;padding:0 1rem;color:#172033;background:#f6f8fb}
.warning{background:#fff2cc;border-left:5px solid #d99b00;padding:1rem} img{max-width:100%;background:white;border:1px solid #ccd3df;border-radius:8px}
table{border-collapse:collapse;background:white} th,td{padding:.55rem .8rem;border:1px solid #ccd3df;text-align:right} th:first-child,td:first-child{text-align:left}
code{background:#e9edf3;padding:.15rem .3rem;border-radius:3px}
</style>
<h1>CAD risk-area + deformation GNN</h1>
<p class="warning"><strong>Diagnostic training-set fit only.</strong> ah   unvalidated NG run(s), weak point-dilated masks, one CAD and one run-level class. These values do not measure generalization or production accuracy.</p>
<p>Input: STEP-derived graph + XLS process values/masks. Outputs: CAD-node risk probability, signed normal deformation, deformation magnitude, and a graph-level defect-type head.</p>
<p>Final loss: <strong>rÑ   z(</strong>; pooled training IoU: <strong>z)</strong>; pooled training Dice: <strong>z%</strong>. Defect-type status: <code>z—</code>.</p>
<table><thead><tr><th>Run</th><th>Target nodes</th><th>Predicted nodes</th><th>Training IoU</th><th>Training Dice</th></tr></thead><tbody>uK  </tbody></table>
<h2>Training trace</h2><img src="training.png" alt="Diagnostic GNN training curve">
<h2>Fitted fields</h2><img src="predictions.png" alt="Weak target, fitted risk and fitted deformation fields">
<p><a href="report.json">Full JSON report</a> Â· <a href="diagnostic_weak_gnn.pt">Diagnostic checkpoint</a></p>
</html>);r   rƒ   r   r   Úlongr	   rk   re   r)   ÚoptimÚAdamWÚ
parametersrt   Ú	clamp_minÚclamprv   r+   ÚtrainÚ	zero_gradÚFÚ binary_cross_entropy_with_logitsrŠ   Ú
huber_lossr†   ÚsquareÚmeanÚcross_entropyÚbackwardÚstepÚdetachr©   ÚitemsÚclonerm   rh   Úload_state_dictÚevalÚno_gradr%   rC   Úreluru   Ú	enumerateÚslicerr   ÚOUTÚmkdirÚsaveÚplot_resultsrs   r'   Úrelative_tor
   Ú
write_textÚjsonÚdumpsÚjoinrÒ   rÓ   )8r¶   r·   r/   rW   rX   rK   rY   rZ   r[   r\   Úsigned_targetÚmagnitude_targetÚclass_targetÚmodelÚ	optimizerÚpositiveÚpositive_weightÚsrcÚdstÚ
undirectedrÊ   Úselected_lossr¼   Úselected_stateÚtype_statusr™   Úoutputr›   Údicer�   r‰   Úrisk_smoothÚdeformation_smoothr    ÚlossÚ
loss_valuer:   r   Ú
predictionÚintersectionÚunionÚ
dice_valueÚ	iou_valueÚconstraint_violationÚper_runr~   r,   rQ   ÚslÚrun_predictionÚ
run_targetÚrun_intersectionÚ	run_unionrÈ   ÚresultÚmetrics_rowss8                                                           r   rÝ   rÝ   t   s`	  € ÜÔÜÓ€DÜ�4˜‘<Ó €D¬°°f±¼u¿z¹zÓ)J $Ü˜˜[Ñ)Ó*€I´G¸DÀ¹MÌ5Ï:É:Ó4V¨EÜ�d˜9‘oÓ&€G¬w°t¸F±|Ó/D¨Ü˜$˜}Ñ-Ó.€KÄÈÈXÉÓ@W°Ü˜t KÑ0Ó1ÐÄ'È$È~ÑJ^Ô`e×`jÑ`jÓBk°<Ü%Ø�
‰
�1‰�y—‘ qÑ)¨7¯=©=¸Ñ+;¼SÀÄCÈÈ]ÑH[ÓD\Ó=]ó_€Eä—‘×!Ñ! %×"2Ñ"2Ó"4¸ÐUYÐ!ÓZ€IØ�‰Ó ×*Ñ*¨1Ó-€HÜ˜KÓ(¨8Ñ3°xÑ?×FÑFÈ3ÐFÓO€OØ�H€Cˆà�s‘€JØ€GÜ˜%“L€MØ€NØ/3€NÜ*-¨d°=Ñ.AÓ*BÀQÒ*FÑ&ÐLo€KÜ�v—ˆØ�‰Œ�y×*Ñ*°tÐ*Ô<Ù�t˜T 9¨g°uÓ=ˆÜ×0Ñ0°¸Ñ1EÀtÐXgÔhˆÜ˜f \Ñ2°DÓ9ˆÜ—l‘l 6Ð*EÑ#FÈÐ]`ÔaˆØ!¤A§L¡L°Ð8OÑ1PÐRbÐjmÔ$nÑnˆÜ—m‘m F¨<Ñ$8Ó9ˆØ" 3 z¡?Ñ3°kÀ#ÀjÁ/Ñ6RÑR×ZÑZÓ\×aÑaÓcˆàÐ.Ñ/°°J±Ñ@ØÐ.Ñ/°°J±Ñ@ñAßBHÁ&Ã(Ï4É4Ë6ð 	ô ˆt�MÑ"Ó# aÒ'ÜŸ™¨Ð/CÑ(DÀlÓS‰IàÐ3Ñ4×8Ñ8Ó:¸QÑ>ˆIØ�T‰z˜C +Ñ-Ñ-°°kÑ0AÑAÀDÐK]ÑD]Ñ]Ð`iÑiˆØ�‰Œ˜Ÿ™Ô)Ü˜4Ÿ;™;›=Ó)ˆ
Ø˜Ò%Ø&ˆMØ" Q™YˆNØLQ×L\ÑL\ÓL^×LdÑLdÔLfÔgÑLf¹j¸cÀ5˜c 5§<¡<£>×#7Ñ#7Ó#9Ñ9ÐLfˆNÑgØ�‰Ø˜Q‘Y¨¼EÀ#Ç*Á*Ã,Ó<OÜ˜tŸ{™{›}Ó-¼eÀK×DVÑDVÓDXÓ>YÜ%*¨;×+=Ñ+=Ó+?Ó%@Ü,1Ð2D×2KÑ2KÓ2MÓ,NÜ˜y×/Ñ/Ó1Ó2ñ
ö 	ð/ ð> ÐÜÐ8Ó9Ð9Ø	×Ñ˜.Ô)Ø	‡J�J„LÜ	�‰�Ù�t˜T 9¨g°uÓ=ˆÜ—m‘m F¨<Ñ$8Ó9ˆØ  BÑ&ˆ
Ø" [×%5Ñ%5Ó%7Ñ7×<Ñ<Ó>×CÑCÓEˆØ˜k×.Ñ.Ó0Ñ0×5Ñ5Ó7×<Ñ<Ó>ˆØ˜,Ñ&¬#¨a°·±Ó1A×1FÑ1FÓ1HÈ;Ï?É?ÓK\×KaÑKaÓKcÑ1cÓ*dÑdˆ
Ø ¤3 q¨%£=Ñ0ˆ	Ü$Ÿz™zØÐ.Ñ/×3Ñ3Ó5¸Ð?VÑ8WÑWó YßY\ÑY\ÓY^×_cÑ_cÓ_eð 	àˆØ�_Ñ%ˆÜ# D¨¡L×1‰JˆE�3Ü�u˜u‘} u¨q¡y°EÑ&9Ó:ˆBØ'¨™^ˆNØ$ R™×-Ñ-Ó/ˆJØ .°Ñ ;×@Ñ@ÓB×GÑGÓIÐØ'¨*Ñ4×9Ñ9Ó;×@Ñ@ÓBˆIØ�N‰NØÜ),¨Z¯^©^Ó-=Ó)>Ü,/°×0BÑ0BÓ0DÓ,EØ 0´3°q¸)Ó3DÑ DØ!"Ð%5Ñ!5¼¸A¸~×?QÑ?QÓ?S×?XÑ?XÓ?ZÐ]g×]kÑ]kÓ]m×]rÑ]rÓ]tÑ?tÓ8uÑ!uÜ/4°[À±_×5HÑ5HÓ5JÓ/Kñö ñ 2÷ 
ô6 ‡I�I�d T€IÔ*ÜÐ/Ñ/€JÜ	‡J�JØ×&Ñ&Ó(¸eØ˜MÑ*Ò?jÜ˜$˜v™,Ó'Ð(Ð(sÐtñð ô	ô
 ��w Ô'ðØÐ<ðà˜Eðà#<¸eðð 	Ðsðð 	Ðið	ð
 	��V‘ðð
 4´S¸¸f¹Ó5Fðð 	˜$˜}Ñ-ðð 0FÀ{ðð 	Ðhðð 	�&ðð *¨=ðð 	˜ ™
 7Ñ+ðð .:¸=ðð 	˜7 2™; wÑ/ðð 2BÀ>ðð 	! )ðð ISØ#*ä"6Ø^Ø!Ð";Ñ<ñ-
ð
 ]Ø)=Ø4Ð6[Ð\à{ð Að,
ô ˜*×0Ñ0´Ó6Ó7Ø:Ð<eÐfØò7€Fô: 	ˆ=Ñ×$Ñ$¤T§Z¡Z°ÀUÐSTÔ%UÐ`gÐ$ÔhØ—7‘7ñ 	ñ ó	ó 	€Lô 	ˆ<Ñ×#Ñ#ð 
)Gô HKÈ4ÐPVÉ<ÓGXÐFYð Zà˜|Ñ,¨SÐ1Ð1YÐZcÐdgÐYhð  iRð  S]ð  ^að  Rbð  bGô  HL÷  HSñ  HSð  T_ó  H`ð  Gað aKð LXð  KYð Yð%ð" ð# $ô ð$ €MùóU h÷ 
‰ús   Î)b9Ò*I2b?â?c	c                ó  — |D �cg c]  }|d   ‘Œ	 }}t        j                  dd¬«      \  }}dD ]'  }|j                  ||D �cg c]  }||   ‘Œ	 c}|¬«       Œ) |j                  d«       |j	                  d«       |j                  d«       |j                  «        |j                  d	¬
«       |j                  d«       |j                  t        dz  d¬«       t        j                  |«       t        j                  |d   «      j                  «       j                  «       }|d   j                  «       j                  «       t         z  }	| d   }
| d   }| d   }t        j                  t#        | d   «      dddt#        | d   «      z  fd¬«      \  }}t#        | d   «      dk(  r|d    }t%        | d   «      D �]r  \  }}t'        ||z  |dz   |z  «      }|
|   ddddf||   ddddf|	|   dddt         ff}t)        ||   |«      D �]#  \  }\  }}}}}d|v r�|j+                  |d d …df   |d d …df   d dd¬!«       |d"kD  }|j+                  ||df   ||df   ||   d#|||d¬$«      }t-        t/        j0                  |«      «      }|j+                  ||df   ||df   d%d&d'd(d)¬*«       n'|j+                  |d d …df   |d d …df   |d|||d¬$«      }|j3                  d+«       |j                  d,«       |j	                  d-«       |j                  |› d.|› �«       |j5                  ||¬/«       �Œ& �Œu |j7                  d0t#        | d   «      › d1�«       |j                  t        d2z  d¬«       t        j                  |«       y c c}w c c}w )3Nr™   )é   é   T)ÚfigsizeÚconstrained_layout)rš   r›   rœ   r�   )Úlabelzdiagnostic training lossÚlogg      Ð?)ÚalphazWeak-label GNN training curveztraining.pngé–   )Údpir“   r—   r[   rc   rF   rb   é   é   g333333@r   zweak 10 mm risk targetÚmagmar   zfitted risk probabilityz/fitted deformation magnitude (30 mm target cap)Úviridisr…   z#d9dde3)ÚcÚsÚ
rasterizedg{®Gáz”?é
   )r(  r)  ÚcmapÚvminÚvmaxr*  rG   z#00b7ffé-   gffffffö?Úmaximum)Úmarkerr(  r)  Ú
linewidthsr  Úequalz
CAD X (mm)z
CAD Z (mm)z: )Úaxz!Training-set visualization only; z4 weak/unvalidated NG run(s), no held-out performancezpredictions.png)ÚpltÚsubplotsÚplotÚ
set_xlabelÚ
set_ylabelÚ
set_yscaleÚlegendÚgridÚ	set_titleÚsavefigrð   Úcloser   r†   ÚcpuÚnumpyrs   r)   rî   rï   rq   Úscatterrr   r!   ÚargmaxÚ
set_aspectÚcolorbarÚsuptitle)r/   rÊ   r  rÕ   r¶   Úfigr4  r:   r‰   r^   rˆ   r~   ÚposÚaxesr,   rQ   r  Úpanelsr   Útitler,  ÚlowÚhighÚshownÚdrawÚpeaks                             r   ró   ró     s‘  € Ù&-Ó.¡g˜sˆc�'‹l g€FÐ.Ü�l‰l 6¸dÔC�G€CˆÛ;ˆØ
�‰�©WÓ5©W c˜˜S›¨WÑ5¸SˆÕAð <à‡M�M�'Ô˜BŸM™MÐ*DÔEÀrÇ}Á}ÐUZÔG[Ø‡I�I„K�—‘˜s�Ô# R§\¡\Ð2QÔ%RØ‡K�K”�nÑ$¨#€KÔ.´·	±	¸#´ä—-‘-  |Ñ 4Ó5×9Ñ9Ó;×AÑAÓC€KØÐ.Ñ/×3Ñ3Ó5×;Ñ;Ó=Ô@TÑT€IØ�&‰\€FØ�Ñ!€E¨¨lÑ); 3Ü—‘œS  f¡Ó.°¸BÀÄcÈ$ÈvÉ,ÓFWÑ@WÐ;XÐmqÔr�I€CˆÜ
ˆ4�‰<Ó˜AÒ d¨4¡j˜tÜ  V¡×-‰
ˆˆsÜ�5˜5‘= 5¨1¡9°Ñ"5Ó6ˆØ˜"‘:Ð7¸À!ÀQÐGØ˜r‘?Ð$=¸wÈÈ1ÐMØ˜R‘=Ð"SÐU^Ð`aÔcwÐxðzˆô 47°t¸E±{ÀF×3KÑ/ˆBÑ/�˜˜t S¨$Ø˜‰Ø—
‘
˜3šq !˜t™9 cª!¨Q¨$¡i°9ÀÈd�
ÔSØ ™�Ø—z‘z # e¨Q h¡-°°U¸A°X±À%ÈÁ,ÐRTØ'+°#¸DÈTð "ó S�äœ2Ÿ9™9 UÓ+Ó,�Ø—
‘
˜3˜t Q˜w™<¨¨T°1¨W©¸cÀYÐRTØ&)°ð õ <ð —z‘z #¢a¨ d¡)¨S²°A°©Y¸%À1È4Ø'*°À$ð "ó H�à�M‰M˜'Ô" B§M¡M°,Ô$?ÀÇÁÈ|ÔA\Ø�L‰L˜C˜5  5 'Ð*Ô+¨S¯\©\¸$À2¨\Ö-Fò 4Lð .ð& ‡L�LÐ4´S¸¸f¹Ó5FÐ4GÐG{Ð|Ô}Ø‡K�K”Ð'Ñ'¨S€KÔ1´3·9±9¸Sµ>ùòE /ùò 6s   …M=ÁNc            
     ó¼  — t        j                  t        ¬«      } | j                  dd¬«       | j                  dt        d¬«       | j                  dt
        d	¬«       | j                  «       }|j                  st        d
«      ‚t        |j                  |j                  «      }t        t        j                  dD �ci c]  }|||   “Œ
 c}dd¬«      «       y c c}w )N)Údescriptionz--allow-diagnostic-weak-labelsÚ
store_true)Úactionz--epochsé<   )ÚtypeÚdefaultz--learning-rategü©ñÒMb`?zwRefusing weak/unvalidated targets. Pass --allow-diagnostic-weak-labels for the requested diagnostic overfit experiment.)r­   r¸   r¹   r½   rÁ   r´   Fr…   rË   )ÚargparseÚArgumentParserÚ__doc__Úadd_argumentrr   rv   Ú
parse_argsÚallow_diagnostic_weak_labelsÚ
SystemExitrÝ   r¶   r·   Úprintrö   r÷   )ÚparserÚargsr  r:   s       r   Úmainrb  2  sÚ   € Ü×$Ñ$´Ô9€FØ
×ÑÐ8ÀÐÔNØ
×Ñ˜
¬°bÐÔ9Ø
×ÑÐ)´¸tÐÔDØ×ÑÓ€DØ×,Ò,Üð  Só  Tð  	TÜ�4—;‘; × 2Ñ 2Ó3€FÜ	Œ$�*‰*ñ 3;ó <ñ 3;¨3�c˜6 #™;Ñ&ð 3;ñ <àJOÐXYô[õ \ùò <s   Â=CÚ__main__)r   ú
np.ndarrayr   ztorch.dtypeÚreturnr   )r/   zdict[str, np.ndarray]re  rd  )re  údict[str, Any])r‡   r   rˆ   r   re  r   )r¶   rr   r·   rv   re  rf  )r/   rf  rÊ   zlist[dict[str, float]]r  zdict[str, Tensor]re  ÚNone)re  rg  )+rZ  Ú
__future__r   rX  rÒ   rö   Úpathlibr   Útypingr   Ú
matplotlibÚuseÚmatplotlib.pyplotÚpyplotr5  rA  r!   r   r   Útorch.nn.functionalÚnnÚ
functionalrß   Úarchitecturesr	   r/   r
   r   r   r   Útrainingr   rð   rs   r#   r   r>   rƒ   rŠ   rÝ   ró   rb  Ú__name__rB   r   r   Ú<module>ru     s¦   ðñõ #ã Û Û Ý Ý ã Ø €
‡�ˆuÔ Ý Û Û Ý ß Ð å 4ß TÓ TÝ %à
Ð&Ñ&€ØÐ ð 5:·M±Mô /óaó20óf_ó
Uóp#BóL\ð ˆzÒÙ…Fð r   