Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tcr db #1

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
49fbfc6
docker config
suluxan Jun 12, 2023
363dd8b
start of annotations
suluxan Jun 12, 2023
4ee5802
added neo4j to gitignore
suluxan Jun 12, 2023
f82337e
type defs for annotations - customized to whatever the data input is …
suluxan Jun 13, 2023
393a14e
resolver to read in data (hardcoded to the file currently will be cha…
suluxan Jun 13, 2023
9784a1f
titles and logos
suluxan Jun 13, 2023
29e7666
hook to get annotations query data
suluxan Jun 13, 2023
3c362d8
clean up nav bar
suluxan Jun 13, 2023
c228647
annotations list/cards with filtering by search text and highlighting…
suluxan Jun 13, 2023
d8bbd53
menu change
suluxan Dec 15, 2023
fa77f02
added debounce and fuse
suluxan Dec 15, 2023
db51fb9
title
suluxan Dec 15, 2023
98346d3
about
suluxan Dec 15, 2023
f5d6c21
updated hook to use state variables
suluxan Dec 15, 2023
3217e2b
updated fuse and filters
suluxan Dec 15, 2023
71c36ec
options temporarily hardcoded
suluxan Dec 18, 2023
098bf54
adding wes/graphene
suluxan Dec 19, 2023
c3fb369
scripts
suluxan Dec 19, 2023
b4bfcad
latest gliph2 pipeline dockerfile
suluxan Dec 19, 2023
12ab010
test for gliph
suluxan Dec 19, 2023
330b4ca
irtools
suluxan Dec 19, 2023
3a3810c
neomodel
suluxan Dec 19, 2023
5748561
Basic mutation to submit run in neomodel
jurbinan Dec 20, 2023
16dcebf
remove extras
suluxan Dec 20, 2023
fc3573d
remove
suluxan Dec 20, 2023
95ce5e7
Improved Run neomodel model and bugfixes
jurbinan Dec 20, 2023
b2513f1
git ignore updated
suluxan Feb 2, 2024
c45fb11
Dockerfile updated
suluxan Feb 2, 2024
28e8d95
latest packages
suluxan Feb 2, 2024
70a956a
TIGERdb changes
suluxan Feb 2, 2024
bc418e5
Keycloak Public Portal Setup
suluxan Feb 2, 2024
723e249
download button that will be enabled later once public data is organized
suluxan Feb 2, 2024
7131ee8
fix for certificate error (self signed/expired)
suluxan Feb 7, 2024
5bc53bf
neo4j should pick up /data from folders instead of docker volume
suluxan Feb 7, 2024
4c81167
Added bar chart and related query
jurbinan Mar 18, 2024
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
8 changes: 6 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ ui/dist
api/build
keycloak/keycloak-db

.env
**/.env
**/.venv
ui/.env
ui/.DS_Store
api/src/cql/Code Book-Table 1.csv
api/src/cql/Data-Table 1.csv
zzz.tmp.csv

api/src/funnel/inputs
api/src/funnel/inputs
neo4j
nginx/certs
minio
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,3 @@
path = api/src/neo4jgraphql
url = https://gitlab.com/CHILDdb/neo4jgraphql
branch = imic
[submodule "imic_docs"]
path = imic_docs
url = https://github.com/mdpham/imic_docs.git
14 changes: 7 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,26 @@ WORKDIR /usr/src/app
COPY package.json .
COPY package-lock.json .
COPY .npmrc .
RUN GITLAB_AUTH_TOKEN=${GITLAB_AUTH_TOKEN} npm install --force graphql-ws
# RUN GITLAB_AUTH_TOKEN=${GITLAB_AUTH_TOKEN} npm install --force graphql-ws
RUN GITLAB_AUTH_TOKEN=${GITLAB_AUTH_TOKEN} npm i --force
RUN GITLAB_AUTH_TOKEN=${GITLAB_AUTH_TOKEN} npm --force ci
# RUN GITLAB_AUTH_TOKEN=${GITLAB_AUTH_TOKEN} npm --force ci

COPY . .
ENV NODE_ENV production
RUN npm run build:ui

WORKDIR /usr/src/app/imic_docs
RUN npm install --force
RUN npm run clean
RUN npm run build
# WORKDIR /usr/src/app/imic_docs
# RUN npm install --force
# RUN npm run clean
# RUN npm run build




FROM nginx:alpine
WORKDIR /usr/src/app
COPY --from=build-deps /usr/src/app/ui/dist ./dist
COPY --from=build-deps /usr/src/app/imic_docs/public ./docs
# COPY --from=build-deps /usr/src/app/imic_docs/public ./docs

# RUN sed -i 's/https/http/' /etc/apk/repositories
# RUN apk add bash
Expand Down
6 changes: 3 additions & 3 deletions api/src/graphql/graphqlServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ export const createApolloServer = async () => {
if (!allowedWithoutTOS.includes(queryName))
throw new Error(`Access denied. User [${email} / ${sub}] has not accepted the TOS. Please accept the TOS to gain access.`)
}
} else {
throw new Error(`Access denied. Keycloak auth token required to access graphql. Please login with keycloak.`)
}
} //else {
//throw new Error(`Access denied. Keycloak auth token required to access graphql. Please login with keycloak.`)
//}


return {
Expand Down
78 changes: 78 additions & 0 deletions api/src/graphql/resolvers/curatedAnnotation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { listBucketObjects, makePresignedURL } from '../../minio/minio'
import papa from 'papaparse'
import { ApolloError } from 'apollo-server'
import zlib from 'zlib'


export const resolvers = {
Query: {
countEpitopeSpecies: async (_parent, _args, { driver }) => {
const session = driver.session()
const epitopeSpeciesList = await session.run("MATCH (a:AnnotationVariable) RETURN DISTINCT a.epitopeSpecies AS e")
const annotationVariables = await session.run("MATCH (a:AnnotationVariable) RETURN a")
const results = []

const epitopeSpeciesCount = {}
epitopeSpeciesList.records.map((species) => {
epitopeSpeciesCount[species.get('e')] = 0
})

annotationVariables.records.forEach((variable) => {
const species = variable.get('a').properties['epitopeSpecies']
epitopeSpeciesCount[species]++
})

Object.keys(epitopeSpeciesCount).forEach((key) => {
results.push({ "epitopeSpecies": key, "count": epitopeSpeciesCount[key] })
})

return results
}
},
Mutation: {
createCuratedAnnotationFromRawDataset: async (parent, { name, description, rawDatasetID }, { driver, ogm, minioClient }) => {
try {
// Create model and add a curated dataset node to db
const CuratedAnnotationModel = ogm.model("CuratedAnnotation")
const bucketName = `raw-dataset-${rawDatasetID}`

const curatedAnnotationInput = {name, description, generatedByRawDataset: {connect: {where: {node: {rawDatasetID}}}}}
const { curatedAnnotations: [curatedAnnotation] } = await CuratedAnnotationModel.create({ input: [curatedAnnotationInput], })
const { curatedAnnotationID } = curatedAnnotation

const session = driver.session()

// const bucketObjects = (await listBucketObjects(minioClient, bucketName)).map(({ name }) => name)
// // console.log(bucketObjects)
// const presignedURL = await makePresignedURL(minioClient, bucketName, bucketObjects.slice(-1)[0])
// // console.log(presignedURL)

// original api with datavariables containing chr,start,end,datavalue
const createCuratedAnnotationFromRawDataset = await session.run(
`CALL apoc.periodic.iterate(\'CALL apoc.load.csv($presignedURL, {sep: \"TAB\"}) YIELD list\', \'MATCH (b:CuratedAnnotation {curatedAnnotationID: $curatedAnnotationID}) CREATE (a:AnnotationVariable {annotationVariableID: apoc.create.uuid(), locus: list[0], cdr3b: list[1], trbv: list[2], trbj: list[3], mhc: list[4], mhcClass: list[5], epitope: list[6], epitopeGene: list[7], epitopeSpecies: list[8], reference: list[9] }), (b)-[:HAS_ANNOTATION_VARIABLE]->(a) RETURN a\', { batchSize:10000, iterateList: true, parallel:true, params:{curatedAnnotationID: $curatedAnnotationID, presignedURL: $presignedURL}})`,
{curatedAnnotationID: curatedAnnotationID, presignedURL: 'file:///VDJdb_MinimalScoreConfidence3_VersionII.tsv'}
)
// const createCuratedDatasetFromRawDataset = await session.run(
// `CALL apoc.periodic.iterate(
// \'CALL apoc.load.csv($presignedURL, {sep: \" \", compression: \"GZIP\", header: false}) YIELD list\',
// \'MATCH (b:CuratedDataset {curatedDatasetID: $curatedDatasetID})
// CREATE (a:DataVariable {dataVariableID: apoc.create.uuid()}),
// (c:DataVariableField {name: \"chromosome\", value: toFloat(apoc.text.replace(list[0],\"chr\",\"\")) }),
// (d:DataVariableField {name: \"start\", value: toInteger(list[1])}),
// (e:DataVariableField {name: \"end\", value: toInteger(list[2])}),
// (f:DataVariableField {name: \"datavalue\", value: toFloat(list[3])}),
// (a)-[:HAS_FIELD]->(c), (a)-[:HAS_FIELD]->(d), (a)-[:HAS_FIELD]->(e), (a)-[:HAS_FIELD]->(f), (b)-[:HAS_DATA_VARIABLE]->(a)
// RETURN a\',
// {batchSize:10000, iterateList:true, parallel:true, params:{curatedDatasetID: $curatedDatasetID, presignedURL: $presignedURL}}
// )`,
// {curatedDatasetID: curatedDatasetID, presignedURL: presignedURL}
// )

return curatedAnnotation
} catch (error) {
console.log(error)
throw new ApolloError('curatedAnnotationFromRawDataset', error )
}
}
},
}
20 changes: 20 additions & 0 deletions api/src/graphql/typeDefinitions/annotationVariable.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
type AnnotationVariable {
annotationVariableID: ID! @id
locus: String
cdr3b: String
trbv: String
trbj: String
mhc: String
mhcClass: String
epitope: String
epitopeGene: String
epitopeSpecies: String
reference: String
# Define fields you want to search over here, transformation script must map to this shape

# currentDefinition: DataVariableDefinition! @relationship(type: "HAS_DEFINITION", direction: OUT, properties: "HasDefinition")
# currentDefinition: DataVariableDefinition! @relationship(type: "HAS_DEFINITION", direction: OUT)
# previousDefinitions: [DataVariableDefinition!]! @relationship(type: "HAS_DEFINITION", direction: OUT)

# fields: [DataVariableField!]! @relationship(type: "HAS_FIELD", direction: OUT)
}
62 changes: 62 additions & 0 deletions api/src/graphql/typeDefinitions/curatedAnnotation.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# type Subject {
# subjectID: ID! @id
# childID: ID!
# }



# type DataVariableDefinition {
# dataVariable: DataVariable! @relationship(type: "HAS_DEFINITION", direction: IN)
# dataVariableDefinitionID: ID! @id
# label: String!
# }

# type DataVariableSample {
# dataVariableSampleID: ID! @id
# # value: JSON
# currentValueState: DataVariableSampleState! @relationship(type: "HAS_DEFINITION", direction: IN)
# previousValueStates: [DataVariableSampleState!]! @relationship(type: "HAS_DEFINITION", direction: IN)
# }

# # For time versioning
# type DataVariableSampleState {
# value: JSON
# }

type CuratedAnnotation {
curatedAnnotationID: ID! @id
# createdAt: DateTime! @timestamp(operations: [CREATE])
# updatedAt: DateTime! @timestamp(operations: [UPDATE])
name: String!
description: String!
annotationVariables: [AnnotationVariable!]! @relationship(type: "HAS_ANNOTATION_VARIABLE", direction: OUT)

generatedByRawDataset: RawDataset! @relationship(type: "GENERATED_CURATED_ANNOTATION", direction: IN)
}

type EpitopeSpeciesCount {
epitopeSpecies: String!
count: Int!
}

type Mutation {
createCuratedAnnotationFromRawDataset(
name: String!
description: String!
rawDatasetID: ID!
): CuratedAnnotation!
}

type Query {
countEpitopeSpecies: [EpitopeSpeciesCount]!
}

# extend type CuratedAnnotation @auth(
# rules: [{
# isAuthenticated: true,
# where: {AND: [
# {allowedStudies: "$jwt.resource_access.pibu-app.roles"},
# {allowedSites: "$jwt.resource_access.pibu-app.roles"},
# ]}
# }]
# )
Loading