Skip to content

Commit d68f3d0

Browse files
authored
Merge pull request #8 from p2m2/develop
1.0.2 with new json format
2 parents e50cd87 + bfce653 commit d68f3d0

File tree

5 files changed

+38
-112
lines changed

5 files changed

+38
-112
lines changed

README.md

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,14 @@ API Service to parse the formats of the metabolomics data acquisition devices of
77

88
## API
99

10-
| Path | Description | Return values | Return values |
11-
|:-----------------------------------------------|:--------------------------------------------------------------------------------|:---------------------------------------------------------|:------------------------------------------------|
12-
| /p2m2tools/api/format/sniffer | returns the file type | `gcms, openlabcds, masslynx-txt, masslynx-xml, xcalibur` | { format : `value`} |
13-
| /p2m2tools/api/format/parse | parse a file from a metabolomics analysis by guessing its format | compound | [ { `GenerricP2M2HeaderFile` : `value` } {} ] |
14-
| /p2m2tools/api/format/parse/gcms | parse a GCMS metabolomics analysis file | compound list | |
15-
| /p2m2tools/api/format/parse/gcms/generic | parse a GCMS metabolomics analysis file. Convert to Generic format P2M2 | header, format, class, compound list | [ { `GenerricP2M2HeaderFile` : `value` } {} ] |
16-
| /p2m2tools/api/format/parse/openlabcds | parse a openlab CDS metabolomics analysis file | compound list | |
17-
| /p2m2tools/api/format/parse/openlabcds/generic | parse a openlab CDS metabolomics analysis file. Convert to Generic format P2M2 | header, format, class, compound list | [ { `GenerricP2M2HeaderFile` : `value` } {} ] |
18-
| /p2m2tools/api/format/parse/masslynx | parse a MassLynx metabolomics analysis file (Quantitative Summary File) | compound list | |
19-
| /p2m2tools/api/format/parse/masslynx/generic | parse a MassLynx metabolomics analysis file. Convert to Generic format P2M2 | header, format, class, compound list | [ { `GenerricP2M2HeaderFile` : `value` } {} ] |
20-
| /p2m2tools/api/format/parse/xcalibur | parse a Xcalibur metabolomics analysis file | compound list | |
21-
| /p2m2tools/api/format/parse/xcalibur/generic | parse a Xcalibur metabolomics analysis file. Convert to Generic format P2M2 | header, format, class, compound list | [ { `GenerricP2M2HeaderFile` : `value` } {} ] |
22-
23-
24-
To see the possible values of GenerricP2M2HeaderFile :
25-
- sample
26-
- metabolite
27-
- retTime
28-
- area
29-
- height
30-
- injectedVolume
31-
- vial
32-
- acquisitionDate
33-
- exportDate
10+
| Path | Description | Return values | Return values |
11+
|:-----------------------------------------------|:-------------------------------------------------------------------------------|:---------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------|
12+
| /p2m2tools/api/format/sniffer | returns the file type | `gcms, openlabcds, masslynx-txt, masslynx-xml, xcalibur` | { format : `value`} |
13+
| /p2m2tools/api/format/parse | parse a file from a metabolomics analysis by guessing its format | compound | `{ header : [sample, metabolite, retTime, area, height, injectedVolume, vial, acquisitionDate, exportDate], samples : list< list<string> > }` |
14+
| /p2m2tools/api/format/parse/gcms | parse a GCMS metabolomics analysis file | compound list | `{ "class":"GCMS","format":"gcms","origin": "","header": <map> ,"results":<list<map>>, "request":{"size:":<int>} }` |
15+
| /p2m2tools/api/format/parse/openlabcds | parse a openlab CDS metabolomics analysis file | compound list | `{ "class":"OpenLabCDS","format":"openlabcds","origin": "","header": <map> ,"results":<list<map>>, "request":{"size:":<int>} }` |
16+
| /p2m2tools/api/format/parse/masslynx | parse a MassLynx metabolomics analysis file (Quantitative Summary File) | compound list | |
17+
| /p2m2tools/api/format/parse/xcalibur | parse a Xcalibur metabolomics analysis file | compound list | |
3418

3519
## prerequisites
3620

app/src/APIMetabolomicsFormat.scala renamed to app/src/fr/inrae/metabolomics/p2m2/api/APIMetabolomicsFormat.scala

Lines changed: 18 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package fr.inrae.metabolomics.p2m2.api
22

33
import cask.decorators.compress
4-
import cask.main.Main
54
import io.undertow.Undertow
65
import io.undertow.server.handlers.BlockingHandler
7-
import fr.inrae.metabolomics.p2m2.format.XMLQuantitativeDataProcessingMassLynx
8-
import fr.inrae.metabolomics.p2m2.format.ms.{GCMS, GenericP2M2, MassSpectrometryResultSet, OpenLabCDS, QuantifyCompoundSummaryReportMassLynx, QuantifySampleSummaryReportMassLynx, QuantifySummaryReportMassLynx, Xcalibur}
9-
import fr.inrae.metabolomics.p2m2.parser.{GCMSParser, OpenLabCDSParser, ParserManager, ParserUtils, QuantifySummaryReportMassLynxParser, QuantitativeDataProcessingMassLynxParser, XcaliburXlsParser}
6+
import fr.inrae.metabolomics.p2m2.format.ms.{GCMS, GenericP2M2, OpenLabCDS, QuantifyCompoundSummaryReportMassLynx, QuantifySampleSummaryReportMassLynx, QuantifySummaryReportMassLynx, Xcalibur}
7+
import fr.inrae.metabolomics.p2m2.parser.{GCMSParser, OpenLabCDSParser, ParserManager, ParserUtils, QuantifySummaryReportMassLynxParser, XcaliburXlsParser}
108
import org.slf4j.LoggerFactory
119
import upickle.default._
1210

@@ -44,8 +42,8 @@ object APIMetabolomicsFormat extends cask.MainRoutes {
4442
logger.info(s" == start service ${this.getClass.getSimpleName} == ")
4543
@volatile var keepRunning = true
4644

47-
Runtime.getRuntime().addShutdownHook(new Thread {
48-
override def run = {
45+
Runtime.getRuntime.addShutdownHook(new Thread {
46+
override def run() = {
4947
println("* catch signal / stop service *")
5048
server.stop()
5149
keepRunning = false
@@ -91,7 +89,13 @@ object APIMetabolomicsFormat extends cask.MainRoutes {
9189
@cask.post("/p2m2tools/api/format/parse")
9290
def parser(request: cask.Request) : ujson.Value = {
9391
ParserManager.buildMassSpectrometryObject(request.bytes) match {
94-
case Some(obj) => SeqMapValuesToJson(obj.toGenericP2M2.samples)
92+
case Some(obj) =>
93+
val header = GenericP2M2.HeaderField.values.toList.sorted
94+
val samples = obj.toGenericP2M2.samples
95+
ujson.Obj(
96+
"header" -> header.map(_.toString),
97+
"samples" -> samples.map( sample => header.map( h => sample.getOrElse(h,"")))
98+
)
9599
case None => ujson.Obj()
96100
}
97101
}
@@ -106,20 +110,12 @@ object APIMetabolomicsFormat extends cask.MainRoutes {
106110
"format" -> "gcms",
107111
"origin" -> obj.origin,
108112
"header" -> MapValuesToJson(obj.header),
109-
"msQuantitativeResults" -> SeqMapValuesToJson(obj.msQuantitativeResults),
113+
"results" -> SeqMapValuesToJson(obj.msQuantitativeResults),
110114
"request" -> ujson.Obj("size:"->request.bytes.length)
111115
)
112116
case Failure(e) =>
113-
System.err.println(e.toString);
114-
cask.Abort(401);ujson.Obj("error" -> e.toString)
115-
}
116-
}
117-
118-
@cask.post("/p2m2tools/api/format/parse/gcms/generic")
119-
def gcmsToGenericP2M2(request: cask.Request): ujson.Value = {
120-
Try(GCMSParser.parseByteArray(request.bytes)) match {
121-
case Success(obj: MassSpectrometryResultSet) => SeqMapValuesToJson(obj.toGenericP2M2.samples)
122-
case Failure(e) => System.err.println(e.toString); cask.Abort(401); ujson.Obj("error" -> e.toString)
117+
System.err.println(e.getMessage)
118+
cask.Abort(401);ujson.Obj("error" -> e.getMessage)
123119
}
124120
}
125121

@@ -140,19 +136,10 @@ object APIMetabolomicsFormat extends cask.MainRoutes {
140136
"results" -> SeqMapValuesToJson(obj.results),
141137
"request" -> ujson.Obj("size:"->request.bytes.length)
142138
)
143-
case Failure(e) => System.err.println(e.toString); cask.Abort(401); ujson.Obj("error" -> e.toString)
144-
}
145-
}
146-
147-
@cask.post("/p2m2tools/api/format/parse/openlabcds/generic")
148-
def openlabcdsToGenericP2M2(request: cask.Request) : ujson.Value = {
149-
Try(OpenLabCDSParser.parseByteArray(request.bytes)) match {
150-
case Success(obj: MassSpectrometryResultSet) => SeqMapValuesToJson(obj.toGenericP2M2.samples)
151-
case Failure(e) => System.err.println(e.toString); cask.Abort(401); ujson.Obj("error" -> e.toString)
139+
case Failure(e) => System.err.println(e.getMessage); cask.Abort(401); ujson.Obj("error" -> e.getMessage)
152140
}
153141
}
154142

155-
156143
/**
157144
* Get Generic format of Metabolomics File MassLynx format
158145
*
@@ -183,27 +170,18 @@ object APIMetabolomicsFormat extends cask.MainRoutes {
183170
case Success(obj) => ujson.Obj( "error" -> obj.toString )
184171
case Failure(e) =>
185172
cask.Abort(401);
186-
ujson.Obj("error" -> e.toString)
173+
ujson.Obj("error" -> e.getMessage)
187174
}
188175
}
189176

190-
@cask.post("/p2m2tools/api/format/parse/masslynx/generic")
191-
def masslynxTxtToGenericP2M2(request: cask.Request): ujson.Value = {
192-
Try(QuantifySummaryReportMassLynxParser.parseByteArray(request.bytes)) match {
193-
case Success(obj: MassSpectrometryResultSet) => SeqMapValuesToJson(obj.toGenericP2M2.samples)
194-
case Failure(e) =>
195-
cask.Abort(401);
196-
ujson.Obj("error" -> e.toString)
197-
}
198-
}
199177
/*
200178
@cask.post("/p2m2tools/api/format/parse/masslynx/xml")
201179
def masslynxXml(request: cask.Request): ujson.Value = {
202180
Try(QuantitativeDataProcessingMassLynxParser.parseByteArray(request.bytes)) match {
203181
case Success(obj: XMLQuantitativeDataProcessingMassLynx) => SeqMapValuesToJson(obj.toGenericP2M2)
204182
case Failure(e) =>
205183
cask.Abort(401);
206-
ujson.Obj("error" -> e.toString)
184+
ujson.Obj("error" -> e.getMessage)
207185
}
208186
}
209187
*/
@@ -227,15 +205,7 @@ object APIMetabolomicsFormat extends cask.MainRoutes {
227205
)),
228206
"request" -> ujson.Obj("size:"->request.bytes.length)
229207
)
230-
case Failure(e) => System.err.println(e.toString); cask.Abort(401); ujson.Obj("error" -> e.toString)
231-
}
232-
}
233-
234-
@cask.post("/p2m2tools/api/format/parse/xcalibur/generic")
235-
def xcaliburToGenericP2M2(request: cask.Request): ujson.Value = {
236-
Try(XcaliburXlsParser.parseByteArray(request.bytes)) match {
237-
case Success(obj: MassSpectrometryResultSet) => SeqMapValuesToJson(obj.toGenericP2M2.samples)
238-
case Failure(e) => System.err.println(e.toString); cask.Abort(401); ujson.Obj("error" -> e.toString)
208+
case Failure(e) => System.err.println(e.getMessage); cask.Abort(401); ujson.Obj("error" -> e.getMessage)
239209
}
240210
}
241211

app/src/CorsHandler.scala renamed to app/src/fr/inrae/metabolomics/p2m2/api/CorsHandler.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@ import cask.router.EndpointMetadata
88
import cask.router.Decorator
99
import cask.model.Response
1010
import cask.router.Result
11-
1211
import io.undertow.Undertow
1312
import io.undertow.server.HttpServerExchange
1413
import io.undertow.server.handlers.BlockingHandler
1514
import io.undertow.util.Headers
1615
import io.undertow.util.HttpString
1716

17+
import java.util
1818
import java.util.concurrent.TimeUnit
19-
2019
import scala.concurrent.duration._
2120
import scala.io.StdIn
2221
import scala.jdk.CollectionConverters._
@@ -29,8 +28,8 @@ object CorsHandler {
2928

3029
val origin = "*"
3130
val accepted = "true"
32-
val headers = Set("Authorization", "Content-Type", "X-Requested-With").asJava
33-
val methods = Set("POST", "GET", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS").asJava
31+
val headers: util.Set[String] = Set("Authorization", "Content-Type", "X-Requested-With").asJava
32+
val methods: util.Set[String] = Set("POST", "GET", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS").asJava
3433
}
3534

3635
case class CorsHandler(dispatchTrie: DispatchTrie[Map[String, (Routes, EndpointMetadata[_])]],

app/test/src/APIMetabolomicsFormatTest.scala renamed to app/test/src/fr/inrae/metabolomics/p2m2/api/APIMetabolomicsFormatTest.scala

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,11 @@ object APIMetabolomicsFormatTest extends TestSuite {
5959
assert(ujson.read(response.text()).asInstanceOf[ujson.Obj].value("format") == ujson.Str("gcms"))
6060
}
6161

62-
63-
test("gcms/generic") - withServer(APIMetabolomicsFormat){
64-
host =>
65-
val response = requests.post(s"$host/p2m2tools/api/format/parse/gcms/generic",data=MetabolomicsData.gcms)
66-
assert(response.statusCode == 200)
67-
assert(ujson.read(response.text()).arr.length == 1)
68-
}
69-
7062
test("gcms generic parsing") - withServer(APIMetabolomicsFormat) {
7163
host =>
7264
val response = requests.post(s"$host/p2m2tools/api/format/parse", data = MetabolomicsData.gcms)
7365
assert(response.statusCode == 200)
74-
assert(ujson.read(response.text()).arr.length == 1)
66+
assert(ujson.read(response.text()).isInstanceOf[ujson.Obj])
7567
}
7668

7769
test("openlabcds") - withServer(APIMetabolomicsFormat) {
@@ -84,18 +76,12 @@ object APIMetabolomicsFormatTest extends TestSuite {
8476
assert(ujson.read(response.text()).asInstanceOf[ujson.Obj].value("format") == ujson.Str("openlabcds"))
8577
}
8678

87-
test("openlabcds/generic") - withServer(APIMetabolomicsFormat) {
88-
host =>
89-
val response = requests.post(s"$host/p2m2tools/api/format/parse/openlabcds/generic", data = MetabolomicsData.openlabcds)
90-
assert(response.statusCode == 200)
91-
assert(ujson.read(response.text()).arr.length == 4)
92-
}
93-
9479
test("openlabcds generic parsing") - withServer(APIMetabolomicsFormat) {
9580
host =>
9681
val response = requests.post(s"$host/p2m2tools/api/format/parse", data = MetabolomicsData.openlabcds)
9782
assert(response.statusCode == 200)
98-
assert(ujson.read(response.text()).arr.length == 4)
83+
assert(ujson.read(response.text()).isInstanceOf[ujson.Obj])
84+
assert(ujson.read(response.text()).asInstanceOf[ujson.Obj].value("samples").arr.length == 4)
9985
}
10086

10187
test("masslynx") - withServer(APIMetabolomicsFormat) {
@@ -109,18 +95,12 @@ object APIMetabolomicsFormatTest extends TestSuite {
10995
assert(ujson.read(response.text()).asInstanceOf[ujson.Obj].value("format") == ujson.Str("masslynx"))
11096
}
11197

112-
test("masslynx/generic") - withServer(APIMetabolomicsFormat) {
113-
host =>
114-
val response = requests.post(s"$host/p2m2tools/api/format/parse/masslynx/generic", data = MetabolomicsData.masslynx)
115-
assert(response.statusCode == 200)
116-
assert(ujson.read(response.text()).arr.length == 8313)
117-
}
118-
11998
test("masslynx generic parsing") - withServer(APIMetabolomicsFormat) {
12099
host =>
121100
val response = requests.post(s"$host/p2m2tools/api/format/parse", data = MetabolomicsData.masslynx)
122101
assert(response.statusCode == 200)
123-
assert(ujson.read(response.text()).arr.length == 8313)
102+
assert(ujson.read(response.text()).isInstanceOf[ujson.Obj])
103+
assert(ujson.read(response.text()).asInstanceOf[ujson.Obj].value("samples").arr.length == 8313)
124104
}
125105

126106
test("xcalibur") - withServer(APIMetabolomicsFormat) {
@@ -133,18 +113,12 @@ object APIMetabolomicsFormatTest extends TestSuite {
133113
assert(ujson.read(response.text()).asInstanceOf[ujson.Obj].value("format") == ujson.Str("xcalibur"))
134114
}
135115

136-
test("xcalibur/generic") - withServer(APIMetabolomicsFormat) {
137-
host =>
138-
val response = requests.post(s"$host/p2m2tools/api/format/parse/xcalibur/generic", data = MetabolomicsData.xcalibur)
139-
assert(response.statusCode == 200)
140-
assert(ujson.read(response.text()).arr.length == 468)
141-
}
142-
143116
test("xcalibur generic parsing") - withServer(APIMetabolomicsFormat) {
144117
host =>
145118
val response = requests.post(s"$host/p2m2tools/api/format/parse", data = MetabolomicsData.xcalibur)
146119
assert(response.statusCode == 200)
147-
assert(ujson.read(response.text()).arr.length == 468)
120+
assert(ujson.read(response.text()).isInstanceOf[ujson.Obj])
121+
assert(ujson.read(response.text()).asInstanceOf[ujson.Obj].value("samples").arr.length == 468)
148122
}
149123

150124
test("Empty close connexion")

app/test/src/MetabolomicsData.scala renamed to app/test/src/fr/inrae/metabolomics/p2m2/api/MetabolomicsData.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package fr.inrae.metabolomics.p2m2.api
22

33
import java.nio.file.{Files, Paths}
4-
import scala.io.Source
54

65
object MetabolomicsData {
7-
val gcms =
6+
val gcms: String =
87
"""
98
|[Header]
109
|Data File Name C:\Users\ydellero\Desktop\Projets CR\P2M2\TQD\210510_13C_Younes\13CPROT2.qgd
@@ -15,7 +14,7 @@ object MetabolomicsData {
1514
|ID# Name Type ISTD Group# Mass Ret.Time Start Time End Time A/H Area Height Conc. Mode Peak# Std.Ret.Time Calibration Curve 3rd 2nd 1st Constant Ref.Ion Area Ref.Ion Height Ref.Ion Set Ratio Ref.Ion Ratio Recovery SI Ref.Ion1 m/z Ref.Ion1 Area Ref.Ion1 Height Ref.Ion1 Set Ratio Ref.Ion1 Ratio Ref.Ion2 m/z Ref.Ion2 Area Ref.Ion2 Height Ref.Ion2 Set Ratio Ref.Ion2 Ratio Ref.Ion3 m/z Ref.Ion3 Area Ref.Ion3 Height Ref.Ion3 Set Ratio Ref.Ion3 Ratio Ref.Ion4 m/z Ref.Ion4 Area Ref.Ion4 Height Ref.Ion4 Set Ratio Ref.Ion4 Ratio Ref.Ion5 m/z Ref.Ion5 Area Ref.Ion5 Height Ref.Ion5 Set Ratio Ref.Ion5 Ratio Ret. Index S/N Unit Description Threshold
1615
|1 Glyoxylate (1MEOX) (1TMS )m0 Target 1 160.00 6.405 6.393 6.423 1.080 14 13 0.00029 Auto 3 6.400 Default 0 0 0 0 0 0 84.50 0.00 0.00 18 73.00 0 0 84.50 0.00 59.00 142 129 49.59 1014.29 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1218 4.87 mg/L 0.00000
1716
|""".stripMargin
18-
val openlabcds =
17+
val openlabcds: String =
1918
"""
2019
|Data File C:\Chemstation\1\Data\211011_Corentin-Younes 2021-10-11 15-56-48\Std 500.D
2120
|Sample Name: Std 500

0 commit comments

Comments
 (0)