-
Notifications
You must be signed in to change notification settings - Fork 0
/
UnknownFeatureConsolidationProvider.cs
153 lines (129 loc) · 5.27 KB
/
UnknownFeatureConsolidationProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using OpenMS.OpenMSFile;
using Thermo.Magellan.EntityDataFramework;
using Thermo.Magellan.MassSpec;
using Thermo.Metabolism.DataObjects;
using Thermo.Metabolism.DataObjects.Constants;
using Thermo.Metabolism.DataObjects.EntityDataObjects;
using Thermo.Metabolism.Processing.Common;
namespace OpenMS.AdapterNodes
{
public struct Centroid
{
public double mass;
public double rt;
}
#region Implement logic for Consolidation of UnknownFeatureInstanceItems
public class UnknownFeatureConsolidationProvider : PeakConsolidationProvider<UnknownFeatureIonInstanceItem>
{
private Dictionary<ulong, Centroid> m_dict;
public UnknownFeatureConsolidationProvider(Dictionary<ulong, Centroid> consensusDict, int processingNodeNumber, string processingNodeName, IEntityDataService entityDataService)
: base(processingNodeNumber, processingNodeName, entityDataService)
{
m_dict = consensusDict;
}
public override IEnumerable<ConsolidatedComponentPeak> RetrieveComponentPeaks()
{
// init container
var componentPeaks = new List<ConsolidatedComponentPeak>();
// get entity reader
var entityReader = EntityDataService.CreateEntityItemReader();
// read all the peaks
foreach (var ion in entityReader.ReadAll<UnknownFeatureIonInstanceItem>())
{
// 1 ion has at least 1 peak, monoisotopic was used for Ion information
// (UnknownCompound..:process each ion individually)
// make ConsolidatedComponentPeak
var fid = Convert.ToUInt64(ion.FeatureID);
componentPeaks.Add(new ConsolidatedComponentPeak
{
Mass = m_dict[fid].mass,
RetentionTime = m_dict[fid].rt,
Area = ion.Area,
IonDescription = "unknown",
FileID = ion.FileID,
IdentifyingNodeNumber = ProcessingNodeNumber,
RelatedItemIDs = ion.GetIDs()
});
}
return componentPeaks;
}
/// <summary>
/// Compares individual items with their respective items from control file.
/// </summary>
/// <param name="items">Items to compare.</param>
/// <param name="sampleToControlMaxFold">Maximum sample to control ratio.</param>
/// <param name="controlToSampleMaxFold">Maximum control to sample ratio.</param>
/// <param name="massTolerance">Mass tolerance used for peak consolidation.</param>
/// <param name="inputFiles">Input files information sorted in the final view order.</param>
protected override Dictionary<UnknownFeatureIonInstanceItem, Tuple<InControlStatus, double?>> CompareComponentItems(
List<UnknownFeatureIonInstanceItem> items,
double sampleToControlMaxFold,
double controlToSampleMaxFold,
MassTolerance massTolerance,
List<InputFileInfo> inputFiles)
{
// init results dict
var results = new Dictionary<UnknownFeatureIonInstanceItem, Tuple<InControlStatus, double?>>();
// make input files map
var inputFilesMap = inputFiles.ToDictionary(key => key.FileID);
// get all control items
var controlItems = items.Where(w => inputFilesMap[w.FileID].IsReference).ToList();
// compare all items
foreach (var item in items)
{
// init status and ratio
InControlStatus status;
double? ratio = null;
// get input file info
var inputFile = inputFilesMap[item.FileID];
// control item itself but NOT found
if (inputFile.IsReference && item.Area.Equals(0))
{
status = InControlStatus.NotInControlSelf;
results.Add(item, Tuple.Create(status, ratio));
continue;
}
// control item itself
if (inputFile.IsReference)
{
status = InControlStatus.InControlSelf;
results.Add(item, Tuple.Create(status, ratio));
continue;
}
// no control file assigned
if (inputFile.HasReference == false)
{
status = InControlStatus.NoControlAssigned;
results.Add(item, Tuple.Create(status, ratio));
continue;
}
// get corresponding control item
double maxDelta = massTolerance.GetToleranceInU(item.MolecularWeight);
var controlItem = controlItems.FirstOrDefault(w => w.FileID == inputFile.ReferenceFileID && Math.Abs(w.MolecularWeight - item.MolecularWeight) <= maxDelta);
// not found in control
if (controlItem == null || controlItem.Area.Equals(0))
{
status = InControlStatus.NotInControl;
results.Add(item, Tuple.Create(status, ratio));
continue;
}
// calc sample to control area ratio
ratio = item.Area / controlItem.Area;
// get in-control status
bool inControl = (sampleToControlMaxFold.Equals(0) || ratio <= sampleToControlMaxFold) &&
(controlToSampleMaxFold.Equals(0) || 1.0 / ratio <= controlToSampleMaxFold);
status = (inControl) ? InControlStatus.InControl : InControlStatus.Outside;
// store result
results.Add(item, Tuple.Create(status, ratio));
}
return results;
}
}
#endregion
}