phenotypic.sdk_.metadata_only_mask#

phenotypic.sdk_.metadata_only_mask(df: pandas.DataFrame) pandas.Series[source]#

Mask of --metadata phantom rows; all-False when unknowable.

A phantom row is one the CLI’s --metadata left join carried through from the metadata CSV even though no measured object matched its key — every measurement/info column on it is null. Those rows are marked with the METADATA_ONLY (QC_MetadataOnly) boolean column.

The flag is CLI-only, so public analysis/post entry points that a user calls on a hand-built or measure() frame see no flag at all. This helper degrades to an all-False mask in that case, which reproduces exactly the pre-left-join behavior for every caller.

The dtype check is deliberately strict: only a real boolean column is trusted. An object/string column is rejected rather than coerced, because pd.Series(["False", "True"]).astype(bool) is [True, True] — the string "False" is truthy — which would silently mark every row a phantom. Rejecting costs nothing (it falls back to today’s behavior); a lenient coercion would corrupt every result. Both real CLI round-trips preserve the dtype: parquet stores a native bool, and polars’ write_csv emits true/false, which pd.read_csv parses to bool.

Parameters:

df (pandas.DataFrame) – Any measurement-shaped DataFrame.

Returns:

True where the row is a metadata-only phantom, False everywhere else (and everywhere when the flag column is absent or not a boolean column).

Return type:

Boolean Series aligned to df.index

Examples

>>> import pandas as pd
>>> from phenotypic.sdk_ import metadata_only_mask
>>> # A frame from a notebook ``image.measure()`` carries no flag.
>>> metadata_only_mask(pd.DataFrame({"Shape_Area": [10.0, 12.0]})).tolist()
[False, False]
>>> # A CLI mirror does: the undetected strain is flagged.
>>> mirror = pd.DataFrame({"QC_MetadataOnly": [False, True]})
>>> metadata_only_mask(mirror).tolist()
[False, True]