o
    j                     @  sj  d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	Z	ddl
ZddlZejdd ddlmZ ddlmZmZ ddlmZ dd	lmZmZmZmZmZ dd
lmZmZ ddl m!Z! ddl"m#Z# ddl$m%Z%m&Z& ee'( j)d Z*e*d d d e*d d d e*d d d gZ+e*d d Z,e*d Z-dZ.e*d d Z/dZ0g dZ1e2e1dksJ ej3dd eD ej4dZ5ddddd d!Z6i d"d"d#d#d$d#d%d#d&d#d'd#d(d(d)d(d*d(d+d(d,d(d-d-d.d-d/d/d0d/d1d/Z7g d2Z8i d3d4d5d4d6d4d7d4d8d4d9d4d:d4d;d4d<d4d=d4d>d4d?d@dAd@dBd@dCd@dDd@dEd@d@d@dFZ9d4Z:dGdGdGdGdGdHdHdHdHdHdHdIZ;dJdK Z<efdLdMZ=	NdddVdWZ>ddd[d\Z?	X	]ddd`daZ@	b	4	GdddhdiZAg djZBdNZCdkZDddodpZEdddtduZF	H	4dddwdxZGdydz ZHd{d| ZId}d~ ZJdddZKdd ZLdd ZMdddZNdd ZOePdkreO  dS dS )u  A/B/C experiment: compare V2-dynamics mask strategies on one scenario.

Generates 3 variants of daily_003 viewer bundles:
    A: strict 11-channel mask (brow+cheekSquint+noseSneer+eyeSquint)
    B: tiered ~19-channel mask (A + smile/frown/eyeWide/dimple at reduced α)
    C: no V2 — current baseline (compiler + LAM only)

Usage:
    python3 scripts/compiler/abc_experiment.py [--scenario daily_003]
    )annotationsN)Pathz-/dataset/text-to-face-se/LAM_Audio2Expression)AudioFeatureExtractor)compile_expressive_batchMOUTH_CHEEK_OVERLAY_CHANNELS)parametric_layer)ARKIT_52_NAMESLAM_WEIGHTS_SHAREDLIPSYNC_ONLYEXPRESSION_ONLYSHARED_CHANNELS)merge_lam_compilerspeech_gate)apply_eye_motion)
LAMWrapper)load_presets_from_jsonbuild_synthetic_presets   dataemotionzseed_train_final.jsonlzseed_val.jsonlzseed_test.jsonlaudio_previewzexpression_presets.jsonzD/dataset/mead-expression-training/e2f/distill/emotion_face_int8.onnxviewer   )4eyeBlinkLefteyeBlinkRighteyeLookDownLefteyeLookDownRighteyeLookInLefteyeLookInRighteyeLookOutLefteyeLookOutRighteyeLookUpLefteyeLookUpRighteyeSquintLefteyeSquintRighteyeWideLefteyeWideRight
jawForwardjawLeftjawRightjawOpen
mouthClosemouthFunnelmouthPucker	mouthLeft
mouthRightmouthSmileLeftmouthSmileRightmouthFrownLeftmouthFrownRightmouthDimpleLeftmouthDimpleRightmouthStretchLeftmouthStretchRightmouthRollLowermouthRollUppermouthShrugLowermouthShrugUppermouthPressLeftmouthPressRightmouthLowerDownLeftmouthLowerDownRightmouthUpperUpLeftmouthUpperUpRightbrowDownLeftbrowDownRightbrowInnerUpbrowOuterUpLeftbrowOuterUpRight	cheekPuffcheekSquintLeftcheekSquintRightnoseSneerLeftnoseSneerRight	tongueOut4   c                 C  s   g | ]}t |qS  )V2_NAMESindex.0nrN   rN   "scripts/compiler/abc_experiment.py
<listcomp>S       rU   dtype         )neutraljoyangersadnesssurpriser\   r]   laughter
excitement	agreement	gratituder_   cryingsulkapologystruggler^   refusalr`   flustershy)rD   rB   rC   rE   rF   rH   rI   rJ   rK   r#   r$   rD         ?rB   rC   rE   rF   rH   rI   rJ   rK   r#   r$   r0   g      ?r1   r2   r3   r%   r&   )r4   r5         ?      ?)rD   rB   rC   rE   rF   r#   r$   rH   rI   rJ   rK   c                 C  s  t jdt jd}t jdt jd}d}dD ]'}|  d| }||v r;t j|| d t jd}t ||}t ||}d}q|sNt jdt jdt jdt jdfS tt jg dt jd}tt jg d	t jd}	t ||	}
t	D ]}t
|| t|
| ||< qn||fS )
a  Per-channel (min, max) across L1/L3/L5 of this emotion family.

    Returns (lo, hi) each (52,). Used to cap V2 motion so it never exceeds
    the user-authored intensity range for that emotion.

    Option E correction: on the mouth/cheek channels that the parametric
    overlay can drive, expand `hi` to accommodate parametric's max output at
    extreme V (positive or negative). Otherwise the cap clamps Option E's
    contribution back to 0 on emotions where the authored mouth shape is 0
    (e.g. surprise).
    rM   rW   F)rY   rZ      _LbsT)rm   rm   rm   )g      rm   rm   )nponesfloat32zerosasarrayminimummaximumr   arrayr   maxfloat)r   presetslohifoundLkeyrq   p_posp_negp_maxchrN   rN   rT   get_preset_envelope   s&    r   c                   s   t j fdd| D t jdS )Nc                   s   g | ]}  |qS rN   )rP   rQ   orderingrN   rT   rU      rV   zname_to_idx.<locals>.<listcomp>rW   )rr   ry   int64)namesr   rN   r   rT   name_to_idx   s   r   皙?vads
np.ndarrayr|   dictsigmar{   returnc                 C  s   t jdd | D t jd}t jdd | D t jd}| jd }t j|dft jd}dd|d	   }t|D ])}t j|| |  d	 d
d}	t |	 | }
|
 }|dkr\|
| }
|
| ||< q9t 	|dd
t jS )u  RBF over ALL preset anchors based on VAD distance (cross-emotion blend).

    Unlike `compile_expressive_batch` which interpolates only within an
    emotion family using L1/L3/L5 anchors, this blends across every preset
    in the dataset. Frames whose VAD lies between, e.g., crying and sulk
    anchors get a weighted mix of both shapes — adds emotional cross-
    pollination from VAD proximity rather than the categorical label.

    vads: (T, 3) per-frame VAD trajectory.
    presets: dict from utils.load_presets_from_json. Each value: 'vad' + 'bs'.
    sigma: RBF kernel width. Smaller = nearest anchor dominates, larger = broader.

    Returns (T, 52) blendshape pose array.
    c                 S     g | ]}|d  qS )vadrN   rR   prN   rN   rT   rU          z)cross_emotion_compile.<locals>.<listcomp>rW   c                 S  r   )rq   rN   r   rN   rN   rT   rU      r   r   rM   rm          @r   rY   axisg&.>        )rr   rv   valuesrt   shaperu   rangesumexpclipastype)r   r|   r   anchor_vads	anchor_bsTout	inv_2sig2td2wsrN   rN   rT   cross_emotion_compile   s"   
r         .@xsigma_framesc                 C  s$   ddl m} || |ddd}| | S )u   Remove slow drift via subtracting a Gaussian-smoothed version.

    sigma_frames=15 at 30fps → 0.5s cutoff → keeps sub-second prosody.
    r   gaussian_filter1dnearestr   r   mode)scipy.ndimager   )r   r   r   smoothedrN   rN   rT   highpass_per_channel   s   r         @hp_sigmalp_sigmac                 C  s(   ddl m} t| |d}|||dddS )u   Bandpass filter for prosody: HPF removes slow drift, LPF removes jitter.

    lp_sigma=4 at 30fps ≈ 133ms window → smooths phoneme-rate jitter but
    preserves syllable-rate prosody (~150-300ms).
    r   r   )r   r   r   )r   r   r   )r   r   r   r   hprN   rN   rT   bandpass_prosody   s   r         >@signalfps
min_cutoffbetad_cutoffc                 C  s   dd }t | }tj|tjd}| d |d< d}d| }	td|D ]>}
||	|}| |
 ||
d   |	 }|| d| |  }|}||t|  }||	|}|| |
  d| ||
d    ||
< q!|S )zFOne-Euro filter (ported from mead training). Peak-preserving low-pass.c                 S  s   dt j | |  }||d  S )Nr   rm   )rr   pi)tecutoffrrN   rN   rT   sf   s   z_one_euro_filter.<locals>.sfrW   r   r   rm   rY   )lenrr   ru   rt   r   abs)r   r   r   r   r   r   r   r   dx_prevr   ia_ddxdx_hatr   arN   rN   rT   _one_euro_filter   s   

&r   )r   rY   r   rZ   r[   g?prev_vnext_vr   c                 C  s   t d }|d| k r*d| dkr|d|  nd}ddt|tj   }d| |  S |d| k r2dS d| }|dkrB|d|  | nd}ddt|tj   }|| S )u  For a single brow channel value over the crossfade.
    t ∈ [0, 1] across the fade window.
    Profile:
      [0, 0.5−PAUSE/2]:  prev → 0 (cosine ramp-down)
      [0.5−PAUSE/2, 0.5+PAUSE/2]:  hold at 0 (neutral pause)
      [0.5+PAUSE/2, 1]:  0 → next (cosine ramp-up)
    r   rl   r   rm   r   )NEUTRAL_PAUSE_FRACTIONrr   cosr   )r   r   r   
half_pauselocal_teaseddenomrN   rN   rT   _brow_pass_through_zero  s   r      fade_framesintc                 C  sF  t j| ddt j}|d }d}t|dd D ]\}}||7 }| | d }| |d  d }	td|| }
t|jd || }||
 }|dkrIqg }tD ]}t	t
|| t
|	|  tkrd|| qMt|
|D ]5}||
 |d  }ddt |t j   }d| | ||	  ||< |D ]}t|| |	| ||||f< qqjq|S )	uS  Cosine-eased blend of static comp_bs across turn boundaries.

    Cosine ease (smoothstep) reads as more natural than linear because real
    facial-expression shifts have ramp-up/ramp-down rather than constant
    velocity. Same fade_frames duration as linear, but the *feel* is smoother.

    For BROW channels with large opposite-sign swings (e.g. raised brows for
    sadness/surprise transitioning to lowered brows for anger), the pose-LERP
    approach looks unnatural — straight-line trajectory between extremes lacks
    the brief muscular relaxation real human faces show. We route those brow
    channels through a brief neutral pause (Option B).

    comp_stack: list of (T_i, 52) arrays, one per turn (static-per-turn).
    turn_lengths: parallel list of T_i.
    Returns concatenated (total_T, 52) with smooth boundary transitions.
    r   r   r   NrY   rl   rm   )rr   concatenater   rt   	enumeraterz   minr   BROW_CHANNELSr   r{   BROW_SWING_DELTAappendr   r   r   r   )
comp_stackturn_lengthsr   concathalfcursorr   Ti	prev_pose	next_pose
fade_startfade_endr   brow_pass_channelsr   fr   alpharN   rN   rT   crossfade_turn_boundaries$  s4    
r   targetc                 C  sh   |   }tttttdh B }|D ]}t|dd|f ||d|dd|f< qt|ddtj	S )zDApply One-Euro filter to expression channels (not lipsync-critical).   Nr   r   r   rm   )
copysortedsetr   r   r   rr   r   r   rt   )r   r   r   result	smooth_chr   rN   rN   rT   smooth_expression_channelsW  s   r   c              	   C  sz   t D ]8}| s	q| %}|D ]}t|}|d | kr*|  W  d      S qW d    n1 s5w   Y  qd S )Nscenario_id)	SCENARIOSexistsopenjsonloads)sidr   r   liner   rN   rN   rT   find_scenariod  s   

r  c                 C  sd   t |  d| d| d }| r| jdkr|S dd t |  d| dD }|r0|d S d S )	N_t_.mp3  c                 S  s   g | ]}|  jd kr|qS )r  )statst_size)rR   mrN   rN   rT   rU   t  s    zfind_audio.<locals>.<listcomp>z_*.mp3r   )	AUDIO_DIRr   r  r  glob)r   tiemoexactmatchesrN   rN   rT   
find_audiop  s
    r  c           	      C  s   | |tj}|jd }t|d}tjd|dftjd}|dkr.d|dddt| f< | 	d|d |d	d d }|ddt
f tjS )
z9Run V2 ONNX. Returns (T, 52) in AnimaSync order, float32.r   r\   rY   ro   rW   rm   N)N.)featuresr   )extractr   rr   rt   r   SUB_TO_BASEgetru   
EMO_TO_IDXrunV2_TO_ANIMA)	sessfeat_extractorwavemotion_namefeatsr   baser   r   rN   rN   rT   run_v2y  s   
r  c              
   C  sH  |dkr| S t |ddd}|  }|dkr>tD ]%}t|}t|t}	| dd|f |	|dd|f   |dd|f< qn8|dkrot	 D ]'\}}
t|}t||
}	| dd|f |	|dd|f   |dd|f< qFnt
d| |dur|dddf |  }|d	k}t|t||dddf |}t|d
dtjS )uB  Add V2 dynamics to comp_bs per mask variant.

    Returns modified comp_bs (same shape, AnimaSync ordering).

    Brow channels get ALPHA_BOOST × normal α for expressivity.
    Output is capped to the emotion's preset envelope (lo, hi) if provided —
    peaks never exceed what the user authored for that emotion.
    Cr   r   )r   r   ANBzunknown variant: g-C6?r   rm   )r   r   MASK_A_STRICTr   rP   ALPHA_BOOSTr  ALPHA_STRICTMASK_B_TIEREDitems
ValueErrorrr   whererw   r   r   rt   )comp_bsv2_bsvariantenvelope_loenvelope_hiv2_dynr   namer   r   
base_alphaheadroomcap_maskrN   rN   rT   apply_v2_dynamics  s,   	
2
2"r3  c                 C  s   | d}|d}| D ]}|d|  d qW d    n1 s%w   Y  tjddddd	d
dddt|ddddt|gdd |  d S )Nz.concat.txtr   zfile 'z'
ffmpegz-yz	-loglevelerrorz-fr   z-safe0z-iz-c:a
libmp3lamez-b:a128kT)check)with_suffixr   writeresolve
subprocessr  strunlink)pathsout_mp3	list_filer   r   rN   rN   rT   concat_audio  s   
rC  c              	   C  st   t | d }|tt|t|t| d d}|jddd}tj	||dd W d    |S 1 s3w   Y  |S )	Nz.jsonr[   )r   r   
num_framesr   turnsblendshapesr   zutf-8)encodingF)ensure_ascii)
OUT_DIRFPSr   r   rr   roundtolistr   r   dump)r   scen
turns_metasid_outrD  json_outpayloadr   rN   rN   rT   export_viewer_json  s   
rS  base_idr>  variantslistrO  rN  c           	   	     s   t d }dg i}| rz	t| }W n	 ty   Y nw  fdd|dg D |d< |r4|d ni }|dddd	 }d
d |D }|d  ||d t|||d |	tj
|ddd dS )z=Append/update manifest.json so the player can list scenarios.manifest.json	scenariosc                   s   g | ]}| d  kr|qS )r  r  rR   r   rT  rN   rT   rU     s    z#update_manifest.<locals>.<listcomp>r   text N2   c                 S  s   g | ]}| d dqS )r   ?rY  )rR   r   rN   rN   rT   rU     s    r   )r  rU  r   n_turnsemotionstext_previewFr   )rH  indent)rI  r   r   r   	read_text	Exceptionr  r   r   
write_textdumps)	rT  rU  rO  rN  manifest_pathmanifest
first_turnrb  emotions_in_turnrN   r[  rT   update_manifest  s.   



	rl  c            K      C  s	  t  } | jddd | jdtd dd | jdtdd	d | jd
td dd | jdtddd | jdtddd | jdtddd | jdtddd | jdtddd | jdddd | jdtddd | jd tdd!d | jd"td#d$d |  }|j}tjd%d%d& t	|}|d u rt
d'| td( t }td) tjtd*gd+}t }td,t  t rtt}td-t| d. nt }td/t| d0 g d1}d2d3 |D }	d4d3 |D }
g }g }g }g }g }g }t|d5 D ]\}}|jd ur||jkrq|d6d sq|d7d8}|d9g d:}t|||}|d u r1td;| d< qtjt|d=d%d>\}}t|d?k rEqtd;| d@|dAdBt|| dCdD ||}|jdE }t ||||}|jdE |kry|d | }n"|jdE |k r||jdE  }t!j"|t!#|dFd  |dGfgdEdH}t$|}|%|||||||||d6|dIddJ q|st
dK|j&dk rut|dGkrut|j&}dL|d  }dMdN |D }tt'|dGkrtdO|dE  dP nt|} dEg|  }!dE}"|"| k r9|"}#|#| k r#||# ||" kr#|#dG7 }#|#| k r#||# ||" kst(|"|#D ]	}$|#|" |!|$< q(|#}"|"| k sg }%t(| D ]"}$|!|$ }&|&dGkrL|n|&dQkrS|nd}'|%%|' |'||$ dR< q?tdS| dT|! dUdVdN |%D  dW |j)dEkrt|dGkrt|j)}(t|j*})t!j+|dE d9 t!j,dX}*|dGd  D ]'}+t!j+|+d9 t!j,dX},|(|, d|( |*  }-|)|* d|) |,  }*|-- |+d9< qtdY|( dZ|) d[t|dG  d\ t!j"d]dN |D dEdH}.|j.dEkrt|dGkrdEd^l/m0}/ |/|.|j.dEd_d`1t!j,}.tda|j. dbt| dc dE}0|D ]}+|+dd }|+d7 }|.|0|0|  }1|0|7 }0t2|g| |1||j3de}2|j4dkrYt5|1||j6df}3t|j4}4d|4 |2 |4|3  1t!j,}2t|+dRd}5|5dk r|2|5 1t!j,}2|j7dkrt8D ]}6t!9|2d d |6f |j7|2d d |6f< qvt:||\}7}8|D ]}9t;|2|+dg |9|7|8dh}:|
|9 %|: q|%|+di  |%|+dj  |%| |%|+dk  |%|+dl |+d7 |+d9 |+d6 |+dI dm q|st
dKt|dnk};|j<d ur|j<n|;rdondp}<|;rdqndr}=t!j"|dEdH}>t!j"|dEdH}?tds|< dt|= du|; d0 |D ]+}9t=|
|9 ||<dv}@t>|>|@|?}At?|A|=dLdw}At@|A| dx|9 dy|jAdz}A|A|	|9< q|jd urWd{|j nd}Bt| |B |jB d| }CtC||C td}|C  td~ |B |jB }D|D ]O}9|	|9 }E| |D d|9 }FtD|E|||F|EjdE }Gt|F d }H|H s|HE r|HF  |HG|CjH |GI jJd }Itd|9 d|GjH d|I d|Ej  q~| |D }JtK|J||| tdtd   td td|J  d S )Nz
--scenario	daily_003)defaultz--turnz+If set, process only this single turn index)typern  helpz--option-e-intensityrm   u[   α scalar for Option E parametric mouth/cheek overlay (1.0=full, 0.7=−30%%, 0.0=disabled)z--fade-framesuh   Override turn-boundary crossfade duration in frames (default: 48 for monologues ≥3 turns, 8 otherwise)z--vad-smooth-sigmar   u   Gaussian sigma (in frames) for cross-turn VAD trajectory smoothing. 0 = disabled (per-turn step). 15 ≈ 0.5s ramp around boundaries. NOTE: symmetric kernel — offline use only.z--vad-damp-gammar   u   Causal monologue VAD damping. Each turn's VAD becomes γ·raw + (1−γ)·running_mean(past_turns). 0=disabled, 0.6=moderate, 0.4=strong. First turn always unchanged. Single-turn scenarios bypassed entirely. Real-time safe.z--vad-damp-betagffffff?uk   Running-mean update rate for causal damping. running_mean = β·old + (1−β)·new_turn. 0.7 = slow drift.z--persistence-dampingu4  Pose-level scale toward zero for multi-turn fleeting emotions. Default 1.0 (off). When <1.0, isolated turns have comp_bs · ps; paired turns midpoint; sustained/single-turn unaffected. Pair with --brow-v2-floor to keep V2 prosody jitter intact (otherwise clipping at 0 squashes V2 by ~50%%). Recommended 0.5.z--brow-v2-floora"  Minimum value held on brow channels (0-4) AFTER pose damping, before V2 dynamics is added. Gives V2 negative prosody excursions room to oscillate without clipping at zero. Recommended 0.06-0.10 when --persistence-damping is on. Adds a small constant brow lift even when authored value is 0.z--out-suffixr]  z]Suffix appended to output sid so experimental renders don't overwrite the canonical scenario.)rn  rp  z--blink-intervalr   zsMean seconds between blinks (Poisson). Default 4.0. Lower = more frequent. Real conversational blink rate is ~3-4s.z--cross-emotion-weightud  Weight (0-1) for cross-emotion VAD-driven pose. Default 0.0 (pure within-emotion authored anchor). When >0, blends a VAD-distance-weighted RBF across ALL preset anchors (regardless of emotion family) with the current authored within-emotion pose. Final = (1-w)·authored + w·cross_emotion. Recommended 0.3 for 'authored with a bit of cross-emotion bleed'.z--cross-emotion-sigmar   zGaussian RBF sigma for cross-emotion VAD distance weighting. Smaller = tighter (only nearest anchors matter), larger = broader blend. Default 0.4.T)parentsexist_okzscenario not found: z[setup] loading LAM...z[setup] loading V2 ONNX...CPUExecutionProvider)	providersz[setup] loading presets: z	  loaded z presetsz*  WARN: no presets JSON, using synthetic ())r   r!  r  c                 S     i | ]}|g qS rN   rN   rR   vrN   rN   rT   
<dictcomp>B      zmain.<locals>.<dictcomp>c                 S  rv  rN   rN   rw  rN   rN   rT   ry  C  rz  rE  r\  r   r\   r   )r   r   r   z  [tz] no audio, skipi>  )srmonog      @z] 10sz  wav=z.2fr   r   r   rY   r   speaker)turn_idxr   r   aplam_bsr*  gater   r\  r~  persist_scalezno turns processedrl   c                 S  s   g | ]
}t |d  dqS )r   r\   )r  r  rR   crN   rN   rT   rU   {  s    zmain.<locals>.<listcomp>z%[persist-damp] all turns share base 'z
'; skippedr   r  z[persist-damp] bases=z  persistence=z	  scales=c                 S  s   g | ]}t |d qS )r   )rK  rZ  rN   rN   rT   rU     rV   z  (pose-level)rW   u   [vad-damp] γ=u    β=z applied to z) non-first turns (causal, real-time safe)c                 S  s0   g | ]}t t j|d  t jd|d dfqS )r   rW   r   rY   )rr   tilerv   rt   r  rN   rN   rT   rU     s    "r   r   r   u   [vad-smooth] σ=zf applied across z turnsr   )ra  r   r|   parametric_overlay_intensity)r   r*  )r,  r-  r  r  r  r  )r  r   r   r\  r~  rZ   0   r   g?rn   z[smooth] fade_frames=z  min_cutoff=z  (monologue=)r   r   z::r   )seed_strr   blink_interval_sr  z_ABC.mp3z[audio] z	
[export]r  r  i   z  z: z (z KB)  shape=z
[manifest] updated: rW  z
Open in browser:z>  http://localhost:8890/tools/blendshape-player.html?scenario=)LargparseArgumentParseradd_argumentr   r{   
parse_argsscenariorI  mkdirr  
SystemExitprintr   ortInferenceSessionONNX_V2r   PRESETSr   r   r   r   r   turnr  stripr  librosaloadr>  infer_audior   r  rr   r   r  r   r   persistence_dampingr   r   vad_damp_gammavad_damp_betary   rt   rL  vad_smooth_sigmar   r   r   r   option_e_intensitycross_emotion_weightr   cross_emotion_sigmabrow_v2_floorr   rx   r   r3  r   r   r   r   r   blink_interval
out_suffixrC  rS  
is_symlinkr?  
symlink_tor/  r  r  rl  )Kr  argsr   rN  lamv2_sessv2_featr|   rU  targetscomp_stacks	lam_stack
gate_stackr   audio_pathsrO  	collectedr  r  r  r   ap_r  r{  r  r   r*  padr  fleetingpairedbasesrS   run_lenr   jkscalesr   r      γ   βrunning_meanr  rawdampedall_vadsr   r   	vad_slicer)  xemor   psr   env_loenv_hirx  comp_modifiedis_monologuer   r   lam_catgate_catcomp_catmergedturn_suffix
shared_mp3suffixconcat_targetrP  rQ  variant_mp3size_kbrT  rN   rN   rT   main  s  











(

&




 



$









(r  __main__)r   )r   r   r|   r   r   r{   r   r   )r   )r   r   r   r{   r   r   )r   r   )r   r   r   r{   r   r{   r   r   )r   rn   rl   rm   )r   r   r   r{   r   r{   r   r{   r   r{   r   r   )r   r{   r   r{   r   r{   r   r{   )r   )r   r   )rn   rl   )r   r   r   r{   r   r{   r   r   )NN)rT  r>  rU  rV  rO  rV  rN  r   )Q__doc__
__future__r   r  r   r=  syspathlibr   r  numpyrr   onnxruntimer  pathinsertdistillation.student_modelr   scripts.compiler.expressiver   r   scripts.compiler.parametricr   scripts.compiler.constantsr   r	   r
   r   r   scripts.compiler.data_pipeliner   r   scripts.compiler.eye_motionr   scripts.compiler.lam_wrapperr   scripts.compiler.utilsr   r   __file__r<  rq  PROJECT_ROOTr   r
  r  r  rI  rJ  rO   r   ry   r   r  r  r  r"  r%  r$  r#  r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r3  rC  rS  rl  r  __name__rN   rN   rN   rT   <module>   s&  
		


%!

4	
,
  
5
