Ë
    ©¨j3  ã                  ó  — d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z ddlZddlmZ  ej                   g d¢«      Ze G 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d„Zd d„Zd!d„Zd"d„Zedk(  r e«        yy)#zLAudit fused and per-view binary PLY point clouds without loading them fully.é    )ÚannotationsN)Ú	dataclass)ÚPath)ÚcKDTree))Úxú<f4)Úyr   )Úzr   )ÚredÚu1)Úgreenr   )Úbluer   c                  ó,   — e Zd ZU ded<   ded<   ded<   y)ÚPlyInfor   ÚpathÚintÚcountÚheader_bytesN)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__© ó    õ   ì „ì²˜ë¦¬/audit_ply_fusion.pyr   r      s   … à
ƒJØƒJØÔr   r   c           	     óÄ  — | j                  d«      5 }d}d|vrG|j                  d«      }|st        d| › �«      ‚||z  }t        |«      dkD  rt        d| › �«      ‚d|vrŒGd d d «       j	                  d«      t        d«      z   }|d | j                  d«      }d	|vrt        d
| › �«      ‚t        d„ |j                  «       D «       «      }t        |j                  dd«      d   «      }||t        j                  z  z   }| j                  «       j                  |k7  r-t        d| › d| j                  «       j                  › d|› d�«      ‚t        | ||«      S # 1 sw Y   Œ÷xY w)NÚrbr   s   end_header
i   zMissing PLY end_header: i   zUnexpectedly large PLY header: Úasciizformat binary_little_endian 1.0z,Only binary little-endian PLY is supported: c              3  óD   K  — | ]  }|j                  d «      sŒ|–— Œ y­w)zelement vertex N)Ú
startswith)Ú.0r   s     r   Ú	<genexpr>zply_info.<locals>.<genexpr>+   s   è ø€ ÐPÑ,�a°·±Ð=NÕ0O”Ñ,ùs   ‚ ™ Ú é   zPLY size/header mismatch: z (z != Ú))ÚopenÚreadÚ
ValueErrorÚlenÚindexÚdecodeÚnextÚ
splitlinesr   ÚrsplitÚ	PLY_DTYPEÚitemsizeÚstatÚst_sizer   )	r   ÚfhÚheaderÚblockÚendÚtextÚliner   Úexpecteds	            r   Úply_infor:      sd  € Ø	�‰�4Œ˜BØˆØ VÑ+Ø—G‘G˜D“MˆEÙÜ Ð#;¸D¸6Ð!BÓCÐCØ�e‰OˆFÜ�6‹{˜UÒ"Ü Ð#BÀ4À&Ð!IÓJÐJð  VÒ+÷ 
ð �,‰,�Ó
'¬#¨oÓ*>Ñ
>€CØ�$�3ˆ<×Ñ˜wÓ'€DØ(°Ñ4ÜÐGÈÀvÐNÓOÐOÜÑP˜4Ÿ?™?Ô,ÓPÓP€DÜ�—‘˜C Ó# AÑ&Ó'€EØ�UœY×/Ñ/Ñ/Ñ/€HØ‡y�yƒ{×Ñ˜hÒ&ÜÐ5°d°V¸2¸d¿i¹i»k×>QÑ>QÐ=RÐRVÐW_ÐV`Ð`aÐbÓcÐcÜ�4˜ Ó$Ð$÷% 
ˆús   ’AEÅEc                ó|   — t        j                  | j                  t        d| j                  | j
                  f¬«      S )NÚr)ÚdtypeÚmodeÚoffsetÚshape)ÚnpÚmemmapr   r/   r   r   )Úinfos    r   Úmmap_plyrD   3   s.   € Ü�9‰9�T—Y‘Y¤i°cÀ$×BSÑBSØ ŸJ™J˜=ô*ð *r   c                ó.  — t        | «      }t        | j                  |«      }t        j                  |t        j
                  ¬«      | j                  z  | j                  dz  z   |z  }||   }t        j                  |d   |d   |d   f«      j                  t        j                  «      }t        j                  |d   |d   |d   f«      j                  t        j                  «      }t        j                  |«      j                  d	¬
«      }||   ||   fS )N)r=   é   r   r	   r
   r   r   r   r$   ©Úaxis)rD   Úminr   rA   ÚarangeÚint64Úcolumn_stackÚastypeÚfloat64Úuint8ÚisfiniteÚall)	rC   ÚlimitÚdataÚnÚidxÚrowsÚxyzÚrgbÚkeeps	            r   Ú
sample_plyrZ   8   sâ   € Ü�D‹>€DÜˆD�J‰J˜Ó€Aä�I‰I�aœrŸx™xÔ(¨4¯:©:Ñ5¸¿
¹
Àa¹ÑGÈAÑM€CØ�‰9€DÜ
�/‰/˜4 ™9 d¨3¡i°°c±Ð;Ó
<×
CÑ
CÄBÇJÁJÓ
O€CÜ
�/‰/˜4 ™;¨¨W©°t¸F±|ÐDÓ
E×
LÑ
LÌRÏXÉXÓ
V€CÜ�;‰;�sÓ×Ñ QÐÓ'€DØˆt‰9�c˜$‘iÐÐr   c                óÖ  — t        j                  |g d¢d¬«      }||j                  d¬«      z
  }|j                  |z  t	        dt        |«      dz
  «      z  }t         j                  j                  |«      \  }}t        j                  |«      d d d…   }||   |d d …|f   }}t        j                  |ddgd¬«      \  }	}
|t        j                  ||	k\  ||
k  z  d¬«         }t        |«      dkD  r9|t        j                  dt        |«      dz
  d«      j                  t        «         }t        |«      }|j                  |dd¬	«      d   d d …df   }i }d
D ]t  }t        j                  ||z  «      j                  t         j                   «      }t        t        j"                  |d¬«      «      }||t        |«      z  dœ|t%        |«      <   Œv t%        | j&                  «      | j&                  j)                  «       j*                  | j,                  t        |«      t/        d«      D ��ci c]"  \  }}t%        |«      ||   j1                  «       “Œ$ c}}|d   |d   z
  j1                  «       |j                  d¬«      j1                  «       |j1                  «       |j1                  «       t3        t        j                  |d«      «      t3        t        j                  |d«      «      t3        t        j                  |d«      «      t3        t        j                  |dk(  «      «      dœ|j5                  d¬«      j1                  «       |j	                  d¬«      j1                  «       |dœS c c}}w )N)r   çš™™™™™¹?r$   é2   éc   gš™™™™ùX@éd   r   rG   r$   éÿÿÿÿr^   iPÃ  rF   ©ÚkÚworkers)r\   ç      à?ç      ð?g       @ç      @)Úunique_sample_voxelsÚsample_occupancy_ratior]   éZ   )Úp50Úp90Úp99Ú
zero_ratio)r   Ú
file_bytesÚvertex_countÚsample_countÚsample_quantiles_xyzÚsample_extent_xyzÚsample_centroid_xyzÚpca_varianceÚpca_axes_columnsÚnearest_neighbor_sampleÚrgb_minÚrgb_maxÚvoxel_sample)rA   Ú
percentileÚmeanÚTÚmaxr)   ÚlinalgÚeighÚargsortrQ   ÚlinspacerM   r   r   ÚqueryÚfloorrK   ÚuniqueÚstrr   r1   r2   r   Ú	enumerateÚtolistÚfloatrI   )rC   rW   rX   ÚqÚcenteredÚcovÚeigvalÚeigvecÚorderÚloÚhiÚcentralÚtreeÚnnÚvoxelÚsizeÚkeysr„   ÚiÚps                       r   Ústatsr™   D   sÉ  € Ü
�‰�cÒ8¸qÔA€AØ�S—X‘X 1�XÓ%Ñ%€HØ
�*‰*�xÑ
¤# a¬¨S«°A©Ó"6Ñ
6€CÜ—Y‘Y—^‘^ CÓ(�N€FˆFÜ�J‰J�vÓ™t ˜tÑ$€EØ˜E‘] Fª1¨e¨8Ñ$4ˆF€Fô �]‰]˜3  B ¨aÔ0�F€BˆØ”"—&‘&˜# ™)¨¨r©	Ñ2¸Ô;Ñ<€GÜ
ˆ7ƒ|�eÒØœ"Ÿ+™+ a¬¨W«¸Ñ)9¸5ÓA×HÑHÌÓMÑNˆÜ�7Ó€DØ	�‰�G˜q¨"ˆÓ	-¨aÑ	0²°A°Ñ	6€Bà€EÛ)ˆÜ�x‰x˜˜d™
Ó#×*Ñ*¬2¯8©8Ó4ˆÜ”R—Y‘Y˜t¨!Ô,Ó-ˆà$*Ø&,¬s°3«xÑ&7ñ
ˆŒc�$‹iÒð *ô �D—I‘I“Ø—i‘i—n‘nÓ&×.Ñ.ØŸ
™
Ü˜C›ÜCLÐMjÔCkÔ lÑCk¹4¸1¸a¤ Q£¨¨1©¯©«Ñ!6ÐCkÒ lØ ™e a¨¡d™l×2Ñ2Ó4Ø"Ÿx™x¨Q˜xÓ/×6Ñ6Ó8ØŸ™›Ø"ŸM™M›OäœŸ™ r¨2Ó.Ó/ÜœŸ™ r¨2Ó.Ó/ÜœŸ™ r¨2Ó.Ó/Ü¤§¡¨¨a©Ó 0Ó1ñ	$
ð —7‘7 �7“?×)Ñ)Ó+Ø—7‘7 �7“?×)Ñ)Ó+Øñ%ð ùó
 !ms   È('M%c           
     óú  — t        | «      }t        j                  dt        j                  «      }t        j                  dt        j                   «      }d}d}d}t	        d| j
                  |«      D �]G  }||t        ||z   | j
                  «       }	t        j                  |	d   |	d   |	d   f«      }
t        j                  |
«      j                  d¬«      }|t        | j                  «       «      z  }|
|   }
t        |
«      sŒ”t        j                  ||
j                  d¬«      «      }t        j                  ||
j                  d¬«      «      }|�'|t        t        j                  ||
d   k(  «      «      z  }|t        t        j                  |
dd |
dd	 k(  d¬«      j                  «       «      z  }|
d	   }�ŒJ | j
                  |j!                  «       |j!                  «       ||z
  j!                  «       ||d
œS )zARead every fused vertex to validate coordinates and exact bounds.é   r   Nr   r	   r
   r$   rG   r`   )ro   Úmin_xyzÚmax_xyzÚ
extent_xyzÚnonfinite_verticesÚadjacent_exact_duplicates)rD   rA   ÚfullÚinfÚranger   rI   rL   rP   rQ   r   Úsumr)   ÚminimumÚmaximumr}   r‡   )rC   Ú
chunk_sizerS   ÚlowerÚupperÚ	nonfiniteÚadjacent_duplicatesÚpreviousÚstartrV   rW   Úfinites               r   Úfull_scan_checkr¯   r   s´  € ä�D‹>€DÜ�G‰G�A”r—v‘vÓ€EÜ�G‰G�AœŸ™�wÓ€EØ€IØÐØ€HÜ�q˜$Ÿ*™* j×1ˆØ�Eœ#˜e jÑ0°$·*±*Ó=Ð>ˆÜ�o‰o˜t C™y¨$¨s©)°T¸#±YÐ?Ó@ˆÜ—‘˜SÓ!×%Ñ%¨1Ð%Ó-ˆØ”S˜6˜'Ÿ™›Ó)Ñ)ˆ	Ø�&‰kˆÜ�3ŒxØÜ—
‘
˜5 #§'¡'¨q '£/Ó2ˆÜ—
‘
˜5 #§'¡'¨q '£/Ó2ˆØÐØ¤3¤r§v¡v¨h¸#¸a¹&Ñ.@Ó'AÓ#BÑBÐØœs¤2§6¡6¨#¨a¨b¨'°S¸¸"°XÑ*=ÀAÔ#F×#JÑ#JÓ#LÓMÑMÐØ�r‘7Šð 2ð Ÿ
™
Ø—<‘<“>Ø—<‘<“>Ø˜u‘}×,Ñ,Ó.Ø'Ø%8ñð r   c                ód  — t        j                  | ddgd¬«      \  }}| t        j                  | |k\  | |k  z  d¬«         } |t        j                  ||dz
  k\  ||dz   k  z  d¬«         }t        | «      j	                  |dd¬«      d   }t        |«      t        t        j                  |d	«      «      t        t        j                  |d
«      «      t        t        j                  |d«      «      t        t        j                  |dk  «      «      t        t        j                  |dk  «      «      ddœS )zFDiagnostic distance only; samples are not known point correspondences.çš™™™™™É?ç33333óX@r   rG   r$   é   r`   ra   r]   ri   é_   rF   zEsample-to-sample diagnostic; not a calibrated correspondence residual)Úcomponent_sample_keptÚp50_mmÚp90_mmÚp95_mmÚ
within_2mmÚ
within_5mmÚinterpretation)rA   rz   rQ   r   r‚   r)   rˆ   r{   )ÚfusedÚ	componentr¨   r©   Údistances        r   Úsampled_distance_to_fusedr¿   ’   s  € ä—=‘= ¨¨T¨
¸Ô;�L€Eˆ5Ø”"—&‘&˜% 5™.¨U°e©^Ñ<À1ÔEÑF€EØœ"Ÿ&™& )¨u°q©yÑ"8¸YÈ%ÐRSÉ)Ñ=SÑ!TÐ[\Ô]Ñ^€IÜ�u‹~×#Ñ# I°¸BÐ#Ó?ÀÑB€Hä!$ Y£ÜœŸ™ h°Ó3Ó4ÜœŸ™ h°Ó3Ó4ÜœŸ™ h°Ó3Ó4ÜœBŸG™G H°¡MÓ2Ó3ÜœBŸG™G H°¡MÓ2Ó3Øañð r   c           	     ó0  — t        j                  t        j                  | dd¬«      t        j                  |dd¬«      «      }t        j                  | |z
  |z  «      j	                  t         j
                  «      }t        j                  ||z
  |z  «      j	                  t         j
                  «      }t        j                  t         j                  |j                  j                  |j                  d   z  f«      }t        j                  t        j                  |«      j                  |«      j                  «       «      }t        j                  t        j                  |«      j                  |«      j                  «       «      }t        j                  ||d¬«      j                  }	t!        |«      t!        |«      z   |	z
  }
|t#        |	«      t#        |
«      |
r|	|
z  ndt!        |«      r|	t!        |«      z  ndt!        |«      r|	t!        |«      z  dœS ddœS )Nr$   r   rG   T)Úassume_uniquere   )Ú
voxel_sizeÚintersectionÚunionÚjaccardÚ	a_coveredÚ	b_covered)rA   r¥   rz   rƒ   rM   Úint32r=   Úvoidr0   r@   r„   ÚascontiguousarrayÚviewÚravelÚintersect1dr•   r)   r   )ÚaÚbrÂ   ÚoriginÚqaÚqbÚrowÚuaÚubÚinterrÄ   s              r   Úoverlap_scorer×   £   sˆ  € Ü�Z‰ZœŸ™ a¨°Ô3´R·]±]À1ÀaÈaÔ5PÓQ€FÜ	�‰�1�v‘: Ñ+Ó	,×	3Ñ	3´B·H±HÓ	=€BÜ	�‰�1�v‘: Ñ+Ó	,×	3Ñ	3´B·H±HÓ	=€Bä
�(‰(”B—G‘G˜RŸX™X×.Ñ.°·±¸!±Ñ<Ð=Ó
>€CÜ	�‰”2×'Ñ'¨Ó+×0Ñ0°Ó5×;Ñ;Ó=Ó	>€BÜ	�‰”2×'Ñ'¨Ó+×0Ñ0°Ó5×;Ñ;Ó=Ó	>€BÜ�N‰N˜2˜r°Ô6×;Ñ;€EÜ�‹G”c˜"“gÑ Ñ%€Eà Ü˜E›
Ü�U“Ù$)�5˜5’=¨sÜ(+¨B¬�UœS ›W’_°SÜ(+¨B¬�UœS ›W‘_ñð ð 69ñð r   c                ó  — t        j                  | D �cg c]  }|d d …|f   ‘Œ c}d¬«      }t        j                  |dd¬«      }t        j                  |dd¬«      }t        j                  ||z
  dz  d«      }||z
  ||z   fS c c}w )Nr   rG   r±   r²   g¸…ëQ¸ž?g�íµ ÷Æ°>)rA   Úconcatenaterz   r¦   )ÚgroupsÚaxesÚgÚcatr�   r�   Úpads          r   Úrobust_limitsrß   ·   s}   € Ü
�.‰.©fÓ5©f¨˜!šA˜t˜G›*¨fÑ5¸AÔ
>€CÜ	�‰�s˜B QÔ	'€BÜ	�‰�s˜D qÔ	)€BÜ
�*‰*�b˜2‘g ‘_ dÓ
+€CØ�‰8�R˜#‘XÐÐùò	 6s   ”Bc           	     ó,  — | j                  |d d …|d   f   |d d …|d   f   |||dd¬«       | j                  |dd¬«       | j                  dd	¬
«       | j                  d|d      «       | j	                  d|d      «       | j                  dd¬«       y )Nr   r$   T)ÚsÚcÚalphaÚ
linewidthsÚ
rasterizedé
   Úbold©ÚfontsizeÚweightÚequalÚbox©Ú
adjustableÚXYZç¸…ëQ¸¾?rd   )rã   Ú	linewidth)ÚscatterÚ	set_titleÚ
set_aspectÚ
set_xlabelÚ
set_ylabelÚgrid)ÚaxrW   rÛ   ÚcolorÚtitler•   rã   s          r   Úscatter_projectionrû   ¿   s”   € Ø‡J�Jˆs’1�d˜1‘g�:‰ ¢A t¨A¡w J¡°4¸5ÈØ¨ð ô .à‡L�L� ¨F€LÔ3Ø‡M�M�' e€MÔ,Ø‡M�M�%˜˜Q™‘.Ô!Ø‡M�M�%˜˜Q™‘.Ô!Ø‡G�G�# €GÕ$r   c                óâ  — t        | j                  d«      «      }|D �cg c]  }d|j                  vsŒ|| dz  k7  sŒ|‘Œ }}g }|D ]¡  }t        |j                  j                  d«      «      }dt	        |j                  «      v rd}nLd|j                  j
                  v rd}n1d|j                  j
                  v rd	}n|j                  j
                  }|j                  |||d
œ«       Œ£ |S c c}w )Nz **/all_merge_pointcloud_full.plyÚviewerz#datas/all_merge_pointcloud_full.plyzmerged_pointcloud_*.plyÚac28_plyÚ18Ú18h01Ú16Ú16h)Úlabelr¼   Ú
components)ÚsortedÚglobÚpartsÚparentr…   ÚnameÚappend)Úrootr¼   r˜   ÚrunsÚcompsr  s         r   Ú	find_runsr  É   sÕ   € Ü�4—9‘9Ð?Ó@ÓA€EáÓo™�1 °·±Ò!8¸QÀ$ÐInÑBnÓ=nŠQ˜€EÐoØ€DÛˆÜ�q—x‘x—}‘}Ð%>Ó?Ó@ˆØœ˜QŸX™X›Ñ&Ø‰EØ�Q—X‘X—]‘]Ñ"Ø‰EØ�Q—X‘X—]‘]Ñ"Ø‰Eà—H‘H—M‘MˆEØ�‰˜e¨a¸uÑEÕFð ð €Kùò ps   ŸC,³C,¼C,c                 óp  — t        j                  «       } | j                  dt        t        t        «      j                  «       j                  d   ¬«       | j                  dt        d ¬«       | j                  dt        d¬«       | j                  «       }|j                  j                  «       }|j                  xs |dz  j                  «       }|j                  dd¬	«       t        |«      }d
|j                  dœg dœ}i }i }i }|D �]o  }	|	d   g|	d   ¢}
|	d   t        |	d   j                  |«      «      g i dœ}|
D ]|  }t!        |«      }t#        ||j                  «      \  }}t        |«      }||f||<   t%        |||«      |d   |j&                  <   ||	d   k7  sŒ_|d   j)                  |j&                  «       Œ~ |t        |	d   «         d   }t+        t!        |	d   «      «      ||	d   <   i |d<   i ||	d   <   |	d   D ]a  }|t        |«         d   }t-        ||d«      |d   |j.                  <   |j.                  j1                  dd«      }t3        ||«      ||	d      |<   Œc |d   j)                  |«       �Œr t5        j6                  t9        |«      dddt9        |«      z  fd¬«      \  }}t9        |«      dk(  r	|d d d …f   }t;        |«      D ]Í  \  }}	|t        |	d   «         \  }}t=        j>                  |jA                  tB        «      dz  dd«      }t;        d«      D ]y  \  }}tE        |||f   ||||	d   › dd |d      › d |d      › �«       tG        |g|«      \  }}|||f   jI                  |d   |d   «       |||f   jK                  |d   |d   «       Œ{ ŒÏ |jM                  d!dd"¬#«       |jO                  |d$z  d%¬&«       t5        jP                  |«       g d'¢}|D �]ê  }	|	d   sŒ
|	d   D �cg c]  }|t        |«         d   ‘Œ }}|D �cg c]   }|d d tS        dt9        |«      d(z  «      …   ‘Œ" }}t5        j6                  ddd)d¬«      \  }}tU        |d«      D �]!  \  } }tU        ||	d   |«      D ]M  \  }}}!| jW                  |d d …|d   f   |d d …|d   f   d*|!d+dd|j.                  j1                  dd«      ¬,«       ŒO | jY                  |	d   › d-d |d      › d |d      › �d"¬.«       | j[                  d/d0¬1«       | j]                  d |d      «       | j_                  d |d      «       tG        ||«      \  }}| jI                  |d   |d   «       | jK                  |d   |d   «       | ja                  d2¬3«       �Œ$ |d4   jc                  d5d6d7¬8«       |jO                  ||	d   › d9�z  d%¬&«       t5        jP                  |«       �Œí |d:z  je                  d;d<¬=«      5 }"tg        jh                  ||"d>d?¬@«       d d d «       |dAz  je                  d;d<¬=«      5 }"tg        jh                  ||"d>d?¬@«       d d d «       |dBz  je                  d;d<¬=«      5 }"tg        jh                  ||"d>d?¬@«       d d d «       tk        |d:z  «       y c c}w c c}w # 1 sw Y   Œ’xY w# 1 sw Y   ŒfxY w# 1 sw Y   Œ:xY w)CNz--rootr$   )ÚtypeÚdefaultz--outz--samplei ¿ zresults/ply_auditT)ÚparentsÚexist_okz'deterministic equal-width bin midpoints)ÚsamplingÚsample_limit)Úmethodr  r¼   r  r  )r  r¼   r  Úfilesr  r   Úcomponent_vs_fused_overlaprf   Úmerged_pointcloud_Ú r  r›   é   gš™™™™™@)ÚfigsizeÚconstrained_layoutg     ào@g{®Gáz¤?)©r   r$   )r   rF   )r$   rF   u
    fused Â· rï   u3   all_merge_pointcloud_full.ply â€” fused cloud auditrç   rè   zfused_overview.pngé´   )Údpi)z#2E86DEz#E74C3Cz#27AE60z#8E44ADz#F39C12i`ê  )é   r³   g333333Ã?g      Ð?)rá   rù   rã   rä   rå   r  u    sensors Â· )rê   rë   rì   rí   rð   )rã   r`   é   é   Úbest)Úmarkerscaleré   Úlocz_sensor_overlay.pngzreport.jsonÚwzutf-8)ÚencodingFrF   )Úensure_asciiÚindentzfull_scan_checks.jsonz%sensor_to_fused_sample_distances.json)6ÚargparseÚArgumentParserÚadd_argumentr   Ú__file__Úresolver  r   Ú
parse_argsr  ÚoutÚmkdirr  Úsampler…   Úrelative_tor:   rZ   r™   r	  r
  r¯   r×   ÚstemÚreplacer¿   ÚpltÚsubplotsr)   r†   rA   ÚcliprM   rˆ   rû   rß   Úset_xlimÚset_ylimÚsuptitleÚsavefigÚcloser}   Úziprò   ró   rô   rõ   rö   r÷   Úlegendr&   ÚjsonÚdumpÚprint)#ÚapÚargsr  r1  r  ÚreportÚfull_checksÚsensor_distancesÚsampledÚrunr  rÓ   r   rC   rW   rX   ÚkeyÚfxyzÚcxyzÚsensorÚfigÚaxsr—   ÚcolorsÚjrÛ   r�   r�   Úpaletter˜   rÚ   rÜ   rø   rù   r3   s#                                      r   ÚmainrT  Ü   s¸  € Ü	×	 Ñ	 Ó	"€BØ‡O�O�H¤4´´h³×1GÑ1GÓ1I×1QÑ1QÐRSÑ1T€OÔUØ‡O�O�G¤$°€OÔ5Ø‡O�O�J¤S°&€OÔ9Ø�=‰=‹?€DØ�9‰9×ÑÓ€DØ�8‰8Ò1�tÐ1Ñ1×
:Ñ
:Ó
<€CØ‡I�I�d T€IÔ*ä�T‹?€DØ%NÐ`d×`kÑ`kÑlÐvxÑy€FØ€KØÐØ8:€GäˆØ�W‘Ð2  LÑ 1Ð2ˆØ˜G™¬s°3°w±<×3KÑ3KÈDÓ3QÓ/RÐbdÐoqÑrˆÛˆDÜ˜D“>ˆDÜ! $¨¯©Ó4‰HˆC�Ü�d“)ˆCØ ˜:ˆG�C‰LÜ&+¨D°#°sÓ&;ˆC�‰L˜Ÿ™Ñ#Ø�s˜7‘|Ó#Ø�LÑ!×(Ñ(¨¯©Õ3ð ð ”s˜3˜w™<Ó(Ñ)¨!Ñ,ˆÜ$3´H¸SÀ¹\Ó4JÓ$Kˆ�C˜‘LÑ!Ø,.ˆÐ(Ñ)Ø)+Ð˜˜W™Ñ&Ø˜Ô%ˆDØœ3˜t›9Ñ% aÑ(ˆDÜ;HÈÈtÐUXÓ;YˆCÐ,Ñ-¨d¯i©iÑ8Ø—Y‘Y×&Ñ&Ð';¸RÓ@ˆFÜ5NÈtÐUYÓ5ZÐ˜S ™\Ñ*¨6Ò2ð	 &ð
 	ˆv‰×Ñ˜cÖ"ð) ô. �|‰|œC ›I q°2°s¼SÀ»Y±Ð2GÐ\`Ôa�H€CˆÜ
ˆ4ƒy�A‚~Ø�$š�'‰lˆÜ˜D–/‰ˆˆ3Øœ3˜s 7™|Ó,Ñ-‰ˆˆSÜ—‘˜Ÿ™¤EÓ*¨UÑ2°C¸Ó;ˆÜ Ð!9Ö:‰GˆAˆtÜ˜s 1 a 4™y¨#¨t°VÀÀGÁ¸~ÈZÐX]Ð^bÐcdÑ^eÑXfÐWgÐhmÐnrÐstÑnuÑhvÐgwÐ=xÔyÜ" C 5¨$Ó/‰FˆB�Ø��1�‰I×Ñ˜r !™u b¨¡eÔ,¨c°!°Q°$©i×.@Ñ.@ÀÀAÁÈÈ1ÉÕ.Nñ ;ð "ð ‡L�LÐFÐQSÐ\b€LÔcØ‡K�K�Ð*Ñ*°€KÔ4Ü‡I�Iˆc„Nò F€GÜˆØ�<Ò ØØ.1°,Ò.?Ó@Ñ.?¨�'œ#˜a›&‘/ !Ó$Ð.?ˆÐ@á6<Ó=±f°�!Ñ+”c˜!œS ›V U™]Ó+Ð+Ó,°fˆÐ=Ü—<‘<  1¨gÈ$ÔO‰ˆˆSÜ˜CÐ!9×:‰HˆB�Ü"% f¨c°,Ñ.?ÀÖ"I‘��4˜Ø—
‘
˜1šQ  Q¡˜Z™=¨!ªA¨t°A©w¨J©-¸3ÀeÐSVØ&'°DÀÇ	Á	×@QÑ@QÐRfÐhjÓ@kð õ mð #Jð �L‰L˜C ™L˜>¨°e¸DÀ¹G±nÐ5EÀeÈDÐQRÉGÁnÐEUÐVÐ_eˆLÔfØ�M‰M˜'¨eˆMÔ4Ø�M‰M˜%  Q¡™.Ô)¨2¯=©=¸¸tÀA¹w¹Ô+HÜ" 6¨4Ó0‰FˆB�Ø�K‰K˜˜1™˜r !™uÔ% r§{¡{°2°a±5¸"¸Q¹%Ô'@À"Ç'Á'ÐPSÀ'ÖBTð ;ð 	ˆB‰�‰ 2°°vˆÔ>Ø�‰�C˜S ™\˜NÐ*=Ð>Ñ>ÀCˆÔHÜ�	‰	�#Žð% ð( �Ñ
×	#Ñ	# C°'Ð	#Ô	:¸bÜ�	‰	�&˜"¨5¸Õ;÷ 
;à
Ð'Ñ
'×	-Ñ	-¨c¸GÐ	-Ô	DÈÜ�	‰	�+˜r°¸aÕ@÷ 
Eà
Ð7Ñ
7×	=Ñ	=¸cÈGÐ	=Ô	TÐXZÜ�	‰	Ð" B°UÀ1ÕE÷ 
Uä	ˆ#�Ñ
Õùò/ Aùâ=÷ 
;Ð	:úç	DÐ	Dúç	TÐ	Tús0   Ï6Z
Ð%Z×)ZØ!Z ÙZ,ÚZÚ Z)Ú,Z5Ú__main__)r   r   Úreturnr   )rC   r   rV  z	np.memmap)rC   r   rR   r   rV  ztuple[np.ndarray, np.ndarray])rC   r   rW   ú
np.ndarrayrX   rW  rV  Údict)i@KL )rC   r   r§   r   rV  rX  )r¼   rW  r½   rW  rV  rX  )rÎ   rW  rÏ   rW  rÂ   rˆ   rV  rX  )r  )rÚ   zlist[np.ndarray])rð   gÍÌÌÌÌÌÜ?)r  r   rV  z
list[dict])rV  ÚNone)Ú__doc__Ú
__future__r   r+  rA  Údataclassesr   Úpathlibr   Úmatplotlib.pyplotÚpyplotr7  ÚnumpyrA   Úscipy.spatialr   r=   r/   r   r:   rD   rZ   r™   r¯   r¿   r×   rß   rû   r  rT  r   r   r   r   Ú<module>rb     sŸ   ðá Rå "ã Û Ý !Ý å Û Ý !ð ˆB�H‰Hò ó €	ð ÷ð ó ðó%ó,*ó
	 ó+ô\ó@ó"ô(ó%óó&Qðh ˆzÒÙ…Fð r   