Skip to content

Commit

Permalink
Use identation-significant syntax
Browse files Browse the repository at this point in the history
This is done through the compiler's automated rewrite; there remaining
a few cases that it did not rewrite.
  • Loading branch information
mtomko committed Jan 11, 2024
1 parent 4eccf03 commit 6dc9eae
Show file tree
Hide file tree
Showing 115 changed files with 963 additions and 1,381 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v3.1.0
- uses: jrouly/scalafmt-native-action@v2
with:
version: '3.5.8'
version: '3.7.17'
- name: Set up JDK 8
uses: actions/setup-java@v3.6.0
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- run: git config --global user.name "GPP Informatics"
- uses: jrouly/scalafmt-native-action@v2
with:
version: '3.5.8'
version: '3.7.17'
- name: Set up JDK 8
uses: actions/setup-java@v3.6.0
with:
Expand Down
3 changes: 2 additions & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# PoolQ3 .scalafmt configuration
version=3.5.8
version=3.7.17
style = IntelliJ

maxColumn = 120
Expand All @@ -14,4 +14,5 @@ rewrite.redundantBraces.generalExpressions = false
rewrite.redundantBraces.includeUnitMethods = false
rewrite.redundantBraces.maxBreaks = 16
rewrite.redundantBraces.stringInterpolation = true
rewrite.scala3.insertEndMarkerMinLines = 10
runner.dialect = scala3
44 changes: 20 additions & 24 deletions src/main/scala/org/broadinstitute/gpp/poolq3/PoolQ.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,25 @@ import org.broadinstitute.gpp.poolq3.types.{
}
import org.log4s.{Logger, getLogger}

object PoolQ {
object PoolQ:

private[this] val log: Logger = getLogger

private[this] val AlwaysWrittenFiles: Set[OutputFileType] =
Set(CountsFileType, QualityFileType, LogNormalizedCountsFileType, BarcodeCountsFileType, RunInfoFileType)

final def main(args: Array[String]): Unit =
PoolQConfig.parse(args) match {
PoolQConfig.parse(args) match
case None => System.exit(-1)
case Some(config) =>
run(config) match {
run(config) match
case Success(_) => // do nothing
case Failure(t) =>
log.error(t)("PoolQ failed")
System.exit(-1)
}
}

/** The main entry point for PoolQ3 as an API */
final def run(config: PoolQConfig): Try[PoolQSummary] = {
final def run(config: PoolQConfig): Try[PoolQSummary] =
log.info(s"PoolQ version: ${BuildInfo.version}")
logCli(config)

Expand All @@ -68,10 +66,9 @@ object PoolQ {
log.info("Reading column reference data")
val colReferenceData = ReferenceData(config.input.colReference).forColumnBarcodes(config.reportsDialect)

val globalReferenceDataOpt = config.input.globalReference.map {
val globalReferenceDataOpt = config.input.globalReference.map:
log.info("Reading global reference data")
ReferenceData(_)
}

val (rowBarcodePolicy, revRowBarcodePolicyOpt, rowBarcodeLength) =
makeRowBarcodePolicy(
Expand Down Expand Up @@ -123,14 +120,14 @@ object PoolQ {

lazy val unexpectedSequenceCacheDir: Option[Path] =
if config.skipUnexpectedSequenceReport then None
else {
val ret = config.unexpectedSequenceCacheDir.map(Files.createDirectories(_)).orElse {
val ret: Path = Files.createTempDirectory("unexpected-sequence-cache")
Some(ret)
}
else
val ret = config.unexpectedSequenceCacheDir
.map(Files.createDirectories(_))
.orElse:
val ret: Path = Files.createTempDirectory("unexpected-sequence-cache")
Some(ret)
ret.foreach(path => log.info(s"Writing unexpected sequence cache files to $path"))
ret
}

val consumer =
if config.noopConsumer then new NoOpConsumer
Expand Down Expand Up @@ -195,17 +192,19 @@ object PoolQ {
globalReference
)
.as(UnexpectedSequencesFileType.some)
if config.removeUnexpectedSequenceCache then {
if config.removeUnexpectedSequenceCache then
log.info(s"Removing unexpected sequence cache ${config.unexpectedSequenceCacheDir}")
UnexpectedSequenceWriter.removeCache(dir)
}
ret
}
_ = log.info(s"Writing run info ${config.output.unexpectedSequencesFile}")
_ <- RunInfoWriter.write(config.output.runInfoFile, config)
_ = log.info("PoolQ complete")
yield PoolQSummary(runSummary, AlwaysWrittenFiles ++ Set(cfto, usfto).flatten)
}

end for

end run

def runProcess(barcodes: CloseableIterable[Barcodes], consumer: Consumer): Try[PoolQRunSummary] =
Using(barcodes.iterator) { iterator =>
Expand All @@ -227,20 +226,17 @@ object PoolQ {
val revRowBarcodePolicy = BarcodePolicy(revPolicy, revRowBcLength, skipShortReads)
(rowBarcodePolicy, Some(revRowBarcodePolicy), rowBarcodePolicy.length + revRowBarcodePolicy.length)
}
.getOrElse {
.getOrElse:
val rowBarcodePolicy = BarcodePolicy(rowBarcodePolicyStr, rowReferenceData.barcodeLength, skipShortReads)
(rowBarcodePolicy, None, rowBarcodePolicy.length)
}

private[this] def logCli(config: PoolQConfig): Unit = {
private[this] def logCli(config: PoolQConfig): Unit =
val logStr =
synthesizeArgs(config)
.map {
.map:
case (param, "") => s"--$param"
case (param, arg) => s"--$param $arg"
}
.mkString(" \\\n")
log.info(s"PoolQ command-line settings:\n$logStr")
}

}
end PoolQ
86 changes: 34 additions & 52 deletions src/main/scala/org/broadinstitute/gpp/poolq3/PoolQConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ final case class PoolQInput(
addlColReads: List[Path] = Nil,
addlReads: List[(Option[String], Path)] = Nil,
demultiplexed: Boolean = false
) {
):

def readsSourceE: Either[Exception, ReadsSource] = (rowReads, reverseRowReads, colReads, reads, demultiplexed) match {
def readsSourceE: Either[Exception, ReadsSource] = (rowReads, reverseRowReads, colReads, reads, demultiplexed) match
case (None, None, None, Some(r), false) =>
Right(ReadsSource.SelfContained(Nel(r._2, addlReads.view.map(_._2).toList)))

Expand All @@ -63,11 +63,10 @@ final case class PoolQInput(
else Left(PoolQException("Row and column reads files must match"))

case _ => Left(PoolQException("Conflicting input options"))
}

def readsSource: ReadsSource = readsSourceE.fold(e => throw e, rs => rs)

}
end PoolQInput

final case class PoolQOutput(
countsFile: Path = Paths.get("counts.txt"),
Expand Down Expand Up @@ -100,7 +99,7 @@ final case class PoolQConfig(
reportsDialect: ReportsDialect = PoolQ3Dialect,
alwaysCountColumnBarcodes: Boolean = false,
noopConsumer: Boolean = false
) {
):

def isPairedEnd =
reverseRowBarcodePolicyStr.isDefined &&
Expand All @@ -113,45 +112,42 @@ final case class PoolQConfig(
case Left(_) => false
})

}
end PoolQConfig

object PoolQConfig {
object PoolQConfig:

private[poolq3] val BarcodePathRegex = "([ACGT]+):(.+)".r

private[poolq3] val DefaultPath = Paths.get(".")

implicit private[this] val readPath: Read[Path] = implicitly[Read[File]].map(_.toPath)

implicit private[this] val readPaths: Read[(Path, List[Path])] = implicitly[Read[Seq[File]]].map { files =>
files.toList.map(_.toPath) match {
implicit private[this] val readPaths: Read[(Path, List[Path])] = implicitly[Read[Seq[File]]].map: files =>
files.toList.map(_.toPath) match
case Nil => throw new IllegalArgumentException(s"No argument provided")
case (x :: xs) => (x, xs)
}
}

implicit private[this] val readBarcodePaths: Read[List[(Option[String], Path)]] = implicitly[Read[Seq[String]]].map {
args =>
args.view.map { arg =>
arg match {
case BarcodePathRegex(bc, pathStr) => (Option(bc), Paths.get(pathStr))
case _ => (None, Paths.get(arg))
}
}.toList
}

implicit private[this] val readBarcodePaths: Read[List[(Option[String], Path)]] =
implicitly[Read[Seq[String]]].map: args =>
args.view
.map: arg =>
arg match
case BarcodePathRegex(bc, pathStr) => (Option(bc), Paths.get(pathStr))
case _ => (None, Paths.get(arg))
.toList

implicit private[this] val readReadIdCheckPolicy: Read[ReadIdCheckPolicy] =
implicitly[Read[String]].map(ReadIdCheckPolicy.forName)

def parse(args: Array[String]): Option[PoolQConfig] = {
def parse(args: Array[String]): Option[PoolQConfig] =

val parser: OptionParser[PoolQConfig] = new OptionParser[PoolQConfig]("poolq") {
val parser: OptionParser[PoolQConfig] = new OptionParser[PoolQConfig]("poolq"):
private[this] def existsAndIsReadable(f: Path): Either[String, Unit] =
if !Files.exists(f) then failure(s"Could not find ${f.toAbsolutePath}")
else if !Files.isReadable(f) then failure(s"Could not read ${f.toAbsolutePath}")
else success

locally {
locally:
val _ = head(BuildInfo.name, BuildInfo.version)

val _ = opt[Path]("row-reference")
Expand Down Expand Up @@ -323,7 +319,7 @@ object PoolQConfig {
val _ = opt[Unit]("noop").hidden().action((_, c) => c.copy(noopConsumer = true))

val _ = checkConfig { c =>
val readsCheck = (c.input.reads, c.input.rowReads, c.input.colReads, c.input.demultiplexed) match {
val readsCheck = (c.input.reads, c.input.rowReads, c.input.colReads, c.input.demultiplexed) match
case (None, None, None, _) => failure("No reads files specified.")
case (None, None, Some(_), false) =>
failure("Column barcode file specified but no row barcodes file specified.")
Expand All @@ -332,24 +328,20 @@ object PoolQConfig {
case (None, Some(_), None, false) =>
failure("Row barcode file specified but no column barcodes file specified.")
case _ => success
}

val pairedEndConsistencyCheck = (c.input.reverseRowReads, c.reverseRowBarcodePolicyStr) match {
val pairedEndConsistencyCheck = (c.input.reverseRowReads, c.reverseRowBarcodePolicyStr) match
case (Some(_), None) => failure("Reverse row reads file specified but no reverse barcode policy specified")
case (None, Some(_)) => failure("Reverse barcode policy specified but now reverse row reads file specified")
case _ => success
}

readsCheck >> pairedEndConsistencyCheck
}
}
}

parser.parse(args, PoolQConfig())

}
end parse

def synthesizeArgs(config: PoolQConfig): List[(String, String)] = {
def synthesizeArgs(config: PoolQConfig): List[(String, String)] =
val args = new mutable.ArrayBuffer[(String, String)]

// umi
Expand Down Expand Up @@ -388,29 +380,21 @@ object PoolQConfig {
// run control
args += (("row-matcher", config.rowMatchFn))
args += (("col-matcher", config.colMatchFn))
if config.countAmbiguous then {
args += (("count-ambiguous", ""))
}
if config.countAmbiguous then args += (("count-ambiguous", ""))
args += (("row-barcode-policy", config.rowBarcodePolicyStr))
config.reverseRowBarcodePolicyStr.foreach(p => args += (("rev-row-barcode-policy", p)))
config.colBarcodePolicyStr.foreach(pol => args += (("col-barcode-policy", pol)))
umiInfo.map(_._2).foreach(str => args += (("umi-barcode-policy", str)))

// deal with the unexpected sequence options
if config.skipUnexpectedSequenceReport then {
args += (("skip-unexpected-sequence-report", ""))
} else {
if config.skipUnexpectedSequenceReport then args += (("skip-unexpected-sequence-report", ""))
else
// give whatever path we were given here - this _may_ not need to be included at all, honestly
config.unexpectedSequenceCacheDir.foreach(file => args += (("unexpected-sequence-cache", file.toString)))
args += (("unexpected-sequence-threshold", config.unexpectedSequencesToReport.toString))
}

if config.skipShortReads then {
args += (("skip-short-reads", ""))
}
if config.reportsDialect == PoolQ2Dialect then {
args += (("compat", ""))
}
if config.skipShortReads then args += (("skip-short-reads", ""))
if config.reportsDialect == PoolQ2Dialect then args += (("compat", ""))

// output files
val output = config.output
Expand All @@ -424,15 +408,13 @@ object PoolQConfig {
output.umiCountsFilesDir.foreach(d => args += (("umi-counts-dir", d.toString)))
output.umiBarcodeCountsFilesDir.foreach(d => args += (("umi-barcode-counts-dir", d.toString)))
}
if !config.skipUnexpectedSequenceReport then {
if !config.skipUnexpectedSequenceReport then
args += (("unexpected-sequences", output.unexpectedSequencesFile.getFileName.toString))
}
if config.alwaysCountColumnBarcodes then {
args += (("always-count-col-barcodes", ""))
}
if config.alwaysCountColumnBarcodes then args += (("always-count-col-barcodes", ""))
args += (("run-info", output.runInfoFile.getFileName.toString))

args.toList
}

}
end synthesizeArgs

end PoolQConfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import cats.data.{NonEmptyList => Nel}

sealed trait ReadsSource extends Product with Serializable

object ReadsSource {
object ReadsSource:

final case class SelfContained(paths: Nel[Path]) extends ReadsSource
final case class Split(index: Nel[Path], forward: Nel[Path]) extends ReadsSource
Expand All @@ -21,4 +21,4 @@ object ReadsSource {
final case class DmuxedPairedEnd(read1: Nel[(Option[String], Path)], read2: Nel[(Option[String], Path)])
extends ReadsSource

}
end ReadsSource
Loading

0 comments on commit 6dc9eae

Please sign in to comment.