Skip to content

Commit

Permalink
feat: include v2d extra information regarding beta and odds ratio
Browse files Browse the repository at this point in the history
  • Loading branch information
mkarmona committed Mar 13, 2019
1 parent a3aa974 commit 8f61595
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 66 deletions.
53 changes: 32 additions & 21 deletions app/models/Backend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,20 @@ import models.DNA._
import models.Entities.DBImplicits._
import models.Entities.ESImplicits._
import models.Violations._
import com.sksamuel.elastic4s.analyzers._
import sangria.validation.Violation

import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
import scala.concurrent._
import com.sksamuel.elastic4s.http._
import org.elasticsearch.index.query.MultiMatchQueryBuilder
import play.db.NamedDatabase
import play.api.Logger
import play.api.Environment
import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
import java.nio.file.{Path, Paths}

import models.FRM.{D2V2G, D2V2GOverallScore, D2V2GScored, Genes, Overlaps, Studies, V2DsByChrPos, V2DsByStudy, V2G, V2GOverallScore, V2GStructure, Variants}
import org.elasticsearch.common.lucene.search.function.FieldValueFactorFunction
import org.elasticsearch.search.suggest.term.TermSuggestionBuilder

class Backend @Inject()(@NamedDatabase("default") protected val dbConfigProvider: DatabaseConfigProvider,
@NamedDatabase("sumstats") protected val dbConfigProviderSumStats: DatabaseConfigProvider,
Expand Down Expand Up @@ -143,10 +138,8 @@ class Backend @Inject()(@NamedDatabase("default") protected val dbConfigProvider

def getSearchResultSet(qString: String, pageIndex: Option[Int], pageSize: Option[Int]):
Future[Entities.SearchResultSet] = {
import com.sksamuel.elastic4s.playjson._
val limitClause = parsePaginationTokensForES(pageIndex, pageSize)
val stoken = qString.toLowerCase
val cleanedTokens = stoken.replaceAll("-", " ")

if (stoken.length > 0) {
esQ.execute {
Expand Down Expand Up @@ -218,7 +211,6 @@ class Backend @Inject()(@NamedDatabase("default") protected val dbConfigProvider
def getOverlapVariantsIntersectionForStudies(stid: String, stids: Seq[String]): Future[Vector[String]] = {
if (stids.nonEmpty) {
val numStudies = stids.length.toLong
val stidListString = stids.map("'" + _ + "'").mkString(",")

val q = overlaps
.filter(r => (r.studyIdA === stid) && (r.studyIdB inSetBind stids))
Expand All @@ -227,8 +219,6 @@ class Backend @Inject()(@NamedDatabase("default") protected val dbConfigProvider
.filter(_._2 === numStudies)
.map(_._1)

// q.result.statements.foreach(println)

db.run(q.result.asTry).map {
case Success(v) =>
v.view.map(_.id).toVector
Expand All @@ -247,9 +237,8 @@ class Backend @Inject()(@NamedDatabase("default") protected val dbConfigProvider
.filter(r => (r.studyIdA === stid) && (r.studyIdB inSetBind stids))
.groupBy(r => (r.studyIdB, r.variantA, r.variantB))
.map { case (l, g) =>
(l._1, l._2, l._3) -> (g.map(_.overlapsAB).any, g.map(_.distinctA).any, g.map(_.distinctB).any)}

// q.result.statements.foreach(println)
(l._1, l._2, l._3) -> (g.map(_.overlapsAB).any, g.map(_.distinctA).any, g.map(_.distinctB).any)
}

db.run(q.result.asTry).map {
case Success(v) =>
Expand Down Expand Up @@ -300,10 +289,8 @@ class Backend @Inject()(@NamedDatabase("default") protected val dbConfigProvider

/** query variants table with a list of variant ids and get all related information
*
* NOTE! WARNING! THERE IS A DIFF AT THE MOMENT BETWEEN THE VARIANTS COMING FROM VCF FILE
* AND THE ONES COMING FROM UKB AND WE NEED TO FILL THAT GAP WHILE THIS ISSUE IS NOT
* ADDRESSED. AT THE MOMENT, THE WAY TO DO IS USING THE VARIANT APPLY CONSTRUCTOR FROM A
* STRING TO GET A WHITE-LABEL VARIANT WITH ANY OTHER REFERENCES FROM RSID OR NEAREST GENES
* NOTE! WARNING! AT THE MOMENT, THE WAY TO DO IS USING THE VARIANT APPLY CONSTRUCTOR FROM A
* STRING TO GET A WHITE-LABEL VARIANT WITH NO OTHER REFERENCES FROM RSID OR NEAREST GENES
* (NONCODING AND PROTCODING)
*/
def getVariants(variantIds: Seq[String]): Future[Seq[DNA.Variant]] = {
Expand Down Expand Up @@ -342,7 +329,6 @@ class Backend @Inject()(@NamedDatabase("default") protected val dbConfigProvider
def buildManhattanTable(studyId: String, pageIndex: Option[Int], pageSize: Option[Int]):
Future[Entities.ManhattanTable] = {
val limitClause = parsePaginationTokens(pageIndex, pageSize)

val idxVariants = sql"""
|SELECT DISTINCT
| lead_chrom,
Expand All @@ -352,6 +338,13 @@ class Backend @Inject()(@NamedDatabase("default") protected val dbConfigProvider
| pval,
| pval_mantissa,
| pval_exponent,
| odds,
| oddsL,
| oddsU,
| direction,
| beta,
| betaL,
| betaU,
| credibleSetSize,
| ldSetSize,
| uniq_variants,
Expand All @@ -367,6 +360,13 @@ class Backend @Inject()(@NamedDatabase("default") protected val dbConfigProvider
| any(pval) AS pval,
| any(pval_mantissa) AS pval_mantissa,
| any(pval_exponent) AS pval_exponent,
| any(odds_ratio) as odds,
| any(oddsr_ci_lower) as oddsL,
| any(oddsr_ci_upper) as oddsU,
| any(direction) as direction,
| any(beta) as beta,
| any(beta_ci_lower) as betaL,
| any(beta_ci_upper) as betaU,
| uniqIf((tag_chrom, tag_pos, tag_ref, tag_alt), posterior_prob > 0.) AS credibleSetSize,
| uniqIf((tag_chrom, tag_pos, tag_ref, tag_alt), overall_r2 > 0.) AS ldSetSize,
| uniq(tag_chrom, tag_pos, tag_ref, tag_alt) AS uniq_variants
Expand Down Expand Up @@ -401,8 +401,9 @@ class Backend @Inject()(@NamedDatabase("default") protected val dbConfigProvider
db.run(idxVariants.asTry).map {
case Success(v) => ManhattanTable(studyId,
v.map(el => {
ManhattanAssociation(SimpleVariant(el.lead_chrom, el.lead_pos, el.lead_ref, el.lead_alt).id, el.pval,
ManhattanAssociation(el.variantId, el.pval,
el.pval_mantissa, el.pval_exponent,
el.v2dOdds, el.v2dBeta,
el.topGenes, el.credibleSetSize, el.ldSetSize, el.totalSetSize)
})
)
Expand Down Expand Up @@ -494,15 +495,25 @@ class Backend @Inject()(@NamedDatabase("default") protected val dbConfigProvider
q.map(_.pval).any,
q.map(_.pvalExponent).any,
q.map(_.pvalMantissa).any,
q.map(_.overallScore).any)}
q.map(_.overallScore).any,
q.map(_.oddsCI).any,
q.map(_.oddsCILower).any,
q.map(_.oddsCIUpper).any,
q.map(_.direction).any,
q.map(_.betaCI).any,
q.map(_.betaCILower).any,
q.map(_.betaCIUpper).any
)}

db.run(geneIdsInLoci.result.asTry zip assocsQ.result.asTry).map {
case (Success(geneIds), Success(assocs)) =>
val geckoRows = assocs.view
.map(r => GeckoRow(r._1._4, r._1._3, r._1._2, r._1._1,
V2DAssociation(r._2._4.get, r._2._5.get, r._2._6.get, r._2._1, r._2._2, r._2._3,
None, None, None, None, None),
r._2._7.getOrElse(0D)))
r._2._7.getOrElse(0D),
V2DOdds(r._2._8, r._2._9, r._2._10),
V2DBeta(r._2._11, r._2._12, r._2._13, r._2._14)))
Entities.Gecko(geckoRows, geneIds.toSet)

case (Success(geneIds), Failure(asscsEx)) =>
Expand Down
37 changes: 25 additions & 12 deletions app/models/Entities.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import scala.collection.SeqView

object Entities {

case class V2DOdds(oddsCI: Double, oddsCILower: Double, oddsCIUpper: Double)
case class V2DBeta(direction: String, betaCI: Double, betaCILower: Double, betaCIUpper: Double)
case class V2DOdds(oddsCI: Option[Double], oddsCILower: Option[Double], oddsCIUpper: Option[Double])
case class V2DBeta(direction: Option[String], betaCI: Option[Double], betaCILower: Option[Double],
betaCIUpper: Option[Double])
case class V2DAssociation(pval: Double, pvalExponent: Long, pvalMantissa: Double,
r2: Option[Double], log10Abf: Option[Double],
posteriorProbability: Option[Double], afr1000GProp: Option[Double],
Expand Down Expand Up @@ -46,15 +47,16 @@ object Entities {
case class ManhattanTable(studyId: String, associations: Vector[ManhattanAssociation])

case class ManhattanAssociation(variantId: String, pval: Double, pvalMantissa: Double, pvalExponent: Long,
v2dOdds: V2DOdds, v2dBeta: V2DBeta,
bestGenes: Seq[(String, Double)], crediblbeSetSize: Option[Long],
ldSetSize: Option[Long], totalSetSize: Long)

case class V2DStructure(typeId: String,
sourceId: String,
bioFeatureSet: Seq[String])

case class V2DByStudy(lead_chrom: String, lead_pos: Long, lead_ref: String, lead_alt: String, pval: Double,
pval_mantissa: Double, pval_exponent: Long,
case class V2DByStudy(variantId: String, pval: Double,
pval_mantissa: Double, pval_exponent: Long, v2dOdds: V2DOdds, v2dBeta: V2DBeta,
credibleSetSize: Option[Long], ldSetSize: Option[Long], totalSetSize: Long, topGenes: Seq[(String, Double)])

case class StudyInfo(study: Option[Study])
Expand All @@ -71,12 +73,13 @@ object Entities {
nCasesVariant: Option[Long], oddRatio: Option[Double], chip: String, info: Option[Double])
case class GeneTagVariant(geneId: String, tagVariantId: String, overallScore: Double)
case class TagVariantIndexVariantStudy(tagVariantId: String, indexVariantId: String, studyId: String,
v2DAssociation: V2DAssociation)
v2DAssociation: V2DAssociation, odds: V2DOdds, beta: V2DBeta)
case class Gecko(geneIds: Seq[String], tagVariants: Seq[String], indexVariants: Seq[String],
studies: Seq[String], geneTagVariants: Seq[GeneTagVariant],
tagVariantIndexVariantStudies: Seq[TagVariantIndexVariantStudy])
case class GeckoRow(geneId: String, tagVariant: SimpleVariant, indexVariant: SimpleVariant, studyId: String,
v2dAssociation: V2DAssociation, overallScore: Double)
v2dAssociation: V2DAssociation, overallScore: Double,
odds: V2DOdds, beta: V2DBeta)

object Gecko {
def apply(geckoLines: SeqView[GeckoRow, Seq[_]], geneIdsInLoci: Set[String] = Set.empty): Option[Gecko] = {
Expand All @@ -99,7 +102,7 @@ object Entities {
studies += line.studyId
geneTagVariants += GeneTagVariant(line.geneId, tVID, line.overallScore)
tagVariantIndexVariantStudies += TagVariantIndexVariantStudy(tVID, lVID,
line.studyId, line.v2dAssociation)
line.studyId, line.v2dAssociation, line.odds, line.beta)
})

// breakOut could be a good way to map virtually to a other collection of a different type
Expand Down Expand Up @@ -315,14 +318,24 @@ object Entities {
val ordScored = (geneIds zip geneScores)
.sortBy(_._2)(Ordering[Double].reverse)

if (ordScored.isEmpty) ordScored
else {
if (ordScored.isEmpty)
ordScored
else
ordScored.takeWhile(_._2 == ordScored.head._2)
}
}

GetResult(r => V2DByStudy(r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<?, r.<<?, r.<<,
toGeneScoreTuple(StrSeqRep(r.<<), DSeqRep(r.<<))))
GetResult(r => {
val svID: String = SimpleVariant(r.<<, r.<<, r.<<, r.<<).id
val pval: Double = r.<<
val pvalMantissa: Double = r.<<
val pvalExponent: Long = r.<<
val odds = V2DOdds(r.<<?, r.<<?, r.<<?)
val beta = V2DBeta(r.<<?, r.<<?, r.<<?, r.<<?)

V2DByStudy(svID, pval, pvalMantissa, pvalExponent, odds, beta,
r.<<?, r.<<?, r.<<,
toGeneScoreTuple(StrSeqRep(r.<<), DSeqRep(r.<<)))
})
}

implicit val getSumStatsByVariantPheWAS: GetResult[VariantPheWAS] =
Expand Down
59 changes: 30 additions & 29 deletions app/models/FRM.scala
Original file line number Diff line number Diff line change
Expand Up @@ -170,16 +170,16 @@ object FRM {
def leadVariant =
(leadChromosome, leadPosition, leadRefAllele, leadAltAllele).mapTo[SimpleVariant]

def direction = column[String]("direction")
def betaCI = column[Double]("beta")
def betaCILower = column[Double]("beta_ci_lower")
def betaCIUpper = column[Double]("beta_ci_upper")
def direction = column[Option[String]]("direction")
def betaCI = column[Option[Double]]("beta")
def betaCILower = column[Option[Double]]("beta_ci_lower")
def betaCIUpper = column[Option[Double]]("beta_ci_upper")
def beta =
(direction, betaCI, betaCILower, betaCIUpper).mapTo[V2DBeta]

def oddsCI = column[Double]("odds_ratio")
def oddsCILower = column[Double]("oddsr_ci_lower")
def oddsCIUpper = column[Double]("oddsr_ci_upper")
def oddsCI = column[Option[Double]]("odds_ratio")
def oddsCILower = column[Option[Double]]("oddsr_ci_lower")
def oddsCIUpper = column[Option[Double]]("oddsr_ci_upper")
def odds =
(oddsCI, oddsCILower, oddsCIUpper).mapTo[V2DOdds]

Expand Down Expand Up @@ -238,16 +238,16 @@ object FRM {
def leadVariant =
(leadChromosome, leadPosition, leadRefAllele, leadAltAllele).mapTo[SimpleVariant]

def direction = column[String]("direction")
def betaCI = column[Double]("beta")
def betaCILower = column[Double]("beta_ci_lower")
def betaCIUpper = column[Double]("beta_ci_upper")
def direction = column[Option[String]]("direction")
def betaCI = column[Option[Double]]("beta")
def betaCILower = column[Option[Double]]("beta_ci_lower")
def betaCIUpper = column[Option[Double]]("beta_ci_upper")
def beta =
(direction, betaCI, betaCILower, betaCIUpper).mapTo[V2DBeta]

def oddsCI = column[Double]("odds_ratio")
def oddsCILower = column[Double]("oddsr_ci_lower")
def oddsCIUpper = column[Double]("oddsr_ci_upper")
def oddsCI = column[Option[Double]]("odds_ratio")
def oddsCILower = column[Option[Double]]("oddsr_ci_lower")
def oddsCIUpper = column[Option[Double]]("oddsr_ci_upper")
def odds =
(oddsCI, oddsCILower, oddsCIUpper).mapTo[V2DOdds]

Expand Down Expand Up @@ -410,16 +410,16 @@ object FRM {
def leadVariant =
(leadChromosome, leadPosition, leadRefAllele, leadAltAllele).mapTo[SimpleVariant]

def direction = column[String]("direction")
def betaCI = column[Double]("beta")
def betaCILower = column[Double]("beta_ci_lower")
def betaCIUpper = column[Double]("beta_ci_upper")
def direction = column[Option[String]]("direction")
def betaCI = column[Option[Double]]("beta")
def betaCILower = column[Option[Double]]("beta_ci_lower")
def betaCIUpper = column[Option[Double]]("beta_ci_upper")
def beta =
(direction, betaCI, betaCILower, betaCIUpper).mapTo[V2DBeta]

def oddsCI = column[Double]("odds_ratio")
def oddsCILower = column[Double]("oddsr_ci_lower")
def oddsCIUpper = column[Double]("oddsr_ci_upper")
def oddsCI = column[Option[Double]]("odds_ratio")
def oddsCILower = column[Option[Double]]("oddsr_ci_lower")
def oddsCIUpper = column[Option[Double]]("oddsr_ci_upper")
def odds =
(oddsCI, oddsCILower, oddsCIUpper).mapTo[V2DOdds]

Expand Down Expand Up @@ -516,16 +516,16 @@ object FRM {
def leadVariant =
(leadChromosome, leadPosition, leadRefAllele, leadAltAllele).mapTo[SimpleVariant]

def direction = column[String]("direction")
def betaCI = column[Double]("beta")
def betaCILower = column[Double]("beta_ci_lower")
def betaCIUpper = column[Double]("beta_ci_upper")
def direction = column[Option[String]]("direction")
def betaCI = column[Option[Double]]("beta")
def betaCILower = column[Option[Double]]("beta_ci_lower")
def betaCIUpper = column[Option[Double]]("beta_ci_upper")
def beta =
(direction, betaCI, betaCILower, betaCIUpper).mapTo[V2DBeta]

def oddsCI = column[Double]("odds_ratio")
def oddsCILower = column[Double]("oddsr_ci_lower")
def oddsCIUpper = column[Double]("oddsr_ci_upper")
def oddsCI = column[Option[Double]]("odds_ratio")
def oddsCILower = column[Option[Double]]("oddsr_ci_lower")
def oddsCIUpper = column[Option[Double]]("oddsr_ci_upper")
def odds =
(oddsCI, oddsCILower, oddsCIUpper).mapTo[V2DOdds]

Expand Down Expand Up @@ -555,7 +555,8 @@ object FRM {
def v2dRow = (tagVariant, leadVariant, study, association, odds, beta).mapTo[V2DRow]

def geckoRow =
(geneId, tagVariant, leadVariant, studyId, association, overallScore).mapTo[GeckoRow]
(geneId, tagVariant, leadVariant, studyId, association,
overallScore, odds, beta).mapTo[GeckoRow]

def geneId = column[String]("gene_id")
def typeId = column[String]("type_id")
Expand Down
Loading

0 comments on commit 8f61595

Please sign in to comment.