Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions app/models/Backend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import clickhouse.ClickHouseProfile
import net.logstash.logback.argument.StructuredArguments.keyValue
import com.sksamuel.elastic4s.*
import com.sksamuel.elastic4s.http.JavaClient
import com.sksamuel.elastic4s.requests.searches.*
import com.sksamuel.elastic4s.requests.searches.aggs.*
import esecuele.*

import javax.inject.Inject
Expand All @@ -26,6 +24,7 @@ import models.entities.Interactions.*
import models.entities.Loci.*
import models.entities.MechanismsOfAction.*
import models.entities.MousePhenotypes.*
import models.entities.NoveltyResults.*
import models.entities.Pharmacogenomics.*
import models.entities.SearchFacetsResults.*
import models.entities.Studies.*
Expand Down Expand Up @@ -726,6 +725,24 @@ class Backend @Inject() (implicit
dbRetriever.executeQuery[MechanismsOfAction, Query](query.query)
}

def getNovelty(diseaseId: String,
targetId: String,
isDirect: Boolean,
pagination: Option[Pagination]
): Future[NoveltyResults] = {
val tableName = getTableWithPrefixOrDefault(defaultOTSettings.clickhouse.novelty.name)
val pag = pagination.getOrElse(Pagination.mkDefault).offsetLimit
logger.debug(s"querying novelty", keyValue("table", tableName))
val query = NoveltyQuery(diseaseId, targetId, isDirect, tableName, pag._1, pag._2)
dbRetriever.executeQuery[Novelty, Query](query.query).map { noveltySeq =>
if (noveltySeq.isEmpty) {
NoveltyResults(0, noveltySeq)
} else {
NoveltyResults(noveltySeq.head.meta_total, noveltySeq)
}
}
}

def getDrugWarnings(ids: Seq[String]): Future[IndexedSeq[DrugWarnings]] = {
val tableName = getTableWithPrefixOrDefault(defaultOTSettings.clickhouse.drugWarnings.name)
logger.debug(s"querying drug warnings", keyValue("ids", ids), keyValue("table", tableName))
Expand Down
1 change: 0 additions & 1 deletion app/models/GQLSchema.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import entities.*
import sangria.execution.deferred.*
import gql.validators.QueryTermsValidator.*

import scala.concurrent.ExecutionContext.Implicits.global
import models.gql.Objects.*
import models.gql.Arguments.*
import models.gql.Fetchers.*
Expand Down
1 change: 0 additions & 1 deletion app/models/db/CredibleSetQuery.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import esecuele.Column.column
import esecuele.Column.literal
import esecuele._
import utils.OTLogging
import models.entities.StudyQueryArgs
import models.gql.StudyTypeEnum
import models.entities.CredibleSetQueryArgs

Expand Down
2 changes: 0 additions & 2 deletions app/models/db/InteractionSourcesQuery.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package models.db

import esecuele.Column.column
import esecuele.Column.literal
import esecuele._
import utils.OTLogging
import play.libs.F
import models.gql.InteractionSourceEnum

case class InteractionSourcesQuery(
Expand Down
43 changes: 43 additions & 0 deletions app/models/db/NoveltyQuery.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package models.db

import esecuele.Column.column
import esecuele.Column.literal
import esecuele.*
import utils.OTLogging

case class NoveltyQuery(diseaseId: String,
targetId: String,
isDirect: Boolean,
tableName: String,
offset: Int,
size: Int
) extends Queryable
with OTLogging {

private val positionalQuery = Where(
Functions.and(
Functions.equals(column("diseaseId"), literal(diseaseId)),
Functions.equals(column("targetId"), literal(targetId)),
Functions.equals(column("isDirect"), literal(isDirect))
)
)

val totals: Query =
Query(
Select(Functions.count(Column.star) :: Nil),
From(column(tableName)),
positionalQuery
)

override val query: Query =
Query(
Select(
Column.star :: Functions.countOver("meta_total") :: Nil
),
From(column(tableName)),
positionalQuery,
OrderBy(column("year").asc :: Nil),
Limit(offset, size),
Format("JSONEachRow")
)
}
1 change: 1 addition & 0 deletions app/models/entities/Configuration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ object Configuration {
clinicalTarget: DbTableSettings,
mechanismOfAction: DbTableSettings,
mousePhenotypes: DbTableSettings,
novelty: DbTableSettings,
otarProjects: DbTableSettings,
pharmacogenomics: PharmacogenomicsSettings,
proteinCodingCoordinates: ProteinCodingCoordinatesSettings,
Expand Down
31 changes: 31 additions & 0 deletions app/models/entities/Novelty.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package models.entities

import play.api.libs.json.{Json, OFormat}
import slick.jdbc.GetResult
import utils.db.DbJsonParser.fromPositionedResult

case class Novelty(
diseaseId: String,
targetId: String,
aggregationType: String,
aggregationValue: String,
year: Option[Int],
associationScore: Double,
novelty: Option[Double],
yearlyEvidenceCount: Option[Int],
isDirect: Boolean,
meta_total: Long
)

case class NoveltyResults(
count: Long,
rows: Vector[Novelty]
)

object NoveltyResults {
val empty: NoveltyResults = NoveltyResults(0, Vector.empty)
implicit val getNoveltyRowFromDB: GetResult[Novelty] =
GetResult(fromPositionedResult[Novelty])
implicit val NoveltyImp: OFormat[Novelty] = Json.format[Novelty]
implicit val NoveltyResultsImp: OFormat[NoveltyResults] = Json.format[NoveltyResults]
}
1 change: 0 additions & 1 deletion app/models/entities/Studies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ case class Study(
)

object Studies extends OTLogging {
import sangria.macros.derive._
def empty: Studies = Studies(0, IndexedSeq.empty)

implicit val studiesFromDB: GetResult[Study] =
Expand Down
8 changes: 6 additions & 2 deletions app/models/gql/Arguments.scala
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,6 @@ object Arguments {
Argument("studyId", OptionInputType(StringType), description = "Study ID")
val studyIds: Argument[Option[Seq[String]]] =
Argument("studyIds", OptionInputType(ListInputType(StringType)), description = "Study IDs")
val diseaseId: Argument[Option[String]] =
Argument("diseaseId", OptionInputType(StringType), description = "Disease ID")
val diseaseIds: Argument[Option[Seq[String]]] =
Argument("diseaseIds", OptionInputType(ListInputType(StringType)), description = "Disease IDs")
val studyTypes =
Expand All @@ -177,6 +175,12 @@ object Arguments {
OptionInputType(ListInputType(StringType)),
description = "Study-locus IDs"
)
val isDirect: Argument[Boolean] = Argument(
"isDirect",
BooleanType,
description =
"Whether to include only direct associations/evidence (true), or also indirect ones (false)."
)
val enableIndirect: Argument[Option[Boolean]] = Argument(
"enableIndirect",
OptionInputType(BooleanType),
Expand Down
71 changes: 70 additions & 1 deletion app/models/gql/Objects.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import models.entities.ClinicalIndications.{
clinicalIndicationsFromDrugImp
}
import models.entities.ClinicalTargets.clinicalTargetsImp
import play.api.libs.json.*
import sangria.macros.derive.*
import sangria.schema.*

Expand Down Expand Up @@ -444,6 +443,14 @@ object Objects extends OTLogging {
description = Some(""),
arguments = Nil,
resolve = ctx => ctx.ctx.getClinicalTargetsByTarget(ctx.value.id)
),
Field(
"novelty",
noveltyResultsImp,
description = Some("Novelty"),
arguments = efoId :: isDirect :: pageArg :: Nil,
resolve = ctx =>
ctx.ctx.getNovelty(ctx.arg(efoId), ctx.value.id, ctx.arg(isDirect), ctx.arg(pageArg))
)
)
)
Expand Down Expand Up @@ -684,6 +691,14 @@ object Objects extends OTLogging {
),
arguments = Nil,
resolve = ctx => ctx.ctx.getClinicalIndicationsByDisease(ctx.value.id)
),
Field(
"novelty",
noveltyResultsImp,
description = Some("Novelty"),
arguments = ensemblId :: isDirect :: pageArg :: Nil,
resolve = ctx =>
ctx.ctx.getNovelty(ctx.value.id, ctx.arg(ensemblId), ctx.arg(isDirect), ctx.arg(pageArg))
)
)
)
Expand Down Expand Up @@ -789,6 +804,60 @@ object Objects extends OTLogging {
"List of credible set entries with their associated statistics and fine-mapping information"
)
)
implicit val noveltyResultsImp: ObjectType[Backend, NoveltyResults] =
deriveObjectType[Backend, NoveltyResults](
ObjectTypeDescription(
"Novelty of the association between a target and a disease. Calculated based on the accumulation of evidence over time, providing insights into how novel or well-established a target-disease association is."
),
DocumentField(
"count",
"Total number of novelty results matching the query filters"
),
DocumentField(
"rows",
"List of novelty entries with their associated novelty scores and temporal information"
)
)

implicit val noveltyImp: ObjectType[Backend, Novelty] = deriveObjectType[Backend, Novelty](
ObjectTypeDescription(
"Novelty of the association between a target and a disease. Calculated based on the accumulation of evidence over time, providing insights into how novel or well-established a target-disease association is."
),
DocumentField("diseaseId", "EFO ID of the disease"),
DocumentField(
"targetId",
"Ensembl ID of the target gene"
),
DocumentField(
"aggregationType",
"Type of aggregation used for novelty calculation"
),
DocumentField(
"aggregationValue",
"Value used for novelty aggregation"
),
DocumentField(
"year",
"Year of the evidence item used for novelty calculation"
),
DocumentField(
"associationScore",
"Association score between the target and disease"
),
DocumentField(
"novelty",
"Novelty score indicating how novel the target-disease association is."
),
DocumentField(
"yearlyEvidenceCount",
"Yearly count of evidence items"
),
DocumentField(
"isDirect",
"Flag indicating whether the novelty calculation is based on direct evidence only or includes indirect evidence"
),
ExcludeFields("meta_total")
)

implicit val tissueImp: ObjectType[Backend, Tissue] = deriveObjectType[Backend, Tissue](
ObjectTypeDescription(
Expand Down
4 changes: 4 additions & 0 deletions conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ ot {
label = "Mouse phenotypes table"
name = "mouse_phenotypes"
}
novelty {
label = "Novelty table"
name = "novelty"
}
otarProjects {
label = "OTAR projects table"
name = "otar_projects"
Expand Down
Loading