
    Sjn              	      N   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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mZmZ ddlmZmZmZ ddlmZ ddlmZmZmZ dd	lmZ  ej8                         d
z  dz  dz  Zedz  ZdZdZ  e!dd      Z"dZ#dZ$h dZ%dddddddddZ&dZ'dhe'D  ch c]  } d|  	 c} z   e(e&jS                               z  Z*dhe%D ch c]  }d | 	 c}z  Z+h d!Z,h d"Z- ed#$       G d% d&             Z.d?d'Z/d@d(Z0dAd)Z1dBd*Z2dCd+Z3dDd,Z4dDd-Z5dAd.Z6dEd/Z7dEd0Z8	 dF	 	 	 	 	 dGd1Z9dEd2Z:dHd3Z;dId4Z<dJd5Z=dKd6Z>	 	 	 	 	 	 	 	 	 	 dLd7Z?	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dMd8Z@	 dF	 	 	 	 	 dNd9ZAd@d:ZBdOd;ZCdPd<ZDdFdQd=ZEeFd>k(  r eG eE             yc c} w c c}w )RaK  Safety-first multimodal correlation engine for HealthManager.

The engine computes exploratory, phase-stratified Spearman associations from
complete cases only. Missing symptom days are never interpreted as symptom-free.
Only aggregate statistics are persisted; daily values and source names remain in
the protected source tables.
    )annotationsN)defaultdict)	dataclassreplace)datedatetime	timedelta)Path)AnyCallableIterable)	spearmanrz.hermesassets
Gesundheitzhealth_data.db   g333333?   Bspearman_7d_block_permutation_complete_case_phase_stratified_bh_v1i  >   hautaugengelenkegi_darmaphthen_mundulzeramuedigkeit_fatiguevaskulaer_thrombose_warnzeichenzlab:crp_mg_lzlab:d_dimer_ug_lzlab:fibrinogen_g_lzlab:factor_viii_percentzlab:platelets_tsd_ulzlab:leukocytes_tsd_ulzlab:ferritin_ng_ml))c_reaktives_protein_crpmg_l)crpr   )d_dimerug_l)
fibrinogeng_l)faktor_viiipercent)thrombozytentsd_ul)
leukozytenr%   )ferritinng_ml)
step_countactive_energysleep_analysisresting_heart_rateheart_rate_variabilityblood_oxygen_saturationrespiratory_ratephysical_effortnutrition:histamine_scoreapple:symptom_totalsymptom_>   unknownearly_treatmentstable_treatmentbaseline_pre_treatment>   computedinsufficient_ninsufficient_coverageT)frozenc                      e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   ded	<   d
ed<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   y)CorrelationResultstr	predictortargetintlag_daysmedication_phaseneligible_target_daysexpected_target_daysfloattarget_coveragemissing_pairsfloat | Nonerhop_valueq_valuestatusmethodztuple[str, ...]quality_flagsinterpretationN)__name__
__module____qualname____annotations__     H/home/agent/.hermes/assets/Gesundheit/scripts/multimodal_correlations.pyr>   r>   J   s\    NKM
F	KK""rX   r>   c                Z    t        j                  |       }t         j                  |_        |S N)sqlite3connectRowrow_factory)db_path
connections     rY   connrb   ^   s"    )J$[[JrX   c                .    t         j                  | _        y r[   )r\   r^   r_   )ra   s    rY   _ensure_row_factoryrd   d   s    $[[JrX   c                   	 | t        |       j                         dk(  ry t        t        |       j                  dd      j                               }t	        j
                  |      r|S d S # t        t        f$ r Y y w xY w)N ,.)r?   striprH   r   mathisfinite	TypeError
ValueError)valuenumbers     rY   _floatrp   h   st    =CJ,,."4s5z))#s399;<v.v8D8z" s   A, AA, *A, ,A>=A>c                   t        | xs d      j                         }t        j                  d|      r$	 t	        j
                  |      j                         S t        j                  d|      sy 	 t        j
                  |j                  d      r|d d dz   n|      }|j	                         j                         S # t        $ r Y y w xY w# t        $ r Y y w xY w)Nrf   z\d{4}-\d{2}-\d{2}zG\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,6})?(?:Z|[+-]\d{2}:\d{2})?Zz+00:00)
r?   ri   re	fullmatchr   fromisoformat	isoformatrm   r   endswith)rn   textparseds      rY   _canonical_dayr{   r   s    u{!!#D	||($/	%%d+5577 <<R ''c@RSb	H(<X\] ;;=""$$  		  s#   "B< 0.C <	CC	CCc                b    t        j                  |       t        |      z   j                         S )Ndays)r   rv   r	   rw   )daylags     rY   _day_addr      s&    s#iS&99DDFFrX   c           	         t        | xs d      j                         j                  t         j                  ddddd            }t	        j
                  dd|      j                  d      S )	Nrf   aeoeuess)   ä   ö   ü   ßz
[^a-z0-9]+_)r?   casefold	translate	maketransrt   subri   )ry   
normalizeds     rY   _slugr      sV    TZR))+55cmm4W[cgosDt6uvJ66-j177<<rX   c                    t        t        | xs d      j                  dd      j                  dd      j                  dd            S )Nrf      µuu   μ%z	 percent )r   r?   r   )ry   s    rY   
_unit_slugr      s=    TZR((s3;;D#FNNsT_`aarX   c                    t        | xs d      j                         j                         }dddddddddddddd}|j                  |      S )Nrf                 ?g       @g      @)0123z	keine (0)znone (0)z
leicht (1)zmild (1)z
mittel (2)zmoderat (2)z
schwer (3)z	stark (3)zhoch (3))r?   r   ri   get)rn   ry   exacts      rY   	_severityr      s`    u{$$&,,.DE 99T?rX   c           
        t        |        t        d       }| j                  d      D ]V  }t        t	        |d               }|t
        vr#t	        |d         dd }||   |   j                  t        |d                X di it
        D ci c]  }d	| i 
 c}}|j                         D ]  \  }}t        |      t
        k7  rt        d
 |j                         D              r:|j                         D ci c]  \  }}|d   |t        |d          }}}t        |j                               |d   |<   |j                         D ]  \  }}	|	|d	|    |<     |S c c}w c c}}w )z@Load only complete structured quick logs; absence stays missing.c                      t        t              S r[   )r   listrW   rX   rY   <lambda>z&load_symptom_targets.<locals>.<lambda>   s    ;W[K\ rX   zSELECT id,datum,symptom,schwergrad FROM symptom_log
           WHERE kontext='daily_quick_score' AND datum IS NOT NULL
           ORDER BY idsymptomdatumN
   
schwergradr3   r4   c              3  J   K   | ]  }t        |      d k7  xs |d   du   yw)   r   N)len).0valuess     rY   	<genexpr>z'load_symptom_targets.<locals>.<genexpr>   s*     Ws6{a46!9#44Ws   !#r   )rd   r   executer   r?   SYMPTOM_DIMENSIONSappendr   itemssetanyr   rH   sum)
ra   by_dayrow	dimensionr   result
dimensionsr   complete_valuesrn   s
             rY   load_symptom_targetsr      s   
#7BC\7]F!!	 D
 #c)n-.	..#g,$ 	sI%%iL0A&BCD 	+7I
J)Xi[!2%
J+F "<<> 8Zz?00W:CTCTCVWW &0%5%5%7
!	6ay$ uVAY''
 

 (+?+A+A+C'D$ / 5 5 7 	8Iu27FXi[)*3/	88 M K
s   E";E'c                    t        |        i }| j                  d      D ]R  }t        |d   xs d      dk  st        |d   xs d      dk7  r.t        |d         }|?||t	        |d         dd <   T d	|iS )
zUse only the rule-based score whose unit semantics are explicit.

    Macro and nutrient columns stay excluded until the separate YAZIO nutrient-unit
    audit is complete.
    zSELECT datum,histamine_score,item_count,histamine_unknown_count
           FROM nutrition_daily_summary_v2 WHERE datum IS NOT NULL
item_countr   histamine_unknown_counthistamine_scoreNr   r   r1   )rd   r   rB   rp   r?   )ra   seriesr   rn   s       rY   load_nutrition_featuresr      s     
#!F!!	F 3 s< %A&!+s37P3Q3VUV/W[\/\s,-.-2F3s7|$Sb)*3 (00rX   c           	        |}|t        |        t        j                  j                  dt	        t        t              j                         j                               ddl	m
 dj                  d t        D              }t        t              | j                  d| dt              }|D ]"  }t	        |d            j!                  |       $ dfd}|}i }t        D ]Y  }i }	 ||      j#                         D ]4  \  }
}t%        |d	d       d
k7  rt'        t%        |dd             }|0||	|
<   6 |	|d| <   [ |S )Nr   )daily_pointsrg   c              3      K   | ]  }d   yw)?NrW   )r   r   s     rY   r   z&load_apple_features.<locals>.<genexpr>   s     ;;s   zSELECT id,metric,value,unit,start_date,end_date,source_name,file_name,file_hash
                FROM apple_health_records
                WHERE value IS NOT NULL AND start_date IS NOT NULL
                  AND metric IN (zD)
                ORDER BY metric,start_date,end_date,source_name,idmetricc                8     | j                  | g             S )N)_rows)r   )r   r   rows_by_metrics    rY   	from_rowsz&load_apple_features.<locals>.from_rows   s    n.@.@.LMMrX   qualitydirectrn   r2   )r   r?   returnzdict[str, Any])rd   syspathinsertr?   r
   __file__resolveparentapple_health_analyticsr   joinAPPLE_METRICSr   r   r   r   r   getattrrp   )ra   points_loaderloaderplaceholdersrowsr   r   featuresr   r   r   pointrn   r   r   s                @@rY   load_apple_featuresr      sR    F~J'3tH~557>>?@7xx;];;7B47H!!" #/ 0CF
 
  	;C3s8}-.55c:	;	N ,.H -#% ...0 	$JCui.(:75'489E #s	$ '-6&"#- OrX   c           
        t        |        t        t              }| j                  d      }t        t              }t        j                  d      }|D ]  }t        j                  t        t        |d               t        t        |d               f      }|sGt        |d         xs t        |d         }|h|||f   j                  t        |d   xs d      j                                 |j                         D ]D  \  \  }}}t!        |      d	k7  s|j#                  |d
         s,t%        |d
         }	|	=|	||   |<   F t        |      S )zHLoad only exact, strictly provenance-verified same-day lab observations.aQ  SELECT parameter_name,wert,einheit,abnahme_datum,befund_datum
           FROM laborwerte
           WHERE lower(trim(COALESCE(validierungsstatus,'')))='validiert'
             AND verified_against_original=1
             AND reference_range_source='scanned_original'
             AND trim(COALESCE(einheit,''))<>''
           ORDER BY idz^[+-]?\d+(?:[.,]\d+)?$parameter_nameeinheitabnahme_datumbefund_datumwertrf   r   r   )rd   r   dictr   r   rt   compileLAB_FEATURE_ALLOWLISTr   r   r?   r   r{   r   ri   r   r   ru   rp   )
ra   r   r   
candidatesexact_numberr   safe_featurer   
raw_valuesrn   s
             rY   load_lab_featuresr     s]   
#,7,=H	D 4?t3DJ::78L O,003s+,-.
3s9~;N0OP
  S12YnSEX6Y;L#&'..s3v;3D"/E/K/K/MNO ,6+;+;+= 0'sZz?a|'='=jm'Lz!}%*/H\"3'0 >rX   c                   t        |        | j                  d      j                         d   }| j                  d      D cg c]  }t        |d         x}| }}|r |st	        j
                  t        |            nd dfd}|S c c}w )NaY  SELECT COUNT(*) FROM medication_administrations
           WHERE (lower(COALESCE(medication_name,'')) LIKE '%hyrimoz%'
              OR lower(COALESCE(medication_name,'')) LIKE '%adalimumab%')
             AND lower(trim(COALESCE(event_type,''))) IN
                 ('stopped','paused','restart','dose_change','abgesetzt','pausiert','neustart')r   a!  SELECT datum FROM medication_administrations
               WHERE (lower(COALESCE(medication_name,'')) LIKE '%hyrimoz%'
                  OR lower(COALESCE(medication_name,'')) LIKE '%adalimumab%')
                 AND lower(trim(COALESCE(event_type,''))) IN ('administered','verabreicht')r   c                n    yt        j                  | d d       }|k  ry|t        d      z   k  ryy)Nr5   r   r8   8   r}   r6   r7   )r   rv   r	   )r   currentstarts     rY   phasez(medication_phase_function.<locals>.phaseA  sC    =$$S"X.U?+UYB///$!rX   )r   r?   r   r?   )rd   r   fetchoner{   r   rv   min)ra   
disruptiver   r   administration_daysr   r   s         @rY   medication_phase_functionr   ,  s    
###	c hjJ %%_
	 "#g,//C< 		 	 =PXbDs#678hlE" L-	s   B	c                *   t        |       }t        |      }|sg S t        t        |      |j                        }dg|z  }d}t        |dz
  dd      D ]=  }||   }|dz   }t        |||   |z  |z        }t        t        |||         d      ||<   ? |S )N)keyr   r   rs   )r   r   sortedrange__getitem__r   max)	p_valuesr   countorderadjustedrunning
rank_indexoriginal_indexranks	            rY   benjamini_hochbergr  N  s    (^FKE	5<V%7%78Euu}HGEAIr2. R
z*A~gvn5=DE#&s7F>4J'KS#Q 	R
 OrX   c                @    t        t        | |      j                        S r[   )rH   r   	statistic)xsyss     rY   _spearman_rhor  ^  s    2r",,--rX   c                   t        |       t        |      k7  rt        d      t        t              }t	        || d      D ][  \  }}t        j                  |      }|t        |j                               z
  j                         }||   j                  ||f       ] t        |      D cg c]#  }t        ||         D cg c]  \  }}|	 c}}% c}}}S c c}}w c c}}}w )Nz&values and days must have equal lengthT)strictr}   )r   rm   r   r   zipr   rv   r	   weekdayrw   r   r   )r   r~   by_weekday_textrn   r   
week_start_days           rY   _calendar_week_blocksr  b  s    
6{c$iABB2=d2CGtVD9 6%  *I3;;=99DDF

""He#456 !/  #))<"=>;4> >s   -C CC C c                R   t        t        | |            }t        ||      }t        t	        t        |                  }t        |      dk  ryt        |      dk  rt        t        j                  |            }nt        t        j                  |j                               j                         dd d      }t        j                  |      }	|g}|h}
t        |      t         k  r`t        |      }|	j#                  |       t        |      }||
vr"|
j%                  |       |j'                  |       t        |      t         k  r`d}|D ]>  }|D cg c]  }||   D ]  }|  }}}t        t        | |            |dz
  k\  s:|dz  }@ t)        |d      t        |      z  S c c}}w )	zGTwo-sided calendar-week block permutation preserving within-week order.   r      N   r   g-q=r   )absr  r  tupler   r   r   	itertoolspermutationsrB   hashlibsha256encode	hexdigestrandomRandomMAX_BLOCK_PERMUTATIONSshuffleaddr   r   )r
  r  	pair_days	seed_textobservedblocksindexesr  seedrngseen	candidateitemextremepermutationblock_indexrn   permuteds                     rY   _block_permutation_pr5  p  s    =R()H"2y1FE#f+&'G
6{Q
6{aI227;<7>>)"2"2"45??A#2FKmmD!yy,"88WIKK	"#D4##D) ,"88 G# -8Zkf[FYZUEZEZZ}R*+x%/??qLG w?S... [s   F#c
                `   t        |      }
g d}t        | ||||
||t        |d      t        ||
z
  d      d t              }|t
        k  r-|j                  d       t        di |d d dt        |      ddS |
t        k  s.t        t        |            d	k  st        t        |            d	k  r-|j                  d
       t        di |d d dt        |      ddS t        ||      }t        |||	|  d| d| d|       }t        di |t        |d      t        |d      dt        |      ddS )Ncomplete_casephase_stratified7d_block_permutationno_causality   r   )r@   rA   rC   rD   rE   rF   rG   rI   rJ   rN   rP   low_target_coverager;   2   Zielabdeckung unter 60 Prozent; keine Kausalität.)rL   rM   rO   rQ   rR      low_n_or_variancer:   G   Unzureichende vollständige Datenpaare oder Varianz; keine Kausalität.|r9   u`   Explorative phasenstratifizierte Rangassoziation mit 7-Tage-Blockpermutation; keine Kausalität.rW   )r   r   roundr   METHODMIN_TARGET_COVERAGEr   r>   r  	MIN_PAIRSr   r  r5  )r@   rA   r   
phase_nameeligibleexpectedcoverager
  r  r'  rE   flagscommonrL   rM   s                  rY   _result_for_pairsrM    si    	BAYE#
%%h*(Q,*F %%*+  

*,O
 	
 	9}CGq(CBL1,<()  

#,d
 	
 B
C"
B	i[&3%qEG  
#qMgq!Ely rX   c                F   t        |       }i }|j                  t        |              |j                  t        | |             |j                  t	        |              t        |       }g }|j                         D ]	  \  }}|s
t        |D ch c]
  } ||       c}      xs dg}	t        |j                               D ]  \  }
}|s
t        D ]  }|	D ]  }|D cg c]  }t        ||       }}t        t        |      t        |            }t        t        |      t        |            }||kD  r_g }t        j                  |      }t        j                  |      }||k  rY|j                         }t        ||       } ||      |k(  r ||      |k(  r|j                  |       |t!        d      z  }||k  rY|s|D cg c]	  }||v s| }}t#        |      t#        |      z  }g }g }g }|D ]M  }t        ||       }||vr|j                  ||          |j                  ||          |j                  |       O |j                  t%        |
|||t#        |      t#        |      ||||
                 t'        t(              }t+        |      D ]L  \  }}|j,                  dk(  s|j.                  #||j0                  |j2                  f   j                  |       N |j5                         D ]  }t7        |D cg c]"  }||   j.                  ||   j.                  nd$ c}      }t9        ||      D ]B  \  }} | dk  xr ||   j:                  dk\  }!|!rdnd	}"t=        ||   t?        | d
      |"      ||<   D  |S c c}w c c}w c c}w c c}w )Nr5   r   r}   r9   r   皙?   B   Exploratives Signal nach Mehrfachtestkorrektur; keine Kausalität.G   Kein belastbares korrigiertes Signal; explorativ und keine Kausalität.r<  )rN   rR   ) r   updater   r   r   r   r   r   LAGSr   r   r   r   rv   rw   r   r	   r   rM  r   r   	enumeraterO   rM   rA   rD   r   r  r  rE   r   rC  )#ra   apple_points_loadertargetsr   	phase_forresultstarget_nametarget_seriesr   phasesr@   predictor_seriesr   rG  shifted_predictor_daysr   endexpected_daysr   end_dateoutcome_daypredictor_dayeligible_daysrJ  r
  r  r'  groupedindexr   r+  r  rN   signalrR   s#                                      rY   compute_resultsrh    s    #:.G,.HOO+J78OO'
4GHIOO%j12)*5I')G&-mmo 2"]=AC3ABQyk+1(..2B+C .	'I'# +"( *JL\-]ShsC.@-]*-]M 2C8N4OPEc-0#6L2MNCs{ /1M"007G#11#6H!X-&-&7&7&9(0sd(C$[1Z?ImD\`jDj)00=9!#44 "X- ) 4A$ZSSMEYS$ZM$Z"=1C4FFH&(B&(B+-I'4 6(0sd(C(0@@$		"2="AB		-"<=!((56 NN)%'&..$%;*+.		2h 1<D0AG"7+ Lv==J&6>>+EV]]F$;$;<=DDUKL >># o% '
 '.en&<&<&HGEN""cQ'
  "'84 	oNE7^>(8(8B(>F  U^ 
 %WU^U7A=N_mnGEN	oo NE B .^  %[@'
s   N
N	NN'N
c                    | j                  d       | j                  d      D ch c]  }|d   	 }}d|vr| j                  d       d|vr| j                  d       | j                  d       y c c}w )	Nac  CREATE TABLE IF NOT EXISTS multimodal_correlation_results (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            predictor TEXT NOT NULL,
            target TEXT NOT NULL,
            lag_days INTEGER NOT NULL,
            medication_phase TEXT NOT NULL,
            n INTEGER NOT NULL,
            eligible_target_days INTEGER NOT NULL,
            expected_target_days INTEGER NOT NULL DEFAULT 0,
            target_coverage REAL NOT NULL DEFAULT 0,
            missing_pairs INTEGER NOT NULL,
            rho REAL,
            p_value REAL,
            q_value REAL,
            status TEXT NOT NULL,
            method TEXT NOT NULL,
            quality_flags TEXT NOT NULL,
            interpretation TEXT NOT NULL,
            computed_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
            UNIQUE(predictor,target,lag_days,medication_phase)
        )z1PRAGMA table_info(multimodal_correlation_results)r   rG   zeALTER TABLE multimodal_correlation_results ADD COLUMN expected_target_days INTEGER NOT NULL DEFAULT 0rI   z]ALTER TABLE multimodal_correlation_results ADD COLUMN target_coverage REAL NOT NULL DEFAULT 0zCREATE INDEX IF NOT EXISTS idx_multimodal_correlations_status ON multimodal_correlation_results(status,target,medication_phase))r   )ra   r   columnss      rY   ensure_schemark     s    	. ",!3!34g!hi#s1viGiW,s	
 'k	
  	J js   A/c                P   | j                   t        vrt        d      | j                  t        vrt        d      | j
                  t        vs| j                  t        vrt        d      | j                  t        vs| j                  t        k7  rt        d      | j                  | j                  | j                  | j                   f}t#        d |D              rt        d      | j                  dk  s5| j                  | j                  cxk  r| j                  k  st        d       t        d      | j                   | j                  | j                  z
  k7  rt        d	      t%        | j&                  t(              s t%        | j&                  t*        t,        f      st        d
      | j                  | j                  z  }t/        j0                  t-        | j&                              r,t/        j2                  t-        | j&                        |dd      st        d      d+d} || j4                  ddd        || j6                  ddd        || j8                  ddd       d}| j                  dk(  rd|dz   }d}| j&                  t:        k\  rt        d      t#        d | j4                  | j6                  | j8                  fD              r$t        d      | j                  dk(  rc|dz   }d}| j&                  t:        k  rt        d      t#        d  | j4                  | j6                  | j8                  fD              rt        d!      |}| j&                  t:        k  s| j                  t<        k  rt        d"      t#        d# | j4                  | j6                  | j8                  fD              rt        d$      | j8                  d uxr  | j8                  d%k  xr | j                  d&k\  }|rd'nd(}| j>                  |k7  rt        d)      | j@                  |k7  rt        d*      y ),Nzpredictor is not allowlistedztarget is not allowlistedz"phase or status is not allowlistedz lag or method is not allowlistedc              3  p   K   | ].  }t        |t              xs t        |t               xs |d k   0 yw)r   N)
isinstanceboolrB   r   rn   s     rY   r   z/_validate_result_for_storage.<locals>.<genexpr>V  s3     
bRW:eT"M*UC*@&@MEAIM
bs   46z$counts must be non-negative integersr   zcount invariants are invalidz"missing-pair count is inconsistentztarget coverage must be numericr   gƠ>)rel_tolabs_tolz*target coverage is invalid or inconsistentc                    | y t        | t              st        | t        t        f      st	        | d      t        j                  t        |             r|t        |       cxk  r|k  sn t	        | d      y )Nz must be numericz is outside its valid range)rn  ro  rB   rH   rm   rj   rk   )rn   loweruppernames       rY   boundedz-_validate_result_for_storage.<locals>.boundedf  sm    =eT"*US%L*Iv%5677}}U5\*%5<2P52Pv%@ABB 3QrX   g      r   rL   rM   rN   r7  r;   )r=  r>  zcoverage status is inconsistentc              3  $   K   | ]  }|d u 
 y wr[   rW   rp  s     rY   r   z/_validate_result_for_storage.<locals>.<genexpr>z       [UuD [   z8insufficient-coverage result contains inferential valuesr:   )r@  rA  z3insufficient-n status is inconsistent with coveragec              3  $   K   | ]  }|d u 
 y wr[   rW   rp  s     rY   r   z/_validate_result_for_storage.<locals>.<genexpr>  ry  rz  z1insufficient-n result contains inferential valuesz8computed status is inconsistent with evidence thresholdsc              3  $   K   | ]  }|d u  
 y wr[   rW   rp  s     rY   r   z/_validate_result_for_storage.<locals>.<genexpr>  s     Wu}Wrz  z(computed result lacks inferential valuesrO  rP  rQ  rR  z2quality flags are not generated by the safe enginez2interpretation is not generated by the safe engine)
rn   rK   rt  rH   ru  rH   rv  r?   r   None)!r@   ALLOWED_PREDICTORSrm   rA   ALLOWED_TARGETSrD   ALLOWED_PHASESrO   ALLOWED_STATUSESrC   rT  rP   rD  rE   rF   rG   rJ   r   rn  rI   ro  rB   rH   rj   rk   iscloserL   rM   rN   rE  rF  rQ   rR   )r   countsexpected_coveragerw  
base_flagsexpected_flagsexpected_interpretationrg  s           rY   _validate_result_for_storager  F  s   11788}}O+455n4M]8]=>>d"fmmv&=;<< 	####	F 
b[a
bb?@@""Q&F//N63N3NN788 	O788v::VXXEE=>>&(($/z&BXBX[^`eZf7g:;;33f6Q6QQ==v5567t||f$$%'8#t@ EFFC FJJc5)FNNCi0FNNCi0J }}//#&>>"V!!%88>??[vzz6>>6>>.Z[[WXX	*	*#&<<U 	  !!$77RSS[vzz6>>6>>.Z[[PQQ#!!$77688i;OWXXW6::v~~v~~*VWWGHHt+X#0EX&((VX.  QZ 	 
 ~-MNN 77MNN 8rX   c                F   t        |      }|D ]  }t        |        t        |        | j                  d       | j	                  d|D cg c]  }|j
                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                   |j"                  |j$                  t'        j(                  |j*                        |j,                  f c}       y c c}w )Nz*DELETE FROM multimodal_correlation_resultsaV  INSERT INTO multimodal_correlation_results
           (predictor,target,lag_days,medication_phase,n,eligible_target_days,
            expected_target_days,target_coverage,missing_pairs,rho,p_value,q_value,status,
            method,quality_flags,interpretation,computed_at)
           VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,CURRENT_TIMESTAMP))r   r  rk  r   executemanyr@   rA   rC   rD   rE   rF   rG   rI   rJ   rL   rM   rN   rO   rP   jsondumpsrQ   rR   )ra   rY  materializedr   s       rY   store_resultsr    s    =L -$V,-*CD	H '		
    &--&BYBY&55v7R7R&&(<(<fjj&..v}}

6//0&2G2G		
		
s   
CD
c                >   t        j                  t              }|j                  dt        d       |j                  |       }|j                  j                         st        d|j                         t        |j                        }	 t        |      }t        ||       |j                          t        d |D              }t        d |D              }t        t        j                   d||d	             |j#                          y
# |j#                          w xY w)N)descriptionz--dbT)typerequiredzDatabase not found: c              3  :   K   | ]  }|j                   d k(    yw)r9   NrO   r   r   s     rY   r   zmain.<locals>.<genexpr>  s     Ivv}}
2I   c              3  :   K   | ]  }|j                   d k(    yw)r:   Nr  r  s     rY   r   zmain.<locals>.<genexpr>  s     S6==,<<Sr  ok)rO   r9   insufficientr   )argparseArgumentParser__doc__add_argumentr
   
parse_argsdbexists
SystemExitrb   rh  r  commitr   printr  r  close)argvparserargsra   rY  r9   r  s          rY   mainr    s    $$9F
TD9T"D77>>/y9::dggJ!*-j'*IIIS7SSdjjDhP\]^_ 	s   A-D
 
D__main__)r`   r
   r   sqlite3.Connection)ra   r  r   r}  )rn   r   r   rK   )rn   r   r   z
str | None)r   r?   r   rB   r   r?   )ry   r?   r   r?   )ra   r  r   dict[str, dict[str, float]]r[   )ra   r  r   &Callable[[str], dict[str, Any]] | Noner   r  )ra   r  r   zCallable[[str], str])r   zIterable[float]r   list[float])r
  r  r  r  r   rH   )r   r  r~   	list[str]r   zlist[list[float]])
r
  r  r  r  r'  r  r(  r?   r   rH   )r@   r?   rA   r?   r   rB   rG  r?   rH  rB   rI  rB   rJ  rH   r
  r  r  r  r'  r  r   r>   )ra   r  rV  r  r   zlist[CorrelationResult])r   r>   r   r}  )ra   r  rY  zIterable[CorrelationResult]r   r}  )r  zlist[str] | Noner   rB   )Hr  
__future__r   r  r  r  r  rj   r"  rt   r\   r   collectionsr   dataclassesr   r   r   r   r	   pathlibr
   typingr   r   r   scipy.statsr   homeBASEDBrF  rE  r   rT  rD  r$  r   r   r   r   r   r~  r  r  r  r>   rb   rd   rp   r{   r   r   r   r   r   r   r   r   r   r  r  r  r5  rM  rh  rk  r  r  r  rS   r  )r   r   s   00rY   <module>r     s   #       	  
 # * . .  * * !tyy{Y)L8		 Q{	M   *8#+/ 9 65/	 	 !!'45Vx56	

&
&
()* 
 ##Oa&b))'=&bb]J  $  &)%&G=
b(!H1, =A&"&9& !&R"JD .//$/1:/GJ/
/>::: 
: 	:
 : : : 	: 	: : :~ CGQ"Q?Q Qh#LNOb2& z
TV
 C 6 'cs   "FF"