Skip to content

Commit

Permalink
3379 cred set (#196)
Browse files Browse the repository at this point in the history
* credible set endpoint and entity

* format files

* add fectcher to clean cache and resolvers

* add new fields

* Filter documents

* update id type

* update to JsValue

* format file

* remove commeted code

* undo Any type
  • Loading branch information
remo87 authored Aug 2, 2024
1 parent c803950 commit ad9a54a
Show file tree
Hide file tree
Showing 6 changed files with 323 additions and 2 deletions.
6 changes: 6 additions & 0 deletions app/models/Backend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ class Backend @Inject() (implicit
esRetriever.getByIds(indexName, ids, fromJsValue[VariantIndex])
}

def getCredSet(ids: Seq[String]): Future[IndexedSeq[JsValue]] = {
val indexName = getIndexOrDefault("credible_set")

esRetriever.getByIds(indexName, ids, fromJsValue[JsValue])
}

def getGwasIndexes(ids: Seq[String]): Future[IndexedSeq[JsValue]] = {
val indexName = getIndexOrDefault("gwas_index")

Expand Down
11 changes: 10 additions & 1 deletion app/models/GQLSchema.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import play.api.Logging
import play.api.libs.json._
import sangria.schema._
import entities._
import models.entities.CredibleSet.credibleSetImp
import models.entities.GwasIndex.gwasImp
import sangria.execution.deferred._

Expand All @@ -28,7 +29,8 @@ object GQLSchema {
indicationFetcher,
goFetcher,
variantFetcher,
gwasFetcher
gwasFetcher,
credSetFetcher
)

val query: ObjectType[Backend, Unit] = ObjectType(
Expand Down Expand Up @@ -149,6 +151,13 @@ object GQLSchema {
description = Some("Return a Gwas Index Study"),
arguments = studyId :: Nil,
resolve = ctx => gwasFetcher.deferOpt(ctx.arg(studyId))
),
Field(
"credibleSet",
OptionType(credibleSetImp),
description = None,
arguments = credibleSetId :: Nil,
resolve = ctx => credSetFetcher.deferOpt(ctx.arg(credibleSetId))
)
)
)
Expand Down
288 changes: 288 additions & 0 deletions app/models/entities/CredibleSet.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
package models.entities

import models.Backend
import models.entities.GwasIndex.gwasImp
import models.gql.Fetchers.{gwasFetcher, targetsFetcher, variantFetcher}
import models.gql.Objects.{logger, targetImp, variantIndexImp}
import play.api.Logging
import play.api.libs.json.{JsValue, Json, OFormat, OWrites}
import sangria.schema.{
Field,
FloatType,
IntType,
ListType,
ObjectType,
OptionType,
StringType,
fields
}

case class Locus(
variantId: Option[String],
posteriorProbability: Option[Double],
pValueMantissa: Option[Double],
pValueExponent: Option[Int],
logBF: Option[Double],
beta: Option[Double],
standardError: Option[Double],
is95CredibleSet: Option[Boolean],
is99CredibleSet: Option[Boolean],
r2Overall: Option[Double]
)

case class LdSet(
tagVariantId: Option[String],
r2Overall: Option[Double]
)

case class StrongestLocus2gene(geneId: String, score: Double)

case class CredibleSet(studyLocusId: String,
variantId: Option[String],
chromosome: Option[String],
position: Option[Int],
region: Option[String],
studyId: Option[String],
beta: Option[Double],
zScore: Option[Double],
pValueMantissa: Option[Double],
pValueExponent: Option[Int],
effectAlleleFrequencyFromSource: Option[Double],
standardError: Option[Double],
subStudyDescription: Option[String],
qualityControls: Option[Seq[String]],
finemappingMethod: Option[String],
credibleSetIndex: Option[Int],
credibleSetlog10BF: Option[Double],
purityMeanR2: Option[Double],
purityMinR2: Option[Double],
locusStart: Option[Int],
locusEnd: Option[Int],
locus: Option[Seq[Locus]],
sampleSize: Option[Int],
strongestLocus2gene: Option[StrongestLocus2gene],
ldSet: Option[Seq[LdSet]],
studyType: Option[String],
traitFromSourceMappedIds: Option[Seq[String]],
qtlGeneId: Option[String]
)

object CredibleSet extends Logging {
import sangria.macros.derive._

implicit val strongestLocus2geneImp: ObjectType[Backend, StrongestLocus2gene] =
deriveObjectType[Backend, StrongestLocus2gene](
ReplaceField(
"geneId",
Field(
"target",
OptionType(targetImp),
Some("Target"),
resolve = r => targetsFetcher.deferOpt(r.value.geneId)
)
)
)
implicit val ldSetImp: ObjectType[Backend, LdSet] =
deriveObjectType[Backend, LdSet]()
implicit val locusImp: ObjectType[Backend, Locus] = deriveObjectType[Backend, Locus](
ReplaceField(
"variantId",
Field(
"variant",
OptionType(variantIndexImp),
description = None,
resolve = r => {
val variantId = (r.value.variantId)
logger.debug(s"Finding variant index: $variantId")
variantFetcher.deferOpt(variantId)
}
)
)
)

implicit val ldSetF: OFormat[LdSet] = Json.format[LdSet]
implicit val locusF: OFormat[Locus] = Json.format[Locus]
implicit val strongestLocus2geneF: OFormat[StrongestLocus2gene] = Json.format[StrongestLocus2gene]
val credibleSetImp: ObjectType[Backend, JsValue] = ObjectType(
"credibleSet",
"",
fields[Backend, JsValue](
Field(
"studyLocusId",
StringType,
description = None,
resolve = js => (js.value \ "studyLocusId").as[String]
),
Field(
"variant",
OptionType(variantIndexImp),
description = None,
resolve = js => {
val id = (js.value \ "variantId").asOpt[String]
logger.debug(s"Finding variant for id: $id")
variantFetcher.deferOpt(id)
}
),
Field(
"chromosome",
OptionType(StringType),
description = None,
resolve = js => (js.value \ "chromosome").asOpt[String]
),
Field(
"position",
OptionType(IntType),
description = None,
resolve = js => (js.value \ "position").asOpt[Int]
),
Field(
"region",
OptionType(StringType),
description = None,
resolve = js => (js.value \ "region").asOpt[String]
),
Field(
"study",
OptionType(gwasImp),
description = Some("Gwas study"),
resolve = js => {
val studyId = (js.value \ "studyId").asOpt[String]
logger.debug(s"Finding gwas study: $studyId")
gwasFetcher.deferOpt(studyId)
}
),
Field(
"beta",
OptionType(FloatType),
description = None,
resolve = js => (js.value \ "beta").asOpt[Double]
),
Field(
"zScore",
OptionType(FloatType),
description = None,
resolve = js => (js.value \ "zScore").asOpt[Double]
),
Field(
"pValueMantissa",
OptionType(FloatType),
description = None,
resolve = js => (js.value \ "pValueMantissa").asOpt[Double]
),
Field(
"pValueExponent",
OptionType(IntType),
description = None,
resolve = js => (js.value \ "pValueExponent").asOpt[Int]
),
Field(
"effectAlleleFrequencyFromSource",
OptionType(FloatType),
description = None,
resolve = js => (js.value \ "effectAlleleFrequencyFromSource").asOpt[Double]
),
Field(
"standardError",
OptionType(FloatType),
description = None,
resolve = js => (js.value \ "standardError").asOpt[Double]
),
Field(
"subStudyDescription",
OptionType(StringType),
description = None,
resolve = js => (js.value \ "subStudyDescription").asOpt[String]
),
Field(
"qualityControls",
OptionType(ListType(StringType)),
description = None,
resolve = js => (js.value \ "qualityControls").asOpt[Seq[String]]
),
Field(
"finemappingMethod",
OptionType(StringType),
description = None,
resolve = js => (js.value \ "finemappingMethod").asOpt[String]
),
Field(
"credibleSetIndex",
OptionType(IntType),
description = None,
resolve = js => (js.value \ "credibleSetIndex").asOpt[Int]
),
Field(
"credibleSetlog10BF",
OptionType(FloatType),
description = None,
resolve = js => (js.value \ "credibleSetlog10BF").asOpt[Double]
),
Field(
"purityMeanR2",
OptionType(FloatType),
description = None,
resolve = js => (js.value \ "purityMeanR2").asOpt[Double]
),
Field(
"purityMinR2",
OptionType(FloatType),
description = None,
resolve = js => (js.value \ "purityMinR2").asOpt[Double]
),
Field(
"locusStart",
OptionType(IntType),
description = None,
resolve = js => (js.value \ "locusStart").asOpt[Int]
),
Field(
"locusEnd",
OptionType(IntType),
description = None,
resolve = js => (js.value \ "locusEnd").asOpt[Int]
),
Field(
"locus",
OptionType(ListType(locusImp)),
description = None,
resolve = js => (js.value \ "locus").asOpt[Seq[Locus]]
),
Field(
"sampleSize",
OptionType(IntType),
description = None,
resolve = js => (js.value \ "sampleSize").asOpt[Int]
),
Field(
"strongestLocus2gene",
OptionType(strongestLocus2geneImp),
description = None,
resolve = js => (js.value \ "strongestLocus2gene").asOpt[StrongestLocus2gene]
),
Field(
"ldSet",
OptionType(ListType(ldSetImp)),
description = None,
resolve = js => (js.value \ "ldSet").asOpt[Seq[LdSet]]
),
Field(
"studyType",
OptionType(StringType),
description = None,
resolve = js => (js.value \ "studyType").asOpt[String]
),
Field(
"traitFromSourceMappedIds",
OptionType(ListType(StringType)),
description = None,
resolve = js => (js.value \ "traitFromSourceMappedIds").asOpt[Seq[String]]
),
Field(
"qtlGeneId",
OptionType(StringType),
description = None,
resolve = js => (js.value \ "qtlGeneId").asOpt[String]
)
)
)
}
2 changes: 2 additions & 0 deletions app/models/gql/Arguments.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ object Arguments {
Argument("goIds", ListInputType(StringType), description = "List of GO IDs, eg. GO:0005515")
val variantId: Argument[String] = Argument("variantId", StringType, description = "Variant ID")
val studyId: Argument[String] = Argument("studyId", StringType, description = "Study ID")
val credibleSetId: Argument[String] =
Argument("credibleSetId", StringType, description = "Credible Set ID")

val indirectEvidences: Argument[Option[Boolean]] = Argument(
"enableIndirect",
Expand Down
17 changes: 16 additions & 1 deletion app/models/gql/Fetchers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package models.gql

import models.Helpers.fromJsValue
import models.entities.{
CredibleSet,
Disease,
Drug,
Expressions,
Expand Down Expand Up @@ -128,6 +129,19 @@ object Fetchers extends Logging {
}
)

val credSetFetcherCache = FetcherCache.simple
val credSetFetcher: Fetcher[Backend, JsValue, JsValue, String] = {
implicit val credSetFetcherId: HasId[JsValue, String] =
HasId[JsValue, String](js => (js \ "studyLocusId").as[String])
Fetcher(
config =
FetcherConfig.maxBatchSize(entities.Configuration.batchSize).caching(credSetFetcherCache),
fetch = (ctx: Backend, ids: Seq[String]) => {
ctx.getCredSet(ids)
}
)
}

val gwasFetcherCache = FetcherCache.simple
val gwasFetcher: Fetcher[Backend, JsValue, JsValue, String] = {
implicit val gwasFetcherId: HasId[JsValue, String] =
Expand Down Expand Up @@ -166,7 +180,8 @@ object Fetchers extends Logging {
reactomeFetcherCache,
expressionFetcherCache,
otarProjectsFetcherCache,
soTermsFetcherCache
soTermsFetcherCache,
credSetFetcherCache
)
fetchers.foreach(_.clear())
}
Expand Down
1 change: 1 addition & 0 deletions app/models/gql/Objects.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import models._
import models.entities.Configuration._
import models.entities.Evidence.sequenceOntologyTermImp
import models.entities.Evidences._
import models.entities.GwasIndex.gwasImp
import models.entities.Interactions._
import models.entities.Publications.publicationsImp
import models.entities._
Expand Down

0 comments on commit ad9a54a

Please sign in to comment.