29#include <unordered_map>
47 std::vector<std::string>
runs;
78 const std::set<std::pair<std::string, unsigned>>& known_cells)
80 std::set<std::string> known_runs;
81 for (
const auto& [run, label] : known_cells) { (void)label; known_runs.insert(run); }
85 unsigned fraction_group = 0;
86 unsigned fraction = 0;
87 bool initialized =
false;
88 std::map<unsigned, Size> label_sample;
90 std::map<std::string, RunInfo> run_info;
96 if (run.empty()) {
continue; }
97 if (!known_runs.count(run)) {
dropped_runs_.insert(run);
continue; }
100 invalid_sample_ =
"run '" + run +
"', label " + std::to_string(entry.label)
101 +
" refers to sample " + std::to_string(entry.sample)
102 +
", but the sample section contains " + std::to_string(n_samples)
105 if (!known_cells.count({run, entry.label}))
109 missing_cell_ =
"run '" + run +
"' is in this map, but no column header describes its "
110 "label " + std::to_string(entry.label)
111 +
", which the experimental design declares";
115 auto& info = run_info[run];
116 if (!info.initialized)
118 info.fraction_group = entry.fraction_group;
119 info.fraction = entry.fraction;
120 info.initialized =
true;
125 + std::to_string(info.fraction_group) +
" and "
126 + std::to_string(entry.fraction_group);
131 auto [it, inserted] = info.label_sample.emplace(entry.label, entry.sample);
132 if (!inserted && it->second != entry.sample) {
inconsistent_ =
true; }
135 std::map<UInt, std::vector<std::string>> runs_by_fraction_group;
136 for (
const auto& [run, info] : run_info)
138 runs_by_fraction_group[info.fraction_group].push_back(run);
141 for (
auto& [fraction_group, runs] : runs_by_fraction_group)
145 unit.
runs = std::move(runs);
146 std::sort(unit.
runs.begin(), unit.
runs.end(),
147 [&run_info](
const std::string& a,
const std::string& b)
149 const auto& ia = run_info.at(a);
150 const auto& ib = run_info.at(b);
151 return std::tie(ia.fraction, a) < std::tie(ib.fraction, b);
154 const std::string unit_name =
"fraction group " + std::to_string(fraction_group);
155 std::map<unsigned, Size> label_sample;
156 for (
const auto& run : unit.
runs)
158 for (
const auto& [label, sample] : run_info.at(run).label_sample)
160 auto [ls, ls_fresh] = label_sample.emplace(label, sample);
164 +
" maps to sample " + std::to_string(ls->second) +
" and sample "
165 + std::to_string(sample);
169 for (
const auto& run : unit.
runs)
171 for (
const auto& [label, sample] : label_sample)
173 if (run_info.at(run).label_sample.count(label)) {
continue; }
176 +
" has no design row for label " + std::to_string(label)
177 +
", which resolves to sample " + std::to_string(sample)
178 +
" in the other run(s)";
181 for (
const auto& [label, sample] : label_sample) { unit.
channels.push_back(
QuantChannel{label, sample,
""}); }
182 for (
const auto& run : unit.
runs)
190 units_.push_back(std::move(unit));
223 template <
typename LabelFor>
228 std::map<std::string, unsigned> label_to_channel;
229 for (
auto& channel : unit.channels)
231 channel.qpx_label = label_for(unit.runs.front(), channel.label);
232 if (channel.qpx_label.empty()) {
return false; }
233 for (
size_t i = 1; i < unit.runs.size(); ++i)
235 const std::string other = label_for(unit.runs[i], channel.label);
236 if (other == channel.qpx_label) {
continue; }
237 if (other.empty()) {
return false; }
239 << unit.runs[i] <<
"' belong to fraction group " << unit.fraction_group
240 <<
" but name label " << channel.label <<
" differently ('"
241 << channel.qpx_label <<
"' vs '" << other
242 <<
"'). A grouped row cannot choose one arbitrarily." << std::endl;
245 auto [label_it, label_inserted] = label_to_channel.emplace(channel.qpx_label, channel.label);
246 if (!label_inserted && label_it->second != channel.label)
249 << channel.label <<
" of fraction group " << unit.fraction_group
250 <<
" both resolve to QPX label '" << channel.qpx_label
251 <<
"'. They would duplicate the protein-group primary key." << std::endl;
281 if (array.getName() ==
"abundances") {
return &array; }
292 std::map<std::pair<UInt, UInt>,
float>
values;
299 constexpr const char* abundance_name =
"fraction_group_level_abundance";
300 constexpr const char* fraction_group_name =
"fraction_group_level_fraction_group";
301 constexpr const char* label_name =
"fraction_group_level_label";
308 if (array.getName() == abundance_name) { abundances = &array; }
312 if (array.getName() == fraction_group_name) { fraction_groups = &array; }
313 else if (array.getName() == label_name) { labels = &array; }
317 result.
present = abundances !=
nullptr || fraction_groups !=
nullptr || labels !=
nullptr;
318 if (!result.
present) {
return result; }
319 if (abundances ==
nullptr || fraction_groups ==
nullptr || labels ==
nullptr)
321 result.
valid =
false;
322 result.
error =
"the fraction-group abundance, fraction-group key and label key arrays are not all present";
325 if (abundances->size() != fraction_groups->size() || abundances->size() != labels->size())
327 result.
valid =
false;
328 result.
error =
"the parallel fraction-group abundance arrays have different lengths";
332 for (
Size i = 0; i < abundances->size(); ++i)
336 if ((*fraction_groups)[i] <= 0 || (*labels)[i] <= 0)
338 result.
valid =
false;
339 result.
error =
"a fraction-group or label key is not 1-based";
342 const auto key = std::make_pair(
static_cast<UInt>((*fraction_groups)[i]),
343 static_cast<UInt>((*labels)[i]));
344 if (!result.
values.emplace(key, (*abundances)[i]).second)
346 result.
valid =
false;
347 result.
error =
"the fraction-group abundance arrays contain a duplicate (fraction_group, label) key";
369 const std::set<std::pair<UInt, UInt>>& expected_quantity_keys)
371 if (!quantities.
valid)
373 return "has invalid fraction-group abundance annotations: " + quantities.
error;
375 if (sample_abundances !=
nullptr && sample_abundances->size() != design_samples)
377 return "carries " + std::to_string(sample_abundances->size())
378 +
" sample abundances but the experimental design describes "
379 + std::to_string(design_samples)
380 +
" samples, so the design does not belong to this quantification";
388 const bool quantified = sample_abundances !=
nullptr || quantities.
present;
389 if (!quantified) {
return {}; }
392 return "carries only the legacy sample-level abundances of an older OpenMS; the QPX "
393 "quantification unit is (fraction group, label), so this map has to be re-quantified";
397 return "carries fraction-group abundances, but the experimental design yields no matching "
398 "quantification unit";
400 if (quantities.
values.size() != expected_quantity_keys.size())
402 return "carries " + std::to_string(quantities.
values.size())
403 +
" fraction-group/label quantities but the experimental design requires "
404 + std::to_string(expected_quantity_keys.size())
405 +
", so the annotations and design do not describe the same quantification";
407 for (
const auto& key : expected_quantity_keys)
409 if (!quantities.
values.count(key))
411 return "has no quantity for fraction group " + std::to_string(key.first)
412 +
", label " + std::to_string(key.second);
#define OPENMS_LOG_ERROR
Macro for non-fatal errors (processing continues)
Definition LogStream.h:604
Float data array class.
Definition DataArrays.h:25
Integer data array class.
Definition DataArrays.h:75
Representation of an experimental design in OpenMS. Instances can be loaded with the ExperimentalDesi...
Definition ExperimentalDesign.h:449
unsigned getNumberOfSamples() const
Number of samples measured (= number of rows in the sample section)
const MSFileSection & getMSFileSection() const
Definition ProteinGroupArrowExport_impl.h:58
const std::set< std::string > & droppedRuns() const
Design files the ConsensusMap has no column header for, left out of every unit.
Definition ProteinGroupArrowExport_impl.h:202
std::vector< QuantUnit > units_
Definition ProteinGroupArrowExport_impl.h:260
size_t indexOf(const std::string &run) const
Index of the unit containing run, or units().size() when the design does not list it.
Definition ProteinGroupArrowExport_impl.h:212
QuantificationUnits()=default
const std::string & raggedUnit() const
Non-empty when a unit's runs do not all carry every label it publishes.
Definition ProteinGroupArrowExport_impl.h:200
const std::string & runInSeveralGroups() const
Non-empty when one run is assigned to multiple fraction groups.
Definition ProteinGroupArrowExport_impl.h:208
const std::string & missingCell() const
Non-empty when a run that IS in the map lacks a header for a label the design declares.
Definition ProteinGroupArrowExport_impl.h:204
std::string ambiguous_label_
Definition ProteinGroupArrowExport_impl.h:264
std::string invalid_sample_
Definition ProteinGroupArrowExport_impl.h:266
bool inconsistent_
Definition ProteinGroupArrowExport_impl.h:268
bool inconsistent() const
A design assigning one (run, label) to several samples; the rows would be wrong.
Definition ProteinGroupArrowExport_impl.h:196
bool empty() const
Definition ProteinGroupArrowExport_impl.h:194
std::set< std::string > dropped_runs_
Definition ProteinGroupArrowExport_impl.h:262
std::string missing_cell_
Definition ProteinGroupArrowExport_impl.h:263
const std::vector< QuantUnit > & units() const
Definition ProteinGroupArrowExport_impl.h:209
const std::string & ambiguousLabel() const
Non-empty when one label of a unit means several samples; the row cannot be written.
Definition ProteinGroupArrowExport_impl.h:198
std::unordered_map< std::string, size_t > unit_of_run_
Definition ProteinGroupArrowExport_impl.h:261
QuantificationUnits(const ExperimentalDesign &design, const std::set< std::pair< std::string, unsigned > > &known_cells)
Definition ProteinGroupArrowExport_impl.h:77
std::string ragged_unit_
Definition ProteinGroupArrowExport_impl.h:265
std::string run_in_several_groups_
Definition ProteinGroupArrowExport_impl.h:267
const std::string & invalidSample() const
Non-empty when a design row refers outside its sample section.
Definition ProteinGroupArrowExport_impl.h:206
bool resolveLabels(LabelFor label_for, const std::string &context)
Definition ProteinGroupArrowExport_impl.h:224
Bundles multiple (e.g. indistinguishable) proteins in a group.
Definition ProteinIdentification.h:73
const IntegerDataArrays & getIntegerDataArrays() const
Returns a const reference to the integer meta data arrays.
const FloatDataArrays & getFloatDataArrays() const
Returns a const reference to the float meta data arrays.
unsigned int UInt
Unsigned integer type.
Definition Types.h:64
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition Types.h:97
std::string qpxRunFileName(const std::string &ms_run_path)
Reduce an MS run path to the QPX run_file_name form.
Namespace used to hide implementation details from users.
Definition BayesianProteinInferenceAlgorithm.h:26
std::string validateQuantificationAnnotations(const ProteinIdentification::ProteinGroup::FloatDataArray *sample_abundances, const FractionGroupAbundanceData &quantities, Size design_samples, const QuantificationUnits &units, const std::set< std::pair< UInt, UInt > > &expected_quantity_keys)
Validate one protein group's complete QPX 1.1 quantification annotation contract.
Definition ProteinGroupArrowExport_impl.h:364
UInt fraction_group
OpenMS fraction_group defining this unit.
Definition ProteinGroupArrowExport_impl.h:46
std::string qpx_label
QPX intensity label ("LFQ", "TMT126", ...)
Definition ProteinGroupArrowExport_impl.h:40
std::vector< QuantChannel > channels
one per label the unit's runs carry
Definition ProteinGroupArrowExport_impl.h:48
bool valid
Definition ProteinGroupArrowExport_impl.h:290
Size sample
design sample, retained to validate consistent run/sample resolution
Definition ProteinGroupArrowExport_impl.h:39
std::map< std::pair< UInt, UInt >, float > values
Definition ProteinGroupArrowExport_impl.h:292
std::string error
Definition ProteinGroupArrowExport_impl.h:291
const ProteinIdentification::ProteinGroup::FloatDataArray * sampleAbundances(const ProteinIdentification::ProteinGroup &group)
Definition ProteinGroupArrowExport_impl.h:276
FractionGroupAbundanceData fractionGroupAbundances(const ProteinIdentification::ProteinGroup &group)
Read PeptideAndProteinQuant's named unit-level arrays and validate their parallel-key contract.
Definition ProteinGroupArrowExport_impl.h:296
bool present
Definition ProteinGroupArrowExport_impl.h:289
unsigned label
design label / channel number, 1-based
Definition ProteinGroupArrowExport_impl.h:38
std::vector< std::string > runs
QPX run names, in fraction order.
Definition ProteinGroupArrowExport_impl.h:47
Parsed parallel arrays carrying protein quantities at (fraction_group, label) grain.
Definition ProteinGroupArrowExport_impl.h:288
One label of a quantification unit and the sample it resolves to in the design.
Definition ProteinGroupArrowExport_impl.h:37
One QPX quantification unit: exactly one OpenMS experimental-design fraction group.
Definition ProteinGroupArrowExport_impl.h:45