@@ -29,34 +29,57 @@ object MainGlucosinolates extends IOApp {
2929
3030 private val builder = OParser .builder[Config ]
3131 private val parser1 = {
32- import builder ._
33- OParser .sequence(
34- programName(" MainGlucosinolates" ),
35- head(" MainGlucosinolates" , " 1.0" ),
36- opt[String ]('o' , " output" )
37- .required()
38- .action((x, c) => c.copy(outputFile = Some (x)))
39- .text(" Output file" ),
40- opt[Double ]('s' , " startRT" )
41- .optional()
42- .action((x, c) => c.copy(startRT = Some (x)))
43- .text(" start RT" ),
44- opt[Double ]('e' , " endRT" )
45- .optional()
46- .action((x, c) => c.copy(endRT = Some (x)))
47- .text(" end RT" ),
48- opt[Double ]('i' , " minIntensity" )
49- .optional()
50- .action((x, c) => c.copy(minIntensity = x))
51- .text(" Minimum intensity threshold selecting the ions of interest" ),
52- arg[String ](" <file>" )
53- .required()
54- .action((x, c) => c.copy(mzFile = Some (x)))
55- .text(" Input mzXML file" ),
56- help(" help" ).text(" prints this usage text" )
57- )
58- }
59-
32+ import builder ._
33+ OParser .sequence(
34+ programName(" MainGlucosinolates" ),
35+ head(" MainGlucosinolates" , " 1.0" ),
36+ opt[String ]('o' , " output" )
37+ .required()
38+ .action((x, c) => c.copy(outputFile = Some (x)))
39+ .text(" Output file" ),
40+ opt[Double ]('s' , " startRT" )
41+ .optional()
42+ .action((x, c) => c.copy(startRT = Some (x)))
43+ .text(" Start retention time" ),
44+ opt[Double ]('e' , " endRT" )
45+ .optional()
46+ .action((x, c) => c.copy(endRT = Some (x)))
47+ .text(" End retention time" ),
48+ opt[Double ]('i' , " minIntensity" )
49+ .optional()
50+ .action((x, c) => c.copy(minIntensity = x))
51+ .text(" Minimum intensity threshold" ),
52+ opt[Double ](" deltaMp0Mp2" )
53+ .optional()
54+ .action((x, c) => c.copy(deltaMp0Mp2 = x))
55+ .text(" Delta between M0 and M2 peaks" ),
56+ opt[Int ](" carbonMin" )
57+ .optional()
58+ .action((x, c) => c.copy(numberCarbonMin = x))
59+ .text(" Minimum number of carbon atoms" ),
60+ opt[Int ](" carbonMax" )
61+ .optional()
62+ .action((x, c) => c.copy(numberCarbonMax = x))
63+ .text(" Maximum number of carbon atoms" ),
64+ opt[Double ](" sulfurMin" )
65+ .optional()
66+ .action((x, c) => c.copy(numberSulfurMin = x))
67+ .text(" Minimum number of sulfur atoms" ),
68+ opt[Double ](" sulfurMax" )
69+ .optional()
70+ .action((x, c) => c.copy(numberSulfurMax = x))
71+ .text(" Maximum number of sulfur atoms" ),
72+ opt[Double ](" precisionMz" )
73+ .optional()
74+ .action((x, c) => c.copy(precisionMz = x))
75+ .text(" Precision for m/z matching" ),
76+ arg[String ](" <file>" )
77+ .required()
78+ .action((x, c) => c.copy(mzFile = Some (x)))
79+ .text(" Input mzXML file" ),
80+ help(" help" ).text(" prints this usage text" )
81+ )
82+ }
6083 def run (args : List [String ]): IO [ExitCode ] = {
6184 OParser .parse(parser1, args, Config ()) match {
6285 case Some (config) =>
@@ -70,6 +93,7 @@ private def processFile(config: Config): IO[Unit] = {
7093 mzXMLFile <- IO .fromOption(config.mzFile)(new IllegalArgumentException (" Missing mzXML file" ))
7194 startTime = config.startRT.getOrElse(0.0 )
7295 endTime = config.endRT.getOrElse(Double .MaxValue )
96+
7397 processStart <- IO .realTime.map(rt => DateTime .now().plus(rt.toMillis))
7498 _ <- IO .println(s " Start analyze: $mzXMLFile" )
7599
@@ -87,7 +111,7 @@ private def processFile(config: Config): IO[Unit] = {
87111 .count
88112
89113 _ <- totalSpectraRef.set(totalSpectra.toInt)
90-
114+
91115 results <- SpectrumRequest (mzXMLFile)
92116 .msLevel(1 )
93117 .filter(_.isDefined)
@@ -110,8 +134,22 @@ private def processFile(config: Config): IO[Unit] = {
110134
111135 _ <- IO .println(s " Sorting completed. Number of results: ${sortedResults.size}" )
112136
113- _ <- Stream .emits(sortedResults)
114- .evalMap(result => IO .println(result.toString))
137+ // CSV Header
138+ csvHeader = " RetentionTime;M0_mz;M0_intensity;M1_mz;M1_intensity;M2_mz;M2_intensity"
139+
140+ _ <- Stream .emits(Seq (csvHeader) ++ sortedResults)
141+ .map {
142+ case header : String => header
143+ case result : Product =>
144+ result match {
145+ case (rt : Double , ((mz0 : Double , int0 : Double ), (mz1 : Double , int1 : Double ), (mz2 : Double , int2 : Double ))) =>
146+ s " $rt; $mz0; $int0; $mz1; $int1; $mz2; $int2"
147+ case _ => " "
148+ }
149+ }
150+ .map(_ + " \n " )
151+ .through(text.utf8.encode)
152+ .through(Files [IO ].writeAll(Path (config.outputFile.getOrElse(" output.csv" ))))
115153 .compile
116154 .drain
117155
@@ -122,7 +160,6 @@ private def processFile(config: Config): IO[Unit] = {
122160 } yield ()
123161}
124162
125-
126163private def processSpectrum (config : Config , spectrum : Spectrum ): Seq [(Double , ((Double , Double ), (Double , Double ), (Double , Double )))] = {
127164 spectrum.peaks
128165 .filter { case (_, int0) => int0 > config.minIntensity }
0 commit comments