ProteoWizard
SpectrumList_MSn_Test.cpp
Go to the documentation of this file.
1 //
2 // $Id: SpectrumList_MSn_Test.cpp 4129 2012-11-20 00:05:37Z chambm $
3 //
4 //
5 // Original author: Barbara Frewen <frewen@u.washington.edu>
6 //
7 // Copyright 2008 Spielberg Family Center for Applied Proteomics
8 // Cedars Sinai Medical Center, Los Angeles, California 90048
9 //
10 // Licensed under the Apache License, Version 2.0 (the "License");
11 // you may not use this file except in compliance with the License.
12 // You may obtain a copy of the License at
13 //
14 // http://www.apache.org/licenses/LICENSE-2.0
15 //
16 // Unless required by applicable law or agreed to in writing, software
17 // distributed under the License is distributed on an "AS IS" BASIS,
18 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 // See the License for the specific language governing permissions and
20 // limitations under the License.
21 //
22 
23 
24 #include "SpectrumList_MSn.hpp"
25 #include "Serializer_MSn.hpp"
26 #include "TextWriter.hpp"
31 #include <iostream>
32 #include <iterator>
33 #include <cstring>
34 
35 
36 using namespace pwiz::msdata;
37 using namespace pwiz::util;
38 using namespace pwiz::minimxml;
39 
40 
41 ostream* os_ = 0;
42 
43 const char *testMS1 =
44 "H CreationDate 10-6-2007\n"
45 "H Extractor MakeMS2\n"
46 "H ExtractorVersion 2.0\n"
47 "H Comments MakeMS2 written by Michael J. MacCoss, Michael R. Hoopmann, 2007\n"
48 "H ExtractorOptions MS1\n"
49 "S 116 116\n"
50 "I RTime 0.4462\n"
51 "175.4067 0.6\n"
52 "195.9831 0.9\n"
53 "236.2524 0.7\n"
54 "266.1989 0.8\n"
55 "276.3145 0.6\n"
56 "278.6099 0.7\n"
57 "281.1050 62.6\n"
58 "298.4888 9.2\n"
59 "299.1033 4\n"
60 "303.5076 1.8\n"
61 "330.1379 1.9\n"
62 "337.1581 0.6\n"
63 "341.0460 1.8\n"
64 "342.3756 0.8\n"
65 "359.0190 1.7\n"
66 "363.0510 1.1\n"
67 "373.2335 1.7\n"
68 "377.2952 1\n"
69 "399.2092 1.6\n"
70 "399.8853 1\n"
71 "403.3747 2.2\n"
72 "405.3385 0.6\n"
73 "408.1845 0.8\n"
74 "409.8174 0.8\n"
75 "414.0231 1.2\n"
76 "415.0792 1.8\n"
77 "417.1754 1.6\n"
78 "419.3268 1.2\n"
79 "420.4443 1.5\n"
80 "421.3249 1.1\n"
81 "429.1662 2.5\n"
82 "435.1794 0.8\n"
83 "436.3020 1.9\n"
84 "439.8971 1\n"
85 "440.6216 1.1\n"
86 "443.7952 0.6\n"
87 "444.5042 1.2\n"
88 "447.0575 0.6\n"
89 "448.5712 1.8\n"
90 "451.1549 2\n"
91 "452.1009 0.8\n"
92 "453.0457 0.7\n"
93 "461.8017 0.7\n"
94 "464.1340 2.7\n"
95 "469.8256 1.8\n"
96 "471.8412 1\n"
97 "473.1831 3.2\n"
98 "474.2579 1\n"
99 "479.8830 1.1\n"
100 "482.2438 1.7\n"
101 "483.1778 2.8\n"
102 "483.8499 0.8\n"
103 "486.1272 2.8\n"
104 "487.5856 0.7\n"
105 "489.5583 4.5\n"
106 "490.6985 4.2\n"
107 "491.4770 5.2\n"
108 "492.3076 7.9\n"
109 "496.1183 1.2\n"
110 "498.5404 2.6\n"
111 "500.5744 7.8\n"
112 "501.2284 6.6\n"
113 "501.9958 3.9\n"
114 "503.0387 37.4\n"
115 "505.0599 2.9\n"
116 "507.2243 1.2\n"
117 "508.2107 0.8\n"
118 "509.1219 2.4\n"
119 "510.4375 0.9\n"
120 "511.3940 0.7\n"
121 "513.4534 3.5\n"
122 "514.4604 4.5\n"
123 "517.0839 6.3\n"
124 "518.1203 18.8\n"
125 "519.0070 65\n"
126 "525.1636 3.1\n"
127 "526.4990 9.4\n"
128 "527.5856 12.2\n"
129 "560.5077 1.2\n"
130 "585.4477 2\n"
131 "621.8749 0.7\n"
132 "632.6031 1\n"
133 "634.1111 0.7\n"
134 "636.3641 1.2\n"
135 "638.4987 1.1\n"
136 "640.5447 1.7\n"
137 "650.5433 0.9\n"
138 "664.1221 0.8\n"
139 "698.4615 0.9\n"
140 "709.7639 1.1\n"
141 "711.2064 1.1\n"
142 "726.0311 1.2\n"
143 "740.0786 0.8\n"
144 "745.3728 0.6\n"
145 "757.8849 1\n"
146 "761.9862 0.8\n"
147 "774.4131 1.3\n"
148 "788.2714 1\n"
149 "829.2268 0.7\n"
150 "840.0249 2\n"
151 "856.4430 0.8\n"
152 "857.6420 0.7\n"
153 "898.4391 0.8\n"
154 "902.4149 0.7\n"
155 "942.4218 1.4\n"
156 "1026.6023 1\n"
157 "S 118 118\n"
158 "I RTime 0.4573\n"
159 "159.1265 1\n"
160 "176.0755 1.4\n"
161 "189.2380 1.3\n"
162 "199.4232 0.8\n"
163 "205.2997 0.6\n"
164 "213.3207 1.4\n"
165 "221.2078 0.9\n"
166 "231.0154 1.6\n"
167 "238.9865 1\n"
168 "244.2399 1.4\n"
169 "249.2524 1.1\n"
170 "252.1188 0.9\n"
171 "253.2228 0.9\n"
172 "263.1987 0.8\n"
173 "269.3484 0.8\n"
174 "272.3980 0.9\n"
175 "273.2263 0.9\n"
176 "276.9475 2.2\n"
177 "279.2698 1.4\n"
178 "299.1149 0.8\n"
179 "302.9478 0.8\n"
180 "305.6744 1.4\n"
181 "308.3992 1.2\n"
182 "317.9594 1.3\n"
183 "322.2583 1.2\n"
184 "332.9634 0.7\n"
185 "337.3151 0.8\n"
186 "346.9624 1.3\n"
187 "349.1566 2.3\n"
188 "351.1241 1.3\n"
189 "357.0767 1.8\n"
190 "361.8666 0.9\n"
191 "363.1213 2.1\n"
192 "365.3057 1.3\n"
193 "370.7582 2.3\n"
194 "375.0994 1.5\n"
195 "377.1262 4.7\n"
196 "383.2674 2.4\n"
197 "385.3204 1.1\n"
198 "386.8699 0.8\n"
199 "390.2235 2\n"
200 "391.1315 1.8\n"
201 "393.2798 1.3\n"
202 "399.0021 0.7\n"
203 "399.8439 1\n"
204 "401.0514 2\n"
205 "401.9986 2.1\n"
206 "405.0557 2.3\n"
207 "406.2401 1.8\n"
208 "407.1901 2.9\n"
209 "409.2251 0.9\n"
210 "410.0710 1.1\n"
211 "411.0744 4.5\n"
212 "412.0661 3.5\n"
213 "416.1904 0.8\n"
214 "418.3093 0.8\n"
215 "419.3824 4.1\n"
216 "420.0984 3.3\n"
217 "421.1917 10.7\n"
218 "422.2375 2.3\n"
219 "423.5126 1.9\n"
220 "424.3980 1.3\n"
221 "426.1027 0.9\n"
222 "426.8067 0.8\n"
223 "428.1773 5.9\n"
224 "429.0244 4.4\n"
225 "430.1233 1.5\n"
226 "433.7563 1.5\n"
227 "435.2169 1.1\n"
228 "435.9414 0.9\n"
229 "437.1042 2.3\n"
230 "438.0438 1.2\n"
231 "442.4830 4.6\n"
232 "443.4222 1.6\n"
233 "446.2477 23.2\n"
234 "447.0900 44.6\n"
235 "447.9651 5.1\n"
236 "452.9314 2.1\n"
237 "455.4204 6.1\n"
238 "456.3987 3\n"
239 "464.9924 12\n"
240 "466.0859 1.3\n"
241 "482.7336 1.8\n"
242 "531.3920 0.8\n"
243 "646.3096 1.8\n"
244 ;
245 
246 const char *testBMS1 =
247 "AQAAAAMAAABDcmVhdGlvbkRhdGUJMTAtNi0yMDA3CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEV4dHJhY3RvcglNYWtlTVMyCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARXh0cmFjdG9yVmVyc2lvbgkyLjAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDb21tZW50cwlNYWtlTVMyIHdyaXR0ZW4gYnkgTWljaGFlbCBKLiBNYWNDb3NzLCBNaWNoYWVsIFIuIEhvb3BtYW5uLCAyMDA3CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEV4dHJhY3Rvck9wdGlvbnMJTVMxCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOjsAAAAA4LNaC/9/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgENzAAAAAAA/AAAAAAAAAGe2Wgv/fwAAACiWEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAYBITgAAAAAAACmWEAAAAADRa0wAAAAAAAAAAAAAAAAALY1OAAAAAAAAAAAAAAAAAJ6BTwAAAAAAsCWWEAAAAAAHAAAAAAAAAAAAAAAAAAAA0LRaC/9/AAAAtloL/38AAFAflhAAAAAA8M9aC/9/AADAZUcAAAAAAIBlRwAAAAAARolMAAAAAAAvbmV0L2dzL3ZvbDMvc29mdHdhcmUvbW9kdWxlcy1zdy9nY2MvNC41LjEvTGludXgvUkhFTDUveDg2XzY0L2xpYjY0LwAvbmV0L2dzL3ZvbHQAAAB0AAAAAAAAAAAAAABUdOQ+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAagAAABDpt68D7WVAmpkZP1OWIY51f2hAZmZmP1UwKqkTiG1AMzMzP8oyxLEuo3BAzcxMP3npJjEIRXFAmpkZP0mdgCbCaXFAMzMzP0jhehSukXFAZmZ6Qo/k8h/Sp3JAMzMTQdSa5h2nsXJAAACAQDJ3LSEf+HJAZmbmP+VhodY0onRAMzPzP/aX3ZOHEnVAmpkZP9v5fmq8UHVAZmbmPwtGJXUCZnVAzcxMP/yp8dJNcHZAmpnZP4lBYOXQsHZAzcyMP9v5fmq8U3dAmpnZP3icoiO5lHdAAACAPyxlGeJY83hAzczMP2EyVTAq/nhAAACAP/tcbcX+NXlAzcwMQCPb+X5qVXlAmpkZP8uhRbbzgnlAzcxMPwK8BRIUnXlAzcxMP5oIG55e4HlAmpmZP34dOGdE8XlAZmbmP3/7OnDOEnpAzczMP1MFo5I6NXpAmpmZP84ZUdobR3pAAADAP4enV8oyVXpAzcyMP4bJVMGo0npAAAAgQHDOiNLeMntAzcxMP0a28/3URHtAMzPzP96Th4VafntAAACAPxlz1xLyiXtAzcyMP3icoiO5vHtAmpkZP0vqBDQRyHtAmpmZP1K4HoXr8HtAmpkZP5p3nKIjCXxAZmbmP2gibHh6MnxAAAAAQKqCUUmdQXxAzcxMP9ZW7C+7UHxAMzMzP0ATYcPT3HxAMzMzP6AaL90kAn1AzcwsQD55WKg1XX1AZmbmP1OWIY51fX1AAACAP13+Q/rtkn1AzcxMQDcawFsgpH1AAACAP+Olm8Qg/n1AzcyMPz0s1JrmI35AmpnZP6kT0ETYMn5AMzMzQO0NvjCZPX5AzcxMP9IA3gIJYn5AMzMzQJoIG55eeX5AMzMzP7UV+8vumH5AAACQQBkEVg4tq35AZmaGQBKDwMqht35AZmamQP5D+u3rxH5Azcz8QN5xio7kAX9AmpmZPyJseHqlKH9AZmYmQCntDb4wSX9Ampn5QIEmwoanU39AMzPTQLUV+8vuX39Ampl5QK8l5IOecH9AmpkVQn3Qs1n1kH9Ampk5QOPHmLuWs39AmpmZP0aU9gZfw39AzcxMPx4Wak3z0X9AmpkZQAAAAAAA539AZmZmP/yp8dJN9n9AMzMzPw3gLZCgC4BAAABgQKH4MeauE4BAAACQQBNhw9OrKIBAmpnJQKyt2F/2MIBAZmaWQZMYBFYOOIBAAACCQgFNhA1PaYBAZmZGQKJFtvP9c4BAZmYWQU2EDU+vfIBAMzNDQW+BBMUPhIFAmpmZP1vTvOOUS4JAAAAAQCo6ksv/boNAMzMzP77BFybTxINAAACAP6+UZYjj0INAMzMzP8rDQq3p4oNAmpmZPx/0bFb984NAzcyMPw1xrItbBIRAmpnZP1afq61YVIRAZmZmP7yWkA/6wIRAzcxMP9V46Sax04VAZmZmP1FrmnccLoZAzcyMPygPC7WmOYZAzcyMPz9XW7E/sIZAmpmZP7prCfmgIIdAzcxMP5f/kH77SodAmpkZP9iBc0YUr4dAAACAP4Za07zjz4dAzcxMP9JvXwdOM4hAZmamPxNhw9MroohAAACAP921hHzQ6YlAMzMzP11txf4yQIpAAAAAQAaBlUOLw4pAzcxMP0Jg5dAizYpAMzMzP2Rd3EaDE4xAzcxMP+JYF7dRM4xAMzMzP5+rrdhfc41AMzOzP4bJVMFoCpBAAACAP3YAAAB2AAAAAAAAAAAAAAA6I+o+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVQAAADVeukkM5GNAAACAPyPb+X5qAmZAMzOzP1YOLbKdp2dAZmamP1r1udqK7WhAzcxMP49TdCSXqWlAmpkZP3h6pSxDqmpAMzOzP3uDL0ympmtAZmZmP3gLJCh+4GxAzczMPyGwcmiR321AAACAP+/Jw0Kth25AMzOzP1UwKqkTKG9AzcyMP3lYqDXNg29AZmZmP5Axdy0hp29AZmZmP3EbDeAtc3BAzcxMP9Pe4AuT1XBAzcxMP+58PzVeBnFAZmZmP1uxv+yeE3FAZmZmP1yPwvUoT3FAzcwMQF8HzhlRdHFAMzOzP/fkYaHWsXJAzcxMP2EyVTAq73JAzcxMP8KGp1fKGnNAMzOzPwMJih9jRnNAmpmZP4V80LNZ33NAZmamP+lILv8hJHRAmpmZP3ZPHhZqz3RAMzMzP4MvTKYKFXVAzcxMP7raiv1lr3VAZmamP9xoAG+B0nVAMzMTQPAWSFD88XVAZmamP6d5xyk6UXZAZmbmP2sr9pfdnXZAZmZmPxTQRNjwsXZAZmYGQDLmriXk1HZAZmamPzy9UpYhLHdAMzMTQI9TdCSXcXdAAADAPxWMSuoEkndAZmaWQDXvOEVH9HdAmpkZQDcawFsgFXhAzcyMP6UsQxzrLXhAzcxMP39qvHSTY3hAAAAAQMl2vp8acnhAZmbmP7yWkA96lHhAZmamPyV1ApoI8HhAMzMzP4NRSZ2A/XhAAACAPztwzojSEHlAAAAAQJJc/kP6H3lAZmYGQDLmriXkUHlAMzMTQFD8GHPXY3lAZmbmP4MvTKYKc3lAmpk5QEYldQKak3lAZmZmP0Jg5dAioXlAzcyMPyntDb4wsXlAAACQQECk374OwXlAAABgQInS3uALA3pAzcxMP3KKjuTyJHpAzcxMP9lfdk8eNnpAMzODQNPe4AuTQXpAMzNTQEvqBDQRU3pAMzMrQc3MzMzMY3pAMzMTQOC+DpwzeHpAMzPzP+58PzVehnpAZmamP8pUwaikoXpAZmZmP+5aQj7orHpAzcxMP0tZhjjWwnpAzcy8QFwgQfFj0HpAzcyMQIy5awn54XpAAADAP3BfB84ZHHtAAADAPwpoImx4M3tAzcyMP0VHcvkPP3tAZmZmP+SDns2qUXtAMzMTQAn5oGezYHtAmpmZP30/NV66p3tAMzOTQPCFyVTBtntAzczMP4JzRpT243tAmpm5QT0K16Nw8XtAZmYyQuqVsgxx/3tAMzOjQOm3rwPnTnxAZmYGQNCzWfW5dnxAMzPDQKVOQBNhhnxAAABAQM6I0t7gD31AAABAQZ+rrdhfIX1AZmamP4iFWtO8K35AZmbmP0Jg5dAim4BAzcxMP7yWkA96MoRAZmbmPw==";
248 
249 
250 const char *testCMS1_v3 =
251 "AgAAAAMAAABDcmVhdGlvbkRhdGUJMTEtMjAtMjAwOAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEV4dHJhY3RvcglNYWtlTVMyCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARXh0cmFjdG9yVmVyc2lvbgkyLjAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDb21tZW50cwlNYWtlTVMyIHdyaXR0ZW4gYnkgTWljaGFlbCBKLiBNYWNDb3NzLCBNaWNoYWVsIFIuIEhvb3BtYW5uLCAyMDA3CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEV4dHJhY3Rvck9wdGlvbnMJTVMxL01TMgoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOjsAAAAAcDeURv9/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgENzAAAAAAA/AAAAAAAAAPc5lEb/fwAAAFijBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAYBITgAAAAAAAFmjBAAAAADRa0wAAAAAAAAAAAAAAAAALY1OAAAAAAAAAAAAAAAAAJ6BTwAAAAAAsFWjBAAAAAAHAAAAAAAAAAAAAAAAAAAAYDiURv9/AAAAOpRG/38AAFBPowQAAAAA8F+URv9/AADAZUcAAAAAAIBlRwAAAAAARolMAAAAAAAvbmV0L2dzL3ZvbDMvc29mdHdhcmUvbW9kdWxlcy1zdy9nY2MvNC41LjEvTGludXgvUkhFTDUveDg2XzY0L2xpYjY0LwAvbmV0L2dzL3ZvbCQAAAAkAAAA7FG4HoUhg0AJG94+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAANMAAABOAAAAeJwByAA3/8KGp1fKoGtA1lbsL7vHa0Dl0CLb+eRrQDj4wmSqAm5AyxDHurg9b0D+ZffkYWFvQNuK/WX3nm9A1zTvOEWRcEA0ETY8vbFwQIenV8oywXBAoBov3STQcEDOGVHaG5JxQH/ZPXlYoXFAS8gHPZuxcUCWQ4ts59FxQApoImx44HFAImx4eqXwcUCY3ZOHhZRyQGTMXUvIqnJAyxDHurjAckCJQWDl0G51QIhjXdxGsnVAnYAmwoYxdkALRiV1AkF2QHgLJCh+UXZAsJRfOnicMzZudmBgcHA4e2YPkIYDh1kzZ9qDGGfPuDgyMBwA8i0djY0/O6SlsQHZO4H4pn1a2jP7s2d6kPXBwdkzE5wYGEycZs285QQAfAkb/fwBAAD8AQAAAAAAAAAAAABwzshAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAOsAAABRAAAAeJwB4AAf/7WmeccpJmBAC7WmecdBYECdEaW9wWNgQMDsnjwsCGFAEce6uI0+YUC8BRIUP1xhQPmgZ7PqhWFA48eYu5akYUAYldQJaORhQG40gLdAZmJA3bWEfNDFYkArhxbZzuViQMuhRbbzAWNAeekmMQhiY0Bg5dAi24NjQEtZhjjWpWNAKqkT0ETMY0C1N/jCZCZkQPkx5q4lwmRAnu+nxksnZUC/DpwzolJlQJayDHGso2VAg8DKoUXkZUAWak3zjgNmQH2utmJ/Q2ZAI0p7gy+EZkBgdk8eFqhmQIj029eB32ZAwPlnynicmzWz0ImB4YCDsfFmewYgSEtjcwDRMP7ZMzwOs2YaOjKAwQH7WTNngnFamhpUnbADRK4BLM4ABWlpdo5nz/QA1S2zB9EgvQwMCg4ANGkdIA==";
252 
253 const char *testMS2 =
254 "H CreationDate 10-6-2007\n"
255 "H Extractor MakeMS2\n"
256 "H ExtractorVersion 2.0\n"
257 "H Comments MakeMS2 written by Michael J. MacCoss, Michael R. Hoopmann, 2007\n"
258 "H ExtractorOptions MS2\n"
259 "S 116 116 536.39\n"
260 "Z 2 1071.77\n"
261 "Z 3 1607.15\n"
262 "I RTime 0.4462\n"
263 "175.4067 0.6\n"
264 "195.9831 0.9\n"
265 "236.2524 0.7\n"
266 "266.1989 0.8\n"
267 "276.3145 0.6\n"
268 "278.6099 0.7\n"
269 "281.1050 62.6\n"
270 "298.4888 9.2\n"
271 "299.1033 4\n"
272 "303.5076 1.8\n"
273 "330.1379 1.9\n"
274 "337.1581 0.6\n"
275 "341.0460 1.8\n"
276 "342.3756 0.8\n"
277 "359.0190 1.7\n"
278 "363.0510 1.1\n"
279 "373.2335 1.7\n"
280 "377.2952 1\n"
281 "399.2092 1.6\n"
282 "399.8853 1\n"
283 "403.3747 2.2\n"
284 "405.3385 0.6\n"
285 "408.1845 0.8\n"
286 "409.8174 0.8\n"
287 "414.0231 1.2\n"
288 "415.0792 1.8\n"
289 "417.1754 1.6\n"
290 "419.3268 1.2\n"
291 "420.4443 1.5\n"
292 "421.3249 1.1\n"
293 "429.1662 2.5\n"
294 "435.1794 0.8\n"
295 "436.3020 1.9\n"
296 "439.8971 1\n"
297 "440.6216 1.1\n"
298 "443.7952 0.6\n"
299 "444.5042 1.2\n"
300 "447.0575 0.6\n"
301 "448.5712 1.8\n"
302 "451.1549 2\n"
303 "452.1009 0.8\n"
304 "453.0457 0.7\n"
305 "461.8017 0.7\n"
306 "464.1340 2.7\n"
307 "469.8256 1.8\n"
308 "471.8412 1\n"
309 "473.1831 3.2\n"
310 "474.2579 1\n"
311 "479.8830 1.1\n"
312 "482.2438 1.7\n"
313 "483.1778 2.8\n"
314 "483.8499 0.8\n"
315 "486.1272 2.8\n"
316 "487.5856 0.7\n"
317 "489.5583 4.5\n"
318 "490.6985 4.2\n"
319 "491.4770 5.2\n"
320 "492.3076 7.9\n"
321 "496.1183 1.2\n"
322 "498.5404 2.6\n"
323 "500.5744 7.8\n"
324 "501.2284 6.6\n"
325 "501.9958 3.9\n"
326 "503.0387 37.4\n"
327 "505.0599 2.9\n"
328 "507.2243 1.2\n"
329 "508.2107 0.8\n"
330 "509.1219 2.4\n"
331 "510.4375 0.9\n"
332 "511.3940 0.7\n"
333 "513.4534 3.5\n"
334 "514.4604 4.5\n"
335 "517.0839 6.3\n"
336 "518.1203 18.8\n"
337 "519.0070 65\n"
338 "525.1636 3.1\n"
339 "526.4990 9.4\n"
340 "527.5856 12.2\n"
341 "560.5077 1.2\n"
342 "585.4477 2\n"
343 "621.8749 0.7\n"
344 "632.6031 1\n"
345 "634.1111 0.7\n"
346 "636.3641 1.2\n"
347 "638.4987 1.1\n"
348 "640.5447 1.7\n"
349 "650.5433 0.9\n"
350 "664.1221 0.8\n"
351 "698.4615 0.9\n"
352 "709.7639 1.1\n"
353 "711.2064 1.1\n"
354 "726.0311 1.2\n"
355 "740.0786 0.8\n"
356 "745.3728 0.6\n"
357 "757.8849 1\n"
358 "761.9862 0.8\n"
359 "774.4131 1.3\n"
360 "788.2714 1\n"
361 "829.2268 0.7\n"
362 "840.0249 2\n"
363 "856.4430 0.8\n"
364 "857.6420 0.7\n"
365 "898.4391 0.8\n"
366 "902.4149 0.7\n"
367 "942.4218 1.4\n"
368 "1026.6023 1\n"
369 "S 118 118 464.98\n"
370 "Z 2 928.95\n"
371 "Z 3 1392.92\n"
372 "I RTime 0.4573\n"
373 "159.1265 1\n"
374 "176.0755 1.4\n"
375 "189.2380 1.3\n"
376 "199.4232 0.8\n"
377 "205.2997 0.6\n"
378 "213.3207 1.4\n"
379 "221.2078 0.9\n"
380 "231.0154 1.6\n"
381 "238.9865 1\n"
382 "244.2399 1.4\n"
383 "249.2524 1.1\n"
384 "252.1188 0.9\n"
385 "253.2228 0.9\n"
386 "263.1987 0.8\n"
387 "269.3484 0.8\n"
388 "272.3980 0.9\n"
389 "273.2263 0.9\n"
390 "276.9475 2.2\n"
391 "279.2698 1.4\n"
392 "299.1149 0.8\n"
393 "302.9478 0.8\n"
394 "305.6744 1.4\n"
395 "308.3992 1.2\n"
396 "317.9594 1.3\n"
397 "322.2583 1.2\n"
398 "332.9634 0.7\n"
399 "337.3151 0.8\n"
400 "346.9624 1.3\n"
401 "349.1566 2.3\n"
402 "351.1241 1.3\n"
403 "357.0767 1.8\n"
404 "361.8666 0.9\n"
405 "363.1213 2.1\n"
406 "365.3057 1.3\n"
407 "370.7582 2.3\n"
408 "375.0994 1.5\n"
409 "377.1262 4.7\n"
410 "383.2674 2.4\n"
411 "385.3204 1.1\n"
412 "386.8699 0.8\n"
413 "390.2235 2\n"
414 "391.1315 1.8\n"
415 "393.2798 1.3\n"
416 "399.0021 0.7\n"
417 "399.8439 1\n"
418 "401.0514 2\n"
419 "401.9986 2.1\n"
420 "405.0557 2.3\n"
421 "406.2401 1.8\n"
422 "407.1901 2.9\n"
423 "409.2251 0.9\n"
424 "410.0710 1.1\n"
425 "411.0744 4.5\n"
426 "412.0661 3.5\n"
427 "416.1904 0.8\n"
428 "418.3093 0.8\n"
429 "419.3824 4.1\n"
430 "420.0984 3.3\n"
431 "421.1917 10.7\n"
432 "422.2375 2.3\n"
433 "423.5126 1.9\n"
434 "424.3980 1.3\n"
435 "426.1027 0.9\n"
436 "426.8067 0.8\n"
437 "428.1773 5.9\n"
438 "429.0244 4.4\n"
439 "430.1233 1.5\n"
440 "433.7563 1.5\n"
441 "435.2169 1.1\n"
442 "435.9414 0.9\n"
443 "437.1042 2.3\n"
444 "438.0438 1.2\n"
445 "442.4830 4.6\n"
446 "443.4222 1.6\n"
447 "446.2477 23.2\n"
448 "447.0900 44.6\n"
449 "447.9651 5.1\n"
450 "452.9314 2.1\n"
451 "455.4204 6.1\n"
452 "456.3987 3\n"
453 "464.9924 12\n"
454 "466.0859 1.3\n"
455 "482.7336 1.8\n"
456 "531.3920 0.8\n"
457 "646.3096 1.8\n"
458 ;
459 
460 const char *testBMS2 =
461 "AwAAAAIAAABDcmVhdGlvbkRhdGUJMTAtNi0yMDA3CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEV4dHJhY3RvcglNYWtlTVMyCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARXh0cmFjdG9yVmVyc2lvbgkyLjAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDb21tZW50cwlNYWtlTVMyIHdyaXR0ZW4gYnkgTWljaGFlbCBKLiBNYWNDb3NzLCBNaWNoYWVsIFIuIEhvb3BtYW5uLCAyMDA3CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEV4dHJhY3Rvck9wdGlvbnMJTVMyCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgjlkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDOfwAAAAAAAAAAAAAAAAAAAAAAAAAAACGcUwAAAAAA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";
462 
463 
464 const char *testCMS2 =
465 "BAAAAAIAAABDcmVhdGlvbkRhdGUJMTAtNi0yMDA3CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEV4dHJhY3RvcglNYWtlTVMyCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARXh0cmFjdG9yVmVyc2lvbgkyLjAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDb21tZW50cwlNYWtlTVMyIHdyaXR0ZW4gYnkgTWljaGFlbCBKLiBNYWNDb3NzLCBNaWNoYWVsIFIuIEhvb3BtYW5uLCAyMDA3CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEV4dHJhY3Rvck9wdGlvbnMJTVMyCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgjlkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDOfwAAAAAAAAAAAAAAAAAAAAAAAAAAACGcUwAAAAAA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";
466 
467 const char* testMS2_v3 =
468 "H CreationDate 11-20-2008\n"
469 "H Extractor MakeMS2\n"
470 "H ExtractorVersion 2.0\n"
471 "H Comments MakeMS2 written by Michael J. MacCoss, Michael R. Hoopmann, 2007\n"
472 "H ExtractorOptions MS1/MS2\n"
473 "S 36 36 612.1900\n"
474 "I RTime 0.4338\n"
475 "I BPM 0.0000\n"
476 "I ConvA 0.0000\n"
477 "I TIC 0.00\n"
478 "I IIT 0.0000\n"
479 "I EZ 1 611.1855 0.8897 27106.6\n"
480 "Z 1 611.1855\n"
481 "221.0247 4.1\n"
482 "222.2416 3\n"
483 "223.1555 5.9\n"
484 "240.0833 0\n"
485 "249.9288 0\n"
486 "251.0432 2\n"
487 "252.9677 1.2\n"
488 "265.0794 0\n"
489 "267.1087 12.3\n"
490 "268.0749 6\n"
491 "269.0090 11.6\n"
492 "281.1318 7.6\n"
493 "282.0841 2.1\n"
494 "283.1004 5.8\n"
495 "285.1190 1.7\n"
496 "286.0294 1.8\n"
497 "287.0404 4.4\n"
498 "297.2826 0\n"
499 "298.6739 0\n"
500 "300.0451 0\n"
501 "342.9260 0\n"
502 "347.1423 0\n"
503 "355.0954 72.4\n"
504 "356.0631 45\n"
505 "357.0933 109.3\n"
506 "S 508 508 441.2300\n"
507 "I RTime 6.2752\n"
508 "I ConvA 0.0000\n"
509 "I ConvB 0.0000\n"
510 "I TIC 0.00\n"
511 "I IIT 0.0000\n"
512 "I EZ 3 1318.7270 5.9467 28240.3\n"
513 "I EZ 2 880.4527 6.2403 34674.3\n"
514 "Z 3 1318.7270\n"
515 "Z 2 880.4527\n"
516 "129.1926 60.4\n"
517 "130.0556 6\n"
518 "131.1174 1.4\n"
519 "136.2554 0\n"
520 "137.9548 2.1\n"
521 "138.8827 0\n"
522 "140.1849 1.4\n"
523 "141.1434 0\n"
524 "143.1377 2.2\n"
525 "147.1954 11.1\n"
526 "150.1817 0\n"
527 "151.1815 1.5\n"
528 "152.0610 1.2\n"
529 "155.0635 1.2\n"
530 "156.1205 2.6\n"
531 "157.1824 0\n"
532 "158.3834 2.3\n"
533 "161.1998 0\n"
534 "166.0671 1\n"
535 "169.2280 1.2\n"
536 "170.5823 0\n"
537 "173.1148 0\n"
538 "175.1335 11.9\n"
539 "176.1112 1.1\n"
540 "178.1093 1.3\n"
541 "180.1308 1.1\n"
542 "181.2527 1.5\n"
543 "182.9846 2.5\n"
544 ;
545 
546 const char* testCMS2_v3 =
547 "BAAAAAMAAAAgICAgICBDcmVhdGlvbkRhdGUgICAgMTEtMjAtMjAwOAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgIEV4dHJhY3RvciAgICAgICBNYWtlTVMyCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgRXh0cmFjdG9yVmVyc2lvbiAgICAgICAgMi4wCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICBDb21tZW50cyAgICAgICAgTWFrZU1TMiB3cml0dGVuIGJ5IE1pY2hhZWwgSi4gTWFjQ29zcywgTWljaGFlbCBSLiBIb29wbWFubiwgMjAwNwoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgIEV4dHJhY3Rvck9wdGlvbnMgICAgICAgIE1TMS9NUzIKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD21UoAAAAAACQAAAAkAAAA7FG4HoUhg0AJG94+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAGQAAAAEAAABEi2znexmDQAEAAABEi2znexmDQGHDYz8zxdNG0wAAAE4AAAB4nAHIADf/woanV8qga0DWVuwvu8drQOXQItv55GtAOPjCZKoCbkDLEMe6uD1vQP5l9+RhYW9A24r9Zfeeb0DXNO84RZFwQDQRNjy9sXBAh6dXyjLBcECgGi/dJNBwQM4ZUdobknFAf9k9eVihcUBLyAc9m7FxQJZDi2zn0XFACmgibHjgcUAibHh6pfBxQJjdk4eFlHJAZMxdS8iqckDLEMe6uMByQIlBYOXQbnVAiGNd3EaydUCdgCbChjF2QAtGJXUCQXZAeAskKH5RdkCwlF86eJwzNm52YGBwcDh7Zg+QhgOHWTNn2oMYZ8+4ODIwHADyLR2NjT87pKWxAdk7gfimfVraM/uzZ3qQ9cHB2TMTnBgYTJxmzbzlBAB8CRv9/AEAAPwBAABI4XoUrpN7QHDOyEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAIAAAAcAAAAAwAAAMUgsHLompRAAgAAADJ3LSGfg4tAAwAAAMUgsHLompRAXku+QJqg3EYCAAAAMnctIZ+Di0CKsMdATXIHR+sAAABRAAAAeJwB4AAf/7WmeccpJmBAC7WmecdBYECdEaW9wWNgQMDsnjwsCGFAEce6uI0+YUC8BRIUP1xhQPmgZ7PqhWFA48eYu5akYUAYldQJaORhQG40gLdAZmJA3bWEfNDFYkArhxbZzuViQMuhRbbzAWNAeekmMQhiY0Bg5dAi24NjQEtZhjjWpWNAKqkT0ETMY0C1N/jCZCZkQPkx5q4lwmRAnu+nxksnZUC/DpwzolJlQJayDHGso2VAg8DKoUXkZUAWak3zjgNmQH2utmJ/Q2ZAI0p7gy+EZkBgdk8eFqhmQIj029eB32ZAwPlnynicmzWz0ImB4YCDsfFmewYgSEtjcwDRMP7ZMzwOs2YaOjKAwQH7WTNngnFamhpUnbADRK4BLM4ABWlpdo5nz/QA1S2zB9EgvQwMCg4ANGkdIA==";
548 
549 void test(SpectrumListPtr sl, int msLevel)
550 {
551  if (os_)
552  {
553  TextWriter write(*os_);
554  write(*sl);
555  *os_ << endl;
556  }
557 
558  // check easy functions
559 
560  unit_assert(sl.get());
561  unit_assert(sl->size() == 2);
562  unit_assert(sl->find("scan=116") == 0);
563  unit_assert(sl->find("scan=118") == 1);
564 
565  // check scan 0
566 
567  unit_assert(sl->spectrumIdentity(0).index == 0);
568  unit_assert(sl->spectrumIdentity(0).id == "scan=116");
569  unit_assert(sl->spectrumIdentity(0).sourceFilePosition != -1);
570 
571  SpectrumPtr s = sl->spectrum(0, false);
572 
573  unit_assert(s.get());
574  unit_assert(s->id == "scan=116");
575  unit_assert(s->index == 0);
576  unit_assert(s->sourceFilePosition != -1);
577  unit_assert(s->cvParam(MS_ms_level).valueAs<int>() == msLevel);
578  unit_assert_equal(s->cvParam(MS_total_ion_current).valueAs<double>(), 385.4, 5e-1);
579  unit_assert_equal(s->cvParam(MS_base_peak_intensity).valueAs<double>(), 65.0, 5e-1);
580 
581  if (msLevel == 1)
582  {
583  unit_assert(s->precursors.size() == 0);
584  }
585  else
586  {
587  unit_assert(s->precursors.size() == 1);
588  Precursor& precursor0 = s->precursors[0];
589  unit_assert(precursor0.selectedIons.size() == 1);
590  unit_assert_equal(precursor0.isolationWindow.cvParam(MS_isolation_window_target_m_z).valueAs<double>(), 536.39, 5e-2);
591 
592  // This test spectrum only has possible charge states (2 total, values 2,3)
593  unit_assert(precursor0.selectedIons[0].cvParam(MS_charge_state).value.empty());
594  vector<string> charges;
595  BOOST_FOREACH(CVParam& param, precursor0.selectedIons[0].cvParams)
596  {
597  if (param.cvid == MS_possible_charge_state)
598  {
599  charges.push_back(param.value);
600  }
601  }
602  unit_assert(charges.size() == 2);
603  vector<string>::const_iterator charge_it = charges.begin();
604  unit_assert(*charge_it == "2");
605  unit_assert(*(++charge_it) == "3");
606  }
607 
608  unit_assert(s->defaultArrayLength == 106);
609  unit_assert(s->binaryDataArrayPtrs.size() == 2);
610  unit_assert(s->binaryDataArrayPtrs[0]->hasCVParam(MS_m_z_array));
611  unit_assert(s->binaryDataArrayPtrs[1]->hasCVParam(MS_intensity_array));
612  unit_assert(s->binaryDataArrayPtrs[0]->data.empty() && s->binaryDataArrayPtrs[1]->data.empty());
613 
614  s = sl->spectrum(0, true);
615  unit_assert(s->defaultArrayLength == 106);
616  unit_assert(s->binaryDataArrayPtrs.size() == 2);
617  unit_assert(!s->binaryDataArrayPtrs[0]->data.empty() && !s->binaryDataArrayPtrs[1]->data.empty());
618 
619  vector<MZIntensityPair> pairs;
620  s->getMZIntensityPairs(pairs);
621 
622  if (os_)
623  {
624  *os_ << "scan 0:\n";
625  copy(pairs.begin(), pairs.end(), ostream_iterator<MZIntensityPair>(*os_, "\n"));
626  *os_ << endl;
627  }
628 
629 
630  // check scan 1
631 
632  unit_assert(sl->spectrumIdentity(1).index == 1);
633  unit_assert(sl->spectrumIdentity(1).id == "scan=118");
634 
635  s = sl->spectrum(1, true);
636  unit_assert(s.get());
637  unit_assert(s->id == "scan=118");
638  unit_assert(s->index == 1);
639  unit_assert(s->sourceFilePosition != -1);
640  unit_assert(s->cvParam(MS_ms_level).valueAs<int>() == msLevel);
641  unit_assert(s->scanList.scans.size() == 1);
642  unit_assert_equal(s->scanList.scans[0].cvParam(MS_scan_start_time).timeInSeconds(), 0.4573*60, 5e-4);
643 
644  if (msLevel == 1)
645  {
646  unit_assert(s->precursors.size() == 0);
647  }
648  else
649  {
650  unit_assert(s->precursors.size() == 1);
651  Precursor& precursor1 = s->precursors[0];
652  unit_assert(precursor1.selectedIons.size() == 1);
653  unit_assert_equal(precursor1.isolationWindow.cvParam(MS_isolation_window_target_m_z).valueAs<double>(), 464.98, 1e-5);
654 
655  // This test spectrum only has possible charge states (2 total, values 2,3)
656  unit_assert(precursor1.selectedIons[0].cvParam(MS_charge_state).value.empty());
657  vector<string> charges;
658  BOOST_FOREACH(CVParam& param, precursor1.selectedIons[0].cvParams)
659  {
660  if (param.cvid == MS_possible_charge_state)
661  {
662  charges.push_back(param.value);
663  }
664  }
665  unit_assert(charges.size() == 2);
666  vector<string>::const_iterator charge_it = charges.begin();
667  unit_assert(*charge_it == "2");
668  unit_assert(*(++charge_it) == "3");
669  }
670 
671  unit_assert(s->defaultArrayLength == 85);
672 
673  pairs.clear();
674  s->getMZIntensityPairs(pairs);
675 
676  unit_assert(s->defaultArrayLength == pairs.size());
677 
678  if (os_)
679  {
680  *os_ << "scan 1:\n";
681  copy(pairs.begin(), pairs.end(), ostream_iterator<MZIntensityPair>(*os_, "\n"));
682  *os_ << endl;
683  }
684 }
685 
686 void test_v3(SpectrumListPtr sl, int msLevel)
687 {
688  if (os_)
689  {
690  TextWriter write(*os_);
691  write(*sl);
692  *os_ << endl;
693  }
694 
695  // check easy functions
696 
697  unit_assert(sl.get());
698  unit_assert(sl->size() == 2);
699  unit_assert(sl->find("scan=36") == 0);
700  unit_assert(sl->find("scan=508") == 1);
701 
702  // check scan 0
703 
704  unit_assert(sl->spectrumIdentity(0).index == 0);
705  unit_assert(sl->spectrumIdentity(0).id == "scan=36");
706  unit_assert(sl->spectrumIdentity(0).sourceFilePosition != -1);
707 
708  SpectrumPtr s = sl->spectrum(0, false);
709 
710  unit_assert(s.get());
711  unit_assert(s->id == "scan=36");
712  unit_assert(s->index == 0);
713  unit_assert(s->sourceFilePosition != -1);
714  unit_assert(s->cvParam(MS_ms_level).valueAs<int>() == msLevel);
715  unit_assert_equal(s->cvParam(MS_total_ion_current).valueAs<double>(), 296.2, 5e-1);
716  unit_assert_equal(s->cvParam(MS_base_peak_intensity).valueAs<double>(), 109.3, 5e-1);
717 
718  if (msLevel == 1)
719  {
720  unit_assert(s->precursors.size() == 0);
721  }
722  else
723  {
724  unit_assert(s->precursors.size() == 1);
725  Precursor& precursor0 = s->precursors[0];
726  unit_assert(precursor0.selectedIons.size() == 1);
727  // isolated precursor m/z on S line
728  unit_assert_equal(precursor0.isolationWindow.cvParam(MS_isolation_window_target_m_z).valueAs<double>(), 612.19, 5e-2);
729  // m/z of calculated accurate mass
730  unit_assert_equal(precursor0.selectedIons[0].cvParam(MS_selected_ion_m_z).valueAs<double>(), 610.18, 5e-2);
731 
732  // This test spectrum one charge state, so no possible charge states
733  unit_assert(precursor0.selectedIons[0].cvParam(MS_possible_charge_state).value.empty());
734  vector<string> charges;
735  vector<double> masses;
736  BOOST_FOREACH(CVParam& param, precursor0.selectedIons[0].cvParams)
737  {
738  if (param.cvid == MS_charge_state)
739  {
740  charges.push_back(param.value);
741  }
742  if (param.cvid == MS_accurate_mass)
743  {
744  masses.push_back(lexical_cast<double>(param.value));
745  }
746  }
747  unit_assert(charges.size() == 1);
748  vector<string>::const_iterator charge_it = charges.begin();
749  unit_assert(*charge_it == "1");
750 
751  unit_assert(masses.size() == 1);
752  vector<double>::const_iterator mass_it = masses.begin();
753  unit_assert_equal(*mass_it, 611.1855, 5e-4);
754  }
755 
756  unit_assert(s->defaultArrayLength == 25);
757  unit_assert(s->binaryDataArrayPtrs.size() == 2);
758  unit_assert(s->binaryDataArrayPtrs[0]->hasCVParam(MS_m_z_array));
759  unit_assert(s->binaryDataArrayPtrs[1]->hasCVParam(MS_intensity_array));
760  unit_assert(s->binaryDataArrayPtrs[0]->data.empty() && s->binaryDataArrayPtrs[1]->data.empty());
761 
762  s = sl->spectrum(0, true);
763  unit_assert(s->defaultArrayLength == 25);
764  unit_assert(s->binaryDataArrayPtrs.size() == 2);
765  unit_assert(!s->binaryDataArrayPtrs[0]->data.empty() && !s->binaryDataArrayPtrs[1]->data.empty());
766 
767  vector<MZIntensityPair> pairs;
768  s->getMZIntensityPairs(pairs);
769 
770  if (os_)
771  {
772  *os_ << "scan 0:\n";
773  copy(pairs.begin(), pairs.end(), ostream_iterator<MZIntensityPair>(*os_, "\n"));
774  *os_ << endl;
775  }
776 
777 
778  // check scan 1
779 
780  unit_assert(sl->spectrumIdentity(1).index == 1);
781  unit_assert(sl->spectrumIdentity(1).id == "scan=508");
782 
783  s = sl->spectrum(1, true);
784  unit_assert(s.get());
785  unit_assert(s->id == "scan=508");
786  unit_assert(s->index == 1);
787  unit_assert(s->sourceFilePosition != -1);
788  unit_assert(s->cvParam(MS_ms_level).valueAs<int>() == msLevel);
789  unit_assert(s->scanList.scans.size() == 1);
790  unit_assert_equal(s->scanList.scans[0].cvParam(MS_scan_start_time).timeInSeconds()/60, 6.2752, 5e-4);
791 
792  if (msLevel == 1)
793  {
794  unit_assert(s->precursors.size() == 0);
795  }
796  else
797  {
798  unit_assert(s->precursors.size() == 1);
799  Precursor& precursor1 = s->precursors[0];
800  unit_assert(precursor1.selectedIons.size() == 2);
801  // precursor m/z on S line
802  unit_assert_equal(precursor1.isolationWindow.cvParam(MS_isolation_window_target_m_z).valueAs<double>(), 441.23, 5e-2);
803  // m/z computed from accurate mass on Z line
804  unit_assert_equal(precursor1.selectedIons[0].cvParam(MS_selected_ion_m_z).valueAs<double>(), 439.91142, 1e-4);
805 
806  // This test spectrum has two charge states, both known so no possible charges
807  unit_assert(precursor1.selectedIons[0].cvParam(MS_possible_charge_state).value.empty());
808  vector<string> charges;
809  vector<double> masses;
810  BOOST_FOREACH(SelectedIon& si, precursor1.selectedIons)
811  {
812  BOOST_FOREACH(CVParam& param, si.cvParams)
813  {
814  if (param.cvid == MS_charge_state)
815  {
816  charges.push_back(param.value);
817  }
818  if (param.cvid == MS_accurate_mass)
819  {
820  masses.push_back(lexical_cast<double>(param.value));
821  }
822  }
823  }
824  unit_assert(charges.size() == 2);
825  vector<string>::const_iterator charge_it = charges.begin();
826  unit_assert(*charge_it == "3");
827  unit_assert(*(++charge_it) == "2");
828 
829  unit_assert(masses.size() == 2);
830  vector<double>::const_iterator mass_it = masses.begin();
831  unit_assert_equal(*mass_it, 1318.7270, 5e-4);
832  unit_assert_equal(*(++mass_it), 880.4527, 5e-4);
833  }
834 
835  unit_assert(s->defaultArrayLength == 28);
836 
837  pairs.clear();
838  s->getMZIntensityPairs(pairs);
839 
840  unit_assert(s->defaultArrayLength == pairs.size());
841 
842  if (os_)
843  {
844  *os_ << "scan 1:\n";
845  copy(pairs.begin(), pairs.end(), ostream_iterator<MZIntensityPair>(*os_, "\n"));
846  *os_ << endl;
847  }
848 }
849 
850 int main(int argc, char* argv[])
851 {
852  TEST_PROLOG(argc, argv)
853 
854  try
855  {
856  if (argc>1 && !strcmp(argv[1],"-v")) os_ = &cout;
857 
858  // dummy would normally be read in from file
859  MSData dummy;
861  dummy.instrumentConfigurationPtrs.back()->cvParams.push_back(MS_LCQ_Deca);
862  dummy.instrumentConfigurationPtrs.back()->userParams.push_back(UserParam("doobie", "420"));
863 
864  if (os_)
865  {
866  *os_ << "test()\n";
867  *os_ << "ms1:\n" << testMS1 << endl;
868  *os_ << "ms2:\n" << testMS2 << endl;
869  }
870 
871  // TEST MS1 TEXT FORMAT
872  shared_ptr<istream> isMS1(new istringstream(testMS1));
874  test(slMS1, 1);
875 
876  // TEST BMS1 BINARY FORMAT
877  const string& testBMS1Base64Str = testBMS1;
878  vector<char> binaryBufferBMS1;
879  binaryBufferBMS1.resize(Base64::textToBinarySize(testBMS1Base64Str.size()) + 1, '\0');
880  Base64::textToBinary(testBMS1Base64Str.c_str(), testBMS1Base64Str.size(), &binaryBufferBMS1[0]);
881  string binaryStringBMS1;
882  for (size_t i = 0; i < binaryBufferBMS1.size(); i++)
883  {
884  binaryStringBMS1 += binaryBufferBMS1[i];
885  }
886 
887  shared_ptr<istream> isBMS1(new istringstream(binaryStringBMS1));
888  SpectrumListPtr slBMS1 = SpectrumList_MSn::create(isBMS1, dummy, MSn_Type_BMS1);
889  test(slBMS1, 1);
890 
891  // TEST CMS1 COMPRESSED BINARY FORMAT (version 3)
892  const string& testCMS1_v3Base64Str = testCMS1_v3;
893  vector<char> binaryBufferCMS1_v3;
894  binaryBufferCMS1_v3.resize(Base64::textToBinarySize(testCMS1_v3Base64Str.size()) + 1, '\0');
895  Base64::textToBinary(testCMS1_v3Base64Str.c_str(), testCMS1_v3Base64Str.size(), &binaryBufferCMS1_v3[0]);
896  string binaryStringCMS1_v3;
897  for (size_t i = 0; i < binaryBufferCMS1_v3.size(); i++)
898  {
899  binaryStringCMS1_v3 += binaryBufferCMS1_v3[i];
900  }
901 
902  shared_ptr<istream> isCMS1_v3(new istringstream(binaryStringCMS1_v3));
903  SpectrumListPtr slCMS1_v3 = SpectrumList_MSn::create(isCMS1_v3, dummy, MSn_Type_CMS1);
904  test_v3(slCMS1_v3, 1);
905 
906  // TEST MS2 TEXT FORMAT
907  shared_ptr<istream> isMS2(new istringstream(testMS2));
909  test(slMS2, 2);
910 
911  // TEST BMS2 BINARY FORMAT
912  const string& testBMS2Base64Str = testBMS2;
913  vector<char> binaryBufferBMS2;
914  binaryBufferBMS2.resize(Base64::textToBinarySize(testBMS2Base64Str.size()) + 1, '\0');
915  Base64::textToBinary(testBMS2Base64Str.c_str(), testBMS2Base64Str.size(), &binaryBufferBMS2[0]);
916  string binaryStringBMS2;
917  for (size_t i = 0; i < binaryBufferBMS2.size(); i++)
918  {
919  binaryStringBMS2 += binaryBufferBMS2[i];
920  }
921 
922  shared_ptr<istream> isBMS2(new istringstream(binaryStringBMS2));
923  SpectrumListPtr slBMS2 = SpectrumList_MSn::create(isBMS2, dummy, MSn_Type_BMS2);
924  test(slBMS2, 2);
925 
926  // TEST CMS2 COMPRESSED BINARY FORMAT (version 2)
927  const string& testCMS2Base64Str = testCMS2;
928  vector<char> binaryBufferCMS2;
929  binaryBufferCMS2.resize(Base64::textToBinarySize(testCMS2Base64Str.size()) + 1, '\0');
930  Base64::textToBinary(testCMS2Base64Str.c_str(), testCMS2Base64Str.size(), &binaryBufferCMS2[0]);
931  string binaryStringCMS2;
932  for (size_t i = 0; i < binaryBufferCMS2.size(); i++)
933  {
934  binaryStringCMS2 += binaryBufferCMS2[i];
935  }
936 
937  shared_ptr<istream> isCMS2(new istringstream(binaryStringCMS2));
938  SpectrumListPtr slCMS2 = SpectrumList_MSn::create(isCMS2, dummy, MSn_Type_CMS2);
939  test(slCMS2, 2);
940 
941  // TEST MS2 TEXT FORMAT WITH EZ LINES (version 3)
942  shared_ptr<istream> isMS2_v3(new istringstream(testMS2_v3));
943  SpectrumListPtr slMS2_v3 = SpectrumList_MSn::create(isMS2_v3, dummy, MSn_Type_MS2);
944  test_v3(slMS2_v3, 2);
945 
946  // TEST CMS2 COMPRESSED BINARY FORMAT (version 3)
947  const string& testCMS2_v3Base64Str = testCMS2_v3;
948  vector<char> binaryBufferCMS2_v3;
949  binaryBufferCMS2_v3.resize(Base64::textToBinarySize(testCMS2_v3Base64Str.size()) + 1, '\0');
950  Base64::textToBinary(testCMS2_v3Base64Str.c_str(), testCMS2_v3Base64Str.size(), &binaryBufferCMS2_v3[0]);
951  string binaryStringCMS2_v3;
952  for (size_t i = 0; i < binaryBufferCMS2_v3.size(); i++)
953  {
954  binaryStringCMS2_v3 += binaryBufferCMS2_v3[i];
955  }
956 
957  shared_ptr<istream> isCMS2_v3(new istringstream(binaryStringCMS2_v3));
958  SpectrumListPtr slCMS2_v3 = SpectrumList_MSn::create(isCMS2_v3, dummy, MSn_Type_CMS2);
959  test_v3(slCMS2_v3, 2);
960 
961  }
962  catch (exception& e)
963  {
964  TEST_FAILED(e.what())
965  }
966  catch (...)
967  {
968  TEST_FAILED("Caught unknown exception.")
969  }
970 
972 }
973 
974