U
    —âñj8E  ã                   @   s<  d dl mZ d dlmZmZmZ d dlmZ d dlmZ d dl	m
Z
 dZdZdd	hZed
hƒZd
ZeddhƒZdZdZdd„ Zdd„ Zdd„ Zefdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd>d!d"„Zd#d$„ Zd%d&„ Zd'd(„ Z d?d*d+„Z!d,d-„ Z"d.d/„ Z#d0d1„ Z$d2d3„ Z%d@d4d5„Z&d6d7„ Z'd8d9„ Z(d:d;„ Z)d<d=„ Z*d S )Aé    )Údefaultdict)ÚdatetimeÚ	timedeltaÚtimezone)Ú	ASCENDING)ÚCollectionInvalid)Únormalize_area_idÚScappDBÚfeeder_scoreÚjaulaÚcentroé   Zfeeder_score_reason_audit_v1Zfeeder_score_reason_audit_v2Z	__mixed__c                 C   s   t | ƒ d S ©N)Úprint)Útext© r   ú=/var/www/itgmanager/itgmanager/Analytic/Scapp_feeder_score.pyÚ_feeder_score_logger   s    r   c                 C   s   t | ƒ ¡  ¡ S r   )ÚstrÚstripÚ
capitalize)Úvaluer   r   r   Ú_capitalize_token   s    r   c              
   C   s¤   t | tƒr| }nrt | tƒrz|  ¡ }| d¡r<|d d… d }zt |¡}W q‚ tk
rv } ztdƒ|‚W 5 d }~X Y q‚X ntdƒ‚|jd k	r | t	j
¡jd d�}|S )NÚZéÿÿÿÿz+00:00ztimestamp invalido)Útzinfo)Ú
isinstancer   r   r   ÚendswithÚfromisoformatÚ
ValueErrorr   Ú
astimezoner   ÚutcÚreplace)r   Ú	timestampÚ	raw_valueÚexcr   r   r   Ú_coerce_timestamp   s    



r&   c                 C   s®   ||   ¡ kr@z|  |¡ td|› d�ƒ W n tk
r>   Y nX | | }|jdtfdtfdtfgdddd� |jdtfdtfgd	dd
� |jdtfdtfdtfgddd
� |S )Nz
Coleccion z creada como coleccion normal.Ú	centro_idÚ	camera_idr#   TZ!idx_feeder_score_centro_camera_ts)ÚuniqueÚnameÚ
backgroundZidx_feeder_score_centro_ts)r*   r+   ÚscopeZ idx_feeder_score_scope_centro_ts)Úlist_collection_namesÚcreate_collectionr   r   Úcreate_indexr   )Úscapp_dbÚdatabase_nameÚ
collectionr   r   r   Úensure_feeder_score_collection2   s0    
üýýr3   c              
   C   sÂ   t | tƒr| gn| }t |tƒs&tdƒ‚g }|D ]Ž}t |tƒsJtd|›�ƒ‚| d¡}|s`tdƒ‚| dd¡}|tkr‚td|›�ƒ‚| dd	„ | ¡ D ƒ|t| d
¡ƒ|| d¡p²i dœ–¡ q.|S )Nz&Payload debe ser dict o lista de dictszDocumento invalido: r(   z-Falta 'camera_id' en alguno de los documentosr,   r   zscope invalido: c                 S   s   i | ]\}}|d kr||“qS )Ú_idr   )Ú.0Úkeyr   r   r   r   Ú
<dictcomp>b   s       z?validate_and_normalize_feeder_score_payload.<locals>.<dictcomp>r#   Údata)r(   r#   r,   r8   )	r   ÚdictÚlistr   ÚgetÚVALID_SCOPESÚappendÚitemsr&   )ÚpayloadÚdocsÚ
normalizedÚdocr(   r,   r   r   r   Ú+validate_and_normalize_feeder_score_payloadN   s,    


ûÿ	rC   c                 C   sn   t | ƒ}t ¡ }d}|pg D ]6}|j||d |d dœ|||dœ–dd� |d7 }qtd	|› d
|› d�ƒ |S )Nr   r(   r#   )r'   r(   r#   )r'   ÚupdatedT)Úupsertr   zFeederScore: z* documentos almacenados/actualizados para Ú.)r3   r   ÚnowÚreplace_oner   )r0   r@   r'   r2   Z
updated_atÚsavedrB   r   r   r   Úsave_feeder_score_payloadl   s$    ýýõ
rJ   c           	   
   C   sà   z2|   |||dœdœddi¡ dtfdtfg¡}W nB tk
rt } z$td|jj› d|› �ƒ i  W Y ¢S d }~X Y nX ttƒ}|D ]L}| 	d¡}t
|tƒsœq‚d	| 	d	d
¡i| 	d¡p¶i –|| d¡ | 	d¡< q‚tt| ¡ ƒƒS )N©z$gtez$lt©r'   r#   r4   r   r#   r(   zError leyendo feeder score (z): r,   r   r8   ú%d/%m/%Y)ÚfindÚsortr   Ú	Exceptionr   Ú__traceback__Ú	tb_linenor   r9   r;   r   r   ÚstrftimeÚsortedr>   )	r2   r'   Ú	start_dayÚend_dayÚcursorr%   ÚgroupedrB   r#   r   r   r   Úfetch_feeder_score_data„   s.    þûú

 
ÿþrY   c                 C   sP   t |  ¡ krd S | t  jd|iddddœddgd�}|s<d S | d¡pN| d	¡S )
Nr'   r   r   )r4   rD   r#   )rD   r   )r#   r   )rO   rD   r#   )ÚFEEDER_SCORE_COLLECTION_NAMEr-   Úfind_oner;   )r0   r'   rB   r   r   r   Ú!get_last_feeder_score_received_at�   s    
ýr\   c                 C   s˜   t |ƒ}|tt|ƒd� }t| dd|› d�i||dœdœƒ}ttƒ}| ¡ D ]4\}}| ¡ D ]"\}	}
t|	|
ƒ}|r\||| |	< q\qLdd„ t| ¡ ƒD ƒS )	N©Údaysú$regexú^Ú-rK   rL   c                 S   s"   i | ]\}}|t t| ¡ ƒƒ“qS r   ©r9   rT   r>   ©r5   Údayr>   r   r   r   r7   º   s      z0compute_feeder_score_by_area.<locals>.<dictcomp>)	r   r   ÚintÚ_fetch_docs_by_day_and_centerr   r9   r>   Ú_build_center_rollup_cellrT   )r0   Úarea_idrU   Ú
day_rangesrV   Úgrouped_docsÚresponserd   Úcentersr'   r@   Úcellr   r   r   Úcompute_feeder_score_by_area«   s    þ
rn   Nc                 C   s&  t |ƒ}|tt|ƒd� }t| dd|› d�i||dœdœƒ}ttƒ}| ¡ D ]Â\}}	ttƒ}
|	 ¡ D ]R\}}t||ƒ}|s|qd| 	d¡}t
|ƒdkr¤d |d d… ¡n|}|
|  |¡ qd|dkrê|
 ¡ D ]}|D ]}||| |d	 < qÐqÈqL|
 ¡ D ]\}}t||ƒ|| |< qòqLd
d„ t| ¡ ƒD ƒS )Nr]   r_   r`   ra   rK   rL   é   Úcenterr*   c                 S   s"   i | ]\}}|t t| ¡ ƒƒ“qS r   rb   rc   r   r   r   r7   Ø   s      z2compute_feeder_score_by_region.<locals>.<dictcomp>)r   r   re   rf   r   r9   r>   r:   rg   ÚsplitÚlenÚjoinr=   ÚvaluesÚ_build_area_rollup_cellrT   )r0   Ú	region_idrU   ri   ÚgranularityrV   rj   rk   rd   rl   Z
area_cellsr'   r@   Zcenter_cellÚpartsrh   Zcenters_in_arear   r   r   Úcompute_feeder_score_by_region½   s.    þ

"ry   c                 C   s˜   t |  ¡ kri S | t   |ddi¡ dtfdtfdtfdtfg¡}tdd„ ƒ}|D ]@}| d¡}| d¡}t|tƒrR|szqR|| 	d	¡ |  
|¡ qR|S )
Nr4   r   r#   r'   r,   r(   c                   S   s   t tƒS r   )r   r:   r   r   r   r   Ú<lambda>æ   ó    z/_fetch_docs_by_day_and_center.<locals>.<lambda>rM   )rZ   r-   rN   rO   r   r   r;   r   r   rS   r=   )r0   Zmatch_filterrW   rX   rB   r#   r'   r   r   r   rf   Û   s     ü

rf   c                    sT  t dd„ |D ƒd ƒ‰ ‡ fdd„|D ƒ}ˆ d kr2d S ˆ  d¡p>i }d}d}d}g }tƒ }|D ]ˆ}	|	 d¡pji }
|t|
 d¡dƒ7 }|ttt|
d	ƒdƒƒ7 }|ttt|
d
ƒdƒƒ7 }| t|
 d¡ƒ¡ |
 d¡d k	rZ| |	 d¡¡ qZd| | d¡| d¡| dd¡t	|dƒ||t
|ƒ| dt|ƒ¡| d¡dœ}t| d¡tƒ�rP| d¡|d< |S )Nc                 s   s.   | ]&}|  d ¡dks"|  d¡dkr|V  qdS )r,   r   r(   Ú
__CENTER__N©r;   ©r5   rB   r   r   r   Ú	<genexpr>ñ   s       z,_build_center_rollup_cell.<locals>.<genexpr>c                    s&   g | ]}|ˆ k	r|  d ¡dkr|‘qS )r(   r|   r}   r~   ©Z
center_docr   r   Ú
<listcomp>ò   s       z-_build_center_rollup_cell.<locals>.<listcomp>r8   ç        r   Údelivered_food_kgÚalarmas_totalÚalarmas_no_atendidasÚreaction_timeÚscorer(   r   ÚstatusÚaggregationÚfood_weightedé   Ún_jaulas_scoredÚn_jaulas_fasted)r,   r*   rˆ   r‡   r‰   rƒ   r„   r…   r†   rŒ   r�   Úrw)Únextr;   ÚsetÚ_numberre   Ú_alarm_valueÚextendÚ_reaction_samplesÚaddÚroundÚ_summarize_reactionrr   r   r9   )r'   r@   Z	cage_docsZcenter_dataÚfoodÚalarm_totalÚalarm_unattendedÚreaction_samplesZscored_cagesrB   r8   rm   r   r€   r   rg   ð   sB    
õrg   c                 C   s  t dd„ |D ƒƒ}d}d}d}d}g }d}|D ]˜}	t|	 d¡ƒ}
tdt|	 d¡dƒƒ}|
d k	r‚|d7 }|dkr‚||
| 7 }||7 }|tt|	 d¡dƒƒ7 }|tt|	 d	¡dƒƒ7 }| t|	 d
¡ƒ¡ q.d| |rÔdnd|dkrìt|| dƒnd dt|dƒ||t|ƒ|t	dd„ |D ƒdƒdœS )Nc                 s   s$   | ]}t d t| d¡d ƒƒV  qdS )r‚   rƒ   N)Úmaxr‘   r;   ©r5   rm   r   r   r   r     s     z*_build_area_rollup_cell.<locals>.<genexpr>r‚   r   r‡   rƒ   r   r„   r…   r†   ÚareaÚfinalZfastedro   rŠ   r‹   c                 s   s   | ]}|  d ¡V  qdS )rŽ   Nr}   r�   r   r   r   r   8  s     )r,   r*   rˆ   r‡   r‰   rƒ   r„   r…   r†   Zn_centros_scoredrŽ   )
Úsumr‘   r;   rœ   re   r“   r”   r–   r—   Úaggregate_rw)rh   Zcenter_cellsr˜   Z	score_numZ	score_denr™   rš   r›   Zscored_centersrm   r‡   Úweightr   r   r   ru     s<    
õru   rŠ   c              
   C   sà  dd„ | pg D ƒ}|sd S |dk}d}d}d}t ƒ }t ƒ }t ƒ }	t ƒ }
t ƒ }|D ]¼}tdt| d¡dƒƒ}|rr|nd}|dkr‚d}||7 }||7 }||t| d¡dƒ 7 }| t|ƒ¡ | t|ƒ¡ | d	¡rà|	 | d	¡¡ |
 t| d
¡dƒ¡ | | di ¡ ¡ ¡ qP|dk�s&t	|ƒdk�r*d S t
t|ƒƒ}|tk�rDd S i }t|ƒD �]
}d}d}d}|D ]´}| d¡�pxi  |¡�p„i }tdt| d¡dƒƒ}|�r¦|nd}|dk�r¸d}tdtdt| d¡dƒƒƒ}tdtdt| d¡dƒƒƒ}||| 7 }||| | 7 }||| 7 }�qf|dk�r4t|| dƒnd|dk�rNt|| dƒnddœ||< �qPt|ƒ}t	|ƒdk�r||d nt||t	|	ƒdk�rœt
t|	ƒƒntt	|
ƒdk�r¸t
t|
ƒƒnd t|�rÆ|n|dƒt|| dƒ|dœS )Nc                 S   s4   g | ],}t |tƒrt | d ¡tƒr| d ¡r|‘qS )Údims©r   r9   r;   )r5   Úkernelr   r   r   r�   >  s
   
  
ÿz aggregate_rw.<locals>.<listcomp>rŠ   r‚   Úfood_kgç      ð?r   Ú	deliv_pctÚconfig_versionÚbaser£   r   ÚcovÚqr‹   )r¬   r«   )Úalgo_versionÚalgo_versionsÚcontract_versionr©   rª   r¦   r¨   r£   )r�   rœ   r‘   r;   ÚupdateÚ_kernel_algo_versionsr•   Ú_rw_contract_versionÚkeysrr   r�   ÚiterÚSUPPORTED_RW_CONTRACT_VERSIONSrT   Úminr–   ÚMIXED_ALGO_VERSIONÚMIXED_CONFIG_VERSION)Zkernelsr‰   ÚchildrenZweightedZtotal_weightZ
food_totalZ	deliv_numr®   Zcontract_versionsZconfig_versionsÚbasesZdim_keysr¥   r˜   r¢   r¯   r£   ÚdimZcov_numZq_numZq_denÚitemr«   r¬   Zsorted_algo_versionsr   r   r   r¡   <  s|    ÿ


þør¡   c              	   C   sx  t | ƒsd S |pi  d¡pi }t|p&i  d¡t|  d¡dƒƒ}t|pFi  d¡dƒ}t|pZi  d¡dƒ}t|pni  dd	¡ƒ}d}d}|  d
¡pŽi  ¡ D ]r\}	}
tdt| |	¡dƒƒ}tdtdt|
 d¡dƒƒƒ}tdtdt|
 d¡dƒƒƒ}||| | 7 }||| 7 }q”|dk�r|| nd}ttdt|  d¡dƒd ƒ| |ƒ| }|�rTd| nd}t|t||d| |  | ƒƒS )NÚweightsrª   r‚   ZsfrCapg      .@Z	sfrPerPctgš™™™™™É?ZallowOverscoreTr£   r§   r«   r¬   r   r¨   g      Y@)Úis_recomputabler;   r‘   Úboolr>   rœ   r¶   )r¥   Úparamsr½   rª   Zsfr_capZsfr_per_pctZallow_overscoreÚnumZdenr»   r¼   r¢   r«   r¬   Zq_valueZbonusZceilingr   r   r   Úreweight†  s&     (rÂ   c                 C   s4   t | tƒo2t| ƒtko2t |  d¡tƒo2t|  d¡ƒS )Nr£   )r   r9   r²   rµ   r;   r¿   )r¥   r   r   r   r¾   œ  s    

ÿþür¾   c                 C   s\   t | tƒsd S |  d¡}|d kr2|  d¡tkr2tS t|d ƒ}|d k	rXt|ƒ ¡ rXt|ƒS d S )Nr¯   r­   )	r   r9   r;   Ú#LEGACY_RW_CONTRACT_V1_ALGO_VERSIONSÚLEGACY_RW_CONTRACT_VERSIONr‘   ÚfloatÚ
is_integerre   )r¥   ÚversionÚnumberr   r   r   r²   ¥  s    


r²   c                 C   sj   t | tƒr|  d¡nd }t |tttfƒr>dd„ |D ƒ}|r>|S t | tƒrR|  d¡nd }|rdt|ƒhS dhS )Nr®   c                 S   s   h | ]}|rt |ƒ’qS r   )r   )r5   rÇ   r   r   r   Ú	<setcomp>²  s      z(_kernel_algo_versions.<locals>.<setcomp>r­   Z__unknown__)r   r9   r;   r:   Útupler�   r   )r¥   ÚversionsÚcleanedrÇ   r   r   r   r±   ¯  s    r±   c              	   C   s.   zt | ƒ}W n ttfk
r(   | Y S X |S r   )rÅ   Ú	TypeErrorr   )r   ÚfallbackrÈ   r   r   r   r‘   ¹  s
    
r‘   c                 C   sR   t | tƒr|  d¡ni }t |tƒr:| |¡d k	r:| |¡S t | tƒrN|  |¡S d S )NZreasons_summaryr¤   )r8   r6   Úreasonsr   r   r   r’   Á  s    
r’   c                 C   s|   t | tƒsg S |  d¡}t |tƒr0dd„ |D ƒS |  d|  d¡¡}tt|  d¡dƒƒ}t|ƒ}|d ksn|dkrrg S |g| S )NÚsamples_secc                 S   s    g | ]}t |ƒd k	rt |ƒ‘qS r   ©r‘   ©r5   r   r   r   r   r�   Í  s      z%_reaction_samples.<locals>.<listcomp>Úmean_secÚavgÚnr   )r   r9   r;   r:   re   r‘   )r†   ÚsamplesrÔ   rÕ   Z
avg_numberr   r   r   r”   È  s    


r”   c                 C   sX   t dd„ dd„ | pg D ƒD ƒƒ}|s.dg dœS t|ƒt|ƒt|ƒ t|dƒ|d |dœS )	Nc                 s   s   | ]}|d k	r|V  qd S r   r   rÒ   r   r   r   r   ×  s      z&_summarize_reaction.<locals>.<genexpr>c                 s   s   | ]}t |ƒV  qd S r   rÑ   )r5   r¼   r   r   r   r   ×  s     r   )rÕ   rÐ   é_   r   )rÕ   rÓ   Úp95_secÚmax_secrÐ   )rT   rr   r    Ú_percentile)rÐ   rÖ   r   r   r   r—   Ö  s     
ûr—   c                 C   sr   | sd S t | ƒdkr| d S t | ƒd |d  }t|ƒ}t|d t | ƒd ƒ}|| }| | | | | |  |  S )Nr   r   éd   )rr   re   r¶   )Zsorted_valuesZpctÚposÚlowÚhighÚfracr   r   r   rÚ   ã  s    rÚ   )N)rŠ   )N)+Úcollectionsr   r   r   r   Úpymongor   Úpymongo.errorsr   ÚAnalytic.centro_idsr   ÚSCAPP_DATABASE_NAMErZ   r<   Ú	frozensetrµ   rÄ   rÃ   r·   r¸   r   r   r&   r3   rC   rJ   rY   r\   rn   ry   rf   rg   ru   r¡   rÂ   r¾   r²   r±   r‘   r’   r”   r—   rÚ   r   r   r   r   Ú<module>   sL   
þ
($
J	


