Skip to content

Commit bb25ae8

Browse files
authored
More Metadata Sections for Hermes (#150)
* genotyping information section done * imputation section done * done with genotyping qc
1 parent c4ed3a6 commit bb25ae8

File tree

2 files changed

+217
-10
lines changed

2 files changed

+217
-10
lines changed

cypress/e2e/hermes/hermes-upload.cy.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,19 @@ describe('Hermes Upload', {retries: 0}, () => {
2121
cy.get("#caseDefinition").type("My case definition");
2222
cy.get("#totalSampleSize").type("989");
2323
cy.get("#maleProportionCohort").type("1");
24+
cy.get('#callingAlgorithm').type("You called, algorithm?");
25+
cy.get('#genotypingArray').type("Array against you");
26+
cy.get('[data-cy="referenceGenome"]').type('Hg19').type('{enter}');
27+
cy.get('#imputationSoftware').type('Imputate this software');
28+
cy.get('#imputationReference').type('Imputation reference');
29+
cy.get('#numberOfVariantsForImputation').type('47');
30+
cy.get('#imputationQualityMeasure').type('highest quality');
31+
cy.get('[data-cy="relatedIndividualsRemoved"]').type('Yes').type('{enter}');
32+
cy.get('#variantCallRate').type('.22');
33+
cy.get('#sampleCallRate').type('.2247');
34+
cy.get('#hwePValue').type('.09121');
35+
cy.get('#maf').type('1');
36+
cy.get('#otherFilters').type('My Filters');
2437

2538
// cy.get("#participants").type('20');
2639
// cy.get("#sexProportion").type('20');

pages/hermes/new.vue

Lines changed: 204 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const formSchema = yup.object({
2828
cases: yup.number().integer('Cases must be an integer').positive('Cases must be positive')
2929
.label('Cases').transform(value => (isNaN(value) ? undefined : value)),
3030
maleProportionCohort: yup.number().min(0).max(1).required()
31+
.transform(value => (isNaN(value) ? undefined : value))
3132
.label('Male propoportion (total cohort)'),
3233
maleProportionCases: yup.number().min(0).max(1).label('Male proportion (cases)').when("cases", {
3334
is: (value) => value > 0,
@@ -70,7 +71,7 @@ const formSchema = yup.object({
7071
meanDiagnosisAge: yup.number().positive('Mean diagnosis age must be positive')
7172
.label('Mean diagnosis age').transform(value => (isNaN(value) ? undefined : value)).when("cases", {
7273
is: (value) => value > 0,
73-
then: (schema) => schema.required('You must mean diagnosis age when you specify cases'),
74+
then: (schema) => schema.required('You must specify mean diagnosis age when you specify cases'),
7475
otherwise: (schema) => schema,
7576
}),
7677
sdDiagnosisAge: yup.number().positive('Standard deviation diagnosis age must be positive')
@@ -79,6 +80,27 @@ const formSchema = yup.object({
7980
then: (schema) => schema.required('You must mean diagnosis age when you specify cases'),
8081
otherwise: (schema) => schema,
8182
}),
83+
referenceGenome: yup.string().label('Reference Genome').required(),
84+
genotypingArray: yup.string().label('Genotyping Array').required(),
85+
callingAlgorithm: yup.string().label('Calling Algorithm').required(),
86+
imputationSoftware: yup.string().label('Imputation Software').required(),
87+
imputationReference: yup.string().label('Imputation Reference').required(),
88+
numberOfVariantsForImputation: yup.number().positive("Number of variants for imputation must be positive")
89+
.transform(value => (isNaN(value) ? undefined : value))
90+
.integer("Number of variants should be a whole number")
91+
.label("Number of Variants for Imputation").required(),
92+
imputationQualityMeasure: yup.string().label("Imputation Quality Measure").required(),
93+
relatedIndividualsRemoved: yup.string().label("Related Individuals Removed").required(),
94+
variantCallRate: yup.number().min(0).max(1).transform(value => (isNaN(value) ? undefined : value))
95+
.label("Variant Call Rate").required(),
96+
sampleCallRate: yup.number().min(0).max(1).transform(value => (isNaN(value) ? undefined : value))
97+
.label("Sample Call Rate").required(),
98+
hwePValue: yup.number().min(0).max(1).transform(value => (isNaN(value) ? undefined : value))
99+
.label("HWE p-value").required(),
100+
maf: yup.number().min(0).max(1).transform(value => (isNaN(value) ? undefined : value))
101+
.label("MAF").required(),
102+
otherFilters: yup.string().label("Other QC Filters").required(),
103+
82104
});
83105
84106
@@ -112,6 +134,19 @@ const [meanAgeControls] = defineField('meanAgeControls');
112134
const [sdAgeControls] = defineField('sdAgeControls');
113135
const [meanDiagnosisAge] = defineField('meanDiagnosisAge');
114136
const [sdDiagnosisAge] = defineField('sdDiagnosisAge');
137+
const [referenceGenome] = defineField('referenceGenome');
138+
const [genotypingArray] = defineField('genotypingArray');
139+
const [callingAlgorithm] = defineField('callingAlgorithm');
140+
const [imputationSoftware] = defineField('imputationSoftware');
141+
const [imputationReference] = defineField('imputationReference');
142+
const [numberOfVariantsForImputation] = defineField('numberOfVariantsForImputation');
143+
const [imputationQualityMeasure] = defineField('imputationQualityMeasure');
144+
const [relatedIndividualsRemoved] = defineField('relatedIndividualsRemoved');
145+
const [variantCallRate] = defineField('variantCallRate');
146+
const [sampleCallRate] = defineField('sampleCallRate');
147+
const [hwePValue] = defineField('hwePValue');
148+
const [maf] = defineField('maf');
149+
const [otherFilters] = defineField('otherFilters');
115150
116151
const store = useDatasetStore();
117152
const userStore = useUserStore();
@@ -123,11 +158,18 @@ const missingFileError = ref('');
123158
const missingMappingError = ref('');
124159
let fileName = null;
125160
let previousMapping = {};
126-
const selectedGenomeBuild = ref('');
127161
const caseAscertainmentOptions = ref([
128162
{ name: "Electronic Health Records", value: "Electronic Health Records" },
129163
{ name: "Research Study", value: "Research Study" }
130164
]);
165+
const referenceGenomeOptions = ref([
166+
{ name: "Hg38", value: "Hg38" },
167+
{ name: "Hg19", value: "Hg19" }
168+
]);
169+
const relatedIndividualsRemovedOptions = ref([
170+
{name: "Yes", value: "Yes"},
171+
{name: "No", value: "No"},
172+
]);
131173
const sexOptions = ref([
132174
{ name: "Not sex stratified", value: "Not sex stratified" },
133175
{ name: "Male only", value: "Male only" },
@@ -164,16 +206,8 @@ const analysisSoftware = ref("");
164206
const statisticalModel = ref("");
165207
const covariates = ref("");
166208
const arrayName = ref("");
167-
const callingAlgorithm = ref("");
168-
const variantCallRate = ref(null);
169-
const sampleCallRate = ref(null);
170-
const hwePValue = ref(null);
171-
const maf = ref(null);
172-
const otherQCFilters = ref("");
173209
const nVariantsForImputation = ref("");
174210
const prephasingAndImputationSoftware = ref("");
175-
const imputationReference = ref("");
176-
const imputationQualityMeasure = ref("");
177211
const colOptions = ref([]);
178212
const requiredFields = ref([]);
179213
const selectedFields = ref({});
@@ -706,6 +740,166 @@ async function uploadSubmit(){
706740
707741
</Fieldset>
708742
743+
<Fieldset legend="Genotyping Information">
744+
<div class="field">
745+
<label for="reference">Reference Genome</label>
746+
<Dropdown
747+
id="referenceGenome"
748+
v-model="referenceGenome"
749+
:options="referenceGenomeOptions"
750+
optionLabel="name"
751+
optionValue="value"
752+
placeholder="Select Reference Genome" data-cy="referenceGenome"
753+
aria-describedby="referenceGenome-help"
754+
:class="{ 'p-invalid': errors.referenceGenome }"
755+
756+
/>
757+
<small id="referenceGenome-help" class="p-error">
758+
{{ errors.referenceGenome }}
759+
</small>
760+
</div>
761+
<div class="field">
762+
<label for="genotypingArray">Genotyping Array</label>
763+
<InputText v-model="genotypingArray" id="genotypingArray" type="text"
764+
v-tooltip="'The genotyping array name and version used to generate the genetic data (e.g. Illumina Omni2.5)'"
765+
aria-labelledby="genotypingArray-help"
766+
:class="{'p-invalid': errors.genotypingArray}"
767+
/>
768+
<small id="genotypingArray-help" class="p-error">
769+
{{ errors.genotypingArray }}
770+
</small>
771+
</div>
772+
<div class="field">
773+
<label for="callingAlgorithm">Calling Algorithm</label>
774+
<InputText v-model="callingAlgorithm" id="callingAlgorithm" type="text"
775+
v-tooltip="'The calling algorithm used (e.g. GATK HaplotypeCaller v4.1)'"
776+
aria-labelledby="callingAlgorithm-help"
777+
:class="{'p-invalid': errors.callingAlgorithm}"
778+
/>
779+
<small id="callingAlgorithm-help" class="p-error">
780+
{{ errors.callingAlgorithm }}
781+
</small>
782+
</div>
783+
</Fieldset>
784+
<Fieldset legend="Imputation Information">
785+
<div class="field">
786+
<label for="imputationSoftware">Imputation Software</label>
787+
<InputText v-model="imputationSoftware" id="imputationSoftware" type="text"
788+
v-tooltip="'The prephasing and imputation software and version used in the GWAS analysis (e.g. IMPUTE2 v2.3.2)'"
789+
aria-labelledby="imputationSoftware-help"
790+
:class="{'p-invalid': errors.imputationSoftware}"
791+
/>
792+
<small id="imputationSoftware-help" class="p-error">
793+
{{ errors.imputationSoftware }}
794+
</small>
795+
</div>
796+
<div class="field">
797+
<label for="imputationReference">Imputation Reference</label>
798+
<InputText v-model="imputationReference" id="imputationReference" type="text"
799+
v-tooltip="'The imputation reference used (e.g. HRCr1.1)'"
800+
aria-labelledby="imputationReference-help"
801+
:class="{'p-invalid': errors.imputationReference}"
802+
/>
803+
<small id="imputationReference-help" class="p-error">
804+
{{ errors.imputationReference }}
805+
</small>
806+
</div>
807+
<div class="field">
808+
<label for="numberOfVariantsForImputation">Number of Variants for Imputation</label>
809+
<InputText v-model="numberOfVariantsForImputation" id="numberOfVariantsForImputation" type="number"
810+
v-tooltip="'The number of variants used for imputation (e.g. 10,000)'"
811+
aria-labelledby="numberOfVariantsForImputation-help"
812+
:class="{'p-invalid': errors.numberOfVariantsForImputation}"
813+
/>
814+
<small id="numberOfVariantsForImputation-help" class="p-error">
815+
{{ errors.numberOfVariantsForImputation }}
816+
</small>
817+
</div>
818+
<div class="field">
819+
<label for="imputationQualityMeasure">Imputation Quality Measure</label>
820+
<InputText v-model="imputationQualityMeasure" id="imputationQualityMeasure" type="text"
821+
v-tooltip="'The imputation quality measure used and any threshold applied (e.g. INFO > 0.98 / R^2 > 0.85 / MACH R^2 > 0.92)'"
822+
aria-labelledby="imputationQualityMeasure-help"
823+
:class="{'p-invalid': errors.imputationQualityMeasure}"
824+
/>
825+
<small id="imputationQualityMeasure-help" class="p-error">
826+
{{ errors.imputationQualityMeasure }}
827+
</small>
828+
</div>
829+
</Fieldset>
830+
<Fieldset legend="Genotyping Quality Control">
831+
<div class="field">
832+
<label for="relatedIndividualsRemoved">Related Individuals Removed?</label>
833+
<Dropdown
834+
id="relatedIndividualsRemoved"
835+
v-model="relatedIndividualsRemoved"
836+
:options="relatedIndividualsRemovedOptions"
837+
optionLabel="name"
838+
optionValue="value"
839+
placeholder="Related Individuals Removed?" data-cy="relatedIndividualsRemoved"
840+
aria-describedby="relatedIndividualsRemoved-help"
841+
:class="{ 'p-invalid': errors.relatedIndividualsRemoved }"
842+
/>
843+
<small id="relatedIndividualsRemoved-help" class="p-error">
844+
{{ errors.relatedIndividualsRemoved }}
845+
</small>
846+
</div>
847+
<div class="field">
848+
<label for="variantCallRate">Variant Call Rate</label>
849+
<InputText v-model="variantCallRate" id="variantCallRate" type="number" min="0" max="1"
850+
v-tooltip="'The variant call rate threshold used (e.g. 0.95)'"
851+
aria-labelledby="variantCallRate-help"
852+
:class="{'p-invalid': errors.variantCallRate}"
853+
/>
854+
<small id="variantCallRate-help" class="p-error">
855+
{{ errors.variantCallRate }}
856+
</small>
857+
</div>
858+
<div class="field">
859+
<label for="sampleCallRate">Sample Call Rate</label>
860+
<InputText v-model="sampleCallRate" id="sampleCallRate" type="number" min="0" max="1"
861+
v-tooltip="'The sample call rate threshold used (e.g. 0.97)'"
862+
aria-labelledby="sampleCallRate-help"
863+
:class="{'p-invalid': errors.sampleCallRate}"
864+
/>
865+
<small id="sampleCallRate-help" class="p-error">
866+
{{ errors.sampleCallRate }}
867+
</small>
868+
</div>
869+
<div class="field">
870+
<label for="hwePValue">HWE p-value</label>
871+
<InputText v-model="hwePValue" id="hwePValue" type="number" min="0" max="1"
872+
v-tooltip="'The Hardy-Weinberg Equilibrium p-value threshold used (e.g. 0.05)'"
873+
aria-labelledby="hwePValue-help"
874+
:class="{'p-invalid': errors.hwePValue}"
875+
/>
876+
<small id="hwePValue-help" class="p-error">
877+
{{ errors.hwePValue }}
878+
</small>
879+
</div>
880+
<div class="field">
881+
<label for="maf">MAF Threshold</label>
882+
<InputText v-model="maf" id="maf" type="number" min="0" max="1"
883+
v-tooltip="'The minor allele frequency threshold used (e.g. 0.01)'"
884+
aria-labelledby="maf-help"
885+
:class="{'p-invalid': errors.maf}"
886+
/>
887+
<small id="maf-help" class="p-error">
888+
{{ errors.maf }}
889+
</small>
890+
</div>
891+
<div class="field">
892+
<label for="otherFilters">Other QC Filters</label>
893+
<InputText v-model="otherFilters" id="otherFilters" type="text"
894+
v-tooltip="'Other quality control filters that may have been implemented'"
895+
aria-labelledby="otherFilters-help"
896+
:class="{'p-invalid': errors.otherFilters}"
897+
/>
898+
<small id="otherFilters-help" class="p-error">
899+
{{ errors.otherFilters }}
900+
</small>
901+
</div>
902+
</Fieldset>
709903
710904
711905
</div>

0 commit comments

Comments
 (0)