@@ -828,13 +828,16 @@ See the benchmarks described in more detail in
828828The ` light_curve.embed ` submodule provides pretrained neural network models that map raw photometric
829829time series to dense vector embeddings suitable for downstream machine learning tasks such as
830830classification, anomaly detection, and similarity search.
831- Models are loaded directly from HuggingFace (weights are cached locally after the first download)
832- and require ` onnxruntime ` and ` huggingface-hub ` :
831+ The examples below use ` from_hf() ` to download model weights from HuggingFace Hub
832+ (cached locally after the first download), which requires ` onnxruntime ` and ` huggingface-hub ` :
833833
834834```
835- pip install onnxruntime huggingface_hub
835+ pip install light-curve onnxruntime huggingface_hub
836836```
837837
838+ Models can also be loaded directly from a local ONNX file via ` from_onnx_file() ` ,
839+ without ` huggingface-hub ` .
840+
838841See the [ onnxruntime install guide] ( https://onnxruntime.ai/docs/install/ ) for GPU and platform-specific
839842packages (` onnxruntime-gpu ` , ` onnxruntime-directml ` , etc.).
840843Hardware-specific options such as execution providers can be passed via ` ort_session_kwargs `
@@ -916,6 +919,62 @@ print(embedding.shape) # (1, 1, 1, 384)
916919Input fluxes should be in AB units. The default zero-point is 31.4 (LSST nJy); set ` mag_zp=27.5 `
917920for ELAsTiCC / SNANA FITS data or ` mag_zp=8.9 ` for Jy.
918921
922+ ### Example: nearest-neighbour search on ZTF DR23
923+
924+ The following example reads a ZTF DR23 [ HATS] ( https://hats.readthedocs.io ) pixel directly from the public S3
925+ bucket using
926+ [ ` nested-pandas ` ] ( https://nested-pandas.readthedocs.io ) and ` s3fs `
927+ (install all dependencies for this example with
928+ ` pip install huggingface_hub light-curve nested-pandas onnxruntime s3fs scipy ` ), embeds all well-observed
929+ light curves with Astromer2, and finds the closest neighbour to a given object by cosine distance.
930+ This particular pixel contains ~ 50k objects passing the quality cuts; embedding takes roughly
931+ 12 minutes on M2 Pro (~ 15 ms per object).
932+
933+ <!-- name: test_ztf_dr23_nn_example; mark: skip(reason="requires S3 access and ~12 minutes to run") -->
934+
935+ ``` python
936+ import numpy as np
937+ import nested_pandas as npd
938+ from scipy.spatial.distance import cdist
939+ from upath import UPath
940+ from light_curve.embed import Astromer2
941+
942+ TARGET_OID = 680213300009232 # ZTF r-band light curve
943+ MIN_OBS = 1000
944+
945+ nf = npd.read_parquet(UPath(
946+ " s3://ipac-irsa-ztf/contributed/dr23/lc/hats/ztf_dr23_lc-hats/dataset/Norder=5/Dir=0/Npix=2378/" ,
947+ anon = True ,
948+ ))
949+ nf = nf.query(" lightcurve.catflags == 0" ).query(f " lightcurve.list_lengths >= { MIN_OBS } " )
950+
951+ model = Astromer2.from_hf(reduction = " beginning" )
952+
953+
954+ def embed_row (row ):
955+ return {" embedding.values" : model(row[" lightcurve.hmjd" ], row[" lightcurve.mag" ]).squeeze()}
956+
957+
958+ nf = nf.map_rows(embed_row, columns = [" lightcurve.hmjd" , " lightcurve.mag" ], append_columns = True )
959+
960+ oids = nf[" objectid" ].to_numpy()
961+ matrix = nf[" embedding.values" ].to_numpy().reshape(len (nf), - 1 )
962+
963+ query_idx = np.where(oids == TARGET_OID )[0 ][0 ]
964+ distances = cdist(matrix[query_idx: query_idx + 1 ], matrix, metric = " cosine" )[0 ]
965+ distances[query_idx] = np.inf
966+
967+ best_idx = np.argmin(distances)
968+ print (f " Nearest neighbour: OID { oids[best_idx]} , cosine distance { distances[best_idx]:.6f } " )
969+ # Nearest neighbour: OID 680113300005170, cosine distance 0.000046
970+ ```
971+
972+ The nearest neighbour is OID ` 680113300005170 ` — the same physical
973+ object ([ HZ Her / Her X-1] ( https://en.wikipedia.org/wiki/Hercules_X-1 ) , an X-ray binary) observed in the * g*
974+ -band,
975+ recovered automatically from an * r* -band query through embedding similarity.
976+ See the light curve on [ SNAD Viewer] ( https://ztf.snad.space/dr23/view/680113300005170 ) .
977+
919978## dm-dt map
920979
921980In addition to the feature extractors above, the package provides a separate dm–dt mapping tool.
0 commit comments