![]() |
OpenMS
|
Public helpers for writing and concatenating Arrow tables to Parquet files. More...
Classes | |
| struct | ParquetColumn |
| One column for withColumns(), built without Arrow types. More... | |
| class | ParquetTableStream |
| A Parquet file written table by table: the merged QPX psm file of a multi-file search, appended run by run while the next run is searched. More... | |
| struct | QPXRunFileNameKeys |
| MetaInfo indices qpxPsmRunFileName() consults, resolved once. More... | |
Functions | |
| std::string | generateUuidV4 () |
| Generate a lowercase hyphenated RFC 4122 version-4 UUID string. | |
| Size | tableRowCount (const std::shared_ptr< arrow::Table > &table) |
| Number of rows in an Arrow table, or 0 when it is null. | |
| bool | writeTableToParquet (const std::shared_ptr< arrow::Table > &table, const std::string &filename, const ParquetWriteConfig &config=ParquetWriteConfig{}) |
| Write an Arrow table to a Parquet file. | |
| std::shared_ptr< arrow::Table > | withColumns (const std::shared_ptr< arrow::Table > &table, const std::vector< ParquetColumn > &columns) |
The table with columns added: a column of the name of an existing one replaces it (in its place), any other is appended. The schema metadata of table is kept. | |
| std::shared_ptr< arrow::Table > | tableOfColumns (const std::vector< ParquetColumn > &columns, Size rows) |
A table of columns (in their order, without schema metadata), for callers outside libOpenMS that cannot use Arrow themselves (TOPP tools), e.g. a QPX metadata view (run, provenance) | |
| bool | concatenateAndWriteToParquet (const std::vector< std::shared_ptr< arrow::Table > > &tables, const std::string &filename, const ParquetWriteConfig &config=ParquetWriteConfig{}, const std::shared_ptr< const arrow::KeyValueMetadata > &metadata=nullptr) |
| Concatenate a vector of Arrow tables and write the result to a Parquet file. | |
| bool | validateQPXTable (const std::shared_ptr< arrow::Table > &table, const std::string &filename, const ParquetWriteConfig &config=ParquetWriteConfig{}, const std::shared_ptr< const arrow::KeyValueMetadata > &metadata=nullptr) |
The QPX value validation of writeTableToParquet() alone (QPXValueValidation of the view the table's file_type metadata names; a table without QPX metadata passes) | |
| std::shared_ptr< const arrow::KeyValueMetadata > | qpxFileMetadata (const std::string &file_type, const ParquetWriteConfig &config=ParquetWriteConfig{}, const std::map< std::string, std::string > &extra={}) |
| Build the canonical QPX file-level key-value metadata. | |
| std::string | qpxScanFormat (const std::string &native_id) |
Classify a spectrum native ID into a QPX scan_format token. | |
| std::string | qpxScanFormat (const std::vector< std::string > &native_ids) |
Derive a single QPX scan_format token for a set of native IDs. | |
| std::string | qpxScanFormat (const std::vector< std::string > &native_ids, int threads) |
| std::string | qpxRunFileName (const std::string &ms_run_path) |
Reduce an MS run path to the QPX run_file_name form. | |
| std::vector< Int32 > | qpxScanComponents (const std::string &spectrum_reference) |
The QPX scan column value for one spectrum reference. | |
| std::string | qpxPsmRunFileName (const MetaInfoInterface &hit, const MetaInfoInterface &identification, const std::string &resolved_run_file, const QPXRunFileNameKeys &keys) |
The QPX run_file_name the psm view writes for one identification and hit. | |
| bool | qpxWarnOnRunNameCollisions (const std::string &context, const std::vector< std::string > &ms_run_paths) |
Warn once per export about source files that collapse onto one run_file_name. | |
| std::string | qpxIntensityLabel (const std::string &column_label, const std::string &channel_name) |
QPX intensities[].label for a ConsensusMap column header. | |
| std::map< std::uint64_t, std::string > | qpxIntensityLabels (const ConsensusMap &cmap) |
| Derive canonical QPX intensity labels for every ConsensusMap column. | |
| bool | qpxIsCanonicalIntensityLabel (const std::string &label) |
| Test whether a string is in the canonical SDRF/QPX intensity-label vocabulary. | |
| std::vector< std::pair< std::string, std::string > > | qpxCvParams (const MetaInfoInterface &hit) |
The meta values of an identification that QPX carries as cv_params. | |
| std::vector< std::pair< std::string, std::string > > | qpxCvParams (const MetaInfoInterface &hit, const MS1LabelState::Keys &keys) |
| qpxCvParams() with the registry indices resolved once (MS1LabelState::Keys), for a loop over many hits | |
| std::shared_ptr< arrow::Array > | getColumn (const std::shared_ptr< arrow::Table > &table, const std::string &name, bool required=true) |
| Fetch a named column from a table, combining chunks if needed. | |
| std::string | getStringValue (const std::shared_ptr< arrow::Array > &array, int64_t row) |
Read a string at row, or "" if null/out-of-bounds. | |
| double | getDoubleValue (const std::shared_ptr< arrow::Array > &array, int64_t row, double default_val=0.0) |
Read a double at row, or default_val if null. | |
| float | getFloatValue (const std::shared_ptr< arrow::Array > &array, int64_t row, float default_val=0.0f) |
Read a float at row, or default_val if null. | |
| int32_t | getInt32Value (const std::shared_ptr< arrow::Array > &array, int64_t row, int32_t default_val=0) |
Read an int32 at row, or default_val if null. | |
| int64_t | getInt64Value (const std::shared_ptr< arrow::Array > &array, int64_t row, int64_t default_val=0) |
Read an int64 at row, or default_val if null. | |
| bool | getBoolValue (const std::shared_ptr< arrow::Array > &array, int64_t row, bool default_val=false) |
Read a bool at row, or default_val if null. | |
| bool | isNull (const std::shared_ptr< arrow::Array > &array, int64_t row) |
Whether array is null at row (or unset) | |
| std::string | metaValueString (const DataValue &value) |
| The text a metavalue is written as in a list<struct{name,value,value_type}> column. | |
| void | readMetaValues (const std::shared_ptr< arrow::Array > &array, int64_t row, MetaInfoInterface &target, const std::unordered_set< std::string > &excluded_keys={}) |
| Read metavalues from a list<struct{name,value,value_type}> column. | |
Public helpers for writing and concatenating Arrow tables to Parquet files.
TOPP tools link against libOpenMS (which exports these helpers) but not directly against Arrow/Parquet. These wrappers keep all Arrow/Parquet API calls inside libOpenMS so downstream binaries don't need to import Arrow symbols.
| bool concatenateAndWriteToParquet | ( | const std::vector< std::shared_ptr< arrow::Table > > & | tables, |
| const std::string & | filename, | ||
| const ParquetWriteConfig & | config = ParquetWriteConfig{}, |
||
| const std::shared_ptr< const arrow::KeyValueMetadata > & | metadata = nullptr |
||
| ) |
Concatenate a vector of Arrow tables and write the result to a Parquet file.
All tables must share the same schema. An empty input vector is a no-op (returns true without writing).
| [in] | tables | Vector of Arrow tables to concatenate (must share schema) |
| [in] | filename | Output file path |
| [in] | config | Parquet writer configuration |
| [in] | metadata | Schema key-value metadata for the merged file. Concatenation otherwise inherits the first input's metadata, i.e. that table's identity; pass a fresh one (see qpxFileMetadata()) so the merged file is its own. nullptr keeps whatever the concatenation produced. |
tables is empty), false on error | std::string generateUuidV4 | ( | ) |
Generate a lowercase hyphenated RFC 4122 version-4 UUID string.
Used by QPX Parquet exporters when attaching file metadata.
| bool getBoolValue | ( | const std::shared_ptr< arrow::Array > & | array, |
| int64_t | row, | ||
| bool | default_val = false |
||
| ) |
Read a bool at row, or default_val if null.
| std::shared_ptr< arrow::Array > getColumn | ( | const std::shared_ptr< arrow::Table > & | table, |
| const std::string & | name, | ||
| bool | required = true |
||
| ) |
Fetch a named column from a table, combining chunks if needed.
Returns nullptr if the column is missing or contains no chunks. When required is true, missing columns are logged as errors.
| double getDoubleValue | ( | const std::shared_ptr< arrow::Array > & | array, |
| int64_t | row, | ||
| double | default_val = 0.0 |
||
| ) |
Read a double at row, or default_val if null.
| float getFloatValue | ( | const std::shared_ptr< arrow::Array > & | array, |
| int64_t | row, | ||
| float | default_val = 0.0f |
||
| ) |
Read a float at row, or default_val if null.
| int32_t getInt32Value | ( | const std::shared_ptr< arrow::Array > & | array, |
| int64_t | row, | ||
| int32_t | default_val = 0 |
||
| ) |
Read an int32 at row, or default_val if null.
| int64_t getInt64Value | ( | const std::shared_ptr< arrow::Array > & | array, |
| int64_t | row, | ||
| int64_t | default_val = 0 |
||
| ) |
Read an int64 at row, or default_val if null.
| std::string getStringValue | ( | const std::shared_ptr< arrow::Array > & | array, |
| int64_t | row | ||
| ) |
Read a string at row, or "" if null/out-of-bounds.
| bool isNull | ( | const std::shared_ptr< arrow::Array > & | array, |
| int64_t | row | ||
| ) |
Whether array is null at row (or unset)
| std::string metaValueString | ( | const DataValue & | value | ) |
The text a metavalue is written as in a list<struct{name,value,value_type}> column.
The same as DataValue::toString(), except for doubles (also in lists): they are written in their shortest form that reads back as the same double, so that readMetaValues() restores them exactly. DataValue::toString() rounds values between 0.01 and 10000 to 15 decimals, which loses the last digits of e.g. 1.2345678901234567.
| std::vector< std::pair< std::string, std::string > > qpxCvParams | ( | const MetaInfoInterface & | hit | ) |
The meta values of an identification that QPX carries as cv_params.
QPX reserves cv_params, a list of {cv_name, cv_value} pairs, on the feature and psm views for annotations outside the fixed schema. OpenMS uses it for the label state of an MS1-labeled identification, i.e. the MS1LabelState meta values MS1Label:labeled_sequence, MS1Label:removed_labels and MS1Label:channel that MS1LabeledWorkflow records on the PeptideHit.
Only these keys are exported, so identifications without a label state (label-free, isobaric) keep a null cv_params, as before.
| [in] | hit | The PeptideHit (or any MetaInfoInterface) to read the keys from |
| std::vector< std::pair< std::string, std::string > > qpxCvParams | ( | const MetaInfoInterface & | hit, |
| const MS1LabelState::Keys & | keys | ||
| ) |
qpxCvParams() with the registry indices resolved once (MS1LabelState::Keys), for a loop over many hits
| std::shared_ptr< const arrow::KeyValueMetadata > qpxFileMetadata | ( | const std::string & | file_type, |
| const ParquetWriteConfig & | config = ParquetWriteConfig{}, |
||
| const std::map< std::string, std::string > & | extra = {} |
||
| ) |
Build the canonical QPX file-level key-value metadata.
Writes the keys defined by the QPX serialization spec: qpx_version, file_type, creator, software_provider, creation_date (ISO 8601), compression_format and uuid, plus any extra keys.
Build this once per output file and reuse the returned object for both the writer schema and every batch — each call mints a fresh uuid and creation_date, so calling it per batch would produce mismatched schemas.
For a known file_type it also stamps primary_key and identity_composite, the declaration a reader needs to re-derive the view's opaque row ids (see QPXIdentity). Done here rather than per exporter so that a producer cannot emit ids without saying what they were derived from.
| [in] | file_type | QPX view token: "psm_file", "feature_file" or "pg_file" |
| [in] | config | Write configuration; supplies compression_format |
| [in] | extra | Additional keys, e.g. {{"scan_format", "scan"}} |
nullptr if config selects a compression QPX does not define (LZ4). Callers must treat nullptr as a write failure. | std::string qpxIntensityLabel | ( | const std::string & | column_label, |
| const std::string & | channel_name | ||
| ) |
QPX intensities[].label for a ConsensusMap column header.
The label is a join key: QPX matches intensities[].label against the unnested run.samples[].label of run.parquet (docs/spec/views.md), so it must be a canonical channel token, not a channel index or a file name.
Isobaric channels resolve to the reporter name prefixed by the method family, using OpenMS' own channel names — "TMT126", "TMT131" (TMT10-plex channel 10), "ITRAQ114". Label-free maps resolve to "LFQ". Recognizable SILAC modification labels resolve by mass class; callers that have a whole ConsensusMap should prefer qpxIntensityLabels(), which can distinguish a two-plex second channel (heavy by role) from a three-plex medium channel.
| [in] | column_label | ConsensusMap::ColumnHeader::label. IsobaricChannelExtractor writes "<methodname>_<channelname>" (e.g. "tmt10plex_126"); ProteomicsLFQ writes "label-free". |
| [in] | channel_name | The header's channel_name meta value (e.g. "126"); when it is absent from an isobaric header, the validated column_label suffix is used. |
"" when the isobaric method, non-isobaric vocabulary token, or SILAC role cannot be identified — writing a guessed token into a join key is worse than writing none, so callers must handle the empty result. | std::map< std::uint64_t, std::string > qpxIntensityLabels | ( | const ConsensusMap & | cmap | ) |
Derive canonical QPX intensity labels for every ConsensusMap column.
Unlike the scalar overload, this sees all columns of one source run. It recognizes the FeatureFinderMultiplex SILAC shapes and maps them to the active SDRF/QPX vocabulary: "SILAC light" / "SILAC heavy" for two-plex and "SILAC light" / "SILAC medium" / "SILAC heavy" for three-plex. The mapping is by channel role, so a two-plex Arg6 channel is correctly called heavy even though the same modification is the medium channel in the standard three-plex.
| [in] | cmap | ConsensusMap whose column headers are labelled |
"" and is logged; exporters must refuse it. | bool qpxIsCanonicalIntensityLabel | ( | const std::string & | label | ) |
Test whether a string is in the canonical SDRF/QPX intensity-label vocabulary.
Covers every isobaric method supported by OpenMS plus the QPX LFQ, SILAC, mTRAQ, and dimethyl plex labels. Intended for write-time value validation, after producer-specific labels have been normalized.
| [in] | label | Candidate label |
label is a canonical QPX channel token | std::string qpxPsmRunFileName | ( | const MetaInfoInterface & | hit, |
| const MetaInfoInterface & | identification, | ||
| const std::string & | resolved_run_file, | ||
| const QPXRunFileNameKeys & | keys | ||
| ) |
The QPX run_file_name the psm view writes for one identification and hit.
Prefers a per-hit or per-identification file reference over the identification run's resolved path, then reduces it with qpxRunFileName().
Shared with the feature view for the same reason as qpxScanComponents(): the feature view has to reproduce this exactly to decide which of its rows a given PSM belongs to.
The metavalue keys are passed as pre-resolved MetaInfoRegistry indices rather than looked up by name: MetaInfoRegistry::getIndex() takes an omp critical lock, and this runs once per row inside the exporters' parallel batch build, where a per-row lock would serialize it. Resolve them once outside the row loop with QPXRunFileNameKeys.
| [in] | hit | The PSM's hit; consulted for reference_file_name / run_file_name |
| [in] | identification | The PSM; consulted for reference_file_name |
| [in] | resolved_run_file | Fallback path from IdentifierMSRunMapper::getPrimaryMSRunPath() |
| [in] | keys | Pre-resolved metavalue indices |
| std::string qpxRunFileName | ( | const std::string & | ms_run_path | ) |
Reduce an MS run path to the QPX run_file_name form.
QPX defines run_file_name as the raw data file name without extension, and uses it as a primary-key component in the psm, feature and pg views (and to join them against run.parquet). The full name with extension belongs in run.file_name.
| [in] | ms_run_path | Source path, e.g. /data/proj/S1_Frontal_1.mzML |
S1_Frontal_1; empty input yields an empty result. Referenced by QuantificationUnits::QuantificationUnits().
| std::vector< Int32 > qpxScanComponents | ( | const std::string & | spectrum_reference | ) |
The QPX scan column value for one spectrum reference.
QPX stores scan as a list of integer components. OpenMS derives it from the spectrum's native ID, whose format is auto-detected.
Shared by the psm and feature views on purpose. scan is part of both views' identity composites, so the id linking a PSM to its feature is only reproducible while both extract the same number from the same reference – two verbatim copies of this would be one edit away from a collection whose cross-references silently stop resolving.
| [in] | spectrum_reference | Native ID, e.g. controllerType=0 controllerNumber=1 scan=2075 |
| std::string qpxScanFormat | ( | const std::string & | native_id | ) |
Classify a spectrum native ID into a QPX scan_format token.
| [in] | native_id | A spectrum native ID (e.g. controllerType=0 ... scan=1234) |
"index" for index= IDs, "scan" for other recognized native IDs, or "" when the convention cannot be determined.| std::string qpxScanFormat | ( | const std::vector< std::string > & | native_ids | ) |
Derive a single QPX scan_format token for a set of native IDs.
Unrecognized IDs are ignored. Returns "" when no ID is recognized, or when the inputs disagree — mixed conventions are reported once via the log rather than guessed at, so an ambiguous export omits scan_format instead of mislabeling it.
| std::string qpxScanFormat | ( | const std::vector< std::string > & | native_ids, |
| int | threads | ||
| ) |
qpxScanFormat(native_ids) checking the IDs in threads ranges in parallel (OpenMP; 1: serial): the same result and the same warning (the first pair of conventions in ID order)
| bool qpxWarnOnRunNameCollisions | ( | const std::string & | context, |
| const std::vector< std::string > & | ms_run_paths | ||
| ) |
Warn once per export about source files that collapse onto one run_file_name.
QPX defines the column as the file name without path or extension, so two distinct paths sharing a stem (/a/run1.mzML and /b/run1.mzML) become indistinguishable as a join and partition key. Same-named files in different directories are a legitimate layout and the origin is known – only the spec's representation cannot express it – so this warns rather than failing, matching the policy the PSM exporter already applies.
| [in] | context | Caller name for the log line |
| [in] | ms_run_paths | Source paths participating in one QPX collection |
| void readMetaValues | ( | const std::shared_ptr< arrow::Array > & | array, |
| int64_t | row, | ||
| MetaInfoInterface & | target, | ||
| const std::unordered_set< std::string > & | excluded_keys = {} |
||
| ) |
Read metavalues from a list<struct{name,value,value_type}> column.
Decodes typed entries (int, double/float, *_list, string) and assigns them to target. Keys in excluded_keys are skipped.
| std::shared_ptr< arrow::Table > tableOfColumns | ( | const std::vector< ParquetColumn > & | columns, |
| Size | rows | ||
| ) |
A table of columns (in their order, without schema metadata), for callers outside libOpenMS that cannot use Arrow themselves (TOPP tools), e.g. a QPX metadata view (run, provenance)
| [in] | columns | The columns, each with rows entries |
| [in] | rows | The number of rows |
| Exception::IllegalArgument | if a column has another number of rows |
| Size tableRowCount | ( | const std::shared_ptr< arrow::Table > & | table | ) |
Number of rows in an Arrow table, or 0 when it is null.
Exists so that a TOPP tool can ask "did this table come out empty?" without calling an Arrow member function itself. Arrow is deliberately confined to libOpenMS' implementation (see the note on ParquetTableComparator), and on Windows its symbols are dllimport, so a tool that calls arrow::Table::num_rows() directly fails to link there while building fine on Linux.
| [in] | table | the table to measure; may be null |
| bool validateQPXTable | ( | const std::shared_ptr< arrow::Table > & | table, |
| const std::string & | filename, | ||
| const ParquetWriteConfig & | config = ParquetWriteConfig{}, |
||
| const std::shared_ptr< const arrow::KeyValueMetadata > & | metadata = nullptr |
||
| ) |
The QPX value validation of writeTableToParquet() alone (QPXValueValidation of the view the table's file_type metadata names; a table without QPX metadata passes)
For a table that is written more than once (a run's own file and the merged file of a single run): validated here once, with config.threads, then written with config.validated set. A refused table is logged as by the write.
| [in] | table | The table (must not be null) |
| [in] | filename | The file it is for (in the log) |
| [in] | config | qpx_extra_columns and threads |
| [in] | metadata | The footer the table is written with (concatenateAndWriteToParquet()): it names the view (file_type); a table built by an exporter carries none itself, so without it nothing is checked |
| std::shared_ptr< arrow::Table > withColumns | ( | const std::shared_ptr< arrow::Table > & | table, |
| const std::vector< ParquetColumn > & | columns | ||
| ) |
The table with columns added: a column of the name of an existing one replaces it (in its place), any other is appended. The schema metadata of table is kept.
For callers outside libOpenMS that cannot use Arrow themselves (TOPP tools), e.g. to add optional columns to a QPX view before writing it.
| [in] | table | The table (must not be null) |
| [in] | columns | The columns, each with one entry per row of table |
| Exception::IllegalArgument | if a column has another number of rows than table |
| bool writeTableToParquet | ( | const std::shared_ptr< arrow::Table > & | table, |
| const std::string & | filename, | ||
| const ParquetWriteConfig & | config = ParquetWriteConfig{} |
||
| ) |
Write an Arrow table to a Parquet file.
| [in] | table | The Arrow table to write (must not be null) |
| [in] | filename | Output file path |
| [in] | config | Parquet writer configuration (compression, row group size, ...) |