Skip to content

Commit ee53c54

Browse files
committed
save first version
1 parent 6a6418c commit ee53c54

File tree

9 files changed

+183
-94
lines changed

9 files changed

+183
-94
lines changed

Readme.md

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,56 @@
11

2+
## ammonite example
3+
4+
```scala
5+
import $cp.`target/scala-2.13/mzXML-stream-assembly-1.0.jar`
6+
import cats.effect.{IO, IOApp}
7+
import fs2.{Stream, text, Pipe}
8+
import fs2.io.file.{Files, Path}
9+
import java.nio.file.Paths
10+
11+
import cats.effect.unsafe.implicits._
12+
import fr.inrae.p2m2.mzxml._
13+
14+
15+
val mzXMLFile = "./src/test/resources/LTQ_Orbitrap_precision32.mzXML"
16+
val outputFile = "precursor_288p93.txt"
17+
18+
19+
val formatPrecursorMz : Pipe[IO, Option[Seq[PrecursorMz]], String] = {
20+
inStream =>
21+
inStream.map {
22+
case Some(p) => s"Precursor ${p.head.value} with precursorIntensity ${p.head.precursorIntensity} " +
23+
s"and precursorScanNum ${p.head.precursorScanNum}\n"
24+
case _ => ""
25+
}
26+
}
27+
28+
SpectrumRequest(mzXMLFile).precursorMz(288.93,5000).map {
29+
case Some(r) => Some(r.precursorMz)
30+
case None => None
31+
}
32+
.filter(_.isDefined)
33+
.through(formatPrecursorMz)
34+
.through(text.utf8.encode)
35+
.through(Files[IO].writeAll(Path(outputFile)))
36+
.compile
37+
.drain
38+
.unsafeRunSync()
39+
40+
println(outputFile)
41+
```
42+
43+
`amm example.sc`
44+
45+
246
## test
347

4-
sbt "run example.mzXML"
48+
```bash
49+
sbt "run ./src/test/resources/LTQ_Orbitrap_precision32.mzXML"
50+
```
51+
552

653
## specifications
754

8-
https://sashimi.sourceforge.net/schema_revision/mzXML_2.1/Doc/mzXML_2.0_tutorial.pdf
55+
https://sashimi.sourceforge.net/schema_revision/mzXML_2.1/Doc/mzXML_2.0_tutorial.pdf
56+

example.sc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import $cp.`target/scala-2.13/mzXML-stream-assembly-1.0.jar`
2+
import cats.effect.{IO, IOApp}
3+
import fs2.{Stream, text, Pipe}
4+
import fs2.io.file.{Files, Path}
5+
import java.nio.file.Paths
6+
7+
import cats.effect.unsafe.implicits._
8+
import fr.inrae.p2m2.mzxml._
9+
10+
11+
val mzXMLFile = "./src/test/resources/LTQ_Orbitrap_precision32.mzXML"
12+
val outputFile = "precursor_288p93.txt"
13+
14+
15+
val formatPrecursorMz : Pipe[IO, Option[Seq[PrecursorMz]], String] = {
16+
inStream =>
17+
inStream.map {
18+
case Some(p) => s"Precursor ${p.head.value} with precursorIntensity ${p.head.precursorIntensity} " +
19+
s"and precursorScanNum ${p.head.precursorScanNum}\n"
20+
case _ => ""
21+
}
22+
}
23+
24+
SpectrumRequest(mzXMLFile).precursorMz(288.93,5000).map {
25+
case Some(r) => Some(r.precursorMz)
26+
case None => None
27+
}
28+
.filter(_.isDefined)
29+
.through(formatPrecursorMz)
30+
.through(text.utf8.encode)
31+
.through(Files[IO].writeAll(Path(outputFile)))
32+
.compile
33+
.drain
34+
.unsafeRunSync()
35+
36+
println(outputFile)

src/main/scala/Main.scala

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,47 @@
1-
import cats.Show
21
import cats.effect.{ExitCode, IO, IOApp}
32
import cats.effect.unsafe.implicits.global
4-
import fs2.Stream
53
import fs2._
6-
import fs2.data.xml
7-
import fs2.io.file.{Files, Flags}
8-
import fs2.data.xml._
9-
import fs2.data.xml.xpath.XPath
10-
import fs2.data.xml.xpath.literals._
11-
12-
import java.nio.charset.Charset
13-
import com.lucidchart.open.xtract.XmlReader
14-
import mzxml.ScanOrigin
4+
import fs2.io.file.{Files, Flags, Path}
5+
import fr.inrae.p2m2.mzxml.{PrecursorMz, SpectrumRequest}
156

167
import scala.xml.{NodeSeq, XML}
178

189
object Main extends IOApp {
1910

11+
val formatPrecursorMz : Pipe[IO, Option[Seq[PrecursorMz]], String] = {
12+
inStream =>
13+
inStream.map {
14+
case Some(p) => s"Precursor ${p.head.value} with precursorIntensity ${p.head.precursorIntensity} " +
15+
s"and precursorScanNum ${p.head.precursorScanNum}\n"
16+
case _ => ""
17+
}
18+
}
2019

21-
def run(args: List[String]): IO[ExitCode] =
22-
args.headOption match {
23-
case Some(mzXML) =>
24-
IO {
25-
println("*** mzXML :"+mzXML+"*")
26-
/*val scanListOfInterest : Stream[IO,Seq[Scan]] = msRun(mzXML)
27-
.map {
28-
case Some(run) =>
29-
run.scan.filter(s => s.properties.num==20)
30-
case None => Seq()
31-
}
32-
33-
val res = scanListOfInterest.compile
34-
.toList
35-
.unsafeRunSync()
36-
println(res)*/
37-
}.as(ExitCode.Success)
38-
case None =>
39-
IO(System.err.println("Usage: MyApp name")).as(ExitCode(2))
20+
def run(args: List[String]): IO[ExitCode] = {
21+
val mzXMLFile = {
22+
args.headOption match {
23+
case Some(mzXML) => mzXML
24+
case None =>
25+
"./src/test/resources/LTQ_Orbitrap_precision32.mzXML"
26+
}
4027
}
28+
val outputFile = "precursor_288p93.txt"
29+
30+
IO {
31+
SpectrumRequest(mzXMLFile).precursorMz(288.93, 9000).map {
32+
case Some(r) => Some(r.precursorMz)
33+
case None => None
34+
}
35+
.filter(_.isDefined)
36+
.through(formatPrecursorMz)
37+
.through(text.utf8.encode)
38+
.through(Files[IO].writeAll(Path(outputFile)))
39+
.compile
40+
.drain
41+
.unsafeRunSync()
42+
43+
println(outputFile)
44+
45+
}.as(ExitCode.Success)
46+
}
4147
}

src/main/scala/mzxml/MzXMLTags.scala renamed to src/main/scala/fr/inrae/p2m2/mzxml/MzXMLTags.scala

Lines changed: 43 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
1-
package mzxml
1+
package fr.inrae.p2m2.mzxml
22

33
import com.lucidchart.open.xtract.{XmlReader, __}
44
import com.lucidchart.open.xtract.XmlReader._
55
import cats.syntax.all._
6-
import mzxml.Precision.Value
76
import com.github.marklister.base64.Base64._
7+
import fr.inrae.p2m2.mzxml
88

99
import java.nio._
10-
import javax.xml.datatype.{DatatypeFactory, Duration}
11-
import scala.xml.NodeSeq
10+
import javax.xml.datatype.DatatypeFactory
1211

1312
case class MzXML(
14-
msRun : mzxml.MsRun,
13+
msRun : MsRun,
1514
index : Seq[mzxml.IndexScan] = Nil,
1615
indexOffset : Option[mzxml.IndexOffset],
1716
sha1: Option[String] = None
1817
)
1918

2019
object MzXML {
2120
implicit val reader: XmlReader[MzXML] = (
22-
(__ \ "msRun").read[mzxml.MsRun],
21+
(__ \ "msRun").read[MsRun],
2322
(__ \ "index").read(seq[mzxml.IndexScan]),
2423
(__ \ "indexOffset").read[mzxml.IndexOffset].optional,
2524
attribute[String]("sha1").optional
@@ -29,9 +28,9 @@ case class MsRun(
2928
scanCount : Option[Int],
3029
startTimeInSeconds : Option[Int],
3130
endTimeInSeconds : Option[Int],
32-
parentFile: Seq[mzxml.ParentFile] = Nil,
33-
msInstrument: Seq[mzxml.MsInstrument] = Nil,
34-
dataProcessing: Seq[mzxml.DataProcessing] = Nil,
31+
parentFile: Seq[ParentFile] = Nil,
32+
msInstrument: Seq[MsInstrument] = Nil,
33+
dataProcessing: Seq[DataProcessing] = Nil,
3534
// separation: Option[mzxml.Separation] = None,
3635
// spotting: Option[mzxml.Spotting] = None,
3736
scan: Seq[mzxml.ScanOrigin] = Nil,
@@ -43,9 +42,9 @@ object MsRun {
4342
attribute[String]("scanCount").map(_.toInt).optional,
4443
attribute[String]("startTime").map(DatatypeFactory.newInstance().newDuration).map(_.getSeconds).optional,
4544
attribute[String]("endTime").map(DatatypeFactory.newInstance().newDuration).map(_.getSeconds).optional,
46-
(__ \ "parentFile").read(seq[mzxml.ParentFile]),
47-
(__ \ "msInstrument")read(seq[mzxml.MsInstrument]),
48-
(__ \ "dataProcessing")read(seq[mzxml.DataProcessing]),
45+
(__ \ "parentFile").read(seq[ParentFile]),
46+
(__ \ "msInstrument")read(seq[MsInstrument]),
47+
(__ \ "dataProcessing")read(seq[DataProcessing]),
4948
(__ \ "scan")read(seq[mzxml.ScanOrigin]),
5049
attribute[String]("sha1").optional
5150
).mapN(apply)
@@ -118,31 +117,31 @@ object MsInstrumentSequence {
118117
}
119118

120119
case class MsInstrument(
121-
msInstrumentID : Option[String],
122-
msManufacturer: mzxml.OntologyEntryTypable,
123-
msModel: mzxml.OntologyEntryTypable,
124-
msIonisation: mzxml.OntologyEntryTypable,
125-
msMassAnalyzer: mzxml.OntologyEntryTypable,
126-
msDetector: mzxml.OntologyEntryTypable,
127-
software: mzxml.Software,
128-
msResolution: Option[mzxml.OntologyEntryTypable] = None,
129-
operator: Option[mzxml.Operator] = None,
130-
msinstrumentsequence1: Seq[mzxml.MsInstrumentSequence] = Nil)
120+
msInstrumentID : Option[String],
121+
msManufacturer: OntologyEntryTypable,
122+
msModel: OntologyEntryTypable,
123+
msIonisation: OntologyEntryTypable,
124+
msMassAnalyzer: OntologyEntryTypable,
125+
msDetector: OntologyEntryTypable,
126+
software: Software,
127+
msResolution: Option[OntologyEntryTypable] = None,
128+
operator: Option[Operator] = None,
129+
msinstrumentsequence1: Seq[MsInstrumentSequence] = Nil)
131130

132131
object MsInstrument {
133132

134133
implicit val reader: XmlReader[MsInstrument] = {
135134
(
136135
attribute[String]("msInstrumentID").optional,
137-
(__ \ "msManufacturer").read[mzxml.OntologyEntryTypable],
138-
(__ \ "msModel").read[mzxml.OntologyEntryTypable],
139-
(__ \ "msIonisation").read[mzxml.OntologyEntryTypable],
140-
(__ \ "msMassAnalyzer").read[mzxml.OntologyEntryTypable],
141-
(__ \ "msDetector").read[mzxml.OntologyEntryTypable],
136+
(__ \ "msManufacturer").read[OntologyEntryTypable],
137+
(__ \ "msModel").read[OntologyEntryTypable],
138+
(__ \ "msIonisation").read[OntologyEntryTypable],
139+
(__ \ "msMassAnalyzer").read[OntologyEntryTypable],
140+
(__ \ "msDetector").read[OntologyEntryTypable],
142141
(__ \ "software").read[Software],
143-
(__ \ "msResolution").read[mzxml.OntologyEntryTypable].optional,
144-
(__ \ "operator").read[mzxml.Operator].optional,
145-
(__ \ "msinstrumentsequence").read(seq[mzxml.MsInstrumentSequence])
142+
(__ \ "msResolution").read[OntologyEntryTypable].optional,
143+
(__ \ "operator").read[Operator].optional,
144+
(__ \ "msinstrumentsequence").read(seq[MsInstrumentSequence])
146145
).mapN(apply)
147146
}
148147
}
@@ -154,8 +153,8 @@ case class DataProcessing(
154153
deisotoped : Option[Boolean],
155154
chargeDeconvoluted : Option[Boolean],
156155
spotIntegration : Option[Boolean],
157-
software: mzxml.Software,
158-
dataprocessingsequence1: Seq[mzxml.DataProcessingSequence] = Nil
156+
software: Software,
157+
dataprocessingsequence1: Seq[DataProcessingSequence] = Nil
159158
)
160159
object DataProcessing {
161160
implicit val reader: XmlReader[DataProcessing] = (
@@ -327,12 +326,12 @@ object Peaks {
327326
mzs.zipWithIndex.map( x => (x._1,intensities(x._2))).filter(_._2>0) // removes intensities equal to zero
328327
}
329328

330-
private def strToPrecision(name: String): Value =
329+
private def strToPrecision(name: String): Precision.Value =
331330
mzxml.Precision.values.find(_.toString.toLowerCase() == name.toLowerCase()).getOrElse(Precision.Number32)
332331

333332
private val mzsIntensitiesPairReader: XmlReader[Seq[(Double,Double)]] = {
334333
for {
335-
base64 <- (__).read[String]
334+
base64 <- __.read[String]
336335
precision <- attribute[String]("precision")
337336
compression <- attribute("compressionType")(enum(CompressionType)).default(CompressionType.NoneType)
338337
} yield {
@@ -414,8 +413,8 @@ object ScanProperties {
414413

415414
case class ScanOrigin(
416415
properties : mzxml.ScanProperties,
417-
precursorMz: Seq[mzxml.PrecursorMz] = Nil,
418-
maldi: Option[mzxml.Maldi] = None,
416+
precursorMz: Seq[PrecursorMz] = Nil,
417+
maldi: Option[Maldi] = None,
419418
peaks: Seq[mzxml.Peaks] = Nil,
420419
scanSequence: Seq[mzxml.ScanSequence] = Nil,
421420
scan: Seq[mzxml.SubScan] = Nil
@@ -424,8 +423,8 @@ case class ScanOrigin(
424423
object ScanOrigin {
425424
implicit val reader: XmlReader[ScanOrigin] = {
426425
(__.read[ScanProperties],
427-
( __ \ "precursorMz").read(seq[mzxml.PrecursorMz]),
428-
( __ \ "maldi").read[mzxml.Maldi].optional,
426+
( __ \ "precursorMz").read(seq[PrecursorMz]),
427+
( __ \ "maldi").read[Maldi].optional,
429428
( __ \ "peaks").read(seq[mzxml.Peaks]),
430429
( __ \ "scanSequence").read(seq[mzxml.ScanSequence]),
431430
( __ \ "scan").read(seq[mzxml.SubScan])
@@ -434,12 +433,12 @@ object ScanOrigin {
434433
}
435434

436435
case class SubScan(
437-
properties : mzxml.ScanProperties,
438-
precursorMz: Seq[mzxml.PrecursorMz] = Nil,
439-
maldi: Option[mzxml.Maldi] = None,
440-
peaks: Seq[mzxml.Peaks] = Nil,
441-
scansequence: Seq[mzxml.ScanSequence] = Nil,
442-
scan: Seq[mzxml.ScanOrigin] = Nil
436+
properties : mzxml.ScanProperties,
437+
precursorMz: Seq[PrecursorMz] = Nil,
438+
maldi: Option[Maldi] = None,
439+
peaks: Seq[mzxml.Peaks] = Nil,
440+
scansequence: Seq[mzxml.ScanSequence] = Nil,
441+
scan: Seq[mzxml.ScanOrigin] = Nil
443442
)
444443

445444
object SubScan {

src/main/scala/mzxml/Spectrum.scala renamed to src/main/scala/fr/inrae/p2m2/mzxml/Spectrum.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package mzxml
1+
package fr.inrae.p2m2.mzxml
22

33
import scala.language.implicitConversions
44

@@ -32,7 +32,7 @@ case class Spectrum(
3232
totIonCurrent: Option[Double] = None,
3333
msInstrumentID: Option[Int] = None,
3434
compensationVoltage: Option[Double] = None,
35-
precursorMz: Seq[mzxml.PrecursorMz] = Seq(),
35+
precursorMz: Seq[PrecursorMz] = Seq(),
3636
peaks: Seq[(Double,Double)] = Seq()
3737
) {
3838
}

0 commit comments

Comments
 (0)