/hats-publish
Convierte la publicación de un catálogo de una encuesta en una colección HATS (catálogo + margen + tablas de índice) que se verifica
contra los archivos fuente, se documenta, se aloja y se registra. El procedimiento codifica la documentación de hats-import y lsdb,
el pipeline de importación de Rubin (https://github.com/lincc-frameworks/rubin-dash) y las convenciones del equipo
registradas en issues públicos y notebooks de importación archivados; cada
valor específico del sitio proviene del archivo de sitio descrito en CONFIG.md, cada referencia es una URL pública, y nada en este archivo
nombra una máquina, una persona o un conjunto de datos.
Una ejecución = un catalog.toml (copiado desde templates/catalog.toml a un directorio de trabajo). Cada plantilla lo lee,
las rutas relativas en él se resuelven contra el directorio que lo contiene, y una ejecución es reproducible solo a partir de ese archivo.
Conserva el directorio de trabajo: contiene la configuración, los registros, el
notebook de verificación ejecutado y el registro de la ejecución.
Fija las plantillas al inicio de cada ejecución: T=$(bash <skill>/templates/pin_templates.sh) en el directorio de trabajo
y las copia como solo lectura en templates.pinned/ con el commit de git, y cada paso posterior (job.sbatch y
resubmit_loop.sh incluidos) ejecuta $T/.... Un git pull o una edición del skill no pueden cambiar una importación en ejecución, y
el README nombra el commit que construyó el catálogo. Cambia el código de una ejecución solo con pin_templates.sh --repin.
Cuándo usar
Una nueva publicación de una encuesta por publicar; una re-importación de un catálogo HATS existente con mejor particionamiento, configuración de escritura o metadatos; una solicitud para verificar que una copia HATS coincide con su fuente.
Entradas (preguntar solo si no están definidas)
Archivos fuente o URLs y su formato; encuesta, publicación, página de modelo de datos, artículo, agradecimiento y licencia;
si ya existe una versión HATS (buscar en el árbol data/ de data.lsdb.io y en imports/README.md); las columnas de
coordenadas e id. Todo lo demás se decide en la entrevista a continuación.
Procedimiento
Fases en orden. Los pasos en negrita se detienen y esperan al usuario. Cada fase comienza y termina con una entrada en el registro de ejecución
(run_log.py start|end <phase>); las plantillas hacen esto por sí mismas donde se ejecutan.
- Entorno. Crear o actualizar un entorno con las últimas versiones publicadas de
hats,lsdb,hats-import(pip install -U hats lsdb hats-import nested-pandas pyarrow astropy fitsio jupyter), mostrar las versiones, revisar las notas de la versión para cambios de formato. ConfigurarHATS_PUBLISH_SITE_ENVpara que apunte a tu archivo de sitio (CONFIG.md). Las plantillas que usan las bibliotecas se niegan a ejecutarse por debajo de las versiones mínimas y advierten cuando existe una versión más nueva. - Entrevista de decisión (
reference/decisions.md): los nueve grupos, algunas preguntas a la vez, cada una con su valor predeterminado recomendado y consecuencias. Escribir las respuestas encatalog.tomly el registro de ejecución (run_log.py decision). Luego mostrar el plan: ruta, lector, recursos, particionamiento, configuración del escritor, nombres, destinos. - Adquirir. Descargar en el directorio raw, verificar sumas de comprobación e integridad del archivo (
gzip -t), registrar el sha256 de cada archivo en[source].sha256, y guardar la página del modelo de datos junto a los datos. Contar los archivos contra el listado del archivo ([source].expected_files) y listar nombres de archivo exactos, nunca un glob simple sobre un directorio que pueda contener copias de descarga repetidas. Para miles de archivos pequeños, escribir archivos de índice para los lectores indexados. Una descarga que se ejecuta en segundo plano escribe su pid endownload.piden el directorio de trabajo para questatus.shpueda informar de ella. 2a. Tablas sin coordenadas ([source.positions_from]):attach_positions.pybusca las posiciones por id en una colección HATS de referencia (su tabla de índice) y escribe la fuente como Parquet conra/dec; la importación luego lee esos archivos. CSV con encabezado ECSV con columnas de arreglo ([reader].ecsv_header = true) se parsea en columnas de lista en el camino. 2b. Una tabla dividida en archivos FITS paralelos por fila ([source.companions], por ejemplo, un archivo principal más archivos extra/photo-z/curva de luz con las mismas filas): la importación los lee lado a lado con rangos de fila fitsio, verifica las columnas clave fragmento por fragmento, y puede agregar columnas calculadas ([reader].derive, una función en el directorio de trabajo) y empaquetar columnas de lista en una columna anidada ([reader].pack_nested). El cargador de verificación lee los mismos archivos de forma independiente. - Planificar el particionamiento.
estimate_threshold.py --writemuestrea la entrada con la configuración del escritor de la ejecución y convierte la regla de tamaño de archivo de 200–800 MB enpixel_threshold, y predice el conteo de particiones y el tamaño dedataset/_metadata(advierte cerca del límite del pie de página de 4 GiB); verificarhighest_ordercontra la región más densa. - Prueba.
import_collection.py --trial-file <un archivo>en un directorio de prueba; inspeccionar dtypes, nulos versus centinelas, nombres de columna, columnas de arreglo, filas sin coordenadas ([reader].drop_rows_without_coordinateslas elimina y las cuenta). Ajustar[reader],[columns]y[properties]; mostrar al usuario qué cambió. - Importar.
import_collection.pyen modo separado (nohup/setsid), ojob.sbatchen un nodo por lotes (también ejecuta las fases 5–6 y la comparación), reanudable; construye el catálogo, las tablas de margen e índice con la configuración de[properties]y[writer]. Las tablas pequeñas (menos de aproximadamente 1 M de filas y 1 GB en memoria; por encima de aproximadamente 100 k filas en tablas anchas hats-import es más rápido) usanimport_small.pyen su lugar. Luegowrite_ancillary.py: miniatura de datos (muestra aleatoria por partición), estadísticas por partición, vistas previas PNG, README yindex.htmlcon una sección de procedencia. Progreso:status.sh(desde el directorio de trabajo) imprime la descarga, el trabajo SLURM, la etapa actual de hats-import con su barra de progreso y la entrada más reciente del registro de ejecución. Las descargas e importaciones se ejecutan durante horas: tan pronto como una se ejecuta en segundo plano (fase 2 o 5), iniciar actualizaciones cada 5 minutos sin preguntar. Cada actualización ejecutastatus.shy reporta solo lo que cambió. Decir que se están ejecutando y que el usuario puede cambiar el intervalo o detenerlas. Detenerlas cuando el trabajo termine o falle, y verificar el estado real del trabajo cuando salga de la cola. En una cola preferente, iniciarresubmit_loop.sh <id de trabajo>junto al trabajo: registra los recursos del trabajo enresubmit_opts.txt, reenvía trabajos adelantados o cancelados por el sistema con los mismos recursos (hats-import se reanuda; un trabajo adelantado después de que la importación haya terminado, marcado porimport.done, se reenvía con la importación omitida) y se detiene en cualquier otra cosa. 5a. Producto anidado de series de tiempo ([nested], opcional):attach_nested.pyune columnas de lista por objeto de una HATS de referencia por id (unión espacial interna), las empaqueta en una columna anidada connest_listsy escribe una segunda colección junto a la plana; la sección 9b del notebook concilia filas, longitudes de lista y una muestra de arreglos. - Verificar, cualquier fallo detiene la ejecución (
reference/verification.md):verify_structure.py --spot-check(comprobaciones de hats-import, cumplimiento de HATS-note, barrido de codificación) →run_verify.sh(el notebook a nivel de valores contra la fuente; los checks terminan en PASS, FAIL o SKIP con una razón) → la lista de verificación de revisión con el usuario. - Documentar y archivar. Agregar
catalog.toml, los scripts utilizados y el notebook ejecutado al directorioimports/de data.lsdb.io con una fila en la parte superior de su README (parte del pull request del sitio). - Alojar (
reference/publishing.md). Ejecutarpublish_web.sh --checkypublish_mirror.sh --check, mostrar las vistas previas (lo que se copiaría y lo que el destino ya contiene), y solo después de la aprobación del usuario ejecutarlos con--yes(sin una de las dos banderas se detienen; un destino que contenga archivos que la compilación no tiene los detiene antes de escribir a menos que se proporcione--replace, que elimina los archivos obsoletos): copiar, agrupar, manifiesto de suma de comprobación,hats_statusyhats_service_urlpor tabla, enlace simbólico en el servidor web, prueba pública abierta conlsdb.open_catalogen la raíz de la colección (un fallo revierte el enlace simbólico), luego la descripción de autoíndice; la copia del espejo se vuelve a verificar enverify_results_mirror.csv. - Registrar.
make_site_entry.pyescribe la entrada de la página y el mapa de densidad en una rama en un clon de data.lsdb.io (fusionando en una entrada existente) y la prepara; preguntar por el mensaje de commit; la solicitud de extracción es del usuario. Después de que se fusiona e implementa,registry_entry.pyejecuta el generador de registro en una rama en un clon de registro para la solicitud de extracción del usuario; requiere un clon de sitio limpio enorigin/main. - Cerrar.
NOTES.mdde la plantilla; elementos abiertos (espejos, registro, implementación, retiro de una versión anterior);run_log.py feedbackcon el usuario sobre lo que no estaba claro, manual o incorrecto en los valores predeterminados;run_log.py render --scruby ofrecer una solicitud de extracción agregando el registro arunlogs/en este repositorio.
Re-importaciones: ImportArguments.reimport_from_hats para nuevos umbrales u ordenamiento, reconstruir márgenes e índices, escribir
en un nuevo directorio, verificar, ejecutar compare_versions.py --new <nuevo> --old <anterior> --key <id> (esquema, filas y
valores de la región compartida; la reducción de tipo se informa por separado), re-apuntar los enlaces simbólicos, mantener la copia anterior
hasta que la página y el registro apunten a la nueva.
Plantillas
| Archivo | Propósito |
|---|---|
catalog.toml | la configuración de la ejecución (copiar y completar) |
pin_templates.sh | congelar las plantillas para una ejecución en templates.pinned/ (commit, diff local, sumas de comprobación); --repin para cambiarlas |
_common.py, catalog_source.py, readers.py | ayudantes compartidos: configuración, versiones, variables del sitio, configuración del escritor, propiedades, cargador de fuente, filtro de coordenadas |
estimate_threshold.py | regla de tamaño de archivo → pixel_threshold |
import_collection.py | compilación de colección hats-import (--dry-run, --trial-file) |
import_small.py | ruta en memoria para tablas pequeñas |
attach_positions.py | posiciones por id desde una HATS de referencia para tablas sin coordenadas; arreglos ECSV parseados en columnas de lista |
attach_nested.py | producto anidado de series de tiempo: unir columnas de lista por id desde una HATS de referencia, nest_lists, escribir una colección |
job.sbatch | ruta por lotes: importación, archivos auxiliares, verificación y comparación como un solo trabajo SLURM en un nodo dedicado |
write_ancillary.py | miniatura, estadísticas, vistas previas, README, index.html |
verify_structure.py | comprobaciones estructurales, de cumplimiento y de codificación |
build_verify_notebook.py, run_verify.sh | notebook de verificación a nivel de valores |
compare_versions.py | comparar una nueva compilación con una versión HATS existente (re-importaciones, validación contra una copia publicada) |
publish_mirror.sh, publish_web.sh | destinos de alojamiento |
make_site_entry.py, registry_entry.py | página y registro de data.lsdb.io |
memwatch.sh | vigilante de memoria para pasos largos de un solo proceso en nodos compartidos |
status.sh | resumen de progreso en una pantalla (descarga, trabajo, etapa de importación, registro de ejecución) para actualizaciones programadas |
resubmit_loop.sh | reenviar un trabajo por lotes después de adelantamiento o cancelación del sistema; un bucle por ejecución (guardia de latido) |
run_log.py, NOTES.template.md | registro de ejecución y notas |
Trampas
Una línea cada una; detalles y más en reference/pitfalls.md.
- Una tarea de Dask por archivo de entrada: dividir archivos enormes, usar lectores indexados para miles de archivos pequeños.
- Las filas sin coordenadas detienen la etapa de mapeo: importar de prueba primero, filtrar y contarlas.
- Las entradas CSV comprimidas con gzip necesitan
compression="gzip"(el lector recibe un manejador abierto); la importación lo agrega para archivos.gz. expected_total_rowsdebe coincidir o el pipeline se detiene después del binning; es una comprobación, no una sugerencia.- Usar los valores predeterminados de Parquet de hats (hats, hats-import, lsdb >= 0.11.1): ZSTD 15, índice de página, BYTE_STREAM_SPLIT en
columnas flotantes. Dejar
[writer]vacío a menos que el usuario decida lo contrario; escribir cualquier archivo que el skill escriba por sí mismo conparquet_write_kwargs. Las versiones anteriores escriben flotantes codificados por diccionario, aproximadamente 1,4× más grandes. - Las columnas predeterminadas deben existir en el esquema; las columnas anidadas usan
frame.subcol. - hats escribe
hats.propertiesyproperties; editar ambos o ninguno. hats_release_datees la fecha de la nota de HATS, no la de los datos; poner las fechas de los datos ent_min/t_max.- Un margen puede contener filas adicionales, nunca menos: verificar por contención.
- Los márgenes e índices llevan la ruta de compilación en
hats_primary_table_url; los scripts de publicación la hacen relativa. - Abrir colecciones en la raíz; la página debe apuntar a la raíz de la colección.
- El
.htaccessweb es de primera coincidencia y coincidencia de prefijo; el script de publicación inserta antes de las entradas genéricas y escribe por copia, no por renombrado (directorio persistente). - Las entradas cuyas columnas difieren por región pierden columnas silenciosamente al reducir: ajustarse a un esquema
(
[reader].conform_schema, cualquier formato), probar cada región. _metadatano puede exceder los 4 GiB:estimate_threshold.pylo predice;create_metadata = falsepara catálogos enormes.- Las listas de tamaño fijo nulas rompen los lectores de pyarrow < 26: llenar con NaN o usar listas de longitud variable.
- Las barras de progreso en notebooks sin cabeza se convierten en widgets muertos; el constructor de notebooks usa barras de texto.
- Los shells paralelos comparten un directorio de trabajo: rutas absolutas, archivos pid en lugar de
pgrep -f.
Salida
Una colección HATS verificada en los destinos de alojamiento, una página de data.lsdb.io preparada, una rama de registro, NOTES.md,
verify_results.csv, el notebook de verificación ejecutado y RUNLOG.md.