/hats-publish
將巡天目錄發布轉換為 HATS 集合(目錄 + 邊際 + 索引表),並經過驗證
與原始檔案一致,建立文件、託管並註冊。此程序編碼了 hats-import 和 lsdb
文件、Rubin 匯入管線 (https://github.com/lincc-frameworks/rubin-dash) 以及團隊在
公開問題和已封存匯入筆記本中記錄的慣例;每個
站點特有值均來自 CONFIG.md 中描述的站點檔案,每個參考均為公開 URL,且此處
不命名任何機器、人員或資料集。
一次執行 = 一個 catalog.toml(從 templates/catalog.toml 複製到工作目錄)。每個範本讀取
它,其中的相對路徑會相對於存放它的目錄解析,且一次執行可僅從該檔案重現。保留工作目錄:它包含
設定、日誌、已執行的驗證筆記本和執行日誌。
在每次執行開始時固定範本:在工作目錄中執行 T=$(bash <skill>/templates/pin_templates.sh)
將它們以唯讀方式複製到 templates.pinned/,並包含 git 提交 ID,後續每個步驟(包括 job.sbatch 和
resubmit_loop.sh)都執行 $T/...。這樣,對技能的 git pull 或編輯就不會影響正在進行的匯入,且
README 會標明建置該目錄的提交。僅使用 pin_templates.sh --repin 更改某次執行的程式碼。
使用時機
發布新的巡天資料;使用更好的分割、寫入器 設定或中繼資料重新匯入現有 HATS 目錄;驗證 HATS 副本是否與其原始資料匹配。
輸入(僅在未設定時詢問)
原始檔案或 URL 及其格式;巡天、發布、資料模型頁面、論文、致謝和授權;
是否已存在 HATS 版本(檢查 data.lsdb.io 的 data/ 樹和 imports/README.md);
座標和 ID 欄位。其他一切在下面的訪談中決定。
程序
按順序的階段。粗體步驟會停止並等待使用者。每個階段以執行日誌條目開始和結束
(run_log.py start|end <phase>);範本在它們執行的位置自行處理此操作。
- 環境。 建立或更新環境,包含最新發布的
hats、lsdb、hats-import(pip install -U hats lsdb hats-import nested-pandas pyarrow astropy fitsio jupyter),列印版本,略讀 發行說明以了解格式變更。將HATS_PUBLISH_SITE_ENV指向您的站點檔案(CONFIG.md)。使用這些函式庫的範本 會拒絕在低於最低版本時執行,並在新版本可用時發出警告。 - 決策訪談(
reference/decisions.md):九個群組,每次幾個問題,每個都有其 建議的預設值和後果。將答案寫入catalog.toml和執行日誌 (run_log.py decision)。然後顯示計畫:路由、讀取器、資源、分割、寫入器設定、名稱、 目標。 - 獲取。下載到原始目錄,驗證校驗和與壓縮檔完整性(
gzip -t),記錄每個檔案的 sha256 到[source].sha256,並將資料模型頁面儲存在資料旁邊。將檔案數量與 壓縮檔的清單([source].expected_files)進行比對,並列出確切的檔名,切勿對可能包含重新下載副本的目錄使用裸 glob。 對於數千個小檔案,為索引讀取器寫入索引檔案。 在背景執行的下載會將其 PID 寫入工作目錄中的download.pid,以便status.sh可以報告。 2a. 無座標的表([source.positions_from]):attach_positions.py透過 ID 在參考 HATS 集合(其索引表)中查詢位置, 並將原始資料寫入包含ra/dec的 Parquet;然後匯入讀取 這些檔案。 帶有陣列欄位的 ECSV 標頭 CSV([reader].ecsv_header = true)會在途中解析為列表欄位。 2b. 一個表分割為列並行 FITS 檔案([source.companions],例如一個主檔案加上具有相同列的額外/光譜紅移/光變曲線 檔案):匯入使用 fitsio 列範圍並行讀取它們,逐區塊檢查鍵欄位 ,並且可以新增計算欄位([reader].derive,工作目錄中的函數)並將列表欄位打包 到一個巢狀欄位([reader].pack_nested)。驗證載入器獨立讀取相同的檔案。 - 規劃分割。
estimate_threshold.py --write使用執行的寫入器設定對輸入進行抽樣,並將 200–800 MB 的檔案大小規則轉換為pixel_threshold,並預測分割數量和dataset/_metadata的大小(接近 4 GiB 頁尾限制時發出警告);檢查highest_order是否超過最密集區域。 - 試匯入。
import_collection.py --trial-file <一個檔案>匯入到試行目錄;檢查 dtype、空值與 替代值、欄位名稱、陣列欄位、無座標的列([reader].drop_rows_without_coordinates會丟棄並計數)。調整[reader]、[columns]和[properties];向使用者顯示更改了什麼。 - 匯入。在背景執行
import_collection.py(nohup/setsid),或在批次節點上執行job.sbatch(它也執行 第 5–6 階段和比較),可恢復;它使用[properties]和[writer]設定建置目錄、 邊際和索引表。小型表(約低於 1M 行且在記憶體中低於 1 GB;在寬表上 hats-import 更快,約高於 100k 行)則改用import_small.py。然後執行write_ancillary.py:資料縮圖(每個分割隨機抽樣)、 每個分割的統計資料、PNG 預覽、README 和包含出處說明的index.html。 進度:status.sh(從工作目錄)列印下載狀態、SLURM 作業、目前的 hats-import 階段 及其進度條,以及最新的執行日誌條目。下載和匯入會執行數小時:一旦它們在 背景執行(第 2 或 5 階段),就開始每 5 分鐘不經詢問進行更新。每次更新執行status.sh並 僅報告更改的內容。說明它們正在執行,並且使用者可以更改間隔或停止它們。 當作業完成或失敗時停止它們,並在作業離開佇列時檢查其實際狀態。在可預佔用佇列上,在 作業旁邊啟動resubmit_loop.sh <job id>:它將作業的資源記錄在resubmit_opts.txt中, 重新提交被預佔用或系統取消的作業(使用相同資源)(hats-import 會恢復;如果作業在匯入完成後被預佔用,由import.done標記,則在跳過匯入的情況下重新提交),並在其他任何情況下停止。 5a. 巢狀時間序列產品([nested],可選):attach_nested.py透過 ID 從參考 HATS 加入逐物件列表欄位(空間內連接), 使用nest_lists將它們打包到一個巢狀欄位中,並在平面集合旁邊寫入第二個 集合;筆記本的第 9b 節協調列、列表長度和陣列樣本。 - 驗證,任何失敗都會停止執行(
reference/verification.md):verify_structure.py --spot-check(hats-import 的檢查、HATS note 合規性、編碼掃描)→run_verify.sh(針對原始資料的數值層級筆記本;檢查結果為 PASS、FAIL 或 SKIP 並附帶原因)→ 與使用者一起的審查清單。 - 文件與封存。將
catalog.toml、使用的腳本和已執行的筆記本新增到 data.lsdb.io 的imports/目錄,並在其 README 頂部新增一行(作為站點拉取請求的一部分)。 - 託管(
reference/publishing.md)。執行publish_web.sh --check和publish_mirror.sh --check,顯示 預覽(將複製哪些內容,以及目標端已有哪些內容),僅在使用者批准後才使用--yes執行它們(如果沒有這兩個旗標之一,它們會停止;如果目標端包含建置缺少的檔案,它們會在寫入前停止,除非給定--replace,這會刪除過時的檔案):複製、分組、校驗和清單、每個表的hats_status和hats_service_url、Web 主機上的符號連結、使用lsdb.open_catalog對集合根目錄進行公開開放測試(失敗會復原符號連結),然後是 autoindex 描述; 鏡像副本會重新驗證到verify_results_mirror.csv。 - 註冊。
make_site_entry.py在 data.lsdb.io 克隆的一個分支上寫入頁面條目和密度圖 (合併到現有條目中)並暫存;要求提交訊息;拉取請求由使用者建立。 在合併並部署之後,registry_entry.py在註冊表克隆的一個分支上為使用者的拉取請求執行註冊表產生器; 它需要一個乾淨的位於origin/main的站點克隆。 - 結案。來自範本的
NOTES.md;待辦事項(鏡像、註冊表、部署、淘汰舊版本);run_log.py feedback與使用者一起確認哪些地方不清楚、手動或不正確的預設值;run_log.py render --scrub並提供將日誌新增到此儲存庫runlogs/的拉取請求。
重新匯入:使用 ImportArguments.reimport_from_hats 設定新的閾值或排序,重建邊際和索引,寫入
到新目錄,驗證,執行 compare_versions.py --new <新> --old <舊> --key <id>(共享區域的結構、行和
數值;型別縮小會單獨報告),重新指向符號連結,保留舊副本
直到頁面和註冊表指向新副本。
範本
| 檔案 | 用途 |
|---|---|
catalog.toml | 執行設定(複製並填寫) |
pin_templates.sh | 為一次執行凍結範本在 templates.pinned/(提交、本地差異、校驗和);--repin 以更改它們 |
_common.py、catalog_source.py、readers.py | 共享輔助工具:設定、版本、站點變數、寫入器設定、屬性、來源載入器、座標過濾器 |
estimate_threshold.py | 檔案大小規則 → pixel_threshold |
import_collection.py | hats-import 集合建置(--dry-run、--trial-file) |
import_small.py | 適用於小型表的記憶體中路由 |
attach_positions.py | 對於無座標的表,從參考 HATS 透過 ID 附加位置;將 ECSV 陣列解析為列表欄位 |
attach_nested.py | 巢狀時間序列產品:從參考 HATS 透過 ID 加入列表欄位、nest_lists、寫入集合 |
job.sbatch | 批次路由:匯入、附屬檔案、驗證和比較作為一個 SLURM 作業在專用節點上執行 |
write_ancillary.py | 縮圖、統計資料、預覽、README、index.html |
verify_structure.py | 結構、合規性和編碼檢查 |
build_verify_notebook.py、run_verify.sh | 數值層級驗證筆記本 |
compare_versions.py | 比較新版建置與現有 HATS 版本(重新匯入、針對已發布副本的驗證) |
publish_mirror.sh、publish_web.sh | 託管目標 |
make_site_entry.py、registry_entry.py | data.lsdb.io 頁面和註冊表 |
memwatch.sh | 用於共享節點上長時間單步驟程序的記憶體監視器 |
status.sh | 單頁面進度摘要(下載、作業、匯入階段、執行日誌),用於排程更新 |
resubmit_loop.sh | 在預佔用或系統取消後重新提交批次作業;每個執行一個迴圈(心跳防護) |
run_log.py、NOTES.template.md | 執行日誌和筆記 |
注意事項
每行一個;詳細資訊和更多內容請參閱 reference/pitfalls.md。
- 每個輸入檔案一個 Dask 任務:分割巨型檔案,使用索引讀取器處理數千個小檔案。
- 無座標的列會停止映射階段:先試匯入,過濾並計數它們。
- Gzip 壓縮的 CSV 輸入需要
compression="gzip"(讀取器會取得一個開啟的控制代碼);匯入會為.gz檔案自動加上此設定。 expected_total_rows必須匹配,否則管線會在分箱後停止;這是一個檢查,不是提示。- 使用 hats Parquet 預設值(hats、hats-import、lsdb >= 0.11.1):ZSTD 15、頁面索引、浮點數欄位使用 BYTE_STREAM_SPLIT。除非使用者另有決定,否則將
[writer]保留為空;技能自身寫入的任何檔案都使用parquet_write_kwargs寫入。舊版本會將浮點數字典編碼,大約大 1.4 倍。 - 預設欄位必須存在於結構描述中;巢狀欄位使用
frame.subcol。 - hats 會寫入
hats.properties和properties;編輯兩者或都不編輯。 hats_release_date是 HATS note 的日期,不是資料的日期;將資料日期放在t_min/t_max中。- 邊際可能包含額外的列,絕不會更少:透過包含關係驗證。
- 邊際和索引在
hats_primary_table_url中包含建置路徑;發布腳本會使其相對化。 - 在根目錄開啟集合;頁面必須指向集合根目錄。
- Web 的
.htaccess是首次匹配和前綴匹配;發布腳本在通用條目前插入,並透過複製(而非重新命名)寫入(黏性目錄)。 - 輸入檔案如果欄位因區域而異,會在不產生錯誤的情況下靜態丟失欄位:統一到一個結構描述(
[reader].conform_schema,任何格式),對每個區域進行試匯入。 _metadata不能超過 4 GiB:estimate_threshold.py會預測它;對於超大目錄設定create_metadata = false。- 空固定長度列表會破壞 pyarrow < 26 的讀取器:使用 NaN 填充或改用可變長度列表。
- 無頭筆記本中的進度條會變成死小工具;筆記本建置器使用文字條。
- 並行 shell 共用一個工作目錄:使用絕對路徑、PID 檔案而不是
pgrep -f。
輸出
託管目標上一個經過驗證的 HATS 集合、一個暫存的 data.lsdb.io 頁面、一個註冊表分支、NOTES.md、
verify_results.csv、已執行的驗證筆記本和 RUNLOG.md。